Skip to content
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

ENH: Make layout order an initialization parameter of ArrayProxy #1131

Merged
merged 8 commits into from
Sep 7, 2022

Conversation

effigies
Copy link
Member

For #1090, it's been useful to set the proxy order dynamically, rather than subclassing ArrayProxy. This makes it an initialization argument. I've left it as a class variable on the off-chance that somebody actually uses something like:

class CArrayProxy(ArrayProxy):
    order = 'C'

Minor in-passing cleanups, such as removing the explicit (object) superclass and moving the test loops to parametrizations.

@codecov
Copy link

codecov bot commented Aug 20, 2022

Codecov Report

Merging #1131 (cff42d6) into master (fd5c84b) will increase coverage by 0.00%.
The diff coverage is 100.00%.

@@           Coverage Diff           @@
##           master    #1131   +/-   ##
=======================================
  Coverage   91.80%   91.80%           
=======================================
  Files         101      101           
  Lines       12445    12454    +9     
  Branches     2430     2433    +3     
=======================================
+ Hits        11425    11434    +9     
  Misses        693      693           
  Partials      327      327           
Impacted Files Coverage Δ
nibabel/arrayproxy.py 100.00% <100.00%> (ø)

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@effigies effigies force-pushed the enh/arrayproxy_order branch from 6da2600 to 24b8507 Compare August 20, 2022 17:27
@effigies
Copy link
Member Author

Anybody up for a review?

@matthew-brett
Copy link
Member

Will do, tomorrow ...

Copy link
Member

@matthew-brett matthew-brett left a comment

Choose a reason for hiding this comment

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

Hmm - I see what you mean, but the interface is now a bit clunky, because there are two ways to override the order. I guess the most direct interface would be to make the class variable be default_order. Is there a good way of going there without breaking people's code?

nibabel/arrayproxy.py Outdated Show resolved Hide resolved
fobj.write(arr.tobytes(order='F'))
prox = ArrayProxy(fobj, hdr)
sliceobj = (None, slice(None), 1, -1)
assert_array_equal(arr[sliceobj] * 2.0 + 1.0, prox[sliceobj])


@pytest.mark.parametrize("order", ("C", "F"))
Copy link
Member

Choose a reason for hiding this comment

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

Also test order=None?

Copy link
Member Author

Choose a reason for hiding this comment

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

Does not work for fobj.write(arr.tobytes(order=order)) (currently L198). This is testing override specifically, so I'm not sure "use default" is really relevant.

@effigies
Copy link
Member Author

Hmm - I see what you mean, but the interface is now a bit clunky, because there are two ways to override the order. I guess the most direct interface would be to make the class variable be default_order. Is there a good way of going there without breaking people's code?

Could change order to default_order, and then look for an order class variable (hasattr(self.__class__, "order")) in __init__ and raise a DeprecationWarning.

@effigies effigies force-pushed the enh/arrayproxy_order branch from b7c179c to 8acd26f Compare August 31, 2022 13:54
@matthew-brett
Copy link
Member

Could change order to default_order, and then look for an order class variable (hasattr(self.__class__, "order")) in __init__ and raise a DeprecationWarning.

Nice idea.

@effigies effigies force-pushed the enh/arrayproxy_order branch from 8acd26f to dcf9566 Compare August 31, 2022 15:10
@effigies
Copy link
Member Author

effigies commented Sep 7, 2022

Matthew, any further comments?

Copy link
Member

@matthew-brett matthew-brett left a comment

Choose a reason for hiding this comment

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

Oops - sorry - some of these I forgot to add in another review.

nibabel/arrayproxy.py Outdated Show resolved Hide resolved
nibabel/arrayproxy.py Outdated Show resolved Hide resolved
'to avoid conflict with instance variables.\n'
'* deprecated in version: 5.0\n'
'* will raise error in version: 7.0\n',
DeprecationWarning, stacklevel=2)
Copy link
Member

Choose a reason for hiding this comment

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

I forget the mechanism to time out the deprecation warning ... but shouldn't we put that in here?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's a decorator that works for deprecating an entire function/method/class. It does not work for cases like this. This is why I added the check below:

_default_order = 'C'


class DeprecatedCArrayProxy(ArrayProxy):
Copy link
Member

Choose a reason for hiding this comment

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

Timed out depraction again (as above)?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is specifically for testing. The warning/expiration will show up in test_deprecated_order_classvar. When we remove that function, we can remove this class. I'll add a comment...

'to avoid conflict with instance variables.\n'
'* deprecated in version: 5.0\n'
'* will raise error in version: 7.0\n',
DeprecationWarning, stacklevel=2)
Copy link
Member Author

Choose a reason for hiding this comment

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

It's a decorator that works for deprecating an entire function/method/class. It does not work for cases like this. This is why I added the check below:

Comment on lines +230 to +234
# Start raising errors when we crank the dev version
if Version(__version__) >= Version('7.0.0.dev0'):
cm = pytest.raises(ExpiredDeprecationError)
else:
cm = pytest.deprecated_call()
Copy link
Member Author

Choose a reason for hiding this comment

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

... here.

_default_order = 'C'


class DeprecatedCArrayProxy(ArrayProxy):
Copy link
Member Author

Choose a reason for hiding this comment

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

This is specifically for testing. The warning/expiration will show up in test_deprecated_order_classvar. When we remove that function, we can remove this class. I'll add a comment...

Copy link
Member

@matthew-brett matthew-brett left a comment

Choose a reason for hiding this comment

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

LGTM ...

@effigies
Copy link
Member Author

effigies commented Sep 7, 2022

Thanks!

@effigies effigies merged commit 2838c06 into nipy:master Sep 7, 2022
@effigies effigies deleted the enh/arrayproxy_order branch September 7, 2022 13:50
@effigies effigies added this to the 5.0.0 milestone Jan 3, 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

Successfully merging this pull request may close these issues.

2 participants