_introspection.py 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. """
  2. Python introspection helpers.
  3. """
  4. from types import CodeType as code, FunctionType as function
  5. def copycode(template, changes):
  6. names = [
  7. "argcount", "nlocals", "stacksize", "flags", "code", "consts",
  8. "names", "varnames", "filename", "name", "firstlineno", "lnotab",
  9. "freevars", "cellvars"
  10. ]
  11. if str is not bytes:
  12. names.insert(1, "kwonlyargcount")
  13. values = [
  14. changes.get(name, getattr(template, "co_" + name))
  15. for name in names
  16. ]
  17. return code(*values)
  18. def copyfunction(template, funcchanges, codechanges):
  19. names = [
  20. "globals", "name", "defaults", "closure",
  21. ]
  22. values = [
  23. funcchanges.get(name, getattr(template, "__" + name + "__"))
  24. for name in names
  25. ]
  26. return function(copycode(template.__code__, codechanges), *values)
  27. def preserveName(f):
  28. """
  29. Preserve the name of the given function on the decorated function.
  30. """
  31. def decorator(decorated):
  32. return copyfunction(decorated,
  33. dict(name=f.__name__), dict(name=f.__name__))
  34. return decorator