diff options
37 files changed, 160 insertions, 184 deletions
diff --git a/Doc/lib/libdis.tex b/Doc/lib/libdis.tex index 3f00fa8..84841e4 100644 --- a/Doc/lib/libdis.tex +++ b/Doc/lib/libdis.tex @@ -622,7 +622,7 @@ default parameters, which are found below TOS. \end{opcodedesc} \begin{opcodedesc}{MAKE_CLOSURE}{argc} -Creates a new function object, sets its \var{func_closure} slot, and +Creates a new function object, sets its \var{__closure__} slot, and pushes it on the stack. TOS is the code associated with the function. If the code object has N free variables, the next N items on the stack are the cells for these variables. The function also has \var{argc} diff --git a/Doc/lib/libinspect.tex b/Doc/lib/libinspect.tex index 85651f0..c9a63fc 100644 --- a/Doc/lib/libinspect.tex +++ b/Doc/lib/libinspect.tex @@ -45,11 +45,9 @@ you can expect to find the following special attributes: \hline \lineiv{function}{__doc__}{documentation string}{} \lineiv{}{__name__}{name with which this function was defined}{} - \lineiv{}{func_code}{code object containing compiled function bytecode}{} - \lineiv{}{func_defaults}{tuple of any default values for arguments}{} - \lineiv{}{func_doc}{(same as __doc__)}{} - \lineiv{}{func_globals}{global namespace in which this function was defined}{} - \lineiv{}{func_name}{(same as __name__)}{} + \lineiv{}{__code__}{code object containing compiled function bytecode}{} + \lineiv{}{__defaults__}{tuple of any default values for arguments}{} + \lineiv{}{__globals__}{global namespace in which this function was defined}{} \hline \lineiv{traceback}{tb_frame}{frame object at this level}{} \lineiv{}{tb_lasti}{index of last attempted instruction in bytecode}{} diff --git a/Doc/lib/libstdtypes.tex b/Doc/lib/libstdtypes.tex index cc117ab..f3ce92a 100644 --- a/Doc/lib/libstdtypes.tex +++ b/Doc/lib/libstdtypes.tex @@ -1964,10 +1964,10 @@ Code objects are used by the implementation to represent They differ from function objects because they don't contain a reference to their global execution environment. Code objects are returned by the built-in \function{compile()} function and can be -extracted from function objects through their \member{func_code} +extracted from function objects through their \member{__code__} attribute. \bifuncindex{compile} -\withsubitem{(function object attribute)}{\ttindex{func_code}} +\withsubitem{(function object attribute)}{\ttindex{__code__}} A code object can be executed or evaluated by passing it (instead of a source string) to the \function{exec()} or \function{eval()} diff --git a/Doc/ref/ref3.tex b/Doc/ref/ref3.tex index 4b9da9e..6bd60c9 100644 --- a/Doc/ref/ref3.tex +++ b/Doc/ref/ref3.tex @@ -473,42 +473,42 @@ parameter list. Special attributes: \begin{tableiii}{lll}{member}{Attribute}{Meaning}{} - \lineiii{func_doc}{The function's documentation string, or + \lineiii{__doc__}{The function's documentation string, or \code{None} if unavailable}{Writable} - \lineiii{__doc__}{Another way of spelling - \member{func_doc}}{Writable} - - \lineiii{func_name}{The function's name}{Writable} - - \lineiii{__name__}{Another way of spelling - \member{func_name}}{Writable} + \lineiii{__name__}{The function's name}{Writable} \lineiii{__module__}{The name of the module the function was defined in, or \code{None} if unavailable.}{Writable} - \lineiii{func_defaults}{A tuple containing default argument values + \lineiii{__defaults__}{A tuple containing default argument values for those arguments that have defaults, or \code{None} if no arguments have a default value}{Writable} - \lineiii{func_code}{The code object representing the compiled + \lineiii{__code__}{The code object representing the compiled function body.}{Writable} - \lineiii{func_globals}{A reference to the dictionary that holds the + \lineiii{__globals__}{A reference to the dictionary that holds the function's global variables --- the global namespace of the module in which the function was defined.}{Read-only} - \lineiii{func_dict}{The namespace supporting arbitrary function + \lineiii{__dict__}{The namespace supporting arbitrary function attributes.}{Writable} - \lineiii{func_closure}{\code{None} or a tuple of cells that contain + \lineiii{__closure__}{\code{None} or a tuple of cells that contain bindings for the function's free variables.}{Read-only} + + \lineiii{__annotations__}{A dict containing annotations of parameters.} + {Writable} + + \lineiii{__kwdefaults__}{A dict containing defaults for keyword-only + parameters.}{Writable} \end{tableiii} Most of the attributes labelled ``Writable'' check the type of the assigned value. -\versionchanged[\code{func_name} is now writable]{2.4} +\versionchanged[\code{__name__} is now writable]{2.4} Function objects also support getting and setting arbitrary attributes, which can be used, for example, to attach metadata to @@ -521,16 +521,16 @@ Additional information about a function's definition can be retrieved from its code object; see the description of internal types below. \withsubitem{(function attribute)}{ - \ttindex{func_doc} \ttindex{__doc__} \ttindex{__name__} \ttindex{__module__} \ttindex{__dict__} - \ttindex{func_defaults} - \ttindex{func_closure} - \ttindex{func_code} - \ttindex{func_globals} - \ttindex{func_dict}} + \ttindex{__defaults__} + \ttindex{__closure__} + \ttindex{__code__} + \ttindex{__globals__} + \ttindex{__annotations__} + \ttindex{__kwdefaults__} \indexii{global}{namespace} \item[User-defined methods] @@ -700,7 +700,7 @@ Modules are imported by the \keyword{import} statement (see section~\ref{import}, ``The \keyword{import} statement'').% \stindex{import}\obindex{module} A module object has a namespace implemented by a dictionary object -(this is the dictionary referenced by the func_globals attribute of +(this is the dictionary referenced by the __globals__ attribute of functions defined in the module). Attribute references are translated to lookups in this dictionary, e.g., \code{m.x} is equivalent to \code{m.__dict__["x"]}. diff --git a/Lib/Bastion.py b/Lib/Bastion.py index 6a5cb5c..d83ea3e 100644 --- a/Lib/Bastion.py +++ b/Lib/Bastion.py @@ -158,7 +158,7 @@ def _test(): else: print "accessible" try: - print "b._get_.func_defaults =", map(type, b._get_.func_defaults), + print "b._get_.__defaults__ =", map(type, b._get_.__defaults__), except: print "inaccessible" else: @@ -20,8 +20,8 @@ def dis(x=None): return if hasattr(x, 'im_func'): x = x.im_func - if hasattr(x, 'func_code'): - x = x.func_code + if hasattr(x, '__code__'): + x = x.__code__ if hasattr(x, '__dict__'): items = x.__dict__.items() items.sort() diff --git a/Lib/doctest.py b/Lib/doctest.py index 02e200d..5ee4d85 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -831,7 +831,7 @@ class DocTestFinder: if module is None: return True elif inspect.isfunction(object): - return module.__dict__ is object.func_globals + return module.__dict__ is object.__globals__ elif inspect.isclass(object): return module.__name__ == object.__module__ elif inspect.getmodule(object) is not None: @@ -969,7 +969,7 @@ class DocTestFinder: # Find the line number for functions & methods. if inspect.ismethod(obj): obj = obj.im_func - if inspect.isfunction(obj): obj = obj.func_code + if inspect.isfunction(obj): obj = obj.__code__ if inspect.istraceback(obj): obj = obj.tb_frame if inspect.isframe(obj): obj = obj.f_code if inspect.iscode(obj): diff --git a/Lib/idlelib/CallTips.py b/Lib/idlelib/CallTips.py index b395f15..9152eaa 100644 --- a/Lib/idlelib/CallTips.py +++ b/Lib/idlelib/CallTips.py @@ -147,15 +147,15 @@ def get_arg_text(ob): fob = ob # Try to build one for Python defined functions if type(fob) in [types.FunctionType, types.LambdaType]: - argcount = fob.func_code.co_argcount - real_args = fob.func_code.co_varnames[arg_offset:argcount] - defaults = fob.func_defaults or [] + argcount = fob.__code__.co_argcount + real_args = fob.__code__.co_varnames[arg_offset:argcount] + defaults = fob.__defaults__ or [] defaults = list(map(lambda name: "=%s" % repr(name), defaults)) defaults = [""] * (len(real_args) - len(defaults)) + defaults items = map(lambda arg, dflt: arg + dflt, real_args, defaults) - if fob.func_code.co_flags & 0x4: + if fob.__code__.co_flags & 0x4: items.append("...") - if fob.func_code.co_flags & 0x8: + if fob.__code__.co_flags & 0x8: items.append("***") arg_text = ", ".join(items) arg_text = "(%s)" % re.sub("\.\d+", "<tuple>", arg_text) diff --git a/Lib/inspect.py b/Lib/inspect.py index 986a415..e87d3e2 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -2,7 +2,7 @@ """Get useful information from live Python objects. This module encapsulates the interface provided by the internal special -attributes (func_*, co_*, im_*, tb_*, etc.) in a friendlier fashion. +attributes (co_*, im_*, tb_*, etc.) in a friendlier fashion. It also provides some help for examining source code and class layout. Here are some of the useful functions provided by this module: @@ -129,11 +129,11 @@ def isfunction(object): Function objects provide these attributes: __doc__ documentation string __name__ name with which this function was defined - func_code code object containing compiled function bytecode - func_defaults tuple of any default values for arguments - func_doc (same as __doc__) - func_globals global namespace in which this function was defined - func_name (same as __name__)""" + __code__ code object containing compiled function bytecode + __defaults__ tuple of any default values for arguments + __globals__ global namespace in which this function was defined + __annotations__ dict of parameter annotations + __kwdefaults__ dict of keyword only parameters with defaults""" return isinstance(object, types.FunctionType) def istraceback(object): @@ -353,7 +353,7 @@ def getfile(object): if ismethod(object): object = object.im_func if isfunction(object): - object = object.func_code + object = object.__code__ if istraceback(object): object = object.tb_frame if isframe(object): @@ -496,7 +496,7 @@ def findsource(object): if ismethod(object): object = object.im_func if isfunction(object): - object = object.func_code + object = object.__code__ if istraceback(object): object = object.tb_frame if isframe(object): @@ -741,8 +741,8 @@ def getargspec(func): func = func.im_func if not isfunction(func): raise TypeError('arg is not a Python function') - args, varargs, varkw = getargs(func.func_code) - return args, varargs, varkw, func.func_defaults + args, varargs, varkw = getargs(func.__code__) + return args, varargs, varkw, func.__defaults__ def getargvalues(frame): """Get information about arguments passed into a particular frame. @@ -262,7 +262,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): func = getattr(self, 'do_' + cmd) except AttributeError: func = self.default - if func.func_name in self.commands_resuming : # one of the resuming commands. + if func.__name__ in self.commands_resuming : # one of the resuming commands. self.commands_doprompt[self.commands_bnum] = False self.cmdqueue = [] return 1 @@ -347,7 +347,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): try: if hasattr(func, 'im_func'): func = func.im_func - code = func.func_code + code = func.__code__ #use co_name to identify the bkpt (function names #could be aliased, but co_name is invariant) funcname = code.co_name @@ -759,13 +759,13 @@ class Pdb(bdb.Bdb, cmd.Cmd): return code = None # Is it a function? - try: code = value.func_code + try: code = value.__code__ except: pass if code: print('Function', code.co_name, file=self.stdout) return # Is it an instance method? - try: code = value.im_func.func_code + try: code = value.im_func.__code__ except: pass if code: print('Method', code.co_name, file=self.stdout) diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index 4f43f5d..7512263 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -6,7 +6,7 @@ ... return g ... ->>> dump(f.func_code) +>>> dump(f.__code__) name: f argcount: 1 kwonlyargcount: 0 @@ -18,7 +18,7 @@ nlocals: 2 flags: 3 consts: ('None', '<code object g>') ->>> dump(f(4).func_code) +>>> dump(f(4).__code__) name: g argcount: 1 kwonlyargcount: 0 @@ -37,7 +37,7 @@ consts: ('None',) ... return c ... ->>> dump(h.func_code) +>>> dump(h.__code__) name: h argcount: 2 kwonlyargcount: 0 @@ -54,7 +54,7 @@ consts: ('None',) ... print(obj.attr2) ... print(obj.attr3) ->>> dump(attrs.func_code) +>>> dump(attrs.__code__) name: attrs argcount: 1 kwonlyargcount: 0 @@ -72,7 +72,7 @@ consts: ('None',) ... 53 ... 0x53 ->>> dump(optimize_away.func_code) +>>> dump(optimize_away.__code__) name: optimize_away argcount: 0 kwonlyargcount: 0 @@ -88,7 +88,7 @@ consts: ("'doc string'", 'None') ... return a,b,k1 ... ->>> dump(keywordonly_args.func_code) +>>> dump(keywordonly_args.__code__) name: keywordonly_args argcount: 2 kwonlyargcount: 1 diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 1acb4a1..022f7c0 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -235,7 +235,7 @@ if 1: g = +9223372036854775807 # 1 << 63 - 1 h = -9223372036854775807 # 1 << 63 - 1 - for variable in self.test_32_63_bit_values.func_code.co_consts: + for variable in self.test_32_63_bit_values.__code__.co_consts: if variable is not None: self.assertTrue(isinstance(variable, int)) @@ -315,7 +315,7 @@ if 1: f2 = lambda x=2: x return f1, f2 f1, f2 = f() - self.assertNotEqual(id(f1.func_code), id(f2.func_code)) + self.assertNotEqual(id(f1.__code__), id(f2.__code__)) def test_unicode_encoding(self): code = u"# -*- coding: utf-8 -*-\npass\n" diff --git a/Lib/test/test_compiler.py b/Lib/test/test_compiler.py index bbd7511..8535f42 100644 --- a/Lib/test/test_compiler.py +++ b/Lib/test/test_compiler.py @@ -160,7 +160,7 @@ class CompilerTest(unittest.TestCase): c = compiler.compile(sourcecode, '<string>', 'exec') dct = {} exec(c, dct) - self.assertEquals(dct['f'].func_annotations, expected) + self.assertEquals(dct['f'].__annotations__, expected) def testWith(self): # SF bug 1638243 diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py index cb075c3..fd6109c 100644 --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -83,7 +83,7 @@ class TestCopy(unittest.TestCase): def f(): pass tests = [None, 42, 2**100, 3.14, True, False, 1j, - "hello", u"hello\u1234", f.func_code, + "hello", u"hello\u1234", f.__code__, NewStyle, xrange(10), Classic, max] for x in tests: self.assert_(copy.copy(x) is x, repr(x)) @@ -256,7 +256,7 @@ class TestCopy(unittest.TestCase): def f(): pass tests = [None, 42, 2**100, 3.14, True, False, 1j, - "hello", u"hello\u1234", f.func_code, + "hello", u"hello\u1234", f.__code__, NewStyle, xrange(10), Classic, max] for x in tests: self.assert_(copy.deepcopy(x) is x, repr(x)) diff --git a/Lib/test/test_decorators.py b/Lib/test/test_decorators.py index 56aa5e1..2558247 100644 --- a/Lib/test/test_decorators.py +++ b/Lib/test/test_decorators.py @@ -27,7 +27,7 @@ class DbcheckError (Exception): def dbcheck(exprstr, globals=None, locals=None): "Decorator to implement debugging assertions" def decorate(func): - expr = compile(exprstr, "dbcheck-%s" % func.func_name, "eval") + expr = compile(exprstr, "dbcheck-%s" % func.__name__, "eval") def check(*args, **kwds): if not eval(expr, globals, locals): raise DbcheckError(exprstr, func, args, kwds) @@ -40,12 +40,12 @@ def dbcheck(exprstr, globals=None, locals=None): def countcalls(counts): "Decorator to count calls to a function" def decorate(func): - func_name = func.func_name + func_name = func.__name__ counts[func_name] = 0 def call(*args, **kwds): counts[func_name] += 1 return func(*args, **kwds) - call.func_name = func_name + call.__name__ = func_name return call return decorate @@ -63,7 +63,7 @@ def memoize(func): except TypeError: # Unhashable argument return func(*args) - call.func_name = func.func_name + call.__name__ = func.__name__ return call # ----------------------------------------------- @@ -131,7 +131,7 @@ class TestDecorators(unittest.TestCase): @countcalls(counts) def double(x): return x * 2 - self.assertEqual(double.func_name, 'double') + self.assertEqual(double.__name__, 'double') self.assertEqual(counts, dict(double=0)) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index ab70778..bb8638b 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -19,8 +19,8 @@ dis_f = """\ %-4d 10 LOAD_CONST 1 (1) 13 RETURN_VALUE -"""%(_f.func_code.co_firstlineno + 1, - _f.func_code.co_firstlineno + 2) +"""%(_f.__code__.co_firstlineno + 1, + _f.__code__.co_firstlineno + 2) def bug708901(): @@ -43,9 +43,9 @@ dis_bug708901 = """\ >> 25 POP_BLOCK >> 26 LOAD_CONST 0 (None) 29 RETURN_VALUE -"""%(bug708901.func_code.co_firstlineno + 1, - bug708901.func_code.co_firstlineno + 2, - bug708901.func_code.co_firstlineno + 3) +"""%(bug708901.__code__.co_firstlineno + 1, + bug708901.__code__.co_firstlineno + 2, + bug708901.__code__.co_firstlineno + 3) def bug1333982(x=[]): @@ -78,9 +78,9 @@ dis_bug1333982 = """\ %-4d 48 LOAD_CONST 0 (None) 51 RETURN_VALUE -"""%(bug1333982.func_code.co_firstlineno + 1, - bug1333982.func_code.co_firstlineno + 2, - bug1333982.func_code.co_firstlineno + 3) +"""%(bug1333982.__code__.co_firstlineno + 1, + bug1333982.__code__.co_firstlineno + 2, + bug1333982.__code__.co_firstlineno + 3) _BIG_LINENO_FORMAT = """\ %3d 0 LOAD_GLOBAL 0 (spam) diff --git a/Lib/test/test_extcall.py b/Lib/test/test_extcall.py index 3e0426f..453f464 100644 --- a/Lib/test/test_extcall.py +++ b/Lib/test/test_extcall.py @@ -274,6 +274,6 @@ for name in ['za', 'zade', 'zabk', 'zabdv', 'zabdevk']: for kwargs in ['', 'a', 'd', 'ad', 'abde']: kwdict = {} for k in kwargs: kwdict[k] = k + k - print(func.func_name, args, sortdict(kwdict), '->', end=' ') + print(func.__name__, args, sortdict(kwdict), '->', end=' ') try: func(*args, **kwdict) except TypeError as err: print(err) diff --git a/Lib/test/test_funcattrs.py b/Lib/test/test_funcattrs.py index 2f4b67a..528ca18 100644 --- a/Lib/test/test_funcattrs.py +++ b/Lib/test/test_funcattrs.py @@ -47,7 +47,7 @@ else: raise TestFailed, 'func.__dict__ = None expected TypeError' d = {'hello': 'world'} b.__dict__ = d -if b.func_dict is not d: +if b.__dict__ is not d: raise TestFailed, 'func.__dict__ assignment to dictionary failed' if b.hello != 'world': raise TestFailed, 'attribute after func.__dict__ assignment failed' @@ -179,12 +179,12 @@ except TypeError: pass else: raise TestFailed try: - del another.func_dict + del another.__dict__ except TypeError: pass else: raise TestFailed try: - another.func_dict = None + another.__dict__ = None except TypeError: pass else: raise TestFailed @@ -195,7 +195,7 @@ else: raise TestFailed # This isn't specifically related to function attributes, but it does test a # core dump regression in funcobject.c -del another.func_defaults +del another.__defaults__ def foo(): pass @@ -212,7 +212,7 @@ if foo==bar: d={} d[foo] = 1 -foo.func_code = temp.func_code +foo.__code__ = temp.__code__ d[foo] @@ -236,45 +236,31 @@ def cantset(obj, name, value, exception=(AttributeError, TypeError)): def test_func_closure(): a = 12 def f(): print(a) - c = f.func_closure + c = f.__closure__ verify(isinstance(c, tuple)) verify(len(c) == 1) verify(c[0].__class__.__name__ == "cell") # don't have a type object handy - cantset(f, "func_closure", c) + cantset(f, "__closure__", c) def test_func_doc(): def f(): pass verify(f.__doc__ is None) - verify(f.func_doc is None) f.__doc__ = "hello" verify(f.__doc__ == "hello") - verify(f.func_doc == "hello") del f.__doc__ verify(f.__doc__ is None) - verify(f.func_doc is None) - f.func_doc = "world" - verify(f.__doc__ == "world") - verify(f.func_doc == "world") - del f.func_doc - verify(f.func_doc is None) - verify(f.__doc__ is None) def test_func_globals(): def f(): pass - verify(f.func_globals is globals()) - cantset(f, "func_globals", globals()) + verify(f.__globals__ is globals()) + cantset(f, "__globals__", globals()) def test_func_name(): def f(): pass verify(f.__name__ == "f") - verify(f.func_name == "f") f.__name__ = "g" verify(f.__name__ == "g") - verify(f.func_name == "g") - f.func_name = "h" - verify(f.__name__ == "h") - verify(f.func_name == "h") - cantset(f, "func_globals", 1) + cantset(f, "__globals__", 1) cantset(f, "__name__", 1) # test that you can access func.__name__ in restricted mode s = """def f(): pass\nf.__name__""" @@ -288,25 +274,25 @@ def test_func_code(): def f1(): print(a) def g1(): print(b) def f2(): print(a, b) - verify(type(f.func_code) is types.CodeType) - f.func_code = g.func_code - cantset(f, "func_code", None) + verify(type(f.__code__) is types.CodeType) + f.__code__ = g.__code__ + cantset(f, "__code__", None) # can't change the number of free vars - cantset(f, "func_code", f1.func_code, exception=ValueError) - cantset(f1, "func_code", f.func_code, exception=ValueError) - cantset(f1, "func_code", f2.func_code, exception=ValueError) - f1.func_code = g1.func_code + cantset(f, "__code__", f1.__code__, exception=ValueError) + cantset(f1, "__code__", f.__code__, exception=ValueError) + cantset(f1, "__code__", f2.__code__, exception=ValueError) + f1.__code__ = g1.__code__ def test_func_defaults(): def f(a, b): return (a, b) - verify(f.func_defaults is None) - f.func_defaults = (1, 2) - verify(f.func_defaults == (1, 2)) + verify(f.__defaults__ is None) + f.__defaults__ = (1, 2) + verify(f.__defaults__ == (1, 2)) verify(f(10) == (10, 2)) def g(a=1, b=2): return (a, b) - verify(g.func_defaults == (1, 2)) - del g.func_defaults - verify(g.func_defaults is None) + verify(g.__defaults__ == (1, 2)) + del g.__defaults__ + verify(g.__defaults__ is None) try: g() except TypeError: @@ -317,18 +303,13 @@ def test_func_defaults(): def test_func_dict(): def f(): pass a = f.__dict__ - b = f.func_dict verify(a == {}) - verify(a is b) f.hello = 'world' verify(a == {'hello': 'world'}) - verify(f.func_dict is a is f.__dict__) - f.func_dict = {} - verify(not hasattr(f, "hello")) + verify(a is f.__dict__) f.__dict__ = {'world': 'hello'} verify(f.world == "hello") - verify(f.__dict__ is f.func_dict == {'world': 'hello'}) - cantset(f, "func_dict", None) + verify(f.__dict__ == {'world': 'hello'}) cantset(f, "__dict__", None) def test_im_class(): diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 4a480aa..cb37021 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -162,18 +162,18 @@ class GrammarTests(unittest.TestCase): def f3(two, arguments): pass def f4(two, (compound, (argument, list))): pass def f5((compound, first), two): pass - self.assertEquals(f2.func_code.co_varnames, ('one_argument',)) - self.assertEquals(f3.func_code.co_varnames, ('two', 'arguments')) + self.assertEquals(f2.__code__.co_varnames, ('one_argument',)) + self.assertEquals(f3.__code__.co_varnames, ('two', 'arguments')) if sys.platform.startswith('java'): - self.assertEquals(f4.func_code.co_varnames, + self.assertEquals(f4.__code__.co_varnames, ('two', '(compound, (argument, list))', 'compound', 'argument', 'list',)) - self.assertEquals(f5.func_code.co_varnames, + self.assertEquals(f5.__code__.co_varnames, ('(compound, first)', 'two', 'compound', 'first')) else: - self.assertEquals(f4.func_code.co_varnames, + self.assertEquals(f4.__code__.co_varnames, ('two', '.1', 'compound', 'argument', 'list')) - self.assertEquals(f5.func_code.co_varnames, + self.assertEquals(f5.__code__.co_varnames, ('.0', 'two', 'compound', 'first')) def a1(one_arg,): pass def a2(two, args,): pass @@ -209,9 +209,9 @@ class GrammarTests(unittest.TestCase): # ceval unpacks the formal arguments into the first argcount names; # thus, the names nested inside tuples must appear after these names. if sys.platform.startswith('java'): - self.assertEquals(v3.func_code.co_varnames, ('a', '(b, c)', 'rest', 'b', 'c')) + self.assertEquals(v3.__code__.co_varnames, ('a', '(b, c)', 'rest', 'b', 'c')) else: - self.assertEquals(v3.func_code.co_varnames, ('a', '.1', 'rest', 'b', 'c')) + self.assertEquals(v3.__code__.co_varnames, ('a', '.1', 'rest', 'b', 'c')) self.assertEquals(v3(1, (2, 3), 4), (1, 2, 3, (4,))) def d01(a=1): pass d01() @@ -302,23 +302,23 @@ class GrammarTests(unittest.TestCase): # argument annotation tests def f(x) -> list: pass - self.assertEquals(f.func_annotations, {'return': list}) + self.assertEquals(f.__annotations__, {'return': list}) def f(x:int): pass - self.assertEquals(f.func_annotations, {'x': int}) + self.assertEquals(f.__annotations__, {'x': int}) def f(*x:str): pass - self.assertEquals(f.func_annotations, {'x': str}) + self.assertEquals(f.__annotations__, {'x': str}) def f(**x:float): pass - self.assertEquals(f.func_annotations, {'x': float}) + self.assertEquals(f.__annotations__, {'x': float}) def f(x, y:1+2): pass - self.assertEquals(f.func_annotations, {'y': 3}) + self.assertEquals(f.__annotations__, {'y': 3}) def f(a, (b:1, c:2, d)): pass - self.assertEquals(f.func_annotations, {'b': 1, 'c': 2}) + self.assertEquals(f.__annotations__, {'b': 1, 'c': 2}) def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6): pass - self.assertEquals(f.func_annotations, + self.assertEquals(f.__annotations__, {'b': 1, 'c': 2, 'e': 3, 'g': 6}) def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6, h:7, i=8, j:9=10, **k:11) -> 12: pass - self.assertEquals(f.func_annotations, + self.assertEquals(f.__annotations__, {'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9, 'k': 11, 'return': 12}) diff --git a/Lib/test/test_hotshot.py b/Lib/test/test_hotshot.py index 2751b3f..5480257 100644 --- a/Lib/test/test_hotshot.py +++ b/Lib/test/test_hotshot.py @@ -85,8 +85,8 @@ class HotShotTestCase(unittest.TestCase): x = 1 def g(): f() - f_lineno = f.func_code.co_firstlineno - g_lineno = g.func_code.co_firstlineno + f_lineno = f.__code__.co_firstlineno + g_lineno = g.__code__.co_firstlineno events = [(ENTER, ("test_hotshot", g_lineno, "g")), (LINE, ("test_hotshot", g_lineno+1, "g")), (ENTER, ("test_hotshot", f_lineno, "f")), diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 296e259..5e03218 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -53,7 +53,7 @@ class TestPredicates(IsTestBase): self.istest(inspect.isbuiltin, 'sys.exit') self.istest(inspect.isbuiltin, '[].append') self.istest(inspect.isclass, 'mod.StupidGit') - self.istest(inspect.iscode, 'mod.spam.func_code') + self.istest(inspect.iscode, 'mod.spam.__code__') self.istest(inspect.isframe, 'tb.tb_frame') self.istest(inspect.isfunction, 'mod.spam') self.istest(inspect.ismethod, 'mod.StupidGit.abuse') @@ -210,7 +210,7 @@ class TestRetrievingSourceCode(GetSourceBase): m.__file__ = "<string>" # hopefully not a real filename... m.__loader__ = "dummy" # pretend the filename is understood by a loader exec("def x(): pass", m.__dict__) - self.assertEqual(inspect.getsourcefile(m.x.func_code), '<string>') + self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>') del sys.modules[name] inspect.getmodule(compile('a=10','','single')) diff --git a/Lib/test/test_keywordonlyarg.py b/Lib/test/test_keywordonlyarg.py index 0ace785..2e1f8bd 100644 --- a/Lib/test/test_keywordonlyarg.py +++ b/Lib/test/test_keywordonlyarg.py @@ -135,12 +135,12 @@ class KeywordOnlyArgTestCase(unittest.TestCase): def foo(p1,p2=0, *, k1, k2=0): return p1 + p2 + k1 + k2 - self.assertEquals(2, foo.func_code.co_kwonlyargcount) - self.assertEquals({"k2":0}, foo.func_kwdefaults) - foo.func_kwdefaults = {"k1":0} + self.assertEquals(2, foo.__code__.co_kwonlyargcount) + self.assertEquals({"k2":0}, foo.__kwdefaults__) + foo.__kwdefaults__ = {"k1":0} try: foo(1,k1=10) - self.fail("func_kwdefaults is not properly changed") + self.fail("__kwdefaults__ is not properly changed") except TypeError: pass diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py index 6c98022..9c58c12 100644 --- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -144,7 +144,7 @@ class ExceptionTestCase(unittest.TestCase): class CodeTestCase(unittest.TestCase): def test_code(self): - co = ExceptionTestCase.test_exceptions.func_code + co = ExceptionTestCase.test_exceptions.__code__ new = marshal.loads(marshal.dumps(co)) self.assertEqual(co, new) diff --git a/Lib/test/test_new.py b/Lib/test/test_new.py index e2d26fa..797a8c3 100644 --- a/Lib/test/test_new.py +++ b/Lib/test/test_new.py @@ -79,18 +79,18 @@ class NewTest(unittest.TestCase): return x + y return g g = f(4) - new.function(f.func_code, {}, "blah") - g2 = new.function(g.func_code, {}, "blah", (2,), g.func_closure) + new.function(f.__code__, {}, "blah") + g2 = new.function(g.__code__, {}, "blah", (2,), g.__closure__) self.assertEqual(g2(), 6) - g3 = new.function(g.func_code, {}, "blah", None, g.func_closure) + g3 = new.function(g.__code__, {}, "blah", None, g.__closure__) self.assertEqual(g3(5), 9) def test_closure(func, closure, exc): - self.assertRaises(exc, new.function, func.func_code, {}, "", None, closure) + self.assertRaises(exc, new.function, func.__code__, {}, "", None, closure) test_closure(g, None, TypeError) # invalid closure test_closure(g, (1,), TypeError) # non-cell in closure test_closure(g, (1, 1), ValueError) # closure is wrong size - test_closure(f, g.func_closure, ValueError) # no closure needed + test_closure(f, g.__closure__, ValueError) # no closure needed # Note: Jython will never have new.code() if hasattr(new, 'code'): @@ -98,7 +98,7 @@ class NewTest(unittest.TestCase): # bogus test of new.code() def f(a): pass - c = f.func_code + c = f.__code__ argcount = c.co_argcount kwonlyargcount = c.co_kwonlyargcount nlocals = c.co_nlocals diff --git a/Lib/test/test_profilehooks.py b/Lib/test/test_profilehooks.py index 53f882a..0f5616d 100644 --- a/Lib/test/test_profilehooks.py +++ b/Lib/test/test_profilehooks.py @@ -324,7 +324,7 @@ def ident(function): if hasattr(function, "f_code"): code = function.f_code else: - code = function.func_code + code = function.__code__ return code.co_firstlineno, code.co_name diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py index 478083e..1edda75 100644 --- a/Lib/test/test_pyclbr.py +++ b/Lib/test/test_pyclbr.py @@ -140,7 +140,7 @@ class PyclbrTest(TestCase): if isinstance(item, ClassType): return item.__module__ == module.__name__ if isinstance(item, FunctionType): - return item.func_globals is module.__dict__ + return item.__globals__ is module.__dict__ return False for name in dir(module): item = getattr(module, name) diff --git a/Lib/test/test_scope.py b/Lib/test/test_scope.py index 31e57e5..b9dc711 100644 --- a/Lib/test/test_scope.py +++ b/Lib/test/test_scope.py @@ -518,10 +518,10 @@ self.assert_(X.passed) return lambda: x + 1 g = f(3) - self.assertRaises(TypeError, eval, g.func_code) + self.assertRaises(TypeError, eval, g.__code__) try: - exec(g.func_code, {}) + exec(g.__code__, {}) except TypeError: pass else: diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index 21cba89..0678761 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -54,7 +54,7 @@ def with_warning_restore(func): # Grrr, we need this function to warn every time. Without removing # the warningregistry, running test_tarfile then test_struct would fail # on 64-bit platforms. - globals = func.func_globals + globals = func.__globals__ if '__warningregistry__' in globals: del globals['__warningregistry__'] warnings.filterwarnings("error", r"""^struct.*""", DeprecationWarning) diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index 8b5f73c..6fbb3cc 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -341,7 +341,7 @@ def run_with_locale(catstr, *locales): finally: if locale and orig_locale: locale.setlocale(category, orig_locale) - inner.func_name = func.func_name + inner.__name__ = func.__name__ inner.__doc__ = func.__doc__ return inner return decorator diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 897c6b0..36cca2c 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -230,7 +230,7 @@ class SysModuleTest(unittest.TestCase): self.assertRaises(TypeError, sys._getframe, 42, 42) self.assertRaises(ValueError, sys._getframe, 2000000000) self.assert_( - SysModuleTest.test_getframe.im_func.func_code \ + SysModuleTest.test_getframe.im_func.__code__ \ is sys._getframe().f_code ) diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py index 7b5ac7d..b1778dd 100644 --- a/Lib/test/test_trace.py +++ b/Lib/test/test_trace.py @@ -226,14 +226,14 @@ class TraceTestCase(unittest.TestCase): sys.settrace(tracer.trace) func() sys.settrace(None) - self.compare_events(func.func_code.co_firstlineno, + self.compare_events(func.__code__.co_firstlineno, tracer.events, func.events) def run_test2(self, func): tracer = Tracer() func(tracer.trace) sys.settrace(None) - self.compare_events(func.func_code.co_firstlineno, + self.compare_events(func.__code__.co_firstlineno, tracer.events, func.events) def test_01_basic(self): @@ -313,7 +313,7 @@ class RaisingTraceFuncTestCase(unittest.TestCase): def g(frame, why, extra): if (why == 'line' and - frame.f_lineno == f.func_code.co_firstlineno + 2): + frame.f_lineno == f.__code__.co_firstlineno + 2): raise RuntimeError, "i am crashing" return g @@ -344,7 +344,7 @@ class JumpTracer: self.done = False def trace(self, frame, event, arg): - if not self.done and frame.f_code == self.function.func_code: + if not self.done and frame.f_code == self.function.__code__: firstLine = frame.f_code.co_firstlineno if frame.f_lineno == firstLine + self.jumpFrom: # Cope with non-integer self.jumpTo (because of diff --git a/Lib/test/test_univnewlines.py b/Lib/test/test_univnewlines.py index e91bde7..922c184 100644 --- a/Lib/test/test_univnewlines.py +++ b/Lib/test/test_univnewlines.py @@ -83,7 +83,7 @@ class TestGenericUnivNewlines(unittest.TestCase): namespace = {} execfile(test_support.TESTFN, namespace) func = namespace['line3'] - self.assertEqual(func.func_code.co_firstlineno, 3) + self.assertEqual(func.__code__.co_firstlineno, 3) self.assertEqual(namespace['line4'], FATX) diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index eb962d2..16c612e 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -295,7 +295,7 @@ class QuotingTests(unittest.TestCase): def test_default_safe(self): # Test '/' is default value for 'safe' parameter - self.assertEqual(urllib.quote.func_defaults[0], '/') + self.assertEqual(urllib.quote.__defaults__[0], '/') def test_safe(self): # Test setting 'safe' parameter does what it should do diff --git a/Lib/trace.py b/Lib/trace.py index a1f9ade..79d2171 100644 --- a/Lib/trace.py +++ b/Lib/trace.py @@ -532,7 +532,7 @@ class Trace: ## use of gc.get_referrers() was suggested by Michael Hudson # all functions which refer to this code object funcs = [f for f in gc.get_referrers(code) - if hasattr(f, "func_doc")] + if hasattr(f, "__doc__")] # require len(func) == 1 to avoid ambiguity caused by calls to # new.function(): "In the face of ambiguity, refuse the # temptation to guess." diff --git a/Lib/types.py b/Lib/types.py index cc0c1d3..9811646 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -43,7 +43,7 @@ def _f(): pass FunctionType = type(_f) LambdaType = type(lambda: None) # Same as FunctionType try: - CodeType = type(_f.func_code) + CodeType = type(_f.__code__) except RuntimeError: # Execution in restricted environment pass diff --git a/Lib/xreload.py b/Lib/xreload.py index 8d2dfc0..0730be5 100644 --- a/Lib/xreload.py +++ b/Lib/xreload.py @@ -118,8 +118,8 @@ def _update_function(oldfunc, newfunc): """Update a function object.""" oldfunc.__doc__ = newfunc.__doc__ oldfunc.__dict__.update(newfunc.__dict__) - oldfunc.func_code = newfunc.func_code - oldfunc.func_defaults = newfunc.func_defaults + oldfunc.__code__ = newfunc.__code__ + oldfunc.__defaults__ = newfunc.__defaults__ # XXX What else? return oldfunc diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 63bdc21..956cbbc 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -225,11 +225,10 @@ PyFunction_SetAnnotations(PyObject *op, PyObject *annotations) #define OFF(x) offsetof(PyFunctionObject, x) static PyMemberDef func_memberlist[] = { - {"func_closure", T_OBJECT, OFF(func_closure), + {"__closure__", T_OBJECT, OFF(func_closure), RESTRICTED|READONLY}, - {"func_doc", T_OBJECT, OFF(func_doc), WRITE_RESTRICTED}, {"__doc__", T_OBJECT, OFF(func_doc), WRITE_RESTRICTED}, - {"func_globals", T_OBJECT, OFF(func_globals), + {"__globals__", T_OBJECT, OFF(func_globals), RESTRICTED|READONLY}, {"__module__", T_OBJECT, OFF(func_module), WRITE_RESTRICTED}, {NULL} /* Sentinel */ @@ -306,7 +305,7 @@ func_set_code(PyFunctionObject *op, PyObject *value) * other than a code object. */ if (value == NULL || !PyCode_Check(value)) { PyErr_SetString(PyExc_TypeError, - "func_code must be set to a code object"); + "__code__ must be set to a code object"); return -1; } nfree = PyCode_GetNumFree((PyCodeObject *)value); @@ -345,7 +344,7 @@ func_set_name(PyFunctionObject *op, PyObject *value) * other than a string object. */ if (value == NULL || !PyString_Check(value)) { PyErr_SetString(PyExc_TypeError, - "func_name must be set to a string object"); + "__name__ must be set to a string object"); return -1; } tmp = op->func_name; @@ -381,7 +380,7 @@ func_set_defaults(PyFunctionObject *op, PyObject *value) value = NULL; if (value != NULL && !PyTuple_Check(value)) { PyErr_SetString(PyExc_TypeError, - "func_defaults must be set to a tuple object"); + "__defaults__ must be set to a tuple object"); return -1; } tmp = op->func_defaults; @@ -418,7 +417,7 @@ func_set_kwdefaults(PyFunctionObject *op, PyObject *value) * Can only set func_kwdefaults to NULL or a dict. */ if (value != NULL && !PyDict_Check(value)) { PyErr_SetString(PyExc_TypeError, - "func_kwdefaults must be set to a dict object"); + "__kwdefaults__ must be set to a dict object"); return -1; } tmp = op->func_kwdefaults; @@ -452,7 +451,7 @@ func_set_annotations(PyFunctionObject *op, PyObject *value) * or a dict. */ if (value != NULL && !PyDict_Check(value)) { PyErr_SetString(PyExc_TypeError, - "func_annotations must be set to a dict object"); + "__annotations__ must be set to a dict object"); return -1; } tmp = op->func_annotations; @@ -463,16 +462,14 @@ func_set_annotations(PyFunctionObject *op, PyObject *value) } static PyGetSetDef func_getsetlist[] = { - {"func_code", (getter)func_get_code, (setter)func_set_code}, - {"func_defaults", (getter)func_get_defaults, + {"__code__", (getter)func_get_code, (setter)func_set_code}, + {"__defaults__", (getter)func_get_defaults, (setter)func_set_defaults}, - {"func_kwdefaults", (getter)func_get_kwdefaults, + {"__kwdefaults__", (getter)func_get_kwdefaults, (setter)func_set_kwdefaults}, - {"func_annotations", (getter)func_get_annotations, + {"__annotations__", (getter)func_get_annotations, (setter)func_set_annotations}, - {"func_dict", (getter)func_get_dict, (setter)func_set_dict}, {"__dict__", (getter)func_get_dict, (setter)func_set_dict}, - {"func_name", (getter)func_get_name, (setter)func_set_name}, {"__name__", (getter)func_get_name, (setter)func_set_name}, {NULL} /* Sentinel */ }; |