Skip to content

gh-100129: Make the names of all classes in the types module resolvable #100130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Doc/library/functools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ The :mod:`functools` module defines the following functions:
attribute::

>>> fun.registry.keys()
dict_keys([<class 'NoneType'>, <class 'int'>, <class 'object'>,
dict_keys([<class 'types.NoneType'>, <class 'int'>, <class 'object'>,
<class 'decimal.Decimal'>, <class 'list'>,
<class 'float'>])
>>> fun.registry[float]
Expand Down
2 changes: 1 addition & 1 deletion Doc/library/multiprocessing.shared_memory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ instance:
>>> from multiprocessing import shared_memory
>>> a = shared_memory.ShareableList(['howdy', b'HoWdY', -273.154, 100, None, True, 42])
>>> [ type(entry) for entry in a ]
[<class 'str'>, <class 'bytes'>, <class 'float'>, <class 'int'>, <class 'NoneType'>, <class 'bool'>, <class 'int'>]
[<class 'str'>, <class 'bytes'>, <class 'float'>, <class 'int'>, <class 'types.NoneType'>, <class 'bool'>, <class 'int'>]
>>> a[2]
-273.154
>>> a[2] = -78.5
Expand Down
2 changes: 1 addition & 1 deletion Doc/library/unittest.mock.rst
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,7 @@ object::
...
>>> mock = MagicMock(async_func)
>>> mock
<MagicMock spec='function' id='...'>
<MagicMock spec='FunctionType' id='...'>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not types.FunctionType?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the MagicMock repr contains only spec_class.__name__, not the fully qualified name.

>>> mock() # doctest: +SKIP
<coroutine object AsyncMockMixin._mock_call at ...>

Expand Down
7 changes: 7 additions & 0 deletions Lib/test/pickletester.py
Original file line number Diff line number Diff line change
Expand Up @@ -1989,6 +1989,13 @@ def test_builtin_types(self):
s = self.dumps(t, proto)
self.assertIs(self.loads(s), t)

def test_types_types(self):
for t in types.__dict__.values():
if isinstance(t, type):
for proto in protocols:
s = self.dumps(t, proto)
self.assertIs(self.loads(s), t)

def test_builtin_exceptions(self):
for t in builtins.__dict__.values():
if isinstance(t, type) and issubclass(t, BaseException):
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_complex.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ def split_zeros(x):
self.assertRaises(TypeError, float, 5+3j)
self.assertRaises(ValueError, complex, "")
self.assertRaises(TypeError, complex, None)
self.assertRaisesRegex(TypeError, "not 'NoneType'", complex, None)
self.assertRaisesRegex(TypeError, "not 'types.NoneType'", complex, None)
self.assertRaises(ValueError, complex, "\0")
self.assertRaises(ValueError, complex, "3\09")
self.assertRaises(TypeError, complex, "1", "2")
Expand Down
6 changes: 3 additions & 3 deletions Lib/test/test_coroutines.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ async def foo():
coro = foo()

check = lambda: self.assertRaisesRegex(
TypeError, "'coroutine' object is not iterable")
TypeError, r"'types\.CoroutineType' object is not iterable")

with check():
list(coro)
Expand Down Expand Up @@ -597,7 +597,7 @@ async def foo():
await bar()

check = lambda: self.assertRaisesRegex(
TypeError, "'coroutine' object is not iterable")
TypeError, r"'types\.CoroutineType' object is not iterable")

coro = foo()
with check():
Expand Down Expand Up @@ -958,7 +958,7 @@ def test_corotype_1(self):
self.assertIn('in coroutine', ct.throw.__doc__)
self.assertIn('of the coroutine', ct.__dict__['__name__'].__doc__)
self.assertIn('of the coroutine', ct.__dict__['__qualname__'].__doc__)
self.assertEqual(ct.__name__, 'coroutine')
self.assertEqual(ct.__name__, 'CoroutineType')

async def f(): pass
c = f()
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,7 @@ class mydialect(csv.Dialect):
with self.assertRaises(csv.Error) as cm:
mydialect()
self.assertEqual(str(cm.exception),
'"delimiter" must be string, not NoneType')
'"delimiter" must be string, not types.NoneType')

def test_escapechar(self):
class mydialect(csv.Dialect):
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_descr.py
Original file line number Diff line number Diff line change
Expand Up @@ -4832,11 +4832,11 @@ class X:

def test_qualname(self):
descriptors = [str.lower, complex.real, float.real, int.__add__]
types = ['method', 'member', 'getset', 'wrapper']
types = ['Method', 'Member', 'GetSet', 'Wrapper']

# make sure we have an example of each type of descriptor
for d, n in zip(descriptors, types):
self.assertEqual(type(d).__name__, n + '_descriptor')
self.assertEqual(type(d).__name__, n + 'DescriptorType')

for d in descriptors:
qualname = d.__objclass__.__qualname__ + '.' + d.__name__
Expand Down
42 changes: 20 additions & 22 deletions Lib/test/test_extcall.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,73 +263,71 @@
...
TypeError: h() got an unexpected keyword argument 'e'

