Search code examples
pythonpython-module

Extending __all__. How can I take module __all__ list?


I want to do something like this?

# __init__.py
import a_module

__all__ = [
    'a_module',
]

__all__.extend(a_module.__all__)  # it doesn't work
# AttributeError: 'module' object has no attribute '__all__'

Is there a way to do that?


Solution

  • UPDATE: I don't see why you just don't:

    from a_module import *
    

    ...if all you want to do is re-publish everything a_module publishes... This is even a case where the PEP8 "sanctions" the use of the star import, which it normally discourages.

    ...now if the above solution is not what works for you, here's more or less a hand-written equivalent:

    dir() should give you the list of attributes in an object (incl. a module):

    __all__.extend(dir(a_module))
    

    If you'd like to filter out the stuff starting with __ and _, just:

    __all__.extend(x for x in dir(a_module) if not x.startswith('_'))
    

    This should work regardless of whether the module has declared __all__ or not.

    And, to fully mimic Python's default behavior of considering all non-underscore-prefixed things in a module as public, unless __all__ is declared:

    __all__.extend((x for x in dir(a_module) if not x.startswith('_'))
                   if not hasattr(a_module, '__all__')
                   else a_module.__all__)