From db8216558a73b5c5269359db9b56778b402a77ca Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Tue, 6 Mar 2018 22:42:41 +0100 Subject: [PATCH] CLN/DOC: cache_readonly: remove allow_setting + preserve docstring (#19991) --- pandas/_libs/properties.pyx | 34 +++++++++---------------------- pandas/core/indexes/base.py | 2 +- pandas/tests/indexes/test_base.py | 1 - pandas/tests/test_lib.py | 6 ++++++ 4 files changed, 17 insertions(+), 26 deletions(-) diff --git a/pandas/_libs/properties.pyx b/pandas/_libs/properties.pyx index 4beb24f07c21c..67f58851a9a70 100644 --- a/pandas/_libs/properties.pyx +++ b/pandas/_libs/properties.pyx @@ -6,31 +6,28 @@ from cpython cimport ( PyDict_Contains, PyDict_GetItem, PyDict_SetItem) -cdef class cache_readonly(object): +cdef class CachedProperty(object): cdef readonly: - object func, name, allow_setting + object func, name, __doc__ - def __init__(self, func=None, allow_setting=False): - if func is not None: - self.func = func - self.name = func.__name__ - self.allow_setting = allow_setting - - def __call__(self, func, doc=None): + def __init__(self, func): self.func = func self.name = func.__name__ - return self + self.__doc__ = getattr(func, '__doc__', None) def __get__(self, obj, typ): - # Get the cache or set a default one if needed + if obj is None: + # accessed on the class, not the instance + return self + # Get the cache or set a default one if needed cache = getattr(obj, '_cache', None) if cache is None: try: cache = obj._cache = {} except (AttributeError): - return + return self if PyDict_Contains(cache, self.name): # not necessary to Py_INCREF @@ -40,20 +37,9 @@ cdef class cache_readonly(object): PyDict_SetItem(cache, self.name, val) return val - def __set__(self, obj, value): - - if not self.allow_setting: - raise Exception("cannot set values for [%s]" % self.name) - # Get the cache or set a default one if needed - cache = getattr(obj, '_cache', None) - if cache is None: - try: - cache = obj._cache = {} - except (AttributeError): - return +cache_readonly = CachedProperty - PyDict_SetItem(cache, self.name, value) cdef class AxisProperty(object): cdef: diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 0813c12d573d5..d3a8f11a38715 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -1401,7 +1401,7 @@ def _is_strictly_monotonic_decreasing(self): def is_lexsorted_for_tuple(self, tup): return True - @cache_readonly(allow_setting=True) + @cache_readonly def is_unique(self): """ return if the index has unique values """ return self._engine.is_unique diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index d7f185853ca45..964a6b14d2b1e 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -519,7 +519,6 @@ def test_is_(self): assert not ind.is_(ind.copy()) assert not ind.is_(ind.copy(deep=False)) assert not ind.is_(ind[:]) - assert not ind.is_(ind.view(np.ndarray).view(Index)) assert not ind.is_(np.array(range(10))) # quasi-implementation dependent diff --git a/pandas/tests/test_lib.py b/pandas/tests/test_lib.py index 502f0c3bced61..3e34b48fb6795 100644 --- a/pandas/tests/test_lib.py +++ b/pandas/tests/test_lib.py @@ -3,6 +3,7 @@ import pytest import numpy as np +from pandas import Index from pandas._libs import lib, writers as libwriters import pandas.util.testing as tm @@ -198,3 +199,8 @@ def test_get_reverse_indexer(self): result = lib.get_reverse_indexer(indexer, 5) expected = np.array([4, 2, 3, 6, 7], dtype=np.int64) tm.assert_numpy_array_equal(result, expected) + + +def test_cache_readonly_preserve_docstrings(): + # GH18197 + assert Index.hasnans.__doc__ is not None