>>> h(*h)
>>> h(*1)
Traceback (most recent call last):
...
TypeError: test.test_extcall.h() argument after * must be an iterable, not function
TypeError: test.test_extcall.h() argument after * must be an iterable, not int

>>> h(1, *h)
>>> h(1, *2)
Traceback (most recent call last):
...
TypeError: Value after * must be an iterable, not function
TypeError: Value after * must be an iterable, not int

>>> h(*[1], *h)
>>> h(*[1], *2)
Traceback (most recent call last):
...
TypeError: Value after * must be an iterable, not function
TypeError: Value after * must be an iterable, not int

>>> dir(*h)
>>> dir(*1)
Traceback (most recent call last):
...
TypeError: dir() argument after * must be an iterable, not function
TypeError: dir() argument after * must be an iterable, not int

>>> nothing = None
>>> nothing(*h)
>>> nothing(*1)
Traceback (most recent call last):
...
TypeError: None argument after * must be an iterable, \
not function
TypeError: None argument after * must be an iterable, not int

>>> h(**h)
>>> h(**1)
Traceback (most recent call last):
...
TypeError: test.test_extcall.h() argument after ** must be a mapping, not function
TypeError: test.test_extcall.h() argument after ** must be a mapping, not int

>>> h(**[])
Traceback (most recent call last):
...
TypeError: test.test_extcall.h() argument after ** must be a mapping, not list

>>> h(a=1, **h)
>>> h(a=1, **2)
Traceback (most recent call last):
...
TypeError: test.test_extcall.h() argument after ** must be a mapping, not function
TypeError: test.test_extcall.h() argument after ** must be a mapping, not int

>>> h(a=1, **[])
Traceback (most recent call last):
...
TypeError: test.test_extcall.h() argument after ** must be a mapping, not list

>>> h(**{'a': 1}, **h)
>>> h(**{'a': 1}, **2)
Traceback (most recent call last):
...
TypeError: test.test_extcall.h() argument after ** must be a mapping, not function
TypeError: test.test_extcall.h() argument after ** must be a mapping, not int

>>> h(**{'a': 1}, **[])
Traceback (most recent call last):
...
TypeError: test.test_extcall.h() argument after ** must be a mapping, not list

>>> dir(**h)
>>> dir(**1)
Traceback (most recent call last):
...
TypeError: dir() argument after ** must be a mapping, not function
TypeError: dir() argument after ** must be a mapping, not int

>>> nothing(**h)
>>> nothing(**1)
Traceback (most recent call last):
...
TypeError: None argument after ** must be a mapping, \
not function
TypeError: None argument after ** must be a mapping, not int

>>> dir(b=1, **{'b': 1})
Traceback (most recent call last):
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_funcattrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def f(): print(a)
self.assertIsInstance(c, tuple)
self.assertEqual(len(c), 1)
# don't have a type object handy
self.assertEqual(c[0].__class__.__name__, "cell")
self.assertEqual(c[0].__class__.__name__, "CellType")
self.cannot_set_attr(f, "__closure__", c, AttributeError)

def test_cell_new(self):
Expand Down
8 changes: 4 additions & 4 deletions Lib/test/test_gdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,7 @@ def test_pyup_command(self):
self.assertMultilineMatches(bt,
r'''^.*
#[0-9]+ Frame 0x-?[0-9a-f]+, for file <string>, line 12, in baz \(args=\(1, 2, 3\)\)
#[0-9]+ <built-in method pyobject_fastcall of module object at remote 0x[0-9a-f]+>
#[0-9]+ <built-in method pyobject_fastcall of types.ModuleType object at remote 0x[0-9a-f]+>
$''')

@unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands")
Expand Down Expand Up @@ -785,7 +785,7 @@ def test_up_then_down(self):
self.assertMultilineMatches(bt,
r'''^.*
#[0-9]+ Frame 0x-?[0-9a-f]+, for file <string>, line 12, in baz \(args=\(1, 2, 3\)\)
#[0-9]+ <built-in method pyobject_fastcall of module object at remote 0x[0-9a-f]+>
#[0-9]+ <built-in method pyobject_fastcall of types.ModuleType object at remote 0x[0-9a-f]+>
#[0-9]+ Frame 0x-?[0-9a-f]+, for file <string>, line 12, in baz \(args=\(1, 2, 3\)\)
$''')

