Skip to content

TYP: Annotations in pandas/core/{accessor, sorting}.py #30079

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Dec 6, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions pandas/core/accessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
that can be mixed into or pinned onto other pandas classes.

"""
from typing import FrozenSet, Set
from typing import FrozenSet, List, Set, Union
import warnings

from pandas.util._decorators import Appender
Expand Down Expand Up @@ -58,7 +58,9 @@ def _delegate_method(self, name, *args, **kwargs):
raise TypeError("You cannot call method {name}".format(name=name))

@classmethod
def _add_delegate_accessors(cls, delegate, accessors, typ, overwrite=False):
def _add_delegate_accessors(
cls, delegate, accessors: List[str], typ: str, overwrite: bool = False
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the type annotation of accessors here needs to be compatible with delegate_names below.

_add_delegate_accessors is used in the inner function of delegate_names. This inner function add_delegate_accessors does not have type annotations and is therefore not checked by mypy. Annotating the inner functions gives pandas\core\accessor.py:143: error: Argument 2 to "_add_delegate_accessors" of "PandasDelegate" has incompatible type "Union[List[str], Set[str]]"; expected "List[str]"

Probably Sequence[str] is more appropriate, however beware a string is also a sequence of str.

from typing import Sequence


def foo(bar: Sequence[str]):
    pass


foo(3)
foo("hdfjjdhf")
foo([1, 2, 3])
foo(["bar", "baz"])
test.py:8: error: Argument 1 to "foo" has incompatible type "int"; expected "Sequence[str]"
test.py:10: error: List item 0 has incompatible type "int"; expected "str"
test.py:10: error: List item 1 has incompatible type "int"; expected "str"
test.py:10: error: List item 2 has incompatible type "int"; expected "str"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every combination I tried I got an error. I think I will drop the annotations for accessors in this PR.

):
"""
Add accessors to cls from the delegate class.

Expand Down Expand Up @@ -107,7 +109,9 @@ def f(self, *args, **kwargs):
setattr(cls, name, f)


def delegate_names(delegate, accessors, typ, overwrite=False):
def delegate_names(
delegate, accessors: Union[List[str], Set[str]], typ: str, overwrite: bool = False
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@simonjayhawkins is there some container-ish thing we would use for Union[List[foo], Set[foo]]? Also do we have a convention about annotating return from __init__?

):
"""
Add delegated names to a class using a class decorator. This provides
an alternative usage to directly calling `_add_delegate_accessors`
Expand Down Expand Up @@ -162,7 +166,7 @@ class CachedAccessor:
the single argument ``data``.
"""

def __init__(self, name, accessor):
def __init__(self, name: str, accessor) -> None:
self._name = name
self._accessor = accessor

Expand Down
8 changes: 5 additions & 3 deletions pandas/core/sorting.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def indexer_from_factorized(labels, shape, compress: bool = True):
return get_group_index_sorter(ids, ngroups)


def lexsort_indexer(keys, orders=None, na_position="last"):
def lexsort_indexer(keys, orders=None, na_position: str = "last"):
from pandas.core.arrays import Categorical

labels = []
Expand Down Expand Up @@ -233,7 +233,9 @@ def lexsort_indexer(keys, orders=None, na_position="last"):
return indexer_from_factorized(labels, shape)


def nargsort(items, kind="quicksort", ascending: bool = True, na_position="last"):
def nargsort(
items, kind: str = "quicksort", ascending: bool = True, na_position: str = "last"
):
"""
This is intended to be a drop-in replacement for np.argsort which
handles NaNs. It adds ascending and na_position parameters.
Expand Down Expand Up @@ -273,7 +275,7 @@ class _KeyMapper:
Ease my suffering. Map compressed group id -> key tuple
"""

def __init__(self, comp_ids, ngroups, levels, labels):
def __init__(self, comp_ids, ngroups: int, levels, labels) -> None:
self.levels = levels
self.labels = labels
self.comp_ids = comp_ids.astype(np.int64)
Expand Down