1import builtins
2import collections
3import datetime
4import functools
5import importlib
6import inspect
7import io
8import linecache
9import os
10from os.path import normcase
11import _pickle
12import pickle
13import shutil
14import sys
15import types
16import textwrap
17import unicodedata
18import unittest
19import unittest.mock
20import warnings
21
22try:
23    from concurrent.futures import ThreadPoolExecutor
24except ImportError:
25    ThreadPoolExecutor = None
26
27from test.support import TESTFN, DirsOnSysPath, cpython_only
28from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ
29from test.support.script_helper import assert_python_ok, assert_python_failure
30from test import inspect_fodder as mod
31from test import inspect_fodder2 as mod2
32from test import support
33
34from test.test_import import _ready_to_import
35
36
37# Functions tested in this suite:
38# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
39# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
40# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
41# getclasstree, getargvalues, formatargspec, formatargvalues,
42# currentframe, stack, trace, isdatadescriptor
43
44# NOTE: There are some additional tests relating to interaction with
45#       zipimport in the test_zipimport_support test module.
46
47modfile = mod.__file__
48if modfile.endswith(('c', 'o')):
49    modfile = modfile[:-1]
50
51# Normalize file names: on Windows, the case of file names of compiled
52# modules depends on the path used to start the python executable.
53modfile = normcase(modfile)
54
55def revise(filename, *args):
56    return (normcase(filename),) + args
57
58git = mod.StupidGit()
59
60
61def signatures_with_lexicographic_keyword_only_parameters():
62    """
63    Yields a whole bunch of functions with only keyword-only parameters,
64    where those parameters are always in lexicographically sorted order.
65    """
66    parameters = ['a', 'bar', 'c', 'delta', 'ephraim', 'magical', 'yoyo', 'z']
67    for i in range(1, 2**len(parameters)):
68        p = []
69        bit = 1
70        for j in range(len(parameters)):
71            if i & (bit << j):
72                p.append(parameters[j])
73        fn_text = "def foo(*, " + ", ".join(p) + "): pass"
74        symbols = {}
75        exec(fn_text, symbols, symbols)
76        yield symbols['foo']
77
78
79def unsorted_keyword_only_parameters_fn(*, throw, out, the, baby, with_,
80                                        the_, bathwater):
81    pass
82
83unsorted_keyword_only_parameters = 'throw out the baby with_ the_ bathwater'.split()
84
85class IsTestBase(unittest.TestCase):
86    predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
87                      inspect.isframe, inspect.isfunction, inspect.ismethod,
88                      inspect.ismodule, inspect.istraceback,
89                      inspect.isgenerator, inspect.isgeneratorfunction,
90                      inspect.iscoroutine, inspect.iscoroutinefunction,
91                      inspect.isasyncgen, inspect.isasyncgenfunction])
92
93    def istest(self, predicate, exp):
94        obj = eval(exp)
95        self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
96
97        for other in self.predicates - set([predicate]):
98            if (predicate == inspect.isgeneratorfunction or \
99               predicate == inspect.isasyncgenfunction or \
100               predicate == inspect.iscoroutinefunction) and \
101               other == inspect.isfunction:
102                continue
103            self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
104
105def generator_function_example(self):
106    for i in range(2):
107        yield i
108
109async def async_generator_function_example(self):
110    async for i in range(2):
111        yield i
112
113async def coroutine_function_example(self):
114    return 'spam'
115
116@types.coroutine
117def gen_coroutine_function_example(self):
118    yield
119    return 'spam'
120
121class TestPredicates(IsTestBase):
122
123    def test_excluding_predicates(self):
124        global tb
125        self.istest(inspect.isbuiltin, 'sys.exit')
126        self.istest(inspect.isbuiltin, '[].append')
127        self.istest(inspect.iscode, 'mod.spam.__code__')
128        try:
129            1/0
130        except:
131            tb = sys.exc_info()[2]
132            self.istest(inspect.isframe, 'tb.tb_frame')
133            self.istest(inspect.istraceback, 'tb')
134            if hasattr(types, 'GetSetDescriptorType'):
135                self.istest(inspect.isgetsetdescriptor,
136                            'type(tb.tb_frame).f_locals')
137            else:
138                self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
139        finally:
140            # Clear traceback and all the frames and local variables hanging to it.
141            tb = None
142        self.istest(inspect.isfunction, 'mod.spam')
143        self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
144        self.istest(inspect.ismethod, 'git.argue')
145        self.istest(inspect.ismethod, 'mod.custom_method')
146        self.istest(inspect.ismodule, 'mod')
147        self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
148        self.istest(inspect.isgenerator, '(x for x in range(2))')
149        self.istest(inspect.isgeneratorfunction, 'generator_function_example')
150        self.istest(inspect.isasyncgen,
151                    'async_generator_function_example(1)')
152        self.istest(inspect.isasyncgenfunction,
153                    'async_generator_function_example')
154
155        with warnings.catch_warnings():
156            warnings.simplefilter("ignore")
157            self.istest(inspect.iscoroutine, 'coroutine_function_example(1)')
158            self.istest(inspect.iscoroutinefunction, 'coroutine_function_example')
159
160        if hasattr(types, 'MemberDescriptorType'):
161            self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
162        else:
163            self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
164
165    def test_iscoroutine(self):
166        async_gen_coro = async_generator_function_example(1)
167        gen_coro = gen_coroutine_function_example(1)
168        coro = coroutine_function_example(1)
169
170        self.assertFalse(
171            inspect.iscoroutinefunction(gen_coroutine_function_example))
172        self.assertFalse(
173            inspect.iscoroutinefunction(
174                functools.partial(functools.partial(
175                    gen_coroutine_function_example))))
176        self.assertFalse(inspect.iscoroutine(gen_coro))
177
178        self.assertTrue(
179            inspect.isgeneratorfunction(gen_coroutine_function_example))
180        self.assertTrue(
181            inspect.isgeneratorfunction(
182                functools.partial(functools.partial(
183                    gen_coroutine_function_example))))
184        self.assertTrue(inspect.isgenerator(gen_coro))
185
186        self.assertTrue(
187            inspect.iscoroutinefunction(coroutine_function_example))
188        self.assertTrue(
189            inspect.iscoroutinefunction(
190                functools.partial(functools.partial(
191                    coroutine_function_example))))
192        self.assertTrue(inspect.iscoroutine(coro))
193
194        self.assertFalse(
195            inspect.isgeneratorfunction(coroutine_function_example))
196        self.assertFalse(
197            inspect.isgeneratorfunction(
198                functools.partial(functools.partial(
199                    coroutine_function_example))))
200        self.assertFalse(inspect.isgenerator(coro))
201
202        self.assertTrue(
203            inspect.isasyncgenfunction(async_generator_function_example))
204        self.assertTrue(
205            inspect.isasyncgenfunction(
206                functools.partial(functools.partial(
207                    async_generator_function_example))))
208        self.assertTrue(inspect.isasyncgen(async_gen_coro))
209
210        coro.close(); gen_coro.close(); # silence warnings
211
212    def test_isawaitable(self):
213        def gen(): yield
214        self.assertFalse(inspect.isawaitable(gen()))
215
216        coro = coroutine_function_example(1)
217        gen_coro = gen_coroutine_function_example(1)
218
219        self.assertTrue(inspect.isawaitable(coro))
220        self.assertTrue(inspect.isawaitable(gen_coro))
221
222        class Future:
223            def __await__():
224                pass
225        self.assertTrue(inspect.isawaitable(Future()))
226        self.assertFalse(inspect.isawaitable(Future))
227
228        class NotFuture: pass
229        not_fut = NotFuture()
230        not_fut.__await__ = lambda: None
231        self.assertFalse(inspect.isawaitable(not_fut))
232
233        coro.close(); gen_coro.close() # silence warnings
234
235    def test_isroutine(self):
236        self.assertTrue(inspect.isroutine(mod.spam))
237        self.assertTrue(inspect.isroutine([].count))
238
239    def test_isclass(self):
240        self.istest(inspect.isclass, 'mod.StupidGit')
241        self.assertTrue(inspect.isclass(list))
242
243        class CustomGetattr(object):
244            def __getattr__(self, attr):
245                return None
246        self.assertFalse(inspect.isclass(CustomGetattr()))
247
248    def test_get_slot_members(self):
249        class C(object):
250            __slots__ = ("a", "b")
251        x = C()
252        x.a = 42
253        members = dict(inspect.getmembers(x))
254        self.assertIn('a', members)
255        self.assertNotIn('b', members)
256
257    def test_isabstract(self):
258        from abc import ABCMeta, abstractmethod
259
260        class AbstractClassExample(metaclass=ABCMeta):
261
262            @abstractmethod
263            def foo(self):
264                pass
265
266        class ClassExample(AbstractClassExample):
267            def foo(self):
268                pass
269
270        a = ClassExample()
271
272        # Test general behaviour.
273        self.assertTrue(inspect.isabstract(AbstractClassExample))
274        self.assertFalse(inspect.isabstract(ClassExample))
275        self.assertFalse(inspect.isabstract(a))
276        self.assertFalse(inspect.isabstract(int))
277        self.assertFalse(inspect.isabstract(5))
278
279    def test_isabstract_during_init_subclass(self):
280        from abc import ABCMeta, abstractmethod
281        isabstract_checks = []
282        class AbstractChecker(metaclass=ABCMeta):
283            def __init_subclass__(cls):
284                isabstract_checks.append(inspect.isabstract(cls))
285        class AbstractClassExample(AbstractChecker):
286            @abstractmethod
287            def foo(self):
288                pass
289        class ClassExample(AbstractClassExample):
290            def foo(self):
291                pass
292        self.assertEqual(isabstract_checks, [True, False])
293
294        isabstract_checks.clear()
295        class AbstractChild(AbstractClassExample):
296            pass
297        class AbstractGrandchild(AbstractChild):
298            pass
299        class ConcreteGrandchild(ClassExample):
300            pass
301        self.assertEqual(isabstract_checks, [True, True, False])
302
303
304class TestInterpreterStack(IsTestBase):
305    def __init__(self, *args, **kwargs):
306        unittest.TestCase.__init__(self, *args, **kwargs)
307
308        git.abuse(7, 8, 9)
309
310    def test_abuse_done(self):
311        self.istest(inspect.istraceback, 'git.ex[2]')
312        self.istest(inspect.isframe, 'mod.fr')
313
314    def test_stack(self):
315        self.assertTrue(len(mod.st) >= 5)
316        self.assertEqual(revise(*mod.st[0][1:]),
317             (modfile, 16, 'eggs', ['    st = inspect.stack()\n'], 0))
318        self.assertEqual(revise(*mod.st[1][1:]),
319             (modfile, 9, 'spam', ['    eggs(b + d, c + f)\n'], 0))
320        self.assertEqual(revise(*mod.st[2][1:]),
321             (modfile, 43, 'argue', ['            spam(a, b, c)\n'], 0))
322        self.assertEqual(revise(*mod.st[3][1:]),
323             (modfile, 39, 'abuse', ['        self.argue(a, b, c)\n'], 0))
324        # Test named tuple fields
325        record = mod.st[0]
326        self.assertIs(record.frame, mod.fr)
327        self.assertEqual(record.lineno, 16)
328        self.assertEqual(record.filename, mod.__file__)
329        self.assertEqual(record.function, 'eggs')
330        self.assertIn('inspect.stack()', record.code_context[0])
331        self.assertEqual(record.index, 0)
332
333    def test_trace(self):
334        self.assertEqual(len(git.tr), 3)
335        self.assertEqual(revise(*git.tr[0][1:]),
336             (modfile, 43, 'argue', ['            spam(a, b, c)\n'], 0))
337        self.assertEqual(revise(*git.tr[1][1:]),
338             (modfile, 9, 'spam', ['    eggs(b + d, c + f)\n'], 0))
339        self.assertEqual(revise(*git.tr[2][1:]),
340             (modfile, 18, 'eggs', ['    q = y / 0\n'], 0))
341
342    def test_frame(self):
343        args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
344        self.assertEqual(args, ['x', 'y'])
345        self.assertEqual(varargs, None)
346        self.assertEqual(varkw, None)
347        self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
348        self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
349                         '(x=11, y=14)')
350
351    def test_previous_frame(self):
352        args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
353        self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
354        self.assertEqual(varargs, 'g')
355        self.assertEqual(varkw, 'h')
356        self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
357             '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
358
359class GetSourceBase(unittest.TestCase):
360    # Subclasses must override.
361    fodderModule = None
362
363    def setUp(self):
364        with open(inspect.getsourcefile(self.fodderModule)) as fp:
365            self.source = fp.read()
366
367    def sourcerange(self, top, bottom):
368        lines = self.source.split("\n")
369        return "\n".join(lines[top-1:bottom]) + ("\n" if bottom else "")
370
371    def assertSourceEqual(self, obj, top, bottom):
372        self.assertEqual(inspect.getsource(obj),
373                         self.sourcerange(top, bottom))
374
375class SlotUser:
376    'Docstrings for __slots__'
377    __slots__ = {'power': 'measured in kilowatts',
378                 'distance': 'measured in kilometers'}
379
380class TestRetrievingSourceCode(GetSourceBase):
381    fodderModule = mod
382
383    def test_getclasses(self):
384        classes = inspect.getmembers(mod, inspect.isclass)
385        self.assertEqual(classes,
386                         [('FesteringGob', mod.FesteringGob),
387                          ('MalodorousPervert', mod.MalodorousPervert),
388                          ('ParrotDroppings', mod.ParrotDroppings),
389                          ('StupidGit', mod.StupidGit),
390                          ('Tit', mod.MalodorousPervert),
391                          ('WhichComments', mod.WhichComments),
392                         ])
393        tree = inspect.getclasstree([cls[1] for cls in classes])
394        self.assertEqual(tree,
395                         [(object, ()),
396                          [(mod.ParrotDroppings, (object,)),
397                           [(mod.FesteringGob, (mod.MalodorousPervert,
398                                                   mod.ParrotDroppings))
399                            ],
400                           (mod.StupidGit, (object,)),
401                           [(mod.MalodorousPervert, (mod.StupidGit,)),
402                            [(mod.FesteringGob, (mod.MalodorousPervert,
403                                                    mod.ParrotDroppings))
404                             ]
405                            ],
406                            (mod.WhichComments, (object,),)
407                           ]
408                          ])
409        tree = inspect.getclasstree([cls[1] for cls in classes], True)
410        self.assertEqual(tree,
411                         [(object, ()),
412                          [(mod.ParrotDroppings, (object,)),
413                           (mod.StupidGit, (object,)),
414                           [(mod.MalodorousPervert, (mod.StupidGit,)),
415                            [(mod.FesteringGob, (mod.MalodorousPervert,
416                                                    mod.ParrotDroppings))
417                             ]
418                            ],
419                            (mod.WhichComments, (object,),)
420                           ]
421                          ])
422
423    def test_getfunctions(self):
424        functions = inspect.getmembers(mod, inspect.isfunction)
425        self.assertEqual(functions, [('eggs', mod.eggs),
426                                     ('lobbest', mod.lobbest),
427                                     ('spam', mod.spam)])
428
429    @unittest.skipIf(sys.flags.optimize >= 2,
430                     "Docstrings are omitted with -O2 and above")
431    def test_getdoc(self):
432        self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
433        self.assertEqual(inspect.getdoc(mod.StupidGit),
434                         'A longer,\n\nindented\n\ndocstring.')
435        self.assertEqual(inspect.getdoc(git.abuse),
436                         'Another\n\ndocstring\n\ncontaining\n\ntabs')
437        self.assertEqual(inspect.getdoc(SlotUser.power),
438                         'measured in kilowatts')
439        self.assertEqual(inspect.getdoc(SlotUser.distance),
440                         'measured in kilometers')
441
442    @unittest.skipIf(sys.flags.optimize >= 2,
443                     "Docstrings are omitted with -O2 and above")
444    def test_getdoc_inherited(self):
445        self.assertEqual(inspect.getdoc(mod.FesteringGob),
446                         'A longer,\n\nindented\n\ndocstring.')
447        self.assertEqual(inspect.getdoc(mod.FesteringGob.abuse),
448                         'Another\n\ndocstring\n\ncontaining\n\ntabs')
449        self.assertEqual(inspect.getdoc(mod.FesteringGob().abuse),
450                         'Another\n\ndocstring\n\ncontaining\n\ntabs')
451        self.assertEqual(inspect.getdoc(mod.FesteringGob.contradiction),
452                         'The automatic gainsaying.')
453
454    @unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
455    def test_finddoc(self):
456        finddoc = inspect._finddoc
457        self.assertEqual(finddoc(int), int.__doc__)
458        self.assertEqual(finddoc(int.to_bytes), int.to_bytes.__doc__)
459        self.assertEqual(finddoc(int().to_bytes), int.to_bytes.__doc__)
460        self.assertEqual(finddoc(int.from_bytes), int.from_bytes.__doc__)
461        self.assertEqual(finddoc(int.real), int.real.__doc__)
462
463    def test_cleandoc(self):
464        self.assertEqual(inspect.cleandoc('An\n    indented\n    docstring.'),
465                         'An\nindented\ndocstring.')
466
467    def test_getcomments(self):
468        self.assertEqual(inspect.getcomments(mod), '# line 1\n')
469        self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
470        self.assertEqual(inspect.getcomments(mod2.cls160), '# line 159\n')
471        # If the object source file is not available, return None.
472        co = compile('x=1', '_non_existing_filename.py', 'exec')
473        self.assertIsNone(inspect.getcomments(co))
474        # If the object has been defined in C, return None.
475        self.assertIsNone(inspect.getcomments(list))
476
477    def test_getmodule(self):
478        # Check actual module
479        self.assertEqual(inspect.getmodule(mod), mod)
480        # Check class (uses __module__ attribute)
481        self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
482        # Check a method (no __module__ attribute, falls back to filename)
483        self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
484        # Do it again (check the caching isn't broken)
485        self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
486        # Check a builtin
487        self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
488        # Check filename override
489        self.assertEqual(inspect.getmodule(None, modfile), mod)
490
491    def test_getmodule_file_not_found(self):
492        # See bpo-45406
493        def _getabsfile(obj, _filename):
494            raise FileNotFoundError('bad file')
495        with unittest.mock.patch('inspect.getabsfile', _getabsfile):
496            f = inspect.currentframe()
497            self.assertIsNone(inspect.getmodule(f))
498            inspect.getouterframes(f)  # smoke test
499
500    def test_getframeinfo_get_first_line(self):
501        frame_info = inspect.getframeinfo(self.fodderModule.fr, 50)
502        self.assertEqual(frame_info.code_context[0], "# line 1\n")
503        self.assertEqual(frame_info.code_context[1], "'A module docstring.'\n")
504
505    def test_getsource(self):
506        self.assertSourceEqual(git.abuse, 29, 39)
507        self.assertSourceEqual(mod.StupidGit, 21, 51)
508        self.assertSourceEqual(mod.lobbest, 75, 76)
509
510    def test_getsourcefile(self):
511        self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
512        self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
513        fn = "_non_existing_filename_used_for_sourcefile_test.py"
514        co = compile("x=1", fn, "exec")
515        self.assertEqual(inspect.getsourcefile(co), None)
516        linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
517        try:
518            self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
519        finally:
520            del linecache.cache[co.co_filename]
521
522    def test_getfile(self):
523        self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
524
525    def test_getfile_builtin_module(self):
526        with self.assertRaises(TypeError) as e:
527            inspect.getfile(sys)
528        self.assertTrue(str(e.exception).startswith('<module'))
529
530    def test_getfile_builtin_class(self):
531        with self.assertRaises(TypeError) as e:
532            inspect.getfile(int)
533        self.assertTrue(str(e.exception).startswith('<class'))
534
535    def test_getfile_builtin_function_or_method(self):
536        with self.assertRaises(TypeError) as e_abs:
537            inspect.getfile(abs)
538        self.assertIn('expected, got', str(e_abs.exception))
539        with self.assertRaises(TypeError) as e_append:
540            inspect.getfile(list.append)
541        self.assertIn('expected, got', str(e_append.exception))
542
543    def test_getfile_class_without_module(self):
544        class CM(type):
545            @property
546            def __module__(cls):
547                raise AttributeError
548        class C(metaclass=CM):
549            pass
550        with self.assertRaises(TypeError):
551            inspect.getfile(C)
552
553    def test_getfile_broken_repr(self):
554        class ErrorRepr:
555            def __repr__(self):
556                raise Exception('xyz')
557        er = ErrorRepr()
558        with self.assertRaises(TypeError):
559            inspect.getfile(er)
560
561    def test_getmodule_recursion(self):
562        from types import ModuleType
563        name = '__inspect_dummy'
564        m = sys.modules[name] = ModuleType(name)
565        m.__file__ = "<string>" # hopefully not a real filename...
566        m.__loader__ = "dummy"  # pretend the filename is understood by a loader
567        exec("def x(): pass", m.__dict__)
568        self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
569        del sys.modules[name]
570        inspect.getmodule(compile('a=10','','single'))
571
572    def test_proceed_with_fake_filename(self):
573        '''doctest monkeypatches linecache to enable inspection'''
574        fn, source = '<test>', 'def x(): pass\n'
575        getlines = linecache.getlines
576        def monkey(filename, module_globals=None):
577            if filename == fn:
578                return source.splitlines(keepends=True)
579            else:
580                return getlines(filename, module_globals)
581        linecache.getlines = monkey
582        try:
583            ns = {}
584            exec(compile(source, fn, 'single'), ns)
585            inspect.getsource(ns["x"])
586        finally:
587            linecache.getlines = getlines
588
589    def test_getsource_on_code_object(self):
590        self.assertSourceEqual(mod.eggs.__code__, 12, 18)
591
592class TestGettingSourceOfToplevelFrames(GetSourceBase):
593    fodderModule = mod
594
595    def test_range_toplevel_frame(self):
596        self.maxDiff = None
597        self.assertSourceEqual(mod.currentframe, 1, None)
598
599    def test_range_traceback_toplevel_frame(self):
600        self.assertSourceEqual(mod.tb, 1, None)
601
602class TestDecorators(GetSourceBase):
603    fodderModule = mod2
604
605    def test_wrapped_decorator(self):
606        self.assertSourceEqual(mod2.wrapped, 14, 17)
607
608    def test_replacing_decorator(self):
609        self.assertSourceEqual(mod2.gone, 9, 10)
610
611    def test_getsource_unwrap(self):
612        self.assertSourceEqual(mod2.real, 130, 132)
613
614    def test_decorator_with_lambda(self):
615        self.assertSourceEqual(mod2.func114, 113, 115)
616
617class TestOneliners(GetSourceBase):
618    fodderModule = mod2
619    def test_oneline_lambda(self):
620        # Test inspect.getsource with a one-line lambda function.
621        self.assertSourceEqual(mod2.oll, 25, 25)
622
623    def test_threeline_lambda(self):
624        # Test inspect.getsource with a three-line lambda function,
625        # where the second and third lines are _not_ indented.
626        self.assertSourceEqual(mod2.tll, 28, 30)
627
628    def test_twoline_indented_lambda(self):
629        # Test inspect.getsource with a two-line lambda function,
630        # where the second line _is_ indented.
631        self.assertSourceEqual(mod2.tlli, 33, 34)
632
633    def test_onelinefunc(self):
634        # Test inspect.getsource with a regular one-line function.
635        self.assertSourceEqual(mod2.onelinefunc, 37, 37)
636
637    def test_manyargs(self):
638        # Test inspect.getsource with a regular function where
639        # the arguments are on two lines and _not_ indented and
640        # the body on the second line with the last arguments.
641        self.assertSourceEqual(mod2.manyargs, 40, 41)
642
643    def test_twolinefunc(self):
644        # Test inspect.getsource with a regular function where
645        # the body is on two lines, following the argument list and
646        # continued on the next line by a \\.
647        self.assertSourceEqual(mod2.twolinefunc, 44, 45)
648
649    def test_lambda_in_list(self):
650        # Test inspect.getsource with a one-line lambda function
651        # defined in a list, indented.
652        self.assertSourceEqual(mod2.a[1], 49, 49)
653
654    def test_anonymous(self):
655        # Test inspect.getsource with a lambda function defined
656        # as argument to another function.
657        self.assertSourceEqual(mod2.anonymous, 55, 55)
658
659class TestBlockComments(GetSourceBase):
660    fodderModule = mod
661
662    def test_toplevel_class(self):
663        self.assertSourceEqual(mod.WhichComments, 96, 114)
664
665    def test_class_method(self):
666        self.assertSourceEqual(mod.WhichComments.f, 99, 104)
667
668    def test_class_async_method(self):
669        self.assertSourceEqual(mod.WhichComments.asyncf, 109, 112)
670
671class TestBuggyCases(GetSourceBase):
672    fodderModule = mod2
673
674    def test_with_comment(self):
675        self.assertSourceEqual(mod2.with_comment, 58, 59)
676
677    def test_multiline_sig(self):
678        self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
679
680    def test_nested_class(self):
681        self.assertSourceEqual(mod2.func69().func71, 71, 72)
682
683    def test_one_liner_followed_by_non_name(self):
684        self.assertSourceEqual(mod2.func77, 77, 77)
685
686    def test_one_liner_dedent_non_name(self):
687        self.assertSourceEqual(mod2.cls82.func83, 83, 83)
688
689    def test_with_comment_instead_of_docstring(self):
690        self.assertSourceEqual(mod2.func88, 88, 90)
691
692    def test_method_in_dynamic_class(self):
693        self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
694
695    # This should not skip for CPython, but might on a repackaged python where
696    # unicodedata is not an external module, or on pypy.
697    @unittest.skipIf(not hasattr(unicodedata, '__file__') or
698                                 unicodedata.__file__.endswith('.py'),
699                     "unicodedata is not an external binary module")
700    def test_findsource_binary(self):
701        self.assertRaises(OSError, inspect.getsource, unicodedata)
702        self.assertRaises(OSError, inspect.findsource, unicodedata)
703
704    def test_findsource_code_in_linecache(self):
705        lines = ["x=1"]
706        co = compile(lines[0], "_dynamically_created_file", "exec")
707        self.assertRaises(OSError, inspect.findsource, co)
708        self.assertRaises(OSError, inspect.getsource, co)
709        linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
710        try:
711            self.assertEqual(inspect.findsource(co), (lines,0))
712            self.assertEqual(inspect.getsource(co), lines[0])
713        finally:
714            del linecache.cache[co.co_filename]
715
716    def test_findsource_without_filename(self):
717        for fname in ['', '<string>']:
718            co = compile('x=1', fname, "exec")
719            self.assertRaises(IOError, inspect.findsource, co)
720            self.assertRaises(IOError, inspect.getsource, co)
721
722    def test_findsource_with_out_of_bounds_lineno(self):
723        mod_len = len(inspect.getsource(mod))
724        src = '\n' * 2* mod_len + "def f(): pass"
725        co = compile(src, mod.__file__, "exec")
726        g, l = {}, {}
727        eval(co, g, l)
728        func = l['f']
729        self.assertEqual(func.__code__.co_firstlineno, 1+2*mod_len)
730        with self.assertRaisesRegex(IOError, "lineno is out of bounds"):
731            inspect.findsource(func)
732
733    def test_getsource_on_method(self):
734        self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)
735
736    def test_nested_func(self):
737        self.assertSourceEqual(mod2.cls135.func136, 136, 139)
738
739    def test_class_definition_in_multiline_string_definition(self):
740        self.assertSourceEqual(mod2.cls149, 149, 152)
741
742    def test_class_definition_in_multiline_comment(self):
743        self.assertSourceEqual(mod2.cls160, 160, 163)
744
745    def test_nested_class_definition_indented_string(self):
746        self.assertSourceEqual(mod2.cls173.cls175, 175, 176)
747
748    def test_nested_class_definition(self):
749        self.assertSourceEqual(mod2.cls183, 183, 188)
750        self.assertSourceEqual(mod2.cls183.cls185, 185, 188)
751
752    def test_class_decorator(self):
753        self.assertSourceEqual(mod2.cls196, 194, 201)
754        self.assertSourceEqual(mod2.cls196.cls200, 198, 201)
755
756    def test_class_inside_conditional(self):
757        self.assertSourceEqual(mod2.cls238, 238, 240)
758        self.assertSourceEqual(mod2.cls238.cls239, 239, 240)
759
760    def test_multiple_children_classes(self):
761        self.assertSourceEqual(mod2.cls203, 203, 209)
762        self.assertSourceEqual(mod2.cls203.cls204, 204, 206)
763        self.assertSourceEqual(mod2.cls203.cls204.cls205, 205, 206)
764        self.assertSourceEqual(mod2.cls203.cls207, 207, 209)
765        self.assertSourceEqual(mod2.cls203.cls207.cls205, 208, 209)
766
767    def test_nested_class_definition_inside_function(self):
768        self.assertSourceEqual(mod2.func212(), 213, 214)
769        self.assertSourceEqual(mod2.cls213, 218, 222)
770        self.assertSourceEqual(mod2.cls213().func219(), 220, 221)
771
772    def test_nested_class_definition_inside_async_function(self):
773        import asyncio
774        self.addCleanup(asyncio.set_event_loop_policy, None)
775        self.assertSourceEqual(asyncio.run(mod2.func225()), 226, 227)
776        self.assertSourceEqual(mod2.cls226, 231, 235)
777        self.assertSourceEqual(asyncio.run(mod2.cls226().func232()), 233, 234)
778
779class TestNoEOL(GetSourceBase):
780    def setUp(self):
781        self.tempdir = TESTFN + '_dir'
782        os.mkdir(self.tempdir)
783        with open(os.path.join(self.tempdir,
784                               'inspect_fodder3%spy' % os.extsep), 'w') as f:
785            f.write("class X:\n    pass # No EOL")
786        with DirsOnSysPath(self.tempdir):
787            import inspect_fodder3 as mod3
788        self.fodderModule = mod3
789        super().setUp()
790
791    def tearDown(self):
792        shutil.rmtree(self.tempdir)
793
794    def test_class(self):
795        self.assertSourceEqual(self.fodderModule.X, 1, 2)
796
797
798class _BrokenDataDescriptor(object):
799    """
800    A broken data descriptor. See bug #1785.
801    """
802    def __get__(*args):
803        raise AttributeError("broken data descriptor")
804
805    def __set__(*args):
806        raise RuntimeError
807
808    def __getattr__(*args):
809        raise AttributeError("broken data descriptor")
810
811
812class _BrokenMethodDescriptor(object):
813    """
814    A broken method descriptor. See bug #1785.
815    """
816    def __get__(*args):
817        raise AttributeError("broken method descriptor")
818
819    def __getattr__(*args):
820        raise AttributeError("broken method descriptor")
821
822
823# Helper for testing classify_class_attrs.
824def attrs_wo_objs(cls):
825    return [t[:3] for t in inspect.classify_class_attrs(cls)]
826
827
828class TestClassesAndFunctions(unittest.TestCase):
829    def test_newstyle_mro(self):
830        # The same w/ new-class MRO.
831        class A(object):    pass
832        class B(A): pass
833        class C(A): pass
834        class D(B, C): pass
835
836        expected = (D, B, C, A, object)
837        got = inspect.getmro(D)
838        self.assertEqual(expected, got)
839
840    def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
841                            varkw_e=None, defaults_e=None, formatted=None):
842        with self.assertWarns(DeprecationWarning):
843            args, varargs, varkw, defaults = inspect.getargspec(routine)
844        self.assertEqual(args, args_e)
845        self.assertEqual(varargs, varargs_e)
846        self.assertEqual(varkw, varkw_e)
847        self.assertEqual(defaults, defaults_e)
848        if formatted is not None:
849            with self.assertWarns(DeprecationWarning):
850                self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
851                                 formatted)
852
853    def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
854                                    varkw_e=None, defaults_e=None,
855                                    posonlyargs_e=[], kwonlyargs_e=[],
856                                    kwonlydefaults_e=None,
857                                    ann_e={}, formatted=None):
858        args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
859            inspect.getfullargspec(routine)
860        self.assertEqual(args, args_e)
861        self.assertEqual(varargs, varargs_e)
862        self.assertEqual(varkw, varkw_e)
863        self.assertEqual(defaults, defaults_e)
864        self.assertEqual(kwonlyargs, kwonlyargs_e)
865        self.assertEqual(kwonlydefaults, kwonlydefaults_e)
866        self.assertEqual(ann, ann_e)
867        if formatted is not None:
868            with self.assertWarns(DeprecationWarning):
869                self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
870                                                       kwonlyargs, kwonlydefaults, ann),
871                                 formatted)
872
873    def test_getargspec(self):
874        self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
875
876        self.assertArgSpecEquals(mod.spam,
877                                 ['a', 'b', 'c', 'd', 'e', 'f'],
878                                 'g', 'h', (3, 4, 5),
879                                 '(a, b, c, d=3, e=4, f=5, *g, **h)')
880
881        self.assertRaises(ValueError, self.assertArgSpecEquals,
882                          mod2.keyworded, [])
883
884        self.assertRaises(ValueError, self.assertArgSpecEquals,
885                          mod2.annotated, [])
886        self.assertRaises(ValueError, self.assertArgSpecEquals,
887                          mod2.keyword_only_arg, [])
888
889
890    def test_getfullargspec(self):
891        self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
892                                     kwonlyargs_e=['arg2'],
893                                     kwonlydefaults_e={'arg2':1},
894                                     formatted='(*arg1, arg2=1)')
895
896        self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
897                                     ann_e={'arg1' : list},
898                                     formatted='(arg1: list)')
899        self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
900                                     kwonlyargs_e=['arg'],
901                                     formatted='(*, arg)')
902
903        self.assertFullArgSpecEquals(mod2.all_markers, ['a', 'b', 'c', 'd'],
904                                     kwonlyargs_e=['e', 'f'],
905                                     formatted='(a, b, c, d, *, e, f)')
906
907        self.assertFullArgSpecEquals(mod2.all_markers_with_args_and_kwargs,
908                                     ['a', 'b', 'c', 'd'],
909                                     varargs_e='args',
910                                     varkw_e='kwargs',
911                                     kwonlyargs_e=['e', 'f'],
912                                     formatted='(a, b, c, d, *args, e, f, **kwargs)')
913
914        self.assertFullArgSpecEquals(mod2.all_markers_with_defaults, ['a', 'b', 'c', 'd'],
915                                     defaults_e=(1,2,3),
916                                     kwonlyargs_e=['e', 'f'],
917                                     kwonlydefaults_e={'e': 4, 'f': 5},
918                                     formatted='(a, b=1, c=2, d=3, *, e=4, f=5)')
919
920    def test_argspec_api_ignores_wrapped(self):
921        # Issue 20684: low level introspection API must ignore __wrapped__
922        @functools.wraps(mod.spam)
923        def ham(x, y):
924            pass
925        # Basic check
926        self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
927        self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
928        self.assertFullArgSpecEquals(functools.partial(ham),
929                                     ['x', 'y'], formatted='(x, y)')
930        # Other variants
931        def check_method(f):
932            self.assertArgSpecEquals(f, ['self', 'x', 'y'],
933                                        formatted='(self, x, y)')
934        class C:
935            @functools.wraps(mod.spam)
936            def ham(self, x, y):
937                pass
938            pham = functools.partialmethod(ham)
939            @functools.wraps(mod.spam)
940            def __call__(self, x, y):
941                pass
942        check_method(C())
943        check_method(C.ham)
944        check_method(C().ham)
945        check_method(C.pham)
946        check_method(C().pham)
947
948        class C_new:
949            @functools.wraps(mod.spam)
950            def __new__(self, x, y):
951                pass
952        check_method(C_new)
953
954        class C_init:
955            @functools.wraps(mod.spam)
956            def __init__(self, x, y):
957                pass
958        check_method(C_init)
959
960    def test_getfullargspec_signature_attr(self):
961        def test():
962            pass
963        spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
964        test.__signature__ = inspect.Signature(parameters=(spam_param,))
965
966        self.assertFullArgSpecEquals(test, ['spam'], formatted='(spam)')
967
968    def test_getfullargspec_signature_annos(self):
969        def test(a:'spam') -> 'ham': pass
970        spec = inspect.getfullargspec(test)
971        self.assertEqual(test.__annotations__, spec.annotations)
972
973        def test(): pass
974        spec = inspect.getfullargspec(test)
975        self.assertEqual(test.__annotations__, spec.annotations)
976
977    @unittest.skipIf(MISSING_C_DOCSTRINGS,
978                     "Signature information for builtins requires docstrings")
979    def test_getfullargspec_builtin_methods(self):
980        self.assertFullArgSpecEquals(_pickle.Pickler.dump, ['self', 'obj'],
981                                     formatted='(self, obj)')
982
983        self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump, ['self', 'obj'],
984                                     formatted='(self, obj)')
985
986        self.assertFullArgSpecEquals(
987             os.stat,
988             args_e=['path'],
989             kwonlyargs_e=['dir_fd', 'follow_symlinks'],
990             kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
991             formatted='(path, *, dir_fd=None, follow_symlinks=True)')
992
993    @cpython_only
994    @unittest.skipIf(MISSING_C_DOCSTRINGS,
995                     "Signature information for builtins requires docstrings")
996    def test_getfullargspec_builtin_func(self):
997        import _testcapi
998        builtin = _testcapi.docstring_with_signature_with_defaults
999        spec = inspect.getfullargspec(builtin)
1000        self.assertEqual(spec.defaults[0], 'avocado')
1001
1002    @cpython_only
1003    @unittest.skipIf(MISSING_C_DOCSTRINGS,
1004                     "Signature information for builtins requires docstrings")
1005    def test_getfullargspec_builtin_func_no_signature(self):
1006        import _testcapi
1007        builtin = _testcapi.docstring_no_signature
1008        with self.assertRaises(TypeError):
1009            inspect.getfullargspec(builtin)
1010
1011    def test_getfullargspec_definition_order_preserved_on_kwonly(self):
1012        for fn in signatures_with_lexicographic_keyword_only_parameters():
1013            signature = inspect.getfullargspec(fn)
1014            l = list(signature.kwonlyargs)
1015            sorted_l = sorted(l)
1016            self.assertTrue(l)
1017            self.assertEqual(l, sorted_l)
1018        signature = inspect.getfullargspec(unsorted_keyword_only_parameters_fn)
1019        l = list(signature.kwonlyargs)
1020        self.assertEqual(l, unsorted_keyword_only_parameters)
1021
1022    def test_getargspec_method(self):
1023        class A(object):
1024            def m(self):
1025                pass
1026        self.assertArgSpecEquals(A.m, ['self'])
1027
1028    def test_classify_newstyle(self):
1029        class A(object):
1030
1031            def s(): pass
1032            s = staticmethod(s)
1033
1034            def c(cls): pass
1035            c = classmethod(c)
1036
1037            def getp(self): pass
1038            p = property(getp)
1039
1040            def m(self): pass
1041
1042            def m1(self): pass
1043
1044            datablob = '1'
1045
1046            dd = _BrokenDataDescriptor()
1047            md = _BrokenMethodDescriptor()
1048
1049        attrs = attrs_wo_objs(A)
1050
1051        self.assertIn(('__new__', 'static method', object), attrs,
1052                      'missing __new__')
1053        self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
1054
1055        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1056        self.assertIn(('c', 'class method', A), attrs, 'missing class method')
1057        self.assertIn(('p', 'property', A), attrs, 'missing property')
1058        self.assertIn(('m', 'method', A), attrs,
1059                      'missing plain method: %r' % attrs)
1060        self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1061        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
1062        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1063        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
1064
1065        class B(A):
1066
1067            def m(self): pass
1068
1069        attrs = attrs_wo_objs(B)
1070        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1071        self.assertIn(('c', 'class method', A), attrs, 'missing class method')
1072        self.assertIn(('p', 'property', A), attrs, 'missing property')
1073        self.assertIn(('m', 'method', B), attrs, 'missing plain method')
1074        self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1075        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
1076        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1077        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
1078
1079
1080        class C(A):
1081
1082            def m(self): pass
1083            def c(self): pass
1084
1085        attrs = attrs_wo_objs(C)
1086        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1087        self.assertIn(('c', 'method', C), attrs, 'missing plain method')
1088        self.assertIn(('p', 'property', A), attrs, 'missing property')
1089        self.assertIn(('m', 'method', C), attrs, 'missing plain method')
1090        self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1091        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
1092        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1093        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
1094
1095        class D(B, C):
1096
1097            def m1(self): pass
1098
1099        attrs = attrs_wo_objs(D)
1100        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1101        self.assertIn(('c', 'method', C), attrs, 'missing plain method')
1102        self.assertIn(('p', 'property', A), attrs, 'missing property')
1103        self.assertIn(('m', 'method', B), attrs, 'missing plain method')
1104        self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
1105        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
1106        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1107        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
1108
1109    def test_classify_builtin_types(self):
1110        # Simple sanity check that all built-in types can have their
1111        # attributes classified.
1112        for name in dir(__builtins__):
1113            builtin = getattr(__builtins__, name)
1114            if isinstance(builtin, type):
1115                inspect.classify_class_attrs(builtin)
1116
1117        attrs = attrs_wo_objs(bool)
1118        self.assertIn(('__new__', 'static method', bool), attrs,
1119                      'missing __new__')
1120        self.assertIn(('from_bytes', 'class method', int), attrs,
1121                      'missing class method')
1122        self.assertIn(('to_bytes', 'method', int), attrs,
1123                      'missing plain method')
1124        self.assertIn(('__add__', 'method', int), attrs,
1125                      'missing plain method')
1126        self.assertIn(('__and__', 'method', bool), attrs,
1127                      'missing plain method')
1128
1129    def test_classify_DynamicClassAttribute(self):
1130        class Meta(type):
1131            def __getattr__(self, name):
1132                if name == 'ham':
1133                    return 'spam'
1134                return super().__getattr__(name)
1135        class VA(metaclass=Meta):
1136            @types.DynamicClassAttribute
1137            def ham(self):
1138                return 'eggs'
1139        should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
1140        self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
1141        should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
1142        self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
1143
1144    def test_classify_overrides_bool(self):
1145        class NoBool(object):
1146            def __eq__(self, other):
1147                return NoBool()
1148
1149            def __bool__(self):
1150                raise NotImplementedError(
1151                    "This object does not specify a boolean value")
1152
1153        class HasNB(object):
1154            dd = NoBool()
1155
1156        should_find_attr = inspect.Attribute('dd', 'data', HasNB, HasNB.dd)
1157        self.assertIn(should_find_attr, inspect.classify_class_attrs(HasNB))
1158
1159    def test_classify_metaclass_class_attribute(self):
1160        class Meta(type):
1161            fish = 'slap'
1162            def __dir__(self):
1163                return ['__class__', '__module__', '__name__', 'fish']
1164        class Class(metaclass=Meta):
1165            pass
1166        should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
1167        self.assertIn(should_find, inspect.classify_class_attrs(Class))
1168
1169    def test_classify_VirtualAttribute(self):
1170        class Meta(type):
1171            def __dir__(cls):
1172                return ['__class__', '__module__', '__name__', 'BOOM']
1173            def __getattr__(self, name):
1174                if name =='BOOM':
1175                    return 42
1176                return super().__getattr(name)
1177        class Class(metaclass=Meta):
1178            pass
1179        should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
1180        self.assertIn(should_find, inspect.classify_class_attrs(Class))
1181
1182    def test_classify_VirtualAttribute_multi_classes(self):
1183        class Meta1(type):
1184            def __dir__(cls):
1185                return ['__class__', '__module__', '__name__', 'one']
1186            def __getattr__(self, name):
1187                if name =='one':
1188                    return 1
1189                return super().__getattr__(name)
1190        class Meta2(type):
1191            def __dir__(cls):
1192                return ['__class__', '__module__', '__name__', 'two']
1193            def __getattr__(self, name):
1194                if name =='two':
1195                    return 2
1196                return super().__getattr__(name)
1197        class Meta3(Meta1, Meta2):
1198            def __dir__(cls):
1199                return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
1200                    Meta1.__dir__(cls) + Meta2.__dir__(cls))))
1201            def __getattr__(self, name):
1202                if name =='three':
1203                    return 3
1204                return super().__getattr__(name)
1205        class Class1(metaclass=Meta1):
1206            pass
1207        class Class2(Class1, metaclass=Meta3):
1208            pass
1209
1210        should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
1211        should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
1212        should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
1213        cca = inspect.classify_class_attrs(Class2)
1214        for sf in (should_find1, should_find2, should_find3):
1215            self.assertIn(sf, cca)
1216
1217    def test_classify_class_attrs_with_buggy_dir(self):
1218        class M(type):
1219            def __dir__(cls):
1220                return ['__class__', '__name__', 'missing']
1221        class C(metaclass=M):
1222            pass
1223        attrs = [a[0] for a in inspect.classify_class_attrs(C)]
1224        self.assertNotIn('missing', attrs)
1225
1226    def test_getmembers_descriptors(self):
1227        class A(object):
1228            dd = _BrokenDataDescriptor()
1229            md = _BrokenMethodDescriptor()
1230
1231        def pred_wrapper(pred):
1232            # A quick'n'dirty way to discard standard attributes of new-style
1233            # classes.
1234            class Empty(object):
1235                pass
1236            def wrapped(x):
1237                if '__name__' in dir(x) and hasattr(Empty, x.__name__):
1238                    return False
1239                return pred(x)
1240            return wrapped
1241
1242        ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
1243        isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
1244
1245        self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
1246            [('md', A.__dict__['md'])])
1247        self.assertEqual(inspect.getmembers(A, isdatadescriptor),
1248            [('dd', A.__dict__['dd'])])
1249
1250        class B(A):
1251            pass
1252
1253        self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
1254            [('md', A.__dict__['md'])])
1255        self.assertEqual(inspect.getmembers(B, isdatadescriptor),
1256            [('dd', A.__dict__['dd'])])
1257
1258    def test_getmembers_method(self):
1259        class B:
1260            def f(self):
1261                pass
1262
1263        self.assertIn(('f', B.f), inspect.getmembers(B))
1264        self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
1265        b = B()
1266        self.assertIn(('f', b.f), inspect.getmembers(b))
1267        self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
1268
1269    def test_getmembers_VirtualAttribute(self):
1270        class M(type):
1271            def __getattr__(cls, name):
1272                if name == 'eggs':
1273                    return 'scrambled'
1274                return super().__getattr__(name)
1275        class A(metaclass=M):
1276            @types.DynamicClassAttribute
1277            def eggs(self):
1278                return 'spam'
1279        self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
1280        self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
1281
1282    def test_getmembers_with_buggy_dir(self):
1283        class M(type):
1284            def __dir__(cls):
1285                return ['__class__', '__name__', 'missing']
1286        class C(metaclass=M):
1287            pass
1288        attrs = [a[0] for a in inspect.getmembers(C)]
1289        self.assertNotIn('missing', attrs)
1290
1291class TestIsDataDescriptor(unittest.TestCase):
1292
1293    def test_custom_descriptors(self):
1294        class NonDataDescriptor:
1295            def __get__(self, value, type=None): pass
1296        class DataDescriptor0:
1297            def __set__(self, name, value): pass
1298        class DataDescriptor1:
1299            def __delete__(self, name): pass
1300        class DataDescriptor2:
1301            __set__ = None
1302        self.assertFalse(inspect.isdatadescriptor(NonDataDescriptor()),
1303                         'class with only __get__ not a data descriptor')
1304        self.assertTrue(inspect.isdatadescriptor(DataDescriptor0()),
1305                        'class with __set__ is a data descriptor')
1306        self.assertTrue(inspect.isdatadescriptor(DataDescriptor1()),
1307                        'class with __delete__ is a data descriptor')
1308        self.assertTrue(inspect.isdatadescriptor(DataDescriptor2()),
1309                        'class with __set__ = None is a data descriptor')
1310
1311    def test_slot(self):
1312        class Slotted:
1313            __slots__ = 'foo',
1314        self.assertTrue(inspect.isdatadescriptor(Slotted.foo),
1315                        'a slot is a data descriptor')
1316
1317    def test_property(self):
1318        class Propertied:
1319            @property
1320            def a_property(self):
1321                pass
1322        self.assertTrue(inspect.isdatadescriptor(Propertied.a_property),
1323                        'a property is a data descriptor')
1324
1325    def test_functions(self):
1326        class Test(object):
1327            def instance_method(self): pass
1328            @classmethod
1329            def class_method(cls): pass
1330            @staticmethod
1331            def static_method(): pass
1332        def function():
1333            pass
1334        a_lambda = lambda: None
1335        self.assertFalse(inspect.isdatadescriptor(Test().instance_method),
1336                         'a instance method is not a data descriptor')
1337        self.assertFalse(inspect.isdatadescriptor(Test().class_method),
1338                         'a class method is not a data descriptor')
1339        self.assertFalse(inspect.isdatadescriptor(Test().static_method),
1340                         'a static method is not a data descriptor')
1341        self.assertFalse(inspect.isdatadescriptor(function),
1342                         'a function is not a data descriptor')
1343        self.assertFalse(inspect.isdatadescriptor(a_lambda),
1344                         'a lambda is not a data descriptor')
1345
1346
1347_global_ref = object()
1348class TestGetClosureVars(unittest.TestCase):
1349
1350    def test_name_resolution(self):
1351        # Basic test of the 4 different resolution mechanisms
1352        def f(nonlocal_ref):
1353            def g(local_ref):
1354                print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1355            return g
1356        _arg = object()
1357        nonlocal_vars = {"nonlocal_ref": _arg}
1358        global_vars = {"_global_ref": _global_ref}
1359        builtin_vars = {"print": print}
1360        unbound_names = {"unbound_ref"}
1361        expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1362                                       builtin_vars, unbound_names)
1363        self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1364
1365    def test_generator_closure(self):
1366        def f(nonlocal_ref):
1367            def g(local_ref):
1368                print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1369                yield
1370            return g
1371        _arg = object()
1372        nonlocal_vars = {"nonlocal_ref": _arg}
1373        global_vars = {"_global_ref": _global_ref}
1374        builtin_vars = {"print": print}
1375        unbound_names = {"unbound_ref"}
1376        expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1377                                       builtin_vars, unbound_names)
1378        self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1379
1380    def test_method_closure(self):
1381        class C:
1382            def f(self, nonlocal_ref):
1383                def g(local_ref):
1384                    print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1385                return g
1386        _arg = object()
1387        nonlocal_vars = {"nonlocal_ref": _arg}
1388        global_vars = {"_global_ref": _global_ref}
1389        builtin_vars = {"print": print}
1390        unbound_names = {"unbound_ref"}
1391        expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1392                                       builtin_vars, unbound_names)
1393        self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
1394
1395    def test_nonlocal_vars(self):
1396        # More complex tests of nonlocal resolution
1397        def _nonlocal_vars(f):
1398            return inspect.getclosurevars(f).nonlocals
1399
1400        def make_adder(x):
1401            def add(y):
1402                return x + y
1403            return add
1404
1405        def curry(func, arg1):
1406            return lambda arg2: func(arg1, arg2)
1407
1408        def less_than(a, b):
1409            return a < b
1410
1411        # The infamous Y combinator.
1412        def Y(le):
1413            def g(f):
1414                return le(lambda x: f(f)(x))
1415            Y.g_ref = g
1416            return g(g)
1417
1418        def check_y_combinator(func):
1419            self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
1420
1421        inc = make_adder(1)
1422        add_two = make_adder(2)
1423        greater_than_five = curry(less_than, 5)
1424
1425        self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1426        self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1427        self.assertEqual(_nonlocal_vars(greater_than_five),
1428                         {'arg1': 5, 'func': less_than})
1429        self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1430                         {'x': 3})
1431        Y(check_y_combinator)
1432
1433    def test_getclosurevars_empty(self):
1434        def foo(): pass
1435        _empty = inspect.ClosureVars({}, {}, {}, set())
1436        self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1437        self.assertEqual(inspect.getclosurevars(foo), _empty)
1438
1439    def test_getclosurevars_error(self):
1440        class T: pass
1441        self.assertRaises(TypeError, inspect.getclosurevars, 1)
1442        self.assertRaises(TypeError, inspect.getclosurevars, list)
1443        self.assertRaises(TypeError, inspect.getclosurevars, {})
1444
1445    def _private_globals(self):
1446        code = """def f(): print(path)"""
1447        ns = {}
1448        exec(code, ns)
1449        return ns["f"], ns
1450
1451    def test_builtins_fallback(self):
1452        f, ns = self._private_globals()
1453        ns.pop("__builtins__", None)
1454        expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1455        self.assertEqual(inspect.getclosurevars(f), expected)
1456
1457    def test_builtins_as_dict(self):
1458        f, ns = self._private_globals()
1459        ns["__builtins__"] = {"path":1}
1460        expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1461        self.assertEqual(inspect.getclosurevars(f), expected)
1462
1463    def test_builtins_as_module(self):
1464        f, ns = self._private_globals()
1465        ns["__builtins__"] = os
1466        expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1467        self.assertEqual(inspect.getclosurevars(f), expected)
1468
1469
1470class TestGetcallargsFunctions(unittest.TestCase):
1471
1472    def assertEqualCallArgs(self, func, call_params_string, locs=None):
1473        locs = dict(locs or {}, func=func)
1474        r1 = eval('func(%s)' % call_params_string, None, locs)
1475        r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1476                  locs)
1477        self.assertEqual(r1, r2)
1478
1479    def assertEqualException(self, func, call_param_string, locs=None):
1480        locs = dict(locs or {}, func=func)
1481        try:
1482            eval('func(%s)' % call_param_string, None, locs)
1483        except Exception as e:
1484            ex1 = e
1485        else:
1486            self.fail('Exception not raised')
1487        try:
1488            eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1489                 locs)
1490        except Exception as e:
1491            ex2 = e
1492        else:
1493            self.fail('Exception not raised')
1494        self.assertIs(type(ex1), type(ex2))
1495        self.assertEqual(str(ex1), str(ex2))
1496        del ex1, ex2
1497
1498    def makeCallable(self, signature):
1499        """Create a function that returns its locals()"""
1500        code = "lambda %s: locals()"
1501        return eval(code % signature)
1502
1503    def test_plain(self):
1504        f = self.makeCallable('a, b=1')
1505        self.assertEqualCallArgs(f, '2')
1506        self.assertEqualCallArgs(f, '2, 3')
1507        self.assertEqualCallArgs(f, 'a=2')
1508        self.assertEqualCallArgs(f, 'b=3, a=2')
1509        self.assertEqualCallArgs(f, '2, b=3')
1510        # expand *iterable / **mapping
1511        self.assertEqualCallArgs(f, '*(2,)')
1512        self.assertEqualCallArgs(f, '*[2]')
1513        self.assertEqualCallArgs(f, '*(2, 3)')
1514        self.assertEqualCallArgs(f, '*[2, 3]')
1515        self.assertEqualCallArgs(f, '**{"a":2}')
1516        self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1517        self.assertEqualCallArgs(f, '2, **{"b":3}')
1518        self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1519        # expand UserList / UserDict
1520        self.assertEqualCallArgs(f, '*collections.UserList([2])')
1521        self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1522        self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1523        self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1524        self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1525
1526    def test_varargs(self):
1527        f = self.makeCallable('a, b=1, *c')
1528        self.assertEqualCallArgs(f, '2')
1529        self.assertEqualCallArgs(f, '2, 3')
1530        self.assertEqualCallArgs(f, '2, 3, 4')
1531        self.assertEqualCallArgs(f, '*(2,3,4)')
1532        self.assertEqualCallArgs(f, '2, *[3,4]')
1533        self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1534
1535    def test_varkw(self):
1536        f = self.makeCallable('a, b=1, **c')
1537        self.assertEqualCallArgs(f, 'a=2')
1538        self.assertEqualCallArgs(f, '2, b=3, c=4')
1539        self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1540        self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1541        self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1542        self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1543        self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1544        self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1545        self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1546
1547    def test_varkw_only(self):
1548        # issue11256:
1549        f = self.makeCallable('**c')
1550        self.assertEqualCallArgs(f, '')
1551        self.assertEqualCallArgs(f, 'a=1')
1552        self.assertEqualCallArgs(f, 'a=1, b=2')
1553        self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1554        self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1555        self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1556
1557    def test_keyword_only(self):
1558        f = self.makeCallable('a=3, *, c, d=2')
1559        self.assertEqualCallArgs(f, 'c=3')
1560        self.assertEqualCallArgs(f, 'c=3, a=3')
1561        self.assertEqualCallArgs(f, 'a=2, c=4')
1562        self.assertEqualCallArgs(f, '4, c=4')
1563        self.assertEqualException(f, '')
1564        self.assertEqualException(f, '3')
1565        self.assertEqualException(f, 'a=3')
1566        self.assertEqualException(f, 'd=4')
1567
1568        f = self.makeCallable('*, c, d=2')
1569        self.assertEqualCallArgs(f, 'c=3')
1570        self.assertEqualCallArgs(f, 'c=3, d=4')
1571        self.assertEqualCallArgs(f, 'd=4, c=3')
1572
1573    def test_multiple_features(self):
1574        f = self.makeCallable('a, b=2, *f, **g')
1575        self.assertEqualCallArgs(f, '2, 3, 7')
1576        self.assertEqualCallArgs(f, '2, 3, x=8')
1577        self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1578        self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1579        self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1580        self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1581                                 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1582        self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1583                                 '(4,[5,6])]), **collections.UserDict('
1584                                 'y=9, z=10)')
1585
1586        f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1587        self.assertEqualCallArgs(f, '2, 3, x=8')
1588        self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1589        self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1590        self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1591        self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1592                                 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1593        self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1594                                 '(4,[5,6])]), q=0, **collections.UserDict('
1595                                 'y=9, z=10)')
1596
1597    def test_errors(self):
1598        f0 = self.makeCallable('')
1599        f1 = self.makeCallable('a, b')
1600        f2 = self.makeCallable('a, b=1')
1601        # f0 takes no arguments
1602        self.assertEqualException(f0, '1')
1603        self.assertEqualException(f0, 'x=1')
1604        self.assertEqualException(f0, '1,x=1')
1605        # f1 takes exactly 2 arguments
1606        self.assertEqualException(f1, '')
1607        self.assertEqualException(f1, '1')
1608        self.assertEqualException(f1, 'a=2')
1609        self.assertEqualException(f1, 'b=3')
1610        # f2 takes at least 1 argument
1611        self.assertEqualException(f2, '')
1612        self.assertEqualException(f2, 'b=3')
1613        for f in f1, f2:
1614            # f1/f2 takes exactly/at most 2 arguments
1615            self.assertEqualException(f, '2, 3, 4')
1616            self.assertEqualException(f, '1, 2, 3, a=1')
1617            self.assertEqualException(f, '2, 3, 4, c=5')
1618            # XXX: success of this one depends on dict order
1619            ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
1620            # f got an unexpected keyword argument
1621            self.assertEqualException(f, 'c=2')
1622            self.assertEqualException(f, '2, c=3')
1623            self.assertEqualException(f, '2, 3, c=4')
1624            self.assertEqualException(f, '2, c=4, b=3')
1625            self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1626            # f got multiple values for keyword argument
1627            self.assertEqualException(f, '1, a=2')
1628            self.assertEqualException(f, '1, **{"a":2}')
1629            self.assertEqualException(f, '1, 2, b=3')
1630            # XXX: Python inconsistency
1631            # - for functions and bound methods: unexpected keyword 'c'
1632            # - for unbound methods: multiple values for keyword 'a'
1633            #self.assertEqualException(f, '1, c=3, a=2')
1634        # issue11256:
1635        f3 = self.makeCallable('**c')
1636        self.assertEqualException(f3, '1, 2')
1637        self.assertEqualException(f3, '1, 2, a=1, b=2')
1638        f4 = self.makeCallable('*, a, b=0')
1639        self.assertEqualException(f3, '1, 2')
1640        self.assertEqualException(f3, '1, 2, a=1, b=2')
1641
1642        # issue #20816: getcallargs() fails to iterate over non-existent
1643        # kwonlydefaults and raises a wrong TypeError
1644        def f5(*, a): pass
1645        with self.assertRaisesRegex(TypeError,
1646                                    'missing 1 required keyword-only'):
1647            inspect.getcallargs(f5)
1648
1649
1650        # issue20817:
1651        def f6(a, b, c):
1652            pass
1653        with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
1654            inspect.getcallargs(f6)
1655
1656        # bpo-33197
1657        with self.assertRaisesRegex(ValueError,
1658                                    'variadic keyword parameters cannot'
1659                                    ' have default values'):
1660            inspect.Parameter("foo", kind=inspect.Parameter.VAR_KEYWORD,
1661                              default=42)
1662        with self.assertRaisesRegex(ValueError,
1663                                    "value 5 is not a valid Parameter.kind"):
1664            inspect.Parameter("bar", kind=5, default=42)
1665
1666        with self.assertRaisesRegex(TypeError,
1667                                   'name must be a str, not a int'):
1668            inspect.Parameter(123, kind=4)
1669
1670class TestGetcallargsMethods(TestGetcallargsFunctions):
1671
1672    def setUp(self):
1673        class Foo(object):
1674            pass
1675        self.cls = Foo
1676        self.inst = Foo()
1677
1678    def makeCallable(self, signature):
1679        assert 'self' not in signature
1680        mk = super(TestGetcallargsMethods, self).makeCallable
1681        self.cls.method = mk('self, ' + signature)
1682        return self.inst.method
1683
1684class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1685
1686    def makeCallable(self, signature):
1687        super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1688        return self.cls.method
1689
1690    def assertEqualCallArgs(self, func, call_params_string, locs=None):
1691        return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1692            *self._getAssertEqualParams(func, call_params_string, locs))
1693
1694    def assertEqualException(self, func, call_params_string, locs=None):
1695        return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1696            *self._getAssertEqualParams(func, call_params_string, locs))
1697
1698    def _getAssertEqualParams(self, func, call_params_string, locs=None):
1699        assert 'inst' not in call_params_string
1700        locs = dict(locs or {}, inst=self.inst)
1701        return (func, 'inst,' + call_params_string, locs)
1702
1703
1704class TestGetattrStatic(unittest.TestCase):
1705
1706    def test_basic(self):
1707        class Thing(object):
1708            x = object()
1709
1710        thing = Thing()
1711        self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1712        self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1713        with self.assertRaises(AttributeError):
1714            inspect.getattr_static(thing, 'y')
1715
1716        self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1717
1718    def test_inherited(self):
1719        class Thing(object):
1720            x = object()
1721        class OtherThing(Thing):
1722            pass
1723
1724        something = OtherThing()
1725        self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1726
1727    def test_instance_attr(self):
1728        class Thing(object):
1729            x = 2
1730            def __init__(self, x):
1731                self.x = x
1732        thing = Thing(3)
1733        self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1734        del thing.x
1735        self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1736
1737    def test_property(self):
1738        class Thing(object):
1739            @property
1740            def x(self):
1741                raise AttributeError("I'm pretending not to exist")
1742        thing = Thing()
1743        self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1744
1745    def test_descriptor_raises_AttributeError(self):
1746        class descriptor(object):
1747            def __get__(*_):
1748                raise AttributeError("I'm pretending not to exist")
1749        desc = descriptor()
1750        class Thing(object):
1751            x = desc
1752        thing = Thing()
1753        self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1754
1755    def test_classAttribute(self):
1756        class Thing(object):
1757            x = object()
1758
1759        self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1760
1761    def test_classVirtualAttribute(self):
1762        class Thing(object):
1763            @types.DynamicClassAttribute
1764            def x(self):
1765                return self._x
1766            _x = object()
1767
1768        self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1769
1770    def test_inherited_classattribute(self):
1771        class Thing(object):
1772            x = object()
1773        class OtherThing(Thing):
1774            pass
1775
1776        self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1777
1778    def test_slots(self):
1779        class Thing(object):
1780            y = 'bar'
1781            __slots__ = ['x']
1782            def __init__(self):
1783                self.x = 'foo'
1784        thing = Thing()
1785        self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1786        self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1787
1788        del thing.x
1789        self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1790
1791    def test_metaclass(self):
1792        class meta(type):
1793            attr = 'foo'
1794        class Thing(object, metaclass=meta):
1795            pass
1796        self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1797
1798        class sub(meta):
1799            pass
1800        class OtherThing(object, metaclass=sub):
1801            x = 3
1802        self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1803
1804        class OtherOtherThing(OtherThing):
1805            pass
1806        # this test is odd, but it was added as it exposed a bug
1807        self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1808
1809    def test_no_dict_no_slots(self):
1810        self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1811        self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1812
1813    def test_no_dict_no_slots_instance_member(self):
1814        # returns descriptor
1815        with open(__file__) as handle:
1816            self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1817
1818    def test_inherited_slots(self):
1819        # returns descriptor
1820        class Thing(object):
1821            __slots__ = ['x']
1822            def __init__(self):
1823                self.x = 'foo'
1824
1825        class OtherThing(Thing):
1826            pass
1827        # it would be nice if this worked...
1828        # we get the descriptor instead of the instance attribute
1829        self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1830
1831    def test_descriptor(self):
1832        class descriptor(object):
1833            def __get__(self, instance, owner):
1834                return 3
1835        class Foo(object):
1836            d = descriptor()
1837
1838        foo = Foo()
1839
1840        # for a non data descriptor we return the instance attribute
1841        foo.__dict__['d'] = 1
1842        self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1843
1844        # if the descriptor is a data-descriptor we should return the
1845        # descriptor
1846        descriptor.__set__ = lambda s, i, v: None
1847        self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1848
1849
1850    def test_metaclass_with_descriptor(self):
1851        class descriptor(object):
1852            def __get__(self, instance, owner):
1853                return 3
1854        class meta(type):
1855            d = descriptor()
1856        class Thing(object, metaclass=meta):
1857            pass
1858        self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1859
1860
1861    def test_class_as_property(self):
1862        class Base(object):
1863            foo = 3
1864
1865        class Something(Base):
1866            executed = False
1867            @property
1868            def __class__(self):
1869                self.executed = True
1870                return object
1871
1872        instance = Something()
1873        self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1874        self.assertFalse(instance.executed)
1875        self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1876
1877    def test_mro_as_property(self):
1878        class Meta(type):
1879            @property
1880            def __mro__(self):
1881                return (object,)
1882
1883        class Base(object):
1884            foo = 3
1885
1886        class Something(Base, metaclass=Meta):
1887            pass
1888
1889        self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
1890        self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1891
1892    def test_dict_as_property(self):
1893        test = self
1894        test.called = False
1895
1896        class Foo(dict):
1897            a = 3
1898            @property
1899            def __dict__(self):
1900                test.called = True
1901                return {}
1902
1903        foo = Foo()
1904        foo.a = 4
1905        self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1906        self.assertFalse(test.called)
1907
1908    def test_custom_object_dict(self):
1909        test = self
1910        test.called = False
1911
1912        class Custom(dict):
1913            def get(self, key, default=None):
1914                test.called = True
1915                super().get(key, default)
1916
1917        class Foo(object):
1918            a = 3
1919        foo = Foo()
1920        foo.__dict__ = Custom()
1921        self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
1922        self.assertFalse(test.called)
1923
1924    def test_metaclass_dict_as_property(self):
1925        class Meta(type):
1926            @property
1927            def __dict__(self):
1928                self.executed = True
1929
1930        class Thing(metaclass=Meta):
1931            executed = False
1932
1933            def __init__(self):
1934                self.spam = 42
1935
1936        instance = Thing()
1937        self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
1938        self.assertFalse(Thing.executed)
1939
1940    def test_module(self):
1941        sentinel = object()
1942        self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
1943                         sentinel)
1944
1945    def test_metaclass_with_metaclass_with_dict_as_property(self):
1946        class MetaMeta(type):
1947            @property
1948            def __dict__(self):
1949                self.executed = True
1950                return dict(spam=42)
1951
1952        class Meta(type, metaclass=MetaMeta):
1953            executed = False
1954
1955        class Thing(metaclass=Meta):
1956            pass
1957
1958        with self.assertRaises(AttributeError):
1959            inspect.getattr_static(Thing, "spam")
1960        self.assertFalse(Thing.executed)
1961
1962class TestGetGeneratorState(unittest.TestCase):
1963
1964    def setUp(self):
1965        def number_generator():
1966            for number in range(5):
1967                yield number
1968        self.generator = number_generator()
1969
1970    def _generatorstate(self):
1971        return inspect.getgeneratorstate(self.generator)
1972
1973    def test_created(self):
1974        self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
1975
1976    def test_suspended(self):
1977        next(self.generator)
1978        self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
1979
1980    def test_closed_after_exhaustion(self):
1981        for i in self.generator:
1982            pass
1983        self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1984
1985    def test_closed_after_immediate_exception(self):
1986        with self.assertRaises(RuntimeError):
1987            self.generator.throw(RuntimeError)
1988        self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
1989
1990    def test_running(self):
1991        # As mentioned on issue #10220, checking for the RUNNING state only
1992        # makes sense inside the generator itself.
1993        # The following generator checks for this by using the closure's
1994        # reference to self and the generator state checking helper method
1995        def running_check_generator():
1996            for number in range(5):
1997                self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
1998                yield number
1999                self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
2000        self.generator = running_check_generator()
2001        # Running up to the first yield
2002        next(self.generator)
2003        # Running after the first yield
2004        next(self.generator)
2005
2006    def test_easy_debugging(self):
2007        # repr() and str() of a generator state should contain the state name
2008        names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
2009        for name in names:
2010            state = getattr(inspect, name)
2011            self.assertIn(name, repr(state))
2012            self.assertIn(name, str(state))
2013
2014    def test_getgeneratorlocals(self):
2015        def each(lst, a=None):
2016            b=(1, 2, 3)
2017            for v in lst:
2018                if v == 3:
2019                    c = 12
2020                yield v
2021
2022        numbers = each([1, 2, 3])
2023        self.assertEqual(inspect.getgeneratorlocals(numbers),
2024                         {'a': None, 'lst': [1, 2, 3]})
2025        next(numbers)
2026        self.assertEqual(inspect.getgeneratorlocals(numbers),
2027                         {'a': None, 'lst': [1, 2, 3], 'v': 1,
2028                          'b': (1, 2, 3)})
2029        next(numbers)
2030        self.assertEqual(inspect.getgeneratorlocals(numbers),
2031                         {'a': None, 'lst': [1, 2, 3], 'v': 2,
2032                          'b': (1, 2, 3)})
2033        next(numbers)
2034        self.assertEqual(inspect.getgeneratorlocals(numbers),
2035                         {'a': None, 'lst': [1, 2, 3], 'v': 3,
2036                          'b': (1, 2, 3), 'c': 12})
2037        try:
2038            next(numbers)
2039        except StopIteration:
2040            pass
2041        self.assertEqual(inspect.getgeneratorlocals(numbers), {})
2042
2043    def test_getgeneratorlocals_empty(self):
2044        def yield_one():
2045            yield 1
2046        one = yield_one()
2047        self.assertEqual(inspect.getgeneratorlocals(one), {})
2048        try:
2049            next(one)
2050        except StopIteration:
2051            pass
2052        self.assertEqual(inspect.getgeneratorlocals(one), {})
2053
2054    def test_getgeneratorlocals_error(self):
2055        self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
2056        self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
2057        self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
2058        self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
2059
2060
2061class TestGetCoroutineState(unittest.TestCase):
2062
2063    def setUp(self):
2064        @types.coroutine
2065        def number_coroutine():
2066            for number in range(5):
2067                yield number
2068        async def coroutine():
2069            await number_coroutine()
2070        self.coroutine = coroutine()
2071
2072    def tearDown(self):
2073        self.coroutine.close()
2074
2075    def _coroutinestate(self):
2076        return inspect.getcoroutinestate(self.coroutine)
2077
2078    def test_created(self):
2079        self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED)
2080
2081    def test_suspended(self):
2082        self.coroutine.send(None)
2083        self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED)
2084
2085    def test_closed_after_exhaustion(self):
2086        while True:
2087            try:
2088                self.coroutine.send(None)
2089            except StopIteration:
2090                break
2091
2092        self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
2093
2094    def test_closed_after_immediate_exception(self):
2095        with self.assertRaises(RuntimeError):
2096            self.coroutine.throw(RuntimeError)
2097        self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
2098
2099    def test_easy_debugging(self):
2100        # repr() and str() of a coroutine state should contain the state name
2101        names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
2102        for name in names:
2103            state = getattr(inspect, name)
2104            self.assertIn(name, repr(state))
2105            self.assertIn(name, str(state))
2106
2107    def test_getcoroutinelocals(self):
2108        @types.coroutine
2109        def gencoro():
2110            yield
2111
2112        gencoro = gencoro()
2113        async def func(a=None):
2114            b = 'spam'
2115            await gencoro
2116
2117        coro = func()
2118        self.assertEqual(inspect.getcoroutinelocals(coro),
2119                         {'a': None, 'gencoro': gencoro})
2120        coro.send(None)
2121        self.assertEqual(inspect.getcoroutinelocals(coro),
2122                         {'a': None, 'gencoro': gencoro, 'b': 'spam'})
2123
2124
2125class MySignature(inspect.Signature):
2126    # Top-level to make it picklable;
2127    # used in test_signature_object_pickle
2128    pass
2129
2130class MyParameter(inspect.Parameter):
2131    # Top-level to make it picklable;
2132    # used in test_signature_object_pickle
2133    pass
2134
2135
2136
2137class TestSignatureObject(unittest.TestCase):
2138    @staticmethod
2139    def signature(func, **kw):
2140        sig = inspect.signature(func, **kw)
2141        return (tuple((param.name,
2142                       (... if param.default is param.empty else param.default),
2143                       (... if param.annotation is param.empty
2144                                                        else param.annotation),
2145                       str(param.kind).lower())
2146                                    for param in sig.parameters.values()),
2147                (... if sig.return_annotation is sig.empty
2148                                            else sig.return_annotation))
2149
2150    def test_signature_object(self):
2151        S = inspect.Signature
2152        P = inspect.Parameter
2153
2154        self.assertEqual(str(S()), '()')
2155        self.assertEqual(repr(S().parameters), 'mappingproxy(OrderedDict())')
2156
2157        def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
2158            pass
2159        sig = inspect.signature(test)
2160        po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
2161        pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
2162        pk = sig.parameters['pk']
2163        pkd = sig.parameters['pkd']
2164        args = sig.parameters['args']
2165        ko = sig.parameters['ko']
2166        kwargs = sig.parameters['kwargs']
2167
2168        S((po, pk, args, ko, kwargs))
2169
2170        with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
2171            S((pk, po, args, ko, kwargs))
2172
2173        with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
2174            S((po, args, pk, ko, kwargs))
2175
2176        with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
2177            S((args, po, pk, ko, kwargs))
2178
2179        with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
2180            S((po, pk, args, kwargs, ko))
2181
2182        kwargs2 = kwargs.replace(name='args')
2183        with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
2184            S((po, pk, args, kwargs2, ko))
2185
2186        with self.assertRaisesRegex(ValueError, 'follows default argument'):
2187            S((pod, po))
2188
2189        with self.assertRaisesRegex(ValueError, 'follows default argument'):
2190            S((po, pkd, pk))
2191
2192        with self.assertRaisesRegex(ValueError, 'follows default argument'):
2193            S((pkd, pk))
2194
2195        self.assertTrue(repr(sig).startswith('<Signature'))
2196        self.assertTrue('(po, pk' in repr(sig))
2197
2198    def test_signature_object_pickle(self):
2199        def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
2200        foo_partial = functools.partial(foo, a=1)
2201
2202        sig = inspect.signature(foo_partial)
2203
2204        for ver in range(pickle.HIGHEST_PROTOCOL + 1):
2205            with self.subTest(pickle_ver=ver, subclass=False):
2206                sig_pickled = pickle.loads(pickle.dumps(sig, ver))
2207                self.assertEqual(sig, sig_pickled)
2208
2209        # Test that basic sub-classing works
2210        sig = inspect.signature(foo)
2211        myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
2212        myparams = collections.OrderedDict(sig.parameters, a=myparam)
2213        mysig = MySignature().replace(parameters=myparams.values(),
2214                                      return_annotation=sig.return_annotation)
2215        self.assertTrue(isinstance(mysig, MySignature))
2216        self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
2217
2218        for ver in range(pickle.HIGHEST_PROTOCOL + 1):
2219            with self.subTest(pickle_ver=ver, subclass=True):
2220                sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
2221                self.assertEqual(mysig, sig_pickled)
2222                self.assertTrue(isinstance(sig_pickled, MySignature))
2223                self.assertTrue(isinstance(sig_pickled.parameters['z'],
2224                                           MyParameter))
2225
2226    def test_signature_immutability(self):
2227        def test(a):
2228            pass
2229        sig = inspect.signature(test)
2230
2231        with self.assertRaises(AttributeError):
2232            sig.foo = 'bar'
2233
2234        with self.assertRaises(TypeError):
2235            sig.parameters['a'] = None
2236
2237    def test_signature_on_noarg(self):
2238        def test():
2239            pass
2240        self.assertEqual(self.signature(test), ((), ...))
2241
2242    def test_signature_on_wargs(self):
2243        def test(a, b:'foo') -> 123:
2244            pass
2245        self.assertEqual(self.signature(test),
2246                         ((('a', ..., ..., "positional_or_keyword"),
2247                           ('b', ..., 'foo', "positional_or_keyword")),
2248                          123))
2249
2250    def test_signature_on_wkwonly(self):
2251        def test(*, a:float, b:str) -> int:
2252            pass
2253        self.assertEqual(self.signature(test),
2254                         ((('a', ..., float, "keyword_only"),
2255                           ('b', ..., str, "keyword_only")),
2256                           int))
2257
2258    def test_signature_on_complex_args(self):
2259        def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
2260            pass
2261        self.assertEqual(self.signature(test),
2262                         ((('a', ..., ..., "positional_or_keyword"),
2263                           ('b', 10, 'foo', "positional_or_keyword"),
2264                           ('args', ..., 'bar', "var_positional"),
2265                           ('spam', ..., 'baz', "keyword_only"),
2266                           ('ham', 123, ..., "keyword_only"),
2267                           ('kwargs', ..., int, "var_keyword")),
2268                          ...))
2269
2270    def test_signature_without_self(self):
2271        def test_args_only(*args):  # NOQA
2272            pass
2273
2274        def test_args_kwargs_only(*args, **kwargs):  # NOQA
2275            pass
2276
2277        class A:
2278            @classmethod
2279            def test_classmethod(*args):  # NOQA
2280                pass
2281
2282            @staticmethod
2283            def test_staticmethod(*args):  # NOQA
2284                pass
2285
2286            f1 = functools.partialmethod((test_classmethod), 1)
2287            f2 = functools.partialmethod((test_args_only), 1)
2288            f3 = functools.partialmethod((test_staticmethod), 1)
2289            f4 = functools.partialmethod((test_args_kwargs_only),1)
2290
2291        self.assertEqual(self.signature(test_args_only),
2292                         ((('args', ..., ..., 'var_positional'),), ...))
2293        self.assertEqual(self.signature(test_args_kwargs_only),
2294                         ((('args', ..., ..., 'var_positional'),
2295                           ('kwargs', ..., ..., 'var_keyword')), ...))
2296        self.assertEqual(self.signature(A.f1),
2297                         ((('args', ..., ..., 'var_positional'),), ...))
2298        self.assertEqual(self.signature(A.f2),
2299                         ((('args', ..., ..., 'var_positional'),), ...))
2300        self.assertEqual(self.signature(A.f3),
2301                         ((('args', ..., ..., 'var_positional'),), ...))
2302        self.assertEqual(self.signature(A.f4),
2303                         ((('args', ..., ..., 'var_positional'),
2304                            ('kwargs', ..., ..., 'var_keyword')), ...))
2305    @cpython_only
2306    @unittest.skipIf(MISSING_C_DOCSTRINGS,
2307                     "Signature information for builtins requires docstrings")
2308    def test_signature_on_builtins(self):
2309        import _testcapi
2310
2311        def test_unbound_method(o):
2312            """Use this to test unbound methods (things that should have a self)"""
2313            signature = inspect.signature(o)
2314            self.assertTrue(isinstance(signature, inspect.Signature))
2315            self.assertEqual(list(signature.parameters.values())[0].name, 'self')
2316            return signature
2317
2318        def test_callable(o):
2319            """Use this to test bound methods or normal callables (things that don't expect self)"""
2320            signature = inspect.signature(o)
2321            self.assertTrue(isinstance(signature, inspect.Signature))
2322            if signature.parameters:
2323                self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
2324            return signature
2325
2326        signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
2327        def p(name): return signature.parameters[name].default
2328        self.assertEqual(p('s'), 'avocado')
2329        self.assertEqual(p('b'), b'bytes')
2330        self.assertEqual(p('d'), 3.14)
2331        self.assertEqual(p('i'), 35)
2332        self.assertEqual(p('n'), None)
2333        self.assertEqual(p('t'), True)
2334        self.assertEqual(p('f'), False)
2335        self.assertEqual(p('local'), 3)
2336        self.assertEqual(p('sys'), sys.maxsize)
2337        self.assertNotIn('exp', signature.parameters)
2338
2339        test_callable(object)
2340
2341        # normal method
2342        # (PyMethodDescr_Type, "method_descriptor")
2343        test_unbound_method(_pickle.Pickler.dump)
2344        d = _pickle.Pickler(io.StringIO())
2345        test_callable(d.dump)
2346
2347        # static method
2348        test_callable(bytes.maketrans)
2349        test_callable(b'abc'.maketrans)
2350
2351        # class method
2352        test_callable(dict.fromkeys)
2353        test_callable({}.fromkeys)
2354
2355        # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
2356        test_unbound_method(type.__call__)
2357        test_unbound_method(int.__add__)
2358        test_callable((3).__add__)
2359
2360        # _PyMethodWrapper_Type
2361        # support for 'method-wrapper'
2362        test_callable(min.__call__)
2363
2364        # This doesn't work now.
2365        # (We don't have a valid signature for "type" in 3.4)
2366        with self.assertRaisesRegex(ValueError, "no signature found"):
2367            class ThisWorksNow:
2368                __call__ = type
2369            test_callable(ThisWorksNow())
2370
2371        # Regression test for issue #20786
2372        test_unbound_method(dict.__delitem__)
2373        test_unbound_method(property.__delete__)
2374
2375        # Regression test for issue #20586
2376        test_callable(_testcapi.docstring_with_signature_but_no_doc)
2377
2378    @cpython_only
2379    @unittest.skipIf(MISSING_C_DOCSTRINGS,
2380                     "Signature information for builtins requires docstrings")
2381    def test_signature_on_decorated_builtins(self):
2382        import _testcapi
2383        func = _testcapi.docstring_with_signature_with_defaults
2384
2385        def decorator(func):
2386            @functools.wraps(func)
2387            def wrapper(*args, **kwargs) -> int:
2388                return func(*args, **kwargs)
2389            return wrapper
2390
2391        decorated_func = decorator(func)
2392
2393        self.assertEqual(inspect.signature(func),
2394                         inspect.signature(decorated_func))
2395
2396        def wrapper_like(*args, **kwargs) -> int: pass
2397        self.assertEqual(inspect.signature(decorated_func,
2398                                           follow_wrapped=False),
2399                         inspect.signature(wrapper_like))
2400
2401    @cpython_only
2402    def test_signature_on_builtins_no_signature(self):
2403        import _testcapi
2404        with self.assertRaisesRegex(ValueError,
2405                                    'no signature found for builtin'):
2406            inspect.signature(_testcapi.docstring_no_signature)
2407
2408        with self.assertRaisesRegex(ValueError,
2409                                    'no signature found for builtin'):
2410            inspect.signature(str)
2411
2412    def test_signature_on_non_function(self):
2413        with self.assertRaisesRegex(TypeError, 'is not a callable object'):
2414            inspect.signature(42)
2415
2416    def test_signature_from_functionlike_object(self):
2417        def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2418            pass
2419
2420        class funclike:
2421            # Has to be callable, and have correct
2422            # __code__, __annotations__, __defaults__, __name__,
2423            # and __kwdefaults__ attributes
2424
2425            def __init__(self, func):
2426                self.__name__ = func.__name__
2427                self.__code__ = func.__code__
2428                self.__annotations__ = func.__annotations__
2429                self.__defaults__ = func.__defaults__
2430                self.__kwdefaults__ = func.__kwdefaults__
2431                self.func = func
2432
2433            def __call__(self, *args, **kwargs):
2434                return self.func(*args, **kwargs)
2435
2436        sig_func = inspect.Signature.from_callable(func)
2437
2438        sig_funclike = inspect.Signature.from_callable(funclike(func))
2439        self.assertEqual(sig_funclike, sig_func)
2440
2441        sig_funclike = inspect.signature(funclike(func))
2442        self.assertEqual(sig_funclike, sig_func)
2443
2444        # If object is not a duck type of function, then
2445        # signature will try to get a signature for its '__call__'
2446        # method
2447        fl = funclike(func)
2448        del fl.__defaults__
2449        self.assertEqual(self.signature(fl),
2450                         ((('args', ..., ..., "var_positional"),
2451                           ('kwargs', ..., ..., "var_keyword")),
2452                           ...))
2453
2454        # Test with cython-like builtins:
2455        _orig_isdesc = inspect.ismethoddescriptor
2456        def _isdesc(obj):
2457            if hasattr(obj, '_builtinmock'):
2458                return True
2459            return _orig_isdesc(obj)
2460
2461        with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
2462            builtin_func = funclike(func)
2463            # Make sure that our mock setup is working
2464            self.assertFalse(inspect.ismethoddescriptor(builtin_func))
2465            builtin_func._builtinmock = True
2466            self.assertTrue(inspect.ismethoddescriptor(builtin_func))
2467            self.assertEqual(inspect.signature(builtin_func), sig_func)
2468
2469    def test_signature_functionlike_class(self):
2470        # We only want to duck type function-like objects,
2471        # not classes.
2472
2473        def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2474            pass
2475
2476        class funclike:
2477            def __init__(self, marker):
2478                pass
2479
2480            __name__ = func.__name__
2481            __code__ = func.__code__
2482            __annotations__ = func.__annotations__
2483            __defaults__ = func.__defaults__
2484            __kwdefaults__ = func.__kwdefaults__
2485
2486        self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2487
2488    def test_signature_on_method(self):
2489        class Test:
2490            def __init__(*args):
2491                pass
2492            def m1(self, arg1, arg2=1) -> int:
2493                pass
2494            def m2(*args):
2495                pass
2496            def __call__(*, a):
2497                pass
2498
2499        self.assertEqual(self.signature(Test().m1),
2500                         ((('arg1', ..., ..., "positional_or_keyword"),
2501                           ('arg2', 1, ..., "positional_or_keyword")),
2502                          int))
2503
2504        self.assertEqual(self.signature(Test().m2),
2505                         ((('args', ..., ..., "var_positional"),),
2506                          ...))
2507
2508        self.assertEqual(self.signature(Test),
2509                         ((('args', ..., ..., "var_positional"),),
2510                          ...))
2511
2512        with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2513            self.signature(Test())
2514
2515    def test_signature_wrapped_bound_method(self):
2516        # Issue 24298
2517        class Test:
2518            def m1(self, arg1, arg2=1) -> int:
2519                pass
2520        @functools.wraps(Test().m1)
2521        def m1d(*args, **kwargs):
2522            pass
2523        self.assertEqual(self.signature(m1d),
2524                         ((('arg1', ..., ..., "positional_or_keyword"),
2525                           ('arg2', 1, ..., "positional_or_keyword")),
2526                          int))
2527
2528    def test_signature_on_classmethod(self):
2529        class Test:
2530            @classmethod
2531            def foo(cls, arg1, *, arg2=1):
2532                pass
2533
2534        meth = Test().foo
2535        self.assertEqual(self.signature(meth),
2536                         ((('arg1', ..., ..., "positional_or_keyword"),
2537                           ('arg2', 1, ..., "keyword_only")),
2538                          ...))
2539
2540        meth = Test.foo
2541        self.assertEqual(self.signature(meth),
2542                         ((('arg1', ..., ..., "positional_or_keyword"),
2543                           ('arg2', 1, ..., "keyword_only")),
2544                          ...))
2545
2546    def test_signature_on_staticmethod(self):
2547        class Test:
2548            @staticmethod
2549            def foo(cls, *, arg):
2550                pass
2551
2552        meth = Test().foo
2553        self.assertEqual(self.signature(meth),
2554                         ((('cls', ..., ..., "positional_or_keyword"),
2555                           ('arg', ..., ..., "keyword_only")),
2556                          ...))
2557
2558        meth = Test.foo
2559        self.assertEqual(self.signature(meth),
2560                         ((('cls', ..., ..., "positional_or_keyword"),
2561                           ('arg', ..., ..., "keyword_only")),
2562                          ...))
2563
2564    def test_signature_on_partial(self):
2565        from functools import partial
2566
2567        Parameter = inspect.Parameter
2568
2569        def test():
2570            pass
2571
2572        self.assertEqual(self.signature(partial(test)), ((), ...))
2573
2574        with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2575            inspect.signature(partial(test, 1))
2576
2577        with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2578            inspect.signature(partial(test, a=1))
2579
2580        def test(a, b, *, c, d):
2581            pass
2582
2583        self.assertEqual(self.signature(partial(test)),
2584                         ((('a', ..., ..., "positional_or_keyword"),
2585                           ('b', ..., ..., "positional_or_keyword"),
2586                           ('c', ..., ..., "keyword_only"),
2587                           ('d', ..., ..., "keyword_only")),
2588                          ...))
2589
2590        self.assertEqual(self.signature(partial(test, 1)),
2591                         ((('b', ..., ..., "positional_or_keyword"),
2592                           ('c', ..., ..., "keyword_only"),
2593                           ('d', ..., ..., "keyword_only")),
2594                          ...))
2595
2596        self.assertEqual(self.signature(partial(test, 1, c=2)),
2597                         ((('b', ..., ..., "positional_or_keyword"),
2598                           ('c', 2, ..., "keyword_only"),
2599                           ('d', ..., ..., "keyword_only")),
2600                          ...))
2601
2602        self.assertEqual(self.signature(partial(test, b=1, c=2)),
2603                         ((('a', ..., ..., "positional_or_keyword"),
2604                           ('b', 1, ..., "keyword_only"),
2605                           ('c', 2, ..., "keyword_only"),
2606                           ('d', ..., ..., "keyword_only")),
2607                          ...))
2608
2609        self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
2610                         ((('b', 1, ..., "keyword_only"),
2611                           ('c', 2, ..., "keyword_only"),
2612                           ('d', ..., ..., "keyword_only")),
2613                          ...))
2614
2615        self.assertEqual(self.signature(partial(test, a=1)),
2616                         ((('a', 1, ..., "keyword_only"),
2617                           ('b', ..., ..., "keyword_only"),
2618                           ('c', ..., ..., "keyword_only"),
2619                           ('d', ..., ..., "keyword_only")),
2620                          ...))
2621
2622        def test(a, *args, b, **kwargs):
2623            pass
2624
2625        self.assertEqual(self.signature(partial(test, 1)),
2626                         ((('args', ..., ..., "var_positional"),
2627                           ('b', ..., ..., "keyword_only"),
2628                           ('kwargs', ..., ..., "var_keyword")),
2629                          ...))
2630
2631        self.assertEqual(self.signature(partial(test, a=1)),
2632                         ((('a', 1, ..., "keyword_only"),
2633                           ('b', ..., ..., "keyword_only"),
2634                           ('kwargs', ..., ..., "var_keyword")),
2635                          ...))
2636
2637        self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2638                         ((('args', ..., ..., "var_positional"),
2639                           ('b', ..., ..., "keyword_only"),
2640                           ('kwargs', ..., ..., "var_keyword")),
2641                          ...))
2642
2643        self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2644                         ((('args', ..., ..., "var_positional"),
2645                           ('b', ..., ..., "keyword_only"),
2646                           ('kwargs', ..., ..., "var_keyword")),
2647                          ...))
2648
2649        self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2650                         ((('args', ..., ..., "var_positional"),
2651                           ('b', 0, ..., "keyword_only"),
2652                           ('kwargs', ..., ..., "var_keyword")),
2653                          ...))
2654
2655        self.assertEqual(self.signature(partial(test, b=0)),
2656                         ((('a', ..., ..., "positional_or_keyword"),
2657                           ('args', ..., ..., "var_positional"),
2658                           ('b', 0, ..., "keyword_only"),
2659                           ('kwargs', ..., ..., "var_keyword")),
2660                          ...))
2661
2662        self.assertEqual(self.signature(partial(test, b=0, test=1)),
2663                         ((('a', ..., ..., "positional_or_keyword"),
2664                           ('args', ..., ..., "var_positional"),
2665                           ('b', 0, ..., "keyword_only"),
2666                           ('kwargs', ..., ..., "var_keyword")),
2667                          ...))
2668
2669        def test(a, b, c:int) -> 42:
2670            pass
2671
2672        sig = test.__signature__ = inspect.signature(test)
2673
2674        self.assertEqual(self.signature(partial(partial(test, 1))),
2675                         ((('b', ..., ..., "positional_or_keyword"),
2676                           ('c', ..., int, "positional_or_keyword")),
2677                          42))
2678
2679        self.assertEqual(self.signature(partial(partial(test, 1), 2)),
2680                         ((('c', ..., int, "positional_or_keyword"),),
2681                          42))
2682
2683        psig = inspect.signature(partial(partial(test, 1), 2))
2684
2685        def foo(a):
2686            return a
2687        _foo = partial(partial(foo, a=10), a=20)
2688        self.assertEqual(self.signature(_foo),
2689                         ((('a', 20, ..., "keyword_only"),),
2690                          ...))
2691        # check that we don't have any side-effects in signature(),
2692        # and the partial object is still functioning
2693        self.assertEqual(_foo(), 20)
2694
2695        def foo(a, b, c):
2696            return a, b, c
2697        _foo = partial(partial(foo, 1, b=20), b=30)
2698
2699        self.assertEqual(self.signature(_foo),
2700                         ((('b', 30, ..., "keyword_only"),
2701                           ('c', ..., ..., "keyword_only")),
2702                          ...))
2703        self.assertEqual(_foo(c=10), (1, 30, 10))
2704
2705        def foo(a, b, c, *, d):
2706            return a, b, c, d
2707        _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2708        self.assertEqual(self.signature(_foo),
2709                         ((('a', ..., ..., "positional_or_keyword"),
2710                           ('b', 10, ..., "keyword_only"),
2711                           ('c', 20, ..., "keyword_only"),
2712                           ('d', 30, ..., "keyword_only"),
2713                           ),
2714                          ...))
2715        ba = inspect.signature(_foo).bind(a=200, b=11)
2716        self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2717
2718        def foo(a=1, b=2, c=3):
2719            return a, b, c
2720        _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2721
2722        ba = inspect.signature(_foo).bind(a=11)
2723        self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
2724
2725        ba = inspect.signature(_foo).bind(11, 12)
2726        self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
2727
2728        ba = inspect.signature(_foo).bind(11, b=12)
2729        self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
2730
2731        ba = inspect.signature(_foo).bind(b=12)
2732        self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2733
2734        _foo = partial(_foo, b=10, c=20)
2735        ba = inspect.signature(_foo).bind(12)
2736        self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2737
2738
2739        def foo(a, b, c, d, **kwargs):
2740            pass
2741        sig = inspect.signature(foo)
2742        params = sig.parameters.copy()
2743        params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2744        params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2745        foo.__signature__ = inspect.Signature(params.values())
2746        sig = inspect.signature(foo)
2747        self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2748
2749        self.assertEqual(self.signature(partial(foo, 1)),
2750                         ((('b', ..., ..., 'positional_only'),
2751                           ('c', ..., ..., 'positional_or_keyword'),
2752                           ('d', ..., ..., 'positional_or_keyword'),
2753                           ('kwargs', ..., ..., 'var_keyword')),
2754                         ...))
2755
2756        self.assertEqual(self.signature(partial(foo, 1, 2)),
2757                         ((('c', ..., ..., 'positional_or_keyword'),
2758                           ('d', ..., ..., 'positional_or_keyword'),
2759                           ('kwargs', ..., ..., 'var_keyword')),
2760                         ...))
2761
2762        self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2763                         ((('d', ..., ..., 'positional_or_keyword'),
2764                           ('kwargs', ..., ..., 'var_keyword')),
2765                         ...))
2766
2767        self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2768                         ((('c', 3, ..., 'keyword_only'),
2769                           ('d', ..., ..., 'keyword_only'),
2770                           ('kwargs', ..., ..., 'var_keyword')),
2771                         ...))
2772
2773        self.assertEqual(self.signature(partial(foo, 1, c=3)),
2774                         ((('b', ..., ..., 'positional_only'),
2775                           ('c', 3, ..., 'keyword_only'),
2776                           ('d', ..., ..., 'keyword_only'),
2777                           ('kwargs', ..., ..., 'var_keyword')),
2778                         ...))
2779
2780    def test_signature_on_partialmethod(self):
2781        from functools import partialmethod
2782
2783        class Spam:
2784            def test():
2785                pass
2786            ham = partialmethod(test)
2787
2788        with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2789            inspect.signature(Spam.ham)
2790
2791        class Spam:
2792            def test(it, a, *, c) -> 'spam':
2793                pass
2794            ham = partialmethod(test, c=1)
2795
2796        self.assertEqual(self.signature(Spam.ham),
2797                         ((('it', ..., ..., 'positional_or_keyword'),
2798                           ('a', ..., ..., 'positional_or_keyword'),
2799                           ('c', 1, ..., 'keyword_only')),
2800                          'spam'))
2801
2802        self.assertEqual(self.signature(Spam().ham),
2803                         ((('a', ..., ..., 'positional_or_keyword'),
2804                           ('c', 1, ..., 'keyword_only')),
2805                          'spam'))
2806
2807        class Spam:
2808            def test(self: 'anno', x):
2809                pass
2810
2811            g = partialmethod(test, 1)
2812
2813        self.assertEqual(self.signature(Spam.g),
2814                         ((('self', ..., 'anno', 'positional_or_keyword'),),
2815                          ...))
2816
2817    def test_signature_on_fake_partialmethod(self):
2818        def foo(a): pass
2819        foo._partialmethod = 'spam'
2820        self.assertEqual(str(inspect.signature(foo)), '(a)')
2821
2822    def test_signature_on_decorated(self):
2823        import functools
2824
2825        def decorator(func):
2826            @functools.wraps(func)
2827            def wrapper(*args, **kwargs) -> int:
2828                return func(*args, **kwargs)
2829            return wrapper
2830
2831        class Foo:
2832            @decorator
2833            def bar(self, a, b):
2834                pass
2835
2836        self.assertEqual(self.signature(Foo.bar),
2837                         ((('self', ..., ..., "positional_or_keyword"),
2838                           ('a', ..., ..., "positional_or_keyword"),
2839                           ('b', ..., ..., "positional_or_keyword")),
2840                          ...))
2841
2842        self.assertEqual(self.signature(Foo().bar),
2843                         ((('a', ..., ..., "positional_or_keyword"),
2844                           ('b', ..., ..., "positional_or_keyword")),
2845                          ...))
2846
2847        self.assertEqual(self.signature(Foo.bar, follow_wrapped=False),
2848                         ((('args', ..., ..., "var_positional"),
2849                           ('kwargs', ..., ..., "var_keyword")),
2850                          ...)) # functools.wraps will copy __annotations__
2851                                # from "func" to "wrapper", hence no
2852                                # return_annotation
2853
2854        # Test that we handle method wrappers correctly
2855        def decorator(func):
2856            @functools.wraps(func)
2857            def wrapper(*args, **kwargs) -> int:
2858                return func(42, *args, **kwargs)
2859            sig = inspect.signature(func)
2860            new_params = tuple(sig.parameters.values())[1:]
2861            wrapper.__signature__ = sig.replace(parameters=new_params)
2862            return wrapper
2863
2864        class Foo:
2865            @decorator
2866            def __call__(self, a, b):
2867                pass
2868
2869        self.assertEqual(self.signature(Foo.__call__),
2870                         ((('a', ..., ..., "positional_or_keyword"),
2871                           ('b', ..., ..., "positional_or_keyword")),
2872                          ...))
2873
2874        self.assertEqual(self.signature(Foo().__call__),
2875                         ((('b', ..., ..., "positional_or_keyword"),),
2876                          ...))
2877
2878        # Test we handle __signature__ partway down the wrapper stack
2879        def wrapped_foo_call():
2880            pass
2881        wrapped_foo_call.__wrapped__ = Foo.__call__
2882
2883        self.assertEqual(self.signature(wrapped_foo_call),
2884                         ((('a', ..., ..., "positional_or_keyword"),
2885                           ('b', ..., ..., "positional_or_keyword")),
2886                          ...))
2887
2888
2889    def test_signature_on_class(self):
2890        class C:
2891            def __init__(self, a):
2892                pass
2893
2894        self.assertEqual(self.signature(C),
2895                         ((('a', ..., ..., "positional_or_keyword"),),
2896                          ...))
2897
2898        class CM(type):
2899            def __call__(cls, a):
2900                pass
2901        class C(metaclass=CM):
2902            def __init__(self, b):
2903                pass
2904
2905        self.assertEqual(self.signature(C),
2906                         ((('a', ..., ..., "positional_or_keyword"),),
2907                          ...))
2908
2909        class CM(type):
2910            def __new__(mcls, name, bases, dct, *, foo=1):
2911                return super().__new__(mcls, name, bases, dct)
2912        class C(metaclass=CM):
2913            def __init__(self, b):
2914                pass
2915
2916        self.assertEqual(self.signature(C),
2917                         ((('b', ..., ..., "positional_or_keyword"),),
2918                          ...))
2919
2920        self.assertEqual(self.signature(CM),
2921                         ((('name', ..., ..., "positional_or_keyword"),
2922                           ('bases', ..., ..., "positional_or_keyword"),
2923                           ('dct', ..., ..., "positional_or_keyword"),
2924                           ('foo', 1, ..., "keyword_only")),
2925                          ...))
2926
2927        class CMM(type):
2928            def __new__(mcls, name, bases, dct, *, foo=1):
2929                return super().__new__(mcls, name, bases, dct)
2930            def __call__(cls, nm, bs, dt):
2931                return type(nm, bs, dt)
2932        class CM(type, metaclass=CMM):
2933            def __new__(mcls, name, bases, dct, *, bar=2):
2934                return super().__new__(mcls, name, bases, dct)
2935        class C(metaclass=CM):
2936            def __init__(self, b):
2937                pass
2938
2939        self.assertEqual(self.signature(CMM),
2940                         ((('name', ..., ..., "positional_or_keyword"),
2941                           ('bases', ..., ..., "positional_or_keyword"),
2942                           ('dct', ..., ..., "positional_or_keyword"),
2943                           ('foo', 1, ..., "keyword_only")),
2944                          ...))
2945
2946        self.assertEqual(self.signature(CM),
2947                         ((('nm', ..., ..., "positional_or_keyword"),
2948                           ('bs', ..., ..., "positional_or_keyword"),
2949                           ('dt', ..., ..., "positional_or_keyword")),
2950                          ...))
2951
2952        self.assertEqual(self.signature(C),
2953                         ((('b', ..., ..., "positional_or_keyword"),),
2954                          ...))
2955
2956        class CM(type):
2957            def __init__(cls, name, bases, dct, *, bar=2):
2958                return super().__init__(name, bases, dct)
2959        class C(metaclass=CM):
2960            def __init__(self, b):
2961                pass
2962
2963        self.assertEqual(self.signature(CM),
2964                         ((('name', ..., ..., "positional_or_keyword"),
2965                           ('bases', ..., ..., "positional_or_keyword"),
2966                           ('dct', ..., ..., "positional_or_keyword"),
2967                           ('bar', 2, ..., "keyword_only")),
2968                          ...))
2969
2970    def test_signature_on_subclass(self):
2971        class A:
2972            def __new__(cls, a=1, *args, **kwargs):
2973                return object.__new__(cls)
2974        class B(A):
2975            def __init__(self, b):
2976                pass
2977        class C(A):
2978            def __new__(cls, a=1, b=2, *args, **kwargs):
2979                return object.__new__(cls)
2980        class D(A):
2981            pass
2982
2983        self.assertEqual(self.signature(B),
2984                         ((('b', ..., ..., "positional_or_keyword"),),
2985                          ...))
2986        self.assertEqual(self.signature(C),
2987                         ((('a', 1, ..., 'positional_or_keyword'),
2988                           ('b', 2, ..., 'positional_or_keyword'),
2989                           ('args', ..., ..., 'var_positional'),
2990                           ('kwargs', ..., ..., 'var_keyword')),
2991                          ...))
2992        self.assertEqual(self.signature(D),
2993                         ((('a', 1, ..., 'positional_or_keyword'),
2994                           ('args', ..., ..., 'var_positional'),
2995                           ('kwargs', ..., ..., 'var_keyword')),
2996                          ...))
2997
2998    def test_signature_on_generic_subclass(self):
2999        from typing import Generic, TypeVar
3000
3001        T = TypeVar('T')
3002
3003        class A(Generic[T]):
3004            def __init__(self, *, a: int) -> None:
3005                pass
3006
3007        self.assertEqual(self.signature(A),
3008                         ((('a', ..., int, 'keyword_only'),),
3009                          None))
3010
3011    @unittest.skipIf(MISSING_C_DOCSTRINGS,
3012                     "Signature information for builtins requires docstrings")
3013    def test_signature_on_class_without_init(self):
3014        # Test classes without user-defined __init__ or __new__
3015        class C: pass
3016        self.assertEqual(str(inspect.signature(C)), '()')
3017        class D(C): pass
3018        self.assertEqual(str(inspect.signature(D)), '()')
3019
3020        # Test meta-classes without user-defined __init__ or __new__
3021        class C(type): pass
3022        class D(C): pass
3023        with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
3024            self.assertEqual(inspect.signature(C), None)
3025        with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
3026            self.assertEqual(inspect.signature(D), None)
3027
3028    @unittest.skipIf(MISSING_C_DOCSTRINGS,
3029                     "Signature information for builtins requires docstrings")
3030    def test_signature_on_builtin_class(self):
3031        expected = ('(file, protocol=None, fix_imports=True, '
3032                    'buffer_callback=None)')
3033        self.assertEqual(str(inspect.signature(_pickle.Pickler)), expected)
3034
3035        class P(_pickle.Pickler): pass
3036        class EmptyTrait: pass
3037        class P2(EmptyTrait, P): pass
3038        self.assertEqual(str(inspect.signature(P)), expected)
3039        self.assertEqual(str(inspect.signature(P2)), expected)
3040
3041        class P3(P2):
3042            def __init__(self, spam):
3043                pass
3044        self.assertEqual(str(inspect.signature(P3)), '(spam)')
3045
3046        class MetaP(type):
3047            def __call__(cls, foo, bar):
3048                pass
3049        class P4(P2, metaclass=MetaP):
3050            pass
3051        self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
3052
3053    def test_signature_on_callable_objects(self):
3054        class Foo:
3055            def __call__(self, a):
3056                pass
3057
3058        self.assertEqual(self.signature(Foo()),
3059                         ((('a', ..., ..., "positional_or_keyword"),),
3060                          ...))
3061
3062        class Spam:
3063            pass
3064        with self.assertRaisesRegex(TypeError, "is not a callable object"):
3065            inspect.signature(Spam())
3066
3067        class Bar(Spam, Foo):
3068            pass
3069
3070        self.assertEqual(self.signature(Bar()),
3071                         ((('a', ..., ..., "positional_or_keyword"),),
3072                          ...))
3073
3074        class Wrapped:
3075            pass
3076        Wrapped.__wrapped__ = lambda a: None
3077        self.assertEqual(self.signature(Wrapped),
3078                         ((('a', ..., ..., "positional_or_keyword"),),
3079                          ...))
3080        # wrapper loop:
3081        Wrapped.__wrapped__ = Wrapped
3082        with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3083            self.signature(Wrapped)
3084
3085    def test_signature_on_lambdas(self):
3086        self.assertEqual(self.signature((lambda a=10: a)),
3087                         ((('a', 10, ..., "positional_or_keyword"),),
3088                          ...))
3089
3090    def test_signature_equality(self):
3091        def foo(a, *, b:int) -> float: pass
3092        self.assertFalse(inspect.signature(foo) == 42)
3093        self.assertTrue(inspect.signature(foo) != 42)
3094        self.assertTrue(inspect.signature(foo) == ALWAYS_EQ)
3095        self.assertFalse(inspect.signature(foo) != ALWAYS_EQ)
3096
3097        def bar(a, *, b:int) -> float: pass
3098        self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3099        self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
3100        self.assertEqual(
3101            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3102
3103        def bar(a, *, b:int) -> int: pass
3104        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3105        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
3106        self.assertNotEqual(
3107            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3108
3109        def bar(a, *, b:int): pass
3110        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3111        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
3112        self.assertNotEqual(
3113            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3114
3115        def bar(a, *, b:int=42) -> float: pass
3116        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3117        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
3118        self.assertNotEqual(
3119            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3120
3121        def bar(a, *, c) -> float: pass
3122        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3123        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
3124        self.assertNotEqual(
3125            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3126
3127        def bar(a, b:int) -> float: pass
3128        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3129        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
3130        self.assertNotEqual(
3131            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3132        def spam(b:int, a) -> float: pass
3133        self.assertFalse(inspect.signature(spam) == inspect.signature(bar))
3134        self.assertTrue(inspect.signature(spam) != inspect.signature(bar))
3135        self.assertNotEqual(
3136            hash(inspect.signature(spam)), hash(inspect.signature(bar)))
3137
3138        def foo(*, a, b, c): pass
3139        def bar(*, c, b, a): pass
3140        self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3141        self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
3142        self.assertEqual(
3143            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3144
3145        def foo(*, a=1, b, c): pass
3146        def bar(*, c, b, a=1): pass
3147        self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3148        self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
3149        self.assertEqual(
3150            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3151
3152        def foo(pos, *, a=1, b, c): pass
3153        def bar(pos, *, c, b, a=1): pass
3154        self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3155        self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
3156        self.assertEqual(
3157            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3158
3159        def foo(pos, *, a, b, c): pass
3160        def bar(pos, *, c, b, a=1): pass
3161        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3162        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
3163        self.assertNotEqual(
3164            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3165
3166        def foo(pos, *args, a=42, b, c, **kwargs:int): pass
3167        def bar(pos, *args, c, b, a=42, **kwargs:int): pass
3168        self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3169        self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
3170        self.assertEqual(
3171            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3172
3173    def test_signature_hashable(self):
3174        S = inspect.Signature
3175        P = inspect.Parameter
3176
3177        def foo(a): pass
3178        foo_sig = inspect.signature(foo)
3179
3180        manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
3181
3182        self.assertEqual(hash(foo_sig), hash(manual_sig))
3183        self.assertNotEqual(hash(foo_sig),
3184                            hash(manual_sig.replace(return_annotation='spam')))
3185
3186        def bar(a) -> 1: pass
3187        self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
3188
3189        def foo(a={}): pass
3190        with self.assertRaisesRegex(TypeError, 'unhashable type'):
3191            hash(inspect.signature(foo))
3192
3193        def foo(a) -> {}: pass
3194        with self.assertRaisesRegex(TypeError, 'unhashable type'):
3195            hash(inspect.signature(foo))
3196
3197    def test_signature_str(self):
3198        def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
3199            pass
3200        self.assertEqual(str(inspect.signature(foo)),
3201                         '(a: int = 1, *, b, c=None, **kwargs) -> 42')
3202
3203        def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
3204            pass
3205        self.assertEqual(str(inspect.signature(foo)),
3206                         '(a: int = 1, *args, b, c=None, **kwargs) -> 42')
3207
3208        def foo():
3209            pass
3210        self.assertEqual(str(inspect.signature(foo)), '()')
3211
3212        def foo(a: list[str]) -> tuple[str, float]:
3213            pass
3214        self.assertEqual(str(inspect.signature(foo)),
3215                         '(a: list[str]) -> tuple[str, float]')
3216
3217        from typing import Tuple
3218        def foo(a: list[str]) -> Tuple[str, float]:
3219            pass
3220        self.assertEqual(str(inspect.signature(foo)),
3221                         '(a: list[str]) -> Tuple[str, float]')
3222
3223    def test_signature_str_positional_only(self):
3224        P = inspect.Parameter
3225        S = inspect.Signature
3226
3227        def test(a_po, *, b, **kwargs):
3228            return a_po, kwargs
3229
3230        sig = inspect.signature(test)
3231        new_params = list(sig.parameters.values())
3232        new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
3233        test.__signature__ = sig.replace(parameters=new_params)
3234
3235        self.assertEqual(str(inspect.signature(test)),
3236                         '(a_po, /, *, b, **kwargs)')
3237
3238        self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
3239                         '(foo, /)')
3240
3241        self.assertEqual(str(S(parameters=[
3242                                P('foo', P.POSITIONAL_ONLY),
3243                                P('bar', P.VAR_KEYWORD)])),
3244                         '(foo, /, **bar)')
3245
3246        self.assertEqual(str(S(parameters=[
3247                                P('foo', P.POSITIONAL_ONLY),
3248                                P('bar', P.VAR_POSITIONAL)])),
3249                         '(foo, /, *bar)')
3250
3251    def test_signature_replace_anno(self):
3252        def test() -> 42:
3253            pass
3254
3255        sig = inspect.signature(test)
3256        sig = sig.replace(return_annotation=None)
3257        self.assertIs(sig.return_annotation, None)
3258        sig = sig.replace(return_annotation=sig.empty)
3259        self.assertIs(sig.return_annotation, sig.empty)
3260        sig = sig.replace(return_annotation=42)
3261        self.assertEqual(sig.return_annotation, 42)
3262        self.assertEqual(sig, inspect.signature(test))
3263
3264    def test_signature_on_mangled_parameters(self):
3265        class Spam:
3266            def foo(self, __p1:1=2, *, __p2:2=3):
3267                pass
3268        class Ham(Spam):
3269            pass
3270
3271        self.assertEqual(self.signature(Spam.foo),
3272                         ((('self', ..., ..., "positional_or_keyword"),
3273                           ('_Spam__p1', 2, 1, "positional_or_keyword"),
3274                           ('_Spam__p2', 3, 2, "keyword_only")),
3275                          ...))
3276
3277        self.assertEqual(self.signature(Spam.foo),
3278                         self.signature(Ham.foo))
3279
3280    def test_signature_from_callable_python_obj(self):
3281        class MySignature(inspect.Signature): pass
3282        def foo(a, *, b:1): pass
3283        foo_sig = MySignature.from_callable(foo)
3284        self.assertIsInstance(foo_sig, MySignature)
3285
3286    def test_signature_from_callable_class(self):
3287        # A regression test for a class inheriting its signature from `object`.
3288        class MySignature(inspect.Signature): pass
3289        class foo: pass
3290        foo_sig = MySignature.from_callable(foo)
3291        self.assertIsInstance(foo_sig, MySignature)
3292
3293    @unittest.skipIf(MISSING_C_DOCSTRINGS,
3294                     "Signature information for builtins requires docstrings")
3295    def test_signature_from_callable_builtin_obj(self):
3296        class MySignature(inspect.Signature): pass
3297        sig = MySignature.from_callable(_pickle.Pickler)
3298        self.assertIsInstance(sig, MySignature)
3299
3300    def test_signature_definition_order_preserved_on_kwonly(self):
3301        for fn in signatures_with_lexicographic_keyword_only_parameters():
3302            signature = inspect.signature(fn)
3303            l = list(signature.parameters)
3304            sorted_l = sorted(l)
3305            self.assertTrue(l)
3306            self.assertEqual(l, sorted_l)
3307        signature = inspect.signature(unsorted_keyword_only_parameters_fn)
3308        l = list(signature.parameters)
3309        self.assertEqual(l, unsorted_keyword_only_parameters)
3310
3311    def test_signater_parameters_is_ordered(self):
3312        p1 = inspect.signature(lambda x, y: None).parameters
3313        p2 = inspect.signature(lambda y, x: None).parameters
3314        self.assertNotEqual(p1, p2)
3315
3316
3317class TestParameterObject(unittest.TestCase):
3318    def test_signature_parameter_kinds(self):
3319        P = inspect.Parameter
3320        self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
3321                        P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
3322
3323        self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
3324        self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
3325
3326    def test_signature_parameter_object(self):
3327        p = inspect.Parameter('foo', default=10,
3328                              kind=inspect.Parameter.POSITIONAL_ONLY)
3329        self.assertEqual(p.name, 'foo')
3330        self.assertEqual(p.default, 10)
3331        self.assertIs(p.annotation, p.empty)
3332        self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
3333
3334        with self.assertRaisesRegex(ValueError, "value '123' is "
3335                                    "not a valid Parameter.kind"):
3336            inspect.Parameter('foo', default=10, kind='123')
3337
3338        with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
3339            inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
3340
3341        with self.assertRaisesRegex(TypeError, 'name must be a str'):
3342            inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
3343
3344        with self.assertRaisesRegex(ValueError,
3345                                    'is not a valid parameter name'):
3346            inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
3347
3348        with self.assertRaisesRegex(ValueError,
3349                                    'is not a valid parameter name'):
3350            inspect.Parameter('.a', kind=inspect.Parameter.VAR_KEYWORD)
3351
3352        with self.assertRaisesRegex(ValueError, 'cannot have default values'):
3353            inspect.Parameter('a', default=42,
3354                              kind=inspect.Parameter.VAR_KEYWORD)
3355
3356        with self.assertRaisesRegex(ValueError, 'cannot have default values'):
3357            inspect.Parameter('a', default=42,
3358                              kind=inspect.Parameter.VAR_POSITIONAL)
3359
3360        p = inspect.Parameter('a', default=42,
3361                              kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
3362        with self.assertRaisesRegex(ValueError, 'cannot have default values'):
3363            p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
3364
3365        self.assertTrue(repr(p).startswith('<Parameter'))
3366        self.assertTrue('"a=42"' in repr(p))
3367
3368    def test_signature_parameter_hashable(self):
3369        P = inspect.Parameter
3370        foo = P('foo', kind=P.POSITIONAL_ONLY)
3371        self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
3372        self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
3373                                              default=42)))
3374        self.assertNotEqual(hash(foo),
3375                            hash(foo.replace(kind=P.VAR_POSITIONAL)))
3376
3377    def test_signature_parameter_equality(self):
3378        P = inspect.Parameter
3379        p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
3380
3381        self.assertTrue(p == p)
3382        self.assertFalse(p != p)
3383        self.assertFalse(p == 42)
3384        self.assertTrue(p != 42)
3385        self.assertTrue(p == ALWAYS_EQ)
3386        self.assertFalse(p != ALWAYS_EQ)
3387
3388        self.assertTrue(p == P('foo', default=42,
3389                               kind=inspect.Parameter.KEYWORD_ONLY))
3390        self.assertFalse(p != P('foo', default=42,
3391                                kind=inspect.Parameter.KEYWORD_ONLY))
3392
3393    def test_signature_parameter_replace(self):
3394        p = inspect.Parameter('foo', default=42,
3395                              kind=inspect.Parameter.KEYWORD_ONLY)
3396
3397        self.assertIsNot(p, p.replace())
3398        self.assertEqual(p, p.replace())
3399
3400        p2 = p.replace(annotation=1)
3401        self.assertEqual(p2.annotation, 1)
3402        p2 = p2.replace(annotation=p2.empty)
3403        self.assertEqual(p, p2)
3404
3405        p2 = p2.replace(name='bar')
3406        self.assertEqual(p2.name, 'bar')
3407        self.assertNotEqual(p2, p)
3408
3409        with self.assertRaisesRegex(ValueError,
3410                                    'name is a required attribute'):
3411            p2 = p2.replace(name=p2.empty)
3412
3413        p2 = p2.replace(name='foo', default=None)
3414        self.assertIs(p2.default, None)
3415        self.assertNotEqual(p2, p)
3416
3417        p2 = p2.replace(name='foo', default=p2.empty)
3418        self.assertIs(p2.default, p2.empty)
3419
3420
3421        p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
3422        self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
3423        self.assertNotEqual(p2, p)
3424
3425        with self.assertRaisesRegex(ValueError,
3426                                    "value <class 'inspect._empty'> "
3427                                    "is not a valid Parameter.kind"):
3428            p2 = p2.replace(kind=p2.empty)
3429
3430        p2 = p2.replace(kind=p2.KEYWORD_ONLY)
3431        self.assertEqual(p2, p)
3432
3433    def test_signature_parameter_positional_only(self):
3434        with self.assertRaisesRegex(TypeError, 'name must be a str'):
3435            inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
3436
3437    @cpython_only
3438    def test_signature_parameter_implicit(self):
3439        with self.assertRaisesRegex(ValueError,
3440                                    'implicit arguments must be passed as '
3441                                    'positional or keyword arguments, '
3442                                    'not positional-only'):
3443            inspect.Parameter('.0', kind=inspect.Parameter.POSITIONAL_ONLY)
3444
3445        param = inspect.Parameter(
3446            '.0', kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
3447        self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_ONLY)
3448        self.assertEqual(param.name, 'implicit0')
3449
3450    def test_signature_parameter_immutability(self):
3451        p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
3452
3453        with self.assertRaises(AttributeError):
3454            p.foo = 'bar'
3455
3456        with self.assertRaises(AttributeError):
3457            p.kind = 123
3458
3459
3460class TestSignatureBind(unittest.TestCase):
3461    @staticmethod
3462    def call(func, *args, **kwargs):
3463        sig = inspect.signature(func)
3464        ba = sig.bind(*args, **kwargs)
3465        return func(*ba.args, **ba.kwargs)
3466
3467    def test_signature_bind_empty(self):
3468        def test():
3469            return 42
3470
3471        self.assertEqual(self.call(test), 42)
3472        with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
3473            self.call(test, 1)
3474        with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
3475            self.call(test, 1, spam=10)
3476        with self.assertRaisesRegex(
3477            TypeError, "got an unexpected keyword argument 'spam'"):
3478
3479            self.call(test, spam=1)
3480
3481    def test_signature_bind_var(self):
3482        def test(*args, **kwargs):
3483            return args, kwargs
3484
3485        self.assertEqual(self.call(test), ((), {}))
3486        self.assertEqual(self.call(test, 1), ((1,), {}))
3487        self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
3488        self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
3489        self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
3490        self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
3491        self.assertEqual(self.call(test, 1, 2, foo='bar'),
3492                         ((1, 2), {'foo': 'bar'}))
3493
3494    def test_signature_bind_just_args(self):
3495        def test(a, b, c):
3496            return a, b, c
3497
3498        self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3499
3500        with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
3501            self.call(test, 1, 2, 3, 4)
3502
3503        with self.assertRaisesRegex(TypeError,
3504                                    "missing a required argument: 'b'"):
3505            self.call(test, 1)
3506
3507        with self.assertRaisesRegex(TypeError,
3508                                    "missing a required argument: 'a'"):
3509            self.call(test)
3510
3511        def test(a, b, c=10):
3512            return a, b, c
3513        self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3514        self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
3515
3516        def test(a=1, b=2, c=3):
3517            return a, b, c
3518        self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
3519        self.assertEqual(self.call(test, a=10), (10, 2, 3))
3520        self.assertEqual(self.call(test, b=10), (1, 10, 3))
3521
3522    def test_signature_bind_varargs_order(self):
3523        def test(*args):
3524            return args
3525
3526        self.assertEqual(self.call(test), ())
3527        self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3528
3529    def test_signature_bind_args_and_varargs(self):
3530        def test(a, b, c=3, *args):
3531            return a, b, c, args
3532
3533        self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
3534        self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
3535        self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
3536        self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
3537
3538        with self.assertRaisesRegex(TypeError,
3539                                     "multiple values for argument 'c'"):
3540            self.call(test, 1, 2, 3, c=4)
3541
3542    def test_signature_bind_just_kwargs(self):
3543        def test(**kwargs):
3544            return kwargs
3545
3546        self.assertEqual(self.call(test), {})
3547        self.assertEqual(self.call(test, foo='bar', spam='ham'),
3548                         {'foo': 'bar', 'spam': 'ham'})
3549
3550    def test_signature_bind_args_and_kwargs(self):
3551        def test(a, b, c=3, **kwargs):
3552            return a, b, c, kwargs
3553
3554        self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
3555        self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
3556                         (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3557        self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
3558                         (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3559        self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
3560                         (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3561        self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
3562                         (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3563        self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
3564                         (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
3565        self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
3566                         (1, 2, 4, {'foo': 'bar'}))
3567        self.assertEqual(self.call(test, c=5, a=4, b=3),
3568                         (4, 3, 5, {}))
3569
3570    def test_signature_bind_kwonly(self):
3571        def test(*, foo):
3572            return foo
3573        with self.assertRaisesRegex(TypeError,
3574                                     'too many positional arguments'):
3575            self.call(test, 1)
3576        self.assertEqual(self.call(test, foo=1), 1)
3577
3578        def test(a, *, foo=1, bar):
3579            return foo
3580        with self.assertRaisesRegex(TypeError,
3581                                     "missing a required argument: 'bar'"):
3582            self.call(test, 1)
3583
3584        def test(foo, *, bar):
3585            return foo, bar
3586        self.assertEqual(self.call(test, 1, bar=2), (1, 2))
3587        self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
3588
3589        with self.assertRaisesRegex(
3590            TypeError, "got an unexpected keyword argument 'spam'"):
3591
3592            self.call(test, bar=2, foo=1, spam=10)
3593
3594        with self.assertRaisesRegex(TypeError,
3595                                     'too many positional arguments'):
3596            self.call(test, 1, 2)
3597
3598        with self.assertRaisesRegex(TypeError,
3599                                     'too many positional arguments'):
3600            self.call(test, 1, 2, bar=2)
3601
3602        with self.assertRaisesRegex(
3603            TypeError, "got an unexpected keyword argument 'spam'"):
3604
3605            self.call(test, 1, bar=2, spam='ham')
3606
3607        with self.assertRaisesRegex(TypeError,
3608                                     "missing a required argument: 'bar'"):
3609            self.call(test, 1)
3610
3611        def test(foo, *, bar, **bin):
3612            return foo, bar, bin
3613        self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
3614        self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
3615        self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
3616                         (1, 2, {'spam': 'ham'}))
3617        self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
3618                         (1, 2, {'spam': 'ham'}))
3619        with self.assertRaisesRegex(TypeError,
3620                                    "missing a required argument: 'foo'"):
3621            self.call(test, spam='ham', bar=2)
3622        self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
3623                         (1, 2, {'bin': 1, 'spam': 10}))
3624
3625    def test_signature_bind_arguments(self):
3626        def test(a, *args, b, z=100, **kwargs):
3627            pass
3628        sig = inspect.signature(test)
3629        ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
3630        # we won't have 'z' argument in the bound arguments object, as we didn't
3631        # pass it to the 'bind'
3632        self.assertEqual(tuple(ba.arguments.items()),
3633                         (('a', 10), ('args', (20,)), ('b', 30),
3634                          ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
3635        self.assertEqual(ba.kwargs,
3636                         {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3637        self.assertEqual(ba.args, (10, 20))
3638
3639    def test_signature_bind_positional_only(self):
3640        P = inspect.Parameter
3641
3642        def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3643            return a_po, b_po, c_po, foo, bar, kwargs
3644
3645        sig = inspect.signature(test)
3646        new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3647        for name in ('a_po', 'b_po', 'c_po'):
3648            new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3649        new_sig = sig.replace(parameters=new_params.values())
3650        test.__signature__ = new_sig
3651
3652        self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3653                         (1, 2, 4, 5, 6, {}))
3654
3655        self.assertEqual(self.call(test, 1, 2),
3656                         (1, 2, 3, 42, 50, {}))
3657
3658        self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3659                         (1, 2, 3, 4, 5, {}))
3660
3661        with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3662            self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3663
3664        with self.assertRaisesRegex(TypeError, "parameter is positional only"):
3665            self.call(test, 1, 2, c_po=4)
3666
3667        with self.assertRaisesRegex(TypeError, "parameter is positional only"):
3668            self.call(test, a_po=1, b_po=2)
3669
3670    def test_signature_bind_with_self_arg(self):
3671        # Issue #17071: one of the parameters is named "self
3672        def test(a, self, b):
3673            pass
3674        sig = inspect.signature(test)
3675        ba = sig.bind(1, 2, 3)
3676        self.assertEqual(ba.args, (1, 2, 3))
3677        ba = sig.bind(1, self=2, b=3)
3678        self.assertEqual(ba.args, (1, 2, 3))
3679
3680    def test_signature_bind_vararg_name(self):
3681        def test(a, *args):
3682            return a, args
3683        sig = inspect.signature(test)
3684
3685        with self.assertRaisesRegex(
3686            TypeError, "got an unexpected keyword argument 'args'"):
3687
3688            sig.bind(a=0, args=1)
3689
3690        def test(*args, **kwargs):
3691            return args, kwargs
3692        self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3693
3694        sig = inspect.signature(test)
3695        ba = sig.bind(args=1)
3696        self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3697
3698    @cpython_only
3699    def test_signature_bind_implicit_arg(self):
3700        # Issue #19611: getcallargs should work with set comprehensions
3701        def make_set():
3702            return {z * z for z in range(5)}
3703        setcomp_code = make_set.__code__.co_consts[1]
3704        setcomp_func = types.FunctionType(setcomp_code, {})
3705
3706        iterator = iter(range(5))
3707        self.assertEqual(self.call(setcomp_func, iterator), {0, 1, 4, 9, 16})
3708
3709    def test_signature_bind_posonly_kwargs(self):
3710        def foo(bar, /, **kwargs):
3711            return bar, kwargs.get(bar)
3712
3713        sig = inspect.signature(foo)
3714        result = sig.bind("pos-only", bar="keyword")
3715
3716        self.assertEqual(result.kwargs, {"bar": "keyword"})
3717        self.assertIn(("bar", "pos-only"), result.arguments.items())
3718
3719
3720class TestBoundArguments(unittest.TestCase):
3721    def test_signature_bound_arguments_unhashable(self):
3722        def foo(a): pass
3723        ba = inspect.signature(foo).bind(1)
3724
3725        with self.assertRaisesRegex(TypeError, 'unhashable type'):
3726            hash(ba)
3727
3728    def test_signature_bound_arguments_equality(self):
3729        def foo(a): pass
3730        ba = inspect.signature(foo).bind(1)
3731        self.assertTrue(ba == ba)
3732        self.assertFalse(ba != ba)
3733        self.assertTrue(ba == ALWAYS_EQ)
3734        self.assertFalse(ba != ALWAYS_EQ)
3735
3736        ba2 = inspect.signature(foo).bind(1)
3737        self.assertTrue(ba == ba2)
3738        self.assertFalse(ba != ba2)
3739
3740        ba3 = inspect.signature(foo).bind(2)
3741        self.assertFalse(ba == ba3)
3742        self.assertTrue(ba != ba3)
3743        ba3.arguments['a'] = 1
3744        self.assertTrue(ba == ba3)
3745        self.assertFalse(ba != ba3)
3746
3747        def bar(b): pass
3748        ba4 = inspect.signature(bar).bind(1)
3749        self.assertFalse(ba == ba4)
3750        self.assertTrue(ba != ba4)
3751
3752        def foo(*, a, b): pass
3753        sig = inspect.signature(foo)
3754        ba1 = sig.bind(a=1, b=2)
3755        ba2 = sig.bind(b=2, a=1)
3756        self.assertTrue(ba1 == ba2)
3757        self.assertFalse(ba1 != ba2)
3758
3759    def test_signature_bound_arguments_pickle(self):
3760        def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3761        sig = inspect.signature(foo)
3762        ba = sig.bind(20, 30, z={})
3763
3764        for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3765            with self.subTest(pickle_ver=ver):
3766                ba_pickled = pickle.loads(pickle.dumps(ba, ver))
3767                self.assertEqual(ba, ba_pickled)
3768
3769    def test_signature_bound_arguments_repr(self):
3770        def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3771        sig = inspect.signature(foo)
3772        ba = sig.bind(20, 30, z={})
3773        self.assertRegex(repr(ba), r'<BoundArguments \(a=20,.*\}\}\)>')
3774
3775    def test_signature_bound_arguments_apply_defaults(self):
3776        def foo(a, b=1, *args, c:1={}, **kw): pass
3777        sig = inspect.signature(foo)
3778
3779        ba = sig.bind(20)
3780        ba.apply_defaults()
3781        self.assertEqual(
3782            list(ba.arguments.items()),
3783            [('a', 20), ('b', 1), ('args', ()), ('c', {}), ('kw', {})])
3784
3785        # Make sure that we preserve the order:
3786        # i.e. 'c' should be *before* 'kw'.
3787        ba = sig.bind(10, 20, 30, d=1)
3788        ba.apply_defaults()
3789        self.assertEqual(
3790            list(ba.arguments.items()),
3791            [('a', 10), ('b', 20), ('args', (30,)), ('c', {}), ('kw', {'d':1})])
3792
3793        # Make sure that BoundArguments produced by bind_partial()
3794        # are supported.
3795        def foo(a, b): pass
3796        sig = inspect.signature(foo)
3797        ba = sig.bind_partial(20)
3798        ba.apply_defaults()
3799        self.assertEqual(
3800            list(ba.arguments.items()),
3801            [('a', 20)])
3802
3803        # Test no args
3804        def foo(): pass
3805        sig = inspect.signature(foo)
3806        ba = sig.bind()
3807        ba.apply_defaults()
3808        self.assertEqual(list(ba.arguments.items()), [])
3809
3810        # Make sure a no-args binding still acquires proper defaults.
3811        def foo(a='spam'): pass
3812        sig = inspect.signature(foo)
3813        ba = sig.bind()
3814        ba.apply_defaults()
3815        self.assertEqual(list(ba.arguments.items()), [('a', 'spam')])
3816
3817    def test_signature_bound_arguments_arguments_type(self):
3818        def foo(a): pass
3819        ba = inspect.signature(foo).bind(1)
3820        self.assertIs(type(ba.arguments), dict)
3821
3822class TestSignaturePrivateHelpers(unittest.TestCase):
3823    def test_signature_get_bound_param(self):
3824        getter = inspect._signature_get_bound_param
3825
3826        self.assertEqual(getter('($self)'), 'self')
3827        self.assertEqual(getter('($self, obj)'), 'self')
3828        self.assertEqual(getter('($cls, /, obj)'), 'cls')
3829
3830    def _strip_non_python_syntax(self, input,
3831        clean_signature, self_parameter, last_positional_only):
3832        computed_clean_signature, \
3833            computed_self_parameter, \
3834            computed_last_positional_only = \
3835            inspect._signature_strip_non_python_syntax(input)
3836        self.assertEqual(computed_clean_signature, clean_signature)
3837        self.assertEqual(computed_self_parameter, self_parameter)
3838        self.assertEqual(computed_last_positional_only, last_positional_only)
3839
3840    def test_signature_strip_non_python_syntax(self):
3841        self._strip_non_python_syntax(
3842            "($module, /, path, mode, *, dir_fd=None, " +
3843                "effective_ids=False,\n       follow_symlinks=True)",
3844            "(module, path, mode, *, dir_fd=None, " +
3845                "effective_ids=False, follow_symlinks=True)",
3846            0,
3847            0)
3848
3849        self._strip_non_python_syntax(
3850            "($module, word, salt, /)",
3851            "(module, word, salt)",
3852            0,
3853            2)
3854
3855        self._strip_non_python_syntax(
3856            "(x, y=None, z=None, /)",
3857            "(x, y=None, z=None)",
3858            None,
3859            2)
3860
3861        self._strip_non_python_syntax(
3862            "(x, y=None, z=None)",
3863            "(x, y=None, z=None)",
3864            None,
3865            None)
3866
3867        self._strip_non_python_syntax(
3868            "(x,\n    y=None,\n      z = None  )",
3869            "(x, y=None, z=None)",
3870            None,
3871            None)
3872
3873        self._strip_non_python_syntax(
3874            "",
3875            "",
3876            None,
3877            None)
3878
3879        self._strip_non_python_syntax(
3880            None,
3881            None,
3882            None,
3883            None)
3884
3885class TestSignatureDefinitions(unittest.TestCase):
3886    # This test case provides a home for checking that particular APIs
3887    # have signatures available for introspection
3888
3889    @cpython_only
3890    @unittest.skipIf(MISSING_C_DOCSTRINGS,
3891                     "Signature information for builtins requires docstrings")
3892    def test_builtins_have_signatures(self):
3893        # This checks all builtin callables in CPython have signatures
3894        # A few have signatures Signature can't yet handle, so we skip those
3895        # since they will have to wait until PEP 457 adds the required
3896        # introspection support to the inspect module
3897        # Some others also haven't been converted yet for various other
3898        # reasons, so we also skip those for the time being, but design
3899        # the test to fail in order to indicate when it needs to be
3900        # updated.
3901        no_signature = set()
3902        # These need PEP 457 groups
3903        needs_groups = {"range", "slice", "dir", "getattr",
3904                        "next", "iter", "vars"}
3905        no_signature |= needs_groups
3906        # These need PEP 457 groups or a signature change to accept None
3907        needs_semantic_update = {"round"}
3908        no_signature |= needs_semantic_update
3909        # These need *args support in Argument Clinic
3910        needs_varargs = {"breakpoint", "min", "max", "print",
3911                         "__build_class__"}
3912        no_signature |= needs_varargs
3913        # These simply weren't covered in the initial AC conversion
3914        # for builtin callables
3915        not_converted_yet = {"open", "__import__"}
3916        no_signature |= not_converted_yet
3917        # These builtin types are expected to provide introspection info
3918        types_with_signatures = set()
3919        # Check the signatures we expect to be there
3920        ns = vars(builtins)
3921        for name, obj in sorted(ns.items()):
3922            if not callable(obj):
3923                continue
3924            # The builtin types haven't been converted to AC yet
3925            if isinstance(obj, type) and (name not in types_with_signatures):
3926                # Note that this also skips all the exception types
3927                no_signature.add(name)
3928            if (name in no_signature):
3929                # Not yet converted
3930                continue
3931            with self.subTest(builtin=name):
3932                self.assertIsNotNone(inspect.signature(obj))
3933        # Check callables that haven't been converted don't claim a signature
3934        # This ensures this test will start failing as more signatures are
3935        # added, so the affected items can be moved into the scope of the
3936        # regression test above
3937        for name in no_signature:
3938            with self.subTest(builtin=name):
3939                self.assertIsNone(obj.__text_signature__)
3940
3941    def test_python_function_override_signature(self):
3942        def func(*args, **kwargs):
3943            pass
3944        func.__text_signature__ = '($self, a, b=1, *args, c, d=2, **kwargs)'
3945        sig = inspect.signature(func)
3946        self.assertIsNotNone(sig)
3947        self.assertEqual(str(sig), '(self, /, a, b=1, *args, c, d=2, **kwargs)')
3948        func.__text_signature__ = '($self, a, b=1, /, *args, c, d=2, **kwargs)'
3949        sig = inspect.signature(func)
3950        self.assertEqual(str(sig), '(self, a, b=1, /, *args, c, d=2, **kwargs)')
3951
3952
3953class NTimesUnwrappable:
3954    def __init__(self, n):
3955        self.n = n
3956        self._next = None
3957
3958    @property
3959    def __wrapped__(self):
3960        if self.n <= 0:
3961            raise Exception("Unwrapped too many times")
3962        if self._next is None:
3963            self._next = NTimesUnwrappable(self.n - 1)
3964        return self._next
3965
3966class TestUnwrap(unittest.TestCase):
3967
3968    def test_unwrap_one(self):
3969        def func(a, b):
3970            return a + b
3971        wrapper = functools.lru_cache(maxsize=20)(func)
3972        self.assertIs(inspect.unwrap(wrapper), func)
3973
3974    def test_unwrap_several(self):
3975        def func(a, b):
3976            return a + b
3977        wrapper = func
3978        for __ in range(10):
3979            @functools.wraps(wrapper)
3980            def wrapper():
3981                pass
3982        self.assertIsNot(wrapper.__wrapped__, func)
3983        self.assertIs(inspect.unwrap(wrapper), func)
3984
3985    def test_stop(self):
3986        def func1(a, b):
3987            return a + b
3988        @functools.wraps(func1)
3989        def func2():
3990            pass
3991        @functools.wraps(func2)
3992        def wrapper():
3993            pass
3994        func2.stop_here = 1
3995        unwrapped = inspect.unwrap(wrapper,
3996                                   stop=(lambda f: hasattr(f, "stop_here")))
3997        self.assertIs(unwrapped, func2)
3998
3999    def test_cycle(self):
4000        def func1(): pass
4001        func1.__wrapped__ = func1
4002        with self.assertRaisesRegex(ValueError, 'wrapper loop'):
4003            inspect.unwrap(func1)
4004
4005        def func2(): pass
4006        func2.__wrapped__ = func1
4007        func1.__wrapped__ = func2
4008        with self.assertRaisesRegex(ValueError, 'wrapper loop'):
4009            inspect.unwrap(func1)
4010        with self.assertRaisesRegex(ValueError, 'wrapper loop'):
4011            inspect.unwrap(func2)
4012
4013    def test_unhashable(self):
4014        def func(): pass
4015        func.__wrapped__ = None
4016        class C:
4017            __hash__ = None
4018            __wrapped__ = func
4019        self.assertIsNone(inspect.unwrap(C()))
4020
4021    def test_recursion_limit(self):
4022        obj = NTimesUnwrappable(sys.getrecursionlimit() + 1)
4023        with self.assertRaisesRegex(ValueError, 'wrapper loop'):
4024            inspect.unwrap(obj)
4025
4026class TestMain(unittest.TestCase):
4027    def test_only_source(self):
4028        module = importlib.import_module('unittest')
4029        rc, out, err = assert_python_ok('-m', 'inspect',
4030                                        'unittest')
4031        lines = out.decode().splitlines()
4032        # ignore the final newline
4033        self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
4034        self.assertEqual(err, b'')
4035
4036    def test_custom_getattr(self):
4037        def foo():
4038            pass
4039        foo.__signature__ = 42
4040        with self.assertRaises(TypeError):
4041            inspect.signature(foo)
4042
4043    @unittest.skipIf(ThreadPoolExecutor is None,
4044            'threads required to test __qualname__ for source files')
4045    def test_qualname_source(self):
4046        rc, out, err = assert_python_ok('-m', 'inspect',
4047                                     'concurrent.futures:ThreadPoolExecutor')
4048        lines = out.decode().splitlines()
4049        # ignore the final newline
4050        self.assertEqual(lines[:-1],
4051                         inspect.getsource(ThreadPoolExecutor).splitlines())
4052        self.assertEqual(err, b'')
4053
4054    def test_builtins(self):
4055        module = importlib.import_module('unittest')
4056        _, out, err = assert_python_failure('-m', 'inspect',
4057                                            'sys')
4058        lines = err.decode().splitlines()
4059        self.assertEqual(lines, ["Can't get info for builtin modules."])
4060
4061    def test_details(self):
4062        module = importlib.import_module('unittest')
4063        args = support.optim_args_from_interpreter_flags()
4064        rc, out, err = assert_python_ok(*args, '-m', 'inspect',
4065                                        'unittest', '--details')
4066        output = out.decode()
4067        # Just a quick sanity check on the output
4068        self.assertIn(module.__name__, output)
4069        self.assertIn(module.__file__, output)
4070        self.assertIn(module.__cached__, output)
4071        self.assertEqual(err, b'')
4072
4073
4074class TestReload(unittest.TestCase):
4075
4076    src_before = textwrap.dedent("""\
4077def foo():
4078    print("Bla")
4079    """)
4080
4081    src_after = textwrap.dedent("""\
4082def foo():
4083    print("Oh no!")
4084    """)
4085
4086    def assertInspectEqual(self, path, source):
4087        inspected_src = inspect.getsource(source)
4088        with open(path) as src:
4089            self.assertEqual(
4090                src.read().splitlines(True),
4091                inspected_src.splitlines(True)
4092            )
4093
4094    def test_getsource_reload(self):
4095        # see issue 1218234
4096        with _ready_to_import('reload_bug', self.src_before) as (name, path):
4097            module = importlib.import_module(name)
4098            self.assertInspectEqual(path, module)
4099            with open(path, 'w') as src:
4100                src.write(self.src_after)
4101            self.assertInspectEqual(path, module)
4102
4103
4104if __name__ == "__main__":
4105    unittest.main()
4106