Skip to content

OrderedDict.fromkeys() returns Dict instead of OrderedDict #3800

Closed

Description

@bluetech

OrderedDict inherits fromkeys() from its parent Dict. dict.fromkeys has hardcoded return type dict:

@staticmethod
@overload
def fromkeys(__iterable: Iterable[_T]) -> Dict[_T, Any]: ... # TODO: Actually a class method (mypy/issues#328)
@staticmethod
@overload
def fromkeys(__iterable: Iterable[_T], __value: _S) -> Dict[_T, _S]: ...

Easy way to fix this is to explicitly override to return OrderedDict, but this doesn't take care of the same problem in other dict subclasses.

I tried to fix it using generic self. For the first (short) form of fromkeys(), I think it should work:

class dict(MutableMapping[_KT, _VT], Generic[_KT, _VT]):
    _FK1 = TypeVar('_FK1', bound='dict[_KT, None]')

    @classmethod
    def fromkeys(cls: Type[_FK1], __iterable: Iterable[_T]) -> _FK1: ...

This uses the method described in the docs.

But the second (long) form has a complication - the value type of the dict depends on a generic argument to fromkeys. The following doesn't work:

class dict(MutableMapping[_KT, _VT], Generic[_KT, _VT]):
    _FK2 = TypeVar('_FK2', bound='dict[_KT, _S]')

    @classmethod
    def fromkeys(cls: Type[_FK2], __iterable: Iterable[_T], __value: _S) -> _FK2: ...

Understandably fails with Type variable "builtins._S" is unbound in the _FK2 = ... line.

I wonder if there is a way to make this work?

Activity

  1. JelleZijlstra commented on Mar 2, 2020

    @JelleZijlstra
    Member

    Wow, I didn't know of that trick (defining a typevar within the class) to make the key type work. I can't think of a way to make the value type work correctly either.

    I think we should just add a stub for OrderedDict.fromkeys and not worry about other possible dict subclasses unless user reports come in that indicate that it's a common problem.

  2. bluetech commented on Mar 5, 2020

    @bluetech
    ContributorAuthor

    I think we should just add a stub for OrderedDict.fromkeys and not worry about other possible dict subclasses unless user reports come in that indicate that it's a common problem.

    Sure. I'll do that after #3799 is settled to avoid a (semantic) conflict.

  3. ssbarnea commented on Jul 25, 2020

    @ssbarnea
    SponsorContributor

    Is there a temporary workaround that we can use until this is sorted?

  4. added a commit that references this issue on Dec 3, 2021
    c00a660
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions