12345678910111213141516171819202122232425262728293031323334353637383940414243444546 |
- """
- Python introspection helpers.
- """
-
- from types import CodeType as code, FunctionType as function
-
-
- def copycode(template, changes):
- if hasattr(code, "replace"):
- return template.replace(**{"co_" + k : v for k, v in changes.items()})
- names = [
- "argcount", "nlocals", "stacksize", "flags", "code", "consts",
- "names", "varnames", "filename", "name", "firstlineno", "lnotab",
- "freevars", "cellvars"
- ]
- if hasattr(code, "co_kwonlyargcount"):
- names.insert(1, "kwonlyargcount")
- if hasattr(code, "co_posonlyargcount"):
- # PEP 570 added "positional only arguments"
- names.insert(1, "posonlyargcount")
- values = [
- changes.get(name, getattr(template, "co_" + name))
- for name in names
- ]
- return code(*values)
-
-
- def copyfunction(template, funcchanges, codechanges):
- names = [
- "globals", "name", "defaults", "closure",
- ]
- values = [
- funcchanges.get(name, getattr(template, "__" + name + "__"))
- for name in names
- ]
- return function(copycode(template.__code__, codechanges), *values)
-
-
- def preserveName(f):
- """
- Preserve the name of the given function on the decorated function.
- """
- def decorator(decorated):
- return copyfunction(decorated,
- dict(name=f.__name__), dict(name=f.__name__))
- return decorator
|