Skip to content

Add support for collections.namedtuple #460

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
akaihola opened this issue Sep 16, 2014 · 9 comments
Closed

Add support for collections.namedtuple #460

akaihola opened this issue Sep 16, 2014 · 9 comments
Labels

Comments

@akaihola
Copy link

namedtupletest.py:

from collections import namedtuple

Test:

$ mypy namedtupletest.py
/tmp/namedtupletest.py, line 1: Module has no attribute 'namedtuple'
@rockneurotiko
Copy link
Contributor

It's not implemented yet.
Code

@JukkaL JukkaL added the feature label Sep 22, 2014
@JukkaL JukkaL changed the title Fails with collections.namedtuple Add support for collections.namedtuple Sep 22, 2014
@akaihola
Copy link
Author

I now noticed that some work-arounds are mentioned in the "Common issues" section of the "Creating stubs for Python modules" wiki page.

@JukkaL JukkaL added the priority label Nov 8, 2014
@JukkaL
Copy link
Collaborator

JukkaL commented Nov 8, 2014

The most primitive support would allow basic type checking with implicit Any item types:

X = namedtuple('X', ['a', 'b'])
x = X(1, 'x')  # Ok
x.c  # Type error
x.a + [1]  # No error, since a has implicit type Any

We also need to support namedtuple as a base class:

class X(namedtuple('X', ['a', 'b'])):
    ...

The above features would allow running mypy on code that uses named tuples and perform rudimentary type checking.

The next step (potentially as a separate issue) would be to allow specifying item types. Here is a potential syntax:

X = namedtuple('X', ['a', 'b'])  # type: (int, str)

Coming up with a syntax for the base class case is more difficult. Suggestions are welcome, or we can require the code to be rewritten like this:

X = namedtuple('X', ['a', 'b'])  # type: (int, str)
class X(X):
    ...

@JukkaL
Copy link
Collaborator

JukkaL commented Nov 30, 2014

I'm working on this.

@JukkaL
Copy link
Collaborator

JukkaL commented Dec 1, 2014

I just pushed an experimental, partial implementation of namedtuple support.

This is supported:

from collections import namedtuple
X = namedtuple('X', ['a', 'b'])
x = X(1, 'x')  # Ok
x = X(1, c='x')  # Error
x.c  # Error
x.a + [1]  # No error, since a has implicit type Any
class Y(X): 
    """you can use a namedtuple class as a base class"""

Also, you can define the types of named tuple items using typing.NamedTuple:

from typing import NamedTuple
X = NamedTuple('X', [('a', int), ('b', str)])
x = X(1, 'x')  # Ok
x = X(1, 2)  # Error

A bunch of stuff is still broken or unsupported, but this should be good enough for (most) library stubs that need namedtuple. I'm going to continue working on this.

@JukkaL
Copy link
Collaborator

JukkaL commented Dec 18, 2014

This is now implemented. It's not quite perfect yet, but it should be usable and I'll file issues for the remaining limitations (or just fix them).

Now you can also use named tuples in the base class list:

from typing import NamedTuple
class Foo(NamedTuple('Bar', [('item1', int), ('item2', str)])):    # OK!
    ...

@JukkaL JukkaL closed this as completed Dec 18, 2014
@gvanrossum
Copy link
Member

I don't see NamedTuple defined in the https://github.com/JukkaL/typing project yet. mypy's own typing.py seems to have diverged (e.g. it has Callable, mypy still has Function, but mypy has NamedTuple).

@ghost
Copy link

ghost commented Apr 29, 2015

Mypy disallows usage of _replace() method from namedtuple (and likewise for NamedTuple).

from collections import namedtuple
Person = namedtuple("Person", 'name')
p = Person("bob")
p._replace(name="sam")

==> "Person" has no attribute "_replace"

@JukkaL
Copy link
Collaborator

JukkaL commented May 12, 2015

Yeah, the namedtuple implementation is missing a few things. Added a new issue: #661

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants