Skip to content

Commit 81f58ec

Browse files
topper-123Kevin D Smith
authored and
Kevin D Smith
committed
BUG: fix tab completion (pandas-dev#37173)
1 parent 8c7fcf8 commit 81f58ec

File tree

13 files changed

+56
-19
lines changed

13 files changed

+56
-19
lines changed

doc/source/whatsnew/v1.2.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@ Other
534534
- 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`)
535535
- Bug in :meth:`Index.union` behaving differently depending on whether operand is a :class:`Index` or other list-like (:issue:`36384`)
536536
- 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`)
537+
- Bug in ``accessor.DirNamesMixin``, where ``dir(obj)`` wouldn't show attributes defined on the instance (:issue:`37173`).
537538

538539
.. ---------------------------------------------------------------------------
539540

pandas/core/accessor.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,23 @@
44
that can be mixed into or pinned onto other pandas classes.
55
66
"""
7-
from typing import FrozenSet, Set
7+
from typing import FrozenSet, List, Set
88
import warnings
99

1010
from pandas.util._decorators import doc
1111

1212

1313
class DirNamesMixin:
1414
_accessors: Set[str] = set()
15-
_deprecations: FrozenSet[str] = frozenset()
15+
_hidden_attrs: FrozenSet[str] = frozenset()
1616

17-
def _dir_deletions(self):
17+
def _dir_deletions(self) -> Set[str]:
1818
"""
1919
Delete unwanted __dir__ for this object.
2020
"""
21-
return self._accessors | self._deprecations
21+
return self._accessors | self._hidden_attrs
2222

23-
def _dir_additions(self):
23+
def _dir_additions(self) -> Set[str]:
2424
"""
2525
Add additional __dir__ for this object.
2626
"""
@@ -33,15 +33,15 @@ def _dir_additions(self):
3333
pass
3434
return rv
3535

36-
def __dir__(self):
36+
def __dir__(self) -> List[str]:
3737
"""
3838
Provide method name lookup and completion.
3939
4040
Notes
4141
-----
4242
Only provide 'public' methods.
4343
"""
44-
rv = set(dir(type(self)))
44+
rv = set(super().__dir__())
4545
rv = (rv - self._dir_deletions()) | self._dir_additions()
4646
return sorted(rv)
4747

pandas/core/arrays/categorical.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ class Categorical(NDArrayBackedExtensionArray, PandasObject, ObjectStringArrayMi
288288
__array_priority__ = 1000
289289
_dtype = CategoricalDtype(ordered=False)
290290
# tolist is not actually deprecated, just suppressed in the __dir__
291-
_deprecations = PandasObject._deprecations | frozenset(["tolist"])
291+
_hidden_attrs = PandasObject._hidden_attrs | frozenset(["tolist"])
292292
_typ = "categorical"
293293
_can_hold_na = True
294294

pandas/core/arrays/sparse/array.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ class SparseArray(OpsMixin, PandasObject, ExtensionArray):
270270
"""
271271

272272
_subtyp = "sparse_array" # register ABCSparseArray
273-
_deprecations = PandasObject._deprecations | frozenset(["get_values"])
273+
_hidden_attrs = PandasObject._hidden_attrs | frozenset(["get_values"])
274274
_sparse_index: SparseIndex
275275

