Skip to content

Commit

Permalink
series_not_empty decorator (#117)
Browse files Browse the repository at this point in the history
series_not_empty decorator
  • Loading branch information
sbrugman authored Sep 22, 2020
1 parent 3d609b1 commit 0633b15
Show file tree
Hide file tree
Showing 25 changed files with 64 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/visions/test/series_sparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def get_sparse_series():
dtype=pd.SparseDtype(np.bool, False),
),
pd.Series(
pd.SparseArray([None, None, "gold", "black", "silver"]),
pd.arrays.SparseArray([None, None, "gold", "black", "silver"]),
name="str_obj_sparse",
),
# Pending https://github.com/pandas-dev/pandas/issues/35762
Expand Down
3 changes: 2 additions & 1 deletion src/visions/types/boolean.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from visions.types.type import VisionsBaseType
from visions.utils import func_nullable_series_contains
from visions.utils.coercion.test_utils import coercion_map, coercion_map_test
from visions.utils.series_utils import series_not_sparse
from visions.utils.series_utils import series_not_empty, series_not_sparse

hasnan_bool_name = "boolean" if int(pd.__version__.split(".")[0]) >= 1 else "Bool"

Expand Down Expand Up @@ -83,6 +83,7 @@ def get_relations(cls) -> Sequence[TypeRelation]:

@classmethod
@series_not_sparse
@series_not_empty
def contains_op(cls, series: pd.Series, state: dict) -> bool:
if not pdt.is_categorical_dtype(series) and pdt.is_bool_dtype(series):
return True
Expand Down
3 changes: 2 additions & 1 deletion src/visions/types/categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from visions.relations import IdentityRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils.series_utils import series_not_sparse
from visions.utils.series_utils import series_not_empty, series_not_sparse


def _get_relations(cls) -> Sequence[TypeRelation]:
Expand All @@ -30,5 +30,6 @@ def get_relations(cls) -> Sequence[TypeRelation]:

@classmethod
@series_not_sparse
@series_not_empty
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return pdt.is_categorical_dtype(series)
3 changes: 2 additions & 1 deletion src/visions/types/complex.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from visions.types.float import string_is_float
from visions.types.type import VisionsBaseType
from visions.utils.coercion import test_utils
from visions.utils.series_utils import series_not_sparse
from visions.utils.series_utils import series_not_empty, series_not_sparse


