Movatterモバイル変換


[0]ホーム

URL:


homepage

Issue33141

This issue trackerhas been migrated toGitHub, and is currentlyread-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title:descriptor __set_name__ feature broken for dataclass descriptor fields
Type:behaviorStage:resolved
Components:Library (Lib)Versions:Python 3.8, Python 3.7
process
Status:closedResolution:fixed
Dependencies:Superseder:
Assigned To: eric.smithNosy List: Ricyteach, eric.smith, miss-islington
Priority:normalKeywords:patch

Created on2018-03-26 02:25 byRicyteach, last changed2022-04-11 14:58 byadmin. This issue is nowclosed.

Files
File nameUploadedDescriptionEdit
broken__set_name__.pyRicyteach,2018-03-26 02:25raises AttributeError on accessing `descriptor_object.name` attribute
Pull Requests
URLStatusLinkedEdit
PR 6260mergederic.smith,2018-03-26 16:34
PR 6261mergedmiss-islington,2018-03-26 17:29
Messages (16)
msg314438 -(view)Author: Rick Teachey (Ricyteach)*Date: 2018-03-26 02:25
Summary: The descriptor `__set_name__` functionality (introduced in Python 3.6) does not seem to be working correctly for `dataclass.Field` objects with a default pointing to a descriptor. I have attached a file demonstrating the trouble.Details: If I set a `dataclass` class object field to a `dataclass.field` with a descriptor object for the `default` argument, the descriptor's `__set_name__` method is not called during initialization. This is unexpected because descriptors themselves seem to work pretty much flawlessly, otherwise. (Bravo on that by the way! Working descriptors isn't mentioned at all in the PEP as a feature but I was very pleased to see them working!!)System details:Python 3.7b02Windows 10PyCharm Community Editionbtw this is my first ever Python bug report; I hope I did a good job.
msg314446 -(view)Author: Eric V. Smith (eric.smith)*(Python committer)Date: 2018-03-26 10:28
That's a tough one. Because C.d is not set to a descriptor at type creation time (it's set to a Field object), the __set_name__ behavior is never invoked. It's when the @dataclass decorator is called that C.d is set to D().https://docs.python.org/3/reference/datamodel.html#creating-the-class-objectI'm not sure it's possible to work around this without duplicating some of the type creation code, and even then I'm not convinced it's doable.
msg314447 -(view)Author: Eric V. Smith (eric.smith)*(Python committer)Date: 2018-03-26 10:47
I suppose I could, when overwriting the class member, check for inspect.ismethoddescriptor and call __set_name__ myself.
msg314452 -(view)Author: Rick Teachey (Ricyteach)*Date: 2018-03-26 13:49
hmmm... if I check the C.d class attribute it seems to return thedescriptor instance object (not a field object) before any C instances havebeen created. i guess this is just a part of how the dataclassimplementation works.i didn't realize there's nothing "special" going on with descriptors here-the descriptors "just work" by virtue of being set to the class attributeat creation time. interesting.maybe because of this descriptors should short-circuit the field creationprocess entirely? that would be a shame though. having the option ofauto-including a descriptor in the class repr turns out to be very usefuland i'm already playing around with it in a project.one idea: what if it there were a keyword argument to mark a field as adescriptor, allowing tje descriptor to be set at type creation? this wouldneed to disallow init=True, i think. and setting a field default to adescriptor class would then raise a type error.---Ricky."I've never met a Kentucky man who wasn't either thinking about going homeor actually going home." - Happy ChandlerOn Mon, Mar 26, 2018 at 6:47 AM, Eric V. Smith <report@bugs.python.org>wrote:>> Eric V. Smith <eric@trueblade.com> added the comment:>> I suppose I could, when overwriting the class member, check for> inspect.ismethoddescriptor and call __set_name__ myself.>> ----------> components: +Library (Lib)> versions: +Python 3.8>> _______________________________________> Python tracker <report@bugs.python.org>> <https://bugs.python.org/issue33141>> _______________________________________>
msg314458 -(view)Author: Eric V. Smith (eric.smith)*(Python committer)Date: 2018-03-26 15:20
Nick Coghlan suggested (on python-dev) to have Field implement __set_name__ and call through to the default value, if it exists.That approach seems to work fine. I'll generate a PR with tests sometime before today's release.
msg314459 -(view)Author: Rick Teachey (Ricyteach)*Date: 2018-03-26 15:46
Sounds like a relatively easy solution then. Hopefully it makes the beta 3 so I can use it immediately- thanks!
msg314460 -(view)Author: Rick Teachey (Ricyteach)*Date: 2018-03-26 16:30
I suppose one downside of that solution is __set_name__ will be called for every Field whether or not it is need. Probably can't be helped without major complications.
msg314463 -(view)Author: Eric V. Smith (eric.smith)*(Python committer)Date: 2018-03-26 16:45
I don't expect there to be too much usage of Field objects, so I'm not so worried about it.If you can, try out the code in the PR. Thanks.
msg314466 -(view)Author: Rick Teachey (Ricyteach)*Date: 2018-03-26 16:57
Eric, looking at the PR; note that if you do this for the __set_name__ check:    if inspect.ismethoddescriptor(self.default):...an object like the one below will not get its __set_name__ called, even thoughPEP 487 says it should:class D:def __set_name__(self, o, n):self.name = nclass C:d: int = D()if __name__ == "__main__":print(f"C.d.name = {C.d.name}") # __set_name__ was calledassert inspect.ismethoddescriptor(C.d) # Error
msg314467 -(view)Author: Eric V. Smith (eric.smith)*(Python committer)Date: 2018-03-26 17:00
Yes, I noticed the same thing. I'll remove the test.
msg314468 -(view)Author: Rick Teachey (Ricyteach)*Date: 2018-03-26 17:03
Yeah and I think lines 2709-2712 of TestDescriptors also needs removed.
msg314469 -(view)Author: Eric V. Smith (eric.smith)*(Python committer)Date: 2018-03-26 17:05
I've updated the PR.I left those lines in, and added a different test. After all, it does need to work with real descriptors.
msg314470 -(view)Author: Rick Teachey (Ricyteach)*Date: 2018-03-26 17:09
Looks great to me. Thanks!
msg314471 -(view)Author: Eric V. Smith (eric.smith)*(Python committer)Date: 2018-03-26 17:29
New changesetde7a2f04d6b9427d568fcb43b6f512f9b4c4bd84 by Eric V. Smith in branch 'master':bpo-33141: Have dataclasses.Field pass through __set_name__ to any default argument. (GH-6260)https://github.com/python/cpython/commit/de7a2f04d6b9427d568fcb43b6f512f9b4c4bd84
msg314473 -(view)Author: miss-islington (miss-islington)Date: 2018-03-26 17:55
New changesetc6147acd2ce5fa9e344f179b539f3b21b9ae1a6d by Miss Islington (bot) in branch '3.7':bpo-33141: Have dataclasses.Field pass through __set_name__ to any default argument. (GH-6260)https://github.com/python/cpython/commit/c6147acd2ce5fa9e344f179b539f3b21b9ae1a6d
msg314474 -(view)Author: Eric V. Smith (eric.smith)*(Python committer)Date: 2018-03-26 18:14
Thanks for the bug report.
History
DateUserActionArgs
2022-04-11 14:58:59adminsetgithub: 77322
2018-03-26 18:14:56eric.smithsetstatus: open -> closed
resolution: fixed
messages: +msg314474

stage: patch review -> resolved
2018-03-26 17:55:15miss-islingtonsetnosy: +miss-islington
messages: +msg314473
2018-03-26 17:29:42miss-islingtonsetpull_requests: +pull_request5987
2018-03-26 17:29:18eric.smithsetmessages: +msg314471
2018-03-26 17:09:15Ricyteachsetmessages: +msg314470
2018-03-26 17:05:19eric.smithsetmessages: +msg314469
2018-03-26 17:03:21Ricyteachsetmessages: +msg314468
2018-03-26 17:00:40eric.smithsetmessages: +msg314467
2018-03-26 16:57:12Ricyteachsetmessages: +msg314466
2018-03-26 16:45:38eric.smithsetmessages: +msg314463
2018-03-26 16:34:22eric.smithsetkeywords: +patch
stage: patch review
pull_requests: +pull_request5984
2018-03-26 16:30:48Ricyteachsetmessages: +msg314460
2018-03-26 15:46:04Ricyteachsetmessages: +msg314459
2018-03-26 15:20:48eric.smithsetmessages: +msg314458
2018-03-26 13:49:01Ricyteachsetmessages: +msg314452
2018-03-26 10:47:31eric.smithsetmessages: +msg314447
components: + Library (Lib)
versions: + Python 3.8
2018-03-26 10:28:57eric.smithsetmessages: +msg314446
2018-03-26 03:53:12rhettingersetassignee:eric.smith
2018-03-26 02:25:49Ricyteachcreate
Supported byThe Python Software Foundation,
Powered byRoundup
Copyright © 1990-2022,Python Software Foundation
Legal Statements

[8]ページ先頭

©2009-2026 Movatter.jp