Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-ini2toml for openSUSE:Factory 
checked in at 2024-05-05 12:10:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-ini2toml (Old)
 and      /work/SRC/openSUSE:Factory/.python-ini2toml.new.1880 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-ini2toml"

Sun May  5 12:10:27 2024 rev:10 rq:1171769 version:0.14

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-ini2toml/python-ini2toml.changes  
2024-03-21 17:00:29.824498110 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-ini2toml.new.1880/python-ini2toml.changes    
    2024-05-05 12:10:33.839395439 +0200
@@ -1,0 +2,17 @@
+Fri May  3 07:41:22 UTC 2024 - Dirk Müller <dmuel...@suse.com>
+
+- update to 0.14:
+  * Introduce LiteTranslator and FullTranslator as convenience
+    classes for more deterministic behaviour, :pr:`95`.
+  * setuptools plugin: Fix ValueError when setup.cfg contains
+    [options.packages.find] but also lists [options] packages =
+    ... explicitly as a list of package names, :issue:`93`.
+  * Fix ValueError when setup.cfg contains
+    [options.packages.find] but also lists [options] packages =
+    ... explicitly as a list of package names, :issue:`93`.
+  * pytest plugin: Remove comments when converting addopts with
+    multi-line values, :issue:`98`.
+  * Remove comments when converting addopts with multi-line
+    values, :issue:`98`.
+
+-------------------------------------------------------------------

Old:
----
  ini2toml-0.13.tar.gz

New:
----
  ini2toml-0.14.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-ini2toml.spec ++++++
--- /var/tmp/diff_new_pack.ZlgmL8/_old  2024-05-05 12:10:35.583458557 +0200
+++ /var/tmp/diff_new_pack.ZlgmL8/_new  2024-05-05 12:10:35.587458701 +0200
@@ -50,7 +50,7 @@
 
 %define skip_python2 1
 Name:           python-ini2toml%{psuffix}
-Version:        0.13
+Version:        0.14
 Release:        0
 Summary:        Automatic conversion of .ini/cfg files to TOML equivalents
 License:        MPL-2.0
@@ -157,6 +157,8 @@
 %if %{with test}
 %check
 %if %{without all} && %{without full}
+rm -v src/ini2toml/drivers/configupdater.py
+rm -v src/ini2toml/drivers/full_toml.py
 ignoretests=(
     --ignore tests/test_examples.py
     --ignore tests/test_transformations.py

++++++ ini2toml-0.13.tar.gz -> ini2toml-0.14.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/.cirrus.yml 
new/ini2toml-0.14/.cirrus.yml
--- old/ini2toml-0.13/.cirrus.yml       2023-10-23 14:15:48.000000000 +0200
+++ new/ini2toml-0.14/.cirrus.yml       2024-04-20 21:23:26.000000000 +0200
@@ -99,8 +99,7 @@
     - name: test (Linux - 3.11)
       container: {image: "python:3.11-bullseye"}
     - name: test (Linux - 3.12)
-      container: {image: "python:3.12-rc-bullseye"}
-      allow_failures: true  # Experimental
+      container: {image: "python:3.12-bullseye"}
   install_script:
     - python -m pip install --upgrade pip tox pipx
   <<: *test-template
@@ -124,7 +123,7 @@
 
 freebsd_task:
   name: test (freebsd - 3.9)
-  freebsd_instance: {image_family: freebsd-13-1}
+  freebsd_instance: {image_family: freebsd-14-0}
   install_script:
     - pkg remove -y python lang/python
     - pkg install -y git python39 py39-pip py39-gdbm py39-sqlite3 py39-tox 
py39-pipx py39-tomli
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/.pre-commit-config.yaml 
new/ini2toml-0.14/.pre-commit-config.yaml
--- old/ini2toml-0.13/.pre-commit-config.yaml   2023-10-23 14:15:48.000000000 
+0200
+++ new/ini2toml-0.14/.pre-commit-config.yaml   2024-04-20 21:23:26.000000000 
+0200
@@ -2,7 +2,7 @@
 
 repos:
 - repo: https://github.com/pre-commit/pre-commit-hooks
-  rev: v4.5.0
+  rev: v4.6.0
   hooks:
   - id: trailing-whitespace
     exclude: 'test_(.*)\.py$'
@@ -19,7 +19,7 @@
     args: ['--fix=lf']
 
 - repo: https://github.com/PyCQA/autoflake
-  rev: v2.2.1
+  rev: v2.3.1
   hooks:
   - id: autoflake
     args: [
@@ -29,12 +29,12 @@
     ]
 
 - repo: https://github.com/PyCQA/isort
-  rev: 5.12.0
+  rev: 5.13.2
   hooks:
   - id: isort
 
 - repo: https://github.com/psf/black
-  rev: 23.9.1
+  rev: 24.4.0
   hooks:
   - id: black
     language_version: python3
@@ -51,13 +51,13 @@
   - id: codespell  # See setup.cfg for args
 
 - repo: https://github.com/PyCQA/flake8
-  rev: 6.1.0
+  rev: 7.0.0
   hooks:
   - id: flake8
     additional_dependencies: [flake8-bugbear>=23.2.13]
 
 - repo: https://github.com/asottile/pyupgrade
-  rev: v3.15.0
+  rev: v3.15.2
   hooks:
   - id: pyupgrade
     args:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/CHANGELOG.rst 
new/ini2toml-0.14/CHANGELOG.rst
--- old/ini2toml-0.13/CHANGELOG.rst     2023-10-23 14:15:48.000000000 +0200
+++ new/ini2toml-0.14/CHANGELOG.rst     2024-04-20 21:23:26.000000000 +0200
@@ -2,6 +2,21 @@
 Changelog
 =========
 
+Version 0.14
+============
+
+* Introduce ``LiteTranslator`` and ``FullTranslator`` as
+  convenience classes for more deterministic behaviour, :pr:`95`.
+* ``setuptools`` plugin:
+
+  * Fix ``ValueError`` when ``setup.cfg`` contains ``[options.packages.find]``
+    but also lists ``[options] packages = ...`` explicitly as a list of package
+    names, :issue:`93`.
+
+* ``pytest`` plugin:
+
+  * Remove comments when converting ``addopts`` with multi-line values, 
:issue:`98`.
+
 Version 0.13
 ============
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/CONTRIBUTING.rst 
new/ini2toml-0.14/CONTRIBUTING.rst
--- old/ini2toml-0.13/CONTRIBUTING.rst  2023-10-23 14:15:48.000000000 +0200
+++ new/ini2toml-0.14/CONTRIBUTING.rst  2024-04-20 21:23:26.000000000 +0200
@@ -77,9 +77,9 @@
 ==================
 
 Understanding how the project works
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-----------------------------------
 
-If you have a change in mind, please have a look in our :doc:`dev-guide`.
+If you have a change in mind, please have a look in our :doc:`/dev-guide`.
 It explains the main aspects of the project and provide a brief overview on how
 it is organised and how to implement :ref:`plugins`.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/PKG-INFO new/ini2toml-0.14/PKG-INFO
--- old/ini2toml-0.13/PKG-INFO  2023-10-23 14:17:02.442848400 +0200
+++ new/ini2toml-0.14/PKG-INFO  2024-04-20 21:24:34.163375100 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: ini2toml
-Version: 0.13
+Version: 0.14
 Summary: Automatically conversion of .ini/.cfg files to TOML equivalents
 Home-page: https://github.com/abravalheri/ini2toml/
 Author: Anderson Bravalheri
@@ -138,9 +138,86 @@
 To do so, don't forget to add it to your `virtual environment`_ or specify it 
as a
 `project dependency`_.
 
+Note that the class ``Translator`` will try to guess which flavour to use based
+on the available installed dependencies. If you need something more
+deterministic, consider using ``LiteTranslator`` and ``FullTranslator``,
+or explicitly specifying the ``ini_loads_fn`` and ``toml_dumps_fn`` keyword
+arguments in the constructor.
+
 More details about ``ini2toml`` and its Python API can be found in `our docs`_.
 
 
+Limitations
+===========
+
+``ini2toml`` will try its best to create good quality translations from
+``.ini/.cfg`` into ``.toml`` files. However the tool comes with a set of
+well known limitations:
+
+* Although ``ini2toml`` attempts to keep the same order/sequence as the 
original
+  information was written, sometimes that is not compatible with the TOML
+  syntax, and things end up moving around a bit.
+
+* ``ini2toml`` uses `ConfigParser`_ + `tomli-w`_ for implementing the *"lite"* 
flavour
+  and `ConfigUpdater`_ + `tomlkit`_ for implementing the *"full"* flavour.
+  Therefore it inherits the limitations from those libraries (please check
+  their documentation for more information). For example:
+
+  * `ConfigUpdater`_, will have trouble to parse interpolations and the related
+    escaping sequence (``%%``) (in this respect, it behaves more similarly to
+    ``RawConfigParser`` than ``ConfigParser``).
+
+  * `tomli-w`_ is not very flexible regarding formatting and will have trouble
+    with multi-line strings.
+
+* ``ini2toml`` *expects the input to be valid* and will not perform extensive
+  checks on the provided document. If something in the output is not working 
as you would
+  expect, it might be a good idea to check the input.
+
+* ``.ini/.cfg`` files are used in a plethora of use cases and it is impossible
+  to cover all of them in a single code base. Even when considering
+  ``setup.cfg``, there are many packages that define different sections in the
+  document in addition to the basic definition by ``setuptools``.
+  Because of that ``ini2toml``, adopts a "best-effort" approach, that might not
+  correspond to what you expect. If that is the case please consider
+  contributing or creating your own `plugin`_.
+
+* The translation procedure analyse only the given input. If the original
+  ``.ini/.cfg`` file contains references to other files, or behaves differently
+  depending on the existence/presence of other files and directories, the
+  translation will not take that into consideration.
+
+Therefore it is recommended to double check the output and fix any
+problems before using the ``.toml`` files in production.
+
+
+Can ``ini2toml`` also translate ``setup.py`` into ``pyproject.toml``?
+=====================================================================
+
+Working with ``.py`` files is not in the scope of the ``ini2toml`` project,
+and therefore this feature is not implemented.
+
+However, you can probably find some tools on PyPI to translate from
+``setup.py`` into ``setup.cfg``, like `setup-py-upgrade`_ and
+`setuptools-py2cfg`_ [#untested]_.
+
+Once you have ``setup.cfg``, you can use ``ini2toml`` [#setuppy]_.
+
+.. [#untested] Such tools are neither maintained by this project,
+   nor tested for integration by ``ini2toml``.
+   It is best to try some of them out and find the one that works for you.
+   Manual corrections might be needed.
+
+.. [#setuppy] Please note that ``setup.py`` is a very dynamic
+   format and that not everything can be represented in ``setup.cfg`` or
+   ``pyproject.toml``. Indeed, the `setuptools' docs`_ explicitly say that
+   ``setup.py`` can be used in tandem with ``pyproject.toml``: ideally all the
+   declarative metadata goes to ``pyproject.toml``, but you can keep the
+   dynamic bits in ``setup.py``.
+   Remember: ``setup.py`` is a perfectly valid and non deprecated 
configuration file;
+   what is deprecated is running it as a CLI tool, i.e. ``python setup.py 
...``.
+
+
 .. _pyscaffold-notes:
 
 .. tip::
@@ -167,8 +244,14 @@
 .. _ini_cfg: 
https://docs.python.org/3/library/configparser.html#supported-ini-file-structure
 .. _our docs: https://ini2toml.readthedocs.io
 .. _PEP 621: https://www.python.org/dev/peps/pep-0621/
-.. _pipx: https://pypa.github.io/pipx/
+.. _pipx: https://pipx.pypa.io/stable/
 .. _project dependency: 
https://packaging.python.org/tutorials/managing-dependencies/
+.. _plugin: https://ini2toml.readthedocs.io/en/latest/dev-guide.html#plugins
+.. _setup-py-upgrade: https://pypi.org/project/setup-cfg-fmt/
+.. _setuptools-py2cfg: https://pypi.org/project/setuptools-py2cfg/
+.. _setuptools' docs: 
https://setuptools.pypa.io/en/latest/userguide/quickstart.html#setuppy-discouraged
 .. _TOML: https://toml.io/en/
 .. _TOML library: https://github.com/sdispater/tomlkit
+.. _tomli-w: https://pypi.org/project/tomli-w/
+.. _tomlkit: https://tomlkit.readthedocs.io/en/latest/
 .. _virtual environment: 
https://realpython.com/python-virtual-environments-a-primer/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/README.rst new/ini2toml-0.14/README.rst
--- old/ini2toml-0.13/README.rst        2023-10-23 14:15:48.000000000 +0200
+++ new/ini2toml-0.14/README.rst        2024-04-20 21:23:26.000000000 +0200
@@ -93,9 +93,86 @@
 To do so, don't forget to add it to your `virtual environment`_ or specify it 
as a
 `project dependency`_.
 
+Note that the class ``Translator`` will try to guess which flavour to use based
+on the available installed dependencies. If you need something more
+deterministic, consider using ``LiteTranslator`` and ``FullTranslator``,
+or explicitly specifying the ``ini_loads_fn`` and ``toml_dumps_fn`` keyword
+arguments in the constructor.
+
 More details about ``ini2toml`` and its Python API can be found in `our docs`_.
 
 
+Limitations
+===========
+
+``ini2toml`` will try its best to create good quality translations from
+``.ini/.cfg`` into ``.toml`` files. However the tool comes with a set of
+well known limitations:
+
+* Although ``ini2toml`` attempts to keep the same order/sequence as the 
original
+  information was written, sometimes that is not compatible with the TOML
+  syntax, and things end up moving around a bit.
+
+* ``ini2toml`` uses `ConfigParser`_ + `tomli-w`_ for implementing the *"lite"* 
flavour
+  and `ConfigUpdater`_ + `tomlkit`_ for implementing the *"full"* flavour.
+  Therefore it inherits the limitations from those libraries (please check
+  their documentation for more information). For example:
+
+  * `ConfigUpdater`_, will have trouble to parse interpolations and the related
+    escaping sequence (``%%``) (in this respect, it behaves more similarly to
+    ``RawConfigParser`` than ``ConfigParser``).
+
+  * `tomli-w`_ is not very flexible regarding formatting and will have trouble
+    with multi-line strings.
+
+* ``ini2toml`` *expects the input to be valid* and will not perform extensive
+  checks on the provided document. If something in the output is not working 
as you would
+  expect, it might be a good idea to check the input.
+
+* ``.ini/.cfg`` files are used in a plethora of use cases and it is impossible
+  to cover all of them in a single code base. Even when considering
+  ``setup.cfg``, there are many packages that define different sections in the
+  document in addition to the basic definition by ``setuptools``.
+  Because of that ``ini2toml``, adopts a "best-effort" approach, that might not
+  correspond to what you expect. If that is the case please consider
+  contributing or creating your own `plugin`_.
+
+* The translation procedure analyse only the given input. If the original
+  ``.ini/.cfg`` file contains references to other files, or behaves differently
+  depending on the existence/presence of other files and directories, the
+  translation will not take that into consideration.
+
+Therefore it is recommended to double check the output and fix any
+problems before using the ``.toml`` files in production.
+
+
+Can ``ini2toml`` also translate ``setup.py`` into ``pyproject.toml``?
+=====================================================================
+
+Working with ``.py`` files is not in the scope of the ``ini2toml`` project,
+and therefore this feature is not implemented.
+
+However, you can probably find some tools on PyPI to translate from
+``setup.py`` into ``setup.cfg``, like `setup-py-upgrade`_ and
+`setuptools-py2cfg`_ [#untested]_.
+
+Once you have ``setup.cfg``, you can use ``ini2toml`` [#setuppy]_.
+
+.. [#untested] Such tools are neither maintained by this project,
+   nor tested for integration by ``ini2toml``.
+   It is best to try some of them out and find the one that works for you.
+   Manual corrections might be needed.
+
+.. [#setuppy] Please note that ``setup.py`` is a very dynamic
+   format and that not everything can be represented in ``setup.cfg`` or
+   ``pyproject.toml``. Indeed, the `setuptools' docs`_ explicitly say that
+   ``setup.py`` can be used in tandem with ``pyproject.toml``: ideally all the
+   declarative metadata goes to ``pyproject.toml``, but you can keep the
+   dynamic bits in ``setup.py``.
+   Remember: ``setup.py`` is a perfectly valid and non deprecated 
configuration file;
+   what is deprecated is running it as a CLI tool, i.e. ``python setup.py 
...``.
+
+
 .. _pyscaffold-notes:
 
 .. tip::
@@ -122,8 +199,14 @@
 .. _ini_cfg: 
https://docs.python.org/3/library/configparser.html#supported-ini-file-structure
 .. _our docs: https://ini2toml.readthedocs.io
 .. _PEP 621: https://www.python.org/dev/peps/pep-0621/
-.. _pipx: https://pypa.github.io/pipx/
+.. _pipx: https://pipx.pypa.io/stable/
 .. _project dependency: 
https://packaging.python.org/tutorials/managing-dependencies/
+.. _plugin: https://ini2toml.readthedocs.io/en/latest/dev-guide.html#plugins
+.. _setup-py-upgrade: https://pypi.org/project/setup-cfg-fmt/
+.. _setuptools-py2cfg: https://pypi.org/project/setuptools-py2cfg/
+.. _setuptools' docs: 
https://setuptools.pypa.io/en/latest/userguide/quickstart.html#setuppy-discouraged
 .. _TOML: https://toml.io/en/
 .. _TOML library: https://github.com/sdispater/tomlkit
+.. _tomli-w: https://pypi.org/project/tomli-w/
+.. _tomlkit: https://tomlkit.readthedocs.io/en/latest/
 .. _virtual environment: 
https://realpython.com/python-virtual-environments-a-primer/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/docs/conf.py 
new/ini2toml-0.14/docs/conf.py
--- old/ini2toml-0.13/docs/conf.py      2023-10-23 14:15:48.000000000 +0200
+++ new/ini2toml-0.14/docs/conf.py      2024-04-20 21:23:26.000000000 +0200
@@ -18,41 +18,16 @@
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
+sys.path.insert(0, os.path.join(__location__))
 sys.path.insert(0, os.path.join(__location__, "../src"))
 
-# -- Run sphinx-apidoc -------------------------------------------------------
-# This hack is necessary since RTD does not issue `sphinx-apidoc` before 
running
-# `sphinx-build -b html . _build/html`. See Issue:
-# https://github.com/readthedocs/readthedocs.org/issues/1139
-# DON'T FORGET: Check the box "Install your project inside a virtualenv using
-# setup.py install" in the RTD Advanced Settings.
-# Additionally it helps us to avoid running apidoc manually
+# -- Automatically generated content ------------------------------------------
 
-try:  # for Sphinx >= 1.7
-    from sphinx.ext import apidoc
-except ImportError:
-    from sphinx import apidoc
+import public_api_docs
 
 output_dir = os.path.join(__location__, "api")
 module_dir = os.path.join(__location__, "../src/ini2toml")
-try:
-    shutil.rmtree(output_dir)
-except FileNotFoundError:
-    pass
-
-try:
-    import sphinx
-
-    cmd_line = f"sphinx-apidoc --implicit-namespaces -f -o {output_dir} 
{module_dir}"
-
-    args = cmd_line.split(" ")
-    if tuple(sphinx.__version__.split(".")) >= ("1", "7"):
-        # This is a rudimentary parse_version to avoid external dependencies
-        args = args[1:]
-
-    apidoc.main(args)
-except Exception as e:
-    print("Running `sphinx-apidoc` failed!\n{}".format(e))
+public_api_docs.gen_stubs(module_dir, output_dir)
 
 # -- General configuration ---------------------------------------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/docs/dev-guide.rst 
new/ini2toml-0.14/docs/dev-guide.rst
--- old/ini2toml-0.13/docs/dev-guide.rst        2023-10-23 14:15:48.000000000 
+0200
+++ new/ini2toml-0.14/docs/dev-guide.rst        2024-04-20 21:23:26.000000000 
+0200
@@ -96,8 +96,7 @@
 
 .. code-block:: python
 
-   def text_process(file_contents: str) -> str:
-       ...
+   def text_process(file_contents: str) -> str: ...
 
 
 .. important:: All processors are called in sequence, so the output of one is
@@ -119,8 +118,7 @@
 
 .. code-block:: python
 
-   def intermediate_process(intermediate: IntermediateRepr) -> 
IntermediateRepr:
-       ...
+   def intermediate_process(intermediate: IntermediateRepr) -> 
IntermediateRepr: ...
 
 :class:`~ini2toml.intermediate_repr.IntermediateRepr` is a special kind of
 Python object with characteristics of both :obj:`dict` and :obj:`list`.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/docs/public_api_docs.py 
new/ini2toml-0.14/docs/public_api_docs.py
--- old/ini2toml-0.13/docs/public_api_docs.py   1970-01-01 01:00:00.000000000 
+0100
+++ new/ini2toml-0.14/docs/public_api_docs.py   2024-04-20 21:23:26.000000000 
+0200
@@ -0,0 +1,77 @@
+import shutil
+from pathlib import Path
+
+TOC_TEMPLATE = """
+Module Reference
+================
+
+.. toctree::
+   :glob:
+   :maxdepth: 2
+
+   ini2toml.api
+   ini2toml.errors
+   ini2toml.types
+
+.. toctree::
+   :maxdepth: 1
+
+   ini2toml.transformations
+
+.. toctree::
+   :caption: Plugins
+   :glob:
+   :maxdepth: 1
+
+   plugins/*
+"""
+
+MODULE_TEMPLATE = """
+``{name}``
+~~{underline}~~
+
+.. automodule:: {name}
+   :members:{_members}
+   :undoc-members:
+   :show-inheritance:
+"""
+
+
+def gen_stubs(module_dir: str, output_dir: str):
+    try_rmtree(output_dir)  # Always start fresh
+    Path(output_dir, "plugins").mkdir(parents=True, exist_ok=True)
+    for module in iter_public():
+        text = module_template(module)
+        Path(output_dir, f"{module}.rst").write_text(text, encoding="utf-8")
+    for module in iter_plugins(module_dir):
+        text = module_template(module, "activate")
+        Path(output_dir, f"plugins/{module}.rst").write_text(text, 
encoding="utf-8")
+    Path(output_dir, "modules.rst").write_text(TOC_TEMPLATE, encoding="utf-8")
+
+
+def iter_public():
+    lines = (x.strip() for x in TOC_TEMPLATE.splitlines())
+    return (x for x in lines if x.startswith("ini2toml."))
+
+
+def iter_plugins(module_dir: str):
+    return (
+        f'ini2toml.plugins.{path.with_suffix("").name}'
+        for path in Path(module_dir, "plugins").iterdir()
+        if path.is_file()
+        and path.name not in {".", "..", "__init__.py"}
+        and not path.name.startswith("_")
+    )
+
+
+def try_rmtree(target_dir: str):
+    try:
+        shutil.rmtree(target_dir)
+    except FileNotFoundError:
+        pass
+
+
+def module_template(name: str, *members: str) -> str:
+    underline = "~" * len(name)
+    _members = (" " + ", ".join(members)) if members else ""
+    return MODULE_TEMPLATE.format(name=name, underline=underline, 
_members=_members)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/setup.cfg new/ini2toml-0.14/setup.cfg
--- old/ini2toml-0.13/setup.cfg 2023-10-23 14:17:02.446848400 +0200
+++ new/ini2toml-0.14/setup.cfg 2024-04-20 21:24:34.163375100 +0200
@@ -75,12 +75,12 @@
 
 [tool:pytest]
 addopts = 
-       --cov ini2toml --cov-report term-missing -vv
+       --cov ini2toml --cov-report term-missing -vv --doctest-modules
 norecursedirs = 
        dist
        build
        .tox
-testpaths = tests
+testpaths = src tests
 
 [devpi:upload]
 no_vcs = 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/setup.py new/ini2toml-0.14/setup.py
--- old/ini2toml-0.13/setup.py  2023-10-23 14:15:48.000000000 +0200
+++ new/ini2toml-0.14/setup.py  2024-04-20 21:23:26.000000000 +0200
@@ -6,6 +6,7 @@
     PyScaffold helps you to put up the scaffold of your new Python project.
     Learn more under: https://pyscaffold.org/
 """
+
 from setuptools import setup
 
 if __name__ == "__main__":
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/src/ini2toml/api.py 
new/ini2toml-0.14/src/ini2toml/api.py
--- old/ini2toml-0.13/src/ini2toml/api.py       2023-10-23 14:15:48.000000000 
+0200
+++ new/ini2toml-0.14/src/ini2toml/api.py       2024-04-20 21:23:26.000000000 
+0200
@@ -13,13 +13,17 @@
 for checking `structural polymorphism`_ during static analysis).
 These should be preferred when writing type hints and signatures.
 
-Plugin authors can also rely on the functions exported by
-:mod:`~ini2toml.transformations`.
+Plugin authors can also use functions exported by 
:mod:`~ini2toml.transformations`.
 
 .. _structural polymorphism: https://www.python.org/dev/peps/pep-0544/
 """
-from . import errors, transformations, types
+
 from .base_translator import BaseTranslator
-from .translator import Translator
+from .translator import FullTranslator, LiteTranslator, Translator
 
-__all__ = ["BaseTranslator", "Translator", "errors", "types", 
"transformations"]
+__all__ = [
+    "BaseTranslator",
+    "FullTranslator",
+    "LiteTranslator",
+    "Translator",
+]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/src/ini2toml/base_translator.py 
new/ini2toml-0.14/src/ini2toml/base_translator.py
--- old/ini2toml-0.13/src/ini2toml/base_translator.py   2023-10-23 
14:15:48.000000000 +0200
+++ new/ini2toml-0.14/src/ini2toml/base_translator.py   2024-04-20 
21:23:26.000000000 +0200
@@ -18,7 +18,7 @@
 
 class BaseTranslator(Generic[T]):
     """Translator object that follows the public API defined in
-    :class:`ini2toml.types.Translator`. See :doc:`dev-guide` for a quick 
explanation of
+    :class:`ini2toml.types.Translator`. See :doc:`/dev-guide` for a quick 
explanation of
     concepts such as plugins, profiles, profile augmentations, etc.
 
     Arguments
@@ -68,7 +68,8 @@
     Tip
     ---
 
-    Most of the times the usage of :class:`~ini2toml.translator.Translator` is 
preferred
+    Most of the times the usage of :class:`~ini2toml.translator.Translator`
+    (or its deterministic variants ``LiteTranslator``, ``FullTranslator``) is 
preferred
     over :class:`~ini2toml.base_translator.BaseTranslator` (unless you are 
vendoring
     ``ini2toml`` and wants to reduce the number of files included in your 
project).
     """
@@ -121,7 +122,7 @@
         help_text: str = "",
     ):
         """Register a profile augmentation function to be called after the
-        profile is selected and before the actual translation (see 
:doc:`dev-guide`).
+        profile is selected and before the actual translation (see 
:doc:`/dev-guide`).
         """
         name = (name or fn.__name__).strip()
         InvalidAugmentationName.check(name)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/src/ini2toml/drivers/full_toml.py 
new/ini2toml-0.14/src/ini2toml/drivers/full_toml.py
--- old/ini2toml-0.13/src/ini2toml/drivers/full_toml.py 2023-10-23 
14:15:48.000000000 +0200
+++ new/ini2toml-0.14/src/ini2toml/drivers/full_toml.py 2024-04-20 
21:23:26.000000000 +0200
@@ -3,6 +3,7 @@
 It makes it easy to swap between implementations for testing (by means of 
search and
 replace).
 """
+
 from collections import UserList
 from collections.abc import Mapping, MutableSequence, Sequence
 from functools import singledispatch
@@ -317,8 +318,9 @@
     literal = '"' in obj or "\\" in single_line
 
     if multiline and not obj.startswith("\n"):
-        # TOML will automatically strip an starting newline
-        # so let's add it, since it is better for reading
+        # TOML feature: during parsing a starting newline character in a 
multi-line
+        # string will be stripped away.
+        # So we are free to add it, since it is better for reading
         obj = "\n" + obj
 
     try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/src/ini2toml/drivers/lite_toml.py 
new/ini2toml-0.14/src/ini2toml/drivers/lite_toml.py
--- old/ini2toml-0.13/src/ini2toml/drivers/lite_toml.py 2023-10-23 
14:15:48.000000000 +0200
+++ new/ini2toml-0.14/src/ini2toml/drivers/lite_toml.py 2024-04-20 
21:23:26.000000000 +0200
@@ -3,6 +3,7 @@
 It makes it easy to swap between implementations for testing (by means of 
search and
 replace).
 """
+
 try:
     from tomli_w import dumps
 except ImportError:  # pragma: no cover
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/src/ini2toml/drivers/plain_builtins.py 
new/ini2toml-0.14/src/ini2toml/drivers/plain_builtins.py
--- old/ini2toml-0.13/src/ini2toml/drivers/plain_builtins.py    2023-10-23 
14:15:48.000000000 +0200
+++ new/ini2toml-0.14/src/ini2toml/drivers/plain_builtins.py    2024-04-20 
21:23:26.000000000 +0200
@@ -4,6 +4,7 @@
 
 This is **not a loss-less** process, since comments are not preserved.
 """
+
 from collections.abc import Mapping, MutableMapping
 from functools import singledispatch
 from typing import Any, TypeVar
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/src/ini2toml/errors.py 
new/ini2toml-0.14/src/ini2toml/errors.py
--- old/ini2toml-0.13/src/ini2toml/errors.py    2023-10-23 14:15:48.000000000 
+0200
+++ new/ini2toml-0.14/src/ini2toml/errors.py    2024-04-20 21:23:26.000000000 
+0200
@@ -15,6 +15,7 @@
 
     @classmethod
     def check(cls, name: str, available: List[str]):
+        """:meta private:"""
         if name not in available:
             raise cls(name, available)
 
@@ -37,6 +38,7 @@
     def check(
         cls, name: str, fn: Callable, registry: Mapping[str, 
types.ProfileAugmentation]
     ):
+        """:meta private:"""
         if name in registry:
             raise cls(name, fn, registry[name].fn)
 
@@ -63,7 +65,7 @@
 
 
 class InvalidCfgBlock(ValueError):  # pragma: no cover -- not supposed to 
happen
-    """Something is wrong with the provided CFG AST, the given block is not 
valid."""
+    """Something is wrong with the provided ``.ini/.cfg`` AST"""
 
     def __init__(self, block):
         super().__init__(f"{block.__class__}: {block}", {"block_object": 
block})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/src/ini2toml/intermediate_repr.py 
new/ini2toml-0.14/src/ini2toml/intermediate_repr.py
--- old/ini2toml-0.13/src/ini2toml/intermediate_repr.py 2023-10-23 
14:15:48.000000000 +0200
+++ new/ini2toml-0.14/src/ini2toml/intermediate_repr.py 2024-04-20 
21:23:26.000000000 +0200
@@ -1,6 +1,7 @@
 """Intermediate representations used by ``ini2toml`` when transforming between
 the INI and TOML syntaxes.
 """
+
 from collections import UserList
 from enum import Enum
 from itertools import chain
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/src/ini2toml/plugins/best_effort.py 
new/ini2toml-0.14/src/ini2toml/plugins/best_effort.py
--- old/ini2toml-0.13/src/ini2toml/plugins/best_effort.py       2023-10-23 
14:15:48.000000000 +0200
+++ new/ini2toml-0.14/src/ini2toml/plugins/best_effort.py       2024-04-20 
21:23:26.000000000 +0200
@@ -7,8 +7,8 @@
 
 M = TypeVar("M", bound=IntermediateRepr)
 
-SECTION_SPLITTER = re.compile(r"\.|:|\\")
-KEY_SEP = "="
+_SECTION_SPLITTER = re.compile(r"\.|:|\\")
+_KEY_SEP = "="
 
 
 def activate(translator: Translator):
@@ -23,12 +23,12 @@
 
     def __init__(
         self,
-        key_sep=KEY_SEP,
-        section_splitter=SECTION_SPLITTER,
+        key_sep=_KEY_SEP,
+        section_splitter=_SECTION_SPLITTER,
     ):
         self.key_sep = key_sep
         self.section_splitter = section_splitter
-        self.split_dict = partial(split_kv_pairs, key_sep=KEY_SEP)
+        self.split_dict = partial(split_kv_pairs, key_sep=key_sep)
 
     def process_values(self, doc: M) -> M:
         doc_items = list(doc.items())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ini2toml-0.13/src/ini2toml/plugins/profile_independent_tasks.py 
new/ini2toml-0.14/src/ini2toml/plugins/profile_independent_tasks.py
--- old/ini2toml-0.13/src/ini2toml/plugins/profile_independent_tasks.py 
2023-10-23 14:15:48.000000000 +0200
+++ new/ini2toml-0.14/src/ini2toml/plugins/profile_independent_tasks.py 
2024-04-20 21:23:26.000000000 +0200
@@ -1,4 +1,5 @@
 """Profile-independent tasks implemented via *profile augmentation*."""
+
 import re
 from functools import wraps
 from typing import Callable
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/src/ini2toml/plugins/pytest.py 
new/ini2toml-0.14/src/ini2toml/plugins/pytest.py
--- old/ini2toml-0.13/src/ini2toml/plugins/pytest.py    2023-10-23 
14:15:48.000000000 +0200
+++ new/ini2toml-0.14/src/ini2toml/plugins/pytest.py    2024-04-20 
21:23:26.000000000 +0200
@@ -1,16 +1,19 @@
 # 
https://docs.pytest.org/en/latest/reference/reference.html#configuration-options
 # 
https://docs.pytest.org/en/latest/reference/customize.html#config-file-formats
+import logging
 from collections.abc import MutableMapping
 from functools import partial
-from typing import TypeVar
+from typing import TypeVar, Union
 
-from ..transformations import coerce_scalar, split_list
-from ..types import IntermediateRepr, Translator
+from ..transformations import coerce_scalar, remove_comments, split_comment, 
split_list
+from ..types import Commented, IntermediateRepr, Translator
 
 R = TypeVar("R", bound=IntermediateRepr)
 
-split_spaces = partial(split_list, sep=" ")
-split_lines = partial(split_list, sep="\n")
+_logger = logging.getLogger(__name__)
+
+_split_spaces = partial(split_list, sep=" ")
+_split_lines = partial(split_list, sep="\n")
 # ^ most of the list values in pytest use whitespace separators,
 #   but markers/filterwarnings are a special case.
 
@@ -60,8 +63,30 @@
             if field in self.DONT_TOUCH:
                 continue
             if field in self.LINE_SEPARATED_LIST_VALUES:
-                section[field] = split_lines(section[field])
+                section[field] = _split_lines(section[field])
             elif field in self.SPACE_SEPARATED_LIST_VALUES:
-                section[field] = split_spaces(section[field])
+                section[field] = _split_spaces(section[field])
+            elif hasattr(self, f"_process_{field}"):
+                section[field] = getattr(self, 
f"_process_{field}")(section[field])
             else:
                 section[field] = coerce_scalar(section[field])
+
+    def _process_addopts(self, content: str) -> Union[Commented[str], str]:
+        # pytest-dev/pytest#12228: pytest maintainers recommend addopts as 
string.
+        # However, it cannot handle embedded comments, so we have to strip 
them.
+
+        if "\n" not in content:
+            # It is easy to handle inline comments for a single line.
+            return split_comment(content)
+
+        if "#" not in content:
+            return content
+
+        msg = (
+            "Stripping comments from `tool.pytest.ini_options.addopts`.\n"
+            "This field is recommended to be a string, however it cannot "
+            "contain embedded comments (ref: pytest-dev/pytest#12228)."
+        )
+        _logger.warning(msg)
+
+        return remove_comments(content)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ini2toml-0.13/src/ini2toml/plugins/setuptools_pep621.py 
new/ini2toml-0.14/src/ini2toml/plugins/setuptools_pep621.py
--- old/ini2toml-0.13/src/ini2toml/plugins/setuptools_pep621.py 2023-10-23 
14:15:48.000000000 +0200
+++ new/ini2toml-0.14/src/ini2toml/plugins/setuptools_pep621.py 2024-04-20 
21:23:26.000000000 +0200
@@ -438,8 +438,13 @@
         options = doc["options"]
         # Abort when not using find or find_namespace
         packages = options.get("packages")
+
         if not isinstance(packages, Directive):
+            if "options.packages.find" in doc:
+                _ConfusingPackagesConfig.emit()
+                doc.pop("options.packages.find", None)
             return doc
+
         prefix = packages.kind.replace("_", "-")
         # Enhancement #1: Unify find and find_namespaces, using `namespaces` 
as a flag
         options["packages"] = Directive("find", {"namespaces": "namespace" in 
prefix})
@@ -845,3 +850,24 @@
     keep1, keep2 = values1[:-1], values2[1:]
     shared = values1[-1].strip().strip("\\").strip() + " " + values2[0].strip()
     return Commented(keep1 + [shared] + keep2, line2.comment)
+
+
+class _ConfusingPackagesConfig(UserWarning):
+    _MSG = """Confusing configuration `[options.packages.find]`.
+
+    Original configuration sets both:
+
+    - `[options] packages = ...` as a list of named packages
+    - `[options.packages.find]`
+
+    The confusion comes from the fact that `[options.packages.find]` should be 
used
+    with `[options] packages = find:` or `[options] packages = 
find_namespace:`.
+
+    Conversion will ignore `[options.packages.find]`, as it cannot be written 
in the
+    TOML format when `[options] packages = ...` is already given.
+    """
+    __doc__ = _MSG
+
+    @classmethod
+    def emit(cls, msg=_MSG, stacklevel=1):
+        warnings.warn(msg, category=cls, stacklevel=stacklevel + 1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/src/ini2toml/transformations.py 
new/ini2toml-0.14/src/ini2toml/transformations.py
--- old/ini2toml-0.13/src/ini2toml/transformations.py   2023-10-23 
14:15:48.000000000 +0200
+++ new/ini2toml-0.14/src/ini2toml/transformations.py   2024-04-20 
21:23:26.000000000 +0200
@@ -1,4 +1,17 @@
-"""Reusable value and type casting transformations"""
+"""
+Reusable value and type casting transformations
+
+This module is stable  on a "best effort"-basis, and small backwards 
incompatibilities
+can be introduced in "minor"/"patch" version bumps (it will not be considered a
+regression automatically).
+While it can be used by plugin writers, it is not intended for general public 
use.
+
+.. testsetup:: *
+
+   # workaround for missing import in sphinx-doctest
+   from ini2toml.transformations import *
+"""
+
 import warnings
 from collections.abc import MutableMapping
 from functools import reduce, wraps
@@ -45,7 +58,7 @@
   For example: transforming ``"2"`` (string) into ``2`` (integer).
 - The second one tries to preserve metadata (such as comments) from the 
original CFG/INI
   file. This kind of transformation processes a string value into an 
intermediary
-  representation (e.g. :obj:`Commented`, :obj:`CommentedList`, 
obj:`CommentedKV`)
+  representation (e.g. :obj:`Commented`, :obj:`CommentedList`, 
:obj:`CommentedKV`)
   that needs to be properly handled before adding to the TOML document.
 
 In a higher level we can also consider an ensemble of transformations that 
transform an
@@ -60,15 +73,18 @@
 
 
 def noop(x: T) -> T:
+    """Return the value unchanged"""
     return x
 
 
 def is_true(value: str) -> bool:
+    """``value in ("true", "1", "yes", "on")``"""
     value = value.lower()
     return value in ("true", "1", "yes", "on")
 
 
 def is_false(value: str) -> bool:
+    """``value in ("false", "0", "no", "off", "none", "null", "nil")``"""
     value = value.lower()
     return value in ("false", "0", "no", "off", "none", "null", "nil")
 
@@ -79,6 +95,7 @@
 
 
 def coerce_bool(value: str) -> bool:
+    """Convert the value based on :func:`~.is_true` and :func:`~.is_false`."""
     if is_true(value):
         return True
     if is_false(value):
@@ -140,18 +157,17 @@
 
 
 @overload
-def split_comment(value: str, *, comment_prefixes=CP) -> Commented[str]:
-    ...
+def split_comment(value: str, *, comment_prefixes=CP) -> Commented[str]: ...
 
 
 @overload
 def split_comment(
     value: str, coerce_fn: CoerceFn[T], comment_prefixes=CP
-) -> Commented[T]:
-    ...
+) -> Commented[T]: ...
 
 
 def split_comment(value, coerce_fn=noop, comment_prefixes=CP):
+    """Split a "comment suffix" from the value."""
     if not isinstance(value, str):
         return value
     value = value.strip()
@@ -162,14 +178,15 @@
         return Commented(coerce_fn(value))
 
     if any(value.startswith(p) for p in comment_prefixes):
-        return Commented(comment=_strip_comment(value, comment_prefixes))
+        return Commented(comment=_strip_prefix(value, comment_prefixes))
 
     prefix = prefixes[0]  # We can only analyse one...
     value, _, cmt = value.partition(prefix)
-    return Commented(coerce_fn(value.strip()), _strip_comment(cmt, 
comment_prefixes))
+    return Commented(coerce_fn(value.strip()), _strip_prefix(cmt, 
comment_prefixes))
 
 
 def split_scalar(value: str, *, comment_prefixes=CP) -> Commented[Scalar]:
+    """Combination of :func:`~.split_comment` and :func:`~.coerce_scalar`."""
     return split_comment(value, coerce_scalar, comment_prefixes)
 
 
@@ -181,8 +198,7 @@
     subsplit_dangling=True,
     comment_prefixes=CP,
     force_multiline=False,
-) -> CommentedList[str]:
-    ...
+) -> CommentedList[str]: ...
 
 
 @overload
@@ -194,8 +210,7 @@
     subsplit_dangling=True,
     comment_prefixes=CP,
     force_multiline=False,
-) -> CommentedList[T]:
-    ...
+) -> CommentedList[T]: ...
 
 
 @overload
@@ -206,8 +221,7 @@
     subsplit_dangling=True,
     comment_prefixes=CP,
     force_multiline=False,
-) -> CommentedList[T]:
-    ...
+) -> CommentedList[T]: ...
 
 
 def split_list(
@@ -247,8 +261,7 @@
     pair_sep=",",
     subsplit_dangling=True,
     comment_prefixes=CP,
-) -> CommentedKV[str]:
-    ...
+) -> CommentedKV[str]: ...
 
 
 @overload
@@ -260,8 +273,7 @@
     pair_sep=",",
     subsplit_dangling=True,
     comment_prefixes=CP,
-) -> CommentedKV[T]:
-    ...
+) -> CommentedKV[T]: ...
 
 
 @overload
@@ -272,8 +284,7 @@
     pair_sep=",",
     subsplit_dangling=True,
     comment_prefixes=CP,
-) -> CommentedKV[T]:
-    ...
+) -> CommentedKV[T]: ...
 
 
 def split_kv_pairs(
@@ -326,25 +337,21 @@
 
 
 @overload
-def pipe(fn1: FN[S, T], fn2: FN[T, U]) -> FN[S, U]:
-    ...
+def pipe(fn1: FN[S, T], fn2: FN[T, U]) -> FN[S, U]: ...
 
 
 @overload
-def pipe(fn1: FN[S, T], fn2: FN[T, U], fn3: FN[U, V]) -> FN[S, V]:
-    ...
+def pipe(fn1: FN[S, T], fn2: FN[T, U], fn3: FN[U, V]) -> FN[S, V]: ...
 
 
 @overload
-def pipe(fn1: FN[S, T], fn2: FN[T, U], fn3: FN[U, V], fn4: FN[V, X]) -> FN[S, 
X]:
-    ...
+def pipe(fn1: FN[S, T], fn2: FN[T, U], fn3: FN[U, V], fn4: FN[V, X]) -> FN[S, 
X]: ...
 
 
 @overload
 def pipe(
     fn1: FN[S, T], fn2: FN[T, U], fn3: FN[U, V], fn4: FN[V, X], fn5: FN[X, Y]
-) -> FN[S, Y]:
-    ...
+) -> FN[S, Y]: ...
 
 
 @overload
@@ -355,8 +362,7 @@
     fn4: FN[V, X],
     fn5: FN[X, Y],
     *fn: FN[Y, Y],
-) -> FN[S, Y]:
-    ...
+) -> FN[S, Y]: ...
 
 
 def pipe(*fns):
@@ -369,10 +375,44 @@
     return lambda x: reduce(apply, fns, x)
 
 
+def remove_comments(text: str, comment_mark="#") -> str:
+    r"""
+    >>> remove_comments("\nhello\n#comment\nworld\n")
+    '\nhello\nworld\n'
+    >>> remove_comments("\n  hello\n\nworld\n")
+    '\n  hello\n\nworld\n'
+    >>> remove_comments("\nhello\n  \nworld\n")
+    '\nhello\n  \nworld\n'
+    """
+    lines = (_line_remove_comment(x, comment_mark) for x in text.splitlines())
+    suffix = "\n" if text.strip(" ").endswith("\n") else ""
+    return "\n".join(x for x in lines if x is not None) + suffix
+
+
 # ---- Private Helpers ----
 
 
-def _strip_comment(msg: Optional[str], prefixes: Sequence[str] = CP) -> 
Optional[str]:
+def _line_remove_comment(line: str, comment_mark="#") -> Optional[str]:
+    """
+    >>> print(_line_remove_comment("   # hello world"))
+    None
+    >>> _line_remove_comment("   abc # hello world")
+    '   abc'
+    >>> _line_remove_comment("   ")
+    '   '
+    >>> _line_remove_comment("")
+    ''
+    """
+    if comment_mark not in line:
+        # Keep empty lines intentionally added by the user
+        return line
+    if line.strip().startswith(comment_mark):
+        # Remove empty lines that were just inserted as a replacement for 
comments
+        return None
+    return line.partition(comment_mark)[0].rstrip()
+
+
+def _strip_prefix(msg: Optional[str], prefixes: Sequence[str] = CP) -> 
Optional[str]:
     if not msg:
         return None
     return remove_prefixes(msg, prefixes)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/src/ini2toml/translator.py 
new/ini2toml-0.14/src/ini2toml/translator.py
--- old/ini2toml-0.13/src/ini2toml/translator.py        2023-10-23 
14:15:48.000000000 +0200
+++ new/ini2toml-0.14/src/ini2toml/translator.py        2024-04-20 
21:23:26.000000000 +0200
@@ -8,6 +8,10 @@
 _logger = logging.getLogger(__name__)
 
 
+# TODO: Once MyPy/other type checkers handle ``partial`` and ``partialmethod``
+#       we probably can use them to simply the implementations in this module.
+
+
 class Translator(BaseTranslator[str]):
     """``Translator`` is the main public Python API exposed by the 
``ini2toml``,
     to convert strings representing ``.ini/.cfg`` files into the ``TOML`` 
syntax.
@@ -20,6 +24,8 @@
     while ``BaseTranslator`` requires the user to explicitly set these 
parameters.
 
     For most of the users ``Translator`` is recommended over 
``BaseTranslator``.
+    Most of the times ``Translator`` (or its deterministic variants 
``LiteTranslator``,
+    ``FullTranslator``) is recommended over ``BaseTranslator``.
 
     See :class:`~ini2toml.base_translator.BaseTranslator` for a description of 
the
     instantiation parameters.
@@ -67,3 +73,73 @@
             raise
 
     return convert
+
+
+class LiteTranslator(Translator):
+    """Similar to ``Translator``, but instead of trying to figure out 
``ini_loads_fn``
+    and ``toml_dumps_fn`` is will always try to use the ``lite`` flavour
+    (ignoring comments).
+    """
+
+    def __init__(
+        self,
+        plugins: Optional[Sequence[types.Plugin]] = None,
+        profiles: Sequence[types.Profile] = (),
+        profile_augmentations: Sequence[types.ProfileAugmentation] = (),
+        ini_parser_opts: Mapping = EMPTY,
+        ini_loads_fn: Optional[types.IniLoadsFn] = None,
+        toml_dumps_fn: Optional[types.TomlDumpsFn] = None,
+    ):
+        if ini_loads_fn:
+            parse = ini_loads_fn
+        else:
+            from .drivers.configparser import parse
+
+        if toml_dumps_fn:
+            convert = toml_dumps_fn
+        else:
+            from .drivers.lite_toml import convert
+
+        super().__init__(
+            ini_loads_fn=parse,
+            toml_dumps_fn=convert,
+            plugins=plugins,
+            ini_parser_opts=ini_parser_opts,
+            profiles=profiles,
+            profile_augmentations=profile_augmentations,
+        )
+
+
+class FullTranslator(Translator):
+    """Similar to ``Translator``, but instead of trying to figure out 
``ini_loads_fn``
+    and ``toml_dumps_fn`` is will always try to use the ``full`` flavour
+    (best effort to maintain comments).
+    """
+
+    def __init__(
+        self,
+        plugins: Optional[Sequence[types.Plugin]] = None,
+        profiles: Sequence[types.Profile] = (),
+        profile_augmentations: Sequence[types.ProfileAugmentation] = (),
+        ini_parser_opts: Mapping = EMPTY,
+        ini_loads_fn: Optional[types.IniLoadsFn] = None,
+        toml_dumps_fn: Optional[types.TomlDumpsFn] = None,
+    ):
+        if ini_loads_fn:
+            parse = ini_loads_fn
+        else:
+            from .drivers.configupdater import parse
+
+        if toml_dumps_fn:
+            convert = toml_dumps_fn
+        else:
+            from .drivers.full_toml import convert
+
+        super().__init__(
+            ini_loads_fn=parse,
+            toml_dumps_fn=convert,
+            plugins=plugins,
+            ini_parser_opts=ini_parser_opts,
+            profiles=profiles,
+            profile_augmentations=profile_augmentations,
+        )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/src/ini2toml/types.py 
new/ini2toml-0.14/src/ini2toml/types.py
--- old/ini2toml-0.13/src/ini2toml/types.py     2023-10-23 14:15:48.000000000 
+0200
+++ new/ini2toml-0.14/src/ini2toml/types.py     2024-04-20 21:23:26.000000000 
+0200
@@ -43,6 +43,8 @@
 
 
 class CLIChoice(Protocol):
+    """:meta private:"""
+
     name: str
     help_text: str
 
@@ -60,14 +62,14 @@
     name: str
     help_text: str
 
-    def fn(self, profile: Profile):
-        ...
+    def fn(self, profile: Profile): ...
 
     def is_active(self, explicitly_active: Optional[bool] = None) -> bool:
         """``explicitly_active`` is a tree-state variable: ``True`` if the user
         explicitly asked for the augmentation, ``False`` if the user 
explicitly denied
         the augmentation, or ``None`` otherwise.
         """
+        ...
 
 
 class Translator(Protocol):
@@ -75,6 +77,7 @@
         """Create and register (and return) a translation :class:`Profile`
         (or return a previously registered one) (see :ref:`core-concepts`).
         """
+        ...
 
     def augment_profiles(
         self,
@@ -89,6 +92,7 @@
         strings), ``name`` is taken from ``fn.__name__`` and ``help_text`` is 
taken from
         ``fn.__doc__`` (docstring).
         """
+        ...
 
 
 Plugin = Callable[[Translator], None]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/src/ini2toml.egg-info/PKG-INFO 
new/ini2toml-0.14/src/ini2toml.egg-info/PKG-INFO
--- old/ini2toml-0.13/src/ini2toml.egg-info/PKG-INFO    2023-10-23 
14:17:02.000000000 +0200
+++ new/ini2toml-0.14/src/ini2toml.egg-info/PKG-INFO    2024-04-20 
21:24:34.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: ini2toml
-Version: 0.13
+Version: 0.14
 Summary: Automatically conversion of .ini/.cfg files to TOML equivalents
 Home-page: https://github.com/abravalheri/ini2toml/
 Author: Anderson Bravalheri
@@ -138,9 +138,86 @@
 To do so, don't forget to add it to your `virtual environment`_ or specify it 
as a
 `project dependency`_.
 
+Note that the class ``Translator`` will try to guess which flavour to use based
+on the available installed dependencies. If you need something more
+deterministic, consider using ``LiteTranslator`` and ``FullTranslator``,
+or explicitly specifying the ``ini_loads_fn`` and ``toml_dumps_fn`` keyword
+arguments in the constructor.
+
 More details about ``ini2toml`` and its Python API can be found in `our docs`_.
 
 
+Limitations
+===========
+
+``ini2toml`` will try its best to create good quality translations from
+``.ini/.cfg`` into ``.toml`` files. However the tool comes with a set of
+well known limitations:
+
+* Although ``ini2toml`` attempts to keep the same order/sequence as the 
original
+  information was written, sometimes that is not compatible with the TOML
+  syntax, and things end up moving around a bit.
+
+* ``ini2toml`` uses `ConfigParser`_ + `tomli-w`_ for implementing the *"lite"* 
flavour
+  and `ConfigUpdater`_ + `tomlkit`_ for implementing the *"full"* flavour.
+  Therefore it inherits the limitations from those libraries (please check
+  their documentation for more information). For example:
+
+  * `ConfigUpdater`_, will have trouble to parse interpolations and the related
+    escaping sequence (``%%``) (in this respect, it behaves more similarly to
+    ``RawConfigParser`` than ``ConfigParser``).
+
+  * `tomli-w`_ is not very flexible regarding formatting and will have trouble
+    with multi-line strings.
+
+* ``ini2toml`` *expects the input to be valid* and will not perform extensive
+  checks on the provided document. If something in the output is not working 
as you would
+  expect, it might be a good idea to check the input.
+
+* ``.ini/.cfg`` files are used in a plethora of use cases and it is impossible
+  to cover all of them in a single code base. Even when considering
+  ``setup.cfg``, there are many packages that define different sections in the
+  document in addition to the basic definition by ``setuptools``.
+  Because of that ``ini2toml``, adopts a "best-effort" approach, that might not
+  correspond to what you expect. If that is the case please consider
+  contributing or creating your own `plugin`_.
+
+* The translation procedure analyse only the given input. If the original
+  ``.ini/.cfg`` file contains references to other files, or behaves differently
+  depending on the existence/presence of other files and directories, the
+  translation will not take that into consideration.
+
+Therefore it is recommended to double check the output and fix any
+problems before using the ``.toml`` files in production.
+
+
+Can ``ini2toml`` also translate ``setup.py`` into ``pyproject.toml``?
+=====================================================================
+
+Working with ``.py`` files is not in the scope of the ``ini2toml`` project,
+and therefore this feature is not implemented.
+
+However, you can probably find some tools on PyPI to translate from
+``setup.py`` into ``setup.cfg``, like `setup-py-upgrade`_ and
+`setuptools-py2cfg`_ [#untested]_.
+
+Once you have ``setup.cfg``, you can use ``ini2toml`` [#setuppy]_.
+
+.. [#untested] Such tools are neither maintained by this project,
+   nor tested for integration by ``ini2toml``.
+   It is best to try some of them out and find the one that works for you.
+   Manual corrections might be needed.
+
+.. [#setuppy] Please note that ``setup.py`` is a very dynamic
+   format and that not everything can be represented in ``setup.cfg`` or
+   ``pyproject.toml``. Indeed, the `setuptools' docs`_ explicitly say that
+   ``setup.py`` can be used in tandem with ``pyproject.toml``: ideally all the
+   declarative metadata goes to ``pyproject.toml``, but you can keep the
+   dynamic bits in ``setup.py``.
+   Remember: ``setup.py`` is a perfectly valid and non deprecated 
configuration file;
+   what is deprecated is running it as a CLI tool, i.e. ``python setup.py 
...``.
+
+
 .. _pyscaffold-notes:
 
 .. tip::
@@ -167,8 +244,14 @@
 .. _ini_cfg: 
https://docs.python.org/3/library/configparser.html#supported-ini-file-structure
 .. _our docs: https://ini2toml.readthedocs.io
 .. _PEP 621: https://www.python.org/dev/peps/pep-0621/
-.. _pipx: https://pypa.github.io/pipx/
+.. _pipx: https://pipx.pypa.io/stable/
 .. _project dependency: 
https://packaging.python.org/tutorials/managing-dependencies/
+.. _plugin: https://ini2toml.readthedocs.io/en/latest/dev-guide.html#plugins
+.. _setup-py-upgrade: https://pypi.org/project/setup-cfg-fmt/
+.. _setuptools-py2cfg: https://pypi.org/project/setuptools-py2cfg/
+.. _setuptools' docs: 
https://setuptools.pypa.io/en/latest/userguide/quickstart.html#setuppy-discouraged
 .. _TOML: https://toml.io/en/
 .. _TOML library: https://github.com/sdispater/tomlkit
+.. _tomli-w: https://pypi.org/project/tomli-w/
+.. _tomlkit: https://tomlkit.readthedocs.io/en/latest/
 .. _virtual environment: 
https://realpython.com/python-virtual-environments-a-primer/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/src/ini2toml.egg-info/SOURCES.txt 
new/ini2toml-0.14/src/ini2toml.egg-info/SOURCES.txt
--- old/ini2toml-0.13/src/ini2toml.egg-info/SOURCES.txt 2023-10-23 
14:17:02.000000000 +0200
+++ new/ini2toml-0.14/src/ini2toml.egg-info/SOURCES.txt 2024-04-20 
21:24:34.000000000 +0200
@@ -24,6 +24,7 @@
 docs/dev-guide.rst
 docs/index.rst
 docs/license.rst
+docs/public_api_docs.py
 docs/readme.rst
 docs/requirements.txt
 docs/setuptools_pep621.rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/tests/examples/pyscaffold/setup.cfg 
new/ini2toml-0.14/tests/examples/pyscaffold/setup.cfg
--- old/ini2toml-0.13/tests/examples/pyscaffold/setup.cfg       2023-10-23 
14:15:48.000000000 +0200
+++ new/ini2toml-0.14/tests/examples/pyscaffold/setup.cfg       2024-04-20 
21:23:26.000000000 +0200
@@ -117,9 +117,8 @@
 # in order to write a coverage file that can be read by Jenkins.
 # CAUTION: --cov flags may prohibit setting breakpoints while debugging.
 #          Comment those flags to avoid this pytest issue.
-addopts =
-    --cov pyscaffold --cov-config .coveragerc --cov-report term-missing
-    --verbose
+addopts = --cov pyscaffold --cov-config .coveragerc --cov-report term-missing
+          --verbose
 #    In order to use xdist, the developer can add, for example, the following
 #    arguments:
 #    --dist=load --numprocesses=auto
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/tests/plugins/test_pytest.py 
new/ini2toml-0.14/tests/plugins/test_pytest.py
--- old/ini2toml-0.13/tests/plugins/test_pytest.py      2023-10-23 
14:15:48.000000000 +0200
+++ new/ini2toml-0.14/tests/plugins/test_pytest.py      2024-04-20 
21:23:26.000000000 +0200
@@ -1,54 +1,77 @@
 from textwrap import dedent
 
+import pytest
 import tomli
 
 from ini2toml.drivers import full_toml, lite_toml
-from ini2toml.plugins import pytest
-from ini2toml.translator import Translator
+from ini2toml.plugins.pytest import activate
+from ini2toml.translator import FullTranslator
 
+EXAMPLES = {
+    "simple": {
+        "example": """\
+            [pytest]
+            minversion = 6.0
+            addopts = -ra -q --cov ini2toml
+            testpaths = tests
+            python_files = test_*.py check_*.py example_*.py
+            required_plugins = pytest-django>=3.0.0,<4.0.0 pytest-html 
pytest-xdist>=1.0.0
+            norecursedirs =
+                dist
+                build
+                .tox
+            filterwarnings=
+                error
+                ignore:Please use `dok_matrix` from the `scipy\\.sparse` 
namespace, the `scipy\\.sparse\\.dok` namespace is 
deprecated.:DeprecationWarning
+            """,  # noqa
+        "expected": """\
+            [pytest]
+            [pytest.ini_options]
+            minversion = "6.0"
+            addopts = "-ra -q --cov ini2toml"
+            testpaths = ["tests"]
+            python_files = ["test_*.py", "check_*.py", "example_*.py"]
+            required_plugins = ["pytest-django>=3.0.0,<4.0.0", "pytest-html", 
"pytest-xdist>=1.0.0"]
+            norecursedirs = [
+                "dist", 
+                "build", 
+                ".tox", 
+            ]
+            filterwarnings = [
+                "error",
+                'ignore:Please use `dok_matrix` from the `scipy\\.sparse` 
namespace, the `scipy\\.sparse\\.dok` namespace is 
deprecated.:DeprecationWarning',
+            ]
+            """,  # noqa
+    },
+    "multiline-addopts": {
+        "example": """\
+            [pytest]
+            addopts = -ra -q
+                      # comment
+                      --cov ini2toml
+            """,
+        "expected": '''\
+            [pytest.ini_options]
+            addopts = """
+            -ra -q
+            --cov ini2toml"""
+            ''',
+    },
+}
 
-def test_pytest():
-    example = """\
-    [pytest]
-    minversion = 6.0
-    addopts = -ra -q --cov ini2toml
-    testpaths = tests
-    python_files = test_*.py check_*.py example_*.py
-    required_plugins = pytest-django>=3.0.0,<4.0.0 pytest-html 
pytest-xdist>=1.0.0
-    norecursedirs =
-        dist
-        build
-        .tox
-    filterwarnings=
-        error
-        ignore:Please use `dok_matrix` from the `scipy\\.sparse` namespace, 
the `scipy\\.sparse\\.dok` namespace is deprecated.:DeprecationWarning
-    """  # noqa
-    expected = """\
-    [pytest]
-    [pytest.ini_options]
-    minversion = "6.0"
-    addopts = "-ra -q --cov ini2toml"
-    testpaths = ["tests"]
-    python_files = ["test_*.py", "check_*.py", "example_*.py"]
-    required_plugins = ["pytest-django>=3.0.0,<4.0.0", "pytest-html", 
"pytest-xdist>=1.0.0"]
-    norecursedirs = [
-        "dist", 
-        "build", 
-        ".tox", 
-    ]
-    filterwarnings = [
-        "error",
-        'ignore:Please use `dok_matrix` from the `scipy\\.sparse` namespace, 
the `scipy\\.sparse\\.dok` namespace is deprecated.:DeprecationWarning',
-    ]
-    """  # noqa
-    for convert in (lite_toml.convert, full_toml.convert):
-        translator = Translator(plugins=[pytest.activate], 
toml_dumps_fn=convert)
-        out = translator.translate(dedent(example), "pytest.ini").strip()
-        expected = dedent(expected).strip()
-        print("expected=\n" + expected + "\n***")
-        print("out=\n" + out)
-        try:
-            assert expected in out
-        except AssertionError:
-            # At least the Python-equivalents when parsing should be the same
-            assert tomli.loads(expected) == tomli.loads(out)
+
+@pytest.mark.parametrize("example_name", EXAMPLES.keys())
+@pytest.mark.parametrize("convert", [full_toml.convert, lite_toml.convert])
+def test_pytest(example_name, convert):
+    example = EXAMPLES[example_name]["example"]
+    expected = EXAMPLES[example_name]["expected"]
+    translator = FullTranslator(plugins=[activate], toml_dumps_fn=convert)
+    out = translator.translate(dedent(example), "pytest.ini").strip()
+    expected = dedent(expected).strip()
+    print("expected=\n" + expected + "\n***")
+    print("out=\n" + out)
+    try:
+        assert expected in out
+    except AssertionError:
+        # At least the Python-equivalents when parsing should be the same
+        assert tomli.loads(expected) == tomli.loads(out)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ini2toml-0.13/tests/plugins/test_setuptools_pep621.py 
new/ini2toml-0.14/tests/plugins/test_setuptools_pep621.py
--- old/ini2toml-0.13/tests/plugins/test_setuptools_pep621.py   2023-10-23 
14:15:48.000000000 +0200
+++ new/ini2toml-0.14/tests/plugins/test_setuptools_pep621.py   2024-04-20 
21:23:26.000000000 +0200
@@ -2,7 +2,12 @@
 import tomli
 
 from ini2toml.plugins.profile_independent_tasks import 
remove_empty_table_headers
-from ini2toml.plugins.setuptools_pep621 import Directive, SetuptoolsPEP621, 
activate
+from ini2toml.plugins.setuptools_pep621 import (
+    Directive,
+    SetuptoolsPEP621,
+    _ConfusingPackagesConfig,
+    activate,
+)
 from ini2toml.translator import Translator
 
 
@@ -738,3 +743,37 @@
     print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
     print(doc)
     assert convert(doc) == expected_convert_directives
+
+
+# ----
+
+# Example taken from https://github.com/aio-libs/aiohttp/
+# In general, you should either list packages explicit or use find,
+# but some configs change and `options.packages.find` is left behind
+example_explicit_packages_with_find = """\
+[options]
+packages = aiohttp
+[options.packages.find]
+exclude =
+  examples
+"""
+
+# In those cases, `ini2toml` should remove  `[options.packages.find]`
+# And warn about it
+expected_explicit_packages_with_find = """\
+[tool.setuptools]
+packages = ["aiohttp"]
+"""
+
+
+def test_explicit_packages_with_find(plugin, parse, convert):
+    doc = parse(example_explicit_packages_with_find)
+    print(doc)
+    doc = plugin.apply_value_processing(doc)
+    print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
+    with pytest.warns(_ConfusingPackagesConfig, 
match="[options.packages.find]"):
+        doc = plugin.handle_packages_find(doc)
+    doc.rename("options", ("tool", "setuptools"))
+    print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
+    print(doc)
+    assert convert(doc) == expected_explicit_packages_with_find
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/tests/test_examples.py 
new/ini2toml-0.14/tests/test_examples.py
--- old/ini2toml-0.13/tests/test_examples.py    2023-10-23 14:15:48.000000000 
+0200
+++ new/ini2toml-0.14/tests/test_examples.py    2024-04-20 21:23:26.000000000 
+0200
@@ -9,7 +9,7 @@
 
 from ini2toml import cli
 from ini2toml.drivers import configparser, full_toml, lite_toml
-from ini2toml.translator import Translator
+from ini2toml.translator import FullTranslator, LiteTranslator
 
 
 def examples():
@@ -39,7 +39,7 @@
 @pytest.mark.filterwarnings("ignore::DeprecationWarning")
 @pytest.mark.parametrize(("original", "expected"), list(examples()))
 def test_examples_api(original, expected, validate):
-    translator = Translator()
+    translator = FullTranslator()
     available_profiles = list(translator.profiles.keys())
     profile = cli.guess_profile(None, original, available_profiles)
     orig = Path(original)
@@ -71,7 +71,7 @@
 @pytest.mark.parametrize(("original", "expected"), list(examples()))
 def test_examples_api_lite(original, expected, validate):
     opts = {"ini_loads_fn": configparser.parse, "toml_dumps_fn": 
lite_toml.convert}
-    translator = Translator(**opts)
+    translator = LiteTranslator(**opts)
     available_profiles = list(translator.profiles.keys())
     profile = cli.guess_profile(None, original, available_profiles)
     # We cannot compare "flake8" sections (currently not handled)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ini2toml-0.13/tests/test_translator.py 
new/ini2toml-0.14/tests/test_translator.py
--- old/ini2toml-0.13/tests/test_translator.py  2023-10-23 14:15:48.000000000 
+0200
+++ new/ini2toml-0.14/tests/test_translator.py  2024-04-20 21:23:26.000000000 
+0200
@@ -5,7 +5,7 @@
 from ini2toml.errors import UndefinedProfile
 from ini2toml.plugins import profile_independent_tasks
 from ini2toml.profile import Profile, ProfileAugmentation
-from ini2toml.translator import Translator
+from ini2toml.translator import FullTranslator, LiteTranslator, Translator
 
 
 def test_simple_example():
@@ -139,3 +139,31 @@
     ]
     translator = Translator(plugins=plugins)
     assert len(translator.plugins) == 1
+
+
+minimal_example = """\
+# comment
+
+[section1]
+option1 = value
+option2 = value # option comments are considered part of the value
+"""
+
+
+def test_lite_translator():
+    parser_opts = {"inline_comment_prefixes": ["#"]}
+    translator = LiteTranslator(plugins=[], ini_parser_opts=parser_opts)
+    # ensure profile exists
+    translator["simple"]
+    out = translator.translate(dedent(minimal_example), "simple")
+    assert "# comment" not in out
+    assert "part of the value" not in out
+
+
+def test_full_translator():
+    translator = FullTranslator(plugins=[])
+    # ensure profile exists
+    translator["simple"]
+    out = translator.translate(dedent(minimal_example), "simple")
+    assert "# comment" in out
+    assert "part of the value" in out

Reply via email to