Skip to content

Commit 664648b

Browse files
pradeep90facebook-github-bot
authored andcommitted
Edit errors.md using inpage editor
Summary: This diff has been automatically generated by the inpage editor. If you want to update this diff, go through the preview link that would be attached to the test plan. Reviewed By: dkgi Differential Revision: D30354087 fbshipit-source-id: f4f01df4eee6075b7233de21882b4a6051993f13
1 parent 8376c96 commit 664648b

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

documentation/website/docs/errors.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,42 @@ def zeroes(number_of_elements: int) -> List[float]:
7070
return a # Type checks!
7171
```
7272

73+
#### Contravariance
74+
75+
`Callable`, on the other hand, is [contravariant](https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Contravariant_method_parameter_type) in its parameter types. This means that, when checking if `Callable[[A], None]` is compatible with `Callable[[B], None]`, we check if `B` is compatible with `A`, not the other way around. This is because the former should be capable of accepting any arguments accepted by the latter.
76+
77+
For example, a function of type `Callable[[Base], int]` may be given an argument of type `Child2`. But if we passed in a function of type `Callable[[Child1], int]`, this could fail at runtime:
78+
79+
```python
80+
class Base: pass
81+
82+
class Child1(Base):
83+
size: int = 42
84+
85+
# No size field.
86+
class Child2(Base): pass
87+
88+
def print_child2_size(get_size: Callable[[Base], int]) -> None:
89+
child2 = Child2()
90+
size = get_size(child2)
91+
print(size)
92+
93+
def size_of_child1(child1: Child1) -> int:
94+
return child1.size
95+
96+
print_child2_size(size_of_child1) # BAD!
97+
98+
# At runtime:
99+
# AttributeError: 'Child2' object has no attribute 'size'
100+
```
101+
102+
To prevent such errors, Pyre raises a type error when violating contravariance:
103+
104+
```
105+
$ pyre
106+
Incompatible parameter type [6]: Expected `typing.Callable[[Base], int]` for 1st positional only parameter to call `print_child2_size` but got `typing.Callable(size_of_child1)[[Named(child1, Child1)], int]`.
107+
```
108+
73109
### Optional Attributes
74110
A common pattern in Python is to check whether an attribute is `None` before accessing its value. E.g.
75111

0 commit comments

Comments
 (0)