Skip to content

Commit

Permalink
Merge branch 'main' into expose_codegen
Browse files Browse the repository at this point in the history
  • Loading branch information
iritkatriel committed Nov 5, 2022
2 parents b07b9c6 + 47ab848 commit a2a1c17
Show file tree
Hide file tree
Showing 19 changed files with 344 additions and 54 deletions.
1 change: 0 additions & 1 deletion Include/internal/pycore_global_strings.h
Expand Up @@ -37,7 +37,6 @@ struct _Py_global_strings {
STRUCT_FOR_STR(anon_string, "<string>")
STRUCT_FOR_STR(anon_unknown, "<unknown>")
STRUCT_FOR_STR(close_br, "}")
STRUCT_FOR_STR(comma_sep, ", ")
STRUCT_FOR_STR(dbl_close_br, "}}")
STRUCT_FOR_STR(dbl_open_br, "{{")
STRUCT_FOR_STR(dbl_percent, "%%")
Expand Down
5 changes: 0 additions & 5 deletions Include/internal/pycore_runtime_init_generated.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Lib/ensurepip/__init__.py
Expand Up @@ -11,7 +11,7 @@
__all__ = ["version", "bootstrap"]
_PACKAGE_NAMES = ('setuptools', 'pip')
_SETUPTOOLS_VERSION = "65.5.0"
_PIP_VERSION = "22.3"
_PIP_VERSION = "22.3.1"
_PROJECTS = [
("setuptools", _SETUPTOOLS_VERSION, "py3"),
("pip", _PIP_VERSION, "py3"),
Expand Down
Binary file not shown.
12 changes: 6 additions & 6 deletions Lib/test/test_abc.py
Expand Up @@ -154,7 +154,7 @@ class C(metaclass=abc_ABCMeta):
@abc.abstractmethod
def method_one(self):
pass
msg = r"class C without an implementation for abstract method method_one"
msg = r"class C without an implementation for abstract method 'method_one'"
self.assertRaisesRegex(TypeError, msg, C)

def test_object_new_with_many_abstractmethods(self):
Expand All @@ -165,7 +165,7 @@ def method_one(self):
@abc.abstractmethod
def method_two(self):
pass
msg = r"class C without an implementation for abstract methods method_one, method_two"
msg = r"class C without an implementation for abstract methods 'method_one', 'method_two'"
self.assertRaisesRegex(TypeError, msg, C)

def test_abstractmethod_integration(self):
Expand Down Expand Up @@ -535,7 +535,7 @@ def updated_foo(self):
A.foo = updated_foo
abc.update_abstractmethods(A)
self.assertEqual(A.__abstractmethods__, {'foo', 'bar'})
msg = "class A without an implementation for abstract methods bar, foo"
msg = "class A without an implementation for abstract methods 'bar', 'foo'"
self.assertRaisesRegex(TypeError, msg, A)

def test_update_implementation(self):
Expand All @@ -547,7 +547,7 @@ def foo(self):
class B(A):
pass

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

Expand Down Expand Up @@ -605,7 +605,7 @@ def foo(self):

abc.update_abstractmethods(B)

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

def test_update_layered_implementation(self):
Expand All @@ -627,7 +627,7 @@ def foo(self):

abc.update_abstractmethods(C)

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

def test_update_multi_inheritance(self):
Expand Down
193 changes: 190 additions & 3 deletions Lib/test/test_capi.py
Expand Up @@ -416,6 +416,86 @@ class SubDict(dict):
self.assertTrue(_testcapi.mapping_has_key(dct2, 'a'))
self.assertFalse(_testcapi.mapping_has_key(dct2, 'b'))

def test_sequence_set_slice(self):
# Correct case:
data = [1, 2, 3, 4, 5]
data_copy = data.copy()

_testcapi.sequence_set_slice(data, 1, 3, [8, 9])
data_copy[1:3] = [8, 9]
self.assertEqual(data, data_copy)
self.assertEqual(data, [1, 8, 9, 4, 5])

# Custom class:
class Custom:
def __setitem__(self, index, value):
self.index = index
self.value = value

c = Custom()
_testcapi.sequence_set_slice(c, 0, 5, 'abc')
self.assertEqual(c.index, slice(0, 5))
self.assertEqual(c.value, 'abc')

# Immutable sequences must raise:
bad_seq1 = (1, 2, 3, 4)
with self.assertRaises(TypeError):
_testcapi.sequence_set_slice(bad_seq1, 1, 3, (8, 9))
self.assertEqual(bad_seq1, (1, 2, 3, 4))

bad_seq2 = 'abcd'
with self.assertRaises(TypeError):
_testcapi.sequence_set_slice(bad_seq2, 1, 3, 'xy')
self.assertEqual(bad_seq2, 'abcd')

# Not a sequence:
with self.assertRaises(TypeError):
_testcapi.sequence_set_slice(None, 1, 3, 'xy')

mapping = {1: 'a', 2: 'b', 3: 'c'}
with self.assertRaises(TypeError):
_testcapi.sequence_set_slice(mapping, 1, 3, 'xy')
self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'})

def test_sequence_del_slice(self):
# Correct case:
data = [1, 2, 3, 4, 5]
data_copy = data.copy()

_testcapi.sequence_del_slice(data, 1, 3)
del data_copy[1:3]
self.assertEqual(data, data_copy)
self.assertEqual(data, [1, 4, 5])

# Custom class:
class Custom:
def __delitem__(self, index):
self.index = index

c = Custom()
_testcapi.sequence_del_slice(c, 0, 5)
self.assertEqual(c.index, slice(0, 5))

# Immutable sequences must raise:
bad_seq1 = (1, 2, 3, 4)
with self.assertRaises(TypeError):
_testcapi.sequence_del_slice(bad_seq1, 1, 3)
self.assertEqual(bad_seq1, (1, 2, 3, 4))

bad_seq2 = 'abcd'
with self.assertRaises(TypeError):
_testcapi.sequence_del_slice(bad_seq2, 1, 3)
self.assertEqual(bad_seq2, 'abcd')

# Not a sequence:
with self.assertRaises(TypeError):
_testcapi.sequence_del_slice(None, 1, 3)

mapping = {1: 'a', 2: 'b', 3: 'c'}
with self.assertRaises(TypeError):
_testcapi.sequence_del_slice(mapping, 1, 3)
self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'})

@unittest.skipUnless(hasattr(_testcapi, 'negative_refcount'),
'need _testcapi.negative_refcount')
def test_negative_refcount(self):
Expand Down Expand Up @@ -907,6 +987,21 @@ def method_example(self): ...
self.assertEqual(_testcapi.eval_get_func_name(sum), "sum") # c function
self.assertEqual(_testcapi.eval_get_func_name(A), "type")

def test_eval_get_func_desc(self):
def function_example(): ...

class A:
def method_example(self): ...

self.assertEqual(_testcapi.eval_get_func_desc(function_example),
"()")
self.assertEqual(_testcapi.eval_get_func_desc(A.method_example),
"()")
self.assertEqual(_testcapi.eval_get_func_desc(A().method_example),
"()")
self.assertEqual(_testcapi.eval_get_func_desc(sum), "()") # c function
self.assertEqual(_testcapi.eval_get_func_desc(A), " object")

def test_function_get_code(self):
import types

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

def test_function_get_defaults(self):
def some(pos_only='p', zero=0, optional=None):
def some(
pos_only1, pos_only2='p',
/,
zero=0, optional=None,
*,
kw1,
kw2=True,
):
pass

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

with self.assertRaises(SystemError):
_testcapi.function_get_module(None) # not a function
_testcapi.function_get_defaults(None) # not a function

def test_function_set_defaults(self):
def some(pos_only='p', zero=0, optional=None):
def some(
pos_only1, pos_only2='p',
/,
zero=0, optional=None,
*,
kw1,
kw2=True,
):
pass

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

with self.assertRaises(SystemError):
_testcapi.function_set_defaults(1, ()) # not a function
self.assertEqual(_testcapi.function_get_defaults(some), old_defaults)
self.assertEqual(some.__defaults__, old_defaults)

new_defaults = ('q', 1, None)
_testcapi.function_set_defaults(some, new_defaults)
self.assertEqual(_testcapi.function_get_defaults(some), new_defaults)
self.assertEqual(some.__defaults__, new_defaults)

# Empty tuple is fine:
new_defaults = ()
_testcapi.function_set_defaults(some, new_defaults)
self.assertEqual(_testcapi.function_get_defaults(some), new_defaults)
self.assertEqual(some.__defaults__, new_defaults)

class tuplesub(tuple): ... # tuple subclasses must work

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

def test_function_get_kw_defaults(self):
def some(
pos_only1, pos_only2='p',
/,
zero=0, optional=None,
*,
kw1,
kw2=True,
):
pass

defaults = _testcapi.function_get_kw_defaults(some)
self.assertEqual(defaults, {'kw2': True})
self.assertEqual(defaults, some.__kwdefaults__)

with self.assertRaises(SystemError):
_testcapi.function_get_kw_defaults(None) # not a function

def test_function_set_kw_defaults(self):
def some(
pos_only1, pos_only2='p',
/,
zero=0, optional=None,
*,
kw1,
kw2=True,
):
pass

old_defaults = {'kw2': True}
self.assertEqual(_testcapi.function_get_kw_defaults(some), old_defaults)
self.assertEqual(some.__kwdefaults__, old_defaults)

with self.assertRaises(SystemError):
_testcapi.function_set_kw_defaults(some, 1) # not dict or None
self.assertEqual(_testcapi.function_get_kw_defaults(some), old_defaults)
self.assertEqual(some.__kwdefaults__, old_defaults)

with self.assertRaises(SystemError):
_testcapi.function_set_kw_defaults(1, {}) # not a function
self.assertEqual(_testcapi.function_get_kw_defaults(some), old_defaults)
self.assertEqual(some.__kwdefaults__, old_defaults)

new_defaults = {'kw2': (1, 2, 3)}
_testcapi.function_set_kw_defaults(some, new_defaults)
self.assertEqual(_testcapi.function_get_kw_defaults(some), new_defaults)
self.assertEqual(some.__kwdefaults__, new_defaults)

# Empty dict is fine:
new_defaults = {}
_testcapi.function_set_kw_defaults(some, new_defaults)
self.assertEqual(_testcapi.function_get_kw_defaults(some), new_defaults)
self.assertEqual(some.__kwdefaults__, new_defaults)

class dictsub(dict): ... # dict subclasses must work

new_defaults = dictsub({'kw2': None})
_testcapi.function_set_kw_defaults(some, new_defaults)
self.assertEqual(_testcapi.function_get_kw_defaults(some), new_defaults)
self.assertEqual(some.__kwdefaults__, new_defaults)

# `None` is special, it sets `kwdefaults` to `NULL`,
# it needs special handling in `_testcapi`:
_testcapi.function_set_kw_defaults(some, None)
self.assertEqual(_testcapi.function_get_kw_defaults(some), None)
self.assertEqual(some.__kwdefaults__, None)


class TestPendingCalls(unittest.TestCase):

Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_dataclasses.py
Expand Up @@ -3970,7 +3970,7 @@ class Date(A):
day: 'int'

self.assertTrue(inspect.isabstract(Date))
msg = 'class Date without an implementation for abstract method foo'
msg = "class Date without an implementation for abstract method 'foo'"
self.assertRaisesRegex(TypeError, msg, Date)


Expand Down
2 changes: 1 addition & 1 deletion Makefile.pre.in
Expand Up @@ -1224,7 +1224,7 @@ regen-limited-abi: all
############################################################################
# Regenerate all generated files

regen-all: regen-opcode regen-opcode-targets regen-typeslots \
regen-all: regen-cases regen-opcode regen-opcode-targets regen-typeslots \
regen-token regen-ast regen-keyword regen-sre regen-frozen clinic \
regen-pegen-metaparser regen-pegen regen-test-frozenmain \
regen-test-levenshtein regen-global-objects
Expand Down
@@ -0,0 +1 @@
Fix ``-Wimplicit-int`` compiler warning in :program:`configure` check for ``PTHREAD_SCOPE_SYSTEM``.
@@ -0,0 +1,3 @@
Improved :class:`TypeError` message for undefined abstract methods of a
:class:`abc.ABC` instance. The names of the missing methods are surrounded
by single-quotes to highlight them.
@@ -0,0 +1 @@
Update the bundled copy of pip to version 22.3.1.

0 comments on commit a2a1c17

Please sign in to comment.