[issue34776] Postponed annotations break inspection of dataclasses
David Hagen added the comment: This PR has been sitting for a while. Any chance we can bring it over the finish line? -- ___ Python tracker <https://bugs.python.org/issue34776> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue36424] Pickle fails on frozen dataclass that has slots
David Hagen added the comment: Because the implementation in GH-25786 relies on the new `dataclass(slots=True)` feature (i.e. it does not work if the slots are specified with `__slots__`), I don't think this can be trivially backported to versions before 3.10. -- ___ Python tracker <https://bugs.python.org/issue36424> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39442] from __future__ import annotations makes dataclasses.Field.type a string, not type
David Hagen added the comment: Should `dataclass.Field.type` become a property that evaluates the annotation at runtime much in the same way that `get_type_hints` works? -- nosy: +drhagen ___ Python tracker <https://bugs.python.org/issue39442> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue31385] `import as` does not work when module has same same as parent module
New submission from David Hagen: Consider the following Python project: bugtest/ __init__.py (Contents: from .foo import *) foo/ __init__.py (Contents: from .foo import *) foo.py (Contents: ) Then in a Python session, the following line executes without error (as expected): >>> import bugtest.foo.foo However, the following line gives an error (not as expected): >>> import bugtest.foo.foo as bar Traceback (most recent call last): File "", line 1, in AttributeError: module 'bugtest.foo.foo' has no attribute 'foo' Note that this behavior is dependent on the folder foo and the file foo.py having the same base name. But is not dependent on actually trying to import bugtest.foo.foo. Trying to import bugtest.foo.baz will also fail as long as bugtest.foo.foo exists. It is also dependent on the __init__.py files importing something from their respective submodules. -- messages: 301614 nosy: David Hagen priority: normal severity: normal status: open title: `import as` does not work when module has same same as parent module type: behavior versions: Python 3.5, Python 3.6 ___ Python tracker <https://bugs.python.org/issue31385> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue36424] Pickle fails on frozen dataclass that has slots
New submission from David Hagen : If a dataclass is `frozen` and has `__slots__`, then unpickling an instance of it fails because the default behavior is to use `setattr` which `frozen` does not allow. ``` import pickle from dataclasses import dataclass @dataclass(frozen=True) class A: __slots__ = ('a',) a: int b = pickle.dumps(A(5)) pickle.loads(b) ``` ``` Traceback (most recent call last): File "", line 1, in File "", line 3, in __setattr__ dataclasses.FrozenInstanceError: cannot assign to field 'a' ``` This has a straightforward workaround, namely to use `object.setattr`. ``` import pickle from dataclasses import dataclass @dataclass(frozen=True) class A: __slots__ = ('a',) a: int def __getstate__(self): return dict( (slot, getattr(self, slot)) for slot in self.__slots__ if hasattr(self, slot) ) def __setstate__(self, state): for slot, value in state.items(): object.__setattr__(self, slot, value) b = pickle.dumps(A(5)) pickle.loads(b) ``` It would be nice if this was fixed for all frozen, slotted dataclasses. Originally report on SO: https://stackoverflow.com/questions/55307017/pickle-a-frozen-dataclass-that-has-slots -- messages: 338803 nosy: drhagen priority: normal severity: normal status: open title: Pickle fails on frozen dataclass that has slots type: behavior versions: Python 3.7 ___ Python tracker <https://bugs.python.org/issue36424> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue34776] Postponed annotations break inspection of dataclasses
New submission from David Hagen : The new postponed annotations have an unexpected interaction with dataclasses. Namely, you cannot get the type hints of any of the data classes methods. For example, I have some code that inspects the type parameters of a class's `__init__` method. (The real use case is to provide a default serializer for the class, but that is not important here.) ``` from dataclasses import dataclass from typing import get_type_hints class Foo: pass @dataclass class Bar: foo: Foo print(get_type_hints(Bar.__init__)) ``` In Python 3.6 and 3.7, this does what is expected; it prints `{'foo': , 'return': }`. However, if in Python 3.7, I add `from __future__ import annotations`, then this fails with an error: ``` NameError: name 'Foo' is not defined ``` I know why this is happening. The `__init__` method is defined in the `dataclasses` module which does not have the `Foo` object in its environment, and the `Foo` annotation is being passed to `dataclass` and attached to `__init__` as the string `"Foo"` rather than as the original object `Foo`, but `get_type_hints` for the new annotations only does a name lookup in the module where `__init__` is defined not where the annotation is defined. I know that the use of lambdas to implement PEP 563 was rejected for performance reasons. I could be wrong, but I think this was motivated by variable annotations because the lambda would have to be constructed each time the function body ran. I was wondering if I could motivate storing the annotations as lambdas in class bodies and function signatures, in which the environment is already being captured and is code that usually only runs once. Original mailing list discussion: https://mail.python.org/pipermail/python-dev/2018-September/155289.html -- messages: 326148 nosy: drhagen priority: normal severity: normal status: open title: Postponed annotations break inspection of dataclasses type: behavior versions: Python 3.7 ___ Python tracker <https://bugs.python.org/issue34776> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue26988] Add AutoNumberedEnum to stdlib
David Hagen added the comment: > Secondarily, the doesn't seem to be any use case that can't be readily > covered by the existing classes. The use case that doesn't have a clean interface in 3.5 at the moment is the most common use case of enums: just a collection of named objects of given type; I don't care about the values because they don't really have values apart from their object identities. When writing enums in Rust, Swift, C#, etc., the bare identifier not only saves typing--it allows the developer to explicitly indicate that the underlying value has no meaning. (It may be better to use "object()" rather than an integer on AutoEnum, but that is not very important.) It was said that Python has this feature already: > Yes, Python 3.4 too: Animal = Enum('Animal', 'ant bee cat dog') I will concede that this can do what I want. I hope others will concede that this is not a clean interface. The class name is duplicated and the members are regexed out of a space-delimited string. This same argument could be made to deprecate the unnecessary "class" keyword in favor of the "type" function. I will also concede that there is some deep magic going on in AutoEnum and that magic should be avoided when it obscures. I personally think the only people who will be truly surprised will be those who already know Python at a deep enough level to know that deep magic must be required here. Everyone else will see "Enum" and a list of bare identifiers, and correctly conclude that this is your basic enum from everyone other language. Perhaps an ideal solution would be an enum keyword: enum PrimaryColor: red blue green But that's not happening ever. The next best solution is the current implementation: class PrimaryColor(AutoEnum): red blue green But because of the magic, it only barely beats out what I think is the other great solution already mentioned here: class PrimaryColor(AutoEnum): red = () blue = () green = () These two solutions are isomorphic. Both save the developer from having to provide a (possibly meaningless) value. Both let docstrings be added. Both provide the ability to reorganize without renumbering. The last one trades magic for boilerplate. I'll keep using them from the aenum package if they don't make it into 3.6, but I think this is a fundamental enough construct that it belongs in the standard library. It is hard to convince tool maintainers to fully support these until they are blessed here. -- nosy: +David Hagen ___ Python tracker <http://bugs.python.org/issue26988> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue26988] Add AutoNumberedEnum to stdlib
David Hagen added the comment: One solution similar to one proposed by Vedran works with the current Enum: class Color(Enum): red = object() green = object() blue= object() I tested this in PyCharm and it is perfectly happy with the autocomplete and everything. The main disadvantage is the boilerplate, of course. And perhaps "object()" does not show the clearest intent, but it depends on your perspective. The repr also looks kind of funny: >>> repr(Color.red) > One possibility would be to add an auto() function to enum as a wrapper around object(), providing a more explicit name and a cleaner repr: from enum import Enum, auto class Color(Enum): red = auto() blue = auto() green = auto() repr(Color.red) # auto() means it has no (meaningful) value, so show nothing -- ___ Python tracker <http://bugs.python.org/issue26988> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com