2525from typing import (
2626 TYPE_CHECKING ,
2727 Any ,
28+ Callable ,
2829 Generic ,
2930 Sequence ,
3031 TypeVar ,
@@ -569,7 +570,7 @@ def logical_maximum(self, *others: Expression | CONSTANT_TYPE) -> "Expression":
569570 return FunctionExpression (
570571 "maximum" ,
571572 [self ] + [self ._cast_to_expr_or_convert_to_constant (o ) for o in others ],
572- infix_name_override = "logical_maximum" ,
573+ repr_function = FunctionExpression . _build_infix_repr ( "logical_maximum" ) ,
573574 )
574575
575576 @expose_as_static
@@ -595,7 +596,7 @@ def logical_minimum(self, *others: Expression | CONSTANT_TYPE) -> "Expression":
595596 return FunctionExpression (
596597 "minimum" ,
597598 [self ] + [self ._cast_to_expr_or_convert_to_constant (o ) for o in others ],
598- infix_name_override = "logical_minimum" ,
599+ repr_function = FunctionExpression . _build_infix_repr ( "logical_minimum" ) ,
599600 )
600601
601602 @expose_as_static
@@ -955,7 +956,10 @@ def array_filter(
955956 args .append (self ._cast_to_expr_or_convert_to_constant (index_alias ))
956957 args .append (filter_expr )
957958
958- return FunctionExpression ("array_filter" , args )
959+ repr_func = (
960+ lambda expr : f"{ expr .params [0 ]!r} .{ expr .name } ({ expr .params [- 1 ]!r} , { expr .params [1 ]!r} { ', ' + repr (expr .params [2 ]) if len (expr .params ) == 4 else '' } )"
961+ )
962+ return FunctionExpression ("array_filter" , args , repr_function = repr_func )
959963
960964 @expose_as_static
961965 def array_transform (
@@ -987,7 +991,10 @@ def array_transform(
987991 args .append (self ._cast_to_expr_or_convert_to_constant (index_alias ))
988992 args .append (transform_expr )
989993
990- return FunctionExpression ("array_transform" , args )
994+ repr_func = (
995+ lambda expr : f"{ expr .params [0 ]!r} .{ expr .name } ({ expr .params [- 1 ]!r} , { expr .params [1 ]!r} { ', ' + repr (expr .params [2 ]) if len (expr .params ) == 4 else '' } )"
996+ )
997+ return FunctionExpression ("array_transform" , args , repr_function = repr_func )
991998
992999 @expose_as_static
9931000 def array_concat (
@@ -2154,7 +2161,9 @@ def array_maximum(self) -> "Expression":
21542161 A new `Expression` representing the maximum element of the array.
21552162 """
21562163 return FunctionExpression (
2157- "maximum" , [self ], infix_name_override = "array_maximum"
2164+ "maximum" ,
2165+ [self ],
2166+ repr_function = FunctionExpression ._build_infix_repr ("array_maximum" ),
21582167 )
21592168
21602169 @expose_as_static
@@ -2169,7 +2178,9 @@ def array_minimum(self) -> "Expression":
21692178 A new `Expression` representing the minimum element of the array.
21702179 """
21712180 return FunctionExpression (
2172- "minimum" , [self ], infix_name_override = "array_minimum"
2181+ "minimum" ,
2182+ [self ],
2183+ repr_function = FunctionExpression ._build_infix_repr ("array_minimum" ),
21732184 )
21742185
21752186 @expose_as_static
@@ -2191,7 +2202,7 @@ def array_maximum_n(self, n: int | "Expression") -> "Expression":
21912202 return FunctionExpression (
21922203 "maximum_n" ,
21932204 [self , self ._cast_to_expr_or_convert_to_constant (n )],
2194- infix_name_override = "array_maximum_n" ,
2205+ repr_function = FunctionExpression . _build_infix_repr ( "array_maximum_n" ) ,
21952206 )
21962207
21972208 @expose_as_static
@@ -2213,7 +2224,7 @@ def array_minimum_n(self, n: int | "Expression") -> "Expression":
22132224 return FunctionExpression (
22142225 "minimum_n" ,
22152226 [self , self ._cast_to_expr_or_convert_to_constant (n )],
2216- infix_name_override = "array_minimum_n" ,
2227+ repr_function = FunctionExpression . _build_infix_repr ( "array_minimum_n" ) ,
22172228 )
22182229
22192230 @expose_as_static
@@ -2683,36 +2694,66 @@ def __init__(
26832694 name : str ,
26842695 params : Sequence [Expression ],
26852696 * ,
2686- use_infix_repr : bool = True ,
2687- infix_name_override : str | None = None ,
2697+ repr_function : Callable [["FunctionExpression" ], str ] | None = None ,
26882698 ):
26892699 self .name = name
26902700 self .params = list (params )
2691- self ._use_infix_repr = use_infix_repr
2692- self ._infix_name_override = infix_name_override
2701+ self ._repr_function = repr_function or self ._build_infix_repr ()
26932702
26942703 def __repr__ (self ):
26952704 """
26962705 Most FunctionExpressions can be triggered infix. Eg: Field.of('age').greater_than(18).
26972706
26982707 Display them this way in the repr string where possible
26992708 """
2700- if self ._use_infix_repr :
2701- infix_name = self ._infix_name_override or self .name
2702- if len (self .params ) == 1 :
2703- return f"{ self .params [0 ]!r} .{ infix_name } ()"
2704- elif len (self .params ) == 2 :
2705- return f"{ self .params [0 ]!r} .{ infix_name } ({ self .params [1 ]!r} )"
2706- else :
2707- return f"{ self .params [0 ]!r} .{ infix_name } ({ ', ' .join ([repr (p ) for p in self .params [1 :]])} )"
2708- return f"{ self .__class__ .__name__ } ({ ', ' .join ([repr (p ) for p in self .params ])} )"
2709+ return self ._repr_function (self )
27092710
27102711 def __eq__ (self , other ):
27112712 if not isinstance (other , FunctionExpression ):
27122713 return False
27132714 else :
27142715 return other .name == self .name and other .params == self .params
27152716
2717+ @staticmethod
2718+ def _build_infix_repr (
2719+ name_override : str | None = None ,
2720+ ) -> Callable [["FunctionExpression" ], str ]:
2721+ """Creates a repr_function that displays a FunctionExpression using infix notation.
2722+
2723+ Example:
2724+ `value.greater_than(18)`
2725+ """
2726+
2727+ def build_repr (expr ):
2728+ final_name = name_override or expr .name
2729+ args = expr .params
2730+ if len (args ) == 0 :
2731+ return f"{ final_name } ()"
2732+ elif len (args ) == 1 :
2733+ return f"{ args [0 ]!r} .{ final_name } ()"
2734+ elif len (args ) == 2 :
2735+ return f"{ args [0 ]!r} .{ final_name } ({ args [1 ]!r} )"
2736+ else :
2737+ return f"{ args [0 ]!r} .{ final_name } ({ ', ' .join ([repr (a ) for a in args [1 :]])} )"
2738+
2739+ return build_repr
2740+
2741+ @staticmethod
2742+ def _build_standalone_repr (
2743+ name_override : str | None = None ,
2744+ ) -> Callable [["FunctionExpression" ], str ]:
2745+ """Creates a repr_function that displays a FunctionExpression using standalone function notation.
2746+
2747+ Example:
2748+ `GreaterThan(value, 18)`
2749+ """
2750+
2751+ def build_repr (expr ):
2752+ final_name = name_override or expr .__class__ .__name__
2753+ return f"{ final_name } ({ ', ' .join ([repr (a ) for a in expr .params ])} )"
2754+
2755+ return build_repr
2756+
27162757 def _to_pb (self ):
27172758 return Value (
27182759 function_value = {
@@ -2966,7 +3007,9 @@ class And(BooleanExpression):
29663007 """
29673008
29683009 def __init__ (self , * conditions : "BooleanExpression" ):
2969- super ().__init__ ("and" , conditions , use_infix_repr = False )
3010+ super ().__init__ (
3011+ "and" , conditions , repr_function = FunctionExpression ._build_standalone_repr ()
3012+ )
29703013
29713014
29723015class Not (BooleanExpression ):
@@ -2982,7 +3025,11 @@ class Not(BooleanExpression):
29823025 """
29833026
29843027 def __init__ (self , condition : BooleanExpression ):
2985- super ().__init__ ("not" , [condition ], use_infix_repr = False )
3028+ super ().__init__ (
3029+ "not" ,
3030+ [condition ],
3031+ repr_function = FunctionExpression ._build_standalone_repr (),
3032+ )
29863033
29873034
29883035class Or (BooleanExpression ):
@@ -2999,7 +3046,9 @@ class Or(BooleanExpression):
29993046 """
30003047
30013048 def __init__ (self , * conditions : "BooleanExpression" ):
3002- super ().__init__ ("or" , conditions , use_infix_repr = False )
3049+ super ().__init__ (
3050+ "or" , conditions , repr_function = FunctionExpression ._build_standalone_repr ()
3051+ )
30033052
30043053
30053054class Nor (BooleanExpression ):
@@ -3015,7 +3064,9 @@ class Nor(BooleanExpression):
30153064 """
30163065
30173066 def __init__ (self , * conditions : "BooleanExpression" ):
3018- super ().__init__ ("nor" , conditions , use_infix_repr = False )
3067+ super ().__init__ (
3068+ "nor" , conditions , repr_function = FunctionExpression ._build_standalone_repr ()
3069+ )
30193070
30203071
30213072class Xor (BooleanExpression ):
@@ -3032,7 +3083,9 @@ class Xor(BooleanExpression):
30323083 """
30333084
30343085 def __init__ (self , conditions : Sequence ["BooleanExpression" ]):
3035- super ().__init__ ("xor" , conditions , use_infix_repr = False )
3086+ super ().__init__ (
3087+ "xor" , conditions , repr_function = FunctionExpression ._build_standalone_repr ()
3088+ )
30363089
30373090
30383091class Conditional (BooleanExpression ):
@@ -3054,7 +3107,9 @@ def __init__(
30543107 self , condition : BooleanExpression , then_expr : Expression , else_expr : Expression
30553108 ):
30563109 super ().__init__ (
3057- "conditional" , [condition , then_expr , else_expr ], use_infix_repr = False
3110+ "conditional" ,
3111+ [condition , then_expr , else_expr ],
3112+ repr_function = FunctionExpression ._build_standalone_repr (),
30583113 )
30593114
30603115
@@ -3075,7 +3130,13 @@ class Count(AggregateFunction):
30753130
30763131 def __init__ (self , expression : Expression | None = None ):
30773132 expression_list = [expression ] if expression else []
3078- super ().__init__ ("count" , expression_list , use_infix_repr = bool (expression_list ))
3133+ super ().__init__ (
3134+ "count" ,
3135+ expression_list ,
3136+ repr_function = FunctionExpression ._build_infix_repr ()
3137+ if expression_list
3138+ else FunctionExpression ._build_standalone_repr (),
3139+ )
30793140
30803141
30813142class CurrentTimestamp (FunctionExpression ):
@@ -3086,7 +3147,11 @@ class CurrentTimestamp(FunctionExpression):
30863147 """
30873148
30883149 def __init__ (self ):
3089- super ().__init__ ("current_timestamp" , [], use_infix_repr = False )
3150+ super ().__init__ (
3151+ "current_timestamp" ,
3152+ [],
3153+ repr_function = FunctionExpression ._build_standalone_repr (),
3154+ )
30903155
30913156
30923157class Rand (FunctionExpression ):
@@ -3098,7 +3163,9 @@ class Rand(FunctionExpression):
30983163 """
30993164
31003165 def __init__ (self ):
3101- super ().__init__ ("rand" , [], use_infix_repr = False )
3166+ super ().__init__ (
3167+ "rand" , [], repr_function = FunctionExpression ._build_standalone_repr ()
3168+ )
31023169
31033170
31043171class Variable (Expression ):
@@ -3137,4 +3204,8 @@ class CurrentDocument(FunctionExpression):
31373204 """
31383205
31393206 def __init__ (self ):
3140- super ().__init__ ("current_document" , [])
3207+ super ().__init__ (
3208+ "current_document" ,
3209+ [],
3210+ repr_function = FunctionExpression ._build_standalone_repr (),
3211+ )
0 commit comments