Skip to content

inspect: getmembers calls properties #82518

Description

@jnsdrtlf
mannequin
BPO 38337
Nosy @csabella, @hongweipeng, @jnsdrtlf
PRs
  • bpo-38337: Change getattr to inspect.getattr_static #16521
  • 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-10-01.12:01:59.088>
    labels = ['type-bug', 'library', '3.9']
    title = 'inspect: getmembers calls properties'
    updated_at = <Date 2020-03-29.19:22:40.724>
    user = 'https://github.com/jnsdrtlf'

    bugs.python.org fields:

    activity = <Date 2020-03-29.19:22:40.724>
    actor = 'jnsdrtlf'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2019-10-01.12:01:59.088>
    creator = 'jnsdrtlf'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 38337
    keywords = ['patch']
    message_count = 9.0
    messages = ['353688', '353698', '353871', '353872', '353895', '353900', '360715', '360748', '365274']
    nosy_count = 3.0
    nosy_names = ['cheryl.sabella', 'hongweipeng', 'jnsdrtlf']
    pr_nums = ['16521']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue38337'
    versions = ['Python 3.9']

    Activity

    1. jnsdrtlf commented on Oct 1, 2019

      jnsdrtlfmannequin
      MannequinAuthor

      When calling inspect.getmembers on a class that has a property (@Property), the property will be called by the getattr call in getmembers.

      Example:

      import inspect
      
      class Example:
          def __init__(self, var):
              self._var = var
              print('__init__')
      
          def foo(self, bar):
              print(bar)
              print('foo')
      
          @property
          def var(self):
              print('Access property')
              return self._var
      
      
      if __name__ == '__main__':
          ex = Example('Hello')
          print('--- getmembers from instance ---')
          print(inspect.getmembers(ex))
          print('--- getmembers from class    ---')
          print(inspect.getmembers(Example))

      Result:

      __init__
      --- getmembers from instance ---
      Access property
      [('__class__', <attribute '__class__' of 'object' objects>), ..., ('var', 'Hello')]
      --- getmembers from class ---
      [('__class__', <attribute '__class__' of 'object' objects>), ..., ('var', <property object at 0x...>)]

      Expected:

      __init__
      --- getmembers from instance ---
      [('__class__', <attribute '__class__' of 'object' objects>), ..., ('var', <property object at 0x...>)]
      --- getmembers from class ---
      [('__class__', <attribute '__class__' of 'object' objects>), ..., ('var', <property object at 0x...>)]

    2. added
      stdlibStandard Library Python modules in the Lib/ directory
      type-bugAn unexpected behavior, bug, or error
      on Oct 1, 2019
    3. s-sanjay commented on Oct 1, 2019

      s-sanjaymannequin
      Mannequin

      the issue happens in 2.7 as well

    4. hongweipeng commented on Oct 3, 2019

      hongweipengmannequin
      Mannequin

      The results of this example are different from mine(version 3.7.4).

      __init__
      --- getmembers from instance ---
      Access property
      [('__class__', <class '__main__.Example'>), ... ('var', 'Hello')]
      --- getmembers from class    ---
      [('__class__', <class 'type'>),'var', <property object at 0x>)]
      
    5. jnsdrtlf commented on Oct 3, 2019

      jnsdrtlfmannequin
      MannequinAuthor

      The results of this example are different from mine(version 3.7.4)

      I do not really see any difference. What do you mean?

    6. hongweipeng commented on Oct 4, 2019

      hongweipengmannequin
      Mannequin

      I mean why member __class__ is expected to be <attribute '__class__'...>). I check PR16521,for class, it always gets <attribute '__class__'...>).

    7. jnsdrtlf commented on Oct 4, 2019

      jnsdrtlfmannequin
      MannequinAuthor

      Oh, yes I see what you mean. That's my fault, it seems like I copied the wrong line. Sorry.

      But the important piece is the 'var' attribute. Sorry for the confusion.

    8. csabella commented on Jan 26, 2020

      @csabella
      Contributor

      Here is a link to the discussion of this on ideas:
      https://discuss.python.org/t/implement-inspect-getmembers-static/2550

    9. jnsdrtlf commented on Jan 27, 2020

      jnsdrtlfmannequin
      MannequinAuthor

      Here is a link to the discussion of this on ideas

      Thank you for posting the link.

      I feel like I came to a dead end with this issue. As I am fairly new to CPython and have never contributed to this project before, I have no idea how to address this and to whom. Maybe this is just to irrelevant and not important, but even then we should probably close this issue or mark it as "indefinitely postponed" or something similar.

    10. jnsdrtlf commented on Mar 29, 2020

      jnsdrtlfmannequin
      MannequinAuthor

      I'm still thinking about this bug/issue/undefined behaviour. Today I wanted to test its behaviour with async:

      import inspect
      
      
      class Foo:
          def __init__(self, bar):
              self._bar = bar
      @property
      async def spam(self):
          print('Called spam')
          return self._bar
      
      if __name__ == '__main__':
          instance = Foo('eggs')
          members = inspect.getmembers(instance)

      This will result in a RuntimeWarning:

      RuntimeWarning: coroutine 'Foo.spam' was never awaited
      members = inspect.getmembers(instance)
      RuntimeWarning: Enable tracemalloc to get the object allocation traceback

      Sure, async properties might not be particularly beautiful or best-practice, but I frequently stumble upon code where getmembers would fail – just like this example. However, I am still clueless about what to do.

    11. transferred this issue fromon Apr 10, 2022
    12. interifter commented on May 30, 2025

      @interifter

      Looks like this is still around with at least 3.12. Not a popular bug :)

    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.9 (EOL)end of lifestdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

      Projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions