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

Add linters configuration, reformat whole code #503

Merged
merged 9 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ jobs:
fail-fast: false
matrix:
include:
- { python-version: "3.11", session: "black" }
- { python-version: "3.11", session: "flake8" }
- { python-version: "3.11", session: "mypy" }
- { python-version: "3.11", session: "isort" }
- { python-version: "3.12", session: "py312" }
- { python-version: "3.11", session: "py311" }
- { python-version: "3.10", session: "py310" }
Expand Down
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ include *.md
include COPYING
include voluptuous/tests/*.py
include voluptuous/tests/*.md
include pytest.ini
include pyproject.toml
include tox.ini
18 changes: 18 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[tool.black]
target-version = ["py38", "py39", "py310", "py311", "py312"]
skip-string-normalization = true

[tool.isort]
skip_gitignore = true
profile = "black"
multi_line_output = 5

[tool.mypy]
python_version = "3.8"

warn_unused_ignores = true

[tool.pytest.ini_options]
python_files = "tests.py"
testpaths = "voluptuous/tests"
addopts = "--doctest-glob=*.md -v"
4 changes: 0 additions & 4 deletions pytest.ini

This file was deleted.

7 changes: 4 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import io
import sys

from setuptools import setup

import sys
import io
sys.path.insert(0, '.')
version = __import__('voluptuous').__version__

Expand Down Expand Up @@ -38,5 +39,5 @@
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
]
],
)
16 changes: 13 additions & 3 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[tox]
envlist = flake8,py38,py39,py310,py311,py312
envlist = flake8,black,py38,py39,py310,py311,py312

[flake8]
; E501: line too long (X > 79 characters)
; W503 line break before binary operator
ignore = E501,W503
; E203, E704: black-related ignores (see https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#flake8)
extend-ignore = E203, E501, E704
exclude = .tox,.venv,build,*.egg

[testenv]
Expand All @@ -28,3 +28,13 @@ deps =
mypy
pytest
commands = mypy voluptuous

[testenv:black]
deps =
black
commands = black --check .

[testenv:isort]
deps =
isort
commands = isort --check .
9 changes: 6 additions & 3 deletions voluptuous/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# flake8: noqa

# fmt: off
from voluptuous.schema_builder import *
from voluptuous.validators import *
from voluptuous.util import *
from voluptuous.error import *
from voluptuous.validators import *
Copy link
Contributor

Choose a reason for hiding this comment

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

This might actually be a breaking change if anything in .error depends on anything in .validators (which is likely), I would disable isort for __init__.py files

Copy link
Contributor Author

Choose a reason for hiding this comment

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

from voluptuous.error import * # isort: skip

made error go to the bottom of imports


from voluptuous.error import * # isort: skip

# fmt: on

__version__ = '0.14.1'
__author__ = 'alecthomas'
10 changes: 7 additions & 3 deletions voluptuous/error.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# fmt: off
import typing

# fmt: on


class Error(Exception):
"""Base validation exception."""
Expand All @@ -24,7 +27,7 @@ def __init__(
message: str,
path: typing.Optional[typing.List[typing.Hashable]] = None,
error_message: typing.Optional[str] = None,
error_type: typing.Optional[str] = None
error_type: typing.Optional[str] = None,
) -> None:
Error.__init__(self, message)
self._path = path or []
Expand All @@ -44,8 +47,7 @@ def error_message(self) -> str:
return self._error_message

def __str__(self) -> str:
path = ' @ data[%s]' % ']['.join(map(repr, self.path)) \
if self.path else ''
path = ' @ data[%s]' % ']['.join(map(repr, self.path)) if self.path else ''
output = Exception.__str__(self)
if self.error_type:
output += ' for ' + self.error_type
Expand Down Expand Up @@ -207,9 +209,11 @@ class ExactSequenceInvalid(Invalid):

class NotEnoughValid(Invalid):
"""The value did not pass enough validations."""

pass


class TooManyValid(Invalid):
"""The value passed more than expected validations."""

pass
35 changes: 25 additions & 10 deletions voluptuous/humanize.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
# fmt: off
import typing

from voluptuous import Invalid, MultipleInvalid
from voluptuous.error import Error
from voluptuous.schema_builder import Schema
import typing

# fmt: on

MAX_VALIDATION_ERROR_ITEM_LENGTH = 500


def _nested_getitem(data: typing.Any, path: typing.List[typing.Hashable]) -> typing.Optional[typing.Any]:
def _nested_getitem(
data: typing.Any, path: typing.List[typing.Hashable]
) -> typing.Optional[typing.Any]:
for item_index in path:
try:
data = data[item_index]
Expand All @@ -18,24 +23,34 @@ def _nested_getitem(data: typing.Any, path: typing.List[typing.Hashable]) -> typ
return data


def humanize_error(data, validation_error: Invalid, max_sub_error_length: int = MAX_VALIDATION_ERROR_ITEM_LENGTH) -> str:
""" Provide a more helpful + complete validation error message than that provided automatically
def humanize_error(
data,
validation_error: Invalid,
max_sub_error_length: int = MAX_VALIDATION_ERROR_ITEM_LENGTH,
) -> str:
"""Provide a more helpful + complete validation error message than that provided automatically
Invalid and MultipleInvalid do not include the offending value in error messages,
and MultipleInvalid.__str__ only provides the first error.
"""
if isinstance(validation_error, MultipleInvalid):
return '\n'.join(sorted(
humanize_error(data, sub_error, max_sub_error_length)
for sub_error in validation_error.errors
))
return '\n'.join(
sorted(
humanize_error(data, sub_error, max_sub_error_length)
for sub_error in validation_error.errors
)
)
else:
offending_item_summary = repr(_nested_getitem(data, validation_error.path))
if len(offending_item_summary) > max_sub_error_length:
offending_item_summary = offending_item_summary[:max_sub_error_length - 3] + '...'
offending_item_summary = (
offending_item_summary[: max_sub_error_length - 3] + '...'
)
return '%s. Got %s' % (validation_error, offending_item_summary)


def validate_with_humanized_errors(data, schema: Schema, max_sub_error_length: int = MAX_VALIDATION_ERROR_ITEM_LENGTH) -> typing.Any:
def validate_with_humanized_errors(
data, schema: Schema, max_sub_error_length: int = MAX_VALIDATION_ERROR_ITEM_LENGTH
) -> typing.Any:
try:
return schema(data)
except (Invalid, MultipleInvalid) as e:
Expand Down
Loading
Loading