[issue39442] from __future__ import annotations makes dataclasses.Field.type a string, not type

ARF1 report at bugs.python.org
Thu Nov 19 04:25:34 EST 2020


ARF1 <arik at funke.eu> added the comment:

One problem I have with the current behaviour is that users of library code need to know the exact namespace in which a library has defined a dataclass.

An example is if a library writer had to deconflict the name of a type he used in a user-facing dataclass.

Below is a "typical" use case which will become very fragile to implement.(E.g. imagine the dataclass with dynamically generated fields, the implementation of which I have neglected for the sake of brevity.)


=== some_library_typing.py ===
mytype = str  # library author defines some type alias


=== some_library_module_a.py ===
from __future__ import annotations
import dataclasses
from some_library_typing import mytype as mytype_deconflicted

mytype = int

@dataclasses.dataclass
class MyClass:
    var1: mytype_deconflicted = 'foo'

    def method1(self, val: mytype) -> mytype:
        return val + 1


=== user_code.py ===
from __future__ import annotations
import dataclasses
from some_library_typing import mytype
from some_library_module_a import MyClass

inst = MyClass('bar')

for f in dataclasses.fields(inst):
    if f.type is mytype:
        print('mytype found')
        break
else:
    print('mytype not found')


The `if f.type is mytype` comparison obviously won't work any more. But neither will `if f.type == 'mytype'`. The user will have to be aware that the library author had to deconflict the identifier `mytype` to `mytype_deconflicted` to write his code.

Of course, the library writer could have written the following to make the code work:

=== some_library_module_a.py ===
from __future__ import annotations
import dataclasses
from some_library_typing import mytype as mytype_deconflicted

mytype = int

@dataclasses.dataclass
class MyClass:
    var1: mytype = 'foo'

    def method1(self, val: mytype)
        return val + 1

That is a phenomenally obscure and counter-intuitive way of writing code!

Whichever way one turns this, the current behaviour either seems to require library authors to take extraordinary care with their namespaces when defining dataclasses or forces them to write hard-to-read code or seems to require from users detailed knowledge about the implementation specifics of a library they use.

If this behaviour is kept as is, some clear warnings and guidance on how to deal with this in practice should be given in the docs. From what I can see in the 3.10 docs, that is not yet the case.

----------
nosy: +ARF1
versions: +Python 3.9

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue39442>
_______________________________________


More information about the Python-bugs-list mailing list