Skip to content

Commit a2a1c17

Browse files
authored
Merge branch 'main' into expose_codegen
2 parents b07b9c6 + 47ab848 commit a2a1c17

19 files changed

+344
-54
lines changed

Include/internal/pycore_global_strings.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ struct _Py_global_strings {
3737
STRUCT_FOR_STR(anon_string, "<string>")
3838
STRUCT_FOR_STR(anon_unknown, "<unknown>")
3939
STRUCT_FOR_STR(close_br, "}")
40-
STRUCT_FOR_STR(comma_sep, ", ")
4140
STRUCT_FOR_STR(dbl_close_br, "}}")
4241
STRUCT_FOR_STR(dbl_open_br, "{{")
4342
STRUCT_FOR_STR(dbl_percent, "%%")

Include/internal/pycore_runtime_init_generated.h

Lines changed: 0 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/ensurepip/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
__all__ = ["version", "bootstrap"]
1212
_PACKAGE_NAMES = ('setuptools', 'pip')
1313
_SETUPTOOLS_VERSION = "65.5.0"
14-
_PIP_VERSION = "22.3"
14+
_PIP_VERSION = "22.3.1"
1515
_PROJECTS = [
1616
("setuptools", _SETUPTOOLS_VERSION, "py3"),
1717
("pip", _PIP_VERSION, "py3"),

Lib/test/test_abc.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ class C(metaclass=abc_ABCMeta):
154154
@abc.abstractmethod
155155
def method_one(self):
156156
pass
157-
msg = r"class C without an implementation for abstract method method_one"
157+
msg = r"class C without an implementation for abstract method 'method_one'"
158158
self.assertRaisesRegex(TypeError, msg, C)
159159

160160
def test_object_new_with_many_abstractmethods(self):
@@ -165,7 +165,7 @@ def method_one(self):
165165
@abc.abstractmethod
166166
def method_two(self):
167167
pass
168-
msg = r"class C without an implementation for abstract methods method_one, method_two"
168+
msg = r"class C without an implementation for abstract methods 'method_one', 'method_two'"
169169
self.assertRaisesRegex(TypeError, msg, C)
170170

171171
def test_abstractmethod_integration(self):
@@ -535,7 +535,7 @@ def updated_foo(self):
535535
A.foo = updated_foo
536536
abc.update_abstractmethods(A)
537537
self.assertEqual(A.__abstractmethods__, {'foo', 'bar'})
538-
msg = "class A without an implementation for abstract methods bar, foo"
538+
msg = "class A without an implementation for abstract methods 'bar', 'foo'"
539539
self.assertRaisesRegex(TypeError, msg, A)
540540

541541
def test_update_implementation(self):
@@ -547,7 +547,7 @@ def foo(self):
547547
class B(A):
548548
pass
549549

550-
msg = "class B without an implementation for abstract method foo"
550+
msg = "class B without an implementation for abstract method 'foo'"
551551
self.assertRaisesRegex(TypeError, msg, B)
552552
self.assertEqual(B.__abstractmethods__, {'foo'})
553553

@@ -605,7 +605,7 @@ def foo(self):
605605

606606
abc.update_abstractmethods(B)
607607

608-
msg = "class B without an implementation for abstract method foo"
608+
msg = "class B without an implementation for abstract method 'foo'"
609609
self.assertRaisesRegex(TypeError, msg, B)
610610

611611
def test_update_layered_implementation(self):
@@ -627,7 +627,7 @@ def foo(self):
627627

628628
abc.update_abstractmethods(C)
629629

630-
msg = "class C without an implementation for abstract method foo"
630+
msg = "class C without an implementation for abstract method 'foo'"
631631
self.assertRaisesRegex(TypeError, msg, C)
632632

633633
def test_update_multi_inheritance(self):

Lib/test/test_capi.py

Lines changed: 190 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,86 @@ class SubDict(dict):
416416
self.assertTrue(_testcapi.mapping_has_key(dct2, 'a'))
417417
self.assertFalse(_testcapi.mapping_has_key(dct2, 'b'))
418418

419+
def test_sequence_set_slice(self):
420+
# Correct case:
421+
data = [1, 2, 3, 4, 5]
422+
data_copy = data.copy()
423+
424+
_testcapi.sequence_set_slice(data, 1, 3, [8, 9])
425+
data_copy[1:3] = [8, 9]
426+
self.assertEqual(data, data_copy)
427+
self.assertEqual(data, [1, 8, 9, 4, 5])
428+
429+
# Custom class:
430+
class Custom:
431+
def __setitem__(self, index, value):
432+
self.index = index
433+
self.value = value
434+
435+
c = Custom()
436+
_testcapi.sequence_set_slice(c, 0, 5, 'abc')
437+
self.assertEqual(c.index, slice(0, 5))
438+
self.assertEqual(c.value, 'abc')
439+
440+
# Immutable sequences must raise:
441+
bad_seq1 = (1, 2, 3, 4)
442+
with self.assertRaises(TypeError):
443+
_testcapi.sequence_set_slice(bad_seq1, 1, 3, (8, 9))
444+
self.assertEqual(bad_seq1, (1, 2, 3, 4))
445+
446+
bad_seq2 = 'abcd'
447+
with self.assertRaises(TypeError):
448+
_testcapi.sequence_set_slice(bad_seq2, 1, 3, 'xy')
449+
self.assertEqual(bad_seq2, 'abcd')
450+
451+
# Not a sequence:
452+
with self.assertRaises(TypeError):
453+
_testcapi.sequence_set_slice(None, 1, 3, 'xy')
454+
455+
mapping = {1: 'a', 2: 'b', 3: 'c'}
456+
with self.assertRaises(TypeError):
457+
_testcapi.sequence_set_slice(mapping, 1, 3, 'xy')
458+
self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'})
459+
460+
def test_sequence_del_slice(self):
461+
# Correct case:
462+
data = [1, 2, 3, 4, 5]
463+
data_copy = data.copy()
464+
465+
_testcapi.sequence_del_slice(data, 1, 3)
466+
del data_copy[1:3]
467+
self.assertEqual(data, data_copy)
468+
self.assertEqual(data, [1, 4, 5])
469+
470+
# Custom class:
471+
class Custom:
472+
def __delitem__(self, index):
473+
self.index = index
474+
475+
c = Custom()
476+
_testcapi.sequence_del_slice(c, 0, 5)
477+
self.assertEqual(c.index, slice(0, 5))
478+
479+
# Immutable sequences must raise:
480+
bad_seq1 = (1, 2, 3, 4)
481+
with self.assertRaises(TypeError):
482+
_testcapi.sequence_del_slice(bad_seq1, 1, 3)
483+
self.assertEqual(bad_seq1, (1, 2, 3, 4))
484+
485+
bad_seq2 = 'abcd'
486+
with self.assertRaises(TypeError):
487+
_testcapi.sequence_del_slice(bad_seq2, 1, 3)
488+
self.assertEqual(bad_seq2, 'abcd')
489+
490+
# Not a sequence:
491+
with self.assertRaises(TypeError):
492+
_testcapi.sequence_del_slice(None, 1, 3)
493+
494+
mapping = {1: 'a', 2: 'b', 3: 'c'}
495+
with self.assertRaises(TypeError):
496+
_testcapi.sequence_del_slice(mapping, 1, 3)
497+
self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'})
498+
419499
@unittest.skipUnless(hasattr(_testcapi, 'negative_refcount'),
420500
'need _testcapi.negative_refcount')
421501
def test_negative_refcount(self):
@@ -907,6 +987,21 @@ def method_example(self): ...
907987
self.assertEqual(_testcapi.eval_get_func_name(sum), "sum") # c function
908988
self.assertEqual(_testcapi.eval_get_func_name(A), "type")
909989

990+
def test_eval_get_func_desc(self):
991+
def function_example(): ...
992+
993+
class A:
994+
def method_example(self): ...
995+
996+
self.assertEqual(_testcapi.eval_get_func_desc(function_example),
997+
"()")
998+
self.assertEqual(_testcapi.eval_get_func_desc(A.method_example),
999+
"()")
1000+
self.assertEqual(_testcapi.eval_get_func_desc(A().method_example),
1001+
"()")
1002+
self.assertEqual(_testcapi.eval_get_func_desc(sum), "()") # c function
1003+
self.assertEqual(_testcapi.eval_get_func_desc(A), " object")
1004+
9101005
def test_function_get_code(self):
9111006
import types
9121007

@@ -943,18 +1038,32 @@ def some():
9431038
_testcapi.function_get_module(None) # not a function
9441039

9451040
def test_function_get_defaults(self):
946-
def some(pos_only='p', zero=0, optional=None):
1041+
def some(
1042+
pos_only1, pos_only2='p',
1043+
/,
1044+
zero=0, optional=None,
1045+
*,
1046+
kw1,
1047+
kw2=True,
1048+
):
9471049
pass
9481050

9491051
defaults = _testcapi.function_get_defaults(some)
9501052
self.assertEqual(defaults, ('p', 0, None))
9511053
self.assertEqual(defaults, some.__defaults__)
9521054

9531055
with self.assertRaises(SystemError):
954-
_testcapi.function_get_module(None) # not a function
1056+
_testcapi.function_get_defaults(None) # not a function
9551057

9561058
def test_function_set_defaults(self):
957-
def some(pos_only='p', zero=0, optional=None):
1059+
def some(
1060+
pos_only1, pos_only2='p',
1061+
/,
1062+
zero=0, optional=None,
1063+
*,
1064+
kw1,
1065+
kw2=True,
1066+
):
9581067
pass
9591068

9601069
old_defaults = ('p', 0, None)
@@ -966,11 +1075,22 @@ def some(pos_only='p', zero=0, optional=None):
9661075
self.assertEqual(_testcapi.function_get_defaults(some), old_defaults)
9671076
self.assertEqual(some.__defaults__, old_defaults)
9681077

1078+
with self.assertRaises(SystemError):
1079+
_testcapi.function_set_defaults(1, ()) # not a function
1080+
self.assertEqual(_testcapi.function_get_defaults(some), old_defaults)
1081+
self.assertEqual(some.__defaults__, old_defaults)
1082+
9691083
new_defaults = ('q', 1, None)
9701084
_testcapi.function_set_defaults(some, new_defaults)
9711085
self.assertEqual(_testcapi.function_get_defaults(some), new_defaults)
9721086
self.assertEqual(some.__defaults__, new_defaults)
9731087

1088+
# Empty tuple is fine:
1089+
new_defaults = ()
1090+
_testcapi.function_set_defaults(some, new_defaults)
1091+
self.assertEqual(_testcapi.function_get_defaults(some), new_defaults)
1092+
self.assertEqual(some.__defaults__, new_defaults)
1093+
9741094
class tuplesub(tuple): ... # tuple subclasses must work
9751095

9761096
new_defaults = tuplesub(((1, 2), ['a', 'b'], None))
@@ -984,6 +1104,73 @@ class tuplesub(tuple): ... # tuple subclasses must work
9841104
self.assertEqual(_testcapi.function_get_defaults(some), None)
9851105
self.assertEqual(some.__defaults__, None)
9861106

1107+
def test_function_get_kw_defaults(self):
1108+
def some(
1109+
pos_only1, pos_only2='p',
1110+
/,
1111+
zero=0, optional=None,
1112+
*,
1113+
kw1,
1114+
kw2=True,
1115+
):
1116+
pass
1117+
1118+
defaults = _testcapi.function_get_kw_defaults(some)
1119+
self.assertEqual(defaults, {'kw2': True})
1120+
self.assertEqual(defaults, some.__kwdefaults__)
1121+
1122+
with self.assertRaises(SystemError):
1123+
_testcapi.function_get_kw_defaults(None) # not a function
1124+
1125+
def test_function_set_kw_defaults(self):
1126+
def some(
1127+
pos_only1, pos_only2='p',
1128+
/,
1129+
zero=0, optional=None,
1130+
*,
1131+
kw1,
1132+
kw2=True,
1133+
):
1134+
pass
1135+
1136+
old_defaults = {'kw2': True}
1137+
self.assertEqual(_testcapi.function_get_kw_defaults(some), old_defaults)
1138+
self.assertEqual(some.__kwdefaults__, old_defaults)
1139+
1140+
with self.assertRaises(SystemError):
1141+
_testcapi.function_set_kw_defaults(some, 1) # not dict or None
1142+
self.assertEqual(_testcapi.function_get_kw_defaults(some), old_defaults)
1143+
self.assertEqual(some.__kwdefaults__, old_defaults)
1144+
1145+
with self.assertRaises(SystemError):
1146+
_testcapi.function_set_kw_defaults(1, {}) # not a function
1147+
self.assertEqual(_testcapi.function_get_kw_defaults(some), old_defaults)
1148+
self.assertEqual(some.__kwdefaults__, old_defaults)
1149+
1150+
new_defaults = {'kw2': (1, 2, 3)}
1151+
_testcapi.function_set_kw_defaults(some, new_defaults)
1152+
self.assertEqual(_testcapi.function_get_kw_defaults(some), new_defaults)
1153+
self.assertEqual(some.__kwdefaults__, new_defaults)
1154+
1155+
# Empty dict is fine:
1156+
new_defaults = {}
1157+
_testcapi.function_set_kw_defaults(some, new_defaults)
1158+
self.assertEqual(_testcapi.function_get_kw_defaults(some), new_defaults)
1159+
self.assertEqual(some.__kwdefaults__, new_defaults)
1160+
1161+
class dictsub(dict): ... # dict subclasses must work
1162+
1163+
new_defaults = dictsub({'kw2': None})
1164+
_testcapi.function_set_kw_defaults(some, new_defaults)
1165+
self.assertEqual(_testcapi.function_get_kw_defaults(some), new_defaults)
1166+
self.assertEqual(some.__kwdefaults__, new_defaults)
1167+
1168+
# `None` is special, it sets `kwdefaults` to `NULL`,
1169+
# it needs special handling in `_testcapi`:
1170+
_testcapi.function_set_kw_defaults(some, None)
1171+
self.assertEqual(_testcapi.function_get_kw_defaults(some), None)
1172+
self.assertEqual(some.__kwdefaults__, None)
1173+
9871174

9881175
class TestPendingCalls(unittest.TestCase):
9891176

Lib/test/test_dataclasses.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3970,7 +3970,7 @@ class Date(A):
39703970
day: 'int'
39713971

39723972
self.assertTrue(inspect.isabstract(Date))
3973-
msg = 'class Date without an implementation for abstract method foo'
3973+
msg = "class Date without an implementation for abstract method 'foo'"
39743974
self.assertRaisesRegex(TypeError, msg, Date)
39753975

39763976

Makefile.pre.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1224,7 +1224,7 @@ regen-limited-abi: all
12241224
############################################################################
12251225
# Regenerate all generated files
12261226

1227-
regen-all: regen-opcode regen-opcode-targets regen-typeslots \
1227+
regen-all: regen-cases regen-opcode regen-opcode-targets regen-typeslots \
12281228
regen-token regen-ast regen-keyword regen-sre regen-frozen clinic \
12291229
regen-pegen-metaparser regen-pegen regen-test-frozenmain \
12301230
regen-test-levenshtein regen-global-objects
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix ``-Wimplicit-int`` compiler warning in :program:`configure` check for ``PTHREAD_SCOPE_SYSTEM``.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Improved :class:`TypeError` message for undefined abstract methods of a
2+
:class:`abc.ABC` instance. The names of the missing methods are surrounded
3+
by single-quotes to highlight them.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Update the bundled copy of pip to version 22.3.1.

0 commit comments

Comments
 (0)