Changeset 391 for python/trunk/Lib/inspect.py
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Lib/inspect.py
r2 r391 18 18 getclasstree() - arrange classes so as to represent their hierarchy 19 19 20 getargspec(), getargvalues() - get info about function arguments20 getargspec(), getargvalues(), getcallargs() - get info about function arguments 21 21 formatargspec(), formatargvalues() - format an argument spec 22 22 getouterframes(), getinnerframes() - get info about frames … … 63 63 __doc__ documentation string 64 64 __module__ name of module in which this class was defined""" 65 return isinstance(object, types.ClassType) or hasattr(object, '__bases__')65 return isinstance(object, (type, types.ClassType)) 66 66 67 67 def ismethod(object): … … 158 158 Generator function objects provides same attributes as functions. 159 159 160 See isfunction.__doc__for attributes listing."""160 See help(isfunction) for attributes listing.""" 161 161 return bool((isfunction(object) or ismethod(object)) and 162 162 object.func_code.co_flags & CO_GENERATOR) … … 166 166 167 167 Generator objects provide these attributes: 168 __iter__ defined to support i nteration over container168 __iter__ defined to support iteration over container 169 169 close raises a new GeneratorExit exception inside the 170 170 generator to terminate the iteration … … 243 243 def isabstract(object): 244 244 """Return true if the object is an abstract base class (ABC).""" 245 return isinstance(object, type) and object.__flags__ & TPFLAGS_IS_ABSTRACT245 return bool(isinstance(object, type) and object.__flags__ & TPFLAGS_IS_ABSTRACT) 246 246 247 247 def getmembers(object, predicate=None): … … 250 250 results = [] 251 251 for key in dir(object): 252 value = getattr(object, key) 252 try: 253 value = getattr(object, key) 254 except AttributeError: 255 continue 253 256 if not predicate or predicate(value): 254 257 results.append((key, value)) … … 286 289 result = [] 287 290 for name in names: 288 # Get the object associated with the name .291 # Get the object associated with the name, and where it was defined. 289 292 # Getting an obj from the __dict__ sometimes reveals more than 290 293 # using getattr. Static and class methods are dramatic examples. 291 if name in cls.__dict__: 292 obj = cls.__dict__[name] 294 # Furthermore, some objects may raise an Exception when fetched with 295 # getattr(). This is the case with some descriptors (bug #1785). 296 # Thus, we only use getattr() as a last resort. 297 homecls = None 298 for base in (cls,) + mro: 299 if name in base.__dict__: 300 obj = base.__dict__[name] 301 homecls = base 302 break 293 303 else: 294 304 obj = getattr(cls, name) 295 296 # Figure out where it was defined. 297 homecls = getattr(obj, "__objclass__", None) 298 if homecls is None: 299 # search the dicts. 300 for base in mro: 301 if name in base.__dict__: 302 homecls = base 303 break 304 305 # Get the object again, in order to get it from the defining 306 # __dict__ instead of via getattr (if possible). 307 if homecls is not None and name in homecls.__dict__: 308 obj = homecls.__dict__[name] 309 310 # Also get the object via getattr. 311 obj_via_getattr = getattr(cls, name) 305 homecls = getattr(obj, "__objclass__", homecls) 312 306 313 307 # Classify the object. … … 318 312 elif isinstance(obj, property): 319 313 kind = "property" 320 elif (ismethod(obj_via_getattr) or 321 ismethoddescriptor(obj_via_getattr)): 314 elif ismethoddescriptor(obj): 322 315 kind = "method" 316 elif isdatadescriptor(obj): 317 kind = "data" 323 318 else: 324 kind = "data" 319 obj_via_getattr = getattr(cls, name) 320 if (ismethod(obj_via_getattr) or 321 ismethoddescriptor(obj_via_getattr)): 322 kind = "method" 323 else: 324 kind = "data" 325 obj = obj_via_getattr 325 326 326 327 result.append(Attribute(name, kind, homecls, obj)) … … 400 401 if hasattr(object, '__file__'): 401 402 return object.__file__ 402 raise TypeError(' arg is a built-in module')403 raise TypeError('{!r} is a built-in module'.format(object)) 403 404 if isclass(object): 404 405 object = sys.modules.get(object.__module__) 405 406 if hasattr(object, '__file__'): 406 407 return object.__file__ 407 raise TypeError(' arg is a built-in class')408 raise TypeError('{!r} is a built-in class'.format(object)) 408 409 if ismethod(object): 409 410 object = object.im_func … … 416 417 if iscode(object): 417 418 return object.co_filename 418 raise TypeError(' argis not a module, class, method, '419 'function, traceback, frame, or code object' )419 raise TypeError('{!r} is not a module, class, method, ' 420 'function, traceback, frame, or code object'.format(object)) 420 421 421 422 ModuleInfo = namedtuple('ModuleInfo', 'name suffix mode module_type') … … 438 439 439 440 def getsourcefile(object): 440 """Return the Python source file an object was defined in, if it exists.""" 441 """Return the filename that can be used to locate an object's source. 442 Return None if no way can be identified to get the source. 443 """ 441 444 filename = getfile(object) 442 445 if string.lower(filename[-4:]) in ('.pyc', '.pyo'): … … 450 453 # only return a non-existent filename if the module has a PEP 302 loader 451 454 if hasattr(getmodule(object, filename), '__loader__'): 455 return filename 456 # or it is in the linecache 457 if filename in linecache.cache: 452 458 return filename 453 459 … … 517 523 in the file and the line number indexes a line in that list. An IOError 518 524 is raised if the source code cannot be retrieved.""" 519 file = getsourcefile(object) or getfile(object) 525 526 file = getfile(object) 527 sourcefile = getsourcefile(object) 528 if not sourcefile and file[:1] + file[-1:] != '<>': 529 raise IOError('source code not available') 530 file = sourcefile if sourcefile else file 531 520 532 module = getmodule(object, file) 521 533 if module: … … 717 729 if not parent in children: 718 730 children[parent] = [] 719 children[parent].append(c) 731 if c not in children[parent]: 732 children[parent].append(c) 720 733 if unique and parent in classes: break 721 734 elif c not in roots: … … 737 750 738 751 if not iscode(co): 739 raise TypeError(' arg is not a code object')752 raise TypeError('{!r} is not a code object'.format(co)) 740 753 741 754 nargs = co.co_argcount … … 801 814 func = func.im_func 802 815 if not isfunction(func): 803 raise TypeError(' arg is not a Python function')816 raise TypeError('{!r} is not a Python function'.format(func)) 804 817 args, varargs, varkw = getargs(func.func_code) 805 818 return ArgSpec(args, varargs, varkw, func.func_defaults) … … 845 858 if defaults: 846 859 firstdefault = len(args) - len(defaults) 847 for i in range(len(args)):848 spec = strseq(arg s[i], formatarg, join)860 for i, arg in enumerate(args): 861 spec = strseq(arg, formatarg, join) 849 862 if defaults and i >= firstdefault: 850 863 spec = spec + formatvalue(defaults[i - firstdefault]) … … 880 893 return '(' + string.join(specs, ', ') + ')' 881 894 895 def getcallargs(func, *positional, **named): 896 """Get the mapping of arguments to values. 897 898 A dict is returned, with keys the function argument names (including the 899 names of the * and ** arguments, if any), and values the respective bound 900 values from 'positional' and 'named'.""" 901 args, varargs, varkw, defaults = getargspec(func) 902 f_name = func.__name__ 903 arg2value = {} 904 905 # The following closures are basically because of tuple parameter unpacking. 906 assigned_tuple_params = [] 907 def assign(arg, value): 908 if isinstance(arg, str): 909 arg2value[arg] = value 910 else: 911 assigned_tuple_params.append(arg) 912 value = iter(value) 913 for i, subarg in enumerate(arg): 914 try: 915 subvalue = next(value) 916 except StopIteration: 917 raise ValueError('need more than %d %s to unpack' % 918 (i, 'values' if i > 1 else 'value')) 919 assign(subarg,subvalue) 920 try: 921 next(value) 922 except StopIteration: 923 pass 924 else: 925 raise ValueError('too many values to unpack') 926 def is_assigned(arg): 927 if isinstance(arg,str): 928 return arg in arg2value 929 return arg in assigned_tuple_params 930 if ismethod(func) and func.im_self is not None: 931 # implicit 'self' (or 'cls' for classmethods) argument 932 positional = (func.im_self,) + positional 933 num_pos = len(positional) 934 num_total = num_pos + len(named) 935 num_args = len(args) 936 num_defaults = len(defaults) if defaults else 0 937 for arg, value in zip(args, positional): 938 assign(arg, value) 939 if varargs: 940 if num_pos > num_args: 941 assign(varargs, positional[-(num_pos-num_args):]) 942 else: 943 assign(varargs, ()) 944 elif 0 < num_args < num_pos: 945 raise TypeError('%s() takes %s %d %s (%d given)' % ( 946 f_name, 'at most' if defaults else 'exactly', num_args, 947 'arguments' if num_args > 1 else 'argument', num_total)) 948 elif num_args == 0 and num_total: 949 if varkw: 950 if num_pos: 951 # XXX: We should use num_pos, but Python also uses num_total: 952 raise TypeError('%s() takes exactly 0 arguments ' 953 '(%d given)' % (f_name, num_total)) 954 else: 955 raise TypeError('%s() takes no arguments (%d given)' % 956 (f_name, num_total)) 957 for arg in args: 958 if isinstance(arg, str) and arg in named: 959 if is_assigned(arg): 960 raise TypeError("%s() got multiple values for keyword " 961 "argument '%s'" % (f_name, arg)) 962 else: 963 assign(arg, named.pop(arg)) 964 if defaults: # fill in any missing values with the defaults 965 for arg, value in zip(args[-num_defaults:], defaults): 966 if not is_assigned(arg): 967 assign(arg, value) 968 if varkw: 969 assign(varkw, named) 970 elif named: 971 unexpected = next(iter(named)) 972 if isinstance(unexpected, unicode): 973 unexpected = unexpected.encode(sys.getdefaultencoding(), 'replace') 974 raise TypeError("%s() got an unexpected keyword argument '%s'" % 975 (f_name, unexpected)) 976 unassigned = num_args - len([arg for arg in args if is_assigned(arg)]) 977 if unassigned: 978 num_required = num_args - num_defaults 979 raise TypeError('%s() takes %s %d %s (%d given)' % ( 980 f_name, 'at least' if defaults else 'exactly', num_required, 981 'arguments' if num_required > 1 else 'argument', num_total)) 982 return arg2value 983 882 984 # -------------------------------------------------- stack frame extraction 883 985 … … 898 1000 lineno = frame.f_lineno 899 1001 if not isframe(frame): 900 raise TypeError(' arg is not a frame or traceback object')1002 raise TypeError('{!r} is not a frame or traceback object'.format(frame)) 901 1003 902 1004 filename = getsourcefile(frame) or getfile(frame)
Note:
See TracChangeset
for help on using the changeset viewer.