Skip to content

__dir__ on unittest.mock not safe for all spec types #80762

Closed

Description

@dsem
mannequin
BPO 36581
Nosy @cjw296, @voidspace, @mariocj89, @tirkarthi, @dsem, @iritkatriel
PRs
  • gh-80762: Fix dir() on MagicMock with tuple specs #12753
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2019-04-09.22:46:11.142>
    labels = ['type-bug', 'library', '3.9', '3.10', '3.11']
    title = '__dir__ on unittest.mock not safe for all spec types'
    updated_at = <Date 2021-10-18.17:34:19.322>
    user = 'https://github.com/dsem'

    bugs.python.org fields:

    activity = <Date 2021-10-18.17:34:19.322>
    actor = 'iritkatriel'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2019-04-09.22:46:11.142>
    creator = 'Dylan Semler'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 36581
    keywords = ['patch']
    message_count = 4.0
    messages = ['339813', '339815', '339819', '404202']
    nosy_count = 6.0
    nosy_names = ['cjw296', 'michael.foord', 'mariocj89', 'xtreak', 'Dylan Semler', 'iritkatriel']
    pr_nums = ['12753']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue36581'
    versions = ['Python 3.9', 'Python 3.10', 'Python 3.11']

    Activity

    1. dsem commented on Apr 9, 2019

      dsemmannequin
      MannequinAuthor

      If a MagicMock is created with a spec or spec_set that is a non-list iterable of strings (like a tuple), calling dir() on said mock produces a Traceback. Here's a minimum example:

      🡒 cat poc.py
      from unittest.mock import MagicMock

      mock = MagicMock(spec=('a', 'tuple'))
      dir(mock)
      🡒 python3 poc.py 
      Traceback (most recent call last):
        File "poc.py", line 4, in <module>
          dir(mock)
        File "/usr/lib64/python3.6/unittest/mock.py", line 677, in __dir__
          return sorted(set(extras + from_type + from_dict +
      TypeError: can only concatenate tuple (not "list") to tuple
    2. added
      type-crashA hard crash of the interpreter, possibly with a core dump
      stdlibStandard Library Python modules in the Lib/ directory
      on Apr 9, 2019
    3. tirkarthi commented on Apr 9, 2019

      @tirkarthi
      Member

      https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock

      spec: This can be either a list of strings or an existing object (a class or instance) that acts as the specification for the mock object. If you pass in an object then a list of strings is formed by calling dir on the object (excluding unsupported magic attributes and methods). Accessing any attribute not in this list will raise an AttributeError.

      Docs state it should be list of strings. Can you please link to docs where an iterable of strings is mentioned? A simple patch would be to wrap it inside a list() call but I am not sure of making the interface more relaxed which was documented to accept list of strings. I am adding module mock devs to take a call on this.

      diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
      index 8684f1dfa5..35dc7b044e 100644
      --- a/Lib/unittest/mock.py
      +++ b/Lib/unittest/mock.py
      @@ -679,7 +679,7 @@ class NonCallableMock(Base):
      if not FILTER_DIR:
      return object.__dir__(self)

      -        extras = self._mock_methods or []
      +        extras = list(self._mock_methods or [])
               from_type = dir(type(self))
               from_dict = list(self.__dict__)
    4. dsem commented on Apr 9, 2019

      dsemmannequin
      MannequinAuthor

      I agree docs only say "list of strings" and so this isn't a case where there's behavior that contrasts with the documentation. I merely ran into this issue in my project and found it difficult to get to the root of so wanted to fix it upstream. I made a patch and reported this bug only as a formality to accompany my patch.

    5. iritkatriel commented on Oct 18, 2021

      @iritkatriel
      Member

      Changing type as crash typically refers to segfault or hang or the like, and not an exception.

      Reproduced on 3.11.

    6. added
      3.11only security fixes
      type-bugAn unexpected behavior, bug, or error
      and removed
      type-crashA hard crash of the interpreter, possibly with a core dump
      on Oct 18, 2021
    7. transferred this issue fromon Apr 10, 2022
    8. serhiy-storchaka commented on Aug 12, 2026

      @serhiy-storchaka
      Member

      Support of a tuple of strings was never documented, although it worked for most parts except dir(). But since it was not documented, we can consider this as adding a new feature.

    9. added
      type-featureA feature request or enhancement
      3.16new features, bugs and security fixes
      and removed
      type-bugAn unexpected behavior, bug, or error
      3.11only security fixes
      on Aug 12, 2026
    10. added a commit that references this issue on Aug 12, 2026
    11. changed the title [-]__dir__ on unittest.mock not safe for all spec types[/-] [+]`__dir__` on unittest.mock not safe for all spec types[/+] on Aug 12, 2026
    12. added a commit that references this issue on Aug 14, 2026
    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

      3.16new features, bugs and security fixesstdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement

      Projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions