Skip to content

Commit

Permalink
Add regression tests for builtins.pow and object.__reduce__ (#7663)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexWaygood committed Apr 22, 2022
1 parent 66383ee commit 2773480
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 2 deletions.
3 changes: 2 additions & 1 deletion pyrightconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"typeshedPath": ".",
"include": [
"stdlib",
"stubs"
"stubs",
"test_cases"
],
"exclude": [
"**/@python2"
Expand Down
3 changes: 2 additions & 1 deletion pyrightconfig.stricter.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"typeshedPath": ".",
"include": [
"stdlib",
"stubs"
"stubs",
"test_cases"
],
"exclude": [
"**/@python2",
Expand Down
24 changes: 24 additions & 0 deletions test_cases/README.md
Original file line number Diff line number Diff line change
@@ -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.
11 changes: 11 additions & 0 deletions test_cases/stdlib/builtins/test_object.py
Original file line number Diff line number Diff line change
@@ -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
40 changes: 40 additions & 0 deletions test_cases/stdlib/builtins/test_pow.py
Original file line number Diff line number Diff line change
@@ -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)

0 comments on commit 2773480

Please sign in to comment.