diff options
Diffstat (limited to 'Lib/test/test_inspect/test_inspect.py')
-rw-r--r-- | Lib/test/test_inspect/test_inspect.py | 122 |
1 files changed, 100 insertions, 22 deletions
diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py index 06f0ca36f97..79eb103224b 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -786,12 +786,12 @@ class TestRetrievingSourceCode(GetSourceBase): def test_getfile_builtin_module(self): with self.assertRaises(TypeError) as e: inspect.getfile(sys) - self.assertTrue(str(e.exception).startswith('<module')) + self.assertStartsWith(str(e.exception), '<module') def test_getfile_builtin_class(self): with self.assertRaises(TypeError) as e: inspect.getfile(int) - self.assertTrue(str(e.exception).startswith('<class')) + self.assertStartsWith(str(e.exception), '<class') def test_getfile_builtin_function_or_method(self): with self.assertRaises(TypeError) as e_abs: @@ -2949,7 +2949,7 @@ class TestSignatureObject(unittest.TestCase): pass sig = inspect.signature(test) - self.assertTrue(repr(sig).startswith('<Signature')) + self.assertStartsWith(repr(sig), '<Signature') self.assertTrue('(po, /, pk' in repr(sig)) # We need two functions, because it is impossible to represent @@ -2958,7 +2958,7 @@ class TestSignatureObject(unittest.TestCase): pass sig2 = inspect.signature(test2) - self.assertTrue(repr(sig2).startswith('<Signature')) + self.assertStartsWith(repr(sig2), '<Signature') self.assertTrue('(pod=42, /)' in repr(sig2)) po = sig.parameters['po'] @@ -3412,9 +3412,10 @@ class TestSignatureObject(unittest.TestCase): int)) def test_signature_on_classmethod(self): - self.assertEqual(self.signature(classmethod), - ((('function', ..., ..., "positional_only"),), - ...)) + if not support.MISSING_C_DOCSTRINGS: + self.assertEqual(self.signature(classmethod), + ((('function', ..., ..., "positional_only"),), + ...)) class Test: @classmethod @@ -3434,9 +3435,10 @@ class TestSignatureObject(unittest.TestCase): ...)) def test_signature_on_staticmethod(self): - self.assertEqual(self.signature(staticmethod), - ((('function', ..., ..., "positional_only"),), - ...)) + if not support.MISSING_C_DOCSTRINGS: + self.assertEqual(self.signature(staticmethod), + ((('function', ..., ..., "positional_only"),), + ...)) class Test: @staticmethod @@ -3845,7 +3847,6 @@ class TestSignatureObject(unittest.TestCase): ('b', ..., ..., "positional_or_keyword")), ...)) - def test_signature_on_class(self): class C: def __init__(self, a): @@ -3954,9 +3955,10 @@ class TestSignatureObject(unittest.TestCase): self.assertEqual(C(3), 8) self.assertEqual(C(3, 7), 1) - # BUG: Returns '<Signature (b)>' - with self.assertRaises(AssertionError): - self.assertEqual(self.signature(C), self.signature((0).__pow__)) + if not support.MISSING_C_DOCSTRINGS: + # BUG: Returns '<Signature (b)>' + with self.assertRaises(AssertionError): + self.assertEqual(self.signature(C), self.signature((0).__pow__)) class CM(type): def __new__(mcls, name, bases, dct, *, foo=1): @@ -4019,6 +4021,45 @@ class TestSignatureObject(unittest.TestCase): ('bar', 2, ..., "keyword_only")), ...)) + def test_signature_on_class_with_decorated_new(self): + def identity(func): + @functools.wraps(func) + def wrapped(*args, **kwargs): + return func(*args, **kwargs) + return wrapped + + class Foo: + @identity + def __new__(cls, a, b): + pass + + self.assertEqual(self.signature(Foo), + ((('a', ..., ..., "positional_or_keyword"), + ('b', ..., ..., "positional_or_keyword")), + ...)) + + self.assertEqual(self.signature(Foo.__new__), + ((('cls', ..., ..., "positional_or_keyword"), + ('a', ..., ..., "positional_or_keyword"), + ('b', ..., ..., "positional_or_keyword")), + ...)) + + class Bar: + __new__ = identity(object.__new__) + + varargs_signature = ( + (('args', ..., ..., 'var_positional'), + ('kwargs', ..., ..., 'var_keyword')), + ..., + ) + + self.assertEqual(self.signature(Bar), ((), ...)) + self.assertEqual(self.signature(Bar.__new__), varargs_signature) + self.assertEqual(self.signature(Bar, follow_wrapped=False), + varargs_signature) + self.assertEqual(self.signature(Bar.__new__, follow_wrapped=False), + varargs_signature) + def test_signature_on_class_with_init(self): class C: def __init__(self, b): @@ -4352,7 +4393,8 @@ class TestSignatureObject(unittest.TestCase): __call__ = (2).__pow__ self.assertEqual(C()(3), 8) - self.assertEqual(self.signature(C()), self.signature((0).__pow__)) + if not support.MISSING_C_DOCSTRINGS: + self.assertEqual(self.signature(C()), self.signature((0).__pow__)) with self.subTest('ClassMethodDescriptorType'): class C(dict): @@ -4361,7 +4403,8 @@ class TestSignatureObject(unittest.TestCase): res = C()([1, 2], 3) self.assertEqual(res, {1: 3, 2: 3}) self.assertEqual(type(res), C) - self.assertEqual(self.signature(C()), self.signature(dict.fromkeys)) + if not support.MISSING_C_DOCSTRINGS: + self.assertEqual(self.signature(C()), self.signature(dict.fromkeys)) with self.subTest('MethodDescriptorType'): class C(str): @@ -4375,7 +4418,8 @@ class TestSignatureObject(unittest.TestCase): __call__ = int.__pow__ self.assertEqual(C(2)(3), 8) - self.assertEqual(self.signature(C()), self.signature((0).__pow__)) + if not support.MISSING_C_DOCSTRINGS: + self.assertEqual(self.signature(C()), self.signature((0).__pow__)) with self.subTest('MemberDescriptorType'): class C: @@ -4393,7 +4437,8 @@ class TestSignatureObject(unittest.TestCase): def __call__(self, *args, **kwargs): pass - self.assertEqual(self.signature(C), ((), ...)) + if not support.MISSING_C_DOCSTRINGS: + self.assertEqual(self.signature(C), ((), ...)) self.assertEqual(self.signature(C()), ((('a', ..., ..., "positional_only"), ('b', ..., ..., "positional_or_keyword"), @@ -4952,6 +4997,37 @@ class TestSignatureObject(unittest.TestCase): with self.assertRaisesRegex(NameError, "undefined"): signature_func(ida.f) + def test_signature_deferred_annotations(self): + def f(x: undef): + pass + + class C: + x: undef + + def __init__(self, x: undef): + self.x = x + + sig = inspect.signature(f, annotation_format=Format.FORWARDREF) + self.assertEqual(list(sig.parameters), ['x']) + sig = inspect.signature(C, annotation_format=Format.FORWARDREF) + self.assertEqual(list(sig.parameters), ['x']) + + class CallableWrapper: + def __init__(self, func): + self.func = func + self.__annotate__ = func.__annotate__ + + def __call__(self, *args, **kwargs): + return self.func(*args, **kwargs) + + @property + def __annotations__(self): + return self.__annotate__(Format.VALUE) + + cw = CallableWrapper(f) + sig = inspect.signature(cw, annotation_format=Format.FORWARDREF) + self.assertEqual(list(sig.parameters), ['args', 'kwargs']) + def test_signature_none_annotation(self): class funclike: # Has to be callable, and have correct @@ -5057,7 +5133,7 @@ class TestParameterObject(unittest.TestCase): with self.assertRaisesRegex(ValueError, 'cannot have default values'): p.replace(kind=inspect.Parameter.VAR_POSITIONAL) - self.assertTrue(repr(p).startswith('<Parameter')) + self.assertStartsWith(repr(p), '<Parameter') self.assertTrue('"a=42"' in repr(p)) def test_signature_parameter_hashable(self): @@ -5801,7 +5877,7 @@ class TestSignatureDefinitions(unittest.TestCase): def test_os_module_has_signatures(self): unsupported_signature = {'chmod', 'utime'} unsupported_signature |= {name for name in - ['get_terminal_size', 'posix_spawn', 'posix_spawnp', + ['get_terminal_size', 'link', 'posix_spawn', 'posix_spawnp', 'register_at_fork', 'startfile'] if hasattr(os, name)} self._test_module_has_signatures(os, unsupported_signature=unsupported_signature) @@ -6101,12 +6177,14 @@ class TestRepl(unittest.TestCase): object. """ + # TODO(picnixz): refactor this as it's used by test_repl.py + # To run the REPL without using a terminal, spawn python with the command # line option '-i' and the process name set to '<stdin>'. # The directory of argv[0] must match the directory of the Python # executable for the Popen() call to python to succeed as the directory - # path may be used by Py_GetPath() to build the default module search - # path. + # path may be used by PyConfig_Get("module_search_paths") to build the + # default module search path. stdin_fname = os.path.join(os.path.dirname(sys.executable), "<stdin>") cmd_line = [stdin_fname, '-E', '-i'] cmd_line.extend(args) |