ini2toml.plugins package#


ini2toml.plugins.best_effort module#

class ini2toml.plugins.best_effort.BestEffort(key_sep='=', section_splitter=re.compile('\\.|:|\\\\'))[source]#

Bases: object

Guess option value conversion based on the string format

apply_best_effort(container: M, field: str, value: str)[source]#
apply_best_effort_to_section(section: M) M[source]#
process_values(doc: M) M[source]#
ini2toml.plugins.best_effort.activate(translator: Translator)[source]#

ini2toml.plugins.coverage module#

class ini2toml.plugins.coverage.Coverage[source]#

Bases: object

Convert settings to ‘pyproject.toml’ equivalent

LIST_VALUES = ('exclude_lines', 'concurrency', 'disable_warnings', 'debug', 'include', 'omit', 'plugins', 'source', 'source_pkgs', 'partial_branches')#
PREFIX = 'coverage:'#
SECTIONS = ('run', 'paths', 'report', 'html', 'xml', 'json')#
process_section(section: M)[source]#
process_values(doc: M, sections=('run', 'paths', 'report', 'html', 'xml', 'json'), prefix='coverage:') M[source]#
ini2toml.plugins.coverage.activate(translator: Translator)[source]#

ini2toml.plugins.isort module#

class ini2toml.plugins.isort.ISort[source]#

Bases: object

Convert settings to ‘pyproject.toml’ equivalent

FIELDS = {'add_imports', 'classes', 'constants', 'force_to_top', 'forced_separate', 'length_sort_sections', 'namespace_packages', 'no_lines_before', 'remove_imports', 'sections', 'sources', 'treat_comments_as_code', 'variables'}#
FIELD_ENDS = ['skip', 'glob', 'paths', 'exclusions', 'plugins']#
FIELD_STARTS = ['known', 'extra']#
find_list_options(section: Mapping) Set[str][source]#
process_section(section: M)[source]#
process_values(doc: M, section_name='isort') M[source]#
ini2toml.plugins.isort.activate(translator: Translator)[source]#

ini2toml.plugins.mypy module#

class ini2toml.plugins.mypy.Mypy[source]#

Bases: object

Convert settings to ‘pyproject.toml’ equivalent

DONT_TOUCH = ('python_version',)#
LIST_VALUES = ('files', 'always_false', 'disable_error_code', 'plugins')#
add_overrided_modules(section: R, name: str, modules: List[str])[source]#
get_or_create_overrides(parent: MutableMapping) MutableSequence[source]#
process_options(section: M) M[source]#
process_overrides(section: R, overrides: MutableSequence, name: str) R[source]#
process_values(doc: M) M[source]#
ini2toml.plugins.mypy.activate(translator: Translator)[source]#

ini2toml.plugins.profile_independent_tasks module#

Profile-independent tasks implemented via profile augmentation.

ini2toml.plugins.profile_independent_tasks.activate(translator: Translator)[source]#
ini2toml.plugins.profile_independent_tasks.ensure_terminating_newlines(text: str) str[source]#
ini2toml.plugins.profile_independent_tasks.normalise_newlines(text: str) str[source]#

Make sure every table is preceded by an empty newline, but remove them elsewhere in the output TOML document. Also ensure a terminating newline is present for best POSIX tool compatibility.

ini2toml.plugins.profile_independent_tasks.post_process(fn: Callable[[str], str])[source]#
ini2toml.plugins.profile_independent_tasks.remove_empty_table_headers(text: str) str[source]#

Remove empty TOML table headers

ini2toml.plugins.pytest module#

class ini2toml.plugins.pytest.Pytest[source]#

Bases: object

Convert settings to ‘pyproject.toml’ (‘ini_options’ table)

DONT_TOUCH = ('minversion',)#
LIST_VALUES = ('filterwarnings', 'norecursedirs', 'python_classes', 'python_files', 'python_functions', 'required_plugins', 'testpaths', 'usefixtures')#
process_section(section: MutableMapping)[source]#
process_values(doc: R) R[source]#
ini2toml.plugins.pytest.activate(translator: Translator)[source]#

ini2toml.plugins.setuptools_pep621 module#

