Improved nestedmodule decorator implementation
Gregory Ewing
greg.ewing at canterbury.ac.nz
Tue Jul 5 05:31:52 EDT 2016
I wrote:
> The only shortcoming I can think of is that a nestedmodule
> inside another nestedmodule won't be able to see the names
> in the outer nestedmodule
Actually, that's not correct -- the version I posted before
actually crashes if you try to refer to a name in an outer
nestedmodule from an inner nestedmodule.
Here's an improved version that fully supports nesting to
any depth.
% python3 test_nested_nested.py
foo
blarg
#------------------------------------------
#
# test_nested_nested.py
#
#------------------------------------------
from nestedmodule import nestedmodule
@nestedmodule
def m1():
def foo():
print("foo")
@nestedmodule
def m2():
def blarg():
foo()
print("blarg")
m1.m2.blarg()
#------------------------------------------
#
# nestedmodule.py
#
#------------------------------------------
from types import CodeType, FunctionType, ModuleType
from dis import dis
def hack_code(f):
"""Hack 'return locals()' onto the end of the bytecode of f."""
code1 = f.__code__
bytes1 = code1.co_code
names1 = code1.co_names
n = len(names1)
names2 = names1 + ('locals',)
bytes2 = bytes1[:-4] + bytes([116, n, 0, 131, 0, 0, 83])
code2 = CodeType(code1.co_argcount, code1.co_kwonlyargcount, code1.co_nlocals,
code1.co_stacksize, code1.co_flags, bytes2, code1.co_consts, names2,
code1.co_varnames, code1.co_filename, code1.co_name, code1.co_firstlineno,
code1.co_lnotab, code1.co_freevars, code1.co_cellvars)
f2 = FunctionType(code2, f.__globals__, f.__name__, f.__kwdefaults__,
f.__closure__)
return f2
def nestedmodule(f):
f2 = hack_code(f)
l = f2()
m = ModuleType(f.__name__)
m.__dict__.update(l)
return m
More information about the Python-list
mailing list