Skip to content

Version 0.3.0 Working Branch#10

Merged
Erotemic merged 5 commits intomasterfrom
dev/0.3.0
Dec 26, 2020
Merged

Version 0.3.0 Working Branch#10
Erotemic merged 5 commits intomasterfrom
dev/0.3.0

Conversation

@Erotemic
Copy link
Copy Markdown
Owner

Work to support networkx/networkx#4349

@Erotemic
Copy link
Copy Markdown
Owner Author

Erotemic commented Dec 22, 2020

This branch contains a initial code to format __init__ module such that they make use of Python 3.7's lazy initialization. Currently the lazy initialization version of this:

from foo import bar
from foo import baz

from foo.bar import (func1, func2,)

__all__ = ['bar', 'baz', 'func1', 'func2']

Looks like:

def lazy_install(module_name, submodules, submod_attrs):
    import sys
    import importlib
    import importlib.util
    all_funcs = []
    for mod, funcs in submod_attrs.items():
        all_funcs.extend(funcs)
    name_to_submod = {
        func: mod for mod, funcs in submod_attrs.items()
        for func in funcs
    }

    def require(fullname):
        if fullname in sys.modules:
            return sys.modules[fullname]

        spec = importlib.util.find_spec(fullname)
        try:
            module = importlib.util.module_from_spec(spec)
        except:
            raise ImportError(f'Could not lazy import module {fullname}') from None
        loader = importlib.util.LazyLoader(spec.loader)

        sys.modules[fullname] = module

        # Make module with proper locking and get it inserted into sys.modules.
        loader.exec_module(module)

        return module

    def __getattr__(name):
        if name in submodules:
            fullname = f'{module_name}.{name}'
            attr = require(fullname)
        elif name name_to_submod:
            modname = name_to_submod[name]
            attr = importlib.import_module(
                f'{module_name}.{modname}'
            )
        else:
            raise AttributeError(f'No {module_name} attribute {name}')
        # Set module-level attribute so getattr is not called again
        globals()[name] = attr
        return attr
    return __getattr__

__getattr__ = lazy_install(
    __name__,
    submodules={
        'bar',
        'baz',
    },
    submod_attrs={
        'bar': [
            'func1',
            'func2',
        ],
    },
)

def __dir__():
    return __all__

__all__ = ['bar', 'baz', 'func1', 'func2']

I'm not 100% sure what the best way to handle this overhead is. Its also possible the formatting of the lazy install call could be slightly more compact. Some of this could be mitigate with a TPL import, in which case we could get something more like this:

from importlib import lazy_install

__getattr__ = lazy_install(
    __name__,
    submodules={'bar', 'baz'},
    submod_attrs={
        'bar': ['func1', 'func2',],
    },
)

@codecov-io
Copy link
Copy Markdown

codecov-io commented Dec 22, 2020

Codecov Report

Merging #10 (929110e) into master (159e919) will increase coverage by 0.35%.
The diff coverage is 76.63%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #10      +/-   ##
==========================================
+ Coverage   82.09%   82.45%   +0.35%     
==========================================
  Files           7        8       +1     
  Lines         754      832      +78     
  Branches      170      189      +19     
==========================================
+ Hits          619      686      +67     
- Misses         95      102       +7     
- Partials       40       44       +4     
Impacted Files Coverage Δ
mkinit/static_analysis.py 86.23% <0.00%> (+1.81%) ⬆️
mkinit/static_mkinit.py 83.76% <70.00%> (+6.06%) ⬆️
mkinit/formatting.py 83.33% <74.19%> (-2.93%) ⬇️
mkinit/util/util_import.py 77.65% <77.65%> (ø)
mkinit/util/util_diff.py 80.35% <87.50%> (+4.68%) ⬆️
mkinit/__init__.py 100.00% <100.00%> (ø)
mkinit/top_level_ast.py 94.73% <100.00%> (ø)
... and 1 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 159e919...55be4c1. Read the comment docs.

wip

wip

Fix python2 issue

Add codecov.yml

wip

wip

work on CircleCI

wip

wip

wip

wip

wip

wip

wip

wip

wip

wip

wip

wip

wip

wip
@Erotemic Erotemic merged commit 98b5d4e into master Dec 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants