Merging upstream version 3.4.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
0baf3577f1
commit
ba12874741
11 changed files with 94 additions and 68 deletions
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
|
@ -1 +0,0 @@
|
||||||
github: asottile
|
|
13
.github/workflows/main.yml
vendored
Normal file
13
.github/workflows/main.yml
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
name: main
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main, test-me-*]
|
||||||
|
tags: '*'
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
main:
|
||||||
|
uses: asottile/workflows/.github/workflows/tox.yml@v1.5.0
|
||||||
|
with:
|
||||||
|
env: '["py38", "py39", "py310", "py311"]'
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,6 +1,4 @@
|
||||||
*.egg-info
|
*.egg-info
|
||||||
*.pyc
|
*.pyc
|
||||||
/.pytest_cache
|
|
||||||
/.coverage
|
/.coverage
|
||||||
/.tox
|
/.tox
|
||||||
/venv*
|
|
||||||
|
|
|
@ -1,38 +1,37 @@
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.0.1
|
rev: v4.4.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
- id: check-docstring-first
|
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
- id: debug-statements
|
- id: debug-statements
|
||||||
|
- id: double-quote-string-fixer
|
||||||
- id: name-tests-test
|
- id: name-tests-test
|
||||||
- id: requirements-txt-fixer
|
- id: requirements-txt-fixer
|
||||||
- repo: https://github.com/PyCQA/flake8
|
|
||||||
rev: 3.9.2
|
|
||||||
hooks:
|
|
||||||
- id: flake8
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-autopep8
|
|
||||||
rev: v1.5.7
|
|
||||||
hooks:
|
|
||||||
- id: autopep8
|
|
||||||
- repo: https://github.com/asottile/reorder_python_imports
|
|
||||||
rev: v2.6.0
|
|
||||||
hooks:
|
|
||||||
- id: reorder-python-imports
|
|
||||||
args: [--py3-plus]
|
|
||||||
- repo: https://github.com/asottile/pyupgrade
|
|
||||||
rev: v2.24.0
|
|
||||||
hooks:
|
|
||||||
- id: pyupgrade
|
|
||||||
args: [--py36-plus]
|
|
||||||
- repo: https://github.com/asottile/add-trailing-comma
|
|
||||||
rev: v2.1.0
|
|
||||||
hooks:
|
|
||||||
- id: add-trailing-comma
|
|
||||||
args: [--py36-plus]
|
|
||||||
- repo: https://github.com/asottile/setup-cfg-fmt
|
- repo: https://github.com/asottile/setup-cfg-fmt
|
||||||
rev: v1.17.0
|
rev: v2.4.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: setup-cfg-fmt
|
- id: setup-cfg-fmt
|
||||||
|
- repo: https://github.com/asottile/reorder-python-imports
|
||||||
|
rev: v3.10.0
|
||||||
|
hooks:
|
||||||
|
- id: reorder-python-imports
|
||||||
|
args: [--py38-plus, --add-import, 'from __future__ import annotations']
|
||||||
|
- repo: https://github.com/asottile/add-trailing-comma
|
||||||
|
rev: v3.0.1
|
||||||
|
hooks:
|
||||||
|
- id: add-trailing-comma
|
||||||
|
- repo: https://github.com/asottile/pyupgrade
|
||||||
|
rev: v3.10.1
|
||||||
|
hooks:
|
||||||
|
- id: pyupgrade
|
||||||
|
args: [--py38-plus]
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-autopep8
|
||||||
|
rev: v2.0.2
|
||||||
|
hooks:
|
||||||
|
- id: autopep8
|
||||||
|
- repo: https://github.com/PyCQA/flake8
|
||||||
|
rev: 6.1.0
|
||||||
|
hooks:
|
||||||
|
- id: flake8
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
[![Build Status](https://dev.azure.com/asottile/asottile/_apis/build/status/asottile.cfgv?branchName=master)](https://dev.azure.com/asottile/asottile/_build/latest?definitionId=24&branchName=master)
|
[![build status](https://github.com/asottile/cfgv/actions/workflows/main.yml/badge.svg)](https://github.com/asottile/cfgv/actions/workflows/main.yml)
|
||||||
[![Azure DevOps coverage](https://img.shields.io/azure-devops/coverage/asottile/asottile/24/master.svg)](https://dev.azure.com/asottile/asottile/_build/latest?definitionId=24&branchName=master)
|
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/asottile/cfgv/main.svg)](https://results.pre-commit.ci/latest/github/asottile/cfgv/main)
|
||||||
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/asottile/cfgv/master.svg)](https://results.pre-commit.ci/latest/github/asottile/cfgv/master)
|
|
||||||
|
|
||||||
cfgv
|
cfgv
|
||||||
====
|
====
|
||||||
|
@ -9,7 +8,9 @@ Validate configuration and produce human readable error messages.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
`pip install cfgv`
|
```bash
|
||||||
|
pip install cfgv
|
||||||
|
```
|
||||||
|
|
||||||
## Sample error messages
|
## Sample error messages
|
||||||
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
trigger:
|
|
||||||
branches:
|
|
||||||
include: [master, test-me-*]
|
|
||||||
tags:
|
|
||||||
include: ['*']
|
|
||||||
|
|
||||||
resources:
|
|
||||||
repositories:
|
|
||||||
- repository: asottile
|
|
||||||
type: github
|
|
||||||
endpoint: github
|
|
||||||
name: asottile/azure-pipeline-templates
|
|
||||||
ref: refs/tags/v2.1.0
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
- template: job--python-tox.yml@asottile
|
|
||||||
parameters:
|
|
||||||
toxenvs: [pypy3, py36, py37, py38]
|
|
||||||
os: linux
|
|
9
cfgv.py
9
cfgv.py
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
import contextlib
|
import contextlib
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -390,12 +392,15 @@ def load_from_filename(
|
||||||
schema,
|
schema,
|
||||||
load_strategy,
|
load_strategy,
|
||||||
exc_tp=ValidationError,
|
exc_tp=ValidationError,
|
||||||
|
*,
|
||||||
|
display_filename=None,
|
||||||
):
|
):
|
||||||
|
display_filename = display_filename or filename
|
||||||
with reraise_as(exc_tp):
|
with reraise_as(exc_tp):
|
||||||
if not os.path.isfile(filename):
|
if not os.path.isfile(filename):
|
||||||
raise ValidationError(f'{filename} is not a file')
|
raise ValidationError(f'{display_filename} is not a file')
|
||||||
|
|
||||||
with validate_context(f'File {filename}'):
|
with validate_context(f'File {display_filename}'):
|
||||||
try:
|
try:
|
||||||
with open(filename, encoding='utf-8') as f:
|
with open(filename, encoding='utf-8') as f:
|
||||||
contents = f.read()
|
contents = f.read()
|
||||||
|
|
10
setup.cfg
10
setup.cfg
|
@ -1,6 +1,6 @@
|
||||||
[metadata]
|
[metadata]
|
||||||
name = cfgv
|
name = cfgv
|
||||||
version = 3.3.1
|
version = 3.4.0
|
||||||
description = Validate configuration and produce human readable error messages.
|
description = Validate configuration and produce human readable error messages.
|
||||||
long_description = file: README.md
|
long_description = file: README.md
|
||||||
long_description_content_type = text/markdown
|
long_description_content_type = text/markdown
|
||||||
|
@ -8,21 +8,17 @@ url = https://github.com/asottile/cfgv
|
||||||
author = Anthony Sottile
|
author = Anthony Sottile
|
||||||
author_email = asottile@umich.edu
|
author_email = asottile@umich.edu
|
||||||
license = MIT
|
license = MIT
|
||||||
license_file = LICENSE
|
license_files = LICENSE
|
||||||
classifiers =
|
classifiers =
|
||||||
License :: OSI Approved :: MIT License
|
License :: OSI Approved :: MIT License
|
||||||
Programming Language :: Python :: 3
|
Programming Language :: Python :: 3
|
||||||
Programming Language :: Python :: 3 :: Only
|
Programming Language :: Python :: 3 :: Only
|
||||||
Programming Language :: Python :: 3.6
|
|
||||||
Programming Language :: Python :: 3.7
|
|
||||||
Programming Language :: Python :: 3.8
|
|
||||||
Programming Language :: Python :: 3.9
|
|
||||||
Programming Language :: Python :: Implementation :: CPython
|
Programming Language :: Python :: Implementation :: CPython
|
||||||
Programming Language :: Python :: Implementation :: PyPy
|
Programming Language :: Python :: Implementation :: PyPy
|
||||||
|
|
||||||
[options]
|
[options]
|
||||||
py_modules = cfgv
|
py_modules = cfgv
|
||||||
python_requires = >=3.6.1
|
python_requires = >=3.8
|
||||||
|
|
||||||
[bdist_wheel]
|
[bdist_wheel]
|
||||||
universal = True
|
universal = True
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -1,2 +1,4 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
setup()
|
setup()
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import json
|
import json
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
|
@ -34,11 +36,12 @@ from cfgv import WarnAdditionalKeys
|
||||||
|
|
||||||
|
|
||||||
def _assert_exception_trace(e, trace):
|
def _assert_exception_trace(e, trace):
|
||||||
inner = e
|
parts = []
|
||||||
for ctx in trace[:-1]:
|
while e.ctx is not None:
|
||||||
assert inner.ctx == ctx
|
parts.append(e.ctx)
|
||||||
inner = inner.error_msg
|
e = e.error_msg
|
||||||
assert inner.error_msg == trace[-1]
|
parts.append(e.error_msg)
|
||||||
|
assert tuple(parts) == trace
|
||||||
|
|
||||||
|
|
||||||
def test_ValidationError_simple_str():
|
def test_ValidationError_simple_str():
|
||||||
|
@ -580,6 +583,35 @@ def test_load_from_filename_applies_defaults(tmpdir):
|
||||||
assert ret == {'key': False}
|
assert ret == {'key': False}
|
||||||
|
|
||||||
|
|
||||||
|
def test_load_from_filename_custom_display_no_file(tmp_path):
|
||||||
|
with pytest.raises(ValidationError) as excinfo:
|
||||||
|
load_from_filename(
|
||||||
|
tmp_path.joinpath('cfg.json'),
|
||||||
|
map_required,
|
||||||
|
json.loads,
|
||||||
|
display_filename='cfg.json',
|
||||||
|
)
|
||||||
|
_assert_exception_trace(excinfo.value.args[0], ('cfg.json is not a file',))
|
||||||
|
|
||||||
|
|
||||||
|
def test_load_from_filename_custom_display_error(tmp_path):
|
||||||
|
f = tmp_path.joinpath('cfg.json')
|
||||||
|
f.write_text('{}')
|
||||||
|
with pytest.raises(ValidationError) as excinfo:
|
||||||
|
load_from_filename(
|
||||||
|
f,
|
||||||
|
map_required,
|
||||||
|
json.loads,
|
||||||
|
display_filename='cfg.json',
|
||||||
|
)
|
||||||
|
expected = (
|
||||||
|
'File cfg.json',
|
||||||
|
'At foo(key=MISSING)',
|
||||||
|
'Missing required key: key',
|
||||||
|
)
|
||||||
|
_assert_exception_trace(excinfo.value.args[0], expected)
|
||||||
|
|
||||||
|
|
||||||
conditional_recurse = Map(
|
conditional_recurse = Map(
|
||||||
'Map', None,
|
'Map', None,
|
||||||
|
|
||||||
|
|
4
tox.ini
4
tox.ini
|
@ -1,12 +1,12 @@
|
||||||
[tox]
|
[tox]
|
||||||
envlist = py36,py37,pypy3,pre-commit
|
envlist = py,pre-commit
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
deps = -rrequirements-dev.txt
|
deps = -rrequirements-dev.txt
|
||||||
commands =
|
commands =
|
||||||
coverage erase
|
coverage erase
|
||||||
coverage run -m pytest {posargs:tests}
|
coverage run -m pytest {posargs:tests}
|
||||||
coverage report --fail-under 100
|
coverage report
|
||||||
|
|
||||||
[testenv:pre-commit]
|
[testenv:pre-commit]
|
||||||
skip_install = true
|
skip_install = true
|
||||||
|
|
Loading…
Add table
Reference in a new issue