Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support TOML v1.0.0 syntax in pyproject.toml #8857

Merged
merged 4 commits into from Jul 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Expand Up @@ -58,7 +58,7 @@ repos:
- py>=1.8.2
- attrs>=19.2.0
- packaging
- types-toml
- tomli
- types-pkg_resources
- repo: local
hooks:
Expand Down
1 change: 1 addition & 0 deletions AUTHORS
Expand Up @@ -302,6 +302,7 @@ Sven-Hendrik Haase
Sylvain Marié
Tadek Teleżyński
Takafumi Arakaki
Taneli Hukkinen
Tanvi Mehta
Tarcisio Fischer
Tareq Alayan
Expand Down
1 change: 1 addition & 0 deletions changelog/8789.feature.rst
@@ -0,0 +1 @@
Switch TOML parser from ``toml`` to ``tomli`` for TOML v1.0.0 support in ``pyproject.toml``.
2 changes: 1 addition & 1 deletion setup.cfg
Expand Up @@ -47,7 +47,7 @@ install_requires =
packaging
pluggy>=0.12,<1.0.0a1
py>=1.8.2
toml
tomli>=1.0.0,<2.0.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the >=1.0.0 is needed here, given that there never was a < 1.0.0 release. Not sure about the <2.0.0 part. We don't typically add upper bounds for dependencies, and I guess the tiny bit of API we need will probably stay the same across future versions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are <1.0.0 releases. I had this same discussion with Black maintainers recently 😄 . You'll find my thoughts in that thread.

If you tell me exactly what constraint you want I'll change it to that of course (or you can just push to this branch).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, I thought I had looked at PyPI, but apparently I messed up somehow. Ok, seems fine to me either way, let's see what others think.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also not inclined to not having the upper pinning in there, because I don't consider pytest a user facing application, but a framework, so our dependencies need to be compatible downstream with user's code.

But having said that, I understand the points @hukkin made in that thread, and given he is the main author, his opinion here carries some weight. Also, seems we might never even see a 2.0 version. 😁

In summary: -0 on the upper pinning.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll put my -1 on the upper pinning, please remove it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry, had enough approvals that I thought it would be OK to merge. 👍

atomicwrites>=1.0;sys_platform=="win32"
colorama;sys_platform=="win32"
importlib-metadata>=0.12;python_version<"3.8"
Expand Down
8 changes: 6 additions & 2 deletions src/_pytest/config/findpaths.py
Expand Up @@ -64,9 +64,13 @@ def load_config_dict_from_file(

# '.toml' files are considered if they contain a [tool.pytest.ini_options] table.
elif filepath.suffix == ".toml":
import toml
import tomli

config = toml.load(str(filepath))
toml_text = filepath.read_text(encoding="utf-8")
try:
config = tomli.loads(toml_text)
except tomli.TOMLDecodeError as exc:
raise UsageError(str(exc)) from exc

result = config.get("tool", {}).get("pytest", {}).get("ini_options", None)
if result is not None:
Expand Down
10 changes: 10 additions & 0 deletions testing/test_findpaths.py
Expand Up @@ -2,6 +2,7 @@
from textwrap import dedent

import pytest
from _pytest.config import UsageError
from _pytest.config.findpaths import get_common_ancestor
from _pytest.config.findpaths import get_dirs_from_args
from _pytest.config.findpaths import load_config_dict_from_file
Expand Down Expand Up @@ -52,6 +53,13 @@ def test_unsupported_pytest_section_in_cfg_file(self, tmp_path: Path) -> None:
load_config_dict_from_file(fn)

def test_invalid_toml_file(self, tmp_path: Path) -> None:
"""Invalid .toml files should raise `UsageError`."""
fn = tmp_path / "myconfig.toml"
fn.write_text("]invalid toml[", encoding="utf-8")
with pytest.raises(UsageError):
load_config_dict_from_file(fn)

def test_custom_toml_file(self, tmp_path: Path) -> None:
""".toml files without [tool.pytest.ini_options] are not considered for configuration."""
fn = tmp_path / "myconfig.toml"
fn.write_text(
Expand All @@ -77,6 +85,7 @@ def test_valid_toml_file(self, tmp_path: Path) -> None:
y = 20.0
values = ["tests", "integration"]
name = "foo"
heterogeneous_array = [1, "str"]
"""
),
encoding="utf-8",
Expand All @@ -86,6 +95,7 @@ def test_valid_toml_file(self, tmp_path: Path) -> None:
"y": "20.0",
"values": ["tests", "integration"],
"name": "foo",
"heterogeneous_array": [1, "str"],
}


Expand Down