Skip to content

Commit fa1f1c8

Browse files
committed
Fixed the issue with co-variance and __or__
1 parent e56dbac commit fa1f1c8

File tree

1 file changed

+6
-26
lines changed

1 file changed

+6
-26
lines changed

src/parsy/__init__.py

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,11 @@
1515
from .version import __version__ # noqa: F401
1616

1717

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-
2618
OUT = TypeVar("OUT")
2719
OUT1 = TypeVar("OUT1")
2820
OUT2 = TypeVar("OUT2")
21+
OUT_co = TypeVar("OUT_co", covariant=True)
22+
2923

3024
T = TypeVar("T")
3125

@@ -65,10 +59,10 @@ def __str__(self) -> str:
6559

6660

6761
@dataclass
68-
class Result(Generic[OUT]):
62+
class Result(Generic[OUT_co]):
6963
status: bool
7064
index: int
71-
value: OUT
65+
value: OUT_co
7266
furthest: int
7367
expected: FrozenSet[str]
7468

@@ -310,26 +304,12 @@ def __or__(self: Parser[OUT1], other: Parser[OUT2]) -> Parser[Union[OUT1, OUT2]]
310304
def alt_parser(stream: str, index: int) -> Result[Union[OUT1, OUT2]]:
311305
result0 = None
312306

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-
327307
result1 = self(stream, index).aggregate(result0)
328308
if result1.status:
329-
return result1 # type:ignore
309+
return result1
330310

331311
result2 = other(stream, index).aggregate(result1)
332-
return result2 # type:ignore
312+
return result2
333313

334314
return alt_parser
335315

0 commit comments

Comments
 (0)