Skip to content

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

@bluetech

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions