Skip to content

Commit

Permalink
BUG: fix tab completion (#37173)
Browse files Browse the repository at this point in the history
  • Loading branch information
topper-123 committed Oct 26, 2020
1 parent 178acf6 commit 91a2711
Show file tree
Hide file tree
Showing 13 changed files with 56 additions and 19 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ Other
- Fixed metadata propagation in the :class:`Series.dt` and :class:`Series.str` accessors and :class:`DataFrame.duplicated` and :class:`DataFrame.stack` and :class:`DataFrame.unstack` and :class:`DataFrame.pivot` methods (:issue:`28283`)
- Bug in :meth:`Index.union` behaving differently depending on whether operand is a :class:`Index` or other list-like (:issue:`36384`)
- Passing an array with 2 or more dimensions to the :class:`Series` constructor now raises the more specific ``ValueError``, from a bare ``Exception`` previously (:issue:`35744`)
- Bug in ``accessor.DirNamesMixin``, where ``dir(obj)`` wouldn't show attributes defined on the instance (:issue:`37173`).

.. ---------------------------------------------------------------------------
Expand Down
14 changes: 7 additions & 7 deletions pandas/core/accessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@
that can be mixed into or pinned onto other pandas classes.
"""
from typing import FrozenSet, Set
from typing import FrozenSet, List, Set
import warnings

from pandas.util._decorators import doc


class DirNamesMixin:
_accessors: Set[str] = set()
_deprecations: FrozenSet[str] = frozenset()
_hidden_attrs: FrozenSet[str] = frozenset()

def _dir_deletions(self):
def _dir_deletions(self) -> Set[str]:
"""
Delete unwanted __dir__ for this object.
"""
return self._accessors | self._deprecations
return self._accessors | self._hidden_attrs

def _dir_additions(self):
def _dir_additions(self) -> Set[str]:
"""
Add additional __dir__ for this object.
"""
Expand All @@ -33,15 +33,15 @@ def _dir_additions(self):
pass
return rv

def __dir__(self):
def __dir__(self) -> List[str]:
"""
Provide method name lookup and completion.
Notes
-----
Only provide 'public' methods.
"""
rv = set(dir(type(self)))
rv = set(super().__dir__())
rv = (rv - self._dir_deletions()) | self._dir_additions()
return sorted(rv)

Expand Down
2 changes: 1 addition & 1 deletion pandas/core/arrays/categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ class Categorical(NDArrayBackedExtensionArray, PandasObject, ObjectStringArrayMi
__array_priority__ = 1000
_dtype = CategoricalDtype(ordered=False)
# tolist is not actually deprecated, just suppressed in the __dir__
_deprecations = PandasObject._deprecations | frozenset(["tolist"])
_hidden_attrs = PandasObject._hidden_attrs | frozenset(["tolist"])
_typ = "categorical"
_can_hold_na = True

Expand Down
2 changes: 1 addition & 1 deletion pandas/core/arrays/sparse/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ class SparseArray(OpsMixin, PandasObject, ExtensionArray):
"""

_subtyp = "sparse_array" # register ABCSparseArray
_deprecations = PandasObject._deprecations | frozenset(["get_values"])
_hidden_attrs = PandasObject._hidden_attrs | frozenset(["get_values"])
_sparse_index: SparseIndex

def __init__(
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ class IndexOpsMixin(OpsMixin):

# ndarray compatibility
__array_priority__ = 1000
_deprecations: FrozenSet[str] = frozenset(
_hidden_attrs: FrozenSet[str] = frozenset(
["tolist"] # tolist is not deprecated, just suppressed in the __dir__
)

Expand Down
2 changes: 1 addition & 1 deletion pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ def _constructor(self) -> Type[DataFrame]:
return DataFrame

_constructor_sliced: Type[Series] = Series
_deprecations: FrozenSet[str] = NDFrame._deprecations | frozenset([])
_hidden_attrs: FrozenSet[str] = NDFrame._hidden_attrs | frozenset([])
_accessors: Set[str] = {"sparse"}

@property
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ class NDFrame(PandasObject, SelectionMixin, indexing.IndexingMixin):
]
_internal_names_set: Set[str] = set(_internal_names)
_accessors: Set[str] = set()
_deprecations: FrozenSet[str] = frozenset(["get_values", "tshift"])
_hidden_attrs: FrozenSet[str] = frozenset(["get_values", "tshift"])
_metadata: List[str] = []
_is_copy = None
_mgr: BlockManager
Expand Down
15 changes: 15 additions & 0 deletions pandas/core/groupby/groupby.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,21 @@ def group_selection_context(groupby: "BaseGroupBy") -> Iterator["BaseGroupBy"]:
class BaseGroupBy(PandasObject, SelectionMixin, Generic[FrameOrSeries]):
_group_selection: Optional[IndexLabel] = None
_apply_allowlist: FrozenSet[str] = frozenset()
_hidden_attrs = PandasObject._hidden_attrs | {
"as_index",
"axis",
"dropna",
"exclusions",
"grouper",
"group_keys",
"keys",
"level",
"mutated",
"obj",
"observed",
"sort",
"squeeze",
}

def __init__(
self,
Expand Down
5 changes: 5 additions & 0 deletions pandas/core/indexes/accessors.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@


class Properties(PandasDelegate, PandasObject, NoNewAttributesMixin):
_hidden_attrs = PandasObject._hidden_attrs | {
"orig",
"name",
}

def __init__(self, data: "Series", orig):
if not isinstance(data, ABCSeries):
raise TypeError(
Expand Down
6 changes: 3 additions & 3 deletions pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,9 @@ class Index(IndexOpsMixin, PandasObject):
"""

# tolist is not actually deprecated, just suppressed in the __dir__
_deprecations: FrozenSet[str] = (
PandasObject._deprecations
| IndexOpsMixin._deprecations
_hidden_attrs: FrozenSet[str] = (
PandasObject._hidden_attrs
| IndexOpsMixin._hidden_attrs
| frozenset(["contains", "set_value"])
)

Expand Down
2 changes: 1 addition & 1 deletion pandas/core/indexes/multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ class MultiIndex(Index):
of the mentioned helper methods.
"""

_deprecations = Index._deprecations | frozenset()
_hidden_attrs = Index._hidden_attrs | frozenset()

# initialize to zero-length tuples to make everything work
_typ = "multiindex"
Expand Down
6 changes: 3 additions & 3 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,9 @@ class Series(base.IndexOpsMixin, generic.NDFrame):
_metadata: List[str] = ["name"]
_internal_names_set = {"index"} | generic.NDFrame._internal_names_set
_accessors = {"dt", "cat", "str", "sparse"}
_deprecations = (
base.IndexOpsMixin._deprecations
| generic.NDFrame._deprecations
_hidden_attrs = (
base.IndexOpsMixin._hidden_attrs
| generic.NDFrame._hidden_attrs
| frozenset(["compress", "ptp"])
)

Expand Down
16 changes: 16 additions & 0 deletions pandas/tests/test_register_accessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@

import pandas as pd
import pandas._testing as tm
from pandas.core import accessor


def test_dirname_mixin():
# GH37173

class X(accessor.DirNamesMixin):
x = 1
y: int

def __init__(self):
self.z = 3

result = [attr_name for attr_name in dir(X()) if not attr_name.startswith("_")]

assert result == ["x", "z"]


@contextlib.contextmanager
Expand Down

0 comments on commit 91a2711

Please sign in to comment.