Skip to content

Commit

Permalink
Merge pull request #12 from Erotemic/dev/0.3.2
Browse files Browse the repository at this point in the history
Start work on 0.3.2
  • Loading branch information
Erotemic committed May 7, 2021
2 parents 9e80b5d + 3258062 commit e4ab6bd
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 50 deletions.
28 changes: 14 additions & 14 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,9 @@ workflows:
- test_full/cp35-35m-linux:
filters:
<<: *__ignore_release__
- test_full/cp34-34m-linux:
filters:
<<: *__ignore_release__
#- test_full/cp34-34m-linux:
# filters:
# <<: *__ignore_release__
- test_full/cp27-27mu-linux:
filters:
<<: *__ignore_release__
Expand All @@ -252,9 +252,9 @@ workflows:
- test_minimal/cp35-35m-linux:
filters:
<<: *__ignore_release__
- test_minimal/cp34-34m-linux:
filters:
<<: *__ignore_release__
#- test_minimal/cp34-34m-linux:
# filters:
# <<: *__ignore_release__
- test_minimal/cp27-27mu-linux:
filters:
<<: *__ignore_release__
Expand Down Expand Up @@ -498,10 +498,10 @@ jobs:
docker:
- image: circleci/python:3.5

test_full/cp34-34m-linux:
<<: *test_full_template
docker:
- image: circleci/python:3.4
#test_full/cp34-34m-linux:
# <<: *test_full_template
# docker:
# - image: circleci/python:3.4

test_full/cp27-27mu-linux:
<<: *test_full_template
Expand Down Expand Up @@ -539,10 +539,10 @@ jobs:
docker:
- image: circleci/python:3.5

test_minimal/cp34-34m-linux:
<<: *test_minimal_template
docker:
- image: circleci/python:3.4
#test_minimal/cp34-34m-linux:
# <<: *test_minimal_template
# docker:
# - image: circleci/python:3.4

test_minimal/cp27-27mu-linux:
<<: *test_minimal_template
Expand Down
14 changes: 13 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
version: 0.3.2
---------------

### Changed
* Dropped Python 3.4 support
* Modified generated lazy init code
* `__submodules__` can now be a dictionary of submodule names that point to submodule attributes.

### Fixed
* Fixed issues in lazy init
* Fixed issue with ast.Constant


version: 0.3.1
version: 0.3.1 - released 2020-02-14
---------------


Expand Down
2 changes: 1 addition & 1 deletion mkinit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Regenerate Input Command
mkinit ~/code/mkinit/mkinit
"""
__version__ = "0.3.1"
__version__ = "0.3.2"

__submodules__ = [
"dynamic_mkinit",
Expand Down
8 changes: 6 additions & 2 deletions mkinit/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ def main():
The following `__init__.py` variables modify autogeneration behavior:
`__submodules__` - indicates the list of submodules to be
introspected, if unspecified all submodules are introspected.
`__submodules__` (List[str] | Dict[str, List[str])) -
Indicates the list of submodules to be introspected, if
unspecified all submodules are introspected. Can be a list
of submodule names, or a dictionary mapping each submodule name
to a list of attribute names to expose. If the value is None,
then all attributes are exposed (or __all__) is respected).
`__external__` - Specify external modules to expose the attributes of.
Expand Down
29 changes: 15 additions & 14 deletions mkinit/formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,10 +283,10 @@ def _initstr(
from importlib import lazy_import
__getattr__ = lazy_import(
__name__,
submodules=[
submodules={
'bar',
'baz',
],
},
submod_attrs={
'bar': [
'func1',
Expand Down Expand Up @@ -376,16 +376,12 @@ def append_part(new_part):
if options["lazy_import"]:
# NOTE: We are not using f-strings so the code can still be parsed
# in older versions of python.
# NOTE: We differentiate between submodule and submodule_attrs, as
# the keys in submodule_attrs aren't added by default.
default_lazy_boilerplate = textwrap.dedent(
r"""
def lazy_import(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
Expand All @@ -394,14 +390,14 @@ def lazy_import(module_name, submodules, submod_attrs):
def __getattr__(name):
if name in submodules:
attr = importlib.import_module(
'{module_name}.{modname}'.format(
module_name=module_name, modname=modname)
'{module_name}.{name}'.format(
module_name=module_name, name=name)
)
elif name in name_to_submod:
modname = name_to_submod[name]
submodname = name_to_submod[name]
module = importlib.import_module(
'{module_name}.{modname}'.format(
module_name=module_name, modname=modname)
'{module_name}.{submodname}'.format(
module_name=module_name, submodname=submodname)
)
attr = getattr(module, name)
else:
Expand Down Expand Up @@ -439,8 +435,13 @@ def __getattr__(name):
# we can remove complexity and just use ubelt elsewhere
import ubelt as ub

# exposed_submodules = set(exposed_submodules)
submodules_repr = ub.repr2(exposed_submodules).replace("\n", "\n ")
# hack for python <3.7 tests
submodules_repr = submodules_repr.replace('[', '{').replace(']', '}')

initstr = template.format(
submodules=ub.repr2(exposed_submodules).replace("\n", "\n "),
submodules=submodules_repr,
submod_attrs=ub.repr2(submod_attrs).replace("\n", "\n "),
)

Expand Down
8 changes: 6 additions & 2 deletions mkinit/static_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ def _parse_static_node_value(node):
values = map(_parse_static_node_value, node.values)
value = OrderedDict(zip(keys, values))
# value = dict(zip(keys, values))
elif hasattr(ast, 'Constant') and isinstance(node, (ast.Constant)):
# Constant added in 3.6?
# https://bugs.python.org/issue26146
value = node.value
else:
raise TypeError(
"Cannot parse a static value from non-static node "
Expand Down Expand Up @@ -78,12 +82,12 @@ def parse_static_value(key, source=None, fpath=None):
class AssignentVisitor(ast.NodeVisitor):
def visit_Assign(self, node):
for target in node.targets:
if getattr(target, "id", None) == key:
target_id = getattr(target, "id", None)
if target_id == key:
try:
self.value = _parse_static_node_value(node.value)
except TypeError as ex:
import warnings

warnings.warn(repr(ex))

sentinal = object()
Expand Down
49 changes: 35 additions & 14 deletions mkinit/static_mkinit.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ def static_init(modpath_or_name, submodules=None, respect_all=True, options=None
modpath = _rectify_to_modpath(modpath_or_name)

user_decl = parse_user_declarations(modpath)
logger.debug('user_decl = {}'.format(user_decl))
if submodules is not None:
user_decl["__submodules__"] = submodules

Expand Down Expand Up @@ -360,24 +361,40 @@ def _static_parse_imports(modpath, submodules=None, external=None, respect_all=T
>>> print('submodules = {!r}'.format(submodules))
>>> print('from_imports = {!r}'.format(from_imports))
>>> # assert 'autogen_init' in submodules
Example:
>>> from mkinit.static_mkinit import * # NOQA
>>> modpath = util_import.modname_to_modpath('mkinit')
>>> external = ['textwrap']
>>> submodules = {'foo': ['bar', 'baz', 'biz']}
>>> tup = _static_parse_imports(modpath, submodules=submodules, external=external)
>>> modname, submodules, from_imports = tup
>>> print('modname = {!r}'.format(modname))
>>> print('submodules = {!r}'.format(submodules))
>>> print('from_imports = {!r}'.format(from_imports))
>>> # assert 'autogen_init' in submodules
"""
logger.debug("Parse static submodules: {}".format(modpath))
# FIXME: handle the case where the __init__.py file doesn't exist yet
modname = util_import.modpath_to_modname(modpath, check=False)
if submodules is None:
logger.debug("Parsing implicit submodules!")
import_paths = dict(_find_local_submodules(modpath))
submodules = sorted(import_paths.keys())
submodules = {k: None for k in sorted(import_paths.keys())}
# logger.debug('Found {} import paths'.format(len(import_paths)))
# logger.debug('Found {} submodules'.format(len(submodules)))
else:
logger.debug("Given explicit submodules")
if modname is None:
raise AssertionError("modname is None")

if isinstance(submodules, list):
# Make a dict mapping module names to None
submodules = {m: None for m in submodules}

import_paths = {
m: util_import.modname_to_modpath(modname + "." + m, hide_init=False)
for m in submodules
for m in submodules.keys()
}
# FIX for relative nested import_paths
for m in import_paths.keys():
Expand All @@ -391,21 +408,25 @@ def _static_parse_imports(modpath, submodules=None, external=None, respect_all=T
if exists(newval):
import_paths[m] = newval
break
imports = ["." + m for m in submodules]
imports = ["." + m for m in submodules.keys()]

from_imports = []
for rel_modname in submodules:
sub_modpath = import_paths[rel_modname]
if sub_modpath is None:
raise Exception("Failed to submodule lookup {!r}".format(rel_modname))
try:
valid_attrs = _extract_attributes(sub_modpath, respect_all=respect_all)
except SyntaxError as ex:
warnings.warn(
"Failed to parse module {!r}, ex = {!r}".format(rel_modname, ex)
)
for rel_modname, attr_list in submodules.items():
if attr_list is None:
sub_modpath = import_paths[rel_modname]
if sub_modpath is None:
raise Exception("Failed to submodule lookup {!r}".format(rel_modname))
try:
valid_attrs = _extract_attributes(sub_modpath, respect_all=respect_all)
except SyntaxError as ex:
warnings.warn(
"Failed to parse module {!r}, ex = {!r}".format(rel_modname, ex)
)
else:
from_imports.append(("." + rel_modname, sorted(valid_attrs)))
else:
from_imports.append(("." + rel_modname, sorted(valid_attrs)))
valid_attrs = attr_list
from_imports.append(("." + rel_modname, attr_list))

if external:
for ext_modname in external:
Expand Down
5 changes: 4 additions & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[pytest]
addopts = --xdoctest
addopts = --xdoctest --ignore-glob=setup.py
norecursedirs = .git ignore build __pycache__ docs *.egg-info

filterwarnings= default
ignore:.*private pytest class or function.*:Warning
6 changes: 5 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,10 @@ def native_mb_python_tag(plat_impl=None, version_info=None):
"License :: OSI Approved :: Apache Software License",
# Supported Python versions
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
],
)

0 comments on commit e4ab6bd

Please sign in to comment.