From e896acc98c2e41dcc8db926964bdc9146ab373fe Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Fri, 11 Jan 2008 03:04:50 +0000 Subject: [PATCH] Let most inspect functions return named tuples --- Lib/inspect.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/Lib/inspect.py b/Lib/inspect.py index 000725ac6b9..8ae50fc2462 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -30,6 +30,7 @@ __date__ = '1 Jan 2001' import sys, os, types, string, re, dis, imp, tokenize, linecache from operator import attrgetter +from collections import namedtuple # ----------------------------------------------------------- type-checking def ismodule(object): @@ -209,6 +210,8 @@ def getmembers(object, predicate=None): results.sort() return results +Attribute = namedtuple('Attribute', 'name kind defining_class object') + def classify_class_attrs(cls): """Return list of attribute-descriptor tuples. @@ -275,7 +278,7 @@ def classify_class_attrs(cls): else: kind = "data" - result.append((name, kind, homecls, obj)) + result.append(Attribute(name, kind, homecls, obj)) return result @@ -363,6 +366,8 @@ def getfile(object): raise TypeError('arg is not a module, class, method, ' 'function, traceback, frame, or code object') +ModuleInfo = namedtuple('ModuleInfo', 'name suffix mode module_type') + def getmoduleinfo(path): """Get the module name, suffix, mode, and module type for a given file.""" filename = os.path.basename(path) @@ -371,7 +376,7 @@ def getmoduleinfo(path): suffixes.sort() # try longest suffixes first, in case they overlap for neglen, suffix, mode, mtype in suffixes: if filename[neglen:] == suffix: - return filename[:neglen], suffix, mode, mtype + return ModuleInfo(filename[:neglen], suffix, mode, mtype) def getmodulename(path): """Return the module name for a given file, or None.""" @@ -669,6 +674,8 @@ def getclasstree(classes, unique=0): # These constants are from Python's compile.h. CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8 +Arguments = namedtuple('Arguments', 'args varargs keywords') + def getargs(co): """Get information about the arguments accepted by a code object. @@ -725,7 +732,9 @@ def getargs(co): varkw = None if co.co_flags & CO_VARKEYWORDS: varkw = co.co_varnames[nargs] - return args, varargs, varkw + return Arguments(args, varargs, varkw) + +ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults') def getargspec(func): """Get the names and default values of a function's arguments. @@ -741,7 +750,9 @@ def getargspec(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 + return ArgSpec(args, varargs, varkw, func.func_defaults) + +ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals') def getargvalues(frame): """Get information about arguments passed into a particular frame. @@ -817,6 +828,9 @@ def formatargvalues(args, varargs, varkw, locals, return '(' + string.join(specs, ', ') + ')' # -------------------------------------------------- stack frame extraction + +Traceback = namedtuple('Traceback', 'filename lineno function code_context index') + def getframeinfo(frame, context=1): """Get information about a frame or traceback object. @@ -848,7 +862,7 @@ def getframeinfo(frame, context=1): else: lines = index = None - return (filename, lineno, frame.f_code.co_name, lines, index) + return Traceback(filename, lineno, frame.f_code.co_name, lines, index) def getlineno(frame): """Get the line number from a frame object, allowing for optimization."""