Skip to content

TYPING: check-untyped-defs for io.formats #28129

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

Closed
wants to merge 8 commits into from

Conversation

simonjayhawkins
Copy link
Member

xref #27568

pandas\io\formats\console.py:68: error: Name '__IPYTHON__' is not defined
pandas\io\formats\console.py:78: error: Name 'get_ipython' is not defined
pandas\io\formats\csvs.py:230: error: Need type annotation for 'encoded_labels'
pandas\io\formats\css.py:92: error: Incompatible types in assignment (expression has type "None", variable has type "float")
pandas\io\formats\css.py:163: error: Item "None" of "Optional[Match[Any]]" has no attribute "groups"
pandas\io\formats\format.py:1710: error: Item "None" of "Optional[TextAdjustment]" has no attribute "len"    
pandas\io\formats\excel.py:537: error: Incompatible types in assignment (expression has type "Generator[ExcelCell, None, None]", variable has type "Tuple[]")
pandas\io\formats\style.py:125: error: Need type annotation for 'ctx'
pandas\io\formats\style.py:126: error: Need type annotation for '_todo'
pandas\io\formats\style.py:147: error: Need type annotation for 'hidden_columns'
pandas\io\formats\style.py:158: error: Need type annotation for '_display_funcs'
pandas\io\formats\style.py:247: error: Need type annotation for 'cell_context'
pandas\io\formats\style.py:554: error: Cannot determine type of 'ctx'
pandas\io\formats\style.py:557: error: Cannot determine type of 'ctx'
pandas\io\formats\style.py:1335: error: Invalid type "cls"
pandas\io\formats\style.py:1335: error: Invalid base class```

@simonjayhawkins simonjayhawkins added the Typing type annotations, mypy/pyright type checking label Aug 24, 2019

jinja2 = import_optional_dependency("jinja2", extra="DataFrame.style requires jinja2.")
ApplyArgs = Tuple[Callable[[FrameOrSeries], FrameOrSeries], Axis, Optional[_IndexSlice]]
Kwargs = Dict[str, Any]
Copy link
Member

Choose a reason for hiding this comment

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

Hmm not sure about this; I think would be good to limit the amount of global aliases in use.

Do you see a general use for this outside of the ninja example below?

Copy link
Member Author

Choose a reason for hiding this comment

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

no, but alias used for readability of L130

if we don't use aliases, what's your preference for formatting?

python/mypy#4511

Copy link
Member Author

Choose a reason for hiding this comment

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

i've retained the aliases for readability since "Type aliases are useful for simplifying complex type signatures" https://docs.python.org/3/library/typing.html#type-aliases

but moved them to just before the class where they are used. This pattern is used in https://github.com/python/typeshed/blob/master/stdlib/2and3/codecs.pyi

_ApplyArgs = Tuple[
Callable[[FrameOrSeries], FrameOrSeries], Axis, Optional[_IndexSlice]
]
_Kwargs = Dict[str, Any]
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we should create this for Args and Kwargs. Doesn't PEP 484 have a different way of handling anyway?

https://www.python.org/dev/peps/pep-0484/#arbitrary-argument-lists-and-default-argument-values

Copy link
Member Author

Choose a reason for hiding this comment

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

The Kwargs alias is not for annotating kwargs in function signiture. The kwargs dict is stored in a local variable. I appreciate this could be confusing.

It was to make self._todo = [] # type: List[Tuple[Callable, _ApplyArgs, _Kwargs]] more readable.

i'll inline _Kwargs to avoid this confusion.

@@ -1332,7 +1348,8 @@ def from_custom_template(cls, searchpath, name):
"""
loader = jinja2.ChoiceLoader([jinja2.FileSystemLoader(searchpath), cls.loader])

class MyStyler(cls):
# https://github.com/python/mypy/issues/2477
class MyStyler(cls): # type: ignore
Copy link
Member

Choose a reason for hiding this comment

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

Can't this just be a Type of the self class?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes. with a cast. i'll leave the comment to the mypy issue.

Copy link
Member Author

Choose a reason for hiding this comment

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

even with the correct revealed type for cls, mypy still not happy with the dynamic class creation.

pandas\io\formats\style.py:1351: error: Revealed type is 'Type[pandas.io.formats.style.Styler]'
pandas\io\formats\style.py:1353: error: Invalid type "cls"
pandas\io\formats\style.py:1353: error: Invalid base class

Copy link
Member Author

Choose a reason for hiding this comment

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

to keep things moving, will revert the addition of type:ignore here for now.

Copy link
Member

@WillAyd WillAyd left a comment

Choose a reason for hiding this comment

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

Looking good last few things

axis: Axis = 0,
subset: Optional[_IndexSlice] = None,
**kwargs
):
Copy link
Member

Choose a reason for hiding this comment

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

Can you annotate the return ("Styler"?)

Copy link
Member Author

Choose a reason for hiding this comment

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

OK, but may need to change to generic self https://mypy.readthedocs.io/en/latest/generics.html#generic-methods-and-generic-self because of MyStyler subclass when adding type annotations to functions in this module in future pass. not sure until look at this.

The only reason I added type annotations to the arguments of apply was to ensure they were compatible with _ApplyArgs otherwise this pass would have been to fix check-untyped-def errors only

@@ -47,6 +49,11 @@ def _mpl(func):
raise ImportError(no_mpl_message.format(func.__name__))


_ApplyArgs = Tuple[
Copy link
Member

Choose a reason for hiding this comment

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

I assume this is a function of the code itself and not necessarily the annotation, but I find this pretty tough to digest. Is it documented already somewhere how this works? If not can you comment?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'd rather not in this pass. I don't know this module well enough yet.

This pass is just check-untyped-defs as "Working through this flag in advance may lead to less surprises as annotations are added" xref #27568

Also the sooner we resolve these issues, the sooner we can enable this setting in CI to ensure that code modified in functions without annotations is checked for PRs.

@WillAyd WillAyd added this to the 1.0 milestone Aug 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Typing type annotations, mypy/pyright type checking
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants