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