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__”

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:

Tuple[int, int, str]

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._indent(text, indent='    ')[source]
mkinit.formatting._initstr(modname, imports, from_imports, explicit={}, protected={}, private={}, options=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

  • 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_imports_str(imports, rootmodname='.')[source]
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,)