Skip to content
Snippets Groups Projects
Commit 074491ae authored by Piotr Maślanka's avatar Piotr Maślanka
Browse files

v2.2.10

parent 9a35c962
No related branches found
Tags v2.2.10
No related merge requests found
# v2.2.10
* _TBA_
* added [import_from](satella/imports.py)
# v2.2.9
......
Import
======
Sometimes you just have a fairly nested module hierarchy,
and you want to import everything. Don't worry, Satella's got
you covered. Just use this function
.. autofunction:: satella.imports.import_from
An example use would be your module's __init__.py containing
following code:
::
from satella.imports import import_from
__all__ = []
import_from(__path__, __name__, __all__, locals())
In this case, everything will be accessible from this module.
This will examine the __all__ of your submodules, and dir() it
if __all__'s not available. Note that lack of availability of
__all__ will emit a log warning.
......@@ -16,6 +16,7 @@ Welcome to satella's documentation!
exception_handling
json
posix
import
Indices and tables
......
# coding=UTF-8
__version__ = '2.2.10a1'
__version__ = '2.2.10'
import typing as tp
import importlib
import pkgutil
import logging
import os
__all__ = ['import_from']
logger = logging.getLogger(__name__)
def import_from(path: tp.List[str], package_prefix: str, all_: tp.List[str], locals: tp.Dict[str, tp.Any], recursive: bool = True,
fail_on_attributerror: bool = True, add_all: bool = True) -> None:
"""
Import everything from a given module. Append these module's all to.
This will examine __all__ of given module (if it has any, else it will just import everything
from it, which is probably a bad practice and will heavily pollute the namespace.
As a side effect, this will equip all of your packages with __all__.
:param path: module's __path__
:param package_prefix: package prefix to import from. Use __name__
:param all_: module's __all__ to append to
:param recursive: whether to import packages as well
:param fail_on_attributerror: whether to fail if a module reports something in their __all__ that
is physically not there (ie. getattr() raised AttributeError
:param locals: module's locals, obtain them by calling locals() in importing module's context
:param add_all: whether to create artificial __all__'s for modules that don't have them
:raise AttributeError: module's __all__ contained entry that was not in this module
"""
logger.warning('Invoking with path=%s', path)
for importer, modname, ispkg in pkgutil.walk_packages(path, onerror=lambda x: None):
if recursive and ispkg:
module = importlib.import_module(package_prefix+'.'+modname)
logger.warning(repr(package_prefix))
logger.warning(repr(modname))
try:
mod_all = module.__all__
except AttributeError:
mod_all = []
if add_all:
module.__all__ = mod_all
import_from([os.path.join(path[0], modname)], package_prefix+'.'+modname, mod_all, module.__dict__, recursive=recursive, fail_on_attributerror=fail_on_attributerror),
locals[modname] = module
__all__.append(modname)
elif not ispkg:
module = importlib.import_module(package_prefix+'.'+modname)
try:
package_ref = module.__all__
except AttributeError:
logger.warning('Module %s does not contain __all__, enumerating it instead', package_prefix+'.'+modname)
package_ref = dir(module)
for item in package_ref:
try:
locals[item] = getattr(module, item)
except AttributeError:
if fail_on_attributerror:
raise
else:
all_.append(item)
import logging
import typing as tp
logger = logging.getLogger(__name__)
import logging
import typing as tp
logger = logging.getLogger(__name__)
from satella.imports import import_from
__all__ = []
def do_import():
logger.warning(repr(__path__))
logger.warning(repr(__name__))
import_from(__path__, __name__, __all__, locals(), recursive=True, fail_on_attributerror=False, add_all=True)
import logging
import typing as tp
logger = logging.getLogger(__name__)
import logging
import typing as tp
logger = logging.getLogger(__name__)
def sub(a: float, b: float) -> float:
return a-b
\ No newline at end of file
import logging
import typing as tp
logger = logging.getLogger(__name__)
__all__ = ['add', 'would_have_failed']
def add(a: float, b: float) -> float:
return a+b
import logging
import unittest
logger = logging.getLogger(__name__)
class TestImports(unittest.TestCase):
def test_imports(self):
import tests.test_imports.importa
tests.test_imports.importa.do_import()
tests.test_imports.importa.importb.__all__
self.assertEqual(tests.test_imports.importa.importb.add(4, 5), 9)
self.assertEqual(tests.test_imports.importa.importb.sub(4, 5), -1)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment