Skip to content

RF: remove imageopener decorator #361

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

Merged
merged 3 commits into from
Oct 24, 2015

Conversation

effigies
Copy link
Member

Popping this up from @matthew-brett's fork off #329.

Pros for the decorator:

  • Adding allowed valid_exts and specifying how it should be opened happen in
    the same place (decorator at top of class);
  • Using a decorator allows change of internal storage of the ImageOpener
    class.

Cons:

  • Decorators can be hard to read, especially when the decorator is a function
    call (so the decorator returns a decorator);
  • It's hard to see at a glance which extensions are valid, because the
    decorator is at the top of the class, and adds later to valid_exts,
    whereas the apparent definition of valid_exts is after the docstring;
  • The decorator has to know about the internals of the class (in this case,
    the valid_exts attribute);
  • The role of the decorator is to signal that a certain extension has to be
    opened in a certain way, but it seems a bit odd that this signal also adds
    the extension to the class. To me it seems more natural to make this signal
    a line of its own, next to the valid_exts definition;
  • Modifying the ImageOpener dictionary directly doesn't stop us from making
    the dictionary a property or another object type, and changing the
    underlying storage;
  • No decorator means less code.

@bcipolli
Copy link
Contributor

Looks OK to me. My only concern is exposing ImageOpener details to images.

What about just calling ImageOpener.register_ext_from_image('.mgz', ImageOpener.gz_def) as a function where you do the assignment now?

@effigies
Copy link
Member Author

I don't feel very strongly either way, so I think it's good that you popped in.

That does seem to be a decent compromise between either ImageOpener needing to know about image class internals, or image classes needing to know about ImageOpener internals. That said, dictionaries are simple. It's a question of an indirect f(x, y) vs d.__setitem__(x, y).

To my mind a function makes sense if you want a constraint. For instance, we currently disallow setting an entry twice, which this PR does not preserve. If that's worth keeping, then I'd say we go ahead with a lightweight wrapper around compressed_ext_map.__setitem__, named something like register_compressed_ext.

@matthew-brett
Copy link
Member

matthew-brett commented Oct 20, 2015 via email

@bcipolli
Copy link
Contributor

@matthew-brett After further review, I think you're right. I'm still not used to overriding operators in Python, it seems!

LGTM thanks!

@effigies
Copy link
Member Author

Will note again that we're losing the non-overwrite constraint, but if you're both okay with that, I'm okay with that.

@bcipolli
Copy link
Contributor

Fine with me!

@effigies
Copy link
Member Author

Removed an unused line and adapted the usage docs from the decorator to the class itself.

@effigies effigies force-pushed the remove-imageopener-decorator branch from 68a035a to 212076f Compare October 23, 2015 16:33
matthew-brett and others added 3 commits October 23, 2015 12:33
I was finding the decorator for ImageOpener confusing.

Pros for the decorator:

* Adding allowed `valid_exts` and specifying how it should be opened happen in
  the same place (decorator at top of class);
* Using a decorator allows change of internal storage of the ImageOpener
  class.

Cons:

* Decorators can be hard to read, especially when the decorator is a function
  call (so the decorator returns a decorator);
* It's hard to see at a glance which extensions are valid, because the
  decorator is at the top of the class, and adds later to `valid_exts`,
  whereas the apparent definition of `valid_exts` is after the docstring;
* The decorator has to know about the internals of the class (in this case,
  the `valid_exts` attribute);
* The role of the decorator is to signal that a certain extension has to be
  opened in a certain way, but it seems a bit odd that this signal also adds
  the extension to the class.  To me it seems more natural to make this signal
  a line of its own, next to the `valid_exts` definition;
* Modifying the ImageOpener dictionary directly doesn't stop us from making
  the dictionary a property or another object type, and changing the
  underlying storage;
* No decorator means less code.
``func_def`` is a `(function, (args,))` tuple, where `function accepts a
filename as the first parameter, and `args` defines the other arguments
that `function` accepts. These arguments must be any (unordered) subset of
`mode`, `compresslevel`, and `buffering`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice docstring.

@bcipolli
Copy link
Contributor

Re-reviewed, still LGTM!

effigies added a commit that referenced this pull request Oct 24, 2015
RF: remove ImageOpener decorator

Image classes should directly update the ImageOpener.compress_ext_map dictionary.
@effigies effigies merged commit 598b739 into nipy:master Oct 24, 2015
@effigies effigies deleted the remove-imageopener-decorator branch October 24, 2015 17:43
grlee77 pushed a commit to grlee77/nibabel that referenced this pull request Mar 15, 2016
RF: remove ImageOpener decorator

Image classes should directly update the ImageOpener.compress_ext_map dictionary.
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

Successfully merging this pull request may close these issues.

3 participants