-
Notifications
You must be signed in to change notification settings - Fork 48
Various improvements to provisional.py #387
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[tool.black] | ||
line-length = 79 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not inherently opposed to this, but neither me nor Erik are using Black. You are free to use it, of course -- but enshrining it into the repo feels a bit much. The only one style guide DMLC is beholden to is Intel's own. I'd be OK with you putting There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't know about Black before. I'm open to try enforcing it for the DMLC repo, but it doesn't belong to this PR. More specifically: Feel free to blackify all python files in the DMLC repo. The repo is small enough that we probably can sweep through the diff manually and see if it's a net win. If it is, then let's pioneer it by enforcing it with a test. |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a significant knee-jerk dislike of this. Why do this instead of
stable = True
, etc. -- what's the benefit?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See microsoft/pyright#5564
As I understand it, it's how properties are supposed to be overridden.
@abstractproperty
is a deprecated way of defining a read-only property which has been replaced with the syntax:@property @abstractmethod
. ( https://docs.python.org/3/library/abc.html#abc.abstractproperty )Since it's a property, it needs to be overridden in subclasses. If assigned using = I think you are instead replacing the read-only property with an attribute which is read-write.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From that thread:
Buh. I really want to keep my
stable = True
syntax; if there is no go-to way to express mandatory class variables, we have to roll our own. I guess we could do that infeature
. Something like:@mandolaerik Your opinion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. Consider:
In X,
foo
is available on class level, in Y the value is only available from the instance. You can sayX.foo = 2
to change the class member, and you can shadow the class member in one specific instance byX().foo = 3
. In Y, you can also change the class member,Y.foo = 4
.Y().foo
is indeed a read-only expression, in the sense thatY().__setattr__
rejectsfoo
. However, the same is true for X if you seal the set of members through e.g.__slots__
.So, if you insist that properties are kept read-only on instance level, then use
__slots__
or equivalent (e.g.dataclass
). Or, if you want hard guarantees that thiings you intend as immutable stay immutable, then don't use Python.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I get it now. You are only using these classes at the class level, not as instances. I didn't realize. In that case my change is indeed incorrect. Also in that case, I think the second part of the comment quoted is applicable:
I have to read up on Protocol before I have an opinion on that. Assuming you want to keep the code as is, however, then I would like to turn the question around: Why do you declare these class members as properties in the abstract base class? To cause an error if a subclass forgets to override them, e.g. because the property is not printable?
Erik, in you example:
Y.foo is now an int and the original property is no more. It has ceased to exist. It is a late property. If this is the expected use of the abstract base class, then why declare a property in the first place?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My point with Y.foo=2 is that python is hopelessly dynamic: even though the property is read-only in one sense, it's still possible to lift that protection. Nothing is truly protected. In particular, you might say:
with the intention that overrides should be read-only as in:
but Python will happily swallow if someone says
Thus, a user of
X
does not have an immutability guarantee onfoo
.