pytest-dev / pytest

The pytest framework makes it easy to write small tests, yet scales to support complex functional testing
https://pytest.org
MIT License
12.14k stars 2.69k forks source link

Config parsing breaks on valid `black` table in pyproject.toml #10039

Closed Jacob-Stevens-Haas closed 2 years ago

Jacob-Stevens-Haas commented 2 years ago

I noticed an error where my marks, defined in pyproject.toml, weren't registered. So I tried forcing pytest to use pyproject.toml and got an parsing error, pointing to a line in the [tool.black] table. However, black reads this block fine - it's a multiline literal, verified matching description in TOML docs. I then verified using the toml package that the dictionary can be correctly read.

`pip list` ``` Package Version Location --------------------------------- --------------------------- ----------------------------- alabaster 0.7.12 argon2-cffi 21.3.0 argon2-cffi-bindings 21.2.0 asttokens 2.0.5 attrs 21.4.0 Babel 2.10.1 backcall 0.2.0 beautifulsoup4 4.11.1 black 22.3.0 bleach 5.0.0 certifi 2021.10.8 cffi 1.15.0 cfgv 3.3.1 charset-normalizer 2.0.12 click 8.1.3 cmake 3.22.4 codecov 2.1.12 coverage 6.3.2 cvxpy 1.2.0 cycler 0.11.0 debugpy 1.6.0 decorator 5.1.1 defusedxml 0.7.1 derivative 0.3.2 distlib 0.3.4 docutils 0.17.1 ecos 2.0.10 entrypoints 0.4 executing 0.8.3 fastjsonschema 2.15.3 filelock 3.6.0 flake8 4.0.1 flake8-builtins-unleashed 1.3.1 fonttools 4.33.3 hypothesis 6.46.3 identify 2.5.0 idna 3.3 imagesize 1.3.0 importlib-metadata 4.11.3 importlib-resources 5.7.1 ipykernel 6.13.0 ipython 8.3.0 ipython-genutils 0.2.0 ipywidgets 7.7.0 jedi 0.18.1 Jinja2 3.1.2 joblib 1.1.0 jsonschema 4.5.1 jupyter 1.0.0 jupyter-client 7.3.1 jupyter-console 6.4.3 jupyter-contrib-core 0.3.3 jupyter-contrib-nbextensions 0.5.1 jupyter-core 4.10.0 jupyter-highlight-selected-word 0.2.0 jupyter-latex-envs 1.4.6 jupyter-nbextensions-configurator 0.4.1 jupyterlab-pygments 0.2.2 jupyterlab-widgets 1.1.0 kiwisolver 1.4.2 lxml 4.8.0 MarkupSafe 2.1.1 matplotlib 3.5.2 matplotlib-inline 0.1.3 mccabe 0.6.1 mistune 0.8.4 more-itertools 8.13.0 mypy-extensions 0.4.3 nbclient 0.6.3 nbconvert 6.5.0 nbformat 5.4.0 nest-asyncio 1.5.5 nodeenv 1.6.0 notebook 6.4.11 numpy 1.22.3 osqp 0.6.2.post5 packaging 21.3 pandas 1.4.2 pandocfilters 1.5.0 parso 0.8.3 pathspec 0.9.0 pbr 5.9.0 pexpect 4.8.0 pickleshare 0.7.5 Pillow 9.1.0 pip 20.0.2 pkg-resources 0.0.0 platformdirs 2.5.2 pluggy 0.13.1 pre-commit 2.19.0 prometheus-client 0.14.1 prompt-toolkit 3.0.29 psutil 5.9.0 ptyprocess 0.7.0 pure-eval 0.2.2 py 1.11.0 pycodestyle 2.8.0 pycparser 2.21 pyflakes 2.4.0 Pygments 2.12.0 pyparsing 3.0.9 pyrsistent 0.18.1 pysindy 1.8.dev1+g288cf6e.d20220511 /home/xenophon/github/pysindy pytest 5.4.3 pytest-cov 3.0.0 pytest-lazy-fixture 0.6.3 python-dateutil 2.8.2 pytz 2022.1 PyYAML 6.0 pyzmq 22.3.0 qdldl 0.1.5.post2 qtconsole 5.3.0 QtPy 2.1.0 requests 2.27.1 scikit-learn 1.0.2 scipy 1.8.0 scs 3.2.0 seaborn 0.11.2 Send2Trash 1.8.0 setuptools 44.0.0 setuptools-scm 6.4.2 setuptools-scm-git-archive 1.1 six 1.16.0 sklearn 0.0 snowballstemmer 2.2.0 sortedcontainers 2.4.0 soupsieve 2.3.2.post1 Sphinx 4.5.0 sphinx-nbexamples 0.4.1 sphinx-rtd-theme 1.0.0 sphinxcontrib-apidoc 0.3.0 sphinxcontrib-applehelp 1.0.2 sphinxcontrib-devhelp 1.0.2 sphinxcontrib-htmlhelp 2.0.0 sphinxcontrib-jsmath 1.0.1 sphinxcontrib-qthelp 1.0.3 sphinxcontrib-serializinghtml 1.1.5 stack-data 0.2.0 terminado 0.13.3 threadpoolctl 3.1.0 tinycss2 1.1.1 toml 0.10.2 tomli 2.0.1 tornado 6.1 traitlets 5.2.0 typing-extensions 4.2.0 urllib3 1.26.9 virtualenv 20.14.1 wcwidth 0.2.5 webencodings 0.5.1 widgetsnbextension 3.6.0 zipp 3.8.0 ```
Version info `pytest --version`: ``` This is pytest version 5.4.3, imported from /home/xenophon/github/pysindy/env/lib/python3.8/site-packages/pytest/__init__.py setuptools registered plugins: pytest-lazy-fixture-0.6.3 at /home/xenophon/github/pysindy/env/lib/python3.8/site-packages/pytest_lazyfixture.py pytest-cov-3.0.0 at /home/xenophon/github/pysindy/env/lib/python3.8/site-packages/pytest_cov/plugin.py hypothesis-6.46.3 at /home/xenophon/github/pysindy/env/lib/python3.8/site-packages/_hypothesis_pytestplugin.py ``` `cat /etc/os-release`: ``` NAME="Ubuntu" VERSION="20.04.4 LTS (Focal Fossa)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 20.04.4 LTS" VERSION_ID="20.04" HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" VERSION_CODENAME=focal UBUNTU_CODENAME=focal ```

