Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modernize representation of types #823

Merged
merged 1 commit into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 17 additions & 14 deletions pyanalyze/test_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ def test_subclass_value() -> None:
assert_can_assign(val, TypedValue(type))
assert_cannot_assign(val, SubclassValue(TypedValue(str)))
val = SubclassValue(TypedValue(str))
assert "Type[str]" == str(val)
assert str(val) == "type[str]"
assert TypedValue(str) == val.typ
assert val.is_type(str)
assert not val.is_type(int)
Expand Down Expand Up @@ -288,7 +288,7 @@ def test_multi_valued_value() -> None:
[TypedValue(int), KnownValue(None), TypedValue(str)]
) == val | TypedValue(str)

assert "Optional[int]" == str(val)
assert str(val) == "int | None"
assert_can_assign(val, KnownValue(1))
assert_can_assign(val, KnownValue(None))
assert_cannot_assign(val, KnownValue(""))
Expand All @@ -299,20 +299,23 @@ def test_multi_valued_value() -> None:
val, AnyValue(AnySource.marker) | TypedValue(int) | KnownValue(None)
)

assert "Literal[1, 2]" == str(KnownValue(1) | KnownValue(2))
assert "Literal[1, 2, None]" == str(
KnownValue(1) | KnownValue(2) | KnownValue(None)
assert str(KnownValue(1) | KnownValue(2)) == "Literal[1, 2]"
assert (
str(KnownValue(1) | KnownValue(2) | KnownValue(None)) == "Literal[1, 2, None]"
)
assert "Union[int, str]" == str(TypedValue(int) | TypedValue(str))
assert "Union[int, str, None]" == str(
TypedValue(int) | TypedValue(str) | KnownValue(None)
assert str(TypedValue(int) | TypedValue(str)) == "int | str"
assert (
str(TypedValue(int) | TypedValue(str) | KnownValue(None)) == "int | str | None"
)
assert "Union[int, str, Literal[1, 2], None]" == str(
TypedValue(int)
| TypedValue(str)
| KnownValue(None)
| KnownValue(1)
| KnownValue(2)
assert (
str(
TypedValue(int)
| TypedValue(str)
| KnownValue(None)
| KnownValue(1)
| KnownValue(2)
)
== "int | str | Literal[1, 2] | None"
)


Expand Down
10 changes: 4 additions & 6 deletions pyanalyze/value.py
Original file line number Diff line number Diff line change
Expand Up @@ -1923,7 +1923,7 @@ def get_type_value(self) -> Value:
return AnyValue(AnySource.inference)

def __str__(self) -> str:
return f"Type[{self.typ}]"
return f"type[{self.typ}]"

@classmethod
def make(cls, origin: Value, *, exactly: bool = False) -> Value:
Expand Down Expand Up @@ -2087,15 +2087,13 @@ def __str__(self) -> str:
body = ", ".join(repr(val.val) for val in literals)
return f"Literal[{body}]"
else:
if not literals and has_none and len(others) == 1:
return f"Optional[{others[0]}]"
elements = [str(val) for val in others]
if literals:
body = ", ".join(repr(val.val) for val in literals)
elements.append(f"Literal[{body}]")
if has_none:
elements.append("None")
return f"Union[{', '.join(elements)}]"
return " | ".join(elements)

def walk_values(self) -> Iterable["Value"]:
yield self
Expand Down Expand Up @@ -2233,10 +2231,10 @@ def get_type_value(self) -> Value:

def __str__(self) -> str:
if self.bound is not None:
return f"{self.typevar} <: {self.bound}"
return f"{self.typevar}: {self.bound}"
elif self.constraints:
constraints = ", ".join(map(str, self.constraints))
return f"{self.typevar} in ({constraints})"
return f"{self.typevar}: ({constraints})"
return str(self.typevar)


Expand Down
Loading