On Feb 25, 2015, at 8:21, Guido van Rossum email@example.com wrote:
A variant I've often wanted is to make str() return the "clean" type only (e.g. 'int') while leaving repr() alone -- this would address most problems Steven brought up.
On further thought, I'm not sure backward compatibility can be dismissed. Surely code shouldn't care about the str of a callable, right? But yeah, sometimes it might care, if it's, say, a reflective framework for bridging or debugging or similar.
I once wrote a library that exposed Python objects over AppleEvents. I needed to know all the bound methods of the object. For pure-Python objects, this is easy, but for builtin/extension objects, the bound methods constructed from both slot-wrapper and method-descriptor are of type method-wrapper. (The bug turned up when an obscure corner of our code that tried lxml, cElementTree, then ElementTree was run on a 2.x system without lxml installed, something we'd left out of the test matrix for that module.)
When you print out the method, it's obvious what type it is. But how do you deal with it programmatically? Despite what the docs say, method-descriptor does not return true for either isbuiltin or isroutine. In fact, nothing in inspect is much help. And the type isn't in types. Printing out the method, it's dead obvious what it is.
As it turned out, callable(x) and (hasattr(x, 'im_self') or hasattr(x, '__self__')) was good enough for my particular use case, at least in all Python interpreters/versions we supported (it even works in PyPy with CPyExt extension types and an early version of NumPyPy). But what would a good general solution be?
I think dynamically constructing the type from int().__add__ and then verifying that all extension types in all interpreters and versions I care about pass isinstance(that) unless they look like pure-Python bound methods might be the best way. And even if I did resort to using the string representation, I'd probably use the repr rather than the str, and I'd probably look at type(x) rather than x itself. But still, I can imagine someone deciding "whatever I do is going to be hacky, because there's no non-hacky way to get this information, so I might as well go with the simplest hack that's worked on every CPython and PyPy version from 2.2 to today" and use "... or str(x).startswith('<method-wrapper')".
On Wed, Feb 25, 2015 at 12:12 AM, Serhiy Storchaka firstname.lastname@example.org wrote:
This idea is already casually mentioned, but sank deep into the threads of the discussion. Raise it up.
Currently reprs of classes and functions look as:
<built-in method from_bytes of type object at 0x826cf60>
<built-in function open> >>> import collections >>> collections.Counter <class 'collections.Counter'> >>> collections.Counter.fromkeys <bound method Counter.fromkeys of <class 'collections.Counter'>> >>> collections.namedtuple <function namedtuple at 0xb6fc4adc>
What if change default reprs of classes and functions to just full qualified name __module__ + '.' + __qualname__ (or just __qualname__ if __module__ is builtins)? This will look more neatly. And such reprs are evaluable.
Python-ideas mailing list Pythonemail@example.com https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
-- --Guido van Rossum (python.org/~guido) _______________________________________________ Python-ideas mailing list Pythonfirstname.lastname@example.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/