[prev in list] [next in list] [prev in thread] [next in thread] 

List:       python-dev
Subject:    Re: [Python-Dev] Builtin functions are magically static methods?
From:       Mark Shannon <mark () hotpy ! org>
Date:       2015-03-29 20:35:53
Message-ID: 55186229.70603 () hotpy ! org
[Download RAW message or body]



On 29/03/15 19:16, Paul Sokolovsky wrote:
> Hello,
>
> I looked into porting Python3 codecs module to MicroPython and saw
> rather strange behavior, which is best illustrated with following
> testcase:
>
> ==========
> def foo(a):
>      print("func:", a)
>
> import _codecs
> fun = _codecs.utf_8_encode
> #fun = hash
> #fun = str.upper
> #fun = foo
>
>
> class Bar:
>      meth = fun
>
> print(fun)
> print(fun("foo"))
> b = Bar()
> print(b.meth("bar"))
> ==========
>
> Uncommenting either _codecs.utf_8_encode or hash (both builtin
> functions) produces 2 similar output lines, which in particular means
> that its possible to call a native function as (normal) object method,
> which then behaves as if it was a staticmethod - self is not passed to
> a native function.
>
> Using native object method in this manner produces error of self type
> mismatch (TypeError: descriptor 'upper' for 'str' objects doesn't apply
> to 'Bar' object).
>
> And using standard Python function expectedly produces error about
> argument number mismatch, because used as a method, function gets extra
> self argument.
>
> So the questions are:
>
> 1. How so, the native functions exhibit such magic behavior? Is it
> documented somewhere - I never read or heard about that (cannot say I
> read each and every word in Python reference docs, but read enough. As
> an example, https://docs.python.org/3/library/stdtypes.html#functions
> is rather short and mentions difference in implementation, not in
> meta-behavior).

In fact the "magic" is exhibited by Python functions, not by builtin 
ones. Python functions are descriptors, builtin functions are not.

>
> 2. The main question: how to easily and cleanly achieve the same
> behavior for standard Python functions? I'd think it's staticmethod(),
> but:
>

Write your own "BuiltinFunction" class which has the desired properties, 
ie. it would be callable, but not a descriptor.
Then write a "builtin_function" decorator to produce such an object from 
a function. The class and decorator could be the same object.

Personally, I think that such a class (plus a builtin function type that 
behaved like a Python function) would be a useful addition to the 
standard library. Modules do get converted from Python to C and vice-versa.

>>>> staticmethod(lambda:1)()
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: 'staticmethod' object is not callable
>
> Surprise.
>
> (By "easily and cleanly" I mean without meta-programming tricks, like
> instead of real arguments accept "*args, **kwargs" and then munge args).
>
>
> Thanks,
>   Paul                          mailto:pmiscml@gmail.com

Cheers,
Mark
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: https://mail.python.org/mailman/options/python-dev/python-dev-marcsub-zyf4%40marc.info
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic