Skip to content

Attribute without type hint in slotted class can't be changed #1173

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 and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rklasen opened this issue Aug 11, 2023 · 4 comments
Closed

Attribute without type hint in slotted class can't be changed #1173

rklasen opened this issue Aug 11, 2023 · 4 comments

Comments

@rklasen
Copy link

rklasen commented Aug 11, 2023

Hi, so I've just stumbled over something I assume is a misunderstanding on my part, but I want to ask to be sure.

I have a slotted class without type hints:

@define
class Scenario:
    momentum = 0.0
    trackDirectory: Path = Path()

From the default value of 0.0 I assumed attrs would infer the type of momentum, but when I try to change the value, I get an error:

>>> scen = Scenario(trackDirectory=".")
>>> scen.momentum = 15.09
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Scenario' object attribute 'momentum' is read-only
>>> type(scen.momentum)
<class 'float'>

So the type is a float as expected, but I can not change the value of momentum.


But when I add a type hint:

@define
class Scenario:
    momentum: float = 0.0
    trackDirectory: Path = Path()

All works as expected:

>>> scen = Scenario(trackDirectory=".")
>>> scen.momentum = 15.09
>>> type(scen.momentum)
<class 'float'>

So, is this expected/desired behavior and I'm just misunderstanding something? Thanks in advance!

@hynek
Copy link
Member

hynek commented Aug 15, 2023

attrs never infers the type from a value. If you set an attribute to a value (that's not an attrs.field/attr.ib), it's ignored by attrs and it becomes a class variable that can't be changed with slotted classes.

@rklasen
Copy link
Author

rklasen commented Aug 15, 2023

Oh, I see. So is my workflow even recommended, or should I always explicitly call

@define
class Scenario:
    momentum: float = field(default=0.0)
    trackDirectory: Path = Path()

I do like the shorter version for readability, but I don't want to rely on UNintended features.

edit: meant to say UNintended

@hynek
Copy link
Member

hynek commented Aug 15, 2023

No, you can write momentum: float = 0.0, I'm sorry for being unclear.

Attrs picks up everything that is either annotated (except ClassVar) or is assigned a field.

@rklasen
Copy link
Author

rklasen commented Aug 15, 2023

Okay, good to know I can keep the short version. Thanks for the help!

@rklasen rklasen closed this as completed Aug 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants