[Python-ideas] Function-like Modules (better control/introspection)

Nick Coghlan ncoghlan at gmail.com
Mon Mar 17 17:36:31 CET 2014


On 18 Mar 2014 01:59, "C Anthony Risinger" <anthony at xtfx.me> wrote:
>
> ok, let me try this again, sans distractions:
>
> could we consider adding __code__ and __call__ to module objects?
__code__ would contain the code executed in the module __dict__, and
__call__ would reload the module.
>
> thoughts?

The question to ask is: what would such a change make possible that
importlib doesn't already handle?

This specific proposal wouldn't work right for extension modules, so people
will still need to go through the importlib APIs anyway. If you haven't
seen it yet, you may also want to give PEP 451 a read - we already
overhauled several aspects of the import system for 3.4.

Cheers,
Nick.

>
> --
>
> C Anthony
>
>
> On Fri, Mar 14, 2014 at 4:03 PM, C Anthony Risinger <anthony at xtfx.me>
wrote:
>>
>> hello,
>>
>> could we make modules work more like this...
>>
>> https://gist.github.com/xtfxme/9556806
>>
>> tl;dr: __code__ object available (potentially a __self__ object), reload
by calling, makes working with modules more natural/safe!
>>
>> ENCLOSED: modules-next.py
>>
>> --
>>
>> C Anthony
>>
>>
#----------------------------------------------------------------------------------------(
modules-next.py )
>> # encoding: utf-8
>> #
>> # modules-next
>> #
>> # C Anthony Risinger
>>
>>
>> import sys
>>
>>
>> m_name = 'modules_next'
>> m_source = r"""\
>> if __name__ == '{0}':
>>     from . import __call__ as reexec
>>     from . import __code__ as code
>>     from . import __dict__ as ns
>>     print('>>> {{0}}: {{1}}\n{{2}}\n'.format(__name__, code, ns.keys()))
>>     __name__ = 'modules_next_reloaded'
>>     reexec()
>>     print('>>> {{0}}: {{1}}\n{{2}}\n'.format(__name__, code, ns.keys()))
>> else:
>>     print('!!! __name__ == {{0}}\n'.format(__name__))
>>
>> def throw():
>>     raise Exception(__name__)
>> """.format(m_name)
>> m_code = compile(m_source, m_name, 'exec')
>> m_dict = {
>>     '__file__': __file__ + '.next',
>>     '__name__': m_name,
>>     '__path__': list(),
>>     '__doc__': None,
>>     }
>> #...bind namespace/functions
>> module = eval('lambda: None', m_dict)
>> #...automatically expose as attributes
>> module.__dict__ = module.__globals__
>> #...must be set twice, __code__ sees __dict__, but we see descriptor
>> module.__name__ = m_name
>> #...redefine the function body!
>> module.__code__ = m_code
>> #...yay! we haz legitimate module!
>> sys.modules[m_name] = module
>>
>>
>> print('--* importing...')
>> import modules_next
>> print('>>> {0}: {1}\n{2}\n'.format(
>>     __name__,
>>     modules_next.__code__,
>>     modules_next.__dict__.keys(),
>>     ))
>>
>> print('--* importing (for real this time)...')
>> #...import/reload by calling our func-y-module
>> module()
>> print('>>> {0}: {1}\n{2}\n'.format(
>>     __name__,
>>     modules_next.__code__,
>>     modules_next.__dict__.keys(),
>>     ))
>>
>>
>> print('--* throwing...')
>> modules_next.throw()
>
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140318/258b5334/attachment.html>


More information about the Python-ideas mailing list