Skip to content

Commit 68a2c89

Browse files
authored
Add three new challenges (laike9m#12)
1 parent 147ed14 commit 68a2c89

File tree

6 files changed

+208
-0
lines changed

6 files changed

+208
-0
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""
2+
TODO:
3+
4+
foo is a function that returns an interger when called with Foo[int], returns a string when called with Foo[str], otherwise returns a Foo[T].
5+
"""
6+
from typing import TypeVar, Generic
7+
8+
T = TypeVar('T')
9+
10+
class Foo(Generic[T]):
11+
a: T
12+
13+
def foo(value: Foo):
14+
...
15+
16+
17+
def should_pass():
18+
foo(Foo[int]()).bit_length()
19+
foo(Foo[str]()).upper()
20+
foo(Foo[list]()).a.append(1)
21+
22+
23+
def should_fail():
24+
foo(Foo[int]()).upper()
25+
foo(Foo[str]()).bit_length()
26+
foo(Foo[list]()).bit_length()
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""
2+
TODO:
3+
4+
foo is a function that returns an interger when called with Foo[int], returns a string when called with Foo[str], otherwise returns a Foo[T].
5+
"""
6+
from typing import Any, TypeVar, Generic, overload
7+
8+
T = TypeVar('T')
9+
10+
class Foo(Generic[T]):
11+
a: T
12+
13+
@overload
14+
def foo(value: Foo[int]) -> int:
15+
...
16+
17+
@overload
18+
def foo(value: Foo[str]) -> str:
19+
...
20+
21+
@overload
22+
def foo(value: Foo[T]) -> Foo[T]:
23+
...
24+
25+
def foo(value: Foo) -> Any:
26+
...
27+
28+
29+
def should_pass():
30+
foo(Foo[int]()).bit_length()
31+
foo(Foo[str]()).upper()
32+
foo(Foo[list]()).a.append(1)
33+
34+
35+
def should_fail():
36+
foo(Foo[int]()).upper()
37+
foo(Foo[str]()).bit_length()
38+
foo(Foo[list]()).bit_length()
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""
2+
TODO:
3+
4+
foo is a function that returns an interger when second argument is 1, returns a string when second argument is 2, returns a list when second argument is 3, otherwise it returns inputs self.
5+
"""
6+
7+
8+
def foo(value, flag):
9+
...
10+
11+
12+
def should_pass():
13+
foo("42", 1).bit_length()
14+
foo(42, 2).upper()
15+
foo(True, 3).append(1)
16+
foo({}, "4").keys()
17+
18+
19+
def should_fail():
20+
foo("42", 1).upper()
21+
foo(42, 2).append(1)
22+
foo(True, 3).bit_length()
23+
foo({}, "4").upper()
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""
2+
TODO:
3+
4+
foo is a function that returns an interger when second argument is 1, returns a string when second argument is 2, returns a list when second argument is 3, otherwise it returns inputs self.
5+
"""
6+
from typing import Any, Literal, overload, TypeVar
7+
8+
T = TypeVar('T')
9+
10+
@overload
11+
def foo(value: Any, flag: Literal[1]) -> int:
12+
...
13+
14+
@overload
15+
def foo(value: Any, flag: Literal[2]) -> str:
16+
...
17+
18+
@overload
19+
def foo(value: Any, flag: Literal[3]) -> list:
20+
...
21+
22+
@overload
23+
def foo(value: T, flag: Any) -> T:
24+
...
25+
26+
27+
def foo(value, flag) -> Any:
28+
...
29+
30+
31+
def should_pass():
32+
foo("42", 1).bit_length()
33+
foo(42, 2).upper()
34+
foo(True, 3).append(1)
35+
foo({}, "4").keys()
36+
37+
38+
def should_fail():
39+
foo("42", 1).upper()
40+
foo(42, 2).append(1)
41+
foo(True, 3).bit_length()
42+
foo({}, "4").upper()
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""
2+
TODO:
3+
4+
Define a decorator `constructor_parameter` that accepts the type of Foo.
5+
and return a wrapper function with the same signature as the constructor of Foo,
6+
and function decorated by `constructor_parameter` can be called with an instance of Foo.
7+
"""
8+
9+
class Foo:
10+
a: int
11+
b: str
12+
13+
def __init__(self, a: int, b: str) -> None:
14+
...
15+
16+
def constructor_parameter():
17+
...
18+
19+
20+
def should_pass():
21+
@constructor_parameter(Foo)
22+
def func(foo: Foo) -> list[Foo]:
23+
...
24+
25+
res = func(1, "2")
26+
res[0].a.bit_length()
27+
res[0].b.upper()
28+
29+
30+
def should_fail():
31+
@constructor_parameter(Foo)
32+
def func(foo: Foo) -> list:
33+
...
34+
35+
func("1", "2")
36+
func([1, 2, 3])
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"""
2+
TODO:
3+
4+
Define a decorator `constructor_parameter` that accepts the type of Foo.
5+
and return a wrapper function with the same signature as the constructor of Foo,
6+
and function decorated by `constructor_parameter` can be called with an instance of Foo.
7+
"""
8+
from typing import TypeVar, Callable
9+
from typing_extensions import ParamSpec, Concatenate
10+
11+
class Foo:
12+
a: int
13+
b: str
14+
15+
def __init__(self, a: int, b: str) -> None:
16+
...
17+
18+
T = TypeVar('T')
19+
P = ParamSpec('P')
20+
R = TypeVar('R')
21+
22+
23+
def constructor_parameter(cls: Callable[P, T]) -> Callable[[Callable[[T], R]], Callable[P, R]]:
24+
...
25+
26+
27+
def should_pass():
28+
@constructor_parameter(Foo)
29+
def func(foo: Foo) -> list[Foo]:
30+
...
31+
32+
res = func(1, "2")
33+
res[0].a.bit_length()
34+
res[0].b.upper()
35+
36+
37+
def should_fail():
38+
@constructor_parameter(Foo)
39+
def func(foo: Foo) -> list:
40+
...
41+
42+
func("1", "2")
43+
func([1, 2, 3])

0 commit comments

Comments
 (0)