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