Add regression tests for builtins.pow and object.__reduce__ (#7663)

This commit is contained in:
Alex Waygood
2022-04-22 05:17:37 +01:00
committed by GitHub
parent 66383ee8e3
commit 2773480d13
5 changed files with 79 additions and 2 deletions

View File

@@ -2,7 +2,8 @@
"typeshedPath": ".",
"include": [
"stdlib",
"stubs"
"stubs",
"test_cases"
],
"exclude": [
"**/@python2"

View File

@@ -3,7 +3,8 @@
"typeshedPath": ".",
"include": [
"stdlib",
"stubs"
"stubs",
"test_cases"
],
"exclude": [
"**/@python2",

24
test_cases/README.md Normal file
View File

@@ -0,0 +1,24 @@
## Regression tests for typeshed
This directory contains regression tests for the stubs found elsewhere in the
typeshed repo. Each file contains a number of test cases, all of which should
pass a type checker without error.
**This directory should *only* contain tests for functions and classes which
are known to have caused problems in the past, where the stubs are difficult to
get right.** 100% test coverage for typeshed is neither necessary nor
desirable, as it would lead to code duplication. Moreover, typeshed has
multiple other mechanisms for spotting errors in the stubs.
Unlike the rest of typeshed, this directory largely contains `.py` files. This
is because the purpose of this folder is to test the implications of typeshed
changes for end users.
Another difference to the rest of typeshed is that the test cases in this
directory cannot always use modern syntax for type hints. For example, PEP 604
syntax (unions with a pipe `|` operator) is new in Python 3.10. While this
syntax can be used on older Python versions in a `.pyi` file, code using this
syntax will fail at runtime on Python <=3.9. Since the test cases all use `.py`
extensions, and since the tests need to pass on all Python versions >=3.6, PEP
604 syntax cannot be used in a test case. Use `typing.Union` and
`typing.Optional` instead.

View File

@@ -0,0 +1,11 @@
from typing import Any, Tuple, Union
# The following should pass without error (see #6661):
class Diagnostic:
def __reduce__(self) -> Union[str, Tuple[Any, ...]]:
res = super().__reduce__()
if isinstance(res, tuple) and len(res) >= 3:
res[2]["_info"] = 42
return res

View File

@@ -0,0 +1,40 @@
from decimal import Decimal
from fractions import Fraction
from typing import Any, NoReturn
from typing_extensions import Literal, assert_type
assert_type(pow(1, 0), Literal[1]) # See #7163
assert_type(pow(1, 0, None), Literal[1]) # See #7163
assert_type(pow(2, 4, 0), NoReturn)
assert_type(pow(2, 4), int)
assert_type(pow(4, 6, None), int)
assert_type(pow(5, -7), float)
assert_type(pow(2, 4, 5), int) # pow(<smallint>, <smallint>, <smallint>)
assert_type(pow(2, 35, 3), int) # pow(<smallint>, <bigint>, <smallint>)
assert_type(pow(4.6, 8), float)
assert_type(pow(5.1, 4, None), float)
assert_type(pow(complex(6), 6.2), complex)
assert_type(pow(complex(9), 7.3, None), complex)
assert_type(pow(Fraction(), 4, None), Fraction)
assert_type(pow(Fraction(3, 7), complex(1, 8)), complex)
assert_type(pow(complex(4, -8), Fraction(2, 3)), complex)
assert_type(pow(Decimal("1.0"), Decimal("1.6")), Decimal)
assert_type(pow(Decimal("1.0"), Decimal("1.0"), Decimal("1.0")), Decimal)
assert_type(pow(Decimal("4.6"), 7, None), Decimal)
# These would ideally be more precise, but `Any` is acceptable
# They have to be `Any` due to the fact that type-checkers can't distinguish between positive and negative numbers for the second argument to `pow()`
#
# int for positive 2nd-arg, float otherwise
assert_type(pow(4, 65), Any)
assert_type(pow(2, -45), Any)
assert_type(pow(3, 57, None), Any)
# pow(<pos-float>, <pos-or-neg-float>) -> float
# pow(<neg-float>, <pos-or-neg-float>) -> complex
assert_type(pow(4.7, 7.4), Any)
assert_type(pow(-9.8, 8.3), Any)
assert_type(pow(-9.3, -88.2), Any)
assert_type(pow(8.2, -9.8), Any)
assert_type(pow(4.7, 9.2, None), Any)
# See #7046 -- float for a positive 1st arg, complex otherwise
assert_type((-2) ** 0.5, Any)