Skip to content

Commit b116772

Browse files
committed
chore: finish
1 parent 8f113e3 commit b116772

File tree

6 files changed

+151
-60
lines changed

6 files changed

+151
-60
lines changed

challenges/advance-descriptor-basic/question.py

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,18 @@ class Descriptor:
99
...
1010

1111

12-
def should_pass():
13-
class TestClass:
14-
a = Descriptor()
15-
16-
def descriptor_self(x: Descriptor) -> None:
17-
...
18-
19-
def string_value(x: str) -> None:
20-
...
21-
22-
descriptor_self(TestClass.a)
23-
string_value(TestClass().a)
24-
12+
## End of your code ##
13+
class TestClass:
14+
a = Descriptor()
2515

26-
def should_fail():
27-
class TestClass:
28-
a = Descriptor()
29-
30-
def descriptor_self(x: Descriptor) -> None:
31-
...
16+
def descriptor_self(x: Descriptor) -> None:
17+
...
3218

33-
def string_value(x: str) -> None:
34-
...
19+
def string_value(x: str) -> None:
20+
...
3521

36-
descriptor_self(TestClass().a)
37-
string_value(TestClass.a)
22+
descriptor_self(TestClass.a)
23+
string_value(TestClass().a)
3824

25+
descriptor_self(TestClass().a) # expect-type-error
26+
string_value(TestClass.a) # expect-type-error
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"""
2+
TODO:
3+
4+
Define a descriptor, make test case works.
5+
"""
6+
7+
from typing import overload, Self, Any
8+
9+
class Descriptor:
10+
@overload
11+
def __get__(self, instance: None, owner: type) -> Self:
12+
...
13+
14+
@overload
15+
def __get__(self, instance: Any, owner: type) -> str:
16+
...
17+
18+
def __get__(self, instance: Any, owner: type) -> Self | str:
19+
if instance is None:
20+
return self
21+
22+
return ""
23+
24+
25+
## End of your code ##
26+
class TestClass:
27+
a = Descriptor()
28+
29+
def descriptor_self(x: Descriptor) -> None:
30+
...
31+
32+
def string_value(x: str) -> None:
33+
...
34+
35+
descriptor_self(TestClass.a)
36+
string_value(TestClass().a)
37+
38+
descriptor_self(TestClass().a) # expect-type-error
39+
string_value(TestClass.a) # expect-type-error

challenges/advance-my-method/question.py

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,18 @@ def __get__(self, instance, owner) -> None:
1717
return
1818

1919

20+
## End of your code ##
21+
class Foo:
22+
@MyMethod
23+
def do_something(self, value: int) -> None:
24+
...
2025

21-
def should_pass():
22-
class Foo:
23-
@MyMethod
24-
def do_something(self, value: int) -> None:
25-
...
26+
foo = Foo()
2627

27-
foo = Foo()
28+
Foo.do_something(foo, 1111)
29+
foo.do_something(1111)
2830

29-
Foo.do_something(foo, 1111)
30-
foo.do_something(1111)
3131

32-
33-
def should_fail():
34-
class Foo:
35-
@MyMethod
36-
def do_something(self, value: int) -> None:
37-
...
38-
39-
foo = Foo()
40-
41-
Foo.do_something(1111)
42-
foo.do_something(11111, foo)
43-
foo.do_something(foo, 11111)
32+
Foo.do_something(1111) # expect-type-error
33+
foo.do_something(11111, foo) # expect-type-error
34+
foo.do_something(foo, 11111) # expect-type-error
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
"""
2+
TODO:
3+
4+
a method-like descriptor, implements the `__get__` only.
5+
"""
6+
from typing import Any, ParamSpec, TypeVar, Concatenate, Callable, Generic, overload
7+
8+
P = ParamSpec("P")
9+
T = TypeVar("T")
10+
R = TypeVar("R")
11+
12+
class MyMethod(Generic[T, P, R]):
13+
def __init__(self, func: Callable[Concatenate[T, P], R]) -> None:
14+
self.func = func
15+
16+
@overload
17+
def __get__(self, instance: None, owner: type) -> Callable[Concatenate[T, P], R]:
18+
...
19+
20+
@overload
21+
def __get__(self, instance: Any, owner: type) -> Callable[P, R]:
22+
...
23+
24+
def __get__(self, instance: Any | None, owner: type):
25+
if instance is None:
26+
return self.func
27+
28+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
29+
return self.func(instance, *args, **kwargs)
30+
31+
return wrapper
32+
33+
34+
## End of your code ##
35+
class Foo:
36+
@MyMethod
37+
def do_something(self, value: int) -> None:
38+
...
39+
40+
foo = Foo()
41+
42+
Foo.do_something(foo, 1111)
43+
foo.do_something(1111)
44+
45+
46+
Foo.do_something(1111) # expect-type-error
47+
foo.do_something(11111, foo) # expect-type-error
48+
foo.do_something(foo, 11111) # expect-type-error

challenges/extreme-self-casting/question.py

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,16 @@ def __init__(self, f: VnCallable) -> None:
1616
def into_callable(self) -> None:
1717
...
1818

19+
## End of your code ##
20+
@Fn
21+
def example(a: int, b: str, c: float, *, d: bool = False) -> None:
22+
return
1923

20-
def should_pass():
21-
@Fn
22-
def example(a: int, b: str, c: float, *, d: bool = False) -> None:
23-
return
2424

25-
assert_type(example.f(1, "1", 1., d=False), None)
25+
assert_type(example.f(1, "1", 1., d=False), None)
2626

27-
a: Any = 11111111
27+
a: Any = 11111111
28+
b = example.into_callable()(a, 1, "1", 1., d=False)
29+
assert_type(b, None)
2830

29-
b = example.into_callable()(a, 1, "1", 1., d=False)
30-
31-
assert_type(b, None)
32-
33-
34-
def should_fail():
35-
@Fn
36-
def example(a: int, b: str, c: float, *, d: bool = False) -> None:
37-
...
38-
39-
example.into_callable()(1, "1", 1., d=False)
31+
example.into_callable()(1, "1", 1., d=False) # expect-type-error
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""
2+
TODO:
3+
4+
make Fn[VnCallable] could be casted to a Callable with a Any value.
5+
you MUST NOT modify anything expect the `Fn.into_callable`'s annotation.
6+
"""
7+
8+
from typing import Callable, Concatenate, ParamSpec, TypeVar, Generic, Any, assert_type
9+
10+
P = ParamSpec("P")
11+
R = TypeVar("R", covariant=True)
12+
VnCallable = TypeVar("VnCallable", bound=Callable)
13+
14+
class Fn(Generic[VnCallable]):
15+
def __init__(self, f: VnCallable) -> None:
16+
self.f = f
17+
18+
def into_callable(self: 'Fn[Callable[P, R]]') -> Callable[Concatenate[Any, P], R]:
19+
...
20+
21+
## End of your code ##
22+
@Fn
23+
def example(a: int, b: str, c: float, *, d: bool = False) -> None:
24+
return
25+
26+
27+
assert_type(example.f(1, "1", 1., d=False), None)
28+
29+
a: Any = 11111111
30+
b = example.into_callable()(a, 1, "1", 1., d=False)
31+
assert_type(b, None)
32+
33+
example.into_callable()(1, "1", 1., d=False) # expect-type-error

0 commit comments

Comments
 (0)