diff --git a/.github/workflows/tox.yaml b/.github/workflows/tox.yaml index a3de57e7..a9138e86 100644 --- a/.github/workflows/tox.yaml +++ b/.github/workflows/tox.yaml @@ -10,7 +10,7 @@ jobs: strategy: matrix: platform: [ubuntu-latest, windows-latest] - python-version: ["3.8", "3.9", "3.10"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v1 diff --git a/pyproject.toml b/pyproject.toml index 41053764..88f63d5b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,9 @@ license = {text = "Apache"} dependencies = [ 'PyYAML', 'jsonschema', - 'typing-extensions' + 'typing-extensions', + 'importlib-resources', + 'packaging' ] dynamic = ["version", "readme"] diff --git a/src/kubernetes_validate/utils.py b/src/kubernetes_validate/utils.py index e34d94ef..c005b03e 100644 --- a/src/kubernetes_validate/utils.py +++ b/src/kubernetes_validate/utils.py @@ -5,12 +5,14 @@ import platform import re import sys -from distutils.version import LooseVersion from typing import Any, Dict, Generator, List, Union from typing_extensions import Protocol +from packaging.version import Version import jsonschema -import pkg_resources + +import importlib_resources + import yaml from kubernetes_validate.version import __version__ @@ -48,10 +50,12 @@ def __init__(self, message: str): def all_versions() -> List[str]: - schemas = pkg_resources.resource_listdir('kubernetes_validate', '/kubernetes-json-schema') + schemas = importlib_resources.files('kubernetes_validate').joinpath('kubernetes-json-schema') version_regex = re.compile(r'^v([^-]*).*') - return sorted([version_regex.sub(r"\1", schema) for schema in schemas if version_regex.match(schema)], - key=LooseVersion) + return sorted([version_regex.sub(r"\1", schema.name) + for schema in schemas.iterdir() + if version_regex.match(schema.name)], + key=Version) def major_minor(version: str) -> str: @@ -83,24 +87,24 @@ def validate(data: Union[Dict[str, Any], SupportsToDict], desired_version: str, schema_dir = 'v%s-local' % version if strict: schema_dir += '-strict' - schema_file = pkg_resources.resource_filename('kubernetes_validate', - '/kubernetes-json-schema/%s/%s-%s.json' % - (schema_dir, data['kind'].lower(), api_version)) - - try: - f = open(schema_file) - except IOError: - if not os.path.exists(os.path.dirname(schema_file)): - raise VersionNotSupportedError(version=desired_version) - raise SchemaNotFoundError(version=major_minor(desired_version), kind=data['kind'], - api_version=data['apiVersion']) - try: - schema = json.load(f) - except json.decoder.JSONDecodeError: - raise InvalidSchemaError("Couldn't parse schema %s" % schema_file) - finally: - f.close() - schema_dir = os.path.dirname(os.path.abspath(schema_file)) + ref = importlib_resources.files('kubernetes_validate').joinpath('kubernetes-json-schema/%s/%s-%s.json' % + (schema_dir, data['kind'].lower(), + api_version)) + with importlib_resources.as_file(ref) as schema_file: + try: + f = open(schema_file) + except IOError: + if not os.path.exists(os.path.dirname(schema_file)): + raise VersionNotSupportedError(version=desired_version) + raise SchemaNotFoundError(version=major_minor(desired_version), kind=data['kind'], + api_version=data['apiVersion']) + try: + schema = json.load(f) + except json.decoder.JSONDecodeError: + raise InvalidSchemaError("Couldn't parse schema %s" % schema_file) + finally: + f.close() + schema_dir = os.path.dirname(os.path.abspath(schema_file)) uri_prefix = "file://" if platform.system() == 'Windows': diff --git a/tests/test_validate_file.py b/tests/test_validate_file.py index adcdbc1a..27cb3b6e 100644 --- a/tests/test_validate_file.py +++ b/tests/test_validate_file.py @@ -7,34 +7,34 @@ def test_validate_resource_file(): rc = kubernetes_validate.validate_file(os.path.join(parent, 'resource.yaml'), '1.22.0', strict=False, quiet=True, no_warn=True) - assert(rc == 0) + assert (rc == 0) def test_validate_multi_resource_file(): rc = kubernetes_validate.validate_file(os.path.join(parent, 'kuard-all.yaml'), '1.22.0', strict=False, quiet=True, no_warn=True) - assert(rc == 1) + assert (rc == 1) def test_validate_strict_file(): rc = kubernetes_validate.validate_file(os.path.join(parent, 'kuard-extra-property.yaml'), '1.22.0', strict=True, quiet=True, no_warn=True) - assert(rc == 1) + assert (rc == 1) def test_validate_invalid_file(): rc = kubernetes_validate.validate_file(os.path.join(parent, 'kuard-invalid-type.yaml'), '1.22.0', strict=False, quiet=True, no_warn=True) - assert(rc == 1) + assert (rc == 1) def test_validate_madeup_file(): rc = kubernetes_validate.validate_file(os.path.join(parent, 'kuard-made-up-kind.yaml'), '1.22.0', strict=False, quiet=True, no_warn=True) - assert(rc == 0) + assert (rc == 0) def test_validate_version_too_new(): rc = kubernetes_validate.validate_file(os.path.join(parent, 'resource.yaml'), '1.99.0', strict=False, quiet=True, no_warn=True) - assert(rc == 2) + assert (rc == 2) diff --git a/tests/test_validate_resources.py b/tests/test_validate_resources.py index cfd95b63..875cc480 100644 --- a/tests/test_validate_resources.py +++ b/tests/test_validate_resources.py @@ -44,6 +44,7 @@ def test_validate_version_too_new(): except utils.VersionNotSupportedError: assert True + def test_validate_object_resource(): resources = utils.resources_from_file(os.path.join(parent, 'resource.yaml')) diff --git a/tox.ini b/tox.ini index 6dc125ba..221ed38f 100644 --- a/tox.ini +++ b/tox.ini @@ -1,23 +1,25 @@ [tox] minversion = 1.6 -envlist = py{38,39,310}-{pytest,flake8},mypy +envlist = py{38,39,310,311,312}-{pytest,flake8},mypy [gh-actions] python = - 3.8: py38 - 3.9: py39 + 3.8: py38, mypy + 3.9: py39, mypy 3.10: py310, mypy + 3.11: py311, mypy + 3.12: py312, mypy [testenv] -[testenv:py{38,39,310}-pytest] +[testenv:py{38,39,310,311,312}-pytest] deps = -rtest-deps.txt commands = pytest passenv = HOME recreate = False -[testenv:py{38,39,310}-flake8] +[testenv:py{38,39,310,311,312}-flake8] platform = linux|darwin deps = flake8 commands = python -m flake8 src