-
Notifications
You must be signed in to change notification settings - Fork 192
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
Fix behavior of RemoteData.getfile() #3742
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @Crivella and welcome to the aiida-core contributors!
I have just one small suggestion - to adapt also the first line of the docstring.
aiida/orm/nodes/data/remote.py
Outdated
:return: a string with the file content | ||
:param relpath: The relative path of the file on the remote to retrieve. | ||
:param destpath: The absolute path of the copied/retrieved file on the local machine. | ||
:return: a list containing the file names in 'destpath' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, this seems to be what it is doing...
@giovannipizzi Is there a good reason for doing that (e.g. potentially returning the names of files that have nothing to do with the one that was just transferred?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @Crivella
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just coming back to this - it seems I didn't look at this properly, and you are actually pointing out a bug here, right?
The getfile
is currently not doing what its name (or the first comment line) are advertising and needs to be fixed.
It looks to me like one needs to add a return
before t.getfile(full_path, destpath)
:
aiida-core/aiida/orm/nodes/data/remote.py
Lines 67 to 79 in 0644e7d
with t: | |
try: | |
full_path = os.path.join(self.get_remote_path(), relpath) | |
t.getfile(full_path, destpath) | |
except IOError as e: | |
if e.errno == 2: # file not existing | |
raise IOError('The required remote file {} on {} does not exist or has been deleted.'.format( | |
full_path, self.computer.name | |
)) | |
else: | |
raise | |
return t.listdir() |
And if the file is not found, the function already raises an IOError, so you should not need to return anything else.
Do you want to fix this or should I do it myself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @Crivella !
This looks like the correct way to fix this.
Actually as of know this method would have the double behaviour of copying the file to the local machine and returning its content as a string. I'm not sure if it would be better to split this two into separate methods. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for pointing this out.
It turns out that copying the file is actually the only thing it does
aiida-core/aiida/transports/plugins/local.py
Lines 465 to 492 in 66b6f6a
def getfile(self, remotepath, localpath, *args, **kwargs): | |
""" | |
Copies a file recursively from 'remote' remotepath to | |
'local' localpath. | |
:param remotepath: path to local file | |
:param localpath: absolute path to remote file | |
:param overwrite: if True overwrites localpath. | |
Default = False | |
:raise IOError if 'remote' remotepath is not valid or not found | |
:raise ValueError: if 'local' localpath is not valid | |
:raise OSError: if unintentionally overwriting | |
""" | |
overwrite = kwargs.get('overwrite', args[0] if args else True) | |
if not localpath: | |
raise ValueError('Input localpath to get function must be a non empty string') | |
if not remotepath: | |
raise IOError('Input remotepath to get function must be a non empty string') | |
the_source = os.path.join(self.curdir, remotepath) | |
if not os.path.exists(the_source): | |
raise IOError('Source not found') | |
if not os.path.isabs(localpath): | |
raise ValueError('Destination must be an absolute path') | |
if os.path.exists(localpath) and not overwrite: | |
raise OSError('Destination already exists: not overwriting it') | |
shutil.copyfile(the_source, localpath) |
i.e.
t.getfile
actually does not return anything.
Since the method of RemoteData
is called getfile
as well, I would suggest that its behavior should actually be the same as the getfile
of the transport - i.e. not return anything.
Anyhow, let's wait for @giovannipizzi to comment on this , whom you tagged in the PR originally.
Sorry for these confusing interaction from my side (I never actually used this function and should really have paid closer attention).
That none of these changes caused any tests to fail also seems to indicate that this function is currently untested.
Hi all. More generally, let's discuss in #1857 if we want to keep these functions or how to make it clear that they open an transport and you do not want to do this in a workflow (see also #3478 ) |
Co-Authored-By: Leopold Talirz <leopold.talirz@gmail.com>
@giovannipizzi Please review. |
Codecov Report
@@ Coverage Diff @@
## develop #3742 +/- ##
===========================================
- Coverage 77.17% 77.17% -0.01%
===========================================
Files 457 457
Lines 33775 33774 -1
===========================================
- Hits 26066 26065 -1
Misses 7709 7709
Continue to review full report at Codecov.
|
Thanks guys, I will merge another PR first that is already good to go and will then update this and merge it |
Ok, the other PR has problems with the tests, so I will merge this first after all |
The :return: value in the documentation was not correct.