class ini2toml.plugins.setuptools_pep621.Directive(kind: str, args: Any)[source]#

Bases: dict

Represent a setuptools’ setup.cfg directive (e.g ‘file:’, ‘attr:’)

In TOML these directives can be represented as dict-like objects, however in the conversion algorithm we need to be able to differentiate between them. By inheriting from dict, we can use directive classes interchangeably but also check using isinstance(obj, Directive).

ini2toml.plugins.setuptools_pep621.ENV_MARKER = re.compile(';\\s*(python|platform|implementation|os|sys)[_.]', re.MULTILINE)#

Simplified regex for PEP 508 markers that can be used in setup.cfg

class ini2toml.plugins.setuptools_pep621.SetuptoolsPEP621[source]#

Bases: object

Convert settings to ‘pyproject.toml’ based on PEP 621

BUILD_REQUIRES = ('setuptools>=61.2',)#
apply_value_processing(doc: R) R[source]#

Process setup.cfg values according to processing_rules() and dependent_processing_rules().

This function assumes all field names were normalised by normalise_keys().

dependent_processing_rules(doc: IntermediateRepr) Dict[Tuple[str, ...], Callable[[str], Any] | Callable[[M], M]][source]#

Dynamically create processing rules, such as processing_rules() based on the existing document.

ensure_pep518(doc: R) R[source]#

PEP 518 specifies that any other tool adding configuration under pyproject.toml should use the tool table. This means that the only top-level keys are build-system, project and tool.

fix_extras_require(doc: R) R[source]#

extras-require can have markers embedded in the extra group they need to be removed and added to the dependencies themselves

handle_dynamic(doc: R) R[source]#

All the configuration fields in PEP 621 that are dynamically discovered at build time have to be explicitly list in dynamic. This function moves directive usages (e.g. file: and attr:) to a tool-specific subtable (tool.setuptools.dynamic), and add the corresponding field to dynamic. Since version is a mandatory core metadata, it will be added to dynamic when not explicitly set (in that case plugins such as setuptools_scm are expected to provide a value at runtime).

handle_license(doc: R) R[source]#

In PEP 621 we have a single field for license, which is not compatible with setuptools license-files. This field is meant to fill the License core metadata as a plain license text (not a path to a file). Even when the project.license.file table field is given, the idea is that the file should be expanded into text.

This will likely change once PEP 639 is accepted. Meanwhile we have to translate license-files into a setuptools specific configuration.

handle_packages_find(doc: R) R[source]#

setup.cfg uses a option + a section to define options.packages.find and its find_namespace variant. This does not work very well with the convention used for the TOML encoding, since the option and the section would end up with the same name (and overwriting each other). Therefore we need to “merge” them.

make_include_package_data_explicit(doc: R) R[source]#
merge_and_rename_long_description_and_content_type(doc: R) R[source]#

PEP 621 offers a single field (readme) to cover things present in two fields in setup.cfg:

long_description.file => readme.file
long_description => readme.text
long-description-content-type => readme.content-type

We also have to be aware that PEP 621 accepts a single file, so the option of combining multiple files as presented in setup.cfg have to be handled via dynamic.

merge_and_rename_urls(doc: R) R[source]#

The following renames can be applied when comparing setuptools metadata and PEP 621:

url => urls.homepage
download-url =>
project-urls.* => urls.*
merge_authors_maintainers_and_emails(doc: R) R[source]#

When transforming setuptools metadata and PEP 621, we have to merge author/maintainer and author-email/maintainer-email into a single dict-like object with 2 keys. Some projects also provide multiple, comma separated, values for each field. In that case we assume that the value for the i-th author/maintainer should be paired with to the i-th author-email/maintainer-email value.

move_and_split_entrypoints(doc: R) R[source]#

In setup.cfg there is no special treatment for entry-points that will be transformed in console/GUI scripts. On the other hand PEP 621 defines separated fields:

entry-points.console-scripts => scripts
entry-points.gui-scripts => gui-scripts
entry-points.* => "entry-points".*
move_options_missing_in_pep621(doc: R) R[source]#

PEP 621 specifies as project metadata values that are covered in setup.cfg "options" section.

move_setup_requires(doc: R) R[source]#

