@@ -219,127 +219,18 @@ def constant(cls, value: T, name: str = None) -> Union[T, Any]: # Any really me
219219
220220 elif callable (value ):
221221 # a function
222- return cls .make_lambda_friendly_method (value , name = name )
222+ # If the provided method does not have a name then name is mandatory
223+ if (not hasattr (value , '__name__' ) or value .__name__ == '<lambda>' ) and name is None :
224+ raise ValueError ('This method does not have a name (it is either a partial or a lambda) so you have to '
225+ 'provide one: the \' name\' argument is mandatory' )
226+
227+ # return cls.make_lambda_friendly_method(value, name=name)
228+ return cls (str_expr = name or value .__name__ , is_constant = True , constant_value = value )
223229
224230 else :
225231 # a true 'constant'
226232 return cls (str_expr = name or str (value ), is_constant = True , constant_value = value )
227233
228- @classmethod
229- def make_lambda_friendly_method (cls , method : Callable , name : str = None ):
230- """
231- Utility method to transform any method whatever their signature (positional and/or keyword arguments,
232- variable-length included) into a method usable inside lambda expressions, even if some of the arguments are
233- expressions themselves.
234-
235- In particular you may wish to convert:
236-
237- * standard or user-defined functions. Note that by default the name appearing in the expression is func.__name__
238-
239- ```python
240- from mini_lambda import x, _, make_lambda_friendly_method
241- from math import log
242-
243- # transform standard function `log` into lambda-friendly function `Log`
244- Log = make_lambda_friendly_method(log)
245-
246- # now you can use it in your lambda expressions
247- complex_identity = _( Log(10 ** x, 10) )
248- complex_identity(3.5) # returns 3.5
249- print(complex_identity) # "log(10 ** x, 10)"
250- ```
251-
252- * anonymous functions such as lambdas and partial. In which case you HAVE to provide a name
253-
254- ```python
255- from mini_lambda import x, _, make_lambda_friendly_method
256- from math import log
257-
258- # ** partial function (to fix leftmost positional arguments and/or keyword arguments)
259- from functools import partial
260- is_superclass_of_bool = make_lambda_friendly_method(partial(issubclass, bool), name='is_superclass_of_bool')
261-
262- # now you can use it in your lambda expressions
263- expr = _(is_superclass_of_bool(x))
264- expr(int) # True
265- expr(str) # False
266- print(expr) # "is_superclass_of_bool(x)"
267-
268- # ** lambda function
269- Log10 = make_lambda_friendly_method(lambda x: log(x, 10), name='log10')
270-
271- # now you can use it in your lambda expressions
272- complex_identity = _(Log10(10 ** x))
273- complex_identity(3.5) # 3.5
274- print(complex_identity) # "log10(10 ** x)"
275- ```
276-
277- * class functions. Note that by default the name appearing in the expression is func.__name__
278-
279- ```python
280- from mini_lambda import x, _, make_lambda_friendly_method
281-
282- # ** standard class function
283- StartsWith = make_lambda_friendly_method(str.startswith)
284-
285- # now you can use it in your lambda expressions
286- str_tester = _(StartsWith('hello', 'el', x))
287- str_tester(0) # False
288- str_tester(1) # True
289- print(str_tester) # "startswith('hello', 'el', x)"
290-
291- # ** static and class functions
292- class Foo:
293- @staticmethod
294- def bar1(times, num, den):
295- return times * num / den
296-
297- @classmethod
298- def bar2(cls, times, num, den):
299- return times * num / den
300-
301- FooBar1 = make_lambda_friendly_method(Foo.bar1)
302- fun1 = _( FooBar1(x, den=x, num=1) )
303-
304- FooBar2a = make_lambda_friendly_method(Foo.bar2) # the `cls` argument is `Foo` and cant be changed
305- fun2a = _( FooBar2a(x, den=x, num=1) )
306-
307- FooBar2b = make_lambda_friendly_method(Foo.bar2.__func__) # the `cls` argument can be changed
308- fun2b = _( FooBar2b(Foo, x, den=x, num=1) )
309- ```
310-
311- Note: although the above is valid, it is much more recommended to convert the whole class
312-
313-
314- :param method:
315- :param name: an optional name for the method when used to display the expressions. It is mandatory if the method
316- does not have a name, otherwise the default name is method.__name__
317- :return:
318- """
319-
320- # If the provided method does not have a name then name is mandatory
321- if (not hasattr (method , '__name__' ) or method .__name__ == '<lambda>' ) and name is None :
322- raise ValueError ('This method does not have a name (it is either a partial or a lambda) so you have to '
323- 'provide one: the \' name\' argument is mandatory' )
324-
325- # create a named method if a new name is provided
326- if name is not None :
327- # work on a copy to rename it
328- def new_method (* args , ** kwargs ):
329- return method (* args , ** kwargs )
330-
331- new_method .__name__ = name
332- else :
333- new_method = method
334-
335- # construct the lambda-friendly method
336- def lambda_friendly_method (* args , ** kwargs ):
337- """ A replacement method for `method`, that returns a new expression corresponding to executing the inner
338- method with the provided arguments """
339- return cls ._get_expression_for_method_with_args (new_method , * args , ** kwargs )
340-
341- return lambda_friendly_method
342-
343234 @classmethod
344235 def _get_expression_for_method_with_args (cls , method , * args , ** kwargs ):
345236 """
0 commit comments