8000 Merge branch 'python:main' into speedup-posixpath.abspath · python/cpython@aa3ed0c · GitHub
[go: up one dir, main page]

Skip to content

Commit aa3ed0c

Browse files
authored
Merge branch 'python:main' into speedup-posixpath.abspath
2 parents 807b494 + c50cb6d commit aa3ed0c

File tree

7 files changed

+298
-42
lines changed

7 files changed

+298
-42
lines changed

Lib/test/test_descr.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,10 +1687,10 @@ class D(C):
16871687
self.assertEqual(d.foo(1), (d, 1))
16881688
self.assertEqual(D.foo(d, 1), (d, 1))
16891689
sm = staticmethod(None)
1690-
self.assertEqual(sm.__dict__, {'__doc__': None})
1690+
self.assertEqual(sm.__dict__, {'__doc__': None.__doc__})
16911691
sm.x = 42
16921692
self.assertEqual(sm.x, 42)
1693-
self.assertEqual(sm.__dict__, {"x" : 42, '__doc__': None})
1693+
self.assertEqual(sm.__dict__, {"x" : 42, '__doc__': None.__doc__})
16941694
del sm.x
16951695
self.assertNotHasAttr(sm, "x")
16961696

Lib/test/test_inspect/test_inspect.py

Lines changed: 265 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5221,10 +5221,17 @@ class TestSignatureDefinitions(unittest.TestCase):
52215221
# This test case provides a home for checking that particular APIs
52225222
# have signatures available for introspection
52235223

