abravalheri / validate-pyproject

Validation library for simple check on `pyproject.toml`
https://validate-pyproject.readthedocs.io/
Mozilla Public License 2.0
114 stars 11 forks source link

Please install `tomli` (TOML parser) #186

Closed DimitriPapadopoulos closed 1 month ago

DimitriPapadopoulos commented 1 month ago

Although validate-pyproject is documented to support Python ≥ 3.8, it fails to run on Python 3.10 after a pipx installation.

$ pipx install validate-pyproject
  installed package validate-pyproject 0.18, installed using Python 3.10.12
  These apps are now globally available
    - validate-pyproject
done! ✨ 🌟 ✨
$ 
$ validate-pyproject --help
Traceback (most recent call last):
  File "/home/user/.local/pipx/venvs/validate-pyproject/lib/python3.10/site-packages/validate_pyproject/_tomllib.py", line 7, in <module>
    from tomli import TOMLDecodeError, loads
ModuleNotFoundError: No module named 'tomli'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/.local/pipx/venvs/validate-pyproject/lib/python3.10/site-packages/validate_pyproject/_tomllib.py", line 10, in <module>
    from toml import TomlDecodeError as TOMLDecodeError  # type: ignore
ModuleNotFoundError: No module named 'toml'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/user/.local/bin/validate-pyproject", line 5, in <module>
    from validate_pyproject.cli import main
  File "/home/user/.local/pipx/venvs/validate-pyproject/lib/python3.10/site-packages/validate_pyproject/cli.py", line 30, in <module>
    from . import _tomllib as tomllib
  File "/home/user/.local/pipx/venvs/validate-pyproject/lib/python3.10/site-packages/validate_pyproject/_tomllib.py", line 13, in <module>
    raise ImportError("Please install `tomli` (TOML parser)") from ex
ImportError: Please install `tomli` (TOML parser)
$ 

While the tomli dependency is documented, it does not seem to be taken into account by pipx: https://github.com/abravalheri/validate-pyproject/blob/e1aa94607ce086991e6b37b09cae3dfb3c623c8a/setup.cfg#L65-L69

DimitriPapadopoulos commented 1 month ago

This works of course:

pipx install validate-pyproject[all]

The tomli library should not be an optional dependency under extra_requires for Python < 3.11.

abravalheri commented 1 month ago

The tomli library should not be an optional dependency under extra_requires for Python < 3.11.

Hi @DimitriPapadopoulos, please read the rationale in the README. It is unlikely this is going to change.

As a library, having tomli as optional dependency is completely fine. For CLI usage, the installation instructions are well documented.

DimitriPapadopoulos commented 1 month ago

Which exact part of the README? I can understand you want to "keep the dependencies minimal", but it doesn't really make sense to make tomli optional when the purpose of the library is to validate a TOML file.

abravalheri commented 1 month ago

it doesn't really make sense to make tomli optional when the purpose of the library is to validate a TOML file.

As a Python API, validate_pyproject consumes a dict-like (Mapping) Python object, and it is quite indifferent on how the programmer decides to parse the TOML... The developer can decide to use tomli/tomllib, tomlkit, rtoml or the old toml... The developer may even not be interested in reading TOML at all, but rather they may be concerned in validating a configuration that they are automatically creating before writing it to a TOML file.

The CLI is where we need the TOML parsing. But the API can exist and be used without the CLI, the CLI on the other hand cannot work without the API. That is why the CLI and any dependencies supporting it are considered optional features.

The Usage section of the README, recommends the following installation procedure:

$ pipx install 'validate-pyproject[all]'

Which is expanded further:

When you install validate-pyproject[all], the packages tomli, packaging and trove-classifiers will be automatically pulled as dependencies. tomli is a lightweight parser for TOML, while packaging and trove-classifiers are used to validate aspects of PEP 621.

If you are only interested in using the Python API and wants to keep the dependencies minimal, you can also install validate-pyproject (without the [all] extra dependencies group).

If you don't install trove-classifiers, validate-pyproject will try to download a list of valid classifiers directly from PyPI (to prevent that, set the environment variable NO_NETWORK or VALIDATE_PYPROJECT_NO_NETWORK).

On the other hand, if validate-pyproject cannot find a copy of packaging in your environment, the validation will fail.

Now validate_pyproject has a special case because it is interested in providing a way of pre-compiling schemas and allowing package developers to embed these pre-compiled functions in their projects. That is why validate-pyproject tries to be very dry in terms of the base dependencies and relies on the use of extras (so that projects using the pre-compile functionality can have a finer control over requirements).

DimitriPapadopoulos commented 1 month ago

My wrong, I wasn't aware that the library itself consumes a dict, not a TOML file. The issue arises from distributing the library and the command in a single Python package, although they have conflicting needs in terms of dependencies (the library must remain as lightweight as possible while the command requires additional packages to merely run).

Anyway, the tomli problem will go away as distributions start shipping Python ≥ 3.11.

DimitriPapadopoulos commented 1 month ago

Would you at least agree on a PR that changes the CLI to catch the ModuleNotFoundError and print and nicer error message?

abravalheri commented 1 month ago

Would you at least agree on a PR that changes the CLI to catch the ModuleNotFoundError and print and nicer error message?

Yes, that would be fine, thank you very much.

In the past I have tried to create something like that in https://github.com/abravalheri/validate-pyproject/blob/main/src/validate_pyproject/_tomllib.py, but apparently the error message is not working how I expected 😅