@@ -37,6 +37,7 @@ def __init__(
3737 collect_required : bool = False , # property of tree, not node
3838 one_constant_required : bool = False , # property of tree, not node
3939 inputs : Optional [List ] = None ,
40+ lit_value = None ,
4041 ) -> None :
4142 """
4243 Carry a Polars expression term (polars_term) plus annotations.
@@ -46,13 +47,17 @@ def __init__(
4647 :param is_column: True if term is a column name
4748 :param collect_required: True if Polars frame collection required by this node or an input node
4849 :param one_constant_required: True one constant required by this node or an input node
50+ :param lit_value: original value for a literal
4951 :param inputs: inputs to expression node
5052 """
5153 assert isinstance (is_literal , bool )
5254 assert isinstance (is_column , bool )
5355 assert isinstance (collect_required , bool )
5456 assert isinstance (one_constant_required , bool )
5557 assert (is_literal + is_column + (inputs is not None ) + (polars_term is None )) == 1
58+ if lit_value is not None :
59+ assert is_literal
60+ self .lit_value = lit_value
5661 self .polars_term = polars_term
5762 self .is_literal = is_literal
5863 self .collect_required = collect_required
@@ -210,9 +215,9 @@ def _populate_expr_impl_map() -> Dict[int, Dict[str, Callable]]:
210215 # datetime parsing from https://stackoverflow.com/a/71759536/6901725
211216 # TODO: figure out why format is wrong type
212217 # TODO: wire up format
213- "parse_date" : lambda x , format : x .cast (str ).str .strptime (pl .Date , fmt = "%Y-%m-%d" , strict = False ).cast (pl .Date ),
218+ "parse_date" : lambda x , format : x .cast (str ).str .strptime (pl .Date , fmt = format , strict = False ).cast (pl .Date ),
214219 # TODO: wire up format
215- "parse_datetime" : lambda x , format : x .cast (str ).str .strptime (pl .Datetime , strict = False ).cast (pl .Datetime ),
220+ "parse_datetime" : lambda x , format : x .cast (str ).str .strptime (pl .Datetime , fmt = format , strict = False ).cast (pl .Datetime ),
216221 }
217222 impl_map_3 = {
218223 "if_else" : lambda a , b , c : pl .when (a ).then (b ).otherwise (c ),
@@ -265,6 +270,7 @@ def __init__(self, *, use_lazy_eval: bool = True):
265270 "TableDescription" : self ._table_step ,
266271 }
267272 self ._expr_impl_map = _populate_expr_impl_map ()
273+ self ._want_literals_unpacked = {"parse_date" , "parse_datetime" }
268274 self ._collect_required = set ()
269275
270276 def data_frame (self , arg = None ):
@@ -651,7 +657,7 @@ def act_on_literal(self, *, value):
651657 :return: converted result
652658 """
653659 assert not isinstance (value , PolarsTerm )
654- return PolarsTerm (polars_term = pl .lit (value ), is_literal = True )
660+ return PolarsTerm (polars_term = pl .lit (value ), is_literal = True , lit_value = value )
655661
656662 def act_on_column_name (self , * , arg , value ):
657663 """
@@ -679,7 +685,9 @@ def act_on_expression(self, *, arg, values: List, op):
679685 assert isinstance (v , PolarsTerm )
680686 f = self ._expr_impl_map [len (values )][op .op ]
681687 assert f is not None
682- res = f (* [v .polars_term for v in values ])
688+ want_literals_unpacked = op .op in self ._want_literals_unpacked
689+ args = [v .lit_value if (want_literals_unpacked and v .is_literal ) else v .polars_term for v in values ]
690+ res = f (* args )
683691 return PolarsTerm (
684692 polars_term = res ,
685693 inputs = values ,
0 commit comments