Skip to content

Commit

Permalink
Pydantic v2 update (#349)
Browse files Browse the repository at this point in the history
* pydantic compatibility warning

* add note to docs

* try fix MaxOS actions error

* pydantic v2 compatibility

* Keep v1 compatibility

* Remove warning message

* no need to version skip

* update changelog
  • Loading branch information
pjbull authored Jul 12, 2023
1 parent 2a3d712 commit 6b4afe9
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 2 deletions.
4 changes: 4 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# cloudpathlib Changelog

## v0.15.1 (2023-07-12)

- Compatibility with pydantic >= 2.0.0. ([PR #349](https://github.com/drivendataorg/cloudpathlib/pull/349))

## v0.15.0 (2023-06-16)

- Changed return type for `CloudPathMeta.__call__` to fix problems with pyright/pylance ([PR #330](https://github.com/drivendataorg/cloudpathlib/pull/330))
Expand Down
28 changes: 27 additions & 1 deletion cloudpathlib/anypath.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os
from abc import ABC
from pathlib import Path
from typing import Union
from typing import Any, Union

from .cloudpath import InvalidPrefixError, CloudPath
from .exceptions import AnyPathTypeError
Expand Down Expand Up @@ -30,6 +30,32 @@ def __new__(cls, *args, **kwargs) -> Union[CloudPath, Path]: # type: ignore
f"Path exception: {repr(path_exception)}"
)

# =========== pydantic integration special methods ===============
@classmethod
def __get_pydantic_core_schema__(cls, _source_type: Any, _handler):
"""Pydantic special method. See
https://docs.pydantic.dev/2.0/usage/types/custom/"""
try:
from pydantic_core import core_schema

return core_schema.no_info_after_validator_function(
cls.validate,
core_schema.any_schema(),
)
except ImportError:
return None

@classmethod
def validate(cls, v: str) -> Union[CloudPath, Path]:
"""Pydantic special method. See
https://docs.pydantic.dev/2.0/usage/types/custom/"""
try:
return cls.__new__(cls, v)
except AnyPathTypeError as e:
# type errors no longer converted to validation errors
# https://docs.pydantic.dev/2.0/migration/#typeerror-is-no-longer-converted-to-validationerror-in-validators
raise ValueError(e)

@classmethod
def __get_validators__(cls):
"""Pydantic special method. See
Expand Down
20 changes: 20 additions & 0 deletions cloudpathlib/cloudpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -1112,6 +1112,26 @@ def _upload_file_to_cloud(
)

# =========== pydantic integration special methods ===============
@classmethod
def __get_pydantic_core_schema__(cls, _source_type: Any, _handler):
"""Pydantic special method. See
https://docs.pydantic.dev/2.0/usage/types/custom/"""
try:
from pydantic_core import core_schema

return core_schema.no_info_after_validator_function(
cls.validate,
core_schema.any_schema(),
)
except ImportError:
return None

@classmethod
def validate(cls, v: str) -> Self:
"""Used as a Pydantic validator. See
https://docs.pydantic.dev/2.0/usage/types/custom/"""
return cls(v)

@classmethod
def __get_validators__(cls) -> Generator[Callable[[Any], Self], None, None]:
"""Pydantic special method. See
Expand Down
1 change: 1 addition & 0 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ nav:
- cloudpathlib.local: "api-reference/local.md"

markdown_extensions:
- admonition
- pymdownx.highlight
- pymdownx.superfences
- toc:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"

[project]
name = "cloudpathlib"
version = "0.15.0"
version = "0.15.1"
description = "pathlib-style classes for cloud storage services."
readme = "README.md"
authors = [{ name = "DrivenData", email = "[email protected]" }]
Expand Down
3 changes: 3 additions & 0 deletions tests/mock_clients/mock_s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ def copy_from(self, CopySource=None, Metadata=None, MetadataDirective=None):

def download_file(self, to_path, Config=None, ExtraArgs=None):
to_path = Path(to_path)

to_path.parent.mkdir(parents=True, exist_ok=True)

to_path.write_bytes(self.path.read_bytes())
# track config to make sure it's used in tests
self.resource.download_config = Config
Expand Down

0 comments on commit 6b4afe9

Please sign in to comment.