Skip to content

OrderedDict() needs type annotation but {} doesn't #4551

Closed

Description

@kamahen

The following error message is triggered when by adding -> Dict[Text, Any] to the type signature:

/tmp/pod.py:7: error: Need type annotation for 'result'

This is the contents of /tmp/pod.py:

import collections
from typing import Any, Dict, Text

class PlainOldData:

    def as_json_dict(self) -> Dict[Text, Any]:
        result = collections.OrderedDict()
        for k in self.__slots__:
            value = getattr(self, k)
            if value is not None:
                result[k] = value
        return result

Activity

  1. emmatyping commented on Feb 8, 2018

    @emmatyping
    Member

    Since mypy doesn't know the type of the ordered dict when you create it, you need to add a type annotation.

  2. kamahen commented on Feb 8, 2018

    @kamahen
    ContributorAuthor

    Oops ... the problem I was trying to report (about slots) turned out to be due to having __slots__ = () (which gets overridden in subclasses) and I needed to annotate that even though object.slots has an appropriate definition in typeshed.

    As for OrderedDict ... shouldn't it work? When I change the code to result = {}, mypy is happy.

  3. emmatyping commented on Feb 8, 2018

    @emmatyping
    Member

    The issue with __slots__ is #4547 then, while the issue with result is interesting... if I had to guess mypy is inferring the type of {} based on the return type but fails to do so in your real code since it is an OrderedDict.

  4. changed the title [-]Bogus "need type annotation" for __slots__[/-] [+]OrderedDict() needs type annotation but {} doesn't[/+] on Feb 8, 2018
  5. JukkaL commented on Feb 8, 2018

    @JukkaL
    Collaborator

    Mypy has custom type inference rules for common collection types such as List and Dict, but they don't apply to OrderedDict. It would be nice if we could generalize this to (almost) arbitrary collection types.

  6. emmatyping commented on Dec 27, 2024

    @emmatyping
    Member

    The example below (updated to have type information to express subclasses will have __slots__):

    import collections
    from typing import Any, Dict, Text
    
    class PlainOldData:
        __slots__: tuple[str, ...]
        def as_json_dict(self) -> Dict[Text, Any]:
            result = collections.OrderedDict()
            for k in self.__slots__:
                value = getattr(self, k)
                if value is not None:
                    result[k] = value
            return result

    passes with the latest mypy, closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions