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