Should firstlineno be private or dunder

The pydoc optimization should be a private implementation detail and not a public attribute.

Maybe others understand what you are referring to, but I’m a bit lost. Can you provide more details?

2 Likes

In whatsnew: Classes have a new __firstlineno__ attribute, populated by the compiler, with the line number of the first line of the class definition.

>>> class XXX:
...     pass
...
>>> dir(XXX)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__static_attributes__', '__str__', '__subclasshook__', '__weakref__']

The static_attributes dunder is suspect too. It seems fragile. Should you rely on it?

Thanks. You say they are suspect. Are you asking if they will be reliably populated? Or if they will be supported in the future? Or if they will be implemented by other implementations? The more details you can provide, the better we can answer.

Fragile.

>>> class XXX:
...     def __init__(self, x):
...         inst = self
...         if x:
...             inst.y = x
...         else:
...             inst.z = x
...
>>> XXX.__static_attributes__
()

I don’t know anything about __static_attributes__, but it does seem confusing. The docs helped me understand:

A tuple containing names of attributes of this class which are accessed through self.X from any function in its body.

The compiler populates __static_attributes__ based on static analysis. When it sees self.some_name in the body of a method, it adds some_name to the tuple. If you used self.y and self.z in your example, y and z would be in the tuple.

I don’t know what __static_attributes__ is meant to be used for. I guess it isn’t useful to you.

See Use static analysis to assist inlining values and compact object layout. · Issue #115775 · python/cpython · GitHub, it’s a hint for use by the object allocator.

The hint should be a private attribute instead of public dunder method. Making it public is a mistake.

What do you mean with “public”? It’s a dunder, meaning it’s reserved for language/implementation internal usage. If you want to use it, make sure to read the documentation and be prepared for such attributes to be removed with very little warning.

1 Like

I hope publicly documented attributes, even dunders, will not be “removed with very little warning.” But definitely you have to understand what they mean. The details can be surprising, but that doesn’t mean they are fragile or wrong, and it doesn’t mean they should be private.

It is a well known rule to not expose implementation details as public attributes.

A rule which essentially does not get apply in python across the board. Essentially everything that can be reasonably exposed as a python object is exposed as a python object, from functions to code objects to the AST itself to closure variables and C-API pointers. All of these are implementation details, and all are publicly accessible, by design.

So is your position that all of these should be made inaccessible? Or is there something in your mind that makes those private and the two dunders you mentioned public?

As mentioned, there are many aspects of CPython’s implementation that are available on objects, including the bytecode of compiled functions. They details of bytecode are documented, but often change from version to version.

Did you want to use __static_attributes__ for something in particular? Most people will completely ignore it because they have no need for it.