diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2022-02-16 18:06:34 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2022-02-16 18:06:34 +0000 |
commit | 2678ead3c984158ff7ed2c4bd750817a96dce610 (patch) | |
tree | 112062b736ebfb0b839cc52027b1c6a8ed86db96 | |
parent | Releasing progress-linux version 1.2.1-1~progress6+u1. (diff) | |
download | python-tomli-2678ead3c984158ff7ed2c4bd750817a96dce610.tar.xz python-tomli-2678ead3c984158ff7ed2c4bd750817a96dce610.zip |
Merging upstream version 1.2.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r-- | .bumpversion.cfg | 2 | ||||
-rw-r--r-- | .github/workflows/tests.yaml | 25 | ||||
-rw-r--r-- | .pre-commit-config.yaml | 10 | ||||
-rw-r--r-- | CHANGELOG.md | 13 | ||||
-rw-r--r-- | pyproject.toml | 11 | ||||
-rw-r--r-- | tests/requirements.txt | 1 | ||||
-rw-r--r-- | tests/test_error.py | 10 | ||||
-rw-r--r-- | tests/test_misc.py | 5 | ||||
-rw-r--r-- | tomli/__init__.py | 5 | ||||
-rw-r--r-- | tomli/_parser.py | 45 | ||||
-rw-r--r-- | tomli/_re.py | 5 | ||||
-rw-r--r-- | tomli/_types.py | 6 |
12 files changed, 83 insertions, 55 deletions
diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 2df26c8..94a23ef 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -2,7 +2,7 @@ commit = True tag = True tag_name = {new_version} -current_version = 1.2.1 +current_version = 1.2.2 [bumpversion:file:pyproject.toml] search = version = "{current_version}" # DO NOT EDIT THIS LINE MANUALLY. LET bump2version UTILITY DO IT diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 6b3c0ba..0c246e3 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -32,9 +32,9 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: ['pypy-3.6', 'pypy-3.7', '3.6', '3.7', '3.8', '3.9', '3.10-dev'] + python-version: ['pypy-3.7', '3.6', '3.7', '3.8', '3.9', '3.10', '3.11-dev'] os: [ubuntu-latest, macos-latest, windows-latest] - continue-on-error: ${{ matrix.python-version == '3.10-dev' }} + continue-on-error: ${{ matrix.python-version == '3.11-dev' }} steps: - uses: actions/checkout@v2 @@ -50,11 +50,12 @@ jobs: - name: Test with pytest run: | - pytest --cov --cov-fail-under=100 + # Use 'python -m pytest' to add CWD to sys.path + python -m pytest --cov --cov-fail-under=100 - name: Report coverage if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.6' - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v2 test-built-package: runs-on: ubuntu-latest @@ -96,12 +97,16 @@ jobs: - uses: actions/setup-python@v2 with: python-version: '3.7' - - name: Install Flit + - name: Install build and publish tools run: | - pip install "flit==3.3.0" - - name: Build and publish + pip install build twine + - name: Build and check run: | - flit publish --no-setup-py + rm -rf dist/ && python -m build + twine check --strict dist/* + - name: Publish + run: | + twine upload dist/* env: - FLIT_USERNAME: __token__ - FLIT_PASSWORD: ${{ secrets.PYPI_TOKEN }} + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cc42334..10c7890 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/executablebooks/mdformat - rev: b9b885e183ca16670b6d4a5ef8058664395dec58 # frozen: 0.7.7 + rev: 427df9181bd4d8e65c1108b912ad47a81628f03b # frozen: 0.7.10 hooks: - id: mdformat additional_dependencies: @@ -16,11 +16,11 @@ repos: - flake8-builtins - flake8-comprehensions - repo: https://github.com/PyCQA/isort - rev: 6e4281f018ff848226d8993596765b2285e1624f # frozen: 5.9.2 + rev: fd5ba70665a37ec301a1f714ed09336048b3be63 # frozen: 5.9.3 hooks: - id: isort - repo: https://github.com/psf/black - rev: e3000ace2fd1fcb1c181bb7a8285f1f976bcbdc7 # frozen: 21.7b0 + rev: 911470a610e47d9da5ea938b0887c3df62819b85 # frozen: 21.9b0 hooks: - id: black - repo: https://github.com/myint/docformatter @@ -38,7 +38,7 @@ repos: - id: python-check-blanket-noqa - id: python-check-blanket-type-ignore - repo: https://github.com/PyCQA/flake8 - rev: dcd740bc0ebaf2b3d43e59a0060d157c97de13f3 # frozen: 3.9.2 + rev: cbeb4c9c4137cff1568659fcc48e8b85cddd0c8d # frozen: 4.0.1 hooks: - id: flake8 additional_dependencies: @@ -46,7 +46,7 @@ repos: - flake8-builtins - flake8-comprehensions - repo: https://github.com/pre-commit/mirrors-mypy - rev: 44afb68a9695d04030edc5cdc5a4fc4f17e4f9e2 # frozen: v0.910 + rev: 5cf22ccb774a8be8f47dfe4c1e8c4f177c608cbf # frozen: v0.910-1 hooks: - id: mypy args: ["--scripts-are-modules"] diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b1e2c0..7b0720d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## **unreleased** + +- no changes yet + +## 1.2.2 + +- Fixed + - Illegal characters in error messages were surrounded by two pairs of quotation marks +- Improved + - `TOMLDecodeError.__module__` is now the public import path (`tomli`) instead of private import path (`tomli._parser`) + - Eliminated an import cycle when `typing.TYPE_CHECKING` is `True`. + This allows `sphinx-autodoc-typehints` to resolve type annotations. + ## 1.2.1 - Fixed diff --git a/pyproject.toml b/pyproject.toml index 1ec6d11..c562ff3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi" [project] name = "tomli" -version = "1.2.1" # DO NOT EDIT THIS LINE MANUALLY. LET bump2version UTILITY DO IT +version = "1.2.2" # DO NOT EDIT THIS LINE MANUALLY. LET bump2version UTILITY DO IT description = "A lil' TOML parser" authors = [ { name = "Taneli Hukkinen", email = "hukkin@users.noreply.github.com" }, @@ -67,17 +67,18 @@ xfail_strict = true legacy_tox_ini = ''' [tox] # Only run pytest envs when no args given to tox -envlist = py{36,37,38,39} +envlist = py{36,37,38,39,310} isolated_build = True -[testenv:py{36,37,38,39}] +[testenv:py{36,37,38,39,310}] description = run tests against unpackaged source skip_install = True deps = -r tests/requirements.txt commands = - pytest {posargs} + # Use 'python -m pytest' to add CWD to sys.path + python -m pytest {posargs} -[testenv:py{36,37,38,39}-package] +[testenv:py{36,37,38,39,310}-package] description = run tests against a built package (can fail, in theory, if test dependencies need a tomli version incompatible with local state) deps = -r tests/requirements.txt commands = diff --git a/tests/requirements.txt b/tests/requirements.txt index 6fe03b2..ce5780e 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -2,3 +2,4 @@ pytest pytest-randomly pytest-cov >=2.12.1 python-dateutil +coverage !=6.0 diff --git a/tests/test_error.py b/tests/test_error.py index 43cb8ad..d2d982c 100644 --- a/tests/test_error.py +++ b/tests/test_error.py @@ -25,3 +25,13 @@ def test_missing_value(): with pytest.raises(tomli.TOMLDecodeError) as exc_info: tomli.loads("\n\nfwfw=") assert str(exc_info.value) == "Invalid value (at end of document)" + + +def test_invalid_char_quotes(): + with pytest.raises(tomli.TOMLDecodeError) as exc_info: + tomli.loads("v = '\n'") + assert " '\\n' " in str(exc_info.value) + + +def test_module_name(): + assert tomli.TOMLDecodeError().__module__ == "tomli" diff --git a/tests/test_misc.py b/tests/test_misc.py index dcb9715..2eec882 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -3,6 +3,8 @@ import datetime from decimal import Decimal as D from pathlib import Path +import pytest + import tomli @@ -14,7 +16,8 @@ def test_load(tmp_path): # Test text mode with open(file_path, encoding="utf-8", newline="") as f: - actual = tomli.load(f) # type: ignore[arg-type] + with pytest.warns(DeprecationWarning): + actual = tomli.load(f) # type: ignore[arg-type] assert actual == expected # Test binary mode diff --git a/tomli/__init__.py b/tomli/__init__.py index d99eadc..7bcdbab 100644 --- a/tomli/__init__.py +++ b/tomli/__init__.py @@ -1,6 +1,9 @@ """A lil' TOML parser.""" __all__ = ("loads", "load", "TOMLDecodeError") -__version__ = "1.2.1" # DO NOT EDIT THIS LINE MANUALLY. LET bump2version UTILITY DO IT +__version__ = "1.2.2" # DO NOT EDIT THIS LINE MANUALLY. LET bump2version UTILITY DO IT from tomli._parser import TOMLDecodeError, load, loads + +# Pretend this exception was created here. +TOMLDecodeError.__module__ = "tomli" diff --git a/tomli/_parser.py b/tomli/_parser.py index 34d16f4..89e81c3 100644 --- a/tomli/_parser.py +++ b/tomli/_parser.py @@ -1,16 +1,6 @@ import string from types import MappingProxyType -from typing import ( - Any, - BinaryIO, - Callable, - Dict, - FrozenSet, - Iterable, - NamedTuple, - Optional, - Tuple, -) +from typing import Any, BinaryIO, Dict, FrozenSet, Iterable, NamedTuple, Optional, Tuple import warnings from tomli._re import ( @@ -21,6 +11,7 @@ from tomli._re import ( match_to_localtime, match_to_number, ) +from tomli._types import Key, ParseFloat, Pos ASCII_CTRL = frozenset(chr(i) for i in range(32)) | frozenset(chr(127)) @@ -52,11 +43,6 @@ BASIC_STR_ESCAPE_REPLACEMENTS = MappingProxyType( } ) -# Type annotations -ParseFloat = Callable[[str], Any] -Key = Tuple[str, ...] -Pos = int - class TOMLDecodeError(ValueError): """An error raised if a document is not valid TOML.""" @@ -72,6 +58,7 @@ def load(fp: BinaryIO, *, parse_float: ParseFloat = float) -> Dict[str, Any]: "Text file object support is deprecated in favor of binary file objects." ' Use `open("foo.toml", "rb")` to open the file in binary mode.', DeprecationWarning, + stacklevel=2, ) s = s_bytes # type: ignore[assignment] return loads(s, parse_float=parse_float) @@ -265,12 +252,12 @@ def skip_until( except ValueError: new_pos = len(src) if error_on_eof: - raise suffixed_err(src, new_pos, f'Expected "{expect!r}"') + raise suffixed_err(src, new_pos, f"Expected {expect!r}") from None if not error_on.isdisjoint(src[pos:new_pos]): while src[pos] not in error_on: pos += 1 - raise suffixed_err(src, pos, f'Found invalid character "{src[pos]!r}"') + raise suffixed_err(src, pos, f"Found invalid character {src[pos]!r}") return new_pos @@ -306,7 +293,7 @@ def create_dict_rule(src: str, pos: Pos, out: Output) -> Tuple[Pos, Key]: try: out.data.get_or_create_nest(key) except KeyError: - raise suffixed_err(src, pos, "Can not overwrite a value") + raise suffixed_err(src, pos, "Can not overwrite a value") from None if not src.startswith("]", pos): raise suffixed_err(src, pos, 'Expected "]" at the end of a table declaration') @@ -327,7 +314,7 @@ def create_list_rule(src: str, pos: Pos, out: Output) -> Tuple[Pos, Key]: try: out.data.append_nest_to_list(key) except KeyError: - raise suffixed_err(src, pos, "Can not overwrite a value") + raise suffixed_err(src, pos, "Can not overwrite a value") from None if not src.startswith("]]", pos): raise suffixed_err(src, pos, 'Expected "]]" at the end of an array declaration') @@ -350,7 +337,7 @@ def key_value_rule( try: nest = out.data.get_or_create_nest(abs_key_parent) except KeyError: - raise suffixed_err(src, pos, "Can not overwrite a value") + raise suffixed_err(src, pos, "Can not overwrite a value") from None if key_stem in nest: raise suffixed_err(src, pos, "Can not overwrite a value") # Mark inline table and array namespaces recursively immutable @@ -455,9 +442,9 @@ def parse_inline_table(src: str, pos: Pos, parse_float: ParseFloat) -> Tuple[Pos try: nest = nested_dict.get_or_create_nest(key_parent, access_lists=False) except KeyError: - raise suffixed_err(src, pos, "Can not overwrite a value") + raise suffixed_err(src, pos, "Can not overwrite a value") from None if key_stem in nest: - raise suffixed_err(src, pos, f'Duplicate inline table key "{key_stem}"') + raise suffixed_err(src, pos, f"Duplicate inline table key {key_stem!r}") nest[key_stem] = value pos = skip_chars(src, pos, TOML_WS) c = src[pos : pos + 1] @@ -498,8 +485,8 @@ def parse_basic_str_escape( # noqa: C901 return pos, BASIC_STR_ESCAPE_REPLACEMENTS[escape_id] except KeyError: if len(escape_id) != 2: - raise suffixed_err(src, pos, "Unterminated string") - raise suffixed_err(src, pos, 'Unescaped "\\" in a string') + raise suffixed_err(src, pos, "Unterminated string") from None + raise suffixed_err(src, pos, 'Unescaped "\\" in a string') from None def parse_basic_str_escape_multiline(src: str, pos: Pos) -> Tuple[Pos, str]: @@ -570,7 +557,7 @@ def parse_basic_str(src: str, pos: Pos, *, multiline: bool) -> Tuple[Pos, str]: try: char = src[pos] except IndexError: - raise suffixed_err(src, pos, "Unterminated string") + raise suffixed_err(src, pos, "Unterminated string") from None if char == '"': if not multiline: return pos + 1, result + src[start_pos:pos] @@ -585,7 +572,7 @@ def parse_basic_str(src: str, pos: Pos, *, multiline: bool) -> Tuple[Pos, str]: start_pos = pos continue if char in error_on: - raise suffixed_err(src, pos, f'Illegal character "{char!r}"') + raise suffixed_err(src, pos, f"Illegal character {char!r}") pos += 1 @@ -622,8 +609,8 @@ def parse_value( # noqa: C901 if datetime_match: try: datetime_obj = match_to_datetime(datetime_match) - except ValueError: - raise suffixed_err(src, pos, "Invalid date or datetime") + except ValueError as e: + raise suffixed_err(src, pos, "Invalid date or datetime") from e return datetime_match.end(), datetime_obj localtime_match = RE_LOCALTIME.match(src, pos) if localtime_match: diff --git a/tomli/_re.py b/tomli/_re.py index d1bef1a..9126829 100644 --- a/tomli/_re.py +++ b/tomli/_re.py @@ -1,10 +1,9 @@ from datetime import date, datetime, time, timedelta, timezone, tzinfo from functools import lru_cache import re -from typing import TYPE_CHECKING, Any, Optional, Union +from typing import Any, Optional, Union -if TYPE_CHECKING: - from tomli._parser import ParseFloat +from tomli._types import ParseFloat # E.g. # - 00:32:00.999999 diff --git a/tomli/_types.py b/tomli/_types.py new file mode 100644 index 0000000..e37cc80 --- /dev/null +++ b/tomli/_types.py @@ -0,0 +1,6 @@ +from typing import Any, Callable, Tuple + +# Type annotations +ParseFloat = Callable[[str], Any] +Key = Tuple[str, ...] +Pos = int |