Skip to content
This repository was archived by the owner on Jun 10, 2020. It is now read-only.

Ensure stubs are valid for Python 2 and fix running of tests #19

Merged
merged 2 commits into from
May 10, 2018

Conversation

FuegoFro
Copy link
Contributor

@FuegoFro FuegoFro commented May 8, 2018

The stubs contained an unconditional reference to SupportsBytes, which only exists in Python 3. To make these valid on Python 2, conditionally import that Protocol in Python 3 and otherwise use a dummy class in Python 2. Also have ndarray extend Contains, while we're here.

This also extends the test suites to run all tests against both Python 2 and Python 3, with the ability to specify that certain tests should only be run against Python 3 (eg to test Python 3 exclusive operators). This should help prevent errors like this moving forward.

One downside of this is that flake8 doesn't understand the # type: comments, so it thinks that imports from typing are unused. A workaround for this is to add # noqa: F401 at the end of the relevant imports, though this is a bit tedious.

Finally, change how test requirements are installed and how the numpy-stubs package is exposed to mypy, and update the README/Travis file to reflect this. See python/mypy#5007 for more details about the rational behind this change.

The stubs contained an unconditional reference to SupportsBytes, which only exists in Python 3. To make these valid on Python 2, conditionally import that Protocol in Python 3 and otherwise use a dummy class in Python 2. Also have `ndarray` extend `Contains`, while we're here.

This also extends the test suites to run all tests against both Python 2 and Python 3, with the ability to specify that certain tests should only be run against Python 3 (eg to test Python 3 exclusive operators). This should help prevent errors like this moving forward.

One downside of this is that flake8 doesn't understand the `# type:` comments, so it thinks that imports from `typing` are unused. A workaround for this is to add `# noqa: F401` at the end of the relevant imports, though this is a bit tedious.

Finally, change how test requirements are installed and how the `numpy-stubs` package is exposed to mypy, and update the README/Travis file to reflect this. See python/mypy#5007 for more details about the rational behind this change.
Copy link
Member

@shoyer shoyer left a comment

Choose a reason for hiding this comment

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

This looks great, thank you!

@alanhdu @eric-wieser any comments?

@@ -2,3 +2,6 @@ flake8==3.3.0
flake8-pyi==17.3.0
pytest==3.4.2
mypy==0.590
# This makes sure that the repo's stubs are accessible. Using MYPYPATH won't
# work. See https://github.com/python/mypy/issues/5007 for more details.
.
Copy link
Member

Choose a reason for hiding this comment

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

Interesting, I didn't realize that this worked in a requirements.txt file.

Copy link
Contributor

Choose a reason for hiding this comment

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

I prefer to keep the self install separate, as requirements are usually for "dependencies", but I suppose that is more of a stylistic nit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@shoyer Yeah as far as I can tell, anything you can put after pip install you can put as a line in a requirements file :)

@ethanhs That's fair. I mainly wanted to simplify the process of getting the tests to work. But we can definitely remove this and change the README to tell people to run both commands

pip install -r test-requirements.txt
pip install .

if that's what folks prefer :)

Copy link
Member

Choose a reason for hiding this comment

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

Let's do the two command version, just so it's more obvious what is going on. It's pretty non-standard to put . in a requirements.txt file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good, I separated it out and updated the Travis file an README.

if sys.version_info[0] < 3:
class SupportsBytes: ...
else:
from typing import SupportsBytes
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer to see this change be in a separate commit to the reformatting (but I do agree with the reformatting in general)

Copy link
Member

Choose a reason for hiding this comment

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

Personally, I am OK with minor reformatting inline with other changes. There are relatively few cases where I've wanted to look at changes with more granularity than that provided by pull request.

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'm happy to pull this out to a separate commit if you'd like :) In my day job we only do squash-and-merge, so I'm not used to thinking about having granular commits within a PR haha.

Copy link
Member

Choose a reason for hiding this comment

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

I've been doing squash-and-merge for most of the PRs to numpy-stubs, so I think it's fine to keep this as is.

array = np.array([1, 2])

# The @ operator is not in python 2
array @ array
Copy link
Contributor

Choose a reason for hiding this comment

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

Some people on 3.4 may want to run the test suite, so perhaps this shouldn't be used? Mypy defaults to using the python version of the executable used to run it.

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 enough people are still running Python 3.4 that we need to worry about this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could try to come up with a more generalized way of specifying what versions of python a given file can run on, or extend the mechanism so we have something like _py<min_version>.py files, where min_version could be 3, but could also be something like 3.5. If you think that's worth it I'm happy to do that :)

@@ -2,3 +2,6 @@ flake8==3.3.0
flake8-pyi==17.3.0
pytest==3.4.2
mypy==0.590
# This makes sure that the repo's stubs are accessible. Using MYPYPATH won't
# work. See https://github.com/python/mypy/issues/5007 for more details.
.
Copy link
Contributor

Choose a reason for hiding this comment

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

I prefer to keep the self install separate, as requirements are usually for "dependencies", but I suppose that is more of a stylistic nit.

Copy link
Contributor Author

@FuegoFro FuegoFro left a comment

Choose a reason for hiding this comment

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

Thank you so much for the quick reviews! It was a bit unclear to me if I should actually change some of these things, so let me know what you'd like to see changed before merging :)

if sys.version_info[0] < 3:
class SupportsBytes: ...
else:
from typing import SupportsBytes
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'm happy to pull this out to a separate commit if you'd like :) In my day job we only do squash-and-merge, so I'm not used to thinking about having granular commits within a PR haha.

@@ -2,3 +2,6 @@ flake8==3.3.0
flake8-pyi==17.3.0
pytest==3.4.2
mypy==0.590
# This makes sure that the repo's stubs are accessible. Using MYPYPATH won't
# work. See https://github.com/python/mypy/issues/5007 for more details.
.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@shoyer Yeah as far as I can tell, anything you can put after pip install you can put as a line in a requirements file :)

@ethanhs That's fair. I mainly wanted to simplify the process of getting the tests to work. But we can definitely remove this and change the README to tell people to run both commands

pip install -r test-requirements.txt
pip install .

if that's what folks prefer :)

array = np.array([1, 2])

# The @ operator is not in python 2
array @ array
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could try to come up with a more generalized way of specifying what versions of python a given file can run on, or extend the mechanism so we have something like _py<min_version>.py files, where min_version could be 3, but could also be something like 3.5. If you think that's worth it I'm happy to do that :)

@shoyer
Copy link
Member

shoyer commented May 10, 2018

I should have mentioned this before, but could you kindly add Python 2.7 (and maybe Python 3.5) to our test matrix configuration for Travis-CI?

Copy link
Contributor Author

@FuegoFro FuegoFro left a comment

Choose a reason for hiding this comment

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

Regarding

but could you kindly add Python 2.7 (and maybe Python 3.5) to our test matrix configuration for Travis-CI

I'm not entirely sure what this means in this context. In particular, mypy itself should always be run on Python 3, and I'm not sure if we need to test that the mypy tool works on Python 3.5 (that's what mypy's tests are for, right?).

In terms of telling mypy which Python version it should interpret the code/stubs for (eg via the --python-version flag), this diff already handles Python 2.7:

Note that the -2 and --py2 flags are aliases for --python-version 2.7

We can certainly extend the parameterization to also pass --python-version 3.5 to mypy for each test file :)

@@ -2,3 +2,6 @@ flake8==3.3.0
flake8-pyi==17.3.0
pytest==3.4.2
mypy==0.590
# This makes sure that the repo's stubs are accessible. Using MYPYPATH won't
# work. See https://github.com/python/mypy/issues/5007 for more details.
.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good, I separated it out and updated the Travis file an README.

@shoyer
Copy link
Member

shoyer commented May 10, 2018

I'm not entirely sure what this means in this context. In particular, mypy itself should always be run on Python 3, and I'm not sure if we need to test that the mypy tool works on Python 3.5 (that's what mypy's tests are for, right?).

OK, I think I missed this about mypy. So nevermind then :).

At some point it would be interesting to run unit tests with pytype, but that's a whole separate project.

@shoyer shoyer merged commit a4857d4 into numpy:master May 10, 2018
@shoyer
Copy link
Member

shoyer commented May 10, 2018

Thanks @FuegoFro !

@FuegoFro
Copy link
Contributor Author

Thank you!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants