Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM python:3.11-slim

ENV PATH=$PATH:/root/.local/bin
ENV POETRY_VIRTUALENVS_CREATE=false
ENV POETRY_VERSION=1.2.2
ENV POETRY_VERSION=1.6.1

RUN apt-get update \
&& apt-get install -y curl git \
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python: ["3.8", "3.9", "3.10", "3.11"]
python: ["3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
Expand All @@ -34,5 +34,5 @@ jobs:
- name: Test code's execution (pytest)
run: pytest -v tests
- name: Test docs' building (Sphinx)
if: ${{ contains('3.10, 3.11', matrix.python) }}
if: ${{ matrix.python != '3.9' }}
run: docs/build
16 changes: 8 additions & 8 deletions pandas_dataclasses/core/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# standard library
from types import FunctionType
from typing import Any, Callable, Dict, Hashable, Iterable, Optional, Tuple, overload
from typing import Any, Callable, Hashable, Iterable, Optional, overload


# dependencies
Expand Down Expand Up @@ -193,9 +193,9 @@ def asseries(obj: Any, *, factory: Any = None) -> Any:
return squeeze(series)


def get_attrs(spec: Spec) -> Dict[Hashable, Any]:
def get_attrs(spec: Spec) -> dict[Hashable, Any]:
"""Derive attributes from a specification."""
data: Dict[Hashable, Any] = {}
data: dict[Hashable, Any] = {}

for field in spec.fields.of(Tag.ATTR):
data.update(items(field))
Expand All @@ -217,9 +217,9 @@ def get_columns(spec: Spec) -> Optional[pd.MultiIndex]:
)


def get_data(spec: Spec) -> Dict[Hashable, Any]:
def get_data(spec: Spec) -> dict[Hashable, Any]:
"""Derive data from a specification."""
data: Dict[Hashable, Any] = {}
data: dict[Hashable, Any] = {}

for field in spec.fields.of(Tag.DATA):
for key, val in items(field):
Expand All @@ -233,7 +233,7 @@ def get_index(spec: Spec) -> Optional[pd.MultiIndex]:
if not (fields := spec.fields.of(Tag.INDEX)):
return None

data: Dict[Hashable, Any] = {}
data: dict[Hashable, Any] = {}

for field in fields:
for key, val in items(field):
Expand All @@ -251,12 +251,12 @@ def ensure(data: Any, dtype: Optional[str]) -> Any:
data = [data]

if isinstance(data, (pd.Index, pd.Series)):
return type(data)(data, dtype=dtype, copy=False)
return type(data)(data, dtype=dtype, copy=False) # type: ignore
else:
return pd.array(data, dtype=dtype, copy=False)


def items(field: Field) -> Iterable[Tuple[Hashable, Any]]:
def items(field: Field) -> Iterable[tuple[Hashable, Any]]:
"""Generate default(s) of a field specification."""
if field.has(Tag.MULTIPLE):
yield from field.default.items()
Expand Down
8 changes: 4 additions & 4 deletions pandas_dataclasses/core/specs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from dataclasses import Field as Field_, dataclass, fields as fields_, replace
from functools import lru_cache
from itertools import repeat
from typing import Any, Callable, Hashable, Literal, Optional, Tuple, Union
from typing import Any, Callable, Hashable, Literal, Optional, Union


# dependencies
Expand All @@ -25,7 +25,7 @@ class Field:
name: Union[Hashable, HashDict]
"""Name of the field data."""

tags: Tuple[Tag, ...] = ()
tags: tuple[Tag, ...] = ()
"""Tags of the field."""

type: Optional[Any] = None
Expand All @@ -50,7 +50,7 @@ def update(self, obj: Any) -> Self:
)


class Fields(Tuple[Field, ...]):
class Fields(tuple[Field, ...]):
"""List of field specifications with selectors."""

def of(self, tag: Tag) -> Self:
Expand Down Expand Up @@ -104,7 +104,7 @@ def __matmul__(self, obj: Any) -> Self:


