123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- from datetime import datetime
- import sys
- import numpy as np
- import pytest
- from pandas.compat import PYPY
- import pandas as pd
- from pandas import (
- DataFrame,
- Index,
- Series,
- )
- import pandas._testing as tm
- from pandas.core.accessor import PandasDelegate
- from pandas.core.base import (
- NoNewAttributesMixin,
- PandasObject,
- )
- def series_via_frame_from_dict(x, **kwargs):
- return DataFrame({"a": x}, **kwargs)["a"]
- def series_via_frame_from_scalar(x, **kwargs):
- return DataFrame(x, **kwargs)[0]
- @pytest.fixture(
- params=[
- Series,
- series_via_frame_from_dict,
- series_via_frame_from_scalar,
- Index,
- ],
- ids=["Series", "DataFrame-dict", "DataFrame-array", "Index"],
- )
- def constructor(request):
- return request.param
- class TestPandasDelegate:
- class Delegator:
- _properties = ["prop"]
- _methods = ["test_method"]
- def _set_prop(self, value):
- self.prop = value
- def _get_prop(self):
- return self.prop
- prop = property(_get_prop, _set_prop, doc="foo property")
- def test_method(self, *args, **kwargs):
- """a test method"""
- class Delegate(PandasDelegate, PandasObject):
- def __init__(self, obj) -> None:
- self.obj = obj
- def test_invalid_delegation(self):
- # these show that in order for the delegation to work
- # the _delegate_* methods need to be overridden to not raise
- # a TypeError
- self.Delegate._add_delegate_accessors(
- delegate=self.Delegator,
- accessors=self.Delegator._properties,
- typ="property",
- )
- self.Delegate._add_delegate_accessors(
- delegate=self.Delegator, accessors=self.Delegator._methods, typ="method"
- )
- delegate = self.Delegate(self.Delegator())
- msg = "You cannot access the property prop"
- with pytest.raises(TypeError, match=msg):
- delegate.prop
- msg = "The property prop cannot be set"
- with pytest.raises(TypeError, match=msg):
- delegate.prop = 5
- msg = "You cannot access the property prop"
- with pytest.raises(TypeError, match=msg):
- delegate.prop
- @pytest.mark.skipif(PYPY, reason="not relevant for PyPy")
- def test_memory_usage(self):
- # Delegate does not implement memory_usage.
- # Check that we fall back to in-built `__sizeof__`
- # GH 12924
- delegate = self.Delegate(self.Delegator())
- sys.getsizeof(delegate)
- class TestNoNewAttributesMixin:
- def test_mixin(self):
- class T(NoNewAttributesMixin):
- pass
- t = T()
- assert not hasattr(t, "__frozen")
- t.a = "test"
- assert t.a == "test"
- t._freeze()
- assert "__frozen" in dir(t)
- assert getattr(t, "__frozen")
- msg = "You cannot add any new attribute"
- with pytest.raises(AttributeError, match=msg):
- t.b = "test"
- assert not hasattr(t, "b")
- class TestConstruction:
- # test certain constructor behaviours on dtype inference across Series,
- # Index and DataFrame
- @pytest.mark.parametrize(
- "a",
- [
- np.array(["2263-01-01"], dtype="datetime64[D]"),
- np.array([datetime(2263, 1, 1)], dtype=object),
- np.array([np.datetime64("2263-01-01", "D")], dtype=object),
- np.array(["2263-01-01"], dtype=object),
- ],
- ids=[
- "datetime64[D]",
- "object-datetime.datetime",
- "object-numpy-scalar",
- "object-string",
- ],
- )
- def test_constructor_datetime_outofbound(self, a, constructor):
- # GH-26853 (+ bug GH-26206 out of bound non-ns unit)
- # No dtype specified (dtype inference)
- # datetime64[non-ns] raise error, other cases result in object dtype
- # and preserve original data
- if a.dtype.kind == "M":
- # Can't fit in nanosecond bounds -> get the nearest supported unit
- result = constructor(a)
- assert result.dtype == "M8[s]"
- else:
- result = constructor(a)
- assert result.dtype == "object"
- tm.assert_numpy_array_equal(result.to_numpy(), a)
- # Explicit dtype specified
- # Forced conversion fails for all -> all cases raise error
- msg = "Out of bounds|Out of bounds .* present at position 0"
- with pytest.raises(pd.errors.OutOfBoundsDatetime, match=msg):
- constructor(a, dtype="datetime64[ns]")
- def test_constructor_datetime_nonns(self, constructor):
- arr = np.array(["2020-01-01T00:00:00.000000"], dtype="datetime64[us]")
- dta = pd.core.arrays.DatetimeArray._simple_new(arr, dtype=arr.dtype)
- expected = constructor(dta)
- assert expected.dtype == arr.dtype
- result = constructor(arr)
- tm.assert_equal(result, expected)
- # https://github.com/pandas-dev/pandas/issues/34843
- arr.flags.writeable = False
- result = constructor(arr)
- tm.assert_equal(result, expected)
|