Skip to content

Commit 906cc1e

Browse files
authored
Merge branch 'main' into deferred_dunder_new
2 parents 48c0e94 + e65e9f9 commit 906cc1e

25 files changed

+379
-265
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,7 @@ jobs:
658658
build_asan,
659659
build_tsan,
660660
test_hypothesis,
661+
cross-build-linux,
661662
'
662663
|| ''
663664
}}

Doc/c-api/unicode.rst

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -256,13 +256,8 @@ the Python configuration.
256256
257257
.. c:function:: int Py_UNICODE_ISPRINTABLE(Py_UCS4 ch)
258258
259-
Return ``1`` or ``0`` depending on whether *ch* is a printable character.
260-
Nonprintable characters are those characters defined in the Unicode character
261-
database as "Other" or "Separator", excepting the ASCII space (0x20) which is
262-
considered printable. (Note that printable characters in this context are
263-
those which should not be escaped when :func:`repr` is invoked on a string.
264-
It has no bearing on the handling of strings written to :data:`sys.stdout` or
265-
:data:`sys.stderr`.)
259+
Return ``1`` or ``0`` depending on whether *ch* is a printable character,
260+
in the sense of :meth:`str.isprintable`.
266261
267262
268263
These APIs can be used for fast direct character conversions:

Doc/glossary.rst

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -939,11 +939,16 @@ Glossary
939939
modules, respectively.
940940

941941
namespace package
942-
A :pep:`420` :term:`package` which serves only as a container for
943-
subpackages. Namespace packages may have no physical representation,
942+
A :term:`package` which serves only as a container for subpackages.
943+
Namespace packages may have no physical representation,
944944
and specifically are not like a :term:`regular package` because they
945945
have no ``__init__.py`` file.
946946

947+
Namespace packages allow several individually installable packages to have a common parent package.
948+
Otherwise, it is recommended to use a :term:`regular package`.
949+
950+
For more information, see :pep:`420` and :ref:`reference-namespace-package`.
951+
947952
See also :term:`module`.
948953

949954
nested scope

Doc/library/stdtypes.rst

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2012,13 +2012,19 @@ expression support in the :mod:`re` module).
20122012

20132013
.. method:: str.isprintable()
20142014

2015-
Return ``True`` if all characters in the string are printable or the string is
2016-
empty, ``False`` otherwise. Nonprintable characters are those characters defined
2017-
in the Unicode character database as "Other" or "Separator", excepting the
2018-
ASCII space (0x20) which is considered printable. (Note that printable
2019-
characters in this context are those which should not be escaped when
2020-
:func:`repr` is invoked on a string. It has no bearing on the handling of
2021-
strings written to :data:`sys.stdout` or :data:`sys.stderr`.)
2015+
Return true if all characters in the string are printable, false if it
2016+
contains at least one non-printable character.
2017+
2018+
Here "printable" means the character is suitable for :func:`repr` to use in
2019+
its output; "non-printable" means that :func:`repr` on built-in types will
2020+
hex-escape the character. It has no bearing on the handling of strings
2021+
written to :data:`sys.stdout` or :data:`sys.stderr`.
2022+
2023+
The printable characters are those which in the Unicode character database
2024+
(see :mod:`unicodedata`) have a general category in group Letter, Mark,
2025+
Number, Punctuation, or Symbol (L, M, N, P, or S); plus the ASCII space 0x20.
2026+
Nonprintable characters are those in group Separator or Other (Z or C),
2027+
except the ASCII space.
20222028

20232029

20242030
.. method:: str.isspace()

Doc/reference/import.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ Importing ``parent.one`` will implicitly execute ``parent/__init__.py`` and
123123
``parent/three/__init__.py`` respectively.
124124

125125

126+
.. _reference-namespace-package:
127+
126128
Namespace packages
127129
------------------
128130

Grammar/python.gram

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ import_name[stmt_ty]: 'import' a=dotted_as_names { _PyAST_Import(a, EXTRA) }
207207
# note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS
208208
import_from[stmt_ty]:
209209
| 'from' a=('.' | '...')* b=dotted_name 'import' c=import_from_targets {
210-
_PyAST_ImportFrom(b->v.Name.id, c, _PyPegen_seq_count_dots(a), EXTRA) }
210+
_PyPegen_checked_future_import(p, b->v.Name.id, c, _PyPegen_seq_count_dots(a), EXTRA) }
211211
| 'from' a=('.' | '...')+ 'import' b=import_from_targets {
212212
_PyAST_ImportFrom(NULL, b, _PyPegen_seq_count_dots(a), EXTRA) }
213213
import_from_targets[asdl_alias_seq*]:

