Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reimplement Python's __qualname__ in Python 3.7? (with some minor adjustments)

The __qualname__ attribute is useful to me because it contextualizes functions; however, it's difficult for me to use for my use case because:

  1. __qualname__ returns a string. For my usecase, I need references to the parent object(s).

  2. __qualname__ sometimes returns the super class instead of the referenced class. For example:

    class Parent():
    
        def __init__(self):
            pass
    
    
    class Child(Parent):
        pass
    
    
    print(Child.__init__.__qualname__)  # Prints: "Parent.__init__"
    
  3. The package I am developing needs to be robust, and the edge cases for __qualname__ are not documented as far as I can tell.

Outside of parsing the Python file with ast, can __qualname__ be reimplemented in Python3 with inspection? How does Python implement __qualname__? In reimplementing the core functionality, I think I'll be able to adapt it for my use case.


Prior Research:

  • PEP 3155: https://www.python.org/dev/peps/pep-3155/
  • Python 2 qualname implementation: https://github.com/wbolster/qualname/blob/master/qualname.py
  • Parsing __qualname__ to get references: Get defining class of unbound method object in Python 3
  • Python 2 __qualname__ stackoverflow: Reproduce effects of Python 3.3 __qualname__ in earlier Pythons

I was unable to find the qualname implementation in the Python source code.

like image 722
Michael Petrochuk Avatar asked Sep 16 '25 20:09

Michael Petrochuk


1 Answers

You're not going to get what you want. You want your_thing(Parent.__init__) to say something about Parent and your_thing(Child.__init__) to say something about Child, but Parent.__init__ and Child.__init__ are the same exact object.

You've accessed that object two different ways, but Python keeps no record of that. Whatever you implement will only receive a function object, without the information you're looking for.

Even if you do some horrible stack inspection thing to look at the fact that the source code for your_thing(Child.__init__) says "Child" in it, that won't work for cases where the function gets stored in a variable or passed around through a few more layers of function calls. It'll only work, unreliably, for a fraction of cases where you don't need it because you already had the information you wanted when you were writing the code.

like image 179
user2357112 supports Monica Avatar answered Sep 18 '25 09:09

user2357112 supports Monica