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:pmis...@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/archive%40mail-archive.com

Reply via email to