cnamedtuple icon indicating copy to clipboard operation
cnamedtuple copied to clipboard

Minor incompatibilities with collections.namedtuple

Open JelleZijlstra opened this issue 6 years ago • 8 comments

I found a few small differences between this implementation and collections.namedtuple:

  • There's no docstring on the namedtuple class (Point.__doc__ returns None).
  • inspect.signature doesn't work on cnamedtuple classes, but works on collections.namedtuple. I suppose this is because there's no signature information on the __new__ method of cnamedtuple classes.

JelleZijlstra avatar Jul 19 '17 06:07 JelleZijlstra

Thanks for catching these!

For the docstring we can use something that is very similar to the repr code, I can add a tp_getset for __doc__ which computes that value.

For the signature, I think we can just put a __signature__ tp_getset on the type itself which returns the signature. If it can be a string then we can share the same get function as __doc__.

I don't believe the signature thing is tested, at least as of 3.5, because I took the test suite from the stdlib. I may have chosen to remove the __doc__ test if it existed but I would have remembered the signature thing.

llllllllll avatar Jul 19 '17 06:07 llllllllll

FWIW, there wouldn't be a signature test. collections.namedtuple is pure Python, thus it would work fine for inspect.signature, which can introspect the signature of a live callable object. C extensions don't create live code objects in the same way, so there is a __text_signature__, which is what Argument Clinic uses. You could also provide a Signature object via __signature__, but I would think __text_signature__ is more expected, as it is used internally (you can see how it is parsed here.

ethanhs avatar Jul 19 '17 09:07 ethanhs

While it is pure python, many pure python implementations of namedtuple could produce a signature of just __new__(*args, **kwargs). Creating a useful signature is not a given and should probably be tested in CPython.

llllllllll avatar Jul 19 '17 18:07 llllllllll

Why not reusing original stdlib unittests and remove tests relying on "verbose" and "module" parameters and "_source" attribute?

giampaolo avatar Jul 19 '17 19:07 giampaolo

That is what I did.

llllllllll avatar Jul 19 '17 19:07 llllllllll

Okay, perhaps a test of signature would be a good thing, but are most parts of the Python stdlib tested with inspect.signature? (It appears not, but Im not the most familiar with the CPython test suite).

Regardless, back to the more important point, I think using __text_signature__ is probably the best solution here, so you don't have to make a Signature object and the creation of the Signature object can be done only when needed.

ethanhs avatar Jul 19 '17 20:07 ethanhs

__text_signature__ appears to be an internal API that only works with static types. This library creates heaptypes so we are out of luck. That said, we could write a descriptor in python which gets attached to the class at construction time that lazily constructs a Signature object.

llllllllll avatar Sep 01 '17 06:09 llllllllll

@llllllllll good point. Then making a Signature object seems the best strategy.

ethanhs avatar Sep 01 '17 07:09 ethanhs