gh-111874: Call __set_name__ on objects that define the method inside a typing.NamedTuple class dictionary as part of the creation of that class by AlexWaygood · Pull Request #111876 · python/cpython (original) (raw)

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation25 Commits17 Checks0 Files changed

Conversation

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters

[ Show hidden characters]({{ revealButtonHref }})

AlexWaygood

@AlexWaygood

…d inside a typing.NamedTuple class dictionary as part of the creation of that class

AlexWaygood

sobolevn

@AlexWaygood

@AlexWaygood

serhiy-storchaka

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but I have few minor suggestions.

@AlexWaygood

@AlexWaygood

Thanks @serhiy-storchaka! I applied your suggestions; would you mind taking another look? I discovered another interesting thing in the process: __set_name__ was also not being called for the values of annotated fields (which become namedtuple members). I changed that so that __set_name__ is called on these field values also. It's consistent with what e.g. dataclasses does:

Python 3.13.0a1+ (heads/main:e5dfcc2b6e, Nov 15 2023, 17:23:51) [MSC v.1932 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information.

from dataclasses import dataclass class Vanilla: ... def set_name(self, owner, name): ... self.name = name ... @dataclass ... class Foo: ... v: Vanilla = Vanilla() ... f = Foo() f.v.name 'v'

serhiy-storchaka

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure that __set_name__ should be called for annotated fields.

@AlexWaygood

I am not sure that __set_name__ should be called for annotated fields.

Yes, I could be persuaded either way there.

JelleZijlstra

setattr(nm_tpl, key, val)
try:
set_name = type(val).__set_name__
except AttributeError:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth adding a test for the case where this yields some other exception (e.g. due to a weird metaclass)?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Seems like for normal classes, if any strange exception is raised when trying to lookup __set_name__, the interpreter just swallows it and moves on:

class Meta(type): ... def getattribute(self, attr): ... if attr == "set_name": ... raise BaseException("NO") ... class VeryAnnoying(metaclass=Meta): pass ... class Foo: ... attr = VeryAnnoying() ...

We should do the same here (though I don't want to swallow BaseExceptions, since that would catch KeyboardInterrupt, SystemExit, etc. -- I think I'll just use except Exception).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like for normal classes, if any strange exception is raised when trying to lookup __set_name__, the interpreter just swallows it and moves on:

It looks like a bug. I do not think it should be reproduced here. It is better to fix it for normal classes.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I opened #112453, and will revert the changes made here that reproduce the bug

@AlexWaygood @JelleZijlstra

Co-authored-by: Jelle Zijlstra jelle.zijlstra@gmail.com

@AlexWaygood

AlexWaygood

@AlexWaygood

JelleZijlstra

@AlexWaygood

@AlexWaygood

@AlexWaygood

@AlexWaygood

…et_name__`"

This reverts commit 1909fd5.

@AlexWaygood

serhiy-storchaka

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Few minor suggestions which you can ignore.

@AlexWaygood

@AlexWaygood

@AlexWaygood

netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request

Dec 11, 2023

@0-wiz-0

Release 4.9.0 (December 9, 2023)

This feature release adds typing_extensions.ReadOnly, as specified by PEP 705, and makes various other improvements, especially to @typing_extensions.deprecated().

There are no changes since 4.9.0rc1.

Release 4.9.0rc1 (November 29, 2023)

aisk pushed a commit to aisk/cpython that referenced this pull request

Feb 11, 2024

…d inside a typing.NamedTuple class dictionary as part of the creation of that class (python#111876)

Co-authored-by: Jelle Zijlstra jelle.zijlstra@gmail.com

Glyphack pushed a commit to Glyphack/cpython that referenced this pull request

Sep 2, 2024

…d inside a typing.NamedTuple class dictionary as part of the creation of that class (python#111876)

Co-authored-by: Jelle Zijlstra jelle.zijlstra@gmail.com