Skip to content

Commit

Permalink
Merge pull request #174 from SciCatProject/remove-pydantic-v1
Browse files Browse the repository at this point in the history
Remove support for pydantic v1
  • Loading branch information
jl-wynen authored Nov 28, 2023
2 parents f73b842 + d5d5c92 commit 1326921
Show file tree
Hide file tree
Showing 16 changed files with 104 additions and 325 deletions.
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ jobs:
strategy:
matrix:
include:
- {python: '3.11', os: ubuntu-22.04, tox: pydantic1-full}
- {python: '3.12', os: ubuntu-22.04, tox: py312-full}
- {python: '3.11', os: ubuntu-22.04, tox: py311-full}
- {python: '3.10', os: ubuntu-22.04, tox: py310-full}
Expand Down
26 changes: 26 additions & 0 deletions docs/release-notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,32 @@ Release notes
Stability, Maintainability, and Testing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vversion
--------

Security
~~~~~~~~

Features
~~~~~~~~

Breaking changes
~~~~~~~~~~~~~~~~

* **Dropped support for Pydantic v1.**

Bugfixes
~~~~~~~~

Documentation
~~~~~~~~~~~~~

Deprecations
~~~~~~~~~~~~

Stability, Maintainability, and Testing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

v23.10.0
--------

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ classifiers = [
requires-python = ">=3.9"
dependencies = [
"email-validator",
"pydantic >= 1.9",
"pydantic >= 2",
"python-dateutil",
"requests >= 2.31",
]
Expand Down
6 changes: 0 additions & 6 deletions requirements-pydantic1/base.in

This file was deleted.

57 changes: 0 additions & 57 deletions requirements-pydantic1/base.txt

This file was deleted.

9 changes: 0 additions & 9 deletions requirements-pydantic1/test.in

This file was deleted.

40 changes: 0 additions & 40 deletions requirements-pydantic1/test.txt

This file was deleted.

51 changes: 4 additions & 47 deletions src/scitacean/_base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,7 @@
from dateutil.parser import parse as parse_datetime

from ._internal.orcid import is_valid_orcid
from ._internal.pydantic_compat import is_pydantic_v1
from .filesystem import RemotePath
from .logging import get_logger
from .pid import PID
from .thumbnail import Thumbnail

try:
# Python 3.11+
Expand Down Expand Up @@ -57,20 +53,9 @@ class DatasetType(str, Enum): # type: ignore[no-redef]
class BaseModel(pydantic.BaseModel):
"""Base class for Pydantic models for communication with SciCat."""

if is_pydantic_v1():

class Config:
extra = pydantic.Extra.forbid
json_encoders = { # noqa: RUF012
PID: lambda v: str(v),
RemotePath: lambda v: v.posix,
Thumbnail: lambda v: v.serialize(),
}

else:
model_config = pydantic.ConfigDict(
extra="forbid",
)
model_config = pydantic.ConfigDict(
extra="forbid",
)

_user_mask: ClassVar[Tuple[str, ...]]
_masked_fields: ClassVar[Optional[Tuple[str, ...]]] = None
Expand Down Expand Up @@ -107,7 +92,7 @@ def get_name(name: str, field: Any) -> Any:
return field.alias if field.alias is not None else name

field_names = {
get_name(name, field) for name, field in instance.get_model_fields().items()
get_name(name, field) for name, field in instance.model_fields.items()
}
default_mask = tuple(key for key in _IGNORED_KWARGS if key not in field_names)
cls._masked_fields = cls._user_mask + default_mask
Expand Down Expand Up @@ -137,34 +122,6 @@ def download_model_type(cls) -> Optional[Type[BaseModel]]:
"""
return None

if is_pydantic_v1():

@classmethod
def get_model_fields(cls) -> Dict[str, Any]:
return cls.__fields__ # type: ignore[return-value]

def model_dump(self, *args: Any, **kwargs: Any) -> Dict[str, Any]:
return self.dict(*args, **kwargs)

def model_dump_json(self, *args: Any, **kwargs: Any) -> str:
return self.json(*args, **kwargs)

@classmethod
def model_construct(
cls: Type[ModelType], *args: Any, **kwargs: Any
) -> ModelType:
return cls.construct(*args, **kwargs)

@classmethod
def model_rebuild(cls, *args: Any, **kwargs: Any) -> Optional[bool]:
return cls.update_forward_refs(*args, **kwargs)

else:

@classmethod
def get_model_fields(cls) -> Dict[str, pydantic.fields.FieldInfo]:
return cls.model_fields


@dataclasses.dataclass
class BaseUserModel:
Expand Down
2 changes: 1 addition & 1 deletion src/scitacean/_html_repr/_attachment_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,4 @@ def _strip_leading_underscore(s: str) -> str:


def _is_read_only(field_name: str) -> bool:
return field_name not in UploadAttachment.get_model_fields()
return field_name not in UploadAttachment.model_fields
34 changes: 0 additions & 34 deletions src/scitacean/_internal/pydantic_compat.py

This file was deleted.

49 changes: 17 additions & 32 deletions src/scitacean/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,10 @@
import re
from datetime import datetime, timezone
from pathlib import Path, PurePath
from typing import Any, Callable, Generator, Optional, TypeVar, Union
from typing import Any, Optional, TypeVar, Union

from ._internal.pydantic_compat import is_pydantic_v1

if not is_pydantic_v1():
from typing import Type

from pydantic import GetCoreSchemaHandler
from pydantic_core import core_schema

def _get_remote_path_core_schema(
cls: Type[RemotePath], _source_type: Any, _handler: GetCoreSchemaHandler
) -> core_schema.CoreSchema:
return core_schema.no_info_after_validator_function(
cls,
core_schema.union_schema(
[core_schema.is_instance_schema(RemotePath), core_schema.str_schema()]
),
serialization=core_schema.plain_serializer_function_ser_schema(
lambda p: p.posix if isinstance(p, RemotePath) else str(p),
info_arg=False,
return_schema=core_schema.str_schema(),
),
)
from pydantic import GetCoreSchemaHandler
from pydantic_core import core_schema


class RemotePath:
Expand Down Expand Up @@ -176,16 +156,21 @@ def validate(cls, value: Union[str, RemotePath]) -> RemotePath:
"""Pydantic validator for RemotePath fields."""
return RemotePath(value)

if is_pydantic_v1():

@classmethod
def __get_validators__(
@classmethod
def __get_pydantic_core_schema__(
cls, _source_type: Any, _handler: GetCoreSchemaHandler
) -> core_schema.CoreSchema:
return core_schema.no_info_after_validator_function(
cls,
) -> Generator[Callable[[Union[str, RemotePath]], RemotePath], None, None]:
yield cls.validate

else:
__get_pydantic_core_schema__ = classmethod(_get_remote_path_core_schema)
core_schema.union_schema(
[core_schema.is_instance_schema(RemotePath), core_schema.str_schema()]
),
serialization=core_schema.plain_serializer_function_ser_schema(
lambda p: p.posix if isinstance(p, RemotePath) else str(p),
info_arg=False,
return_schema=core_schema.str_schema(),
),
)


def _posix(path: Union[str, RemotePath]) -> str:
Expand Down
Loading

0 comments on commit 1326921

Please sign in to comment.