Skip to content

Commit

Permalink
fix: fix import of removed private vendored attr in pydantic (#215)
Browse files Browse the repository at this point in the history
* fix: fix private import

* fix lint

* fix omero test
  • Loading branch information
tlambert03 authored Aug 20, 2023
1 parent 5754342 commit cdde6f7
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/ome_types/_pydantic_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def model_fields(obj: BaseModel | type[BaseModel]) -> dict[str, FieldInfo]:

def field_regex(obj: type[BaseModel], field_name: str) -> str | None:
field_info = obj.model_fields[field_name]
if field_info.json_schema_extra:
if isinstance(field_info.json_schema_extra, dict):
return field_info.json_schema_extra.get("pattern")
return None

Expand Down
85 changes: 80 additions & 5 deletions src/ome_types/_vendor/_pydantic_color_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,18 @@
import math
import re
from colorsys import hls_to_rgb, rgb_to_hls
from typing import TYPE_CHECKING, Any, Callable, Tuple, Union, cast
from typing import (
TYPE_CHECKING,
Any,
Callable,
Generator,
Iterable,
Tuple,
Union,
cast,
Collection,
)

from pydantic._internal import _repr, _utils
from pydantic_core import CoreSchema, PydanticCustomError, core_schema

ColorTuple = Union[Tuple[int, int, int], Tuple[int, int, int, float]]
Expand Down Expand Up @@ -72,7 +81,68 @@ def __getitem__(self, item: Any) -> Any:
rads = 2 * math.pi


class Color(_repr.Representation):
class Representation:
# Mixin to provide `__str__`, `__repr__`, and `__pretty__` and `__rich_repr__` methods.
# `__pretty__` is used by [devtools](https://python-devtools.helpmanual.io/).
# `__rich_repr__` is used by [rich](https://rich.readthedocs.io/en/stable/pretty.html).
# (this is not a docstring to avoid adding a docstring to classes which inherit from Representation)

# we don't want to use a type annotation here as it can break get_type_hints
__slots__ = () # type: Collection[str]

def __repr_args__(self) -> Any:
"""Returns the attributes to show in __str__, __repr__, and __pretty__ this is generally overridden.
Can either return:
* name - value pairs, e.g.: `[('foo_name', 'foo'), ('bar_name', ['b', 'a', 'r'])]`
* or, just values, e.g.: `[(None, 'foo'), (None, ['b', 'a', 'r'])]`
"""
attrs_names = self.__slots__
if not attrs_names and hasattr(self, "__dict__"):
attrs_names = self.__dict__.keys()
attrs = ((s, getattr(self, s)) for s in attrs_names)
return [(a, v) for a, v in attrs if v is not None]

def __repr_name__(self) -> str:
"""Name of the instance's class, used in __repr__."""
return self.__class__.__name__

def __repr_str__(self, join_str: str) -> str:
return join_str.join(
repr(v) if a is None else f"{a}={v!r}" for a, v in self.__repr_args__()
)

def __pretty__(
self, fmt: Callable[[Any], Any], **kwargs: Any
) -> Generator[Any, None, None]:
"""Used by devtools (https://python-devtools.helpmanual.io/) to pretty print objects."""
yield f"{self.__repr_name__()}("
yield 1
for name, value in self.__repr_args__():
if name is not None:
yield f"{name}="
yield fmt(value)
yield ","
yield 0
yield -1
yield ")"

def __rich_repr__(self) -> Any:
"""Used by Rich (https://rich.readthedocs.io/en/stable/pretty.html) to pretty print objects."""
for name, field_repr in self.__repr_args__():
if name is None:
yield field_repr
else:
yield name, field_repr

def __str__(self) -> str:
return self.__repr_str__(" ")

def __repr__(self) -> str:
return f'{self.__repr_name__()}({self.__repr_str__(", ")})'


class Color(Representation):
"""
Represents a color.
"""
Expand Down Expand Up @@ -257,7 +327,7 @@ def _validate(cls, __input_value: Any, _: Any) -> Color:
def __str__(self) -> str:
return self.as_named(fallback=True)

def __repr_args__(self) -> _repr.ReprArgs:
def __repr_args__(self) -> Iterable[tuple[str | None, Any]]:
return [(None, self.as_named(fallback=True))] + [("rgb", self.as_rgb_tuple())]

def __eq__(self, other: Any) -> bool:
Expand Down Expand Up @@ -415,6 +485,11 @@ def parse_color_value(value: int | str, max_val: int = 255) -> float:
)


def almost_equal_floats(value_1: float, value_2: float, *, delta: float = 1e-8) -> bool:
"""Return True if two floats are almost equal."""
return abs(value_1 - value_2) <= delta


def parse_float_alpha(value: None | str | float | int) -> float | None:
"""
Parse an alpha value checking it's a valid float in the range 0 to 1.
Expand All @@ -441,7 +516,7 @@ def parse_float_alpha(value: None | str | float | int) -> float | None:
"value is not a valid color: alpha values must be a valid float",
)

if _utils.almost_equal_floats(alpha, 1):
if almost_equal_floats(alpha, 1):
return None
elif 0 <= alpha <= 1:
return alpha
Expand Down
10 changes: 5 additions & 5 deletions src/xsdata_pydantic_basemodel/pydantic_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ def iter_fields(obj: type[M]) -> Iterator[tuple[str, FieldInfo]]:
yield from obj.model_fields.items()

def _get_metadata(pydantic_field: FieldInfo) -> dict[str, Any]:
if pydantic_field.json_schema_extra:
metadata = pydantic_field.json_schema_extra
else:
metadata = {}
return metadata
return (
pydantic_field.json_schema_extra
if isinstance(pydantic_field.json_schema_extra, dict)
else {}
)

def model_config(**kwargs: Any) -> dict | type:
return kwargs
Expand Down
1 change: 1 addition & 0 deletions tests/test_autogen.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def imports_autogen(monkeypatch: MonkeyPatch) -> None:
monkeypatch.syspath_prepend(str(SRC))


@pytest.mark.filterwarnings("ignore:Support for class-based::pydantic")
@pytest.mark.skipif(sys.version_info < (3, 8), reason="docs fail on python3.7")
@pytest.mark.skipif(not os.getenv("CI"), reason="slow")
@pytest.mark.usefixtures("imports_autogen")
Expand Down
1 change: 1 addition & 0 deletions tests/test_omero_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def test_populate_omero(monkeypatch: MonkeyPatch, full_ome_object: OME) -> None:
hash="somehash",
folder="",
metadata=["md5", "img_id", "plate_id", "timestamp"],
merge=False,
)
assert conn.method_calls

Expand Down

0 comments on commit cdde6f7

Please sign in to comment.