jbardin / scp.py

scp module for paramiko

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

_recv_popd() assert self._depth > 0 when self._rename?

alanbchristie opened this issue · comments

I'm using the tej module (https://github.com/VisTrails/tej.git) and I'm encountering this assertion when recursively copying files back from a remote server. The section of the tej code that causes the assert calls get() like this: -

scp_client.get(str(target / filename),
               str(destination / filename),
               recursive=recursive)

All the files in the remote location exist in the named directory and there are no sub-directories. I'm just copying all files from a remote directory.

Interestingly the files are copied successfully but the get() fails because it asserts in _recv_popd().

As I have no control of the the internal variable that's being asserted (_depth) I'm wondering how scp gets into this state.

Having looked at the module's source I see that the _depth that's being asserted is incremented in _recv_pushd() but not if self._rename is initially True (lines 473-475). So it looks like we can successfully traverse _recv_pushd() without incrementing _depth. Is that right? If so is the assertion in _recv_popd() correct? If you can get through _recv_pushd() without a depth increment shouldn't _recv_popd() simply check _depth and handle the case where it's zero?

The reason I don't update _depth when getting pushd with _rename is because no directory change actually happen, so popd shouldn't come up one level (that would allow the server to write a file dir/b when you are doing get(remote_path, "dir/a"). Maybe I can allow _depth=-1 to happen (but no command once you're there)?

Another solution like you said is to do nothing if depth == 0 in _recv_popd() 🤔

I think I have found the missing test that covers your situation: b8e4c6e, I will add a fix.

Super, thanks for the rapid feedback. I dislike the idea of _depth = -1. That just sounds wrong. Beautiful software has symmetry so if you think that doing nothing if depth == 0 makes sense then maybe that's the solution.