- Update list of skipped tests in qemu linux-user emulation
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:Factory/python313?expand=0&rev=38
This commit is contained in:
commit
b97ac57404
23
.gitattributes
vendored
Normal file
23
.gitattributes
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
## Default LFS
|
||||||
|
*.7z filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.bsp filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.gem filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.gz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.jar filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.lz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.lzma filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.obscpio filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.oxt filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.rpm filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tbz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tbz2 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tgz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.txz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.whl filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.xz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.zst filter=lfs diff=lfs merge=lfs -text
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.osc
|
361
CVE-2024-6923-email-hdr-inject.patch
Normal file
361
CVE-2024-6923-email-hdr-inject.patch
Normal file
@ -0,0 +1,361 @@
|
|||||||
|
From a590277e980eaa8a08204b79ed6c62a763701c8b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Petr Viktorin <encukou@gmail.com>
|
||||||
|
Date: Wed, 31 Jul 2024 00:19:48 +0200
|
||||||
|
Subject: [PATCH] gh-121650: Encode newlines in headers, and verify headers are
|
||||||
|
sound (GH-122233)
|
||||||
|
|
||||||
|
GH-GH- Encode header parts that contain newlines
|
||||||
|
|
||||||
|
Per RFC 2047:
|
||||||
|
|
||||||
|
> [...] these encoding schemes allow the
|
||||||
|
> encoding of arbitrary octet values, mail readers that implement this
|
||||||
|
> decoding should also ensure that display of the decoded data on the
|
||||||
|
> recipient's terminal will not cause unwanted side-effects
|
||||||
|
|
||||||
|
It seems that the "quoted-word" scheme is a valid way to include
|
||||||
|
a newline character in a header value, just like we already allow
|
||||||
|
undecodable bytes or control characters.
|
||||||
|
They do need to be properly quoted when serialized to text, though.
|
||||||
|
|
||||||
|
GH-GH- Verify that email headers are well-formed
|
||||||
|
|
||||||
|
This should fail for custom fold() implementations that aren't careful
|
||||||
|
about newlines.
|
||||||
|
|
||||||
|
(cherry picked from commit 097633981879b3c9de9a1dd120d3aa585ecc2384)
|
||||||
|
|
||||||
|
Co-authored-by: Petr Viktorin <encukou@gmail.com>
|
||||||
|
Co-authored-by: Bas Bloemsaat <bas@bloemsaat.org>
|
||||||
|
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
|
||||||
|
---
|
||||||
|
Doc/library/email.errors.rst | 7 +++
|
||||||
|
Doc/library/email.policy.rst | 18 ++++++
|
||||||
|
Doc/whatsnew/3.13.rst | 9 +++
|
||||||
|
Lib/email/_header_value_parser.py | 12 +++-
|
||||||
|
Lib/email/_policybase.py | 8 +++
|
||||||
|
Lib/email/errors.py | 4 ++
|
||||||
|
Lib/email/generator.py | 13 +++-
|
||||||
|
Lib/test/test_email/test_generator.py | 62 +++++++++++++++++++
|
||||||
|
Lib/test/test_email/test_policy.py | 26 ++++++++
|
||||||
|
...-07-27-16-10-41.gh-issue-121650.nf6oc9.rst | 5 ++
|
||||||
|
10 files changed, 160 insertions(+), 4 deletions(-)
|
||||||
|
create mode 100644 Misc/NEWS.d/next/Library/2024-07-27-16-10-41.gh-issue-121650.nf6oc9.rst
|
||||||
|
|
||||||
|
diff --git a/Doc/library/email.errors.rst b/Doc/library/email.errors.rst
|
||||||
|
index 33ab4265116178..f8f43d82a3df2e 100644
|
||||||
|
--- a/Doc/library/email.errors.rst
|
||||||
|
+++ b/Doc/library/email.errors.rst
|
||||||
|
@@ -58,6 +58,13 @@ The following exception classes are defined in the :mod:`email.errors` module:
|
||||||
|
:class:`~email.mime.nonmultipart.MIMENonMultipart` (e.g.
|
||||||
|
:class:`~email.mime.image.MIMEImage`).
|
||||||
|
|
||||||
|
+
|
||||||
|
+.. exception:: HeaderWriteError()
|
||||||
|
+
|
||||||
|
+ Raised when an error occurs when the :mod:`~email.generator` outputs
|
||||||
|
+ headers.
|
||||||
|
+
|
||||||
|
+
|
||||||
|
.. exception:: MessageDefect()
|
||||||
|
|
||||||
|
This is the base class for all defects found when parsing email messages.
|
||||||
|
diff --git a/Doc/library/email.policy.rst b/Doc/library/email.policy.rst
|
||||||
|
index 83feedf728351e..314767d0802a08 100644
|
||||||
|
--- a/Doc/library/email.policy.rst
|
||||||
|
+++ b/Doc/library/email.policy.rst
|
||||||
|
@@ -229,6 +229,24 @@ added matters. To illustrate::
|
||||||
|
|
||||||
|
.. versionadded:: 3.6
|
||||||
|
|
||||||
|
+
|
||||||
|
+ .. attribute:: verify_generated_headers
|
||||||
|
+
|
||||||
|
+ If ``True`` (the default), the generator will raise
|
||||||
|
+ :exc:`~email.errors.HeaderWriteError` instead of writing a header
|
||||||
|
+ that is improperly folded or delimited, such that it would
|
||||||
|
+ be parsed as multiple headers or joined with adjacent data.
|
||||||
|
+ Such headers can be generated by custom header classes or bugs
|
||||||
|
+ in the ``email`` module.
|
||||||
|
+
|
||||||
|
+ As it's a security feature, this defaults to ``True`` even in the
|
||||||
|
+ :class:`~email.policy.Compat32` policy.
|
||||||
|
+ For backwards compatible, but unsafe, behavior, it must be set to
|
||||||
|
+ ``False`` explicitly.
|
||||||
|
+
|
||||||
|
+ .. versionadded:: 3.13
|
||||||
|
+
|
||||||
|
+
|
||||||
|
The following :class:`Policy` method is intended to be called by code using
|
||||||
|
the email library to create policy instances with custom settings:
|
||||||
|
|
||||||
|
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
|
||||||
|
index b53f419a59f062..35b808a4dd00a4 100644
|
||||||
|
--- a/Doc/whatsnew/3.13.rst
|
||||||
|
+++ b/Doc/whatsnew/3.13.rst
|
||||||
|
@@ -724,6 +724,15 @@ doctest
|
||||||
|
email
|
||||||
|
-----
|
||||||
|
|
||||||
|
+* Headers with embedded newlines are now quoted on output.
|
||||||
|
+
|
||||||
|
+ The :mod:`~email.generator` will now refuse to serialize (write) headers
|
||||||
|
+ that are improperly folded or delimited, such that they would be parsed as
|
||||||
|
+ multiple headers or joined with adjacent data.
|
||||||
|
+ If you need to turn this safety feature off,
|
||||||
|
+ set :attr:`~email.policy.Policy.verify_generated_headers`.
|
||||||
|
+ (Contributed by Bas Bloemsaat and Petr Viktorin in :gh:`121650`.)
|
||||||
|
+
|
||||||
|
* :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*
|
||||||
|
diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py
|
||||||
|
index 7da1bbaf8a80d7..ec2215a5e5f33c 100644
|
||||||
|
--- a/Lib/email/_header_value_parser.py
|
||||||
|
+++ b/Lib/email/_header_value_parser.py
|
||||||
|
@@ -92,6 +92,8 @@
|
||||||
|
ASPECIALS = TSPECIALS | set("*'%")
|
||||||
|
ATTRIBUTE_ENDS = ASPECIALS | WSP
|
||||||
|
EXTENDED_ATTRIBUTE_ENDS = ATTRIBUTE_ENDS - set('%')
|
||||||
|
+NLSET = {'\n', '\r'}
|
||||||
|
+SPECIALSNL = SPECIALS | NLSET
|
||||||
|
|
||||||
|
def quote_string(value):
|
||||||
|
return '"'+str(value).replace('\\', '\\\\').replace('"', r'\"')+'"'
|
||||||
|
@@ -2802,9 +2804,13 @@ def _refold_parse_tree(parse_tree, *, policy):
|
||||||
|
wrap_as_ew_blocked -= 1
|
||||||
|
continue
|
||||||
|
tstr = str(part)
|
||||||
|
- if part.token_type == 'ptext' and set(tstr) & SPECIALS:
|
||||||
|
- # Encode if tstr contains special characters.
|
||||||
|
- want_encoding = True
|
||||||
|
+ if not want_encoding:
|
||||||
|
+ if part.token_type == 'ptext':
|
||||||
|
+ # Encode if tstr contains special characters.
|
||||||
|
+ want_encoding = not SPECIALSNL.isdisjoint(tstr)
|
||||||
|
+ else:
|
||||||
|
+ # Encode if tstr contains newlines.
|
||||||
|
+ want_encoding = not NLSET.isdisjoint(tstr)
|
||||||
|
try:
|
||||||
|
tstr.encode(encoding)
|
||||||
|
charset = encoding
|
||||||
|
diff --git a/Lib/email/_policybase.py b/Lib/email/_policybase.py
|
||||||
|
index 2ec54fbabae83c..5f9aa9fb091fa2 100644
|
||||||
|
--- a/Lib/email/_policybase.py
|
||||||
|
+++ b/Lib/email/_policybase.py
|
||||||
|
@@ -157,6 +157,13 @@ class Policy(_PolicyBase, metaclass=abc.ABCMeta):
|
||||||
|
message_factory -- the class to use to create new message objects.
|
||||||
|
If the value is None, the default is Message.
|
||||||
|
|
||||||
|
+ verify_generated_headers
|
||||||
|
+ -- if true, the generator verifies that each header
|
||||||
|
+ they are properly folded, so that a parser won't
|
||||||
|
+ treat it as multiple headers, start-of-body, or
|
||||||
|
+ part of another header.
|
||||||
|
+ This is a check against custom Header & fold()
|
||||||
|
+ implementations.
|
||||||
|
"""
|
||||||
|
|
||||||
|
raise_on_defect = False
|
||||||
|
@@ -165,6 +172,7 @@ class Policy(_PolicyBase, metaclass=abc.ABCMeta):
|
||||||
|
max_line_length = 78
|
||||||
|
mangle_from_ = False
|
||||||
|
message_factory = None
|
||||||
|
+ verify_generated_headers = True
|
||||||
|
|
||||||
|
def handle_defect(self, obj, defect):
|
||||||
|
"""Based on policy, either raise defect or call register_defect.
|
||||||
|
diff --git a/Lib/email/errors.py b/Lib/email/errors.py
|
||||||
|
index 3ad00565549968..02aa5eced6ae46 100644
|
||||||
|
--- a/Lib/email/errors.py
|
||||||
|
+++ b/Lib/email/errors.py
|
||||||
|
@@ -29,6 +29,10 @@ class CharsetError(MessageError):
|
||||||
|
"""An illegal charset was given."""
|
||||||
|
|
||||||
|
|
||||||
|
+class HeaderWriteError(MessageError):
|
||||||
|
+ """Error while writing headers."""
|
||||||
|
+
|
||||||
|
+
|
||||||
|
# These are parsing defects which the parser was able to work around.
|
||||||
|
class MessageDefect(ValueError):
|
||||||
|
"""Base class for a message defect."""
|
||||||
|
diff --git a/Lib/email/generator.py b/Lib/email/generator.py
|
||||||
|
index c8056ad47baa0f..47b9df8f4e6090 100644
|
||||||
|
--- a/Lib/email/generator.py
|
||||||
|
+++ b/Lib/email/generator.py
|
||||||
|
@@ -14,12 +14,14 @@
|
||||||
|
from copy import deepcopy
|
||||||
|
from io import StringIO, BytesIO
|
||||||
|
from email.utils import _has_surrogates
|
||||||
|
+from email.errors import HeaderWriteError
|
||||||
|
|
||||||
|
UNDERSCORE = '_'
|
||||||
|
NL = '\n' # XXX: no longer used by the code below.
|
||||||
|
|
||||||
|
NLCRE = re.compile(r'\r\n|\r|\n')
|
||||||
|
fcre = re.compile(r'^From ', re.MULTILINE)
|
||||||
|
+NEWLINE_WITHOUT_FWSP = re.compile(r'\r\n[^ \t]|\r[^ \n\t]|\n[^ \t]')
|
||||||
|
|
||||||
|
|
||||||
|
class Generator:
|
||||||
|
@@ -222,7 +224,16 @@ def _dispatch(self, msg):
|
||||||
|
|
||||||
|
def _write_headers(self, msg):
|
||||||
|
for h, v in msg.raw_items():
|
||||||
|
- self.write(self.policy.fold(h, v))
|
||||||
|
+ folded = self.policy.fold(h, v)
|
||||||
|
+ if self.policy.verify_generated_headers:
|
||||||
|
+ linesep = self.policy.linesep
|
||||||
|
+ if not folded.endswith(self.policy.linesep):
|
||||||
|
+ raise HeaderWriteError(
|
||||||
|
+ f'folded header does not end with {linesep!r}: {folded!r}')
|
||||||
|
+ if NEWLINE_WITHOUT_FWSP.search(folded.removesuffix(linesep)):
|
||||||
|
+ raise HeaderWriteError(
|
||||||
|
+ f'folded header contains newline: {folded!r}')
|
||||||
|
+ self.write(folded)
|
||||||
|
# A blank line always separates headers from body
|
||||||
|
self.write(self._NL)
|
||||||
|
|
||||||
|
diff --git a/Lib/test/test_email/test_generator.py b/Lib/test/test_email/test_generator.py
|
||||||
|
index bc6f734d4fd0a9..c75a842c33578e 100644
|
||||||
|
--- a/Lib/test/test_email/test_generator.py
|
||||||
|
+++ b/Lib/test/test_email/test_generator.py
|
||||||
|
@@ -6,6 +6,7 @@
|
||||||
|
from email.generator import Generator, BytesGenerator
|
||||||
|
from email.headerregistry import Address
|
||||||
|
from email import policy
|
||||||
|
+import email.errors
|
||||||
|
from test.test_email import TestEmailBase, parameterize
|
||||||
|
|
||||||
|
|
||||||
|
@@ -249,6 +250,44 @@ def test_rfc2231_wrapping_switches_to_default_len_if_too_narrow(self):
|
||||||
|
g.flatten(msg)
|
||||||
|
self.assertEqual(s.getvalue(), self.typ(expected))
|
||||||
|
|
||||||
|
+ def test_keep_encoded_newlines(self):
|
||||||
|
+ msg = self.msgmaker(self.typ(textwrap.dedent("""\
|
||||||
|
+ To: nobody
|
||||||
|
+ Subject: Bad subject=?UTF-8?Q?=0A?=Bcc: injection@example.com
|
||||||
|
+
|
||||||
|
+ None
|
||||||
|
+ """)))
|
||||||
|
+ expected = textwrap.dedent("""\
|
||||||
|
+ To: nobody
|
||||||
|
+ Subject: Bad subject=?UTF-8?Q?=0A?=Bcc: injection@example.com
|
||||||
|
+
|
||||||
|
+ None
|
||||||
|
+ """)
|
||||||
|
+ s = self.ioclass()
|
||||||
|
+ g = self.genclass(s, policy=self.policy.clone(max_line_length=80))
|
||||||
|
+ g.flatten(msg)
|
||||||
|
+ self.assertEqual(s.getvalue(), self.typ(expected))
|
||||||
|
+
|
||||||
|
+ def test_keep_long_encoded_newlines(self):
|
||||||
|
+ msg = self.msgmaker(self.typ(textwrap.dedent("""\
|
||||||
|
+ To: nobody
|
||||||
|
+ Subject: Bad subject=?UTF-8?Q?=0A?=Bcc: injection@example.com
|
||||||
|
+
|
||||||
|
+ None
|
||||||
|
+ """)))
|
||||||
|
+ expected = textwrap.dedent("""\
|
||||||
|
+ To: nobody
|
||||||
|
+ Subject: Bad subject
|
||||||
|
+ =?utf-8?q?=0A?=Bcc:
|
||||||
|
+ injection@example.com
|
||||||
|
+
|
||||||
|
+ None
|
||||||
|
+ """)
|
||||||
|
+ s = self.ioclass()
|
||||||
|
+ g = self.genclass(s, policy=self.policy.clone(max_line_length=30))
|
||||||
|
+ g.flatten(msg)
|
||||||
|
+ self.assertEqual(s.getvalue(), self.typ(expected))
|
||||||
|
+
|
||||||
|
|
||||||
|
class TestGenerator(TestGeneratorBase, TestEmailBase):
|
||||||
|
|
||||||
|
@@ -273,6 +312,29 @@ def test_flatten_unicode_linesep(self):
|
||||||
|
g.flatten(msg)
|
||||||
|
self.assertEqual(s.getvalue(), self.typ(expected))
|
||||||
|
|
||||||
|
+ def test_verify_generated_headers(self):
|
||||||
|
+ """gh-121650: by default the generator prevents header injection"""
|
||||||
|
+ class LiteralHeader(str):
|
||||||
|
+ name = 'Header'
|
||||||
|
+ def fold(self, **kwargs):
|
||||||
|
+ return self
|
||||||
|
+
|
||||||
|
+ for text in (
|
||||||
|
+ 'Value\r\nBad Injection\r\n',
|
||||||
|
+ 'NoNewLine'
|
||||||
|
+ ):
|
||||||
|
+ with self.subTest(text=text):
|
||||||
|
+ message = message_from_string(
|
||||||
|
+ "Header: Value\r\n\r\nBody",
|
||||||
|
+ policy=self.policy,
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
+ del message['Header']
|
||||||
|
+ message['Header'] = LiteralHeader(text)
|
||||||
|
+
|
||||||
|
+ with self.assertRaises(email.errors.HeaderWriteError):
|
||||||
|
+ message.as_string()
|
||||||
|
+
|
||||||
|
|
||||||
|
class TestBytesGenerator(TestGeneratorBase, TestEmailBase):
|
||||||
|
|
||||||
|
diff --git a/Lib/test/test_email/test_policy.py b/Lib/test/test_email/test_policy.py
|
||||||
|
index c6b9c80efe1b54..baa35fd68e49c5 100644
|
||||||
|
--- a/Lib/test/test_email/test_policy.py
|
||||||
|
+++ b/Lib/test/test_email/test_policy.py
|
||||||
|
@@ -26,6 +26,7 @@ class PolicyAPITests(unittest.TestCase):
|
||||||
|
'raise_on_defect': False,
|
||||||
|
'mangle_from_': True,
|
||||||
|
'message_factory': None,
|
||||||
|
+ 'verify_generated_headers': True,
|
||||||
|
}
|
||||||
|
# These default values are the ones set on email.policy.default.
|
||||||
|
# If any of these defaults change, the docs must be updated.
|
||||||
|
@@ -294,6 +295,31 @@ def test_short_maxlen_error(self):
|
||||||
|
with self.assertRaises(email.errors.HeaderParseError):
|
||||||
|
policy.fold("Subject", subject)
|
||||||
|
|
||||||
|
+ def test_verify_generated_headers(self):
|
||||||
|
+ """Turning protection off allows header injection"""
|
||||||
|
+ policy = email.policy.default.clone(verify_generated_headers=False)
|
||||||
|
+ for text in (
|
||||||
|
+ 'Header: Value\r\nBad: Injection\r\n',
|
||||||
|
+ 'Header: NoNewLine'
|
||||||
|
+ ):
|
||||||
|
+ with self.subTest(text=text):
|
||||||
|
+ message = email.message_from_string(
|
||||||
|
+ "Header: Value\r\n\r\nBody",
|
||||||
|
+ policy=policy,
|
||||||
|
+ )
|
||||||
|
+ class LiteralHeader(str):
|
||||||
|
+ name = 'Header'
|
||||||
|
+ def fold(self, **kwargs):
|
||||||
|
+ return self
|
||||||
|
+
|
||||||
|
+ del message['Header']
|
||||||
|
+ message['Header'] = LiteralHeader(text)
|
||||||
|
+
|
||||||
|
+ self.assertEqual(
|
||||||
|
+ message.as_string(),
|
||||||
|
+ f"{text}\nBody",
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
# XXX: Need subclassing tests.
|
||||||
|
# For adding subclassed objects, make sure the usual rules apply (subclass
|
||||||
|
# wins), but that the order still works (right overrides left).
|
||||||
|
diff --git a/Misc/NEWS.d/next/Library/2024-07-27-16-10-41.gh-issue-121650.nf6oc9.rst b/Misc/NEWS.d/next/Library/2024-07-27-16-10-41.gh-issue-121650.nf6oc9.rst
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000000..83dd28d4ac575b
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Misc/NEWS.d/next/Library/2024-07-27-16-10-41.gh-issue-121650.nf6oc9.rst
|
||||||
|
@@ -0,0 +1,5 @@
|
||||||
|
+:mod:`email` headers with embedded newlines are now quoted on output. The
|
||||||
|
+:mod:`~email.generator` will now refuse to serialize (write) headers that
|
||||||
|
+are unsafely folded or delimited; see
|
||||||
|
+:attr:`~email.policy.Policy.verify_generated_headers`. (Contributed by Bas
|
||||||
|
+Bloemsaat and Petr Viktorin in :gh:`121650`.)
|
152
F00251-change-user-install-location.patch
Normal file
152
F00251-change-user-install-location.patch
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro@hroncok.cz>
|
||||||
|
Date: Mon, 15 Feb 2021 12:19:27 +0100
|
||||||
|
Subject: [PATCH] 00251: Change user install location
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Set values of base and platbase in sysconfig from /usr
|
||||||
|
to /usr/local when RPM build is not detected
|
||||||
|
to make pip and similar tools install into separate location.
|
||||||
|
|
||||||
|
Fedora Change: https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe
|
||||||
|
Downstream only.
|
||||||
|
|
||||||
|
We've tried to rework in Fedora 36/Python 3.10 to follow https://bugs.python.org/issue43976
|
||||||
|
but we have identified serious problems with that approach,
|
||||||
|
see https://bugzilla.redhat.com/2026979 or https://bugzilla.redhat.com/2097183
|
||||||
|
|
||||||
|
pypa/distutils integration: https://github.com/pypa/distutils/pull/70
|
||||||
|
|
||||||
|
Co-authored-by: Petr Viktorin <encukou@gmail.com>
|
||||||
|
Co-authored-by: Miro Hrončok <miro@hroncok.cz>
|
||||||
|
Co-authored-by: Michal Cyprian <m.cyprian@gmail.com>
|
||||||
|
Co-authored-by: Lumír Balhar <frenzy.madness@gmail.com>
|
||||||
|
---
|
||||||
|
Lib/site.py | 9 ++++++-
|
||||||
|
Lib/sysconfig.py | 49 +++++++++++++++++++++++++++++++++++++-
|
||||||
|
Lib/test/test_sysconfig.py | 17 +++++++++++--
|
||||||
|
3 files changed, 71 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
Index: Python-3.13.0b4/Lib/test/test_sysconfig.py
|
||||||
|
===================================================================
|
||||||
|
--- Python-3.13.0b4.orig/Lib/test/test_sysconfig.py
|
||||||
|
+++ Python-3.13.0b4/Lib/test/test_sysconfig.py
|
||||||
|
@@ -121,8 +121,19 @@ class TestSysConfig(unittest.TestCase):
|
||||||
|
for scheme in _INSTALL_SCHEMES:
|
||||||
|
for name in _INSTALL_SCHEMES[scheme]:
|
||||||
|
expected = _INSTALL_SCHEMES[scheme][name].format(**config_vars)
|
||||||
|
+ tested = get_path(name, scheme)
|
||||||
|
+ # https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe
|
||||||
|
+ if tested.startswith('/usr/local'):
|
||||||
|
+ # /usr/local should only be used in posix_prefix
|
||||||
|
+ self.assertEqual(scheme, 'posix_prefix')
|
||||||
|
+ # Fedora CI runs tests for venv and virtualenv that check for other prefixes
|
||||||
|
+ self.assertEqual(sys.prefix, '/usr')
|
||||||
|
+ # When building the RPM of Python, %check runs this with RPM_BUILD_ROOT set
|
||||||
|
+ # Fedora CI runs this with RPM_BUILD_ROOT unset
|
||||||
|
+ self.assertNotIn('RPM_BUILD_ROOT', os.environ)
|
||||||
|
+ tested = tested.replace('/usr/local', '/usr')
|
||||||
|
self.assertEqual(
|
||||||
|
- os.path.normpath(get_path(name, scheme)),
|
||||||
|
+ os.path.normpath(tested),
|
||||||
|
os.path.normpath(expected),
|
||||||
|
)
|
||||||
|
|
||||||
|
@@ -377,7 +388,7 @@ class TestSysConfig(unittest.TestCase):
|
||||||
|
self.assertTrue(os.path.isfile(config_h), config_h)
|
||||||
|
|
||||||
|
def test_get_scheme_names(self):
|
||||||
|
- wanted = ['nt', 'posix_home', 'posix_prefix', 'posix_venv', 'nt_venv', 'venv']
|
||||||
|
+ wanted = ['nt', 'posix_home', 'posix_prefix', 'posix_venv', 'nt_venv', 'venv', 'rpm_prefix']
|
||||||
|
if HAS_USER_BASE:
|
||||||
|
wanted.extend(['nt_user', 'osx_framework_user', 'posix_user'])
|
||||||
|
self.assertEqual(get_scheme_names(), tuple(sorted(wanted)))
|
||||||
|
@@ -389,6 +400,8 @@ class TestSysConfig(unittest.TestCase):
|
||||||
|
cmd = "-c", "import sysconfig; print(sysconfig.get_platform())"
|
||||||
|
self.assertEqual(py.call_real(*cmd), py.call_link(*cmd))
|
||||||
|
|
||||||
|
+ @unittest.skipIf('RPM_BUILD_ROOT' not in os.environ,
|
||||||
|
+ "Test doesn't expect Fedora's paths")
|
||||||
|
def test_user_similar(self):
|
||||||
|
# Issue #8759: make sure the posix scheme for the users
|
||||||
|
# is similar to the global posix_prefix one
|
||||||
|
Index: Python-3.13.0b4/Lib/sysconfig/__init__.py
|
||||||
|
===================================================================
|
||||||
|
--- Python-3.13.0b4.orig/Lib/sysconfig/__init__.py
|
||||||
|
+++ Python-3.13.0b4/Lib/sysconfig/__init__.py
|
||||||
|
@@ -106,6 +106,11 @@ if os.name == 'nt':
|
||||||
|
else:
|
||||||
|
_INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['posix_venv']
|
||||||
|
|
||||||
|
+# For a brief period of time in the Fedora 36 life cycle,
|
||||||
|
+# this installation scheme existed and was documented in the release notes.
|
||||||
|
+# For backwards compatibility, we keep it here (at least on 3.10 and 3.11).
|
||||||
|
+_INSTALL_SCHEMES['rpm_prefix'] = _INSTALL_SCHEMES['posix_prefix']
|
||||||
|
+
|
||||||
|
def _get_implementation():
|
||||||
|
return 'Python'
|
||||||
|
|
||||||
|
@@ -167,6 +172,19 @@ if _HAS_USER_BASE:
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
+# This is used by distutils.command.install in the stdlib
|
||||||
|
+# as well as pypa/distutils (e.g. bundled in setuptools).
|
||||||
|
+# The self.prefix value is set to sys.prefix + /local/
|
||||||
|
+# if neither RPM build nor virtual environment is
|
||||||
|
+# detected to make distutils install packages
|
||||||
|
+# into the separate location.
|
||||||
|
+# https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe
|
||||||
|
+if (not (hasattr(sys, 'real_prefix') or
|
||||||
|
+ sys.prefix != sys.base_prefix) and
|
||||||
|
+ 'RPM_BUILD_ROOT' not in os.environ):
|
||||||
|
+ _prefix_addition = '/local'
|
||||||
|
+
|
||||||
|
+
|
||||||
|
_SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include',
|
||||||
|
'scripts', 'data')
|
||||||
|
|
||||||
|
@@ -261,11 +279,40 @@ def _extend_dict(target_dict, other_dict
|
||||||
|
target_dict[key] = value
|
||||||
|
|
||||||
|
|
||||||
|
+_CONFIG_VARS_LOCAL = None
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+def _config_vars_local():
|
||||||
|
+ # This function returns the config vars with prefixes amended to /usr/local
|
||||||
|
+ # https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe
|
||||||
|
+ global _CONFIG_VARS_LOCAL
|
||||||
|
+ if _CONFIG_VARS_LOCAL is None:
|
||||||
|
+ _CONFIG_VARS_LOCAL = dict(get_config_vars())
|
||||||
|
+ _CONFIG_VARS_LOCAL['base'] = '/usr/local'
|
||||||
|
+ _CONFIG_VARS_LOCAL['platbase'] = '/usr/local'
|
||||||
|
+ return _CONFIG_VARS_LOCAL
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def _expand_vars(scheme, vars):
|
||||||
|
res = {}
|
||||||
|
if vars is None:
|
||||||
|
vars = {}
|
||||||
|
- _extend_dict(vars, get_config_vars())
|
||||||
|
+
|
||||||
|
+ # when we are not in a virtual environment or an RPM build
|
||||||
|
+ # we change '/usr' to '/usr/local'
|
||||||
|
+ # to avoid surprises, we explicitly check for the /usr/ prefix
|
||||||
|
+ # Python virtual environments have different prefixes
|
||||||
|
+ # we only do this for posix_prefix, not to mangle the venv scheme
|
||||||
|
+ # posix_prefix is used by sudo pip install
|
||||||
|
+ # we only change the defaults here, so explicit --prefix will take precedence
|
||||||
|
+ # https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe
|
||||||
|
+ if (scheme == 'posix_prefix' and
|
||||||
|
+ _PREFIX == '/usr' and
|
||||||
|
+ 'RPM_BUILD_ROOT' not in os.environ):
|
||||||
|
+ _extend_dict(vars, _config_vars_local())
|
||||||
|
+ else:
|
||||||
|
+ _extend_dict(vars, get_config_vars())
|
||||||
|
+
|
||||||
|
if os.name == 'nt':
|
||||||
|
# On Windows we want to substitute 'lib' for schemes rather
|
||||||
|
# than the native value (without modifying vars, in case it
|
26
PACKAGING-NOTES
Normal file
26
PACKAGING-NOTES
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
Notes for packagers of Python3
|
||||||
|
==============================
|
||||||
|
|
||||||
|
0. Faster build turnaround
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
By default, python builds with profile-guided optimization. This needs
|
||||||
|
an additional run of the test suite and it is generally slow.
|
||||||
|
PGO build takes around 50 minutes.
|
||||||
|
|
||||||
|
For development, use "--without profileopt" option to disable PGO. This
|
||||||
|
shortens the build time to ~5 minutes including test suite.
|
||||||
|
|
||||||
|
1. import_failed.map
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
This is a mechanism installed as part of python3-base, that places shim modules
|
||||||
|
on python's path (through a generated zzzz-import-failed-hooks.pth file, so that
|
||||||
|
it is imported as much at the end as makes sense; and an _import_failed subdir
|
||||||
|
of /usr/lib/pythonX.Y). Then when the user tries to import a module that is part
|
||||||
|
of a subpackage, the ImportError will contain a helpful message telling them
|
||||||
|
which missing subpackage to install.
|
||||||
|
|
||||||
|
This can sometimes cause problems on non-standard configurations, if the pth
|
||||||
|
gets included too early (for instance if you are using a script to include all
|
||||||
|
pths by hand in some strange order). Just something to look out for.
|
3
Python-3.13.0b3.tar.xz
Normal file
3
Python-3.13.0b3.tar.xz
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:3be094ad08b11dc2a065463524239c78dc9f2b342b01dcd4e1e606dbbc5c78a5
|
||||||
|
size 20841504
|
18
Python-3.13.0b3.tar.xz.asc
Normal file
18
Python-3.13.0b3.tar.xz.asc
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQKTBAABCgB9FiEEcWlgX2LHUTVtBUomqCHmgOX6YwUFAmZ9d85fFIAAAAAALgAo
|
||||||
|
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDcx
|
||||||
|
Njk2MDVGNjJDNzUxMzU2RDA1NEEyNkE4MjFFNjgwRTVGQTYzMDUACgkQqCHmgOX6
|
||||||
|
YwWXBA//TeNtOZTRpGM4pWnY9GBOvXH+WFyT5k5GQM6AE5ITYhLPkz+Refj3kwPV
|
||||||
|
uF32neYXIJIO3v+vyfFTYyj5jNS5gvGRvjPXe2K5p0K9cv5HpTncob9p8FnTJQRY
|
||||||
|
hqXpzs2q8gjU9YN54wz3SqAFE1ensB2qHlq7EJUABbB+HNWk929TXh+cQwSybRT1
|
||||||
|
XMzdKHc4IO3WCVPKIsMngqglUrj7FhlEgx/C8hmu81zpLVkCzxDXLuEDt7nnHoCG
|
||||||
|
HHcmF8B7kGK6py8KD7n/RZgriXli37tyFHJ0wwCtzwyko73khWVayYyJ53s4Pa5H
|
||||||
|
C6A9eNJMBxAQU/M2uPed+io5xZ8IvzSPs4vJCS8YL+NHTQGubexo5QIIHTP5b7ta
|
||||||
|
JW6s3TDHA8g/b3rGum76ZelJ4dsUJ8TPxNl4fORtsltVLJwol1FLGzb7vK7r/ZTM
|
||||||
|
NBnYFjNjEfe4uWHwsZoLdZzH90Z8bKsUXWz/h4EMjUL3NLgORSE8vbPhpjscmEB/
|
||||||
|
x+DM9IJHQat/s8ijtELuOx9SLpUuFBAmzVkmWVWvlPjFrQ5nw5pWLRzADpEV7/IU
|
||||||
|
XOucXhV4hrc8fJ57dGv0mtpP37DbF/cPMdOC0kA9X4icr1sLwN6MVmQJcFoBcNge
|
||||||
|
LvKvNW8lXxWbdOj0+fIymIXoH+bzJUp8g8l79Hp6QYBM5EOxfso=
|
||||||
|
=KNpM
|
||||||
|
-----END PGP SIGNATURE-----
|
3
Python-3.13.0b4.tar.xz
Normal file
3
Python-3.13.0b4.tar.xz
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:b2aa557c3c875233abdaf1b124284e5d50f6bb238d62a8b55f12dc92cea1953f
|
||||||
|
size 20876136
|
18
Python-3.13.0b4.tar.xz.asc
Normal file
18
Python-3.13.0b4.tar.xz.asc
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQKTBAABCgB9FiEEcWlgX2LHUTVtBUomqCHmgOX6YwUFAmaY/fpfFIAAAAAALgAo
|
||||||
|
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDcx
|
||||||
|
Njk2MDVGNjJDNzUxMzU2RDA1NEEyNkE4MjFFNjgwRTVGQTYzMDUACgkQqCHmgOX6
|
||||||
|
YwV7ExAAkdc0QjTfb4xrTBdKdOkpPk6vsM0tDpA1XnsaCDBwHRertRXKGrHivDfK
|
||||||
|
vDxHQqnXXVa+1PiQYGqFLR4DKUCebYs2RjUlZfULiXwv7SxBWTR1AEpzNyNuzfPU
|
||||||
|
+NXz0Wrs2hlEVo6LFIjCqwN3j0e96gEoIOA3BuuCorw4SeRfzc2Fw/essHYL85MQ
|
||||||
|
kyvzhRcjoyWFGoyDv52OUuP81u8v0OaW1EImkKzG65QnXVSPmihTKWvnHxgUBI95
|
||||||
|
rTu2s5/w5gKUDDhQyBl5SLjb+bsMjgoUY8bDkvy9yTi3bWGVFOCD2VFK8cGOGUP0
|
||||||
|
lz8g3aSPBTbfieKqghoIpPjyttqOt4gJg/twXZaxpv3f5nO2ErixYR3El/RzGdGk
|
||||||
|
uui7GJbX4fKoNsmSqM8FV6QfJ+sO3CV+3XVOyfMdrq3WrEGCpR9dYJ7BwOVfcYuD
|
||||||
|
hxMGchhMBJsj3gb25QgEVmFR/DOTnXoWNowbPkmkb7vv6lEp5j5JI47xfNqdxpID
|
||||||
|
Tyn7OQYGqKu7hzhMXTQ5HkL9AvERNUujtGHrN3uND+1ypiEFSuY6ahCmVWoAeSkJ
|
||||||
|
/TMkUiBEj1wBIMi7U0zAoyHN63zshq0DHYkaGDpb24GPAww1VmMls2pBy7vLSKO1
|
||||||
|
Ggzr4WWIN/EVNB9zulhqVxX750idYWBJrP/kLNubEn0Z/iOchrg=
|
||||||
|
=knpx
|
||||||
|
-----END PGP SIGNATURE-----
|
3
Python-3.13.0rc1.tar.xz
Normal file
3
Python-3.13.0rc1.tar.xz
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:678b884775eec0224d5159fa900879020baca2a36ce942fd95febfa1adb4a6bd
|
||||||
|
size 20881016
|
18
Python-3.13.0rc1.tar.xz.asc
Normal file
18
Python-3.13.0rc1.tar.xz.asc
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQKTBAABCgB9FiEEcWlgX2LHUTVtBUomqCHmgOX6YwUFAmaquNZfFIAAAAAALgAo
|
||||||
|
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDcx
|
||||||
|
Njk2MDVGNjJDNzUxMzU2RDA1NEEyNkE4MjFFNjgwRTVGQTYzMDUACgkQqCHmgOX6
|
||||||
|
YwUclA//Tg0ybBUO7yjNvM85wbZLxIvYujAbReBRARLUkZXFGVMBG9zi3Arf4EE6
|
||||||
|
PKvGvy0vg/jeQPraLBe4KQnaQUTU8qmLsjd7lWWEjZc0E+3zZzAvZ9hXNtcrqY4x
|
||||||
|
YdLaGT8762c4sFoNsp173MYrqdun/usraKK50V1m/BPAqHX1Pdy0yxykkfG4p7lC
|
||||||
|
LEUrc+2KtLWI9+Z0imH2FhI0OdhlSZKgJfi82dbmRDeJwMmEoG9+F9qmanrtIEVu
|
||||||
|
6Tpwv8RphXI1JV7mzr6EjZqW4oHRayHlA4qcS9mTYKBNAfveEODXgbvsGRenh1X1
|
||||||
|
kJclnX/GBpcjP/+PZ9aheAxxrTEvg7kmjrcfZKfzxepJEvCaxlg9hTKAvmMcgKp0
|
||||||
|
V8rhWxBBfy47q8pvezjI4ip2rcedtJ21e0M98PPQLpuUxeo1xldjPLeGh8hyC9Z4
|
||||||
|
F8HAs+uv11FXV5zaJvUIMCPx125ceYhl/1Jh36bJFX9MvjFlKOtR9mnsu84D5piW
|
||||||
|
8+yUy353864bv9rrww/dMWzrrp7nO+/3gZi/goNGfMvm5KVpuhTro6xoW5KQ5LS+
|
||||||
|
ZQGbWXl08lJ9+k8pUuwxCFHQCKjgjmerjb8xL9claBlF8FtfrQjy33BpxqF5BLpW
|
||||||
|
CUbabJ9bA9O7fPsPhbW0XQGdXIJJLjHTP39pxCPGoBqAyUVJOc8=
|
||||||
|
=CSLe
|
||||||
|
-----END PGP SIGNATURE-----
|
43
README.SUSE
Normal file
43
README.SUSE
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
Python 3 in SUSE
|
||||||
|
==============
|
||||||
|
|
||||||
|
* Subpackages *
|
||||||
|
|
||||||
|
Python 3 is split into several subpackages, based on external dependencies.
|
||||||
|
The main package 'python3' has soft dependencies on all subpackages needed to
|
||||||
|
assemble the standard library; however, these might not all be installed by default.
|
||||||
|
|
||||||
|
If you attempt to import a module that is currently not installed, an ImportError is thrown,
|
||||||
|
with instructions to install the missing subpackage. Installing the subpackage might result
|
||||||
|
in installing libraries that the subpackage requires to function.
|
||||||
|
|
||||||
|
|
||||||
|
* ensurepip *
|
||||||
|
|
||||||
|
The 'ensurepip' module from Python 3 standard library (PEP 453) is supposed to deploy
|
||||||
|
a bundled copy of the pip installer. This makes no sense in a managed distribution like SUSE.
|
||||||
|
Instead, you need to install package 'python3-pip'. Usually this will be installed automatically
|
||||||
|
with 'python3'.
|
||||||
|
|
||||||
|
Using 'ensurepip' when pip is not installed will result in an ImportError with instructions
|
||||||
|
to install 'python3-pip'.
|
||||||
|
|
||||||
|
|
||||||
|
* Documentation *
|
||||||
|
|
||||||
|
You can find documentation in seprarate packages: python3-doc and
|
||||||
|
python3-doc-pdf. These contan following documents:
|
||||||
|
|
||||||
|
Tutorial, What's New in Python, Global Module Index, Library Reference,
|
||||||
|
Macintosh Module Reference, Installing Python Modules, Distributing Python
|
||||||
|
Modules, Language Reference, Extending and Embedding, Python/C API,
|
||||||
|
Documenting Python
|
||||||
|
|
||||||
|
The python3-doc package constains many text files from source tarball.
|
||||||
|
|
||||||
|
|
||||||
|
* Interactive mode *
|
||||||
|
|
||||||
|
Interactive mode is by default enhanced with of history and command completion.
|
||||||
|
If you don't like these features, you can unset the PYTHONSTARTUP variable
|
||||||
|
in your .profile or disable it system wide in /etc/profile.d/python.sh.
|
4
_multibuild
Normal file
4
_multibuild
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<multibuild>
|
||||||
|
<package>base</package>
|
||||||
|
<package>doc</package>
|
||||||
|
</multibuild>
|
3
baselibs.conf
Normal file
3
baselibs.conf
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
python313-base
|
||||||
|
python313
|
||||||
|
libpython3_13-1_0
|
3
bluez-devel-vendor.tar.xz
Normal file
3
bluez-devel-vendor.tar.xz
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:4624c6ab6543ec4875bdd5c6c58c874d487128e44e54c8ef1924ec1d48e35928
|
||||||
|
size 25328
|
163
bpo-31046_ensurepip_honours_prefix.patch
Normal file
163
bpo-31046_ensurepip_honours_prefix.patch
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
From 5754521af1d51aa8e445cba07a093bbc0c88596d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zackery Spytz <zspytz@gmail.com>
|
||||||
|
Date: Mon, 16 Dec 2019 18:24:08 -0700
|
||||||
|
Subject: [PATCH] bpo-31046: ensurepip does not honour the value of $(prefix)
|
||||||
|
|
||||||
|
Co-Authored-By: Xavier de Gaye <xdegaye@gmail.com>
|
||||||
|
---
|
||||||
|
Doc/library/ensurepip.rst | 9 +++--
|
||||||
|
Lib/ensurepip/__init__.py | 18 +++++++---
|
||||||
|
Lib/test/test_ensurepip.py | 11 ++++++
|
||||||
|
Makefile.pre.in | 4 +-
|
||||||
|
Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst | 1
|
||||||
|
5 files changed, 34 insertions(+), 9 deletions(-)
|
||||||
|
create mode 100644 Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst
|
||||||
|
|
||||||
|
--- a/Doc/library/ensurepip.rst
|
||||||
|
+++ b/Doc/library/ensurepip.rst
|
||||||
|
@@ -59,8 +59,9 @@ is at least as recent as the one availab
|
||||||
|
By default, ``pip`` is installed into the current virtual environment
|
||||||
|
(if one is active) or into the system site packages (if there is no
|
||||||
|
active virtual environment). The installation location can be controlled
|
||||||
|
-through two additional command line options:
|
||||||
|
+through some additional command line options:
|
||||||
|
|
||||||
|
+* ``--prefix <dir>``: Installs ``pip`` using the given directory prefix.
|
||||||
|
* :samp:`--root {dir}`: Installs ``pip`` relative to the given root directory
|
||||||
|
rather than the root of the currently active virtual environment (if any)
|
||||||
|
or the default root for the current Python installation.
|
||||||
|
@@ -92,7 +93,7 @@ Module API
|
||||||
|
Returns a string specifying the available version of pip that will be
|
||||||
|
installed when bootstrapping an environment.
|
||||||
|
|
||||||
|
-.. function:: bootstrap(root=None, upgrade=False, user=False, \
|
||||||
|
+.. function:: bootstrap(root=None, prefix=None, upgrade=False, user=False, \
|
||||||
|
altinstall=False, default_pip=False, \
|
||||||
|
verbosity=0)
|
||||||
|
|
||||||
|
@@ -102,6 +103,8 @@ Module API
|
||||||
|
If *root* is ``None``, then installation uses the default install location
|
||||||
|
for the current environment.
|
||||||
|
|
||||||
|
+ *prefix* specifies the directory prefix to use when installing.
|
||||||
|
+
|
||||||
|
*upgrade* indicates whether or not to upgrade an existing installation
|
||||||
|
of an earlier version of ``pip`` to the available version.
|
||||||
|
|
||||||
|
@@ -122,6 +125,8 @@ Module API
|
||||||
|
*verbosity* controls the level of output to :data:`sys.stdout` from the
|
||||||
|
bootstrapping operation.
|
||||||
|
|
||||||
|
+ .. versionchanged:: 3.9 the *prefix* parameter was added.
|
||||||
|
+
|
||||||
|
.. audit-event:: ensurepip.bootstrap root ensurepip.bootstrap
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
--- a/Lib/ensurepip/__init__.py
|
||||||
|
+++ b/Lib/ensurepip/__init__.py
|
||||||
|
@@ -106,27 +106,27 @@ def _disable_pip_configuration_settings(
|
||||||
|
os.environ['PIP_CONFIG_FILE'] = os.devnull
|
||||||
|
|
||||||
|
|
||||||
|
-def bootstrap(*, root=None, upgrade=False, user=False,
|
||||||
|
+def bootstrap(*, root=None, prefix=None, upgrade=False, user=False,
|
||||||
|
altinstall=False, default_pip=False,
|
||||||
|
verbosity=0):
|
||||||
|
"""
|
||||||
|
Bootstrap pip into the current Python installation (or the given root
|
||||||
|
- directory).
|
||||||
|
+ and directory prefix).
|
||||||
|
|
||||||
|
Note that calling this function will alter both sys.path and os.environ.
|
||||||
|
"""
|
||||||
|
# Discard the return value
|
||||||
|
- _bootstrap(root=root, upgrade=upgrade, user=user,
|
||||||
|
+ _bootstrap(root=root, prefix=prefix, upgrade=upgrade, user=user,
|
||||||
|
altinstall=altinstall, default_pip=default_pip,
|
||||||
|
verbosity=verbosity)
|
||||||
|
|
||||||
|
|
||||||
|
-def _bootstrap(*, root=None, upgrade=False, user=False,
|
||||||
|
+def _bootstrap(*, root=None, prefix=None, upgrade=False, user=False,
|
||||||
|
altinstall=False, default_pip=False,
|
||||||
|
verbosity=0):
|
||||||
|
"""
|
||||||
|
Bootstrap pip into the current Python installation (or the given root
|
||||||
|
- directory). Returns pip command status code.
|
||||||
|
+ and directory prefix). Returns pip command status code.
|
||||||
|
|
||||||
|
Note that calling this function will alter both sys.path and os.environ.
|
||||||
|
"""
|
||||||
|
@@ -162,6 +162,8 @@ def _bootstrap(*, root=None, upgrade=Fal
|
||||||
|
args = ["install", "--no-cache-dir", "--no-index", "--find-links", tmpdir]
|
||||||
|
if root:
|
||||||
|
args += ["--root", root]
|
||||||
|
+ if prefix:
|
||||||
|
+ args += ["--prefix", prefix]
|
||||||
|
if upgrade:
|
||||||
|
args += ["--upgrade"]
|
||||||
|
if user:
|
||||||
|
@@ -238,6 +240,11 @@ def _main(argv=None):
|
||||||
|
help="Install everything relative to this alternate root directory.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
+ "--prefix",
|
||||||
|
+ default=None,
|
||||||
|
+ help="Install everything using this prefix.",
|
||||||
|
+ )
|
||||||
|
+ parser.add_argument(
|
||||||
|
"--altinstall",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
@@ -256,6 +263,7 @@ def _main(argv=None):
|
||||||
|
|
||||||
|
return _bootstrap(
|
||||||
|
root=args.root,
|
||||||
|
+ prefix=args.prefix,
|
||||||
|
upgrade=args.upgrade,
|
||||||
|
user=args.user,
|
||||||
|
verbosity=args.verbosity,
|
||||||
|
--- a/Lib/test/test_ensurepip.py
|
||||||
|
+++ b/Lib/test/test_ensurepip.py
|
||||||
|
@@ -101,6 +101,17 @@ class TestBootstrap(EnsurepipMixin, unit
|
||||||
|
unittest.mock.ANY,
|
||||||
|
)
|
||||||
|
|
||||||
|
+ def test_bootstrapping_with_prefix(self):
|
||||||
|
+ ensurepip.bootstrap(prefix="/foo/bar/")
|
||||||
|
+ self.run_pip.assert_called_once_with(
|
||||||
|
+ [
|
||||||
|
+ "install", "--no-cache-dir", "--no-index", "--find-links",
|
||||||
|
+ unittest.mock.ANY, "--prefix", "/foo/bar/",
|
||||||
|
+ "pip",
|
||||||
|
+ ],
|
||||||
|
+ unittest.mock.ANY,
|
||||||
|
+ )
|
||||||
|
+
|
||||||
|
def test_bootstrapping_with_user(self):
|
||||||
|
ensurepip.bootstrap(user=True)
|
||||||
|
|
||||||
|
--- a/Makefile.pre.in
|
||||||
|
+++ b/Makefile.pre.in
|
||||||
|
@@ -2157,7 +2157,7 @@ install: @FRAMEWORKINSTALLFIRST@ @INSTAL
|
||||||
|
install|*) ensurepip="" ;; \
|
||||||
|
esac; \
|
||||||
|
$(RUNSHARED) $(PYTHON_FOR_BUILD) -m ensurepip \
|
||||||
|
- $$ensurepip --root=$(DESTDIR)/ ; \
|
||||||
|
+ $$ensurepip --root=$(DESTDIR)/ --prefix=$(prefix) ; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
.PHONY: altinstall
|
||||||
|
@@ -2168,7 +2168,7 @@ altinstall: commoninstall
|
||||||
|
install|*) ensurepip="--altinstall" ;; \
|
||||||
|
esac; \
|
||||||
|
$(RUNSHARED) $(PYTHON_FOR_BUILD) -m ensurepip \
|
||||||
|
- $$ensurepip --root=$(DESTDIR)/ ; \
|
||||||
|
+ $$ensurepip --root=$(DESTDIR)/ --prefix=$(prefix) ; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
.PHONY: commoninstall
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/Misc/NEWS.d/next/Build/2019-12-16-17-50-42.bpo-31046.XA-Qfr.rst
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+A directory prefix can now be specified when using :mod:`ensurepip`.
|
24
bso1227999-reproducible-builds.patch
Normal file
24
bso1227999-reproducible-builds.patch
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
From ac2b8869724d7a57d9b5efbdce2f20423214e8bb Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Bernhard M. Wiedemann" <bwiedemann@suse.de>
|
||||||
|
Date: Tue, 16 Jul 2024 21:39:33 +0200
|
||||||
|
Subject: [PATCH] Allow to override build date with SOURCE_DATE_EPOCH
|
||||||
|
|
||||||
|
to make builds reproducible.
|
||||||
|
See https://reproducible-builds.org/ for why this is good
|
||||||
|
and https://reproducible-builds.org/specs/source-date-epoch/
|
||||||
|
for the definition of this variable.
|
||||||
|
---
|
||||||
|
Doc/library/functions.rst | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/Doc/library/functions.rst
|
||||||
|
+++ b/Doc/library/functions.rst
|
||||||
|
@@ -1502,7 +1502,7 @@ are always available. They are listed h
|
||||||
|
(where :func:`open` is declared), :mod:`os`, :mod:`os.path`, :mod:`tempfile`,
|
||||||
|
and :mod:`shutil`.
|
||||||
|
|
||||||
|
- .. audit-event:: open file,mode,flags open
|
||||||
|
+ .. audit-event:: open path,mode,flags open
|
||||||
|
|
||||||
|
The ``mode`` and ``flags`` arguments may have been modified or inferred from
|
||||||
|
the original call.
|
12
externally_managed.in
Normal file
12
externally_managed.in
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[externally-managed]
|
||||||
|
Error=To install Python packages system-wide, try
|
||||||
|
zypper install __PYTHONPREFIX__-xyz, where xyz is the package
|
||||||
|
you are trying to install.
|
||||||
|
|
||||||
|
If you wish to install a non-rpm packaged Python package,
|
||||||
|
create a virtual environment using __PYTHON__ -m venv path/to/venv.
|
||||||
|
Then use path/to/venv/bin/python and path/to/venv/bin/pip.
|
||||||
|
|
||||||
|
If you wish to install a non-rpm packaged Python application,
|
||||||
|
it may be easiest to use `pipx install xyz`, which will manage a
|
||||||
|
virtual environment for you. Install pipx via `zypper install __PYTHONPREFIX__-pipx` .
|
15
fix_configure_rst.patch
Normal file
15
fix_configure_rst.patch
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
Misc/NEWS | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/Misc/NEWS
|
||||||
|
+++ b/Misc/NEWS
|
||||||
|
@@ -17647,7 +17647,7 @@ C API
|
||||||
|
- bpo-40939: Removed documentation for the removed ``PyParser_*`` C API.
|
||||||
|
|
||||||
|
- bpo-43795: The list in :ref:`limited-api-list` now shows the public name
|
||||||
|
- :c:struct:`PyFrameObject` rather than ``_frame``. The non-existing entry
|
||||||
|
+ :c:type:`PyFrameObject` rather than ``_frame``. The non-existing entry
|
||||||
|
``_node`` no longer appears in the list.
|
||||||
|
|
||||||
|
- bpo-44378: :c:func:`Py_IS_TYPE` no longer uses :c:func:`Py_TYPE` to avoid
|
35
idle3.appdata.xml
Normal file
35
idle3.appdata.xml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!-- Copyright 2017 Zbigniew Jędrzejewski-Szmek -->
|
||||||
|
<application>
|
||||||
|
<id type="desktop">idle3.desktop</id>
|
||||||
|
<name>IDLE3</name>
|
||||||
|
<metadata_licence>CC0</metadata_licence>
|
||||||
|
<project_license>Python-2.0</project_license>
|
||||||
|
<summary>Python 3 Integrated Development and Learning Environment</summary>
|
||||||
|
<description>
|
||||||
|
<p>
|
||||||
|
IDLE is Python’s Integrated Development and Learning Environment.
|
||||||
|
The GUI is uniform between Windows, Unix, and Mac OS X.
|
||||||
|
IDLE provides an easy way to start writing, running, and debugging
|
||||||
|
Python code.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
IDLE is written in pure Python, and uses the tkinter GUI toolkit.
|
||||||
|
It provides:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>a Python shell window (interactive interpreter) with colorizing of code input, output, and error messages,</li>
|
||||||
|
<li>a multi-window text editor with multiple undo, Python colorizing, smart indent, call tips, auto completion, and other features,</li>
|
||||||
|
<li>search within any window, replace within editor windows, and search through multiple files (grep),</li>
|
||||||
|
<li>a debugger with persistent breakpoints, stepping, and viewing of global and local namespaces.</li>
|
||||||
|
</ul>
|
||||||
|
</description>
|
||||||
|
<url type="homepage">https://docs.python.org/3/library/idle.html</url>
|
||||||
|
<screenshots>
|
||||||
|
<screenshot type="default">http://in.waw.pl/~zbyszek/fedora/idle3-appdata/idle3-main-window.png</screenshot>
|
||||||
|
<screenshot>http://in.waw.pl/~zbyszek/fedora/idle3-appdata/idle3-class-browser.png</screenshot>
|
||||||
|
<screenshot>http://in.waw.pl/~zbyszek/fedora/idle3-appdata/idle3-code-viewer.png</screenshot>
|
||||||
|
</screenshots>
|
||||||
|
<update_contact>zbyszek@in.waw.pl</update_contact>
|
||||||
|
</application>
|
12
idle3.desktop
Normal file
12
idle3.desktop
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Version=1.0
|
||||||
|
Name=IDLE 3
|
||||||
|
GenericName=Python 3 IDE
|
||||||
|
Comment=Python 3 Integrated Development and Learning Environment
|
||||||
|
Exec=idle3 %F
|
||||||
|
TryExec=idle3
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
Icon=idle3
|
||||||
|
Categories=Development;IDE;
|
||||||
|
MimeType=text/x-python;
|
7
import_failed.map
Normal file
7
import_failed.map
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
python313-curses: curses _curses _curses_panel
|
||||||
|
python313-dbm: dbm _dbm _gdbm
|
||||||
|
python313-idle: idlelib
|
||||||
|
python313-testsuite: test _ctypes_test _testbuffer _testcapi _testinternalcapi _testimportmultiple _testmultiphase xxlimited
|
||||||
|
python313-tk: tkinter _tkinter
|
||||||
|
python313-tools: turtledemo
|
||||||
|
python313: sqlite3 readline _sqlite3 nis
|
23
import_failed.py
Normal file
23
import_failed.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import sys, os
|
||||||
|
from sysconfig import get_path
|
||||||
|
|
||||||
|
failed_map_path = os.path.join(get_path('stdlib'), '_import_failed', 'import_failed.map')
|
||||||
|
|
||||||
|
if __spec__:
|
||||||
|
failed_name = __spec__.name
|
||||||
|
else:
|
||||||
|
failed_name = __name__
|
||||||
|
|
||||||
|
with open(failed_map_path) as fd:
|
||||||
|
for line in fd:
|
||||||
|
package = line.split(':')[0]
|
||||||
|
imports = line.split(':')[1]
|
||||||
|
if failed_name in imports:
|
||||||
|
raise ImportError(f"""Module '{failed_name}' is not installed.
|
||||||
|
Use:
|
||||||
|
sudo zypper install {package}
|
||||||
|
to install it.""")
|
||||||
|
|
||||||
|
raise ImportError(f"""Module '{failed_name}' is not installed.
|
||||||
|
It is supposed to be part of python3 distribution, but missing from failed import map.
|
||||||
|
Please file a bug on the SUSE Bugzilla.""")
|
28
macros.python3
Normal file
28
macros.python3
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
%have_python3 1
|
||||||
|
|
||||||
|
# commented out legacy macro definitions
|
||||||
|
#py3_prefix /usr
|
||||||
|
#py3_incdir /usr/include/python3.5m
|
||||||
|
#py3_ver 3.5
|
||||||
|
|
||||||
|
# these should now be provided by macros.python_all
|
||||||
|
#python3_sitearch /usr/lib64/python3.5/site-packages
|
||||||
|
#python3_sitelib /usr/lib/python3.5/site-packages
|
||||||
|
#python3_version 3.5
|
||||||
|
|
||||||
|
# hard to say if anyone ever used these?
|
||||||
|
#py3_soflags cpython-35m-x86_64-linux-gnu
|
||||||
|
#py3_abiflags m
|
||||||
|
%cpython3_soabi %(python3 -c "import sysconfig; print(sysconfig.get_config_var('SOABI'))")
|
||||||
|
%py3_soflags %cpython3_soabi
|
||||||
|
|
||||||
|
# compilation macros that might be in use somewhere
|
||||||
|
%py3_compile(O) \
|
||||||
|
find %1 -name '*.pyc' -exec rm -f {} ";"\
|
||||||
|
python3 -c "import sys, os, compileall; br='%{buildroot}'; compileall.compile_dir(sys.argv[1], ddir=br and (sys.argv[1][len(os.path.abspath(br)):]+'/') or None)" %1\
|
||||||
|
%{-O:\
|
||||||
|
find %1 -name '*.pyo' -exec rm -f {} ";"\
|
||||||
|
python3 -O -c "import sys, os, compileall; br='%{buildroot}'; compileall.compile_dir(sys.argv[1], ddir=br and (sys.argv[1][len(os.path.abspath(br)):]+'/') or None)" %1\
|
||||||
|
}
|
||||||
|
|
||||||
|
|
647
no-skipif-doctests.patch
Normal file
647
no-skipif-doctests.patch
Normal file
@ -0,0 +1,647 @@
|
|||||||
|
only in patch2:
|
||||||
|
unchanged:
|
||||||
|
---
|
||||||
|
Doc/library/turtle.rst | 81 -------------------------------------------------
|
||||||
|
1 file changed, 81 deletions(-)
|
||||||
|
|
||||||
|
Index: Python-3.13.0a3/Doc/library/turtle.rst
|
||||||
|
===================================================================
|
||||||
|
--- Python-3.13.0a3.orig/Doc/library/turtle.rst
|
||||||
|
+++ Python-3.13.0a3/Doc/library/turtle.rst
|
||||||
|
@@ -449,7 +449,6 @@ Turtle motion
|
||||||
|
turtle is headed.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.position()
|
||||||
|
(0.00,0.00)
|
||||||
|
@@ -476,7 +475,6 @@ Turtle motion
|
||||||
|
>>> turtle.goto(0, 0)
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.position()
|
||||||
|
(0.00,0.00)
|
||||||
|
@@ -495,13 +493,11 @@ Turtle motion
|
||||||
|
orientation depends on the turtle mode, see :func:`mode`.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
:hide:
|
||||||
|
|
||||||
|
>>> turtle.setheading(22)
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.heading()
|
||||||
|
22.0
|
||||||
|
@@ -520,13 +516,11 @@ Turtle motion
|
||||||
|
orientation depends on the turtle mode, see :func:`mode`.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
:hide:
|
||||||
|
|
||||||
|
>>> turtle.setheading(22)
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.heading()
|
||||||
|
22.0
|
||||||
|
@@ -549,13 +543,11 @@ Turtle motion
|
||||||
|
not change the turtle's orientation.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
:hide:
|
||||||
|
|
||||||
|
>>> turtle.goto(0, 0)
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> tp = turtle.pos()
|
||||||
|
>>> tp
|
||||||
|
@@ -617,13 +609,11 @@ Turtle motion
|
||||||
|
unchanged.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
:hide:
|
||||||
|
|
||||||
|
>>> turtle.goto(0, 240)
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.position()
|
||||||
|
(0.00,240.00)
|
||||||
|
@@ -639,13 +629,11 @@ Turtle motion
|
||||||
|
Set the turtle's second coordinate to *y*, leave first coordinate unchanged.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
:hide:
|
||||||
|
|
||||||
|
>>> turtle.goto(0, 40)
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.position()
|
||||||
|
(0.00,40.00)
|
||||||
|
@@ -672,7 +660,6 @@ Turtle motion
|
||||||
|
=================== ====================
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.setheading(90)
|
||||||
|
>>> turtle.heading()
|
||||||
|
@@ -685,14 +672,12 @@ Turtle motion
|
||||||
|
its start-orientation (which depends on the mode, see :func:`mode`).
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
:hide:
|
||||||
|
|
||||||
|
>>> turtle.setheading(90)
|
||||||
|
>>> turtle.goto(0, -10)
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.heading()
|
||||||
|
90.0
|
||||||
|
@@ -724,7 +709,6 @@ Turtle motion
|
||||||
|
calculated automatically. May be used to draw regular polygons.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.home()
|
||||||
|
>>> turtle.position()
|
||||||
|
@@ -753,7 +737,6 @@ Turtle motion
|
||||||
|
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.home()
|
||||||
|
>>> turtle.dot()
|
||||||
|
@@ -771,7 +754,6 @@ Turtle motion
|
||||||
|
it by calling ``clearstamp(stamp_id)``.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.color("blue")
|
||||||
|
>>> stamp_id = turtle.stamp()
|
||||||
|
@@ -786,7 +768,6 @@ Turtle motion
|
||||||
|
Delete stamp with given *stampid*.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.position()
|
||||||
|
(150.00,-0.00)
|
||||||
|
@@ -824,7 +805,6 @@ Turtle motion
|
||||||
|
undo actions is determined by the size of the undobuffer.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> for i in range(4):
|
||||||
|
... turtle.fd(50); turtle.lt(80)
|
||||||
|
@@ -857,7 +837,6 @@ Turtle motion
|
||||||
|
turtle turn instantly.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.speed()
|
||||||
|
3
|
||||||
|
@@ -878,7 +857,6 @@ Tell Turtle's state
|
||||||
|
Return the turtle's current location (x,y) (as a :class:`Vec2D` vector).
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.pos()
|
||||||
|
(440.00,-0.00)
|
||||||
|
@@ -894,7 +872,6 @@ Tell Turtle's state
|
||||||
|
orientation which depends on the mode - "standard"/"world" or "logo".
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.goto(10, 10)
|
||||||
|
>>> turtle.towards(0,0)
|
||||||
|
@@ -906,7 +883,6 @@ Tell Turtle's state
|
||||||
|
Return the turtle's x coordinate.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.home()
|
||||||
|
>>> turtle.left(50)
|
||||||
|
@@ -922,7 +898,6 @@ Tell Turtle's state
|
||||||
|
Return the turtle's y coordinate.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.home()
|
||||||
|
>>> turtle.left(60)
|
||||||
|
@@ -939,7 +914,6 @@ Tell Turtle's state
|
||||||
|
:func:`mode`).
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.home()
|
||||||
|
>>> turtle.left(67)
|
||||||
|
@@ -956,7 +930,6 @@ Tell Turtle's state
|
||||||
|
other turtle, in turtle step units.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.home()
|
||||||
|
>>> turtle.distance(30,40)
|
||||||
|
@@ -980,7 +953,6 @@ Settings for measurement
|
||||||
|
Default value is 360 degrees.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.home()
|
||||||
|
>>> turtle.left(90)
|
||||||
|
@@ -1003,7 +975,6 @@ Settings for measurement
|
||||||
|
``degrees(2*math.pi)``.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.home()
|
||||||
|
>>> turtle.left(90)
|
||||||
|
@@ -1014,7 +985,6 @@ Settings for measurement
|
||||||
|
1.5707963267948966
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
:hide:
|
||||||
|
|
||||||
|
>>> turtle.degrees(360)
|
||||||
|
@@ -1050,7 +1020,6 @@ Drawing state
|
||||||
|
thickness. If no argument is given, the current pensize is returned.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.pensize()
|
||||||
|
1
|
||||||
|
@@ -1082,7 +1051,6 @@ Drawing state
|
||||||
|
attributes in one statement.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
:options: +NORMALIZE_WHITESPACE
|
||||||
|
|
||||||
|
>>> turtle.pen(fillcolor="black", pencolor="red", pensize=10)
|
||||||
|
@@ -1105,7 +1073,6 @@ Drawing state
|
||||||
|
Return ``True`` if pen is down, ``False`` if it's up.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.penup()
|
||||||
|
>>> turtle.isdown()
|
||||||
|
@@ -1146,7 +1113,6 @@ Color control
|
||||||
|
newly set pencolor.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> colormode()
|
||||||
|
1.0
|
||||||
|
@@ -1195,7 +1161,6 @@ Color control
|
||||||
|
with the newly set fillcolor.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.fillcolor("violet")
|
||||||
|
>>> turtle.fillcolor()
|
||||||
|
@@ -1234,7 +1199,6 @@ Color control
|
||||||
|
with the newly set colors.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.color("red", "green")
|
||||||
|
>>> turtle.color()
|
||||||
|
@@ -1251,7 +1215,6 @@ Filling
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
:hide:
|
||||||
|
|
||||||
|
>>> turtle.home()
|
||||||
|
@@ -1261,7 +1224,6 @@ Filling
|
||||||
|
Return fillstate (``True`` if filling, ``False`` else).
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.begin_fill()
|
||||||
|
>>> if turtle.filling():
|
||||||
|
@@ -1286,7 +1248,6 @@ Filling
|
||||||
|
above may be either all yellow or have some white regions.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.color("black", "red")
|
||||||
|
>>> turtle.begin_fill()
|
||||||
|
@@ -1303,7 +1264,6 @@ More drawing control
|
||||||
|
variables to the default values.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.goto(0,-22)
|
||||||
|
>>> turtle.left(100)
|
||||||
|
@@ -1354,7 +1314,6 @@ Visibility
|
||||||
|
drawing observably.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.hideturtle()
|
||||||
|
|
||||||
|
@@ -1365,7 +1324,6 @@ Visibility
|
||||||
|
Make the turtle visible.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.showturtle()
|
||||||
|
|
||||||
|
@@ -1396,7 +1354,6 @@ Appearance
|
||||||
|
deal with shapes see Screen method :func:`register_shape`.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.shape()
|
||||||
|
'classic'
|
||||||
|
@@ -1422,7 +1379,6 @@ Appearance
|
||||||
|
``resizemode("user")`` is called by :func:`shapesize` when used with arguments.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.resizemode()
|
||||||
|
'noresize'
|
||||||
|
@@ -1446,7 +1402,6 @@ Appearance
|
||||||
|
of the shape's outline.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.shapesize()
|
||||||
|
(1.0, 1.0, 1)
|
||||||
|
@@ -1471,7 +1426,6 @@ Appearance
|
||||||
|
heading of the turtle are sheared.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.shape("circle")
|
||||||
|
>>> turtle.shapesize(5,2)
|
||||||
|
@@ -1488,7 +1442,6 @@ Appearance
|
||||||
|
change the turtle's heading (direction of movement).
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.reset()
|
||||||
|
>>> turtle.shape("circle")
|
||||||
|
@@ -1512,7 +1465,6 @@ Appearance
|
||||||
|
turtle (its direction of movement).
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.reset()
|
||||||
|
>>> turtle.shape("circle")
|
||||||
|
@@ -1541,7 +1493,6 @@ Appearance
|
||||||
|
given matrix.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle = Turtle()
|
||||||
|
>>> turtle.shape("square")
|
||||||
|
@@ -1557,7 +1508,6 @@ Appearance
|
||||||
|
can be used to define a new shape or components of a compound shape.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.shape("square")
|
||||||
|
>>> turtle.shapetransform(4, -1, 0, 2)
|
||||||
|
@@ -1582,7 +1532,6 @@ Using events
|
||||||
|
procedural way:
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> def turn(x, y):
|
||||||
|
... left(180)
|
||||||
|
@@ -1603,7 +1552,6 @@ Using events
|
||||||
|
``None``, existing bindings are removed.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> class MyTurtle(Turtle):
|
||||||
|
... def glow(self,x,y):
|
||||||
|
@@ -1631,7 +1579,6 @@ Using events
|
||||||
|
mouse-click event on that turtle.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.ondrag(turtle.goto)
|
||||||
|
|
||||||
|
@@ -1659,7 +1606,6 @@ Special Turtle methods
|
||||||
|
Return the last recorded polygon.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.home()
|
||||||
|
>>> turtle.begin_poly()
|
||||||
|
@@ -1679,7 +1625,6 @@ Special Turtle methods
|
||||||
|
turtle properties.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> mick = Turtle()
|
||||||
|
>>> joe = mick.clone()
|
||||||
|
@@ -1692,7 +1637,6 @@ Special Turtle methods
|
||||||
|
return the "anonymous turtle":
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> pet = getturtle()
|
||||||
|
>>> pet.fd(50)
|
||||||
|
@@ -1706,7 +1650,6 @@ Special Turtle methods
|
||||||
|
TurtleScreen methods can then be called for that object.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> ts = turtle.getscreen()
|
||||||
|
>>> ts
|
||||||
|
@@ -1724,7 +1667,6 @@ Special Turtle methods
|
||||||
|
``None``, the undobuffer is disabled.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> turtle.setundobuffer(42)
|
||||||
|
|
||||||
|
@@ -1734,7 +1676,6 @@ Special Turtle methods
|
||||||
|
Return number of entries in the undobuffer.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> while undobufferentries():
|
||||||
|
... undo()
|
||||||
|
@@ -1757,7 +1698,6 @@ below:
|
||||||
|
For example:
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> s = Shape("compound")
|
||||||
|
>>> poly1 = ((0,0),(10,-5),(0,10),(-10,-5))
|
||||||
|
@@ -1768,7 +1708,6 @@ below:
|
||||||
|
3. Now add the Shape to the Screen's shapelist and use it:
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> register_shape("myshape", s)
|
||||||
|
>>> shape("myshape")
|
||||||
|
@@ -1788,7 +1727,6 @@ Most of the examples in this section ref
|
||||||
|
``screen``.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
:hide:
|
||||||
|
|
||||||
|
>>> screen = Screen()
|
||||||
|
@@ -1805,7 +1743,6 @@ Window control
|
||||||
|
Set or return background color of the TurtleScreen.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> screen.bgcolor("orange")
|
||||||
|
>>> screen.bgcolor()
|
||||||
|
@@ -1897,7 +1834,6 @@ Window control
|
||||||
|
distorted.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> screen.reset()
|
||||||
|
>>> screen.setworldcoordinates(-50,-7.5,50,7.5)
|
||||||
|
@@ -1908,7 +1844,6 @@ Window control
|
||||||
|
... left(45); fd(2) # a regular octagon
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
:hide:
|
||||||
|
|
||||||
|
>>> screen.reset()
|
||||||
|
@@ -1930,7 +1865,6 @@ Animation control
|
||||||
|
Optional argument:
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> screen.delay()
|
||||||
|
10
|
||||||
|
@@ -1952,7 +1886,6 @@ Animation control
|
||||||
|
:func:`delay`).
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> screen.tracer(8, 25)
|
||||||
|
>>> dist = 2
|
||||||
|
@@ -1989,7 +1922,6 @@ Using screen events
|
||||||
|
must have the focus. (See method :func:`listen`.)
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> def f():
|
||||||
|
... fd(50)
|
||||||
|
@@ -2010,7 +1942,6 @@ Using screen events
|
||||||
|
must have focus. (See method :func:`listen`.)
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> def f():
|
||||||
|
... fd(50)
|
||||||
|
@@ -2035,7 +1966,6 @@ Using screen events
|
||||||
|
named ``turtle``:
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> screen.onclick(turtle.goto) # Subsequently clicking into the TurtleScreen will
|
||||||
|
>>> # make the turtle move to the clicked point.
|
||||||
|
@@ -2055,7 +1985,6 @@ Using screen events
|
||||||
|
Install a timer that calls *fun* after *t* milliseconds.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> running = True
|
||||||
|
>>> def f():
|
||||||
|
@@ -2137,7 +2066,6 @@ Settings and special methods
|
||||||
|
============ ========================= ===================
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> mode("logo") # resets turtle heading to north
|
||||||
|
>>> mode()
|
||||||
|
@@ -2152,7 +2080,6 @@ Settings and special methods
|
||||||
|
values of color triples have to be in the range 0..*cmode*.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> screen.colormode(1)
|
||||||
|
>>> turtle.pencolor(240, 160, 80)
|
||||||
|
@@ -2173,7 +2100,6 @@ Settings and special methods
|
||||||
|
do with a Tkinter Canvas.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> cv = screen.getcanvas()
|
||||||
|
>>> cv
|
||||||
|
@@ -2185,7 +2111,6 @@ Settings and special methods
|
||||||
|
Return a list of names of all currently available turtle shapes.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> screen.getshapes()
|
||||||
|
['arrow', 'blank', 'circle', ..., 'turtle']
|
||||||
|
@@ -2209,7 +2134,6 @@ Settings and special methods
|
||||||
|
coordinates: Install the corresponding polygon shape.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> screen.register_shape("triangle", ((5,-3), (0,5), (-5,-3)))
|
||||||
|
|
||||||
|
@@ -2225,7 +2149,6 @@ Settings and special methods
|
||||||
|
Return the list of turtles on the screen.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> for turtle in screen.turtles():
|
||||||
|
... turtle.color("red")
|
||||||
|
@@ -2287,7 +2210,6 @@ Methods specific to Screen, not inherite
|
||||||
|
center window vertically
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> screen.setup (width=200, height=200, startx=0, starty=0)
|
||||||
|
>>> # sets window to 200x200 pixels, in upper left of screen
|
||||||
|
@@ -2303,7 +2225,6 @@ Methods specific to Screen, not inherite
|
||||||
|
Set title of turtle window to *titlestring*.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> screen.title("Welcome to the turtle zoo!")
|
||||||
|
|
||||||
|
@@ -2374,7 +2295,6 @@ Public classes
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
|
||||||
|
>>> poly = ((0,0),(10,-5),(0,10),(-10,-5))
|
||||||
|
>>> s = Shape("compound")
|
||||||
|
@@ -2759,7 +2679,6 @@ Changes since Python 3.0
|
||||||
|
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
- :skipif: _tkinter is None
|
||||||
|
:hide:
|
||||||
|
|
||||||
|
>>> for turtle in turtles():
|
78
pre_checkin.sh
Normal file
78
pre_checkin.sh
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export LC_ALL=C
|
||||||
|
|
||||||
|
master=python*.spec
|
||||||
|
|
||||||
|
# create import_failed.map from package definitions
|
||||||
|
pkgname=$(grep python_pkg_name $master |grep define |awk -F' ' '{print $3}')
|
||||||
|
MAPFILE=import_failed.map
|
||||||
|
function new_map_line () {
|
||||||
|
package=$1
|
||||||
|
package=$(echo $1 |sed -e "s:%{python_pkg_name}:$pkgname:")
|
||||||
|
modules=$2
|
||||||
|
if [ -z "$package" -o -z "$modules" ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [[ "$package" =~ "-base" ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo "$package:$modules" >> $MAPFILE.tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
for spec in *.spec; do
|
||||||
|
basename=${spec%.spec}
|
||||||
|
package=
|
||||||
|
modules=
|
||||||
|
while read line; do
|
||||||
|
case $line in
|
||||||
|
"%files -n "*)
|
||||||
|
new_map_line $package "$modules"
|
||||||
|
package=${line#"%files -n "}
|
||||||
|
modules=
|
||||||
|
;;
|
||||||
|
"%files "*)
|
||||||
|
new_map_line $package "$modules"
|
||||||
|
package=$basename-${line#"%files "}
|
||||||
|
modules=
|
||||||
|
;;
|
||||||
|
"%files")
|
||||||
|
new_map_line $package "$modules"
|
||||||
|
package=$basename
|
||||||
|
modules=
|
||||||
|
;;
|
||||||
|
"%{sitedir}/config-"*)
|
||||||
|
# ignore
|
||||||
|
;;
|
||||||
|
"%{sitedir}/"*)
|
||||||
|
word=${line#"%{sitedir}/"}
|
||||||
|
if ! echo $word | grep -q /; then
|
||||||
|
modules="$modules $word"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"%{dynlib "*"}")
|
||||||
|
word=${line#"%{dynlib "}
|
||||||
|
word=${word%"}"}
|
||||||
|
modules="$modules $word"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done < $spec
|
||||||
|
new_map_line $package "$modules"
|
||||||
|
done
|
||||||
|
|
||||||
|
cat $MAPFILE.tmp |sort -u > $MAPFILE
|
||||||
|
rm $MAPFILE.tmp
|
||||||
|
|
||||||
|
# run test inclusion check
|
||||||
|
tar xJf Python-*.xz
|
||||||
|
python3 skipped_tests.py
|
||||||
|
|
||||||
|
# generate baselibs.conf
|
||||||
|
VERSION=$(grep ^Version $master|awk -F':' '{print $2}' |sed -e 's/ //g')
|
||||||
|
python_version=${VERSION:0:3} # 3.3
|
||||||
|
python_version_abitag=${python_version//./} # 33
|
||||||
|
python_version_soname=${python_version//./_} # 3_3
|
||||||
|
echo "$pkgname-base" > baselibs.conf
|
||||||
|
echo "$pkgname" >> baselibs.conf
|
||||||
|
echo "libpython$python_version_soname-1_0" >> baselibs.conf
|
||||||
|
|
25
python-3.3.0b1-fix_date_time_compiler.patch
Normal file
25
python-3.3.0b1-fix_date_time_compiler.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
Makefile.pre.in | 7 +++++++
|
||||||
|
1 file changed, 7 insertions(+)
|
||||||
|
|
||||||
|
--- a/Makefile.pre.in
|
||||||
|
+++ b/Makefile.pre.in
|
||||||
|
@@ -1679,11 +1679,18 @@ Modules/getbuildinfo.o: $(PARSER_OBJS) \
|
||||||
|
$(DTRACE_OBJS) \
|
||||||
|
$(srcdir)/Modules/getbuildinfo.c
|
||||||
|
$(CC) -c $(PY_CORE_CFLAGS) \
|
||||||
|
+ -DDATE="\"`date -u -r Makefile.pre.in +"%b %d %Y"`\"" \
|
||||||
|
+ -DTIME="\"`date -u -r Makefile.pre.in +"%T"`\"" \
|
||||||
|
-DGITVERSION="\"`LC_ALL=C $(GITVERSION)`\"" \
|
||||||
|
-DGITTAG="\"`LC_ALL=C $(GITTAG)`\"" \
|
||||||
|
-DGITBRANCH="\"`LC_ALL=C $(GITBRANCH)`\"" \
|
||||||
|
-o $@ $(srcdir)/Modules/getbuildinfo.c
|
||||||
|
|
||||||
|
+Python/getcompiler.o: $(srcdir)/Python/getcompiler.c Makefile
|
||||||
|
+ $(CC) -c $(PY_CORE_CFLAGS) \
|
||||||
|
+ -DCOMPILER='"[GCC]"' \
|
||||||
|
+ -o $@ $(srcdir)/Python/getcompiler.c
|
||||||
|
+
|
||||||
|
Modules/getpath.o: $(srcdir)/Modules/getpath.c Python/frozen_modules/getpath.h Makefile $(PYTHON_HEADERS)
|
||||||
|
$(CC) -c $(PY_CORE_CFLAGS) -DPYTHONPATH='"$(PYTHONPATH)"' \
|
||||||
|
-DPREFIX='"$(prefix)"' \
|
13
python-3.3.0b1-localpath.patch
Normal file
13
python-3.3.0b1-localpath.patch
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
Index: Python-3.13.0a3/Lib/site.py
|
||||||
|
===================================================================
|
||||||
|
--- Python-3.13.0a3.orig/Lib/site.py
|
||||||
|
+++ Python-3.13.0a3/Lib/site.py
|
||||||
|
@@ -77,7 +77,7 @@ import io
|
||||||
|
import stat
|
||||||
|
|
||||||
|
# Prefixes for site-packages; add additional prefixes like /usr/local here
|
||||||
|
-PREFIXES = [sys.prefix, sys.exec_prefix]
|
||||||
|
+PREFIXES = [sys.prefix, sys.exec_prefix, '/usr/local']
|
||||||
|
# Enable per user site-packages directory
|
||||||
|
# set it to False to disable the feature or True to force the feature
|
||||||
|
ENABLE_USER_SITE = None
|
17
python-3.3.0b1-test-posix_fadvise.patch
Normal file
17
python-3.3.0b1-test-posix_fadvise.patch
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
Lib/test/test_posix.py | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
Index: Python-3.13.0a3/Lib/test/test_posix.py
|
||||||
|
===================================================================
|
||||||
|
--- Python-3.13.0a3.orig/Lib/test/test_posix.py
|
||||||
|
+++ Python-3.13.0a3/Lib/test/test_posix.py
|
||||||
|
@@ -433,7 +433,7 @@ class PosixTester(unittest.TestCase):
|
||||||
|
def test_posix_fadvise(self):
|
||||||
|
fd = os.open(os_helper.TESTFN, os.O_RDONLY)
|
||||||
|
try:
|
||||||
|
- posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_WILLNEED)
|
||||||
|
+ posix.posix_fadvise(fd, 0, 0, posix.POSIX_FADV_RANDOM)
|
||||||
|
finally:
|
||||||
|
os.close(fd)
|
||||||
|
|
78
python.keyring
Normal file
78
python.keyring
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
=J6BY
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
3
python313-rpmlintrc
Normal file
3
python313-rpmlintrc
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
addFilter("pem-certificate.*/usr/lib.*/python.*/test/*.pem")
|
||||||
|
addFilter("devel-file-in-non-devel-package.*/usr/lib.*/python.*/tests/*.c")
|
||||||
|
addFilter("devel-file-in-non-devel-package.*/usr/lib.*/python.*/test/*.cpp")
|
7851
python313.changes
Normal file
7851
python313.changes
Normal file
File diff suppressed because it is too large
Load Diff
1047
python313.spec
Normal file
1047
python313.spec
Normal file
File diff suppressed because it is too large
Load Diff
16
skip-test_pyobject_freed_is_freed.patch
Normal file
16
skip-test_pyobject_freed_is_freed.patch
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
Lib/test/test_capi/test_mem.py | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
Index: Python-3.13.0a3/Lib/test/test_capi/test_mem.py
|
||||||
|
===================================================================
|
||||||
|
--- Python-3.13.0a3.orig/Lib/test/test_capi/test_mem.py
|
||||||
|
+++ Python-3.13.0a3/Lib/test/test_capi/test_mem.py
|
||||||
|
@@ -109,6 +109,7 @@ class PyMemDebugTests(unittest.TestCase)
|
||||||
|
def test_pyobject_forbidden_bytes_is_freed(self):
|
||||||
|
self.check_pyobject_is_freed('check_pyobject_forbidden_bytes_is_freed')
|
||||||
|
|
||||||
|
+ @unittest.skip('Failing on Leap 15.*')
|
||||||
|
def test_pyobject_freed_is_freed(self):
|
||||||
|
self.check_pyobject_is_freed('check_pyobject_freed_is_freed')
|
||||||
|
|
16
skip_test_abort_clients.patch
Normal file
16
skip_test_abort_clients.patch
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
Lib/test/test_asyncio/test_server.py | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
Index: Python-3.13.0rc1/Lib/test/test_asyncio/test_server.py
|
||||||
|
===================================================================
|
||||||
|
--- Python-3.13.0rc1.orig/Lib/test/test_asyncio/test_server.py
|
||||||
|
+++ Python-3.13.0rc1/Lib/test/test_asyncio/test_server.py
|
||||||
|
@@ -212,6 +212,7 @@ class TestServer2(unittest.IsolatedAsync
|
||||||
|
await asyncio.sleep(0)
|
||||||
|
self.assertTrue(task.done())
|
||||||
|
|
||||||
|
+ @unittest.skip('Failing test gh#python/cpython#122136')
|
||||||
|
async def test_abort_clients(self):
|
||||||
|
async def serve(rd, wr):
|
||||||
|
fut.set_result((rd, wr))
|
69
skipped_tests.py
Normal file
69
skipped_tests.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
"""
|
||||||
|
Simple regexp-based skipped test checker.
|
||||||
|
It lists tests that are mentioned (presumably for exclusion)
|
||||||
|
in BASE, and in MAIN (presumably for inclusion)
|
||||||
|
and reports discrepancies.
|
||||||
|
|
||||||
|
This will have a number of
|
||||||
|
"""
|
||||||
|
|
||||||
|
MAIN = "python39.spec"
|
||||||
|
|
||||||
|
import glob
|
||||||
|
import re
|
||||||
|
from os.path import basename
|
||||||
|
|
||||||
|
alltests = set()
|
||||||
|
qemu_exclusions = set()
|
||||||
|
|
||||||
|
for item in glob.glob("Python-*/Lib/test/test_*"):
|
||||||
|
testname = basename(item)
|
||||||
|
if testname.endswith(".py"):
|
||||||
|
testname = testname[:-3]
|
||||||
|
alltests.add(testname)
|
||||||
|
|
||||||
|
testre = re.compile(r'[\s"](test_\w+)\b')
|
||||||
|
|
||||||
|
def find_tests_in_spec(specname):
|
||||||
|
global qemu_exclusions
|
||||||
|
|
||||||
|
found_tests = set()
|
||||||
|
with open(specname) as spec:
|
||||||
|
in_qemu = False
|
||||||
|
for line in spec:
|
||||||
|
line = line.strip()
|
||||||
|
if "#" in line:
|
||||||
|
line = line[:line.index("#")]
|
||||||
|
tests = set(testre.findall(line))
|
||||||
|
found_tests |= tests
|
||||||
|
if line == "%if 0%{?qemu_user_space_build} > 0":
|
||||||
|
in_qemu = True
|
||||||
|
if in_qemu:
|
||||||
|
if line == "%endif":
|
||||||
|
in_qemu = False
|
||||||
|
qemu_exclusions |= tests
|
||||||
|
return found_tests
|
||||||
|
|
||||||
|
excluded = find_tests_in_spec(MAIN)
|
||||||
|
|
||||||
|
#print("--- excluded tests:", " ".join(sorted(excluded)))
|
||||||
|
#print("--- included tests:", " ".join(sorted(included)))
|
||||||
|
|
||||||
|
mentioned = excluded
|
||||||
|
nonexistent = mentioned - alltests
|
||||||
|
missing = excluded - qemu_exclusions
|
||||||
|
|
||||||
|
print("--- the following tests are excluded for QEMU and not tested in python")
|
||||||
|
print("--- (that probably means we don't need to worry about them)")
|
||||||
|
for test in sorted(qemu_exclusions - excluded):
|
||||||
|
print(test)
|
||||||
|
|
||||||
|
print("--- the following tests might be excluded in python:")
|
||||||
|
for test in sorted(missing):
|
||||||
|
print(test)
|
||||||
|
|
||||||
|
if nonexistent:
|
||||||
|
print("--- the following tests don't exist:")
|
||||||
|
for test in sorted(nonexistent):
|
||||||
|
print(test)
|
16
subprocess-raise-timeout.patch
Normal file
16
subprocess-raise-timeout.patch
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
Lib/test/test_subprocess.py | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/Lib/test/test_subprocess.py
|
||||||
|
+++ b/Lib/test/test_subprocess.py
|
||||||
|
@@ -280,7 +280,8 @@ class ProcessTestCase(BaseTestCase):
|
||||||
|
"time.sleep(3600)"],
|
||||||
|
# Some heavily loaded buildbots (sparc Debian 3.x) require
|
||||||
|
# this much time to start and print.
|
||||||
|
- timeout=3)
|
||||||
|
+ # OBS might require even more
|
||||||
|
+ timeout=10)
|
||||||
|
self.fail("Expected TimeoutExpired.")
|
||||||
|
self.assertEqual(c.exception.output, b'BDFL')
|
||||||
|
|
Loading…
Reference in New Issue
Block a user