5224+
@staticmethod
5225+
def is_public(name):
5226+
return not name.startswith('_') or name.startswith('__') and name.endswith('__')
5227+
52245228
@cpython_only
52255229
@unittest.skipIf(MISSING_C_DOCSTRINGS,
52265230
"Signature information for builtins requires docstrings")
5227-
def test_builtins_have_signatures(self):
5231+
def _test_module_has_signatures(self, module,
5232+
no_signature=(), unsupported_signature=(),
5233+
methods_no_signature={}, methods_unsupported_signature={},
5234+
good_exceptions=()):
52285235
# This checks all builtin callables in CPython have signatures
52295236
# A few have signatures Signature can't yet handle, so we skip those
52305237
# since they will have to wait until PEP 457 adds the required
@@ -5233,48 +5240,272 @@ def test_builtins_have_signatures(self):
52335240
# reasons, so we also skip those for the time being, but design
52345241
# the test to fail in order to indicate when it needs to be
52355242
# updated.
5236-
no_signature = set()
5237-
# These need PEP 457 groups
5238-
needs_groups = {"range", "slice", "dir", "getattr",
5239-
"next", "iter", "vars"}
5240-
no_signature |= needs_groups
5241-
# These have unrepresentable parameter default values of NULL
5242-
needs_null = {"anext"}
5243-
no_signature |= needs_null
5244-
# These need *args support in Argument Clinic
5245-
needs_varargs = {"min", "max", "__build_class__"}
5246-
no_signature |= needs_varargs
5247-
# These builtin types are expected to provide introspection info
5248-
types_with_signatures = {
5249-
'bool', 'classmethod', 'complex', 'enumerate', 'filter', 'float',
5250-
'frozenset', 'list', 'map', 'memoryview', 'object', 'property',
5251-
'reversed', 'set', 'staticmethod', 'tuple', 'zip'
5252-
}
5243+
no_signature = no_signature or set()
52535244
# Check the signatures we expect to be there
5254-
ns = vars(builtins)
5245+
ns = vars(module)
5246+
try:
5247+
names = set(module.__all__)
5248+
except AttributeError:
5249+
names = set(name for name in ns if self.is_public(name))
52555250
for name, obj in sorted(ns.items()):
5251+
if name not in names:
5252+
continue
52565253
if not callable(obj):
52575254
continue
5258-
# The builtin types haven't been converted to AC yet
5259-
if isinstance(obj, type) and (name not in types_with_signatures):
5260-
# Note that this also skips all the exception types
5255+
if (isinstance(obj, type) and
5256+
issubclass(obj, BaseException) and
5257+
name not in good_exceptions):
52615258
no_signature.add(name)
5262-
if (name in no_signature):
5263-
# Not yet converted
5264-
continue
5265-
if name in {'classmethod', 'staticmethod'}:
5266-
# Bug gh-112006: inspect.unwrap() does not work with types
5267-
# with the __wrapped__ data descriptor.
5268-
continue
5269-
with self.subTest(builtin=name):
5270-
self.assertIsNotNone(inspect.signature(obj))
5259+
if name not in no_signature and name not in unsupported_signature:
5260+
with self.subTest('supported', builtin=name):
5261+
self.assertIsNotNone(inspect.signature(obj))
5262+
if isinstance(obj, type):
5263+
with self.subTest(type=name):
5264+
self._test_builtin_methods_have_signatures(obj,
5265+
methods_no_signature.get(name, ()),
5266+
methods_unsupported_signature.get(name, ()))
52715267
# Check callables that haven't been converted don't claim a signature
52725268
# This ensures this test will start failing as more signatures are
52735269
# added, so the affected items can be moved into the scope of the
52745270
# regression test above
5275-
for name in no_signature - needs_null:
5276-
with self.subTest(builtin=name):
5277-
self.assertIsNone(ns[name].__text_signature__)
5271+
for name in no_signature:
5272+
with self.subTest('none', builtin=name):
5273+
obj = ns[name]
5274+
self.assertIsNone(obj.__text_signature__)
5275+
self.assertRaises(ValueError, inspect.signature, obj)
5276+
for name in unsupported_signature:
5277+
with self.subTest('unsupported', builtin=name):
5278+
obj = ns[name]
5279+
self.assertIsNotNone(obj.__text_signature__)
5280+
self.assertRaises(ValueError, inspect.signature, obj)
5281+
5282+
def _test_builtin_methods_have_signatures(self, cls, no_signature, unsupported_signature):
5283+
ns = vars(cls)
5284+
for name in ns:
5285+
obj = getattr(cls, name, None)
5286+
if not callable(obj) or isinstance(obj, type):
5287+
continue
5288+
if name not in no_signature and name not in unsupported_signature:
5289+
with self.subTest('supported', method=name):
5290+
self.assertIsNotNone(inspect.signature(obj))
5291+
for name in no_signature:
5292+
with self.subTest('none', method=name):
5293+
self.assertIsNone(getattr(cls, name).__text_signature__)
5294+
self.assertRaises(ValueError, inspect.signature, getattr(cls, name))
5295+
for name in unsupported_signature:
5296+
with self.subTest('unsupported', method=name):
5297+
self.assertIsNotNone(getattr(cls, name).__text_signature__)
5298+
self.assertRaises(ValueError, inspect.signature, getattr(cls, name))
5299+
5300+
def test_builtins_have_signatures(self):
5301+
no_signature = {'type', 'super', 'bytearray', 'bytes', 'dict', 'int', 'str'}
5302+
# These need PEP 457 groups
5303+
needs_groups = {"range", "slice", "dir", "getattr",
5304+
"next", "iter", "vars"}
5305+
no_signature |= needs_groups
5306+
# These have unrepresentable parameter default values of NULL
5307+
unsupported_signature = {"anext"}
5308+
# These need *args support in Argument Clinic
5309+
needs_varargs = {"min", "max", "__build_class__"}
5310+
no_signature |= needs_varargs
5311+
5312+
methods_no_signature = {
5313+
'dict': {'update'},
5314+
'object': {'__class__'},
5315+
}
5316+
methods_unsupported_signature = {
5317+
'bytearray': {'count', 'endswith', 'find', 'hex', 'index', 'rfind', 'rindex', 'startswith'},
5318+
'bytes': {'count', 'endswith', 'find', 'hex', 'index', 'rfind', 'rindex', 'startswith'},
5319+
'dict': {'pop'},
5320+
'int': {'__round__'},
5321+
'memoryview': {'cast', 'hex'},
5322+
'str': {'count', 'endswith', 'find', 'index', 'maketrans', 'rfind', 'rindex', 'startswith'},
5323+
}
5324+
self._test_module_has_signatures(builtins,
5325+
no_signature, unsupported_signature,
5326+
methods_no_signature, methods_unsupported_signature)
5327+
5328+
def test_types_module_has_signatures(self):
5329+
unsupported_signature = {'CellType'}
5330+
methods_no_signature = {
5331+
'AsyncGeneratorType': {'athrow'},
5332+
'CoroutineType': {'throw'},
5333+
'GeneratorType': {'throw'},
5334+
}
5335+
self._test_module_has_signatures(types,
5336+
unsupported_signature=unsupported_signature,
5337+
methods_no_signature=methods_no_signature)
5338+
5339+
def test_sys_module_has_signatures(self):
5340+
no_signature = {'getsizeof', 'set_asyncgen_hooks'}
5341+
self._test_module_has_signatures(sys, no_signature)
5342+
5343+
def test_abc_module_has_signatures(self):
5344+
import abc
5345+
self._test_module_has_signatures(abc)
5346+
5347+
def test_atexit_module_has_signatures(self):
5348+
import atexit
5349+
self._test_module_has_signatures(atexit)
5350+
5351+
def test_codecs_module_has_signatures(self):
5352+
import codecs
5353+
methods_no_signature = {'StreamReader': {'charbuffertype'}}
5354+
self._test_module_has_signatures(codecs,
5355+
methods_no_signature=methods_no_signature)
5356+
5357+
def test_collections_module_has_signatures(self):
5358+
no_signature = {'OrderedDict', 'defaultdict'}
5359+
unsupported_signature = {'deque'}
5360+
methods_no_signature = {
5361+
'OrderedDict': {'update'},
5362+
}
5363+
methods_unsupported_signature = {
5364+
'deque': {'index'},
5365+
'OrderedDict': {'pop'},
5366+
'UserString': {'maketrans'},
5367+
}
5368+
self._test_module_has_signatures(collections,
5369+
no_signature, unsupported_signature,
5370+
methods_no_signature, methods_unsupported_signature)
5371+
5372+
def test_collections_abc_module_has_signatures(self):
5373+
import collections.abc
5374+
self._test_module_has_signatures(collections.abc)
5375+
5376+
def test_errno_module_has_signatures(self):
5377+
import errno
5378+
self._test_module_has_signatures(errno)
5379+
5380+
def test_faulthandler_module_has_signatures(self):
5381+
import faulthandler
5382+
unsupported_signature = {'dump_traceback', 'dump_traceback_later', 'enable'}
5383+
unsupported_signature |= {name for name in ['register']
5384+
if hasattr(faulthandler, name)}
5385+
self._test_module_has_signatures(faulthandler, unsupported_signature=unsupported_signature)
5386+
5387+
def test_functools_module_has_signatures(self):
5388+
no_signature = {'reduce'}
5389+
self._test_module_has_signatures(functools, no_signature)
5390+
5391+
def test_gc_module_has_signatures(self):
5392+
import gc
5393+
no_signature = {'set_threshold'}
5394+
self._test_module_has_signatures(gc, no_signature)
5395+
5396+
def test_io_module_has_signatures(self):
5397+
methods_no_signature = {
5398+
'BufferedRWPair': {'read', 'peek', 'read1', 'readinto', 'readinto1', 'write'},
5399+
}
5400+
self._test_module_has_signatures(io,
5401+
methods_no_signature=methods_no_signature)
5402+
5403+
def test_itertools_module_has_signatures(self):
5404+
import itertools
5405+
no_signature = {'islice', 'repeat'}
5406+
self._test_module_has_signatures(itertools, no_signature)
5407+
5408+
def test_locale_module_has_signatures(self):
5409+
import locale
5410+
self._test_module_has_signatures(locale)
5411+
5412+
def test_marshal_module_has_signatures(self):
5413+
import marshal
5414+
self._test_module_has_signatures(marshal)
5415+
5416+
def test_operator_module_has_signatures(self):
5417+
import operator
5418+
self._test_module_has_signatures(operator)
5419+
5420+
def test_os_module_has_signatures(self):
5421+
unsupported_signature = {'chmod', 'utime'}
5422+
unsupported_signature |= {name for name in
5423+
['get_terminal_size', 'posix_spawn', 'posix_spawnp',
5424+
'register_at_fork', 'startfile']
5425+
if hasattr(os, name)}
5426+
self._test_module_has_signatures(os, unsupported_signature=unsupported_signature)
5427+
5428+
def test_pwd_module_has_signatures(self):
5429+
pwd = import_helper.import_module('pwd')
5430+
self._test_module_has_signatures(pwd)
5431+
5432+
def test_re_module_has_signatures(self):
5433+
import re
5434+
methods_no_signature = {'Match': {'group'}}
5435+
self._test_module_has_signatures(re,
5436+
methods_no_signature=methods_no_signature,
5437+
good_exceptions={'error', 'PatternError'})
5438+
5439+
def test_signal_module_has_signatures(self):
5440+
import signal
5441+
self._test_module_has_signatures(signal)
5442+
5443+
def test_stat_module_has_signatures(self):
5444+
import stat
5445+
self._test_module_has_signatures(stat)
5446+
5447+
def test_string_module_has_signatures(self):
5448+
import string
5449+
self._test_module_has_signatures(string)
5450+
5451+
def test_symtable_module_has_signatures(self):
5452+
import symtable
5453+
self._test_module_has_signatures(symtable)
5454+
5455+
def test_sysconfig_module_has_signatures(self):
5456+
import sysconfig
5457+
self._test_module_has_signatures(sysconfig)
5458+
5459+
def test_threading_module_has_signatures(self):
5460+
import threading
5461+
self._test_module_has_signatures(threading)
5462+
5463+
def test_thread_module_has_signatures(self):
5464+
import _thread
5465+
no_signature = {'RLock'}
5466+
self._test_module_has_signatures(_thread, no_signature)
5467+
5468+
def test_time_module_has_signatures(self):
5469+
no_signature = {
5470+
'asctime', 'ctime', 'get_clock_info', 'gmtime', 'localtime',
5471+
'strftime', 'strptime'
5472+
}
5473+
no_signature |= {name for name in
5474+
['clock_getres', 'clock_settime', 'clock_settime_ns',
5475+
'pthread_getcpuclockid']
5476+
if hasattr(time, name)}
5477+
self._test_module_has_signatures(time, no_signature)
5478+
5479+
def test_tokenize_module_has_signatures(self):
5480+
import tokenize
5481+
self._test_module_has_signatures(tokenize)
5482+
5483+
def test_tracemalloc_module_has_signatures(self):
5484+
import tracemalloc
5485+
self._test_module_has_signatures(tracemalloc)
5486+
5487+
def test_typing_module_has_signatures(self):
5488+
import typing
5489+
no_signature = {'ParamSpec', 'ParamSpecArgs', 'ParamSpecKwargs',
5490+
'Text', 'TypeAliasType', 'TypeVar', 'TypeVarTuple'}
5491+
methods_no_signature = {
5492+
'Generic': {'__class_getitem__', '__init_subclass__'},
5493+
}
5494+
methods_unsupported_signature = {
5495+
'Text': {'count', 'find', 'index', 'rfind', 'rindex', 'startswith', 'endswith', 'maketrans'},
5496+
}
5497+
self._test_module_has_signatures(typing, no_signature,
5498+
methods_no_signature=methods_no_signature,
5499+
methods_unsupported_signature=methods_unsupported_signature)
5500+
5501+
def test_warnings_module_has_signatures(self):
5502+
unsupported_signature = {'warn', 'warn_explicit'}
5503+
self._test_module_has_signatures(warnings, unsupported_signature=unsupported_signature)
5504+
5505+
def test_weakref_module_has_signatures(self):
5506+
import weakref
5507+
no_signature = {'ReferenceType', 'ref'}
5508+
self._test_module_has_signatures(weakref, no_signature)
52785509

