mkinit.formatting module¶
Contains logic for formatting statically / dynamically extracted information into the final product.
- mkinit.formatting._ensure_options(given_options=None)[source]¶
Ensures dict contains all formatting options.
- Defaults are:
- with_attrs (bool): if True, generate module attribute from imports
(Default: True)
- with_mods (bool): if True, generate module imports
(Default: True)
- with_all (bool): if True, generate an __all__ variable
(Default: True)
- relative (bool): if True, generate relative . imports
(Default: False)
- mkinit.formatting._insert_autogen_text(modpath, initstr, interface=False)[source]¶
Creates new text for __init__.py containing the autogenerated code.
If an __init__.py already exists in modpath, then it tries to intelligently insert the code without clobbering too much. See _find_insert_points for details on this process.
- mkinit.formatting._find_insert_points(lines)[source]¶
Searches for the points to insert autogenerated text between.
If the # <AUTOGEN_INIT> directive exists, then it is preserved and new text is inserted after it. This text clobbers all other text until the # <AUTOGEN_INIT> is reached.
If the explicit tags are not specified, mkinit will only clobber text after one of these patterns:
A line beginning with a (#) comment
A multiline (triple-quote) comment
A line beginning with “from __future__”
A line beginning with “__version__”
- A line beginning with any special variable:
“__submodules__”, “__external__”, “__protected__”, “__private__”, “__ignore__”, “__explicit__”, or “__extra_all__”
If neither explicit tags or implicit patterns exist, all text is clobbered.
- Parameters:
lines (List[str]) – lines of an __init__.py file.
- Returns:
insert points as starting line, ending line, and any required indentation.
- Return type:
Examples
>>> from mkinit.formatting import * # NOQA >>> lines = textwrap.dedent( ''' preserved1 = True if True: # <AUTOGEN_INIT> clobbered2 = True # </AUTOGEN_INIT> preserved3 = True ''').strip('\n').split('\n') >>> start, end, indent = _find_insert_points(lines) >>> print(repr((start, end, indent))) (3, 4, ' ')
Examples
>>> from mkinit.formatting import * # NOQA >>> lines = textwrap.dedent( ''' preserved1 = True __version__ = '1.0' clobbered2 = True ''').strip('\n').split('\n') >>> start, end, indent = _find_insert_points(lines) >>> print(repr((start, end, indent))) (2, 3, '')
- mkinit.formatting._initstr(modname, imports, from_imports, explicit={}, protected={}, private={}, options=None, module_property_names=None)[source]¶
Calls the other string makers
CommandLine
python -m mkinit.static_autogen _initstr
- Parameters:
modname (str) – the name of the module to generate the init str for
imports (List[str]) – list of module-level imports
from_imports (List[Tuple[str, List[str]]]) – List of submodules and their imported attributes
explicit (set) – names to explicitly include in __all__
protected (set) – modules to import but not expose their attributes
private (set) – modules and attributes to completely exclude (supports fnmatch patterns like ‘test_*’)
options (dict) – customize output
CommandLine
python -m mkinit.formatting _initstr
Example
>>> modname = 'foo' >>> imports = ['.bar', '.baz'] >>> from_imports = [('.bar', ['func1', 'func2'])] >>> initstr = _initstr(modname, imports, from_imports) >>> print(initstr) from foo import bar from foo import baz from foo.bar import (func1, func2,) __all__ = ['bar', 'baz', 'func1', 'func2']
Example
>>> modname = 'foo' >>> imports = ['.bar', '.baz'] >>> from_imports = [('.bar', list(map(chr, range(97, 123))))] >>> initstr = _initstr(modname, imports, from_imports) >>> print(initstr) from foo import bar from foo import baz from foo.bar import (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z,) __all__ = ['a', 'b', 'bar', 'baz', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
Example
>>> import pytest >>> import sys >>> if sys.version_info < (3, 7): >>> pytest.skip('lazy only works on 3.7+') >>> modname = 'foo' >>> imports = ['.bar', '.baz'] >>> from_imports = [('.bar', ['func1', 'func2'])] >>> options = {'lazy_import': 1, 'lazy_boilerplate': None} >>> initstr = _initstr(modname, imports, from_imports, options=options) >>> print(initstr) ...
>>> options = {'lazy_import': 1, 'lazy_boilerplate': 'from importlib import lazy_import'} >>> initstr = _initstr(modname, imports, from_imports, options=options) >>> print(initstr.replace('\n\n', '\n')) from importlib import lazy_import __getattr__ = lazy_import( __name__, submodules={ 'bar', 'baz', }, submod_attrs={ 'bar': [ 'func1', 'func2', ], }, ) def __dir__(): return __all__ __all__ = ['bar', 'baz', 'func1', 'func2']
- mkinit.formatting._make_lazy_boilerplate(exposed_submodules, exposed_from_imports, options, module_property_names)[source]¶
- mkinit.formatting._make_our_lazy_boilerplate(module_property_names=None)[source]¶
Originally this was a non-dyanmic function, but for module properties we had to add in some extra tools.
Example
>>> from mkinit.formatting import _make_our_lazy_boilerplate # NOQA >>> module_property_names = ['foo', 'bar'] >>> text = _make_our_lazy_boilerplate(module_property_names) >>> import ubelt as ub >>> print(ub.highlight_code(text, backend='rich'))
- mkinit.formatting._packed_rhs_text(lhs_text, rhs_text)[source]¶
packs rhs text to have indentation that agrees with lhs text
Example
>>> normname = 'this.is.a.module' >>> fromlist = ['func{}'.format(d) for d in range(10)] >>> indent = '' >>> lhs_text = indent + 'from {normname} import ('.format( >>> normname=normname) >>> rhs_text = ', '.join(fromlist) + ',)' >>> packstr = _packed_rhs_text(lhs_text, rhs_text) >>> print(packstr)
>>> normname = 'this.is.a.very.long.modnamethatwilkeepgoingandgoing' >>> fromlist = ['func{}'.format(d) for d in range(10)] >>> indent = '' >>> lhs_text = indent + 'from {normname} import ('.format( >>> normname=normname) >>> rhs_text = ', '.join(fromlist) + ',)' >>> packstr = _packed_rhs_text(lhs_text, rhs_text) >>> print(packstr)
>>> normname = 'this.is.a.very.long.modnamethatwilkeepgoingandgoingandgoingandgoingandgoingandgoing' >>> fromlist = ['func{}'.format(d) for d in range(10)] >>> indent = '' >>> lhs_text = indent + 'from {normname} import ('.format( >>> normname=normname) >>> rhs_text = ', '.join(fromlist) + ',)' >>> packstr = _packed_rhs_text(lhs_text, rhs_text) >>> print(packstr)
- mkinit.formatting._make_fromimport_str(from_imports, rootmodname='.', indent='')[source]¶
- Parameters:
from_imports (list) – each item is a tuple with module and a list of imported with_attrs.
rootmodname (str) – name of root module
indent (str) – initial indentation
Example
>>> from_imports = [ ... ('.foo', list(map(chr, range(97, 123)))), ... ('.bar', []), ... ('.a_longer_package', list(map(chr, range(65, 91)))), ... ] >>> from_str = _make_fromimport_str(from_imports, indent=' ' * 8) >>> print(from_str) from .foo import (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z,) from .a_longer_package import (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,)