Compare commits
25 Commits
rawhide
...
main-riscv
Author | SHA1 | Date |
---|---|---|
David Abdurachmanov | b9aa19325a | |
Tomáš Hrnčiar | d3e4f80070 | |
Fedora Release Engineering | ff956d27be | |
David Abdurachmanov | 3e5fc8ca46 | |
Fedora Release Engineering | c604248608 | |
Tomáš Hrnčiar | 90929e6c2e | |
Lumir Balhar | 7a094a0571 | |
Miro Hrončok | 3c67985ace | |
Tomáš Hrnčiar | cc458c9fb3 | |
David Abdurachmanov | b735fa02e0 | |
Miro Hrončok | c41c6b28ff | |
David Abdurachmanov | 7ea22f20d4 | |
David Abdurachmanov | bde278d98e | |
David Abdurachmanov | 8b902d984a | |
Yaakov Selkowitz | 261b6e48d6 | |
Miro Hrončok | 187d5c28b8 | |
Miro Hrončok | fb0049bb7a | |
Tomáš Hrnčiar | 614cafc400 | |
Tomáš Hrnčiar | 67ba754f51 | |
Tomáš Hrnčiar | 0483fca31a | |
Charalampos Stratakis | 1f830e372b | |
Fedora Release Engineering | 88668cf1f4 | |
Miro Hrončok | bc99d88db7 | |
Tomáš Hrnčiar | 2d8f888430 | |
Tomáš Hrnčiar | 8522651180 |
|
@ -30,10 +30,10 @@ Co-authored-by: Lumír Balhar <frenzy.madness@gmail.com>
|
|||
3 files changed, 71 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Lib/site.py b/Lib/site.py
|
||||
index 672fa7b000..0a9c5be53e 100644
|
||||
index 924b2460d9..51b5baca93 100644
|
||||
--- a/Lib/site.py
|
||||
+++ b/Lib/site.py
|
||||
@@ -377,8 +377,15 @@ def getsitepackages(prefixes=None):
|
||||
@@ -387,8 +387,15 @@ def getsitepackages(prefixes=None):
|
||||
return sitepackages
|
||||
|
||||
def addsitepackages(known_paths, prefixes=None):
|
||||
|
|
|
@ -16,10 +16,10 @@ https://github.com/GrahamDumpleton/mod_wsgi/issues/730
|
|||
2 files changed, 8 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py
|
||||
index 9e4972ecb6..6f081d8f38 100644
|
||||
index 00d9e591c7..3314319fec 100644
|
||||
--- a/Lib/test/test_threading.py
|
||||
+++ b/Lib/test/test_threading.py
|
||||
@@ -987,39 +987,6 @@ def noop(): pass
|
||||
@@ -1089,39 +1089,6 @@ def noop(): pass
|
||||
threading.Thread(target=noop).start()
|
||||
# Thread.join() is not called
|
||||
|
||||
|
@ -60,10 +60,10 @@ index 9e4972ecb6..6f081d8f38 100644
|
|||
code = """if 1:
|
||||
import atexit
|
||||
diff --git a/Lib/threading.py b/Lib/threading.py
|
||||
index df273870fa..eba297776d 100644
|
||||
index 98cb43c697..ee647f8549 100644
|
||||
--- a/Lib/threading.py
|
||||
+++ b/Lib/threading.py
|
||||
@@ -1565,29 +1565,20 @@ def _shutdown():
|
||||
@@ -1585,29 +1585,20 @@ def _shutdown():
|
||||
|
||||
global _SHUTTING_DOWN
|
||||
_SHUTTING_DOWN = True
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro@hroncok.cz>
|
||||
Date: Mon, 29 May 2023 15:51:16 +0200
|
||||
Subject: [PATCH] 00401: Tests: Use setuptools+wheel from
|
||||
sysconfig.get_config_var('WHEEL_PKG_DIR') if set
|
||||
|
||||
Proposed upstream https://github.com/python/cpython/pull/105056
|
||||
---
|
||||
Lib/test/support/__init__.py | 21 +++++++++++++++++++++
|
||||
Lib/test/test_cppext.py | 4 ++--
|
||||
2 files changed, 23 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
|
||||
index d555c53fee..adc3f5901d 100644
|
||||
--- a/Lib/test/support/__init__.py
|
||||
+++ b/Lib/test/support/__init__.py
|
||||
@@ -2398,5 +2398,26 @@ def adjust_int_max_str_digits(max_digits):
|
||||
finally:
|
||||
sys.set_int_max_str_digits(current)
|
||||
|
||||
+
|
||||
+@functools.cache
|
||||
+def _findwheel(pkgname):
|
||||
+ """Try to find a wheel with the package specified as pkgname.
|
||||
+
|
||||
+ If set, the wheels are searched for in WHEEL_PKG_DIR (see ensurepip).
|
||||
+ Otherwise, they are searched for in the test directory.
|
||||
+ """
|
||||
+ wheel_dir = sysconfig.get_config_var('WHEEL_PKG_DIR') or TEST_HOME_DIR
|
||||
+ filenames = os.listdir(wheel_dir)
|
||||
+ filenames = sorted(filenames) # sort this like ensurepip does it
|
||||
+ for filename in filenames:
|
||||
+ # filename is like 'pip-21.2.4-py3-none-any.whl'
|
||||
+ if not filename.endswith(".whl"):
|
||||
+ continue
|
||||
+ prefix = pkgname + '-'
|
||||
+ if filename.startswith(prefix):
|
||||
+ return os.path.join(wheel_dir, filename)
|
||||
+ raise FileNotFoundError(f"No wheel for {pkgname} found in {wheel_dir}")
|
||||
+
|
||||
+
|
||||
#For recursion tests, easily exceeds default recursion limit
|
||||
EXCEEDS_RECURSION_LIMIT = 5000
|
||||
diff --git a/Lib/test/test_cppext.py b/Lib/test/test_cppext.py
|
||||
index 4fb62d87e8..d124220dac 100644
|
||||
--- a/Lib/test/test_cppext.py
|
||||
+++ b/Lib/test/test_cppext.py
|
||||
@@ -83,8 +83,8 @@ def run_cmd(operation, cmd):
|
||||
|
||||
cmd = [python, '-X', 'dev',
|
||||
'-m', 'pip', 'install',
|
||||
- support.findfile('setuptools-67.6.1-py3-none-any.whl'),
|
||||
- support.findfile('wheel-0.40.0-py3-none-any.whl')]
|
||||
+ support._findwheel('setuptools'),
|
||||
+ support._findwheel('wheel')]
|
||||
run_cmd('Install build dependencies', cmd)
|
||||
|
||||
# Build and install the C++ extension
|
|
@ -0,0 +1,483 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Victor Stinner <vstinner@python.org>
|
||||
Date: Fri, 15 Dec 2023 16:10:40 +0100
|
||||
Subject: [PATCH] 00415: [CVE-2023-27043] gh-102988: Reject malformed addresses
|
||||
in email.parseaddr() (#111116)
|
||||
|
||||
Detect email address parsing errors and return empty tuple to
|
||||
indicate the parsing error (old API). Add an optional 'strict'
|
||||
parameter to getaddresses() and parseaddr() functions. Patch by
|
||||
Thomas Dwyer.
|
||||
|
||||
Co-Authored-By: Thomas Dwyer <github@tomd.tel>
|
||||
---
|
||||
Doc/library/email.utils.rst | 19 +-
|
||||
Lib/email/utils.py | 151 +++++++++++++-
|
||||
Lib/test/test_email/test_email.py | 187 +++++++++++++++++-
|
||||
...-10-20-15-28-08.gh-issue-102988.dStNO7.rst | 8 +
|
||||
4 files changed, 344 insertions(+), 21 deletions(-)
|
||||
create mode 100644 Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst
|
||||
|
||||
diff --git a/Doc/library/email.utils.rst b/Doc/library/email.utils.rst
|
||||
index 345b64001c..d693a9bc39 100644
|
||||
--- a/Doc/library/email.utils.rst
|
||||
+++ b/Doc/library/email.utils.rst
|
||||
@@ -58,13 +58,18 @@ of the new API.
|
||||
begins with angle brackets, they are stripped off.
|
||||
|
||||
|
||||
-.. function:: parseaddr(address)
|
||||
+.. function:: parseaddr(address, *, strict=True)
|
||||
|
||||
Parse address -- which should be the value of some address-containing field such
|
||||
as :mailheader:`To` or :mailheader:`Cc` -- into its constituent *realname* and
|
||||
*email address* parts. Returns a tuple of that information, unless the parse
|
||||
fails, in which case a 2-tuple of ``('', '')`` is returned.
|
||||
|
||||
+ If *strict* is true, use a strict parser which rejects malformed inputs.
|
||||
+
|
||||
+ .. versionchanged:: 3.13
|
||||
+ Add *strict* optional parameter and reject malformed inputs by default.
|
||||
+
|
||||
|
||||
.. function:: formataddr(pair, charset='utf-8')
|
||||
|
||||
@@ -82,12 +87,15 @@ of the new API.
|
||||
Added the *charset* option.
|
||||
|
||||
|
||||
-.. function:: getaddresses(fieldvalues)
|
||||
+.. function:: getaddresses(fieldvalues, *, strict=True)
|
||||
|
||||
This method returns a list of 2-tuples of the form returned by ``parseaddr()``.
|
||||
*fieldvalues* is a sequence of header field values as might be returned by
|
||||
- :meth:`Message.get_all <email.message.Message.get_all>`. Here's a simple
|
||||
- example that gets all the recipients of a message::
|
||||
+ :meth:`Message.get_all <email.message.Message.get_all>`.
|
||||
+
|
||||
+ If *strict* is true, use a strict parser which rejects malformed inputs.
|
||||
+
|
||||
+ Here's a simple example that gets all the recipients of a message::
|
||||
|
||||
from email.utils import getaddresses
|
||||
|
||||
@@ -97,6 +105,9 @@ of the new API.
|
||||
resent_ccs = msg.get_all('resent-cc', [])
|
||||
all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs)
|
||||
|
||||
+ .. versionchanged:: 3.13
|
||||
+ Add *strict* optional parameter and reject malformed inputs by default.
|
||||
+
|
||||
|
||||
.. function:: parsedate(date)
|
||||
|
||||
diff --git a/Lib/email/utils.py b/Lib/email/utils.py
|
||||
index aa949aa933..af2fb14754 100644
|
||||
--- a/Lib/email/utils.py
|
||||
+++ b/Lib/email/utils.py
|
||||
@@ -48,6 +48,7 @@
|
||||
specialsre = re.compile(r'[][\\()<>@,:;".]')
|
||||
escapesre = re.compile(r'[\\"]')
|
||||
|
||||
+
|
||||
def _has_surrogates(s):
|
||||
"""Return True if s may contain surrogate-escaped binary data."""
|
||||
# This check is based on the fact that unless there are surrogates, utf8
|
||||
@@ -106,12 +107,127 @@ def formataddr(pair, charset='utf-8'):
|
||||
return address
|
||||
|
||||
|
||||
+def _iter_escaped_chars(addr):
|
||||
+ pos = 0
|
||||
+ escape = False
|
||||
+ for pos, ch in enumerate(addr):
|
||||
+ if escape:
|
||||
+ yield (pos, '\\' + ch)
|
||||
+ escape = False
|
||||
+ elif ch == '\\':
|
||||
+ escape = True
|
||||
+ else:
|
||||
+ yield (pos, ch)
|
||||
+ if escape:
|
||||
+ yield (pos, '\\')
|
||||
|
||||
-def getaddresses(fieldvalues):
|
||||
- """Return a list of (REALNAME, EMAIL) for each fieldvalue."""
|
||||
- all = COMMASPACE.join(str(v) for v in fieldvalues)
|
||||
- a = _AddressList(all)
|
||||
- return a.addresslist
|
||||
+
|
||||
+def _strip_quoted_realnames(addr):
|
||||
+ """Strip real names between quotes."""
|
||||
+ if '"' not in addr:
|
||||
+ # Fast path
|
||||
+ return addr
|
||||
+
|
||||
+ start = 0
|
||||
+ open_pos = None
|
||||
+ result = []
|
||||
+ for pos, ch in _iter_escaped_chars(addr):
|
||||
+ if ch == '"':
|
||||
+ if open_pos is None:
|
||||
+ open_pos = pos
|
||||
+ else:
|
||||
+ if start != open_pos:
|
||||
+ result.append(addr[start:open_pos])
|
||||
+ start = pos + 1
|
||||
+ open_pos = None
|
||||
+
|
||||
+ if start < len(addr):
|
||||
+ result.append(addr[start:])
|
||||
+
|
||||
+ return ''.join(result)
|
||||
+
|
||||
+
|
||||
+supports_strict_parsing = True
|
||||
+
|
||||
+def getaddresses(fieldvalues, *, strict=True):
|
||||
+ """Return a list of (REALNAME, EMAIL) or ('','') for each fieldvalue.
|
||||
+
|
||||
+ When parsing fails for a fieldvalue, a 2-tuple of ('', '') is returned in
|
||||
+ its place.
|
||||
+
|
||||
+ If strict is true, use a strict parser which rejects malformed inputs.
|
||||
+ """
|
||||
+
|
||||
+ # If strict is true, if the resulting list of parsed addresses is greater
|
||||
+ # than the number of fieldvalues in the input list, a parsing error has
|
||||
+ # occurred and consequently a list containing a single empty 2-tuple [('',
|
||||
+ # '')] is returned in its place. This is done to avoid invalid output.
|
||||
+ #
|
||||
+ # Malformed input: getaddresses(['alice@example.com <bob@example.com>'])
|
||||
+ # Invalid output: [('', 'alice@example.com'), ('', 'bob@example.com')]
|
||||
+ # Safe output: [('', '')]
|
||||
+
|
||||
+ if not strict:
|
||||
+ all = COMMASPACE.join(str(v) for v in fieldvalues)
|
||||
+ a = _AddressList(all)
|
||||
+ return a.addresslist
|
||||
+
|
||||
+ fieldvalues = [str(v) for v in fieldvalues]
|
||||
+ fieldvalues = _pre_parse_validation(fieldvalues)
|
||||
+ addr = COMMASPACE.join(fieldvalues)
|
||||
+ a = _AddressList(addr)
|
||||
+ result = _post_parse_validation(a.addresslist)
|
||||
+
|
||||
+ # Treat output as invalid if the number of addresses is not equal to the
|
||||
+ # expected number of addresses.
|
||||
+ n = 0
|
||||
+ for v in fieldvalues:
|
||||
+ # When a comma is used in the Real Name part it is not a deliminator.
|
||||
+ # So strip those out before counting the commas.
|
||||
+ v = _strip_quoted_realnames(v)
|
||||
+ # Expected number of addresses: 1 + number of commas
|
||||
+ n += 1 + v.count(',')
|
||||
+ if len(result) != n:
|
||||
+ return [('', '')]
|
||||
+
|
||||
+ return result
|
||||
+
|
||||
+
|
||||
+def _check_parenthesis(addr):
|
||||
+ # Ignore parenthesis in quoted real names.
|
||||
+ addr = _strip_quoted_realnames(addr)
|
||||
+
|
||||
+ opens = 0
|
||||
+ for pos, ch in _iter_escaped_chars(addr):
|
||||
+ if ch == '(':
|
||||
+ opens += 1
|
||||
+ elif ch == ')':
|
||||
+ opens -= 1
|
||||
+ if opens < 0:
|
||||
+ return False
|
||||
+ return (opens == 0)
|
||||
+
|
||||
+
|
||||
+def _pre_parse_validation(email_header_fields):
|
||||
+ accepted_values = []
|
||||
+ for v in email_header_fields:
|
||||
+ if not _check_parenthesis(v):
|
||||
+ v = "('', '')"
|
||||
+ accepted_values.append(v)
|
||||
+
|
||||
+ return accepted_values
|
||||
+
|
||||
+
|
||||
+def _post_parse_validation(parsed_email_header_tuples):
|
||||
+ accepted_values = []
|
||||
+ # The parser would have parsed a correctly formatted domain-literal
|
||||
+ # The existence of an [ after parsing indicates a parsing failure
|
||||
+ for v in parsed_email_header_tuples:
|
||||
+ if '[' in v[1]:
|
||||
+ v = ('', '')
|
||||
+ accepted_values.append(v)
|
||||
+
|
||||
+ return accepted_values
|
||||
|
||||
|
||||
def _format_timetuple_and_zone(timetuple, zone):
|
||||
@@ -205,16 +321,33 @@ def parsedate_to_datetime(data):
|
||||
tzinfo=datetime.timezone(datetime.timedelta(seconds=tz)))
|
||||
|
||||
|
||||
-def parseaddr(addr):
|
||||
+def parseaddr(addr, *, strict=True):
|
||||
"""
|
||||
Parse addr into its constituent realname and email address parts.
|
||||
|
||||
Return a tuple of realname and email address, unless the parse fails, in
|
||||
which case return a 2-tuple of ('', '').
|
||||
+
|
||||
+ If strict is True, use a strict parser which rejects malformed inputs.
|
||||
"""
|
||||
- addrs = _AddressList(addr).addresslist
|
||||
- if not addrs:
|
||||
- return '', ''
|
||||
+ if not strict:
|
||||
+ addrs = _AddressList(addr).addresslist
|
||||
+ if not addrs:
|
||||
+ return ('', '')
|
||||
+ return addrs[0]
|
||||
+
|
||||
+ if isinstance(addr, list):
|
||||
+ addr = addr[0]
|
||||
+
|
||||
+ if not isinstance(addr, str):
|
||||
+ return ('', '')
|
||||
+
|
||||
+ addr = _pre_parse_validation([addr])[0]
|
||||
+ addrs = _post_parse_validation(_AddressList(addr).addresslist)
|
||||
+
|
||||
+ if not addrs or len(addrs) > 1:
|
||||
+ return ('', '')
|
||||
+
|
||||
return addrs[0]
|
||||
|
||||
|
||||
diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py
|
||||
index 2a237095b9..4672b790d8 100644
|
||||
--- a/Lib/test/test_email/test_email.py
|
||||
+++ b/Lib/test/test_email/test_email.py
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
import email
|
||||
import email.policy
|
||||
+import email.utils
|
||||
|
||||
from email.charset import Charset
|
||||
from email.generator import Generator, DecodedGenerator, BytesGenerator
|
||||
@@ -3337,15 +3338,137 @@ def test_getaddresses_comma_in_name(self):
|
||||
],
|
||||
)
|
||||
|
||||
+ def test_parsing_errors(self):
|
||||
+ """Test for parsing errors from CVE-2023-27043 and CVE-2019-16056"""
|
||||
+ alice = 'alice@example.org'
|
||||
+ bob = 'bob@example.com'
|
||||
+ empty = ('', '')
|
||||
+
|
||||
+ # Test utils.getaddresses() and utils.parseaddr() on malformed email
|
||||
+ # addresses: default behavior (strict=True) rejects malformed address,
|
||||
+ # and strict=False which tolerates malformed address.
|
||||
+ for invalid_separator, expected_non_strict in (
|
||||
+ ('(', [(f'<{bob}>', alice)]),
|
||||
+ (')', [('', alice), empty, ('', bob)]),
|
||||
+ ('<', [('', alice), empty, ('', bob), empty]),
|
||||
+ ('>', [('', alice), empty, ('', bob)]),
|
||||
+ ('[', [('', f'{alice}[<{bob}>]')]),
|
||||
+ (']', [('', alice), empty, ('', bob)]),
|
||||
+ ('@', [empty, empty, ('', bob)]),
|
||||
+ (';', [('', alice), empty, ('', bob)]),
|
||||
+ (':', [('', alice), ('', bob)]),
|
||||
+ ('.', [('', alice + '.'), ('', bob)]),
|
||||
+ ('"', [('', alice), ('', f'<{bob}>')]),
|
||||
+ ):
|
||||
+ address = f'{alice}{invalid_separator}<{bob}>'
|
||||
+ with self.subTest(address=address):
|
||||
+ self.assertEqual(utils.getaddresses([address]),
|
||||
+ [empty])
|
||||
+ self.assertEqual(utils.getaddresses([address], strict=False),
|
||||
+ expected_non_strict)
|
||||
+
|
||||
+ self.assertEqual(utils.parseaddr([address]),
|
||||
+ empty)
|
||||
+ self.assertEqual(utils.parseaddr([address], strict=False),
|
||||
+ ('', address))
|
||||
+
|
||||
+ # Comma (',') is treated differently depending on strict parameter.
|
||||
+ # Comma without quotes.
|
||||
+ address = f'{alice},<{bob}>'
|
||||
+ self.assertEqual(utils.getaddresses([address]),
|
||||
+ [('', alice), ('', bob)])
|
||||
+ self.assertEqual(utils.getaddresses([address], strict=False),
|
||||
+ [('', alice), ('', bob)])
|
||||
+ self.assertEqual(utils.parseaddr([address]),
|
||||
+ empty)
|
||||
+ self.assertEqual(utils.parseaddr([address], strict=False),
|
||||
+ ('', address))
|
||||
+
|
||||
+ # Real name between quotes containing comma.
|
||||
+ address = '"Alice, alice@example.org" <bob@example.com>'
|
||||
+ expected_strict = ('Alice, alice@example.org', 'bob@example.com')
|
||||
+ self.assertEqual(utils.getaddresses([address]), [expected_strict])
|
||||
+ self.assertEqual(utils.getaddresses([address], strict=False), [expected_strict])
|
||||
+ self.assertEqual(utils.parseaddr([address]), expected_strict)
|
||||
+ self.assertEqual(utils.parseaddr([address], strict=False),
|
||||
+ ('', address))
|
||||
+
|
||||
+ # Valid parenthesis in comments.
|
||||
+ address = 'alice@example.org (Alice)'
|
||||
+ expected_strict = ('Alice', 'alice@example.org')
|
||||
+ self.assertEqual(utils.getaddresses([address]), [expected_strict])
|
||||
+ self.assertEqual(utils.getaddresses([address], strict=False), [expected_strict])
|
||||
+ self.assertEqual(utils.parseaddr([address]), expected_strict)
|
||||
+ self.assertEqual(utils.parseaddr([address], strict=False),
|
||||
+ ('', address))
|
||||
+
|
||||
+ # Invalid parenthesis in comments.
|
||||
+ address = 'alice@example.org )Alice('
|
||||
+ self.assertEqual(utils.getaddresses([address]), [empty])
|
||||
+ self.assertEqual(utils.getaddresses([address], strict=False),
|
||||
+ [('', 'alice@example.org'), ('', ''), ('', 'Alice')])
|
||||
+ self.assertEqual(utils.parseaddr([address]), empty)
|
||||
+ self.assertEqual(utils.parseaddr([address], strict=False),
|
||||
+ ('', address))
|
||||
+
|
||||
+ # Two addresses with quotes separated by comma.
|
||||
+ address = '"Jane Doe" <jane@example.net>, "John Doe" <john@example.net>'
|
||||
+ self.assertEqual(utils.getaddresses([address]),
|
||||
+ [('Jane Doe', 'jane@example.net'),
|
||||
+ ('John Doe', 'john@example.net')])
|
||||
+ self.assertEqual(utils.getaddresses([address], strict=False),
|
||||
+ [('Jane Doe', 'jane@example.net'),
|
||||
+ ('John Doe', 'john@example.net')])
|
||||
+ self.assertEqual(utils.parseaddr([address]), empty)
|
||||
+ self.assertEqual(utils.parseaddr([address], strict=False),
|
||||
+ ('', address))
|
||||
+
|
||||
+ # Test email.utils.supports_strict_parsing attribute
|
||||
+ self.assertEqual(email.utils.supports_strict_parsing, True)
|
||||
+
|
||||
def test_getaddresses_nasty(self):
|
||||
- eq = self.assertEqual
|
||||
- eq(utils.getaddresses(['foo: ;']), [('', '')])
|
||||
- eq(utils.getaddresses(
|
||||
- ['[]*-- =~$']),
|
||||
- [('', ''), ('', ''), ('', '*--')])
|
||||
- eq(utils.getaddresses(
|
||||
- ['foo: ;', '"Jason R. Mastaler" <jason@dom.ain>']),
|
||||
- [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')])
|
||||
+ for addresses, expected in (
|
||||
+ (['"Sürname, Firstname" <to@example.com>'],
|
||||
+ [('Sürname, Firstname', 'to@example.com')]),
|
||||
+
|
||||
+ (['foo: ;'],
|
||||
+ [('', '')]),
|
||||
+
|
||||
+ (['foo: ;', '"Jason R. Mastaler" <jason@dom.ain>'],
|
||||
+ [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]),
|
||||
+
|
||||
+ ([r'Pete(A nice \) chap) <pete(his account)@silly.test(his host)>'],
|
||||
+ [('Pete (A nice ) chap his account his host)', 'pete@silly.test')]),
|
||||
+
|
||||
+ (['(Empty list)(start)Undisclosed recipients :(nobody(I know))'],
|
||||
+ [('', '')]),
|
||||
+
|
||||
+ (['Mary <@machine.tld:mary@example.net>, , jdoe@test . example'],
|
||||
+ [('Mary', 'mary@example.net'), ('', ''), ('', 'jdoe@test.example')]),
|
||||
+
|
||||
+ (['John Doe <jdoe@machine(comment). example>'],
|
||||
+ [('John Doe (comment)', 'jdoe@machine.example')]),
|
||||
+
|
||||
+ (['"Mary Smith: Personal Account" <smith@home.example>'],
|
||||
+ [('Mary Smith: Personal Account', 'smith@home.example')]),
|
||||
+
|
||||
+ (['Undisclosed recipients:;'],
|
||||
+ [('', '')]),
|
||||
+
|
||||
+ ([r'<boss@nil.test>, "Giant; \"Big\" Box" <bob@example.net>'],
|
||||
+ [('', 'boss@nil.test'), ('Giant; "Big" Box', 'bob@example.net')]),
|
||||
+ ):
|
||||
+ with self.subTest(addresses=addresses):
|
||||
+ self.assertEqual(utils.getaddresses(addresses),
|
||||
+ expected)
|
||||
+ self.assertEqual(utils.getaddresses(addresses, strict=False),
|
||||
+ expected)
|
||||
+
|
||||
+ addresses = ['[]*-- =~$']
|
||||
+ self.assertEqual(utils.getaddresses(addresses),
|
||||
+ [('', '')])
|
||||
+ self.assertEqual(utils.getaddresses(addresses, strict=False),
|
||||
+ [('', ''), ('', ''), ('', '*--')])
|
||||
|
||||
def test_getaddresses_embedded_comment(self):
|
||||
"""Test proper handling of a nested comment"""
|
||||
@@ -3536,6 +3659,54 @@ def test_mime_classes_policy_argument(self):
|
||||
m = cls(*constructor, policy=email.policy.default)
|
||||
self.assertIs(m.policy, email.policy.default)
|
||||
|
||||
+ def test_iter_escaped_chars(self):
|
||||
+ self.assertEqual(list(utils._iter_escaped_chars(r'a\\b\"c\\"d')),
|
||||
+ [(0, 'a'),
|
||||
+ (2, '\\\\'),
|
||||
+ (3, 'b'),
|
||||
+ (5, '\\"'),
|
||||
+ (6, 'c'),
|
||||
+ (8, '\\\\'),
|
||||
+ (9, '"'),
|
||||
+ (10, 'd')])
|
||||
+ self.assertEqual(list(utils._iter_escaped_chars('a\\')),
|
||||
+ [(0, 'a'), (1, '\\')])
|
||||
+
|
||||
+ def test_strip_quoted_realnames(self):
|
||||
+ def check(addr, expected):
|
||||
+ self.assertEqual(utils._strip_quoted_realnames(addr), expected)
|
||||
+
|
||||
+ check('"Jane Doe" <jane@example.net>, "John Doe" <john@example.net>',
|
||||
+ ' <jane@example.net>, <john@example.net>')
|
||||
+ check(r'"Jane \"Doe\"." <jane@example.net>',
|
||||
+ ' <jane@example.net>')
|
||||
+
|
||||
+ # special cases
|
||||
+ check(r'before"name"after', 'beforeafter')
|
||||
+ check(r'before"name"', 'before')
|
||||
+ check(r'b"name"', 'b') # single char
|
||||
+ check(r'"name"after', 'after')
|
||||
+ check(r'"name"a', 'a') # single char
|
||||
+ check(r'"name"', '')
|
||||
+
|
||||
+ # no change
|
||||
+ for addr in (
|
||||
+ 'Jane Doe <jane@example.net>, John Doe <john@example.net>',
|
||||
+ 'lone " quote',
|
||||
+ ):
|
||||
+ self.assertEqual(utils._strip_quoted_realnames(addr), addr)
|
||||
+
|
||||
+
|
||||
+ def test_check_parenthesis(self):
|
||||
+ addr = 'alice@example.net'
|
||||
+ self.assertTrue(utils._check_parenthesis(f'{addr} (Alice)'))
|
||||
+ self.assertFalse(utils._check_parenthesis(f'{addr} )Alice('))
|
||||
+ self.assertFalse(utils._check_parenthesis(f'{addr} (Alice))'))
|
||||
+ self.assertFalse(utils._check_parenthesis(f'{addr} ((Alice)'))
|
||||
+
|
||||
+ # Ignore real name between quotes
|
||||
+ self.assertTrue(utils._check_parenthesis(f'")Alice((" {addr}'))
|
||||
+
|
||||
|
||||
# Test the iterator/generators
|
||||
class TestIterators(TestEmailBase):
|
||||
diff --git a/Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst b/Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst
|
||||
new file mode 100644
|
||||
index 0000000000..3d0e9e4078
|
||||
--- /dev/null
|
||||
+++ b/Misc/NEWS.d/next/Library/2023-10-20-15-28-08.gh-issue-102988.dStNO7.rst
|
||||
@@ -0,0 +1,8 @@
|
||||
+:func:`email.utils.getaddresses` and :func:`email.utils.parseaddr` now
|
||||
+return ``('', '')`` 2-tuples in more situations where invalid email
|
||||
+addresses are encountered instead of potentially inaccurate values. Add
|
||||
+optional *strict* parameter to these two functions: use ``strict=False`` to
|
||||
+get the old behavior, accept malformed inputs.
|
||||
+``getattr(email.utils, 'supports_strict_parsing', False)`` can be use to check
|
||||
+if the *strict* paramater is available. Patch by Thomas Dwyer and Victor
|
||||
+Stinner to improve the CVE-2023-27043 fix.
|
|
@ -0,0 +1,36 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Karolina Surma <ksurma@redhat.com>
|
||||
Date: Thu, 8 Feb 2024 15:53:26 +0100
|
||||
Subject: [PATCH] 00418: Don't generate sbom in make regen-all
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The script and make target, added in Python 3.12.2, assumes a fixed
|
||||
location of pip wheel and other bundled libraries, resulting in an
|
||||
error and failed build when not found.
|
||||
Reported upstream: https://github.com/python/cpython/issues/114240
|
||||
and https://github.com/python/cpython/issues/114244
|
||||
|
||||
Co-Authored-By: Tomáš Hrnčiar <thrnciar@redhat.com>
|
||||
---
|
||||
Makefile.pre.in | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Makefile.pre.in b/Makefile.pre.in
|
||||
index dd5e69f7ab..40097647b5 100644
|
||||
--- a/Makefile.pre.in
|
||||
+++ b/Makefile.pre.in
|
||||
@@ -1320,9 +1320,10 @@ regen-limited-abi: all
|
||||
regen-all: regen-cases regen-opcode regen-opcode-targets regen-typeslots \
|
||||
regen-token regen-ast regen-keyword regen-sre regen-frozen \
|
||||
regen-pegen-metaparser regen-pegen regen-test-frozenmain \
|
||||
- regen-test-levenshtein regen-global-objects regen-sbom
|
||||
+ regen-test-levenshtein regen-global-objects
|
||||
@echo
|
||||
- @echo "Note: make regen-stdlib-module-names and make regen-configure should be run manually"
|
||||
+ @echo "Note: make regen-stdlib-module-names, make regen-configure and make regen-sbom "
|
||||
+ @echo "should be run manually"
|
||||
|
||||
############################################################################
|
||||
# Special rules for object files
|
|
@ -16,9 +16,11 @@ LEVELS = (None, 1, 2)
|
|||
# list of globs of test and other files that we expect not to have bytecode
|
||||
not_compiled = [
|
||||
'/usr/bin/*',
|
||||
'*/test/bad_coding.py',
|
||||
'*/test/bad_coding2.py',
|
||||
'*/test/badsyntax_*.py',
|
||||
'*/tokenizedata/bad_coding.py',
|
||||
'*/tokenizedata/bad_coding2.py',
|
||||
'*/tokenizedata/badsyntax_*.py',
|
||||
'*/test_future_stmt/badsyntax_*.py',
|
||||
'*/test_lib2to3/data/*.py',
|
||||
'*/test_lib2to3/data/*/*.py',
|
||||
'*/test_lib2to3/data/*/*/*.py',
|
||||
|
|
163
python3.12.spec
163
python3.12.spec
|
@ -13,11 +13,11 @@ URL: https://www.python.org/
|
|||
|
||||
# WARNING When rebasing to a new Python version,
|
||||
# remember to update the python3-docs package as well
|
||||
%global general_version %{pybasever}.0
|
||||
%global prerel b2
|
||||
%global general_version %{pybasever}.2
|
||||
#global prerel ...
|
||||
%global upstream_version %{general_version}%{?prerel}
|
||||
Version: %{general_version}%{?prerel:~%{prerel}}
|
||||
Release: 3%{?dist}
|
||||
Release: 1.0.riscv64%{?dist}
|
||||
License: Python-2.0.1
|
||||
|
||||
|
||||
|
@ -71,35 +71,36 @@ License: Python-2.0.1
|
|||
# If the rpmwheels condition is disabled, we use the bundled wheel packages
|
||||
# from Python with the versions below.
|
||||
# This needs to be manually updated when we update Python.
|
||||
%global pip_version 23.1.2
|
||||
%global pip_version 24.0
|
||||
%global setuptools_version 67.6.1
|
||||
%global wheel_version 0.40.0
|
||||
# All of those also include a list of indirect bundled libs:
|
||||
# pip
|
||||
# $ %%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/ensurepip/_bundled/pip-*.whl pip/_vendor/vendor.txt)
|
||||
%global pip_bundled_provides %{expand:
|
||||
Provides: bundled(python3dist(cachecontrol)) = 0.12.11
|
||||
Provides: bundled(python3dist(certifi)) = 2022.12.7
|
||||
Provides: bundled(python3dist(cachecontrol)) = 0.13.1
|
||||
Provides: bundled(python3dist(certifi)) = 2023.7.22
|
||||
Provides: bundled(python3dist(chardet)) = 5.1
|
||||
Provides: bundled(python3dist(colorama)) = 0.4.6
|
||||
Provides: bundled(python3dist(distlib)) = 0.3.6
|
||||
Provides: bundled(python3dist(distlib)) = 0.3.8
|
||||
Provides: bundled(python3dist(distro)) = 1.8
|
||||
Provides: bundled(python3dist(idna)) = 3.4
|
||||
Provides: bundled(python3dist(msgpack)) = 1.0.5
|
||||
Provides: bundled(python3dist(packaging)) = 21.3
|
||||
Provides: bundled(python3dist(platformdirs)) = 3.2
|
||||
Provides: bundled(python3dist(pygments)) = 2.14
|
||||
Provides: bundled(python3dist(pyparsing)) = 3.0.9
|
||||
Provides: bundled(python3dist(platformdirs)) = 3.8.1
|
||||
Provides: bundled(python3dist(pygments)) = 2.15.1
|
||||
Provides: bundled(python3dist(pyparsing)) = 3.1
|
||||
Provides: bundled(python3dist(pyproject-hooks)) = 1
|
||||
Provides: bundled(python3dist(requests)) = 2.28.2
|
||||
Provides: bundled(python3dist(requests)) = 2.31
|
||||
Provides: bundled(python3dist(resolvelib)) = 1.0.1
|
||||
Provides: bundled(python3dist(rich)) = 13.3.3
|
||||
Provides: bundled(python3dist(setuptools)) = 67.7.2
|
||||
Provides: bundled(python3dist(rich)) = 13.4.2
|
||||
Provides: bundled(python3dist(setuptools)) = 68
|
||||
Provides: bundled(python3dist(six)) = 1.16
|
||||
Provides: bundled(python3dist(tenacity)) = 8.2.2
|
||||
Provides: bundled(python3dist(tomli)) = 2.0.1
|
||||
Provides: bundled(python3dist(typing-extensions)) = 4.5
|
||||
Provides: bundled(python3dist(urllib3)) = 1.26.15
|
||||
Provides: bundled(python3dist(truststore)) = 0.8
|
||||
Provides: bundled(python3dist(typing-extensions)) = 4.7.1
|
||||
Provides: bundled(python3dist(urllib3)) = 1.26.17
|
||||
Provides: bundled(python3dist(webencodings)) = 0.5.1
|
||||
}
|
||||
# setuptools
|
||||
|
@ -121,7 +122,7 @@ Provides: bundled(python3dist(typing-extensions)) = 4.4
|
|||
Provides: bundled(python3dist(zipp)) = 3.7
|
||||
}
|
||||
# wheel
|
||||
# $ %%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/test/wheel-*.whl wheel/vendored/vendor.txt)
|
||||
# $ %%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/test/wheeldata/wheel-*.whl wheel/vendored/vendor.txt)
|
||||
%global wheel_bundled_provides %{expand:
|
||||
Provides: bundled(python3dist(packaging)) = 23
|
||||
}
|
||||
|
@ -255,7 +256,9 @@ BuildRequires: glibc-devel
|
|||
BuildRequires: gmp-devel
|
||||
BuildRequires: gnupg2
|
||||
BuildRequires: libappstream-glib
|
||||
%if %{undefined rhel}
|
||||
BuildRequires: libb2-devel
|
||||
%endif
|
||||
BuildRequires: libffi-devel
|
||||
BuildRequires: libnsl2-devel
|
||||
BuildRequires: libtirpc-devel
|
||||
|
@ -308,6 +311,9 @@ BuildRequires: %{python_wheel_pkg_prefix}-wheel-wheel
|
|||
# upgrading the main python3 to a new Python version, this would pull in the
|
||||
# old version instead.
|
||||
BuildRequires: python%{pybasever}
|
||||
%endif
|
||||
|
||||
%if %{without bootstrap} || %{without main_python}
|
||||
# for proper automatic provides
|
||||
BuildRequires: python3-rpm-generators
|
||||
%endif
|
||||
|
@ -362,11 +368,24 @@ Patch251: 00251-change-user-install-location.patch
|
|||
# https://github.com/GrahamDumpleton/mod_wsgi/issues/730
|
||||
Patch371: 00371-revert-bpo-1596321-fix-threading-_shutdown-for-the-main-thread-gh-28549-gh-28589.patch
|
||||
|
||||
# 00401 # 48310af24b090719553bf0e9c965d80524e0b40e
|
||||
# Tests: Use setuptools+wheel from sysconfig.get_config_var('WHEEL_PKG_DIR') if set
|
||||
# 00415 # 5b830b814be638d1a167802780b5f498a4a5e97c
|
||||
# [CVE-2023-27043] gh-102988: Reject malformed addresses in email.parseaddr() (#111116)
|
||||
#
|
||||
# Proposed upstream https://github.com/python/cpython/pull/105056
|
||||
Patch401: 00401-tests-use-setuptools-wheel-from-sysconfig-get_config_var-wheel_pkg_dir-if-set.patch
|
||||
# Detect email address parsing errors and return empty tuple to
|
||||
# indicate the parsing error (old API). Add an optional 'strict'
|
||||
# parameter to getaddresses() and parseaddr() functions. Patch by
|
||||
# Thomas Dwyer.
|
||||
Patch415: 00415-cve-2023-27043-gh-102988-reject-malformed-addresses-in-email-parseaddr-111116.patch
|
||||
|
||||
# 00418 # 153905265371131e1227ace0dfef34a5c5efde59
|
||||
# Don't generate sbom in make regen-all
|
||||
#
|
||||
# The script and make target, added in Python 3.12.2, assumes a fixed
|
||||
# location of pip wheel and other bundled libraries, resulting in an
|
||||
# error and failed build when not found.
|
||||
# Reported upstream: https://github.com/python/cpython/issues/114240
|
||||
# and https://github.com/python/cpython/issues/114244
|
||||
Patch418: 00418-don-t-generate-sbom-in-make-regen-all.patch
|
||||
|
||||
# (New patches go here ^^^)
|
||||
#
|
||||
|
@ -490,15 +509,21 @@ Summary: Python runtime libraries
|
|||
|
||||
%if %{with rpmwheels}
|
||||
Requires: %{python_wheel_pkg_prefix}-pip-wheel >= 23.1.2
|
||||
# Bundled libb2 is CC0, covered by grandfathering exception
|
||||
License: Python-2.0.1 AND CC0-1.0
|
||||
%else
|
||||
Provides: bundled(python3dist(pip)) = %{pip_version}
|
||||
%pip_bundled_provides
|
||||
# License manually combined form Python + pip
|
||||
License: Python-2.0.1 AND MIT AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND LGPL-2.1-only AND MPL-2.0 AND (Apache-2.0 OR BSD-2-Clause)
|
||||
License: Python-2.0.1 AND CC0-1.0 AND MIT AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND LGPL-2.1-only AND MPL-2.0 AND (Apache-2.0 OR BSD-2-Clause)
|
||||
%endif
|
||||
|
||||
%unversioned_obsoletes_of_python3_X_if_main libs
|
||||
|
||||
# Bundled internal headers are used even when building with system libb2
|
||||
# last updated by https://github.com/python/cpython/pull/6286
|
||||
Provides: bundled(libb2) = 0.98.1
|
||||
|
||||
# There are files in the standard library that have python shebang.
|
||||
# We've filtered the automatic requirement out so libs are installable without
|
||||
# the main package. This however makes it pulled in by default.
|
||||
|
@ -544,7 +569,8 @@ Recommends: %{pkgname}-pip
|
|||
# tox users are likely to need the devel subpackage
|
||||
Supplements: tox
|
||||
|
||||
%if %{without bootstrap}
|
||||
%if %{without bootstrap} || %{without main_python}
|
||||
# Generators run on the main Python 3 so we cannot require them when bootstrapping it
|
||||
Requires: (python3-rpm-generators if rpm-build)
|
||||
%endif
|
||||
|
||||
|
@ -682,13 +708,13 @@ The debug runtime additionally supports debug builds of C-API extensions
|
|||
# setuptools.whl does not contain the vendored.txt files
|
||||
if [ -f %{_rpmconfigdir}/pythonbundles.py ]; then
|
||||
%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/ensurepip/_bundled/pip-*.whl pip/_vendor/vendor.txt) --compare-with '%pip_bundled_provides'
|
||||
%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/test/wheel-*.whl wheel/vendored/vendor.txt) --compare-with '%wheel_bundled_provides'
|
||||
%{_rpmconfigdir}/pythonbundles.py <(unzip -p Lib/test/wheeldata/wheel-*.whl wheel/vendored/vendor.txt) --compare-with '%wheel_bundled_provides'
|
||||
fi
|
||||
|
||||
%if %{with rpmwheels}
|
||||
rm Lib/ensurepip/_bundled/pip-%{pip_version}-py3-none-any.whl
|
||||
rm Lib/test/setuptools-%{setuptools_version}-py3-none-any.whl
|
||||
rm Lib/test/wheel-%{wheel_version}-py3-none-any.whl
|
||||
rm Lib/test/wheeldata/setuptools-%{setuptools_version}-py3-none-any.whl
|
||||
rm Lib/test/wheeldata/wheel-%{wheel_version}-py3-none-any.whl
|
||||
%endif
|
||||
|
||||
# Remove all exe files to ensure we are not shipping prebuilt binaries
|
||||
|
@ -745,14 +771,15 @@ topdir=$(pwd)
|
|||
# Standard library built here will still use the %%build_...flags,
|
||||
# Fedora packages utilizing %%py3_build will use them as well
|
||||
# https://fedoraproject.org/wiki/Changes/Python_Extension_Flags
|
||||
export CFLAGS="%{extension_cflags} -D_GNU_SOURCE -fPIC -fwrapv"
|
||||
# https://fedoraproject.org/wiki/Changes/Python_Extension_Flags_Reduction
|
||||
export CFLAGS="%{extension_cflags}"
|
||||
export CFLAGS_NODIST="%{build_cflags} -D_GNU_SOURCE -fPIC -fwrapv"
|
||||
export CXXFLAGS="%{extension_cxxflags} -D_GNU_SOURCE -fPIC -fwrapv"
|
||||
export CXXFLAGS="%{extension_cxxflags}"
|
||||
export CPPFLAGS="$(pkg-config --cflags-only-I libffi)"
|
||||
export OPT="%{extension_cflags} -D_GNU_SOURCE -fPIC -fwrapv"
|
||||
export OPT="%{extension_cflags}"
|
||||
export LINKCC="gcc"
|
||||
export CFLAGS="$CFLAGS $(pkg-config --cflags openssl)"
|
||||
export LDFLAGS="%{extension_ldflags} -g $(pkg-config --libs-only-L openssl)"
|
||||
export LDFLAGS="%{extension_ldflags} $(pkg-config --libs-only-L openssl)"
|
||||
export LDFLAGS_NODIST="%{build_ldflags} -g $(pkg-config --libs-only-L openssl)"
|
||||
|
||||
# We can build several different configurations of Python: regular and debug.
|
||||
|
@ -1145,10 +1172,23 @@ CheckPython() {
|
|||
# test_freeze_simple_script is skipped, because it fails without bundled libs.
|
||||
# the freeze tool is only usable from the source checkout anyway,
|
||||
# we don't ship it in the RPM package.
|
||||
# test_check_probes is failing since it was introduced in 3.12.0rc1,
|
||||
# the test is skipped until it is fixed in upstream.
|
||||
# see: https://github.com/python/cpython/issues/104280#issuecomment-1669249980
|
||||
|
||||
LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test.regrtest \
|
||||
-wW --slowest %{_smp_mflags} --timeout=2700 \
|
||||
-wW --slowest %{_smp_mflags} \
|
||||
%ifnarch riscv64
|
||||
--timeout=2700 \
|
||||
%else
|
||||
--timeout=27000 \
|
||||
%endif
|
||||
-i test_freeze_simple_script \
|
||||
-i test_check_probes \
|
||||
%ifarch riscv64
|
||||
-x test_eintr \
|
||||
-x test_peg_generator \
|
||||
%endif
|
||||
%ifarch %{mips64}
|
||||
-x test_ctypes \
|
||||
%endif
|
||||
|
@ -1381,6 +1421,7 @@ CheckPython optimized
|
|||
%{pylibdir}/multiprocessing
|
||||
|
||||
%dir %{pylibdir}/re/
|
||||
%dir %{pylibdir}/re/__pycache__/
|
||||
%{pylibdir}/re/*.py
|
||||
%{pylibdir}/re/__pycache__/*%{bytecode_suffixes}
|
||||
|
||||
|
@ -1390,6 +1431,7 @@ CheckPython optimized
|
|||
%{pylibdir}/sqlite3/__pycache__/*%{bytecode_suffixes}
|
||||
|
||||
%dir %{pylibdir}/tomllib/
|
||||
%dir %{pylibdir}/tomllib/__pycache__/
|
||||
%{pylibdir}/tomllib/*.py
|
||||
%{pylibdir}/tomllib/__pycache__/*%{bytecode_suffixes}
|
||||
%exclude %{pylibdir}/turtle.py
|
||||
|
@ -1399,12 +1441,18 @@ CheckPython optimized
|
|||
%{pylibdir}/xml
|
||||
|
||||
%dir %{pylibdir}/zipfile/
|
||||
%dir %{pylibdir}/zipfile/__pycache__/
|
||||
%{pylibdir}/zipfile/*.py
|
||||
%{pylibdir}/zipfile/__pycache__/*%{bytecode_suffixes}
|
||||
%dir %{pylibdir}/zipfile/_path/
|
||||
%dir %{pylibdir}/zipfile/_path/__pycache__/
|
||||
%{pylibdir}/zipfile/_path/*.py
|
||||
%{pylibdir}/zipfile/_path/__pycache__/*%{bytecode_suffixes}
|
||||
|
||||
%{pylibdir}/zoneinfo
|
||||
|
||||
%dir %{pylibdir}/__phello__
|
||||
%dir %{pylibdir}/__phello__/
|
||||
%dir %{pylibdir}/__phello__/__pycache__/
|
||||
%{pylibdir}/__phello__/__init__.py
|
||||
%{pylibdir}/__phello__/spam.py
|
||||
%{pylibdir}/__phello__/__pycache__/*%{bytecode_suffixes}
|
||||
|
@ -1657,6 +1705,59 @@ CheckPython optimized
|
|||
# ======================================================
|
||||
|
||||
%changelog
|
||||
* Wed Feb 21 2024 David Abdurachmanov <davidlt@rivosinc.com> - 3.12.2-2.3.riscv64
|
||||
- Disable test_peg_generator test on riscv64.
|
||||
- Increase tests timeout on riscv64 by 10x.
|
||||
- Disable test_eintr test on riscv64.
|
||||
|
||||
* Wed Feb 07 2024 Tomáš Hrnčiar <thrnciar@redhat.com> - 3.12.2-1
|
||||
- Update to 3.12.2
|
||||
|
||||
* Fri Jan 26 2024 Fedora Release Engineering <releng@fedoraproject.org> - 3.12.1-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
|
||||
|
||||
* Mon Jan 22 2024 Fedora Release Engineering <releng@fedoraproject.org> - 3.12.1-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
|
||||
|
||||
* Mon Dec 18 2023 Lumír Balhar <lbalhar@redhat.com> - 3.12.1-2
|
||||
- Security fix for CVE-2023-27043 (rhbz#2196190)
|
||||
|
||||
* Fri Dec 08 2023 Tomáš Hrnčiar <thrnciar@redhat.com> - 3.12.1-1
|
||||
- Update to 3.12.1
|
||||
- Own stray directories in /usr/lib64/python3.12
|
||||
- Fixes: rhbz#2252143
|
||||
|
||||
* Thu Oct 05 2023 Yaakov Selkowitz <yselkowi@redhat.com> - 3.12.0-2
|
||||
- Use bundled libb2 in RHEL builds
|
||||
|
||||
* Mon Oct 02 2023 Miro Hrončok <mhroncok@redhat.com> - 3.12.0-1
|
||||
- Update to 3.12.0 final
|
||||
|
||||
* Tue Sep 19 2023 Miro Hrončok <mhroncok@redhat.com> - 3.12.0~rc3-1
|
||||
- Update to 3.12.0rc3
|
||||
|
||||
* Wed Sep 06 2023 Tomáš Hrnčiar <thrnciar@redhat.com> - 3.12.0~rc2-1
|
||||
- Update to 3.12.0rc2
|
||||
|
||||
* Mon Aug 07 2023 Tomáš Hrnčiar <thrnciar@redhat.com> - 3.12.0~rc1-1
|
||||
- Update to 3.12.0rc1
|
||||
|
||||
* Wed Aug 02 2023 Charalampos Stratakis <cstratak@redhat.com> - 3.12.0~b4-3
|
||||
- Remove extra distro-applied CFLAGS passed to user built C extensions
|
||||
- https://fedoraproject.org/wiki/Changes/Python_Extension_Flags_Reduction
|
||||
|
||||
* Fri Jul 21 2023 Fedora Release Engineering <releng@fedoraproject.org> - 3.12.0~b4-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
|
||||
|
||||
* Wed Jul 12 2023 Miro Hrončok <mhroncok@redhat.com> - 3.12.0~b4-1
|
||||
- Update to 3.12.0b4
|
||||
|
||||
* Wed Jun 21 2023 Tomáš Hrnčiar <thrnciar@redhat.com> - 3.12.0~b3-2
|
||||
- Backport upstream patch to add PyType_GetDict() function
|
||||
|
||||
* Tue Jun 20 2023 Tomáš Hrnčiar <thrnciar@redhat.com> - 3.12.0~b3-1
|
||||
- Update to 3.12.0b3
|
||||
|
||||
* Tue Jun 13 2023 Python Maint <python-maint@redhat.com> - 3.12.0~b2-3
|
||||
- Rebuilt for Python 3.12
|
||||
|
||||
|
|
4
sources
4
sources
|
@ -1,2 +1,2 @@
|
|||
SHA512 (Python-3.12.0b2.tar.xz) = 9bfac70f2ccc1f6798bc63a55d92f0b162e3a9077624a2e37448002ea310cb7b1da64ad2aceda795b45de91f60eb4d95dde85984900e54906d814625b42143b5
|
||||
SHA512 (Python-3.12.0b2.tar.xz.asc) = 22a1f2c3335bc428cfee0ce2e081aeed24474d3cd877fac1cc4cf92b4a2bee70f85aed0068a71600cddef9c8b46bbde257a92c57bd494ad820c0686ab7c8c0f0
|
||||
SHA512 (Python-3.12.2.tar.xz) = 2ccfae7b9f95d8e15ea85d3f66eea5f6a8fdcaffc0b405095fecb33efc0df50b831c1215542910ced948b54e6de1f7242b0b8b9afc5f89079451c552430d7d9f
|
||||
SHA512 (Python-3.12.2.tar.xz.asc) = fb477acb49864a662b1586db79e80fd8ebab85d4e5e14acd3bfb5afc3dbe8d6b9bf97eb518dfb77662e27040d400f451ed7575fe1264a6cc0d9feb06e4f2dc84
|
||||
|
|
|
@ -21,19 +21,19 @@
|
|||
run: rpm -qa
|
||||
- smoke:
|
||||
dir: python/smoke
|
||||
run: "VERSION={{ pybasever }} CYTHON=false ./venv.sh"
|
||||
run: "VERSION={{ pybasever }} ./venv.sh"
|
||||
- smoke_virtualenv:
|
||||
dir: python/smoke
|
||||
run: "VERSION={{ pybasever }} METHOD=virtualenv CYTHON=false ./venv.sh"
|
||||
run: "VERSION={{ pybasever }} METHOD=virtualenv ./venv.sh"
|
||||
- debugsmoke:
|
||||
dir: python/smoke
|
||||
run: "PYTHON=python{{ pybasever }}d TOX=false VERSION={{ pybasever }} CYTHON=false ./venv.sh"
|
||||
run: "PYTHON=python{{ pybasever }}d TOX=false VERSION={{ pybasever }} ./venv.sh"
|
||||
- selftest:
|
||||
dir: python/selftest
|
||||
run: "VERSION={{ pybasever }} X='' ./parallel.sh"
|
||||
run: "VERSION={{ pybasever }} X='-i test_check_probes' ./parallel.sh"
|
||||
- debugtest:
|
||||
dir: python/selftest
|
||||
run: "VERSION={{ pybasever }} PYTHON=python{{ pybasever }}d X='' ./parallel.sh"
|
||||
run: "VERSION={{ pybasever }} PYTHON=python{{ pybasever }}d X='-i test_check_probes' ./parallel.sh"
|
||||
- debugflags:
|
||||
dir: python/flags
|
||||
run: "python{{ pybasever }}d ./assertflags.py -O0"
|
||||
|
|
Loading…
Reference in New Issue