52795510
def test_python_function_override_signature(self):
52805511
def func(*args, **kwargs):

Lib/test/test_rlcompleter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def test_attr_matches(self):
5555
if x.startswith('s')])
5656
self.assertEqual(self.stdcompleter.attr_matches('tuple.foospamegg'), [])
5757
expected = sorted({'None.%s%s' % (x,
58-
'()' if x == '__init_subclass__'
58+
'()' if x in ('__init_subclass__', '__class__')
5959
else '' if x == '__doc__'
6060
else '(')
6161
for x in dir(None)})

Objects/object.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2007,6 +2007,11 @@ static PyNumberMethods none_as_number = {
20072007
0, /* nb_index */
20082008
};
20092009

2010+
PyDoc_STRVAR(none_doc,
2011+
"NoneType()\n"
2012+
"--\n\n"
2013+
"The type of the None singleton.");
2014+
20102015
PyTypeObject _PyNone_Type = {
20112016
PyVarObject_HEAD_INIT(&PyType_Type, 0)
20122017
"NoneType",
@@ -2028,7 +2033,7 @@ PyTypeObject _PyNone_Type = {
20282033
0, /*tp_setattro */
20292034
0, /*tp_as_buffer */
20302035
Py_TPFLAGS_DEFAULT, /*tp_flags */
2031-
0, /*tp_doc */
2036+
none_doc, /*tp_doc */
20322037
0, /*tp_traverse */
20332038
0, /*tp_clear */
20342039
_Py_BaseObject_RichCompare, /*tp_richcompare */
@@ -2106,6 +2111,11 @@ static PyNumberMethods notimplemented_as_number = {
21062111
.nb_bool = notimplemented_bool,
21072112
};
21082113

2114+
PyDoc_STRVAR(notimplemented_doc,
2115+
"NotImplementedType()\n"
2116+
"--\n\n"
2117+
"The type of the NotImplemented singleton.");
2118+
21092119
PyTypeObject _PyNotImplemented_Type = {
21102120
PyVarObject_HEAD_INIT(&PyType_Type, 0)
21112121
"NotImplementedType",
@@ -2127,7 +2137,7 @@ PyTypeObject _PyNotImplemented_Type = {
21272137
0, /*tp_setattro */
21282138
0, /*tp_as_buffer */
21292139
Py_TPFLAGS_DEFAULT, /*tp_flags */
2130-
0, /*tp_doc */
2140+
notimplemented_doc, /*tp_doc */
21312141
0, /*tp_traverse */
21322142
0, /*tp_clear */
21332143
0, /*tp_richcompare */

0 commit comments

Comments
 (0)
0