Skip to content

Commit 03cbebd

Browse files
committed
feat: add pine_cast module with type casting utility functions
- Add src/pynecore/core/pine_cast.py with casting functions for Color, Label, Table, Box, Line, LineFill, int, float, bool, and str types, handling NA values appropriately. - Update Series __getitem__ to support float keys by converting them to int before indexing.
1 parent 556a16d commit 03cbebd

2 files changed

Lines changed: 116 additions & 0 deletions

File tree

src/pynecore/core/pine_cast.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
from ..types.na import NA
2+
3+
from ..types.color import Color
4+
from ..types.label import Label
5+
from ..types.table import Table
6+
from ..types.box import Box
7+
from ..types.line import Line
8+
from ..types.linefill import LineFill
9+
10+
11+
def cast_color(x: Color | NA) -> Color | NA[Color]:
12+
"""
13+
Casts `na` to Color
14+
:param x: The value to convert
15+
:return: The casted value
16+
"""
17+
return NA(Color) if isinstance(x, NA) else x
18+
19+
20+
def cast_label(x: Label | NA) -> Label | NA[Label]:
21+
"""
22+
Casts `na` to Label
23+
24+
:param x: The value to convert
25+
:return: The casted value
26+
"""
27+
return NA(Label) if isinstance(x, NA) else x
28+
29+
30+
def cast_table(x: Table | NA) -> Table | NA[Table]:
31+
"""
32+
Casts `na` to Table
33+
34+
:param x: The value to convert
35+
:return: The casted value
36+
"""
37+
return NA(Table) if isinstance(x, NA) else x
38+
39+
40+
def cast_bool(x: bool | int | float | NA) -> bool:
41+
"""
42+
Converts the x value to a bool value
43+
44+
:param x: The value to convert
45+
:return: The casted value
46+
"""
47+
if isinstance(x, NA):
48+
return False
49+
return not not x
50+
51+
52+
def cast_box(x: Box | NA) -> Box | NA[Box]:
53+
"""
54+
Casts `na` to Box
55+
56+
:param x: The value to convert
57+
:return: The casted value
58+
"""
59+
return NA(Box) if isinstance(x, NA) else x
60+
61+
62+
def cast_int(x: int | float | NA) -> int | NA[int]:
63+
"""
64+
Casts na or truncates float value to int
65+
66+
:param x: The value to convert
67+
:return: The casted value
68+
"""
69+
if isinstance(x, NA):
70+
return 0
71+
return int(x)
72+
73+
74+
def cast_line(x: Line | NA) -> Line | NA[Line]:
75+
"""
76+
Casts `na` to Line
77+
78+
:param x: The value to convert
79+
:return: The casted value
80+
"""
81+
return NA(Line) if isinstance(x, NA) else x
82+
83+
84+
def cast_float(x: float | int | NA) -> float | NA[float]:
85+
"""
86+
Casts `na` to float
87+
88+
:param x: The value to convert
89+
:return: The casted value
90+
"""
91+
if isinstance(x, NA):
92+
return NA(float)
93+
return float(x)
94+
95+
96+
def cast_string(x: str | NA) -> str | NA[str]:
97+
"""
98+
Casts `na` to string
99+
100+
:param x: The value to convert
101+
:return: The casted value
102+
"""
103+
return NA(str) if isinstance(x, NA) else x
104+
105+
106+
def cast_linefill(x: LineFill | NA) -> LineFill | NA[LineFill]:
107+
"""
108+
Casts `na` to LineFill
109+
110+
:param x: The value to convert
111+
:return: The casted value
112+
"""
113+
return NA(LineFill) if isinstance(x, NA) else x

src/pynecore/core/series.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ def __getitem__(self, key: int | slice) -> T | NA[T] | ReadOnlySeriesView[T]:
172172
:raises IndexError: If index is out of range or negative
173173
:raises TypeError: If key is not int or slice
174174
"""
175+
if isinstance(key, float):
176+
key = int(key)
177+
175178
if isinstance(key, int):
176179
# Original integer indexing behavior
177180
if key < 0:

0 commit comments

Comments
 (0)