|
15 | 15 | from .version import __version__ # noqa: F401 |
16 | 16 |
|
17 | 17 |
|
18 | | -# Covariance/contravariance: |
19 | | - |
20 | | -# Parser[str] is a subtype of Parser[Union[str, int]] |
21 | | -# Result[str] is a subtype of Result[Union[str, int]] |
22 | | -# So we want covariance for these. |
23 | | - |
24 | | -# However, that gives me problems with any methods that use these type vars. |
25 | | - |
26 | 18 | OUT = TypeVar("OUT") |
27 | 19 | OUT1 = TypeVar("OUT1") |
28 | 20 | OUT2 = TypeVar("OUT2") |
| 21 | +OUT_co = TypeVar("OUT_co", covariant=True) |
| 22 | + |
29 | 23 |
|
30 | 24 | T = TypeVar("T") |
31 | 25 |
|
@@ -65,10 +59,10 @@ def __str__(self) -> str: |
65 | 59 |
|
66 | 60 |
|
67 | 61 | @dataclass |
68 | | -class Result(Generic[OUT]): |
| 62 | +class Result(Generic[OUT_co]): |
69 | 63 | status: bool |
70 | 64 | index: int |
71 | | - value: OUT |
| 65 | + value: OUT_co |
72 | 66 | furthest: int |
73 | 67 | expected: FrozenSet[str] |
74 | 68 |
|
@@ -310,26 +304,12 @@ def __or__(self: Parser[OUT1], other: Parser[OUT2]) -> Parser[Union[OUT1, OUT2]] |
310 | 304 | def alt_parser(stream: str, index: int) -> Result[Union[OUT1, OUT2]]: |
311 | 305 | result0 = None |
312 | 306 |
|
313 | | - # mypy + pyright complain here e.g. |
314 | | - # Expression of type "Result[OUT1@__or__]" cannot be assigned to return type |
315 | | - # "Result[OUT1@__or__ | OUT2@__or__]" |
316 | | - # |
317 | | - # I think it should be enough to say that Result is covariant in its OUT parameter. |
318 | | - # However, doing that results in a bunch of new errors on other methods: |
319 | | - # "covariant type variable cannot be used in parameter type" |
320 | | - |
321 | | - # I think this is due to worrying about immutability, which isn't a worry for us. |
322 | | - # So we just force it here for now using type:ignore, to keep the number of error |
323 | | - # message down. |
324 | | - |
325 | | - # We have the same issue in __and__ below |
326 | | - |
327 | 307 | result1 = self(stream, index).aggregate(result0) |
328 | 308 | if result1.status: |
329 | | - return result1 # type:ignore |
| 309 | + return result1 |
330 | 310 |
|
331 | 311 | result2 = other(stream, index).aggregate(result1) |
332 | | - return result2 # type:ignore |
| 312 | + return result2 |
333 | 313 |
|
334 | 314 | return alt_parser |
335 | 315 |
|
|
0 commit comments