@lru_cache(maxsize=None)
def convert_field(field_: "Field_[Any]") -> Field:
def convert_field(field_: Field_[Any]) -> Field:
"""Convert a dataclass field to a field specification."""
return Field(
id=field_.name,
Expand Down
8 changes: 4 additions & 4 deletions pandas_dataclasses/core/tagging.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
from functools import reduce
from itertools import chain, filterfalse
from operator import or_
from typing import Any, Iterable, Optional, Tuple
from typing import Annotated, Any, Iterable, Optional


# dependencies
from typing_extensions import Annotated, Self, TypeGuard, get_args, get_origin
from typing_extensions import Self, TypeGuard, get_args, get_origin


class Tag(Flag):
Expand Down Expand Up @@ -80,13 +80,13 @@ def get_tagged(
return tagged if keep_annotations else get_args(tagged)[0]


def get_tags(tp: Any, bound: Tag = Tag.ANY) -> Tuple[Tag, ...]:
def get_tags(tp: Any, bound: Tag = Tag.ANY) -> tuple[Tag, ...]:
"""Extract all tags from the first tagged type."""
tagged = get_tagged(tp, bound, True)
return tuple(filter(Tag.creates, get_args(tagged)[1:]))


def get_nontags(tp: Any, bound: Tag = Tag.ANY) -> Tuple[Any, ...]:
def get_nontags(tp: Any, bound: Tag = Tag.ANY) -> tuple[Any, ...]:
"""Extract all except tags from the first tagged type."""
tagged = get_tagged(tp, bound, True)
return tuple(filterfalse(Tag.creates, get_args(tagged)[1:]))
8 changes: 4 additions & 4 deletions pandas_dataclasses/core/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@
# standard library
import types
from dataclasses import Field
from typing import Any, Callable, ClassVar, Dict, Hashable, Protocol, TypeVar, Union
from typing import Any, Callable, ClassVar, Hashable, Protocol, TypeVar, Union


# dependencies
from pandas import DataFrame, Series
from typing_extensions import ParamSpec, get_origin


HashDict = Dict[Hashable, Hashable]
HashDict = dict[Hashable, Hashable]
"""Type hint for dictionary of hashable keys and values."""

Pandas = Union[DataFrame, "Series[Any]"]
Expand All @@ -48,7 +48,7 @@
class DataClass(Protocol[PAny]):
"""Protocol for any dataclass object."""

__dataclass_fields__: ClassVar[Dict[str, "Field[Any]"]]
__dataclass_fields__: ClassVar[dict[str, Field[Any]]]

def __init__(self, *args: PAny.args, **kwargs: PAny.kwargs) -> None:
...
Expand All @@ -57,7 +57,7 @@ def __init__(self, *args: PAny.args, **kwargs: PAny.kwargs) -> None:
class DataClassOf(Protocol[TPandas, PAny]):
"""Protocol for any dataclass object with a factory."""

__dataclass_fields__: ClassVar[Dict[str, "Field[Any]"]]
__dataclass_fields__: ClassVar[dict[str, Field[Any]]]
__pandas_factory__: Callable[..., TPandas]

def __init__(self, *args: PAny.args, **kwargs: PAny.kwargs) -> None:
Expand Down
5 changes: 2 additions & 3 deletions pandas_dataclasses/extras/hints.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@


# standard library
from typing import Collection, Dict, Hashable
from typing import Annotated, Collection


# dependencies
from typing_extensions import Annotated
from ..core.tagging import Tag
from ..core.typing import TAny

Expand All @@ -21,5 +20,5 @@
Index = Annotated[Collection[Annotated[TAny, Tag.DTYPE]], Tag.INDEX]
"""Type hint for index fields (``Index[TAny]``)."""

Multiple = Dict[Hashable, Annotated[TAny, Tag.MULTIPLE]]
Multiple = dict[str, Annotated[TAny, Tag.MULTIPLE]]
"""Type hint for multiple-item fields (``Multiple[TAny]``)."""
6 changes: 3 additions & 3 deletions pandas_dataclasses/extras/new.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# standard library
from inspect import signature
from types import MethodType
from typing import Any, Callable, ForwardRef, Generic, Type, Union
from typing import Any, Callable, ForwardRef, Generic, Union


# dependencies
Expand All @@ -23,7 +23,7 @@ def __init__(self, fget: Callable[..., Any]) -> None:
def __get__(
self,
obj: Any,
cls: Type[DataClassOf[TPandas, PAny]],
cls: type[DataClassOf[TPandas, PAny]],
) -> Callable[PAny, TPandas]:
return self.fget(cls) # type: ignore

Expand Down Expand Up @@ -77,7 +77,7 @@ def get_factory(cls: Any) -> Callable[..., Any]:
raise TypeError("Factory must be callable.")


def get_return(cls: Any) -> Union[Type[Any], str]:
def get_return(cls: Any) -> Union[type[Any], str]:
"""Extract a return type from a class."""
for base in getattr(cls, "__orig_bases__", ()):
if get_origin(base) is not As:
Expand Down
Loading