def test_imaginary_in_string(
Expand Down Expand Up @@ -60,5 +60,6 @@ def get_relations(cls) -> Sequence[TypeRelation]:

@classmethod
@series_not_sparse
@series_not_empty
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return pdt.is_complex_dtype(series)
3 changes: 2 additions & 1 deletion src/visions/types/count.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from visions.relations import IdentityRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils.series_utils import series_not_sparse
from visions.utils.series_utils import series_not_empty, series_not_sparse


def _get_relations(cls) -> Sequence[TypeRelation]:
Expand All @@ -30,5 +30,6 @@ def get_relations(cls) -> Sequence[TypeRelation]:

@classmethod
@series_not_sparse
@series_not_empty
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return pdt.is_unsigned_integer_dtype(series)
4 changes: 3 additions & 1 deletion src/visions/types/date.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@

from visions.relations import IdentityRelation, InferenceRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils import func_nullable_series_contains
from visions.utils.series_utils import (
class_name_attrs,
func_nullable_series_contains,
nullable_series_contains,
series_not_empty,
)


Expand Down Expand Up @@ -53,6 +54,7 @@ def get_relations(cls) -> Sequence[TypeRelation]:
return _get_relations(cls)

@classmethod
@series_not_empty
@nullable_series_contains
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return class_name_attrs(series, date, ["year", "month", "day"])
3 changes: 2 additions & 1 deletion src/visions/types/date_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from visions.relations import IdentityRelation, InferenceRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils.coercion import test_utils
from visions.utils.series_utils import series_not_sparse
from visions.utils.series_utils import series_not_empty, series_not_sparse


def string_is_datetime(series: pd.Series, state: dict) -> bool:
Expand Down Expand Up @@ -51,5 +51,6 @@ def get_relations(cls) -> Sequence[TypeRelation]:

@classmethod
@series_not_sparse
@series_not_empty
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return pdt.is_datetime64_any_dtype(series)
7 changes: 6 additions & 1 deletion src/visions/types/email_address.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
from visions.relations import IdentityRelation, InferenceRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils.coercion import test_utils
from visions.utils.series_utils import isinstance_attrs, nullable_series_contains
from visions.utils.series_utils import (
isinstance_attrs,
nullable_series_contains,
series_not_empty,
)


def string_is_email(series, state: dict):
Expand Down Expand Up @@ -73,6 +77,7 @@ def get_relations(cls) -> Sequence[TypeRelation]:
return _get_relations(cls)

@classmethod
@series_not_empty
@nullable_series_contains
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return isinstance_attrs(series, FQDA, ["local", "fqdn"])
3 changes: 2 additions & 1 deletion src/visions/types/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from visions.relations import IdentityRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils.series_utils import nullable_series_contains
from visions.utils.series_utils import nullable_series_contains, series_not_empty


def _get_relations(cls) -> Sequence[TypeRelation]:
Expand All @@ -30,6 +30,7 @@ def get_relations(cls) -> Sequence[TypeRelation]:
return _get_relations(cls)

@classmethod
@series_not_empty
@nullable_series_contains
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return all(isinstance(p, pathlib.Path) and p.exists() for p in series)
3 changes: 2 additions & 1 deletion src/visions/types/float.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from visions.relations import IdentityRelation, InferenceRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils.coercion import test_utils
from visions.utils.series_utils import func_nullable_series_contains, series_not_sparse
from visions.utils.series_utils import series_not_empty, series_not_sparse
from visions.utils.warning_handling import suppress_warnings


Expand Down Expand Up @@ -89,6 +89,7 @@ def get_relations(cls) -> Sequence[TypeRelation]:
return _get_relations(cls)

@classmethod
@series_not_empty
@series_not_sparse
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return pdt.is_float_dtype(series)
3 changes: 2 additions & 1 deletion src/visions/types/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from visions.relations import IdentityRelation, InferenceRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils.series_utils import nullable_series_contains
from visions.utils.series_utils import nullable_series_contains, series_not_empty


def string_is_geometry(series: pd.Series, state: dict) -> bool:
Expand Down Expand Up @@ -60,6 +60,7 @@ def get_relations(cls) -> Sequence[TypeRelation]:
return _get_relations(cls)

@classmethod
@series_not_empty
@nullable_series_contains
def contains_op(cls, series: pd.Series, state: dict) -> bool:
from shapely.geometry.base import BaseGeometry
Expand Down
3 changes: 2 additions & 1 deletion src/visions/types/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from visions.relations import IdentityRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils.series_utils import nullable_series_contains
from visions.utils.series_utils import nullable_series_contains, series_not_empty


def _get_relations(cls) -> Sequence[TypeRelation]:
Expand All @@ -31,6 +31,7 @@ def get_relations(cls) -> Sequence[TypeRelation]:
return _get_relations(cls)

@classmethod
@series_not_empty
@nullable_series_contains
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return all(
Expand Down
3 changes: 2 additions & 1 deletion src/visions/types/integer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from visions.relations import IdentityRelation, InferenceRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils import func_nullable_series_contains
from visions.utils.series_utils import series_not_sparse
from visions.utils.series_utils import series_not_empty, series_not_sparse


def to_int(series: pd.Series, state: dict) -> pd.Series:
Expand Down Expand Up @@ -53,5 +53,6 @@ def get_relations(cls) -> Sequence[TypeRelation]:

@classmethod
@series_not_sparse
@series_not_empty
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return pdt.is_integer_dtype(series)
3 changes: 2 additions & 1 deletion src/visions/types/ip_address.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from visions.relations import IdentityRelation, InferenceRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils.coercion import test_utils
from visions.utils.series_utils import nullable_series_contains
from visions.utils.series_utils import nullable_series_contains, series_not_empty


def string_is_ip(series, state: dict):
Expand Down Expand Up @@ -42,6 +42,7 @@ def get_relations(cls) -> Sequence[TypeRelation]:
return _get_relations(cls)

@classmethod
@series_not_empty
@nullable_series_contains
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return all(isinstance(x, _BaseAddress) for x in series)
3 changes: 2 additions & 1 deletion src/visions/types/numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from visions.relations import IdentityRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils.series_utils import series_not_sparse
from visions.utils.series_utils import series_not_empty, series_not_sparse


def _get_relations(cls) -> Sequence[TypeRelation]:
Expand All @@ -30,5 +30,6 @@ def get_relations(cls) -> Sequence[TypeRelation]:

@classmethod
@series_not_sparse
@series_not_empty
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return pdt.is_numeric_dtype(series)
3 changes: 2 additions & 1 deletion src/visions/types/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from visions.relations import IdentityRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils.series_utils import series_not_sparse
from visions.utils.series_utils import series_not_empty, series_not_sparse


def _get_relations(cls) -> Sequence[TypeRelation]:
Expand Down Expand Up @@ -33,6 +33,7 @@ def get_relations(cls) -> Sequence[TypeRelation]:

@classmethod
@series_not_sparse
@series_not_empty
def contains_op(cls, series: pd.Series, state: dict) -> bool:
is_object = pdt.is_object_dtype(series)
if is_object:
Expand Down
2 changes: 2 additions & 0 deletions src/visions/types/ordinal.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from visions.relations import IdentityRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils.series_utils import series_not_empty


def to_ordinal(series: pd.Series) -> pd.Categorical:
Expand Down Expand Up @@ -34,5 +35,6 @@ def get_relations(cls) -> Sequence[TypeRelation]:
return _get_relations(cls)

@classmethod
@series_not_empty
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return pdt.is_categorical_dtype(series) and series.cat.ordered
3 changes: 2 additions & 1 deletion src/visions/types/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from visions.relations import IdentityRelation, InferenceRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils.series_utils import nullable_series_contains
from visions.utils.series_utils import nullable_series_contains, series_not_empty


def string_is_path(series, state: dict) -> bool:
Expand Down Expand Up @@ -51,6 +51,7 @@ def get_relations(cls) -> Sequence[TypeRelation]:
return _get_relations(cls)

@classmethod
@series_not_empty
@nullable_series_contains
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return all(isinstance(x, pathlib.PurePath) and x.is_absolute() for x in series)
3 changes: 2 additions & 1 deletion src/visions/types/string.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from visions.relations import IdentityRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils import func_nullable_series_contains
from visions.utils.series_utils import series_not_sparse
from visions.utils.series_utils import series_not_empty, series_not_sparse


@func_nullable_series_contains
Expand Down Expand Up @@ -39,6 +39,7 @@ def get_relations(cls) -> Sequence[TypeRelation]:

@classmethod
@series_not_sparse
@series_not_empty
def contains_op(cls, series: pd.Series, state: dict) -> bool:
# TODO: without the object check this passes string categories... is there a better way?
if pdt.is_categorical_dtype(series):
Expand Down
2 changes: 2 additions & 0 deletions src/visions/types/time.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
class_name_attrs,
func_nullable_series_contains,
nullable_series_contains,
series_not_empty,
)


Expand Down Expand Up @@ -44,6 +45,7 @@ def get_relations(cls) -> Sequence[TypeRelation]:
return _get_relations(cls)

@classmethod
@series_not_empty
@nullable_series_contains
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return class_name_attrs(series, time, ["microsecond", "hour"])
3 changes: 2 additions & 1 deletion src/visions/types/time_delta.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from visions.relations import IdentityRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils.series_utils import series_not_sparse
from visions.utils.series_utils import series_not_empty, series_not_sparse


def _get_relations(cls) -> Sequence[TypeRelation]:
Expand All @@ -30,5 +30,6 @@ def get_relations(cls) -> Sequence[TypeRelation]:

@classmethod
@series_not_sparse
@series_not_empty
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return pdt.is_timedelta64_dtype(series)
7 changes: 0 additions & 7 deletions src/visions/types/type.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@

class VisionsBaseTypeMeta(ABCMeta):
def __contains__(cls, series: pd.Series, state: dict = {}) -> bool:
# Possible alternative:
# return cls in cls.typeset.detect_type_path(series)

if series.empty:
from visions.types import Generic

return issubclass(cls, Generic)
return cls.contains_op(series, state) # type: ignore

@property
Expand Down
2 changes: 2 additions & 0 deletions src/visions/types/url.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
func_nullable_series_contains,
isinstance_attrs,
nullable_series_contains,
series_not_empty,
)


Expand Down Expand Up @@ -51,6 +52,7 @@ def get_relations(cls) -> Sequence[TypeRelation]:
return _get_relations(cls)

@classmethod
@series_not_empty
@nullable_series_contains
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return isinstance_attrs(series, ParseResult, ["netloc", "scheme"])
7 changes: 6 additions & 1 deletion src/visions/types/uuid.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
from visions.relations import IdentityRelation, InferenceRelation, TypeRelation
from visions.types.type import VisionsBaseType
from visions.utils.coercion.test_utils import coercion_true_test
from visions.utils.series_utils import isinstance_attrs, nullable_series_contains
from visions.utils.series_utils import (
isinstance_attrs,
nullable_series_contains,
series_not_empty,
)


def string_is_uuid(series, state: dict) -> bool:
Expand Down Expand Up @@ -56,6 +60,7 @@ def get_relations(cls) -> Sequence[TypeRelation]:
return _get_relations(cls)

@classmethod
@series_not_empty
@nullable_series_contains
def contains_op(cls, series: pd.Series, state: dict) -> bool:
return isinstance_attrs(series, uuid.UUID, ["time_low", "hex"])
Loading

0 comments on commit 0633b15

Please sign in to comment.