Lib/mimetypes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ def add_type(self, type, ext, strict=True):
9090
list of standard types, else to the list of non-standard
9191
types.
9292
"""
93+
if not type:
94+
return
9395
self.types_map[strict][ext] = type
9496
exts = self.types_map_inv[strict].setdefault(type, [])
9597
if ext not in exts:

Lib/test/test_flufl.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,32 @@ def test_guido_as_bdfl(self):
3434
# parser reports the start of the token
3535
self.assertEqual(cm.exception.offset, 3)
3636

37+
def test_barry_as_bdfl_look_ma_with_no_compiler_flags(self):
38+
# Check that the future import is handled by the parser
39+
# even if the compiler flags are not passed.
40+
code = "from __future__ import barry_as_FLUFL;2 {0} 3"
41+
compile(code.format('<>'), '<BDFL test>', 'exec')
42+
with self.assertRaises(SyntaxError) as cm:
43+
compile(code.format('!='), '<FLUFL test>', 'exec')
44+
self.assertRegex(str(cm.exception), "with Barry as BDFL, use '<>' instead of '!='")
45+
self.assertIn('2 != 3', cm.exception.text)
46+
self.assertEqual(cm.exception.filename, '<FLUFL test>')
47+
self.assertEqual(cm.exception.lineno, 1)
48+
self.assertEqual(cm.exception.offset, len(code) - 4)
49+
50+
def test_barry_as_bdfl_relative_import(self):
51+
code = "from .__future__ import barry_as_FLUFL;2 {0} 3"
52+
compile(code.format('!='), '<FLUFL test>', 'exec')
53+
with self.assertRaises(SyntaxError) as cm:
54+
compile(code.format('<>'), '<BDFL test>', 'exec')
55+
self.assertRegex(str(cm.exception), "<BDFL test>")
56+
self.assertIn('2 <> 3', cm.exception.text)
57+
self.assertEqual(cm.exception.filename, '<BDFL test>')
58+
self.assertEqual(cm.exception.lineno, 1)
59+
self.assertEqual(cm.exception.offset, len(code) - 4)
60+
61+
62+
3763

3864
if __name__ == '__main__':
3965
unittest.main()

Lib/test/test_gettext.py

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
# TODO:
1212
# - Add new tests, for example for "dgettext"
13-
# - Remove dummy tests, for example testing for single and double quotes
14-
# has no sense, it would have if we were testing a parser (i.e. pygettext)
1513
# - Tests should have only one assert.
1614

1715
GNU_MO_DATA = b'''\
@@ -175,30 +173,6 @@ def test_some_translations_with_context(self):
175173
eq(pgettext('my other context', 'nudge nudge'),
176174
'wink wink (in "my other context")')
177175

178-
def test_double_quotes(self):
179-
eq = self.assertEqual
180-
# double quotes
181-
eq(_("albatross"), 'albatross')
182-
eq(_("mullusk"), 'bacon')
183-
eq(_(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
184-
eq(_(r"nudge nudge"), 'wink wink')
185-
186-
def test_triple_single_quotes(self):
187-
eq = self.assertEqual
188-
# triple single quotes
189-
eq(_('''albatross'''), 'albatross')
190-
eq(_('''mullusk'''), 'bacon')
191-
eq(_(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
192-
eq(_(r'''nudge nudge'''), 'wink wink')
193-
194-
def test_triple_double_quotes(self):
195-
eq = self.assertEqual
196-
# triple double quotes
197-
eq(_("""albatross"""), 'albatross')
198-
eq(_("""mullusk"""), 'bacon')
199-
eq(_(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
200-
eq(_(r"""nudge nudge"""), 'wink wink')
201-
202176
def test_multiline_strings(self):
203177
eq = self.assertEqual
204178
# multiline strings
@@ -285,30 +259,6 @@ def test_some_translations_with_context_and_domain(self):
285259
eq(gettext.dpgettext('gettext', 'my other context', 'nudge nudge'),
286260
'wink wink (in "my other context")')
287261

288-
def test_double_quotes(self):
289-
eq = self.assertEqual
290-
# double quotes
291-
eq(self._("albatross"), 'albatross')
292-
eq(self._("mullusk"), 'bacon')
293-
eq(self._(r"Raymond Luxury Yach-t"), 'Throatwobbler Mangrove')
294-
eq(self._(r"nudge nudge"), 'wink wink')
295-
296-
def test_triple_single_quotes(self):
297-
eq = self.assertEqual
298-
# triple single quotes
299-
eq(self._('''albatross'''), 'albatross')
300-
eq(self._('''mullusk'''), 'bacon')
301-
eq(self._(r'''Raymond Luxury Yach-t'''), 'Throatwobbler Mangrove')
302-
eq(self._(r'''nudge nudge'''), 'wink wink')
303-
304-
def test_triple_double_quotes(self):
305-
eq = self.assertEqual
306-
# triple double quotes
307-
eq(self._("""albatross"""), 'albatross')
308-
eq(self._("""mullusk"""), 'bacon')
309-
eq(self._(r"""Raymond Luxury Yach-t"""), 'Throatwobbler Mangrove')
310-
eq(self._(r"""nudge nudge"""), 'wink wink')
311-
312262
def test_multiline_strings(self):
313263
eq = self.assertEqual
314264
# multiline strings

Lib/test/test_peepholer.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,83 @@ def test_folding_subscript(self):
535535
self.assertInBytecode(code, 'BINARY_OP', argval=subscr_argval)
536536
self.check_lnotab(code)
537537

538+
def test_constant_folding_remove_nop_location(self):
539+
sources = [
540+
"""
541+
(-
542+
-
543+
-
544+
1)
545+
""",
546+
547+
"""
548+
(1
549+
+
550+
2
551+
+
552+
3)
553+
""",
554+
555+
"""
556+
(1,
557+
2,
558+
3)[0]
559+
""",
560+
561+
"""
562+
[1,
563+
2,
564+
3]
565+
""",
566+
567+
"""
568+
{1,
569+
2,
570+
3}
571+
""",
572+
573+
"""
574+
1 in [
575+
1,
576+
2,
577+
3
578+
]
579+
""",
580+
581+
"""
582+
1 in {
583+
1,
584+
2,
585+
3
586+
}
587+
""",
588+
589+
"""
590+
for _ in [1,
591+
2,
592+
3]:
593+
pass
594+
""",
595+
596+
"""
597+
for _ in [1,
598+
2,
599+
x]:
600+
pass
601+
""",
602+
603+
"""
604+
for _ in {1,
605+
2,
606+
3}:
607+
pass
608+
"""
609+
]
610+
611+
for source in sources:
612+
code = compile(textwrap.dedent(source), '', 'single')
613+
self.assertNotInBytecode(code, 'NOP')
614+
538615
def test_in_literal_list(self):
539616
def containtest():
540617
return x in [a, b]

0 commit comments

Comments
 (0)