Skip to content

Commit

Permalink
Implement next and iter for the Node.open deprecation wrapper (#…
Browse files Browse the repository at this point in the history
…4399)

The return value of `Node.open` was wrapped in `WarnWhenNotEntered` in
`aiida-core==1.4.0` in order to warn users that use the method without a
context manager, which will start to raise in v2.0. Unfortunately, the
raising came a little early as the wrapper does not implement the
`__iter__` and `__next__` methods, which can be called by clients.

An example is `numpy.getfromtxt` which will notice the return value of
`Node.open` is filelike and so will wrap it in `iter`. Without the
current fix, this raises a `TypeError`. The proper fix would be to
forward all magic methods to the wrapped filelike object, but it is not
clear how to do this.
  • Loading branch information
sphuber authored Sep 25, 2020
1 parent 0184518 commit 5e1c6fd
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
6 changes: 6 additions & 0 deletions aiida/orm/nodes/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ def __getattr__(self, key):
def __del__(self):
self._warn_if_not_entered('del')

def __iter__(self):
return self._fileobj.__iter__()

def __next__(self):
return self._fileobj.__next__()

def read(self, *args, **kwargs):
self._warn_if_not_entered('read')
return self._fileobj.read(*args, **kwargs)
Expand Down
18 changes: 18 additions & 0 deletions tests/orm/node/test_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
###########################################################################
# pylint: disable=too-many-public-methods
"""Tests for the Node ORM class."""
import io
import os
import tempfile

Expand Down Expand Up @@ -842,3 +843,20 @@ def test_store_from_cache():
assert clone.is_stored
assert clone.get_cache_source() == data.uuid
assert data.get_hash() == clone.get_hash()


@pytest.mark.usefixtures('clear_database_before_test')
def test_open_wrapper():
"""Test the wrapper around the return value of ``Node.open``.
This should be remove in v2.0.0 because the wrapper should be removed.
"""
filename = 'test'
node = Node()
node.put_object_from_filelike(io.StringIO('test'), filename)

# Both `iter` and `next` should not raise
next(node.open(filename))
iter(node.open(filename))
node.open(filename).__next__()
node.open(filename).__iter__()

0 comments on commit 5e1c6fd

Please sign in to comment.