MWE

pyproject.toml (commented out all other tables, still gives same error):

[tool.black]
line-length = 88
exclude = '''
/(
    \.git
  | \.mypy_cache
  | \.venv
  | .vscode
  | version.py
  | build
  | dist
  | env
)/
'''

[tool.pytest.ini_options]
filterwarnings = [
  "ignore::RuntimeWarning",
  "ignore::UserWarning"
]
addopts = "-m \"not slow\""
markers = [
    "slow: notebook tests (deselect with '-m \"not slow\"')",
]

Running

pytest --co -c pyproject.toml

gives result:

Traceback (most recent call last):
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/py/_vendored_packages/iniconfig/__init__.py", line 126, in _parseline
    name, value = line.split('=', 1)
ValueError: not enough values to unpack (expected 2, got 1)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/py/_vendored_packages/iniconfig/__init__.py", line 131, in _parseline
    name, value = line.split(":", 1)
ValueError: not enough values to unpack (expected 2, got 1)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/xenophon/github/pysindy/env/bin/pytest", line 8, in <module>
    sys.exit(main())
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/_pytest/config/__init__.py", line 105, in main
    config = _prepareconfig(args, plugins)
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/_pytest/config/__init__.py", line 257, in _prepareconfig
    return pluginmanager.hook.pytest_cmdline_parse(
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/pluggy/hooks.py", line 286, in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/pluggy/manager.py", line 93, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/pluggy/manager.py", line 84, in <lambda>
    self._inner_hookexec = lambda hook, methods, kwargs: hook.multicall(
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/pluggy/callers.py", line 203, in _multicall
    gen.send(outcome)
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/_pytest/helpconfig.py", line 90, in pytest_cmdline_parse
    config = outcome.get_result()
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/pluggy/callers.py", line 80, in get_result
    raise ex[1].with_traceback(ex[2])
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/pluggy/callers.py", line 187, in _multicall
    res = hook_impl.function(*args)
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/_pytest/config/__init__.py", line 836, in pytest_cmdline_parse
    self.parse(args)
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/_pytest/config/__init__.py", line 1044, in parse
    self._preparse(args, addopts=addopts)
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/_pytest/config/__init__.py", line 980, in _preparse
    self._initini(args)
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/_pytest/config/__init__.py", line 905, in _initini
    r = determine_setup(
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/_pytest/config/findpaths.py", line 122, in determine_setup
    iniconfig = py.iniconfig.IniConfig(inifile)
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/py/_vendored_packages/iniconfig/__init__.py", line 54, in __init__
    tokens = self._parse(iter(f))
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/py/_vendored_packages/iniconfig/__init__.py", line 83, in _parse
    name, data = self._parseline(line, lineno)
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/py/_vendored_packages/iniconfig/__init__.py", line 133, in _parseline
    self._raise(lineno, 'unexpected line: %r' % line)
  File "/home/xenophon/github/pysindy/env/lib/python3.8/site-packages/py/_vendored_packages/iniconfig/__init__.py", line 77, in _raise
    raise ParseError(self.path, lineno, msg)
py._vendored_packages.iniconfig.ParseError: pyproject.toml:11: unexpected line: '/('

black -v --config pyproject.toml . shows:

Identified `/home/xenophon/github/pysindy` as project root containing a .git directory.
Sources to be formatted: "."
Using configuration in 'pyproject.toml'.
...

Parsing with toml:

Type "help", "copyright", "credits" or "license" for more information.
>>> import toml
>>> import pprint
>>> with open("pyproject.toml", "r") as f:
...     config = toml.load(f)
... 
>>> pprint.pprint(config)
{'tool': {'black': {'exclude': '/(\n'
                               '    \\.git\n'
                               '  | \\.mypy_cache\n'
                               '  | \\.venv\n'
                               '  | .vscode\n'
                               '  | version.py\n'
                               '  | build\n'
                               '  | dist\n'
                               '  | env\n'
                               ')/\n',
                    'line-length': 88},
          'pytest': {'ini_options': {'addopts': '-m "not slow"',
                                     'filterwarnings': ['ignore::RuntimeWarning',
                                                        'ignore::UserWarning'],
                                     'markers': ['slow: notebook tests '
                                                 '(deselect with \'-m "not '
                                                 'slow"\')']}}}}
Jacob-Stevens-Haas commented 2 years ago

Ah, I see pyproject.toml support was only added in 6.0.0 - closing!