epythet.migrate

epythet migrate-style: rewrite RST field lists as Google (or NumPy) sections, opt-in.

The fleet keeps both conventions and napoleon renders both, so nothing here runs by default anywhere (maintainer decision 6: normalizer only, no mass style conversion). This is the tool for the one package, module or file whose maintainer wants :param x: lines to become an Args: section.

It is built on epythet.repair’s machinery and inherits every one of its guarantees: exact-span rewriting, an unchanged AST outside docstrings, byte-identical doctest sources, and a level-0.5 re-validation of each rewritten docstring. On top of that it only converts what round-trips:

  • the field region is the first contiguous block of :param, :type, :returns, :rtype and :raises lines (with their indented continuations); prose before it and everything after it, doctests included, is copied verbatim;

  • a region holding any other field (:keyword, :var, :meta, …) is left alone, because docstring_parser.compose drops or mangles those;

  • the composed section is parsed back and must describe the same parameters, return and exceptions as the original, or the docstring is left alone.

The conversion itself is docstring_parser.parse(..., style=REST) then compose(..., style=GOOGLE) (research §9); the substrate that writes it back is the applier= seam of epythet.repair.repair().

>>> from epythet.migrate import convert_fields
>>> print(convert_fields(":param x: the x value\n:type x: int\n:returns: x doubled\n:rtype: int", to="google"))
:param x: the x value
:type x: int

<BLANKLINE> :returns: x doubled :rtype: int

Module Attributes

CONVERTIBLE_FIELDS

Field names whose conversion round-trips through docstring_parser.

Functions

convert_fields(region, *[, to])

Convert one RST field block to a Google or NumPy section block, or None if unsafe.

field_region(lines)

(start, end) of the first RST field block, or None; end is exclusive.

field_regions(lines)

Every field block of a docstring, in order.

migrate_style(path, *[, to, write, ignore, ...])

Convert the RST field lists under path (a file, package or project) to to sections.

migrate_style_command(path, *[, to, write, ...])

Rewrite RST field lists (:param x:) as Google or NumPy sections, one file or package at a time.

rst_fields_to_sections([to])

A normalizer-shaped rule (lines -> lines) converting the docstring's field block.

epythet.migrate.CONVERTIBLE_FIELDS = frozenset({'arg', 'argument', 'except', 'exception', 'param', 'parameter', 'raise', 'raises', 'return', 'returns', 'rtype', 'type'})

Field names whose conversion round-trips through docstring_parser.

epythet.migrate.convert_fields(region, *, to='google')[source]

Convert one RST field block to a Google or NumPy section block, or None if unsafe.

Return type:

str | None

epythet.migrate.field_region(lines)[source]

(start, end) of the first RST field block, or None; end is exclusive.

A block starts at a field line and takes every following field line at the same indentation and every continuation (a deeper-indented line, or a blank line followed by one of those).

Return type:

tuple[int, int] | None

>>> field_region(["Summary.", "", ":param x: the x", "    more", ":returns: y", "", "Then prose."])
(2, 5)
>>> field_region(["No fields."]) is None
True
epythet.migrate.field_regions(lines)[source]

Every field block of a docstring, in order.

Return type:

list[tuple[int, int]]

>>> field_regions([":param x: x", "", "prose", "", ":returns: y"])
[(0, 1), (4, 5)]
epythet.migrate.migrate_style(path, *, to='google', write=False, ignore=(), ledger=None, napoleon=True, run_doctests=True, applier=<function apply_span_edits>)[source]

Convert the RST field lists under path (a file, package or project) to to sections.

Dry run by default; see epythet.repair.repair() for the arguments, which are the same.

Return type:

RepairReport

epythet.migrate.migrate_style_command(path, *, to='google', write=False, ignore=None, ledger=None, no_napoleon=False, no_doctests=False, applier='span', quiet=False)[source]

Rewrite RST field lists (:param x:) as Google or NumPy sections, one file or package at a time.

Opt-in and never part of a fleet sweep. Dry run by default: prints the diff –write would apply. Docstrings whose fields would not round-trip (:keyword, :var, :meta, …) are left alone and listed.

Parameters:
  • path (str) – A .py file, a package directory, or a project root.

  • to (str) – Target convention: google or numpy.

  • write (bool) – Apply the changes (after re-validating each docstring and re-running doctests).

  • ignore (list[str] | None) – Skip files whose path contains this string (repeat -i for several).

  • ledger (str | None) – Directory of extra rule YAML files overlaid on the bundled ledger.

  • no_napoleon (bool) – Re-validate without napoleon’s Google/NumPy pre-processing.

  • no_doctests (bool) – Do not run each touched file’s doctests before and after writing.

  • applier (str) – The rewriting substrate: span (default) or libcst.

  • quiet (bool) – Print the summary only, not the diff.

Return type:

None

epythet.migrate.rst_fields_to_sections(to='google')[source]

A normalizer-shaped rule (lines -> lines) converting the docstring’s field block.

A docstring with more than one field block is left alone: converting one would leave a mixed-style docstring behind.

Return type:

Callable[[list[str]], list[str]]