Eric
Eric

Reputation: 97691

Why do imports not work when creating custom module classes?

I have this module, wat.py

import re
import types
import sys

hello = "Hello World"

class MyModule(types.ModuleType):
    def get_re(self):
        return re
    def get_hello(self):
        return hello


sys.modules[__name__] = MyModule('wat')

And I run this code:

>>> import wat
>>> wat.get_hello()
None
>>> wat.get_re()
None

Why does this not work?

Upvotes: 1

Views: 203

Answers (3)

martineau
martineau

Reputation: 123531

It doesn't work because you effectively deleted your module when you reassigned its entry in sys.modules. See my related question.

To make it work, change the last line of your module to:

_ref, sys.modules[__name__] = sys.modules[__name__], MyModule('wat')

and it will work.

BTW, you don't have to derive your class from types.ModuleType in order to put instances of it in sys.modules[]. Entries in sys.modules don't have to be module objects (according to Alex Martelli).

Upvotes: 1

root
root

Reputation: 80456

Not sure what you mean by "doesn't play well with imports" as this seems to work also. Not sure if thats what you want but maybe it's useful...

    import sys
    import re
    class _Test(object):
      def __init__(self):
          self.re=re
      def testfunc(self):
          return self.re
      y = property(testfunc)
    sys.modules[__name__] = _Test()

import calltest

>>> calltest.y
<module 're' from 'C:\Python26\lib\re.pyc'>
>>> calltest.re
<module 're' from 'C:\Python26\lib\re.pyc'>
>>> calltest.testfunc()
<module 're' from 'C:\Python26\lib\re.pyc'>

EDIT:

If you simply try to return re you will get None. You have to import re after you do

sys.modules[__name__] = _Test()

like:

sys.modules[__name__] = _Test()
import re

then simply calling re woudld work.

Upvotes: 1

Eric
Eric

Reputation: 97691

This code makes it work:

import types
import sys

def whyDoesThisWorkIDontEven():
    import re
    hello = "Hello World"

    class MyModule(types.ModuleType):
        def get_re(self):
            return re
        def get_hello(self):
            return hello

    return MyModule('wat')

sys.modules[__name__] = whyDoesThisWorkIDontEven()

But I have absolutely no idea why.

Upvotes: 1

Related Questions