-
-
Notifications
You must be signed in to change notification settings - Fork 449
Expand file tree
/
Copy pathpython_literal.py
More file actions
53 lines (43 loc) · 1.94 KB
/
Copy pathpython_literal.py
File metadata and controls
53 lines (43 loc) · 1.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
"""Helpers for rendering Python source literals."""
from __future__ import annotations
from math import isfinite, isnan
from typing import Any
from typing_extensions import Self
class PythonCode(str): # noqa: FURB189 - must behave as str for regex consumers.
"""Python expression rendered without extra quoting."""
code: str
__slots__ = ("code",)
def __new__(cls, code: str, value: str | None = None) -> Self:
"""Initialize with a raw Python expression and optional string value."""
obj = super().__new__(cls, code if value is None else value)
obj.code = code
return obj
def __repr__(self) -> str:
"""Render the wrapped expression."""
return self.code
def represent_python_value(value: Any) -> str: # noqa: PLR0911
"""Render a value as a Python expression safe for generated source."""
match value:
case PythonCode():
return value.code
case float() if isnan(value):
return "float('nan')"
case float() if not isfinite(value):
return "float('inf')" if value > 0 else "float('-inf')"
case dict():
rendered_items = ", ".join(
f"{represent_python_value(key)}: {represent_python_value(item)}" for key, item in value.items()
)
return f"{{{rendered_items}}}"
case list():
return "[" + ", ".join(represent_python_value(item) for item in value) + "]"
case tuple():
rendered_items = ", ".join(represent_python_value(item) for item in value)
trailing_comma = "," if len(value) == 1 else ""
return f"({rendered_items}{trailing_comma})"
case set() if not value:
return "set()"
case set():
sorted_items = sorted(value, key=lambda item: (type(item).__name__, repr(item)))
return "{" + ", ".join(represent_python_value(item) for item in sorted_items) + "}"
return repr(value)