Move setup_requires to the equivalent field in PEP 518, and add mandatory build dependencies if they are missing and

move_tests_require(doc: R) R[source]#

Move tests_require to a testing extra as optional dependency (this option is deprecated in setuptools (the test command is deprecated).

It assumes move_options_missing_in_pep621 already run (to populate project:optional-dependencies.

normalise_key(key: str) str[source]#

Normalise a single key for option

normalise_keys(cfg: R) R[source]#

Normalise keys in setup.cfg, by replacing aliases with cannonic names and replacing the snake case with kebab case.


Although setuptools recently deprecated kebab case in setup.cfg pyproject.toml use it as a convention (as established in PEP 517, PEP 518 and PEP 621) so this normalisation makes more sense for the translation.

parse_setup_py_command_options(doc: R) R[source]#

distutils commands can accept arguments from setup.cfg files. This function moves these arguments to their own distutils tool-specific sub-table

pep621_transform(doc: R) R[source]#

Rules are applied sequentially and therefore can interfere with the following ones. Please notice that renaming is applied after value processing.

processing_rules() Dict[Tuple[str, ...], Callable[[str], Any] | Callable[[M], M]][source]#

Value type processing, as defined in:

remove_metadata_not_in_pep621(doc: R) R[source]#

PEP 621 does not cover all project metadata in setup.cfg "metadata" section. That is left as “tool” specific configuration.

rename_script_files(doc: R) R[source]#

setuptools define a options.scripts parameters that refer to script files, not created via entry-points. To avoid confusion with PEP 621 scripts (generated via entry-points) let’s rename this field to script-files


setup.cfg aliases as defined in:

split_subtables(out: R) R[source]#

setuptools emulate nested sections (e.g.: options.extras_require) which can be directly expressed in TOML via sub-tables.

classmethod template(ir_cls: ~typing.Type[~ini2toml.plugins.setuptools_pep621.R] = <class 'ini2toml.intermediate_repr.IntermediateRepr'>, build_requires: ~typing.Sequence[str] = ()) R[source]#
ini2toml.plugins.setuptools_pep621.activate(translator: Translator)[source]#
ini2toml.plugins.setuptools_pep621.chain_iter(iterable, /)#

Alternative chain() constructor taking a single iterable argument that evaluates lazily.

ini2toml.plugins.setuptools_pep621.directive(*directives: str, orelse=<function split_comment>)[source]#

partial form of split_directive()


Setuptools seem to accept line continuations for markers (with comments in the middle), and that is more difficult to process. e.g.:

ini2toml.plugins.setuptools_pep621.split_directive(value: str, directives: ~typing.Sequence[str] = ('file', 'attr'), orelse=<function split_comment>)[source]#
ini2toml.plugins.setuptools_pep621.value_error(field: str)[source]#

Simply raise a ValueError when used as a transformation function

Module contents#

exception ini2toml.plugins.ErrorLoadingPlugin(plugin: str = '', entry_point: EntryPoint | None = None)[source]#

Bases: RuntimeError

There was an error loading ‘{plugin}’. Please make sure you have installed a version of the plugin that is compatible with {package} {version}. You can also try uninstalling it.

ini2toml.plugins.iterate_entry_points(group='ini2toml.processing') Iterable[EntryPoint][source]#

Produces a generator yielding an EntryPoint object for each plugin registered via setuptools entry point mechanism.

This method can be used in conjunction with load_from_entry_point to filter the plugins before actually loading them.

ini2toml.plugins.list_from_entry_points(group: str = 'ini2toml.processing', filtering: ~typing.Callable[[~importlib.metadata.EntryPoint], bool] = <function <lambda>>) List[Callable[[Translator], None]][source]#

Produces a list of plugin objects for each plugin registered via setuptools entry point mechanism.

  • group – name of the setuptools’ entry_point group where plugins is being registered

  • filtering – function returning a boolean deciding if the entry point should be loaded and included (or not) in the final list. A True return means the plugin should be included.

ini2toml.plugins.load_from_entry_point(entry_point: EntryPoint) Callable[[Translator], None][source]#

Carefully load the plugin, raising a meaningful message in case of errors