Skip to content

__slots__ Union type should not include None. #1853

Closed

Description

@gwk

Consider the following function:

def all_slots(type: Type) -> Set[str]:
  '''
  Subclasses of slots classes may define their own slots,
  which hold just the additions to the parent class.
  Therefore we need to iterate over the inheritance chain to get all slot names.
  We use __mro__ here, and hope for the best regarding multiple inheritance.
  '''
  slots: Set[str] = set()
  for t in type.__mro__:
    try: s = t.__slots__
    except AttributeError: break
    else:
      if isinstance(s, str):
        slots.add(s) # single slot.
      else:
        slots.update(cast(Iterable[str], s)) # mypy bug: __slots__ cannot be None.
  return slots

Without the cast, using latest mypy/typeshed, I get:
Argument 1 to "update" of "set" has incompatible type "Optional[Iterable[str]]"; expected "Iterable[str]"

Mypy thinks that the type of __slots__ is Union[str, Iterable[str], None] (it eliminates the str case due to the check above).

However, I don't think __slots__ can legally be None:

class Z: __slots__ = None
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not iterable

Activity

  1. asottile commented on Feb 26, 2018

    @asottile
    Contributor

    I think what the annotation meant by Optional is it's sometimes not present -- though I don't know of a way to express that in mypy.

    For context, here's where this was added: #780

  2. gvanrossum commented on Feb 26, 2018

    @gvanrossum
    Member

    Looks like you're right -- please submit a fix to remove the Optional[]. There's no way in typeshed (or mypy) to express "this may or may not exist" and mypy does not help detecting cases where that may be an issue, but Optional[] is definitely not the right way to spell that.

  3. gwk commented on Feb 27, 2018

    @gwk
    ContributorAuthor
  4. gvanrossum commented on Feb 27, 2018

    @gvanrossum
    Member
  5. added a commit that references this issue on May 14, 2018
    fba6b9b
  6. added a commit that references this issue on Jun 11, 2018
    f5a74fd
  7. added a commit that references this issue on Jan 23, 2019
    7e41636
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