Skip to content
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

quality(mypy): Add type hints and fix all mypy warnings/errors #22212

Merged
merged 11 commits into from Oct 18, 2021

Conversation

oscarbenjamin
Copy link
Contributor

@oscarbenjamin oscarbenjamin commented Oct 3, 2021

References to other Issues or PRs

The general issue for adding type hints is #17945 so probably high-level discussion belongs there.

See also #20173 which did not get merged. At the time it fixed all mypy errors and there were only a few. The fixes in this PR are what is needed after 1 year of not running mypy in CI.

Also previous PRs that originally fixed all the mypy complaints: #20140 and #18244

Brief description of what is fixed or changed

Adds type hints and type: ignore to silence all mypy errors. There are a few places where the mypy errors indicate genuine bugs such as a method being defined in a superclass where it can only really work for a particular subclass. Otherwise mostly this is just about adding hints and adding ignores.

Other comments

Most of the ignores are needed due to python/mypy#2904.

Some of them actually indicate genuine bugs that I can't easily fix for example the tensor module has a lot of code that does inconsistent things with different types of object that probably would fail under some conditions. Ironically it is also the module with the most type hints and many of those hints are incorrect and inconsistent.

The bulk of the work in making this PR was not about adding hints but about fixing incorrect hints. I think that since contributors are beginning to add type hints anyway sympy needs to start running mypy in CI to make sure that the hints are not garbage. I'll do that in a separate PR though after this one is merged.

Release Notes

  • other
    • Type hints were added to silence all mypy errors in the sympy codebase.

@sympy-bot
Copy link

sympy-bot commented Oct 3, 2021

Hi, I am the SymPy bot (v161). I'm here to help you write a release notes entry. Please read the guide on how to write release notes.

Your release notes are in good order.

Here is what the release notes will look like:

  • other
    • Type hints were added to silence all mypy errors in the sympy codebase. (#22212 by @oscarbenjamin)

This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.10.

Click here to see the pull request description that was parsed.
<!-- Your title above should be a short description of what
was changed. Do not include the issue number in the title. -->

#### References to other Issues or PRs
<!-- If this pull request fixes an issue, write "Fixes #NNNN" in that exact
format, e.g. "Fixes #1234" (see
https://tinyurl.com/auto-closing for more information). Also, please
write a comment on that issue linking back to this pull request once it is
open. -->

The general issue for adding type hints is #17945 so probably high-level discussion belongs there.

See also #20173 which did not get merged. At the time it fixed all mypy errors and there were only a few. The fixes in this PR are what is needed after 1 year of not running mypy in CI.

Also previous PRs that originally fixed all the mypy complaints: #20140 and #18244

#### Brief description of what is fixed or changed

Adds type hints and `type: ignore` to silence all mypy errors. There are a few places where the mypy errors indicate genuine bugs such as a method being defined in a superclass where it can only really work for a particular subclass. Otherwise mostly this is just about adding hints and adding ignores.

#### Other comments

Most of the ignores are needed due to https://github.com/python/mypy/issues/2904.

Some of them actually indicate genuine bugs that I can't easily fix for example the tensor module has a lot of code that does inconsistent things with different types of object that probably would fail under some conditions. Ironically it is also the module with the most type hints and many of those hints are incorrect and inconsistent.

The bulk of the work in making this PR was not about adding hints but about fixing incorrect hints. I think that since contributors are beginning to add type hints anyway sympy needs to start running mypy in CI to make sure that the hints are not garbage. I'll do that in a separate PR though after this one is merged.

#### Release Notes

<!-- Write the release notes for this release below between the BEGIN and END
statements. The basic format is a bulleted list with the name of the subpackage
and the release note for this PR. For example:

* solvers
  * Added a new solver for logarithmic equations.

* functions
  * Fixed a bug with log of integers.

or if no release note(s) should be included use:

NO ENTRY

See https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more
information on how to write release notes. The bot will check your release
notes automatically to see if they are formatted correctly. -->

<!-- BEGIN RELEASE NOTES -->
* other
    * Type hints were added to silence all mypy errors in the sympy codebase.
<!-- END RELEASE NOTES -->

Update

The release notes on the wiki have been updated.

@oscarbenjamin
Copy link
Contributor Author

To test the effect of this PR try running mypy sympy on master. With this PR mypy sympy does not report any errors. On master you get 168 errors but actually once I started fixing some of them more and more appeared. It seems like mypy can't handle the sympy codebase on current master and just bails after a while.

@github-actions
Copy link

github-actions bot commented Oct 3, 2021

Benchmark results from GitHub Actions

Lower numbers are good, higher numbers are bad. A ratio less than 1
means a speed up and greater than 1 means a slowdown. Green lines
beginning with + are slowdowns (the PR is slower then master or
master is slower than the previous release). Red lines beginning
with - are speedups.

Significantly changed benchmark results (PR vs master)

Significantly changed benchmark results (master vs previous release)

Full benchmark results can be found as artifacts in GitHub Actions
(click on checks at the top of the PR).

@@ -2,15 +2,16 @@
import random

import itertools
from typing import Sequence as tSequence, Union as tUnion, List as tList, Tuple as tTuple
from typing import (Sequence as tSequence, Union as tUnion, List as tList,
Tuple as tTuple, Set as tSet)
Copy link
Member

Choose a reason for hiding this comment

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

This naming convention isn't the greatest (not that I can think of a better one). Maybe we should require all typing imports to come from sympy.typing which could provide common alias names. Even the fact that some files import Tuple or Dict as is because they don't use the SymPy Tuple or Dict is confusing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Given the ubiquity of typing now in common editors and so on I wonder if sympy needs to bite the bullet and start calling them symTuple or BasicTuple or something so that Tuple can just be for typing. Or actually maybe there was a PEP that was going to change it so you could just do tuple[int] etc...

Copy link
Member

Choose a reason for hiding this comment

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

I'm also adding type hint, and I expect an official naming convention to be documented somewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't want to add a new package sympy.typing for this. Ideally there would be a better place to add things like this like maybe utilities or external (related to the reorganisation that @oscargus has been doing #22291).

Copy link
Contributor

Choose a reason for hiding this comment

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

like maybe utilities or external

I think one may argue for both of these. utilities since it is, sort of, a utility, external since it is an external (as in non-SymPy). But as it is part of Python, I'd probably say utilities (but do not have any strong opinions really).

An additional package may also be an option of course, but it seems to be a single, quite small, file there so maybe hard to argue that it is worth it.

MatPow, symbols, Dummy, Lambda, HadamardProduct, HadamardPower, S
from sympy.matrices.expressions.matexpr import MatrixExpr
from sympy.tensor.array.expressions.array_expressions import ArrayDiagonal, ArrayTensorProduct, \
PermuteDims, ArrayAdd, ArrayContraction, ArrayElementwiseApplyFunc


def convert_matrix_to_array(expr: MatrixExpr) -> Basic:
def convert_matrix_to_array(expr: Basic) -> Basic:
Copy link
Member

Choose a reason for hiding this comment

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

Why is Expr not good enough here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The function calls itself recursively with the args of its argument. In general the args of Expr are not known to be Expr e.g.:

In [11]: M = MatrixSymbol('X', 2, 2)

In [12]: isinstance(M, Expr)
Out[12]: True

In [13]: isinstance(M.args[0], Expr)
Out[13]: False

It should be possible to add type hints to each of the different classes here like MatMul could have

    args: Tuple[Expr, ...]

I expect that adding those type hints will throw up more errors though when I'm actually trying to silence the errors first so that we can run mypy and then add type-hints properly later.

@oscarbenjamin
Copy link
Contributor Author

I realise that there can be improvements here but really I would just like to get this in and enable mypy in CI and then further improvements can be made while CI is running mypy. I have fixed all mypy errors several times now and I just want mypy to be running in CI so that the next time I come to look at this there won't be a load of new errors to fix.

As I said in the OP:

See also #20173 which did not get merged. At the time it fixed all mypy errors and there were only a few. The fixes in this PR are what is needed after 1 year of not running mypy in CI.

Does anyone object to this being merged as it is?

Copy link
Contributor

@redeboer redeboer left a comment

Choose a reason for hiding this comment

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

Great work, good to see that mypy can soon be enforced through CI!

Could you perhaps add (and install) a file py.typed next to sympy/__init__.py? Then mypy sees SymPy as typed when it checks downstream packages.
https://mypy.readthedocs.io/en/stable/installed_packages.html#creating-pep-561-compatible-packages

@oscarbenjamin
Copy link
Contributor Author

Could you perhaps add (and install) a file py.typed next to sympy/__init__.py?

I can but can that also be done in a subsequent PR? The intention in this PR is to silence warnings from mypy sympy. My next planned PR is to enable mypy checking in GitHub actions. After that many changes can be made by many contributors to improve the typing situation but we can then do those with mypy enabled in CI. This PR already has a sizeable diff and I don't want to add to that any more than is needed.

Copy link
Contributor

@redeboer redeboer left a comment

Choose a reason for hiding this comment

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

Okay LGTM

@oscargus
Copy link
Contributor

Let's merge this and then the repackaging and CI integration can come in subsequent PRs.

@oscarbenjamin
Copy link
Contributor Author

Okay great. Thanks for the reviews. I'll merge this and then we can enable mypy in CI.

@oscarbenjamin oscarbenjamin merged commit ef37f78 into sympy:master Oct 18, 2021
@oscarbenjamin oscarbenjamin deleted the pr_mypy2 branch October 18, 2021 13:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants