Almost two months since the last release, and with reason: I've been working hard to define remote()'s semantics. So far this is what there is:

  • Global and current scope's local variables can be used in the remote code. This includes envvars.
  • Changes to the local variables return to the local code.
  • Execution is done synchronously.

What this means is that if we had the following code:

[block 1]
with remote (...):
    [block 2]
[block 3]

we have the following:

  • Variables in block 1's scope are visible in block 2.
  • Modification to the local scope in block 2 are visible in block 3.
  • block 3 does not start executing until block 2 has finished.

This imposes some limitations on how we can communicate with the remote code. As it is synchronous, we can't expect to be able to send and receive data from block 3, so the previous way of communicating with paramiko's streams is no longer possible. On the other hand, stdin, stdout and stderr are not transmitted yet between the local and the remote, which means that actually no communication is posible right now except via variables.

Also, because of the way remote() is implemented, currently functions, classes and modules that are going to be used in the remote code must be declared/imported there.

Finally, exceptions raised in the remote code will be reraised in the local code. This two things together mean that any custom exception in the script must be declared twice if they're raised in the remote :(.

But all in all I'm happy with the new, defined semantics. I worked a lot to make sure the first two points worked properly. It took me a while to figure out how to do the changes to the scope's locals after the new values were returned from the remote. I know this is a very specific use case, but if you're interested, here's the thread were Armin Rigo tells me how it's done. You might also be interested in Yaniv Ankin's Python innards.

Finally, check the full ChangeLog:

  • Great improvements in remote()'s API and sematics
    • Made sure local variables go to and come back from the remote.
    • Code block is executed synchronously.
    • For the moment the streams are no longer returned.
    • _python_only option is gone.
    • Most tests actually connect to a listening netcat, only one test uses ssh.
  • Fixed bugs in the new parser.
  • Fixed globals/locals mix up.
  • Scripts are no longer wrapped in a function. This means that you can't return values and that module semantics are restored.
  • ayrton exits with status 1 when the script fails to run (SyntaxError, etc).

More fun times are coming!

Get it on github or pypi!

python ayrton