LEFT | RIGHT |
1 # -*- coding: iso-8859-1 -*- | 1 # -*- coding: iso-8859-1 -*- |
2 """Get useful information from live Python objects. | 2 """Get useful information from live Python objects. |
3 | 3 |
4 This module encapsulates the interface provided by the internal special | 4 This module encapsulates the interface provided by the internal special |
5 attributes (func_*, co_*, im_*, tb_*, etc.) in a friendlier fashion. | 5 attributes (func_*, co_*, im_*, tb_*, etc.) in a friendlier fashion. |
6 It also provides some help for examining source code and class layout. | 6 It also provides some help for examining source code and class layout. |
7 | 7 |
8 Here are some of the useful functions provided by this module: | 8 Here are some of the useful functions provided by this module: |
9 | 9 |
10 ismodule(), isclass(), ismethod(), isfunction(), isgeneratorfunction(), | 10 ismodule(), isclass(), ismethod(), isfunction(), isgeneratorfunction(), |
(...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 # implicit 'self' (or 'cls' for classmethods) argument | 920 # implicit 'self' (or 'cls' for classmethods) argument |
921 if func.im_self is not None: | 921 if func.im_self is not None: |
922 positional = (func.im_self,) + positional | 922 positional = (func.im_self,) + positional |
923 elif not positional or not isinstance(positional[0], func.im_class): | 923 elif not positional or not isinstance(positional[0], func.im_class): |
924 got = ('%s instance' % type(positional[0]).__name__ if positional | 924 got = ('%s instance' % type(positional[0]).__name__ if positional |
925 else 'nothing') | 925 else 'nothing') |
926 raise TypeError('unbound method %s() must be called with %s ' | 926 raise TypeError('unbound method %s() must be called with %s ' |
927 'instance as first argument (got %s instead)' % | 927 'instance as first argument (got %s instead)' % |
928 (f_name, func.im_class.__name__, got)) | 928 (f_name, func.im_class.__name__, got)) |
929 num_pos = len(positional) | 929 num_pos = len(positional) |
930 has_named = bool(named) | 930 num_total = num_pos + len(named) |
931 num_args = len(args) | 931 num_args = len(args) |
932 num_defaults = len(defaults) if defaults else 0 | 932 num_defaults = len(defaults) if defaults else 0 |
933 for arg, value in zip(args, positional): | 933 for arg, value in zip(args, positional): |
934 assign(arg, value) | 934 assign(arg, value) |
935 if varargs: | 935 if varargs: |
936 if num_pos > num_args: | 936 if num_pos > num_args: |
937 assign(varargs, positional[-(num_pos-num_args):]) | 937 assign(varargs, positional[-(num_pos-num_args):]) |
938 else: | 938 else: |
939 assign(varargs, ()) | 939 assign(varargs, ()) |
940 elif 0 < num_args < num_pos: | 940 elif 0 < num_args < num_pos: |
941 raise TypeError('%s() takes %s %d %s%s (%d given)' % ( | 941 raise TypeError('%s() takes %s %d %s (%d given)' % ( |
942 f_name, 'at most' if defaults else 'exactly', num_args, | 942 f_name, 'at most' if defaults else 'exactly', num_args, |
943 'non-keyword ' if has_named else '', | 943 'arguments' if num_args>1 else 'argument', num_total)) |
944 'arguments' if num_args>1 else 'argument', num_pos)) | 944 elif num_args == 0 and num_total: |
945 elif num_args == 0 and (num_pos or has_named): | 945 raise TypeError('%s() takes no arguments (%d given)' % (f_name, num_tota
l)) |
946 raise TypeError('%s() takes no arguments (%d given)' % | |
947 (f_name, num_pos + len(named))) | |
948 for arg in args: | 946 for arg in args: |
949 if isinstance(arg, str) and arg in named: | 947 if isinstance(arg, str) and arg in named: |
950 if is_assigned(arg): | 948 if is_assigned(arg): |
951 raise TypeError("%s() got multiple values for keyword " | 949 raise TypeError("%s() got multiple values for keyword " |
952 "argument '%s'" % (f_name, arg)) | 950 "argument '%s'" % (f_name, arg)) |
953 else: | 951 else: |
954 assign(arg, named.pop(arg)) | 952 assign(arg, named.pop(arg)) |
955 if defaults: # fill in any missing values with the defaults | 953 if defaults: # fill in any missing values with the defaults |
956 for arg, value in zip(args[-num_defaults:], defaults): | 954 for arg, value in zip(args[-num_defaults:], defaults): |
957 if not is_assigned(arg): | 955 if not is_assigned(arg): |
958 assign(arg, value) | 956 assign(arg, value) |
959 if varkw: | 957 if varkw: |
960 assign(varkw, named) | 958 assign(varkw, named) |
961 elif named: | 959 elif named: |
962 unexpected = next(iter(named)) | 960 unexpected = next(iter(named)) |
963 if isinstance(unexpected, unicode): | 961 if isinstance(unexpected, unicode): |
964 unexpected = unexpected.encode(sys.getdefaultencoding(), 'replace') | 962 unexpected = unexpected.encode(sys.getdefaultencoding(), 'replace') |
965 raise TypeError("%s() got an unexpected keyword argument '%s'" % | 963 raise TypeError("%s() got an unexpected keyword argument '%s'" % |
966 (f_name, unexpected)) | 964 (f_name, unexpected)) |
967 unassigned = num_args - len([arg for arg in args if is_assigned(arg)]) | 965 unassigned = num_args - len([arg for arg in args if is_assigned(arg)]) |
968 if unassigned: | 966 if unassigned: |
969 num_required = num_args - num_defaults | 967 num_required = num_args - num_defaults |
970 raise TypeError('%s() takes %s %d %s%s (%d given)' % ( | 968 raise TypeError('%s() takes %s %d %s (%d given)' % ( |
971 f_name, 'at least' if defaults else 'exactly', num_required, | 969 f_name, 'at least' if defaults else 'exactly', num_required, |
972 'non-keyword ' if has_named else '', | 970 'arguments' if num_required>1 else 'argument', num_total)) |
973 'arguments' if num_required>1 else 'argument', num_required-unassign
ed)) | |
974 return arg2value | 971 return arg2value |
975 | 972 |
976 # -------------------------------------------------- stack frame extraction | 973 # -------------------------------------------------- stack frame extraction |
977 | 974 |
978 Traceback = namedtuple('Traceback', 'filename lineno function code_context index
') | 975 Traceback = namedtuple('Traceback', 'filename lineno function code_context index
') |
979 | 976 |
980 def getframeinfo(frame, context=1): | 977 def getframeinfo(frame, context=1): |
981 """Get information about a frame or traceback object. | 978 """Get information about a frame or traceback object. |
982 | 979 |
983 A tuple of five things is returned: the filename, the line number of | 980 A tuple of five things is returned: the filename, the line number of |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1042 else: | 1039 else: |
1043 currentframe = lambda _=None: None | 1040 currentframe = lambda _=None: None |
1044 | 1041 |
1045 def stack(context=1): | 1042 def stack(context=1): |
1046 """Return a list of records for the stack above the caller's frame.""" | 1043 """Return a list of records for the stack above the caller's frame.""" |
1047 return getouterframes(sys._getframe(1), context) | 1044 return getouterframes(sys._getframe(1), context) |
1048 | 1045 |
1049 def trace(context=1): | 1046 def trace(context=1): |
1050 """Return a list of records for the stack below the current exception.""" | 1047 """Return a list of records for the stack below the current exception.""" |
1051 return getinnerframes(sys.exc_info()[2], context) | 1048 return getinnerframes(sys.exc_info()[2], context) |
LEFT | RIGHT |