-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expose Info keys as attributes with scikit-learn's Bunch syntax #9767
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
Conversation
|
@larsoner I've checked everything I had in mind. This change makes it possible to add input checks for assignments of attributes with |
|
I didn't follow the discussion, but I'm very against offering TWO ways to get the same info value. This will lead to confusion. If we believe that dict-style indexing with square brackets is not good, we should entirely abandon it, not add an alternative method while keeping the old one in place. Also I'm absolutely not a fan of So unless I'm missing something essential here, this is a clear –5 from me. |
Did you read the entire discussion in #9752 and the linked issues? I thought the reasons for sticking with Bunch/dict subclass and backward compat with |
Reading up now, as I probably should've done earlier 😅 |
Ok now I did, but my concerns are not addressed there:
To address the 2nd issue, if Maybe we can discuss this during the next office hour. My personal preference right now would clearly be a dataclass. |
|
@hoechenberger To build upon your comment, the goal is to provide a way to implement error checking for the attributes, in the future. Note that in this PR, I did not change the inheritance of Indeed, you now have 2 alternatives approaches to do the same thing. In my opinion, the I'm not sure about |
|
And you are right, setting the attribute in a similar way to |
|
Thanks for taking the time to look into this and for your explanations, @mscheltienne! I'll need to think a bit about potential approaches and their pros/cons before I can continue this discussion. But I'd like to say that I appreciate the attempts to rethink and challenge existing designs in order to make things more approachable and modern! |
|
I haven't thought about this before, but I agree with @hoechenberger that having two ways to access the underlying data will be confusing (and it doesn't matter if one is public and the other private). |
I also agree having two (attribute and With this in mind, given how much people want attribute access, I'm okay with the potential confusion of having two ways of doing things -- I think clear documentation of the class is good enough to mitigate this here, and I think the confusion level here will be small to begin with. We say "attribute access is preferred, but But I'm also okay with dropping the idea of attribute-based access altogether if people see that as not a big enough win in itself to offset the two-way-to-do-one-thing issue.
This is the same as in Along those lines (in addition to the above) regarding moving to some new base class like FWIW tab completion already works for Bunch in IPython and plain Python, so I think this is less critical than it would seem, especially because there are only a handful of attributes of this class that users should actually need to modify at all. (For something like |
|
Thanks for summarizing the issues @larsoner. I think the original issue was not to create/add attribute access, but to perform error checking. I am not a fan of |
It comes up from time to time, to list a few:
There are probably others.
Yes, and we probably should at least give this a shot. I don't think this is so controversial because we can try some variant of it regardless of the user-facing access methods. |
|
Correct me if I'm wrong, but writing a custom Example: (a bit extreme with the raising of an error) With this simple example, how do you get As @larsoner stated, getting rid of the item-based access is not an option, as it will break way too much code and the compensation is too thin. This is why I am leaning towards making the dictionary access the private API for backward compatibility and for internal operations while adding a new public API in the form of attributes or properties. |
You create a new frozen |
"We" (~Paris-based MNE folks) suggest new users use VS Code, which would use Pylance for static analysis and completion suggestions. So this is an issue for us / our users 😅 |
|
Gosh, I should be careful what I post on github :) Can't recall the context of the original discussion. But agree with the feelings expressed here that the API is really old and should not be broken. I may have really old scripts that will stop working if that happens. The only real complain I've seen folks have about MNE at Martinos is that the API changes too often and breaks old scripts. The dictionary vs class debate is something I've struggled with myself in other packages (e.g., HNN). While class is often neater, it's hard to foresee as we're often inheriting legacy code. The nice thing about |
|
I didn't have time to discuss this further last Friday, and surprisingly no one wanted to engage this polemic subject 😅, but here is a quick recap to either close this or keep it moving: Goals:
Musts:
Ideas:
Pros/ConsPros:
Cons:
Pros/ConsPros:
Cons:
Pros/ConsPros:
Cons:
Pros/ConsPros:
Cons:
This is not exhaustive, if I forgot anything or made a mistake, please add it/correct it. |
|
Thanks for the nice summary @mscheltienne! I don't understand what "Push either the private or public API outside the current Otherwise, it looks like option 3 could be a good compromise – the |
|
@cbrnr IMO, and I might be wrong, you need an access door with error checking for users, and another without error checking for MNE functions and internal operations. @hoechenberger suggested creating a new frozen info object (for users?), I am not sure how this would play out, maybe he can explain it further? |
Why would you need that? |
This is only if you want read-only properties as you suggested in your example. I don't think we need those, though. |
|
Exactly for that, read-only access from a user perspective. If we don't need it, all the better. |
|
So what are the options if we want to keep dict access and not add attribute access in addition? I'd be strongly in favor of having only one API, and that needs to be dict access for compatibility. Options 2 and 3? |
|
@cbrnr Yes, 2 and 3 don't add an API. |
|
It might be possible to do (2) in a way that isn't terrible: Then we internally/privately use |
I like this proposal, though I would make the method/context manager |
|
@hoechenberger @cbrnr @jasmainak What are your thoughts about @larsoner proposal? |
|
Sounds good to me! |
|
I like it! How are we going to handle keys that are always unlocked? E.g., |
|
@jasmainak With a check in |
|
Everyone seems to be fine with the proposition by @larsoner #9767 (comment) |
Following the discussion on #9752 and the quick testing in #9757 followed by a git CLI mess up; here is a clean version exposing the keys of Info as attributes in a similar way to Bunch. Instead of inheriting from Bunch; or changing the Bunch from MNE to the version of scikit-learn, I simply brought the methods
__setattr__and__getattr__from scikit-learn's Bunch to the Info class.