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
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to