Masquerading real module of a class

python

Solution

try:

B.__module__= 'a'

Incidentally you probably want an absolute import:

from a._b import *

as relative imports without the new explicit dot syntax are going away (see PEP 328).

ETA re comment:

I would have to set the module explicitly for every class

Yes, I don't think there's a way around that but you could at least automate it, at the end of `__init__`:

for value in globals().values():
    if inspect.isclass(value) and value.__module__.startswith('a.'):
        value.__module__= 'a'

(For new-style classes only you could get away with `isinstance(value, type)` instead of `inspect`. If the module doesn't have to run as `__main__` you could use `__name__` instead of hard-coding `'a'`.)

Problem

Suppose you have the following layout for a python package ``` ./a ./a/__init__.py ./a/_b.py ``` inside `__init__.py` you have ``` from _b import * ``` and inside _b.py you have ``` class B(object): pass ``` If you import from interactive prompt ``` >>> import a >>> a.B <class 'a._b.B'> >>> ``` How can I completely hide the existence of _b ? The problem I am trying to solve is the following: I want a facade package importing "hidden" modules and classes. The classes available from the facade (in my case `a`) are kept stable and guaranteed for the future. I want, however, freedom to relocate classes "under the hood", hence the hidden modules. This is all nice, but if some client code pickles an object provided by the facade, this pickled data will refer to the hidden module nesting, not to the facade nesting. In other words, if I reposition the `B` class in a module `_c.py`, client codes will not be able to unpickle because the pickled classes are referring to `a._b.B`, which has been moved. If they referred to `a.B`, I could relocate the B class as much as I want under the hood, without ruining pickled data.

Original source