diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bfd57c9a75..ea92e6a643 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: false matrix: - python: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python: ["3.11", "3.12", "3.13", "3.14", "3.15"] collection: - { name: "Amadeus", id: "amadeus" } - { name: "Autosar", id: "autosar" } @@ -37,11 +37,11 @@ jobs: - { name: "Voko", id: "voko" } - { name: "XCBL", id: "xcbl" } steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: submodules: 'recursive' - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v7 with: python-version: ${{ matrix.python }} - name: Install dependencies diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 32624f272f..8278f2368a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,13 +1,13 @@ exclude: "models|output|samples" repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.14 + rev: v0.17.1 hooks: - id: ruff-check args: [ --fix, --show-fixes ] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.19.1 + rev: v2.4.0 hooks: - id: mypy additional_dependencies: @@ -18,7 +18,7 @@ repos: hooks: - id: doc8 - repo: https://github.com/rbubley/mirrors-prettier - rev: v3.8.1 + rev: v3.9.10 hooks: - id: prettier types_or: [markdown] diff --git a/amadeus/test_bindings.py b/amadeus/test_bindings.py index 2a854f5c97..958693c746 100644 --- a/amadeus/test_bindings.py +++ b/amadeus/test_bindings.py @@ -3,8 +3,10 @@ from lxml import etree -from amadeus.models import FareMasterPricerTravelBoardSearch -from amadeus.models import FareMasterPricerTravelBoardSearchReply +from amadeus.models import ( + FareMasterPricerTravelBoardSearch, + FareMasterPricerTravelBoardSearchReply, +) cwd = Path(__file__).parent.absolute() xsd_location = str( diff --git a/bnm/test_xrates.py b/bnm/test_xrates.py index efffbe9bfe..08689bb52c 100644 --- a/bnm/test_xrates.py +++ b/bnm/test_xrates.py @@ -1,12 +1,9 @@ from pathlib import Path -from unittest import mock -from unittest import TestCase +from unittest import TestCase, mock from requests import Response -from bnm.xrates import Currencies -from bnm.xrates import Currency -from bnm.xrates import fetch +from bnm.xrates import Currencies, Currency, fetch class FetchTest(TestCase): diff --git a/bnm/xrates.py b/bnm/xrates.py index 055c96def1..d1c035e094 100644 --- a/bnm/xrates.py +++ b/bnm/xrates.py @@ -1,9 +1,6 @@ import datetime -from dataclasses import asdict -from dataclasses import dataclass -from dataclasses import field +from dataclasses import asdict, dataclass, field from decimal import Decimal -from typing import List import requests from xsdata.formats.dataclass.parsers import XmlParser @@ -13,12 +10,12 @@ @dataclass class Currency: - id: int = field(metadata=dict(type="Attribute", name="ID")) - name: str = field(metadata=dict(type="Element", name="Name")) - num_code: int = field(metadata=dict(type="Element", name="NumCode")) - iso_code: str = field(metadata=dict(type="Element", name="CharCode")) - nominal: int = field(metadata=dict(type="Element", name="Nominal")) - value: Decimal = field(metadata=dict(type="Element", name="Value")) + id: int = field(metadata={"type": "Attribute", "name": "ID"}) + name: str = field(metadata={"type": "Element", "name": "Name"}) + num_code: int = field(metadata={"type": "Element", "name": "NumCode"}) + iso_code: str = field(metadata={"type": "Element", "name": "CharCode"}) + nominal: int = field(metadata={"type": "Element", "name": "Nominal"}) + value: Decimal = field(metadata={"type": "Element", "name": "Value"}) @dataclass @@ -26,10 +23,10 @@ class Currencies: class Meta: name = "ValCurs" - date: str = field(metadata=dict(type="Attribute", name="Date")) - name: str = field(metadata=dict(type="Attribute")) - values: List[Currency] = field( - default_factory=list, metadata=dict(type="Element", name="Valute") + date: str = field(metadata={"type": "Attribute", "name": "Date"}) + name: str = field(metadata={"type": "Attribute"}) + values: list[Currency] = field( + default_factory=list, metadata={"type": "Element", "name": "Valute"} ) diff --git a/bpmn/test_parser.py b/bpmn/test_parser.py index 9eebb0fa98..e9156a3fbb 100644 --- a/bpmn/test_parser.py +++ b/bpmn/test_parser.py @@ -1,5 +1,4 @@ from pathlib import Path -from typing import Dict from bpmn.models import Definitions @@ -10,7 +9,7 @@ def test_waypoint_example(xml_parser, xml_serializer): fixture = "example" xml_fixture = cwd.joinpath(f"{fixture}.xml") xsdata_fixture = cwd.joinpath(f"{fixture}.xsdata.xml") - ns_map: Dict = {} + ns_map: dict = {} obj = xml_parser.from_path(xml_fixture, Definitions, ns_map) result = xml_serializer.render(obj, ns_map=ns_map) diff --git a/conftest.py b/conftest.py index a779fd3637..15277c0af4 100644 --- a/conftest.py +++ b/conftest.py @@ -4,16 +4,16 @@ import pytest from xsdata.formats.dataclass.context import XmlContext -from xsdata.formats.dataclass.parsers import JsonParser -from xsdata.formats.dataclass.parsers import XmlParser -from xsdata.formats.dataclass.serializers import JsonSerializer -from xsdata.formats.dataclass.serializers import PycodeSerializer -from xsdata.formats.dataclass.serializers import XmlSerializer +from xsdata.formats.dataclass.parsers import JsonParser, XmlParser +from xsdata.formats.dataclass.serializers import ( + JsonSerializer, + PycodeSerializer, + TreeSerializer, + XmlSerializer, +) from xsdata.formats.dataclass.serializers.config import SerializerConfig -from xsdata.formats.dataclass.serializers import TreeSerializer from xsdata.utils.debug import convert - _session_context_data: dict[str, Any] = {} diff --git a/generali/test_parser.py b/generali/test_parser.py index 35135352ae..6acc8c8eba 100644 --- a/generali/test_parser.py +++ b/generali/test_parser.py @@ -1,7 +1,6 @@ from pathlib import Path -from typing import Dict -from generali.models.com.generali.enterprise_services.core.gbm.enterprise.agreement.v1 import ( # noqa +from generali.models.com.generali.enterprise_services.core.gbm.enterprise.agreement.v1 import ( NotifyProgramGbmrequest, ) @@ -12,7 +11,7 @@ def test_parser(xml_parser, xml_serializer): fixture = "example" xml_fixture = cwd.joinpath(f"{fixture}.xml") xsdata_fixture = cwd.joinpath(f"{fixture}.xsdata.xml") - ns_map: Dict = {} + ns_map: dict = {} obj = xml_parser.from_path(xml_fixture, NotifyProgramGbmrequest, ns_map) result = xml_serializer.render(obj, ns_map) diff --git a/ipxact/test_bindings.py b/ipxact/test_bindings.py index 8d63cf84d3..c3b6d40f10 100644 --- a/ipxact/test_bindings.py +++ b/ipxact/test_bindings.py @@ -1,11 +1,10 @@ from pathlib import Path -from typing import Dict import pytest from lxml import etree from lxml.etree import DocumentInvalid -from ipxact.models import * # noqa +from ipxact.models import * here = Path(__file__).parent output = here.joinpath("output") @@ -19,7 +18,7 @@ @pytest.mark.parametrize("sample", samples) def test_bindings(sample, xml_parser, xml_serializer, code_serializer): - ns_map: Dict = {} + ns_map: dict = {} obj = xml_parser.from_path(examples.joinpath(sample), ns_map=ns_map) result = xml_serializer.render(obj, ns_map=ns_map) code = code_serializer.render(obj) diff --git a/mise.toml b/mise.toml index 9d6357bbb2..40a9f30be5 100644 --- a/mise.toml +++ b/mise.toml @@ -1,10 +1,11 @@ [tools] -python = "3.13" - +python = "3.11" +uv = "latest" [env] _.python.venv = { path = ".venv", create = true } - -[settings] -python.venv_stdlib = true \ No newline at end of file +[tasks.install] +description = "Install dependencies" +alias = "i" +run = "uv pip install -r requirements.txt" diff --git a/mypy.ini b/mypy.ini index 9ccf67431f..0671b91d9f 100644 --- a/mypy.ini +++ b/mypy.ini @@ -3,3 +3,9 @@ ignore_missing_imports = True [mypy-typed_dataclass.*] ignore_missing_imports = True + +[mypy-generali.models.*] +ignore_errors = True + +[mypy-sdmx_ml.models.*] +ignore_errors = True diff --git a/netex/performance.py b/netex/performance.py index 82b9b2389b..0d98ada800 100644 --- a/netex/performance.py +++ b/netex/performance.py @@ -2,14 +2,13 @@ import time from contextlib import contextmanager from pathlib import Path -from typing import Any from sys import getsizeof +from typing import Any from xsdata.formats.dataclass.context import XmlContext from xsdata.formats.dataclass.parsers import XmlParser from xsdata.formats.dataclass.parsers.config import ParserConfig -from xsdata.formats.dataclass.parsers.handlers import LxmlEventHandler -from xsdata.formats.dataclass.parsers.handlers import XmlEventHandler +from xsdata.formats.dataclass.parsers.handlers import LxmlEventHandler, XmlEventHandler @contextmanager @@ -32,7 +31,7 @@ def get_size(obj, seen=None): seen.add(obj_id) if isinstance(obj, dict): size += sum(get_size(v, seen) for v in obj.values()) - size += sum(get_size(k, seen) for k in obj.keys()) + size += sum(get_size(k, seen) for k in obj) elif hasattr(obj, "__dict__"): size += get_size(obj.__dict__, seen) elif hasattr(obj, "__iter__") and not isinstance(obj, (str, bytes, bytearray)): @@ -41,18 +40,18 @@ def get_size(obj, seen=None): with timing("importing module"): - from netex.models import * # noqa + from netex.models import * sample = str(Path(__file__).parent.joinpath("NeTEx_HTM__2020-10-12.tar.xz")) with timing("decompress sample"): - subprocess.run(["tar", "-xf", sample, "-C", "/tmp"]) + subprocess.run(["tar", "-xf", sample, "-C", "/tmp"], check=True) sample = "/tmp/NeTEx_HTM__2020-10-12.xml" context = XmlContext() config = ParserConfig(fail_on_unknown_properties=False) -from netex.models import PublicationDelivery # noqa +from netex.models import PublicationDelivery with timing("XmlContext warmup"): context.build_recursive(PublicationDelivery) diff --git a/netex/test_bindings.py b/netex/test_bindings.py index 68d488f47a..bae56304b6 100644 --- a/netex/test_bindings.py +++ b/netex/test_bindings.py @@ -1,5 +1,4 @@ from pathlib import Path -from typing import Dict import pytest from lxml import etree @@ -17,7 +16,7 @@ @pytest.mark.parametrize("sample", samples) def test_bindings(sample, xml_parser, xml_serializer, code_serializer): - ns_map: Dict = {} + ns_map: dict = {} obj = xml_parser.from_path(functions.joinpath(sample), PublicationDelivery, ns_map) result = xml_serializer.render(obj, ns_map=ns_map) code = code_serializer.render(obj) diff --git a/requirements.txt b/requirements.txt index e34ccdac13..252999b9a9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ invoke mypy -types-dataclasses pytest pre-commit requests diff --git a/ruff.toml b/ruff.toml index 44d1327c1e..6b21776a15 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1 +1 @@ -target-version = "py310" \ No newline at end of file +target-version = "py311" diff --git a/sabre/test_bindings.py b/sabre/test_bindings.py index 1ea10ad856..1504442996 100644 --- a/sabre/test_bindings.py +++ b/sabre/test_bindings.py @@ -4,7 +4,7 @@ from lxml import etree from xsdata.formats.dataclass.serializers import DictFactory -from sabre.models import OtaAirLowFareSearchRs, OtaAirLowFareSearchRq +from sabre.models import OtaAirLowFareSearchRq, OtaAirLowFareSearchRs cwd = Path(__file__).parent.absolute() xsd_location = str(cwd.joinpath("schemas/BargainFinderMaxRQ_v1-9-7.xsd")) diff --git a/sdmx_ml/test_bindings.py b/sdmx_ml/test_bindings.py index 6d13d9c379..6a5f76d4d2 100644 --- a/sdmx_ml/test_bindings.py +++ b/sdmx_ml/test_bindings.py @@ -1,10 +1,9 @@ from pathlib import Path -from typing import Dict import pytest from lxml import etree -from sdmx_ml.models import * # noqa +from sdmx_ml.models import * here = Path(__file__).parent output = here.joinpath("output") @@ -19,7 +18,7 @@ @pytest.mark.parametrize("sample", samples) def test_bindings(sample, xml_parser, xml_serializer, code_serializer): - ns_map: Dict = {} + ns_map: dict = {} sample_xml = samples_dir.joinpath(sample).read_bytes() obj = xml_parser.from_bytes(sample_xml) result = xml_serializer.render(obj, ns_map=ns_map) diff --git a/spacex/test_bindings.py b/spacex/test_bindings.py index 3bf2b7cec6..08b303ac9a 100644 --- a/spacex/test_bindings.py +++ b/spacex/test_bindings.py @@ -1,5 +1,4 @@ from pathlib import Path -from typing import List from spacex.models import Launches @@ -8,7 +7,7 @@ def test_parser(json_parser, json_serializer): sample = here.joinpath("launches.json") - launches = json_parser.from_path(sample, List[Launches]) + launches = json_parser.from_path(sample, list[Launches]) assert 145 == len(launches) diff --git a/tasks.py b/tasks.py index c04f343333..cde1f2438e 100644 --- a/tasks.py +++ b/tasks.py @@ -1,8 +1,8 @@ import asyncio import sys -from typing import Iterator +from collections.abc import Iterator -from invoke import task, Context, Collection +from invoke import Collection, Context, task # ANSI color codes for suite prefixes (similar to docker-compose) COLORS = [ @@ -55,7 +55,7 @@ def get_suite(c: Context, suite: str | None = None) -> Iterator[str]: def get_prefix(suite: str) -> str: """Get a colored prefix for a suite.""" - max_suite_len = max(len(s) for s in SUITES.keys()) + max_suite_len = max(len(s) for s in SUITES) suite_index = list(SUITES.keys()).index(suite) color = COLORS[suite_index % len(COLORS)] return f"{color}[{suite:<{max_suite_len}}]{RESET}" @@ -150,9 +150,7 @@ async def run_suite_all( return False if not await run_suite_test(suite, output_format, dump_context): return False - if not await run_suite_mypy(suite): - return False - return True + return await run_suite_mypy(suite) def print_summary(results: dict[str, bool], task_name: str) -> bool: @@ -301,7 +299,7 @@ def config(c: Context, suite: str | None = None): ns.add_task(test) ns.add_task(config) -for key in SUITES.keys(): +for key in SUITES: collection = Collection(key) collection.add_task(build) collection.add_task(test) diff --git a/tpdb/test_bindings.py b/tpdb/test_bindings.py index 8cdf9a8383..e81c52d100 100644 --- a/tpdb/test_bindings.py +++ b/tpdb/test_bindings.py @@ -1,10 +1,9 @@ from pathlib import Path -from typing import Dict import pytest from lxml import etree -from sdmx_ml.models import * # noqa +from sdmx_ml.models import * from tpdb.models import Problem here = Path(__file__).parent @@ -20,7 +19,7 @@ @pytest.mark.parametrize("sample", samples) def test_bindings(sample, xml_parser, xml_serializer, code_serializer): - ns_map: Dict = {} + ns_map: dict = {} sample_xml = samples_dir.joinpath(sample).read_bytes() obj = xml_parser.from_bytes(sample_xml, Problem) result = xml_serializer.render(obj, ns_map=ns_map) diff --git a/ubl/test_bindings.py b/ubl/test_bindings.py index 94cf30c58b..cbf575b423 100644 --- a/ubl/test_bindings.py +++ b/ubl/test_bindings.py @@ -1,11 +1,10 @@ import functools from pathlib import Path -from typing import Dict import pytest from lxml import etree -from ubl.models.maindoc import * # noqa +from ubl.models.maindoc import * cases = [] ids = [] @@ -28,7 +27,7 @@ def get_validator(xsd: str): @pytest.mark.parametrize("schema,sample", cases, ids=ids) def test_serialize(schema, sample, xml_parser, xml_serializer, code_serializer): - ns_map: Dict = {} + ns_map: dict = {} obj = xml_parser.from_path(samples.joinpath(sample), ns_map=ns_map) result = xml_serializer.render(obj, ns_map=ns_map) diff --git a/voko/test_bindings.py b/voko/test_bindings.py index 2b76b4eb92..e5b7b3699c 100644 --- a/voko/test_bindings.py +++ b/voko/test_bindings.py @@ -1,5 +1,4 @@ from pathlib import Path -from typing import Dict import pytest from lxml import etree @@ -19,7 +18,7 @@ def test_bindings(sample, xml_parser, xml_serializer): xml_parser.config.load_dtd = True xml_parser.config.resolve_entities = True - ns_map: Dict = {} + ns_map: dict = {} obj = xml_parser.parse(sample, Vortaro, ns_map) result = xml_serializer.render(obj, ns_map=ns_map) diff --git a/xcbl/test_bindings.py b/xcbl/test_bindings.py index 3c3d0e8986..a5fa1e3c20 100644 --- a/xcbl/test_bindings.py +++ b/xcbl/test_bindings.py @@ -1,10 +1,9 @@ from pathlib import Path -from typing import Dict import pytest from lxml import etree -from xcbl.models import * # noqa +from xcbl.models import * here = Path(__file__).parent schemas = here.joinpath("schemas") @@ -15,7 +14,7 @@ @pytest.mark.parametrize("sample", samples) def test_bindings(sample, xml_parser, xml_serializer): - ns_map: Dict = {} + ns_map: dict = {} obj = xml_parser.parse(sample, ns_map=ns_map) result = xml_serializer.render(obj, ns_map=ns_map)