276276
def __init__(

pandas/core/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ class IndexOpsMixin(OpsMixin):
314314

315315
# ndarray compatibility
316316
__array_priority__ = 1000
317-
_deprecations: FrozenSet[str] = frozenset(
317+
_hidden_attrs: FrozenSet[str] = frozenset(
318318
["tolist"] # tolist is not deprecated, just suppressed in the __dir__
319319
)
320320

pandas/core/frame.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ def _constructor(self) -> Type[DataFrame]:
423423
return DataFrame
424424

425425
_constructor_sliced: Type[Series] = Series
426-
_deprecations: FrozenSet[str] = NDFrame._deprecations | frozenset([])
426+
_hidden_attrs: FrozenSet[str] = NDFrame._hidden_attrs | frozenset([])
427427
_accessors: Set[str] = {"sparse"}
428428

429429
@property

pandas/core/generic.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ class NDFrame(PandasObject, SelectionMixin, indexing.IndexingMixin):
200200
]
201201
_internal_names_set: Set[str] = set(_internal_names)
202202
_accessors: Set[str] = set()
203-
_deprecations: FrozenSet[str] = frozenset(["get_values", "tshift"])
203+
_hidden_attrs: FrozenSet[str] = frozenset(["get_values", "tshift"])
204204
_metadata: List[str] = []
205205
_is_copy = None
206206
_mgr: BlockManager

pandas/core/groupby/groupby.py

+15
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,21 @@ def group_selection_context(groupby: "BaseGroupBy") -> Iterator["BaseGroupBy"]:
489489
class BaseGroupBy(PandasObject, SelectionMixin, Generic[FrameOrSeries]):
490490
_group_selection: Optional[IndexLabel] = None
491491
_apply_allowlist: FrozenSet[str] = frozenset()
492+
_hidden_attrs = PandasObject._hidden_attrs | {
493+
"as_index",
494+
"axis",
495+
"dropna",
496+
"exclusions",
497+
"grouper",
498+
"group_keys",
499+
"keys",
500+
"level",
501+
"mutated",
502+
"obj",
503+
"observed",
504+
"sort",
505+
"squeeze",
506+
}
492507

493508
def __init__(
494509
self,

pandas/core/indexes/accessors.py

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828

2929

3030
class Properties(PandasDelegate, PandasObject, NoNewAttributesMixin):
31+
_hidden_attrs = PandasObject._hidden_attrs | {
32+
"orig",
33+
"name",
34+
}
35+
3136
def __init__(self, data: "Series", orig):
3237
if not isinstance(data, ABCSeries):
3338
raise TypeError(

pandas/core/indexes/base.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,9 @@ class Index(IndexOpsMixin, PandasObject):
193193
"""
194194

195195
# tolist is not actually deprecated, just suppressed in the __dir__
196-
_deprecations: FrozenSet[str] = (
197-
PandasObject._deprecations
198-
| IndexOpsMixin._deprecations
196+
_hidden_attrs: FrozenSet[str] = (
197+
PandasObject._hidden_attrs
198+
| IndexOpsMixin._hidden_attrs
199199
| frozenset(["contains", "set_value"])
200200
)
201201

pandas/core/indexes/multi.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ class MultiIndex(Index):
258258
of the mentioned helper methods.
259259
"""
260260

261-
_deprecations = Index._deprecations | frozenset()
261+
_hidden_attrs = Index._hidden_attrs | frozenset()
262262

263263
# initialize to zero-length tuples to make everything work
264264
_typ = "multiindex"

pandas/core/series.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ class Series(base.IndexOpsMixin, generic.NDFrame):
181181
_metadata: List[str] = ["name"]
182182
_internal_names_set = {"index"} | generic.NDFrame._internal_names_set
183183
_accessors = {"dt", "cat", "str", "sparse"}
184-
_deprecations = (
185-
base.IndexOpsMixin._deprecations
186-
| generic.NDFrame._deprecations
184+
_hidden_attrs = (
185+
base.IndexOpsMixin._hidden_attrs
186+
| generic.NDFrame._hidden_attrs
187187
| frozenset(["compress", "ptp"])
188188
)
189189

pandas/tests/test_register_accessor.py

+16
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,22 @@
44

55
import pandas as pd
66
import pandas._testing as tm
7+
from pandas.core import accessor
8+
9+
10+
def test_dirname_mixin():
11+
# GH37173
12+
13+
class X(accessor.DirNamesMixin):
14+
x = 1
15+
y: int
16+
17+
def __init__(self):
18+
self.z = 3
19+
20+
result = [attr_name for attr_name in dir(X()) if not attr_name.startswith("_")]
21+
22+
assert result == ["x", "z"]
723

824

925
@contextlib.contextmanager

0 commit comments

Comments
 (0)