diff --git a/.github/workflows/python-testing.yml b/.github/workflows/python-testing.yml index bb24f83..ea7cb02 100644 --- a/.github/workflows/python-testing.yml +++ b/.github/workflows/python-testing.yml @@ -37,3 +37,6 @@ jobs: - name: Test with pytest run: | pytest + - name: Test with mypy + run: | + mypy -m pydantic_yaml diff --git a/pydantic_yaml/_yaml.py b/pydantic_yaml/_yaml.py index 504016e..09549ec 100644 --- a/pydantic_yaml/_yaml.py +++ b/pydantic_yaml/_yaml.py @@ -1,7 +1,9 @@ # flake8: noqa try: - import ruamel.yaml as yaml + import ruamel.yaml as yaml # type: ignore + + # ruamel.yaml doesn't have type annotations if yaml.__version__ < "0.15.0": __yaml_lib__ = "ruamel-old" @@ -9,7 +11,7 @@ __yaml_lib__ = "ruamel-new" except ImportError: try: - import yaml + import yaml # type: ignore __yaml_lib__ = "pyyaml" except ImportError: diff --git a/pydantic_yaml/models.py b/pydantic_yaml/models.py index 6cc9053..6049048 100644 --- a/pydantic_yaml/models.py +++ b/pydantic_yaml/models.py @@ -3,10 +3,10 @@ from pathlib import Path from typing import Any, Callable, Optional, Type, TypeVar, Union -from pydantic.main import BaseModel from pydantic.error_wrappers import ErrorWrapper, ValidationError -from pydantic.types import StrBytes +from pydantic.main import BaseModel from pydantic.parse import Protocol +from pydantic.types import StrBytes from pydantic.utils import ROOT_KEY from ._yaml import yaml @@ -14,12 +14,11 @@ __all__ = ["YamlModel"] try: - from typing import Literal - - ExtendedProto = Union[Protocol, Literal["yaml"]] + from typing import Literal # type: ignore except ImportError: - # I think this would happen with Python < 3.8 - ExtendedProto = Union[Protocol, str] + from typing_extensions import Literal + +ExtendedProto = Union[Protocol, Literal["yaml"]] def is_yaml_requested(content_type: str = None, proto: ExtendedProto = None): @@ -31,7 +30,7 @@ def is_yaml_requested(content_type: str = None, proto: ExtendedProto = None): return is_yaml -T = TypeVar('T', bound='YamlModel') +T = TypeVar("T", bound="YamlModel") class YamlModel(BaseModel): @@ -64,7 +63,7 @@ def yaml( exclude_defaults=exclude_defaults, exclude_none=exclude_none, ) - res = yaml.safe_dump(data) + res = str(yaml.safe_dump(data)) return res @classmethod @@ -73,7 +72,7 @@ def parse_raw( b: StrBytes, *, content_type: str = None, - encoding: str = None, + encoding: str = "utf8", proto: ExtendedProto = None, allow_pickle: bool = False, ) -> T: diff --git a/pydantic_yaml/versioned_models.py b/pydantic_yaml/versioned_models.py index f3af7c5..aade4e7 100644 --- a/pydantic_yaml/versioned_models.py +++ b/pydantic_yaml/versioned_models.py @@ -5,7 +5,8 @@ from .models import YamlModel try: - from pydantic import SemVer + # If Pydantic implements a SemVer string (which I want to make a PR for eventually) + from pydantic import SemVer # type: ignore except ImportError: from ._semver import SemVer diff --git a/setup.cfg b/setup.cfg index e65e1b0..2a51543 100644 --- a/setup.cfg +++ b/setup.cfg @@ -41,15 +41,25 @@ install_requires = semver # 2 or 3 should both work test_require = pytest + mypy [options.package_data] -* = *.yaml, *.yml +* = *.yaml, *.yml, py.typed [options.extras_require] -pyyaml = pyyaml +pyyaml = + pyyaml + types-PyYAML ruamel = ruamel.yaml>=0.15,<0.18 # new API starting from 0.15, but old is still available dev = black flake8 bump2version pytest + mypy + +[mypy] +warn_unused_configs = True + +[mypy-ruamel.*] +ignore_missing_imports = True