Expand All @@ -799,7 +799,7 @@ def test_bt(self):
self.assertMultilineMatches(bt,
r'''^.*
Traceback \(most recent call first\):
<built-in method id of module object .*>
<built-in method id of types\.ModuleType object .*>
File ".*gdb_sample.py", line 10, in baz
id\(42\)
File ".*gdb_sample.py", line 7, in bar
Expand Down Expand Up @@ -1014,7 +1014,7 @@ def test_printing_builtin(self):
bt = self.get_stack_trace(script=self.get_sample_script(),
cmds_after_breakpoint=['py-up', 'py-print len'])
self.assertMultilineMatches(bt,
r".*\nbuiltin 'len' = <built-in method len of module object at remote 0x-?[0-9a-f]+>\n.*")
r".*\nbuiltin 'len' = <built-in method len of types\.ModuleType object at remote 0x-?[0-9a-f]+>\n.*")

class PyLocalsTests(DebuggerTests):
@unittest.skipIf(python_is_optimized(),
Expand Down
34 changes: 17 additions & 17 deletions Lib/test/test_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -977,10 +977,10 @@ def b():
... yield 1
...
>>> type(g)
<class 'function'>
<class 'types.FunctionType'>
>>> i = g()
>>> type(i)
<class 'generator'>
<class 'types.GeneratorType'>
>>> [s for s in dir(i) if not s.startswith('_')]
['close', 'gi_code', 'gi_frame', 'gi_running', 'gi_suspended', 'gi_yieldfrom', 'send', 'throw']
>>> from test.support import HAVE_DOCSTRINGS
Expand All @@ -997,11 +997,11 @@ def b():
>>> i.gi_running
0
>>> type(i.gi_frame)
<class 'frame'>
<class 'types.FrameType'>
>>> i.gi_running = 42
Traceback (most recent call last):
...
AttributeError: attribute 'gi_running' of 'generator' objects is not writable
AttributeError: attribute 'gi_running' of 'types.GeneratorType' objects is not writable
>>> def g():
... yield me.gi_running
>>> me = g()
Expand Down Expand Up @@ -1372,27 +1372,27 @@ def b():
>>> def f():
... yield
>>> type(f())
<class 'generator'>
<class 'types.GeneratorType'>


>>> def f():
... if 0:
... yield
>>> type(f())
<class 'generator'>
<class 'types.GeneratorType'>


>>> def f():
... if 0:
... yield 1
>>> type(f())
<class 'generator'>
<class 'types.GeneratorType'>

>>> def f():
... if "":
... yield None
>>> type(f())
<class 'generator'>
<class 'types.GeneratorType'>

>>> def f():
... return
Expand All @@ -1416,15 +1416,15 @@ def b():
... x = 1
... return
>>> type(f())
<class 'generator'>
<class 'types.GeneratorType'>

>>> def f():
... if 0:
... def g():
... yield 1
...
>>> type(f())
<class 'NoneType'>
<class 'types.NoneType'>

>>> def f():
... if 0:
Expand All @@ -1434,15 +1434,15 @@ def b():
... def f(self):
... yield 2
>>> type(f())
<class 'NoneType'>
<class 'types.NoneType'>

>>> def f():
... if 0:
... return
... if 0:
... yield 2
>>> type(f())
<class 'generator'>
<class 'types.GeneratorType'>

This one caused a crash (see SF bug 567538):

Expand Down Expand Up @@ -2093,7 +2093,7 @@ def printsolution(self, x):

>>> def f(): list(i for i in [(yield 26)])
>>> type(f())
<class 'generator'>
<class 'types.GeneratorType'>


A yield expression with augmented assignment.
Expand Down Expand Up @@ -2364,21 +2364,21 @@ def printsolution(self, x):

>>> def f(): x += yield
>>> type(f())
<class 'generator'>
<class 'types.GeneratorType'>

>>> def f(): x = yield
>>> type(f())
<class 'generator'>
<class 'types.GeneratorType'>

>>> def f(): lambda x=(yield): 1
>>> type(f())
<class 'generator'>
<class 'types.GeneratorType'>

>>> def f(d): d[(yield "a")] = d[(yield "b")] = 27
>>> data = [1,2]
>>> g = f(data)
>>> type(g)
<class 'generator'>
<class 'types.GeneratorType'>
>>> g.send(None)
'a'
>>> data
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_genexps.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@

>>> g = (i*i for i in range(4))
>>> type(g)
<class 'generator'>
<class 'types.GeneratorType'>
>>> list(g)
[0, 1, 4, 9]

Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -1521,9 +1521,9 @@ def check(test):
msg=r'indices must be integers or slices, not dict;'
check('[[1, 2] [{3: 4}]]')
check('[[1, 2] [{i: i for i in range(5)}]]')
msg=r'indices must be integers or slices, not generator;'
msg=r'indices must be integers or slices, not types\.GeneratorType;'
check('[[1, 2] [(i for i in range(5))]]')
msg=r'indices must be integers or slices, not function;'
msg=r'indices must be integers or slices, not types\.FunctionType;'
check('[[1, 2] [(lambda x, y: x)]]')
msg=r'indices must be integers or slices, not str;'
check('[[1, 2] [f"{x}"]]')
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_json/test_fail.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def test_non_string_keys_dict(self):
def test_not_serializable(self):
import sys
with self.assertRaisesRegex(TypeError,
'Object of type module is not JSON serializable'):
'Object of type ModuleType is not JSON serializable'):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not types.ModuleType?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same as above. It outputs type(obj).__name__.

self.dumps(sys)

def test_truncated_input(self):
Expand Down
Loading