Uh oh!
There was an error while loading. Please reload this page.
Add optional requires_python to third party stubs metadata - #10724
Conversation
It wouldn't be as easy to adjust pyright/pytype, but I also don't think it'll be as important to "fix" those tests in a "principled" way; we can probably leave them as they are for now |
AlexWaygood
commented
Sep 17, 2023
The changes to |
hamdanal
commented
Sep 17, 2023
Okay. I'll leave them for later
Let me see if it is simple enough to do here, if not I'll leave it as well |
Uh oh!
There was an error while loading. Please reload this page.
AlexWaygood
left a comment
There was a problem hiding this comment.
Lots of good stuff here, but needs a few changes -- see my comments below:
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- move to pyproject.toml - add to __all__ - parens in message - mininum supported version is also not allowed - delete print - test against python runtime version and target versions (mypy and regr tests) - different messages for different reasons - default the specifier to >=oldest_supported
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
With this PR checked out, I tried applying this diff: diff --git a/stubs/requests/METADATA.toml b/stubs/requests/METADATA.toml
index 39371b90e..677799c7d 100644
--- a/stubs/requests/METADATA.toml+++ b/stubs/requests/METADATA.toml@@ -1,6 +1,7 @@
version = "2.31.*"
upstream_repository = "https://github.com/psf/requests"
requires = ["types-urllib3"]
+requires_python = ">=3.9"
[tool.stubtest]
extras = ["socks"]I then ran this command (using Python 3.11): Output: *** Testing Python 3.12 on win32
Testing third-party packages...
testing requests (17 files)... success
*** Testing Python 3.11 on win32
Testing third-party packages...
testing requests (17 files)... success
*** Testing Python 3.10 on win32
Testing third-party packages...
testing requests (17 files)... success
*** Testing Python 3.9 on win32
Testing third-party packages...
testing requests (17 files)... success
*** Testing Python 3.8 on win32
Testing third-party packages...
skipping 'requests' for target Python 3.8 (requires Python >=3.9)
Traceback (most recent call last):
File "C:\Users\alexw\coding\typeshed\tests\mypy_test.py", line 573, in <module>
main()
File "C:\Users\alexw\coding\typeshed\tests\mypy_test.py", line 556, in main
code, files_checked_this_version, packages_skipped_this_version = test_typeshed(code, args=config, tempdir=td_path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\alexw\coding\typeshed\tests\mypy_test.py", line 535, in test_typeshed
code, third_party_files_checked, third_party_packages_skipped = test_third_party_stubs(code, args, tempdir)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\alexw\coding\typeshed\tests\mypy_test.py", line 511, in test_third_party_stubsassert_DISTRIBUTION_TO_VENV_MAPPING.keys() == distributions_to_check.keys()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Running this: Results in this output being printed to the terminal: Could we have it print something like "All tests were skipped!" to the terminal, if all tests were skipped? If all tests were skipped, that doesn't feel like a "successful" test run to me. |
| # Some distributions may have been skipped earlier and therefore don't have a venv. | ||
| distributions_without_venv = { | ||
| distribution: requirements | ||
| for distribution, requirements in distributions_to_check.items() | ||
| if distribution not in _DISTRIBUTION_TO_VENV_MAPPING | ||
| } | ||
| if distributions_without_venv: | ||
| setup_virtual_environments(distributions_without_venv, args, tempdir) | ||
| # Check that there is a venv for every distribution we're testing. | ||
| # Some venvs may exist from previous runs but are skipped in this run. | ||
| assert _DISTRIBUTION_TO_VENV_MAPPING.keys() >= distributions_to_check.keys() | ||
| for distribution in distributions_to_check: | ||
| venv_info = _DISTRIBUTION_TO_VENV_MAPPING[distribution] |
There was a problem hiding this comment.
OK so this should work now in all cases (hopefully). I tested with your requests example and all these invocations work
python tests/mypy_test.py stubs/requestspython tests/mypy_test.py stubs/requests*# multiple packages togetherpython tests/mypy_test.py stubs/requests -p 3.8 3.9 3.10 3.11python tests/mypy_test.py stubs/requests -p 3.11 3.8 3.9 3.10# this also crashed before, order is importantpython tests/mypy_test.py stubs/requests* -p 3.8 3.9 3.10 3.11python tests/mypy_test.py stubs/requests* -p 3.11 3.8 3.9 3.10
Also the for loop now correctly skips distributions that should not run. It must loop over distributions_to_check, not venvs
This is part of the work towards python/typeshed#10722 Note that the field is called `python_requires` in `setup.py`. References: - typeshed issue: python/typeshed#10722 - typeshed PR: python/typeshed#10724 - setuptools docs: https://setuptools.pypa.io/en/latest/userguide/dependency_management.html#python-requirement
Oh, shoot, I just caused you merge conflicts with #10714 -- sorry :( I was planning on merging this first and then fixing the conflicts in my PR, but I forgot :( |
hamdanal
commented
Sep 23, 2023
No problem, I fixed them. I removed the |
hamdanal
commented
Sep 23, 2023
@AlexWaygood WDYT about this patch? diff --git a/tests/parse_metadata.py b/tests/parse_metadata.py
index dfb266ad0..9977db339 100644
--- a/tests/parse_metadata.py+++ b/tests/parse_metadata.py@@ -7,7 +7,7 @@ from __future__ import annotations
import os
import re
import urllib.parse
-from collections.abc import Mapping+from collections.abc import Callable, Mapping
from dataclasses import dataclass
from pathlib import Path
from typing import NamedTuple
@@ -18,7 +18,7 @@ from packaging.requirements import Requirement
from packaging.specifiers import Specifier
from packaging.version import Version
-from utils import cache+from utils import PYTHON_VERSION, cache, colored
__all__ = [
"NoSuchStubError",
@@ -129,6 +129,7 @@ class StubMetadata:
Don't construct instances directly; use the `read_metadata` function.
"""
+ name: str
version: str
requires: Annotated[list[str], "The raw requirements as listed in METADATA.toml"]
extra_description: str | None
@@ -141,6 +142,21 @@ class StubMetadata:
stubtest_settings: StubtestSettings
requires_python: Annotated[Specifier, "Versions of Python supported by the stub package"]
+ def skip_test(self, version: str | None = None, printer: Callable[[str], object] = print) -> bool:+ """Return True if the stub should be skipped.++ If version is None, the runtime Python version is used.+ """+ if self.requires_python.contains(version if version is not None else PYTHON_VERSION):+ return False+ msg = f"skipping {self.name!r} "+ if version is not None:+ msg += f"for target Python {version} (requires Python {self.requires_python})"+ else:+ msg += f"(requires Python {self.requires_python}; test is being run using Python {PYTHON_VERSION})"+ printer(colored(msg, "yellow"))+ return True+
_KNOWN_METADATA_FIELDS: Final = frozenset(
{
@@ -277,6 +293,7 @@ def read_metadata(distribution: str) -> StubMetadata:
assert key in tk, f"Unrecognised {tool} key {key!r} for {distribution!r}"
return StubMetadata(
+ name=distribution,
version=version,
requires=requires,
extra_description=extra_description,since we are doing this check in a lot of places. Then we can simply do: ifmetadata.skip_test():
continueto check against runtime Python version or ifmetadata.skip_test(version):
continueto check against target version from the command line |
AlexWaygood
commented
Sep 23, 2023
Hmm, not sure -- I think I prefer it as you currently have it. That patch leads to more shared code, it's true, but it feels strange to me to be printing stuff to the terminal from I wouldn't be opposed to adding a little helper method, though, e.g. classStubMetadata:
defshould_skip_tests(py_version: str) ->bool:
returnself.requires_python.contains(version) |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
hamdanal
commented
Sep 23, 2023
It is strange hence my question :D |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Other than #10724 (comment), this now looks great. Thanks for persevering with this, there was a lot to think through here!
AlexWaygood
commented
Sep 24, 2023
@srittau, did you want to take a quick look, or are you okay with me merging this? |
srittau
commented
Sep 24, 2023
I haven't had time to look at it, but I don't need to. Please merge if you are confident. |
AlexWaygood
commented
Sep 24, 2023
Thanks again @hamdanal! :D |
hamdanal
commented
Sep 24, 2023
Thank you Alex, as always, you've been very helpful :) |
Avasam
commented
Sep 24, 2023
Thanks! My only issue, is that it's not documented in https://github.com/python/typeshed/blob/main/CONTRIBUTING.md#the-metadatatoml-file ! |
AlexWaygood
commented
Sep 24, 2023
A very good point, that I completely missed! |
AlexWaygood
commented
Sep 24, 2023
Added it to the to-do list in #10722 (comment) |
The typeshed part of #10722
This PR implements the following:
requires_pythonfield in the third party stubsstub-uploader still needs to learn about this field and include it in the
setup.pyfile of the corresponding package with a fallback to the minimal version supported by typeshed.