Skip to content

RF: Circumvents a deprecation warning from np.fromstring #702

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
wants to merge 7 commits into from

Conversation

arokem
Copy link
Member

@arokem arokem commented Dec 17, 2018

I am seeing this warning:

/Users/arokem/.virtualenvs/afq/lib/python3.7/site-packages/nibabel/streamlines/trk.py:562: DeprecationWarning: The binary mode of fromstring is deprecated, as it behaves surprisingly on unicode inputs. Use frombuffer instead
  header_rec = np.fromstring(string=header_str, dtype=header_2_dtype)

I believe this PR fixes that.

@effigies
Copy link
Member

Thanks. Looks like frombuffer() has the same API back at least to our minimum numpy, so this seems reasonable. I think there's a chance you'll have trouble setting the write flag on the pre-release numpy, so we might not be done yet.

Any chance you could swap out numpy.fromstring() in the rest of the codebase, while you're at it?

@arokem
Copy link
Member Author

arokem commented Dec 17, 2018 via email

@coveralls
Copy link

coveralls commented Dec 17, 2018

Coverage Status

Coverage increased (+0.002%) to 91.83% when pulling 6924a56 on arokem:fromstring_deprecation into 3652f16 on nipy:master.

@arokem
Copy link
Member Author

arokem commented Dec 17, 2018

As anticipated, pre-release numpy doesn't allow setting this array to writeable. Do you know if there is any fix to this?

@effigies
Copy link
Member

You'll need to readinto some read-write object, such as a bytearray. See discussions in #697, #700.

@codecov-io
Copy link

codecov-io commented Dec 17, 2018

Codecov Report

Merging #702 into master will increase coverage by 0.03%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #702      +/-   ##
==========================================
+ Coverage   88.85%   88.88%   +0.03%     
==========================================
  Files          93       93              
  Lines       11454    11452       -2     
  Branches     1894     1892       -2     
==========================================
+ Hits        10177    10179       +2     
+ Misses        936      933       -3     
+ Partials      341      340       -1
Impacted Files Coverage Δ
nibabel/openers.py 76.85% <100%> (+0.38%) ⬆️
nibabel/gifti/parse_gifti_fast.py 84.51% <100%> (ø) ⬆️
nibabel/streamlines/trk.py 94.31% <100%> (+0.01%) ⬆️
nibabel/nifti1.py 91.22% <100%> (ø) ⬆️
nibabel/info.py 100% <0%> (ø) ⬆️
nibabel/viewers.py 96.66% <0%> (+1.25%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3652f16...6924a56. Read the comment docs.

@arokem
Copy link
Member Author

arokem commented Dec 17, 2018

OK. I believe that remaining appearances of fromstring are not of the deprecated kind.

Copy link
Member

@effigies effigies left a comment

Choose a reason for hiding this comment

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

Great! Thanks. We can be a little more efficient with the TrkFile header.

As for the other calls, as long as tests pass and coverage hits them, I think we should be safe.

@@ -559,8 +559,8 @@ def _read_header(fileobj):

# Read the header in one block.
header_str = f.read(header_2_dtype.itemsize)
header_rec = np.fromstring(string=header_str, dtype=header_2_dtype)

header_rec = np.frombuffer(buffer=bytearray(header_str),
Copy link
Member

Choose a reason for hiding this comment

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

This still makes a copy from header_str to bytearray(header_str). Instead, we can create a bytearray and read directly into it:

            header_buf = bytearray(header_2_dtype.itemsize)
            n_read = f.readinto(header_buf)
            # Maybe if n_read != header_2_dtype.itemsize: raise HeaderError(...)
            header_rec = np.frombuffer(buffer=header_buf, dtype=header_2_dtype)

@arokem
Copy link
Member Author

arokem commented Dec 17, 2018 via email

@arokem
Copy link
Member Author

arokem commented Dec 17, 2018 via email

@@ -209,6 +209,9 @@ def fileno(self):
def read(self, *args, **kwargs):
return self.fobj.read(*args, **kwargs)

def readinto(self, *args, **kwargs):
return self.fobj.readinto(*args, **kwargs)

Copy link
Member

Choose a reason for hiding this comment

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

Oh, nice. I hadn't realized we didn't already have this...

@arokem
Copy link
Member Author

arokem commented Dec 18, 2018 via email

@effigies
Copy link
Member

I think this function is as close as we come to fully testing the API for equivalence:

def test_file_like_wrapper():
# Test wrapper using BytesIO (full API)
message = b"History of the nude in"
sobj = BytesIO()
fobj = Opener(sobj)
assert_equal(fobj.tell(), 0)
fobj.write(message)
assert_equal(fobj.tell(), len(message))
fobj.seek(0)
assert_equal(fobj.tell(), 0)
assert_equal(fobj.read(6), message[:6])
assert_false(fobj.closed)
fobj.close()
assert_true(fobj.closed)
# Added the fileobj name
assert_equal(fobj.name, None)

@arokem
Copy link
Member Author

arokem commented Dec 18, 2018

Looks like we have similar issues in other places as well. Let me see if I can use similar approaches in these other places as well...

@effigies
Copy link
Member

Awesome, thanks. In #700, I'll be fixing the volumeutils piece to use bz2file, which implements readinto and should take care of that one, but the TCK and TRK ones could use your attention.

@arokem
Copy link
Member Author

arokem commented Dec 18, 2018

OK. I'll look into those.

@arokem
Copy link
Member Author

arokem commented Dec 26, 2018

Sorry: I have not been able to resolve these other spots and might not have time to work on this any time soon. If it's OK, I would suggest merging this one, and then keep working on the other ones on another PR.

```
/Users/arokem/.virtualenvs/afq/lib/python3.7/site-packages/nibabel/streamlines/trk.py:562: DeprecationWarning: The binary mode of fromstring is deprecated, as it behaves surprisingly on unicode inputs. Use frombuffer instead
  header_rec = np.fromstring(string=header_str, dtype=header_2_dtype)
```
This is because newer numpy doesn't allow to change the writeable flag.
@arokem arokem force-pushed the fromstring_deprecation branch from a696d0d to 6924a56 Compare December 26, 2018 21:18
@effigies
Copy link
Member

@arokem I've merged your branch into #700, as I needed some of your improvements to finish the job. Should be just about ready to merge over there. This PR will automatically close when that one is merged.

@arokem
Copy link
Member Author

arokem commented Dec 29, 2018

That's great. Thanks!

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.

4 participants