Release Change Log¶
- RPyC 5.0.0 cannot teleport functions to earlier versions
- Deprecated Python 2 support to coincide with it’s EOL
- Server hostname default supports IPv4 and IPv6 by using the wildcard address #425
docker/docker-compose.ymlfor Python 3.6, 3.7, 3.8, 3.9, and 3.10 containers to improve local workflow
- Fixed pickle failure on windows for
- Fixed teleport function behavior for keyword-only arguments with default #422
- Improved documentation on custom exception handling
- Fixed IPv6 support for server #407
- Added a simple asynchrounous service example #400
- Fixed netref.class_factory id_pack usage per #339 and added test cases
- Name pack casted in _unbox to fix IronPython bug. Fixed #337
- Increased chunk size to improve multi-client response time and throughput of large data #329
- Added warning to _remote_tb when the major version of local and remote mismatch (#332)
- OneShotServer termination was fixed by WilliamBruneau (#343)
- Known issue with 3.8 for CodeType parameters (may drop Python2 support first)
- Added connection back-off and attempts for congested workloads
- Fixed minor resource leak for ForkingServer (#304)
- Cross-connection instance check for cached netref classes (#316)
- Hashing fixed (#324)
- New ID Pack convention breaks compatibility between a client/server >= 4.10 with a client/server < 4.10
- fix default hostname for ipv6 in rpyc_classic.py (#277)
- fix ThreadPoolServer not working (#283)
This release brings a few minor backward incompatibilities, so be sure to read on before upgrading. However, fear not: the ones that are most likely relevant to you have a relatively simple migration path.
classic.teleport_functionnow executes the function in the connection’s namespace by default. To get the old behaviour, use
teleport_function(conn, func, conn.modules[func.__module__].__dict__)instead.
- Changed signature of
on_disconnect, adding the connection as argument.
- Changed signature of
Service.__init__, removing the connection argument
- no longer store connection as
self._conn. (allows services that serve multiple clients using the same service object, see #198).
SlaveServiceis now split into two asymetric classes:
MasterService. The slave exposes functionality to the master but can not anymore access remote objects on the master (#232, #248). If you were previously using
SlaveService, you may experience problems when feeding the slave with netrefs to objects on the master. In this case, do any of the following:
ClassicService(acts exactly like the old
configthat allows attribute access etc
rpyc.utils.deliverto feed copies rather than netrefs to the slave
RegistryServer.on_service_removedis once again called whenever a service instance is removed, making it symmetric to
on_service_added(#238) This reverts PR #173 on issue #172.
- Removed module
rpyc.experimental.splitbrain. It’s too confusing and undocumented for me and I won’t be developing it, so better remove it altogether. (It’s still available in the
- Removed module
rpyc.experimental.retunnel. Seemingly unused anywhere, no documentation, no clue what this is about.
bin/rpyc_classic.pywill bind to
SlaveServiceno longer serves exposed attributes (i.e., it now uses
- Exposed attributes no longer hide plain attributes if one otherwise has the required permissions to access the plain attribute. (#165)
What else is new¶
- teleported functions will now be defined by default in the globals dict
- Can now explicitly specify globals for teleported functions
- Can now use streams as context manager
- keep a hard reference to connection in netrefs, may fix some
EOFErrorissues, in particular on Jython related (#237)
- handle synchronous and asynchronous requests uniformly
- fix deadlock with connections talking to each other multithreadedly (#270)
- handle timeouts cumulatively
- fix possible performance bug in
- use readthedocs theme for documentation (#269)
- actually time out sync requests (#264)
- clarify documentation concerning exceptions in
__hash__for netrefs (#267, #268)
async_for py37 compatibility (#253)
deliver()from IronPython to CPython2 (#251)
- fix brine string handling in py2 IronPython (#251)
- add gevent Server. For now, this requires using
gevent.monkey.patch_all()before importing for rpyc. Client connections can already be made without further changes to rpyc, just using gevent’s monkey patching. (#146)
- add function
rpyc.lib.spawnto spawn daemon threads
- fix several bugs in
bin/rpycd.pythat crashed this script on startup (#231)
- fix problem with MongoDB, or more generally any remote objects that have a
- fix bug when copying remote numpy arrays (#236)
rpyc.utils.helpers.classpartialto bind arguments to services (#244)
- can now pass services optionally as instance or class (could only pass as class, #244)
- The service is now charged with setting up the connection, doing so in
Service._connect. This allows using custom protocols by e.g. subclassing
Connection. More discussions and related features in #239-#247.
- service can now easily override protocol handlers, by updating
on_connect. For example:
conn._HANDLERS[HANDLE_GETATTR] = self._handle_getattr.
- most protocol handlers (
Connection._handle_XXX) now directly get the object rather than its ID as first argument. This makes overriding individual handlers feel much more high-level. And by the way it turns out that this fixes two long-standing issues (#137, #153)
- fix bug with proxying context managers (#228)
- expose server classes from
rpyctop level module
- fix logger issue on jython
- Fix refcount leakage when unboxing from cache (#196)
- Fix TypeError when dispatching exceptions on py2 (unicode)
rpyc_protocol_configfor default Service getattr (#202)
- Support unix domain sockets (#100, #208)
- Use first accessible server in
- Fix deadlock problem with logging (#207, #212)
- Fix timeout problem for long commands (#169)
export_functionon python 3.6
Please excuse the briefity for this versions changelist.
- RPyC integrates with plumbum; plumbum is required
for some features, like
rpyc_classic.pyand zero deploy, but the core of the library doesn’t require it. It is, of course, advised to have it installed.
SshTunnelclasses killed in favor of plumbum’s SSH tunneling. The interface doesn’t change much, except that
ssh_connectnow accept a
plumbum.SshMachineinstance instead of
- Zero deploy: deploy RPyC to a remote machine over an SSH connection and form an SSH tunnel connected to it, in just one line of code. All you need is SSH access and a Python interpreter installed on the remote machine.
- Dropping Python 2.4 support. RPyC now requires Python 2.5 - 3.3.
- rpycd - a well-behaved daemon for
rpyc_classic.py, based on python-daemon
OneShotServeris now exposed by
rpyc_classic -m oneshot
Splitbrain Python- running code on remote machines transparently. Although tested, it is still considered experimental.
- Removing the
BgServerThreadand all polling/timeout hacks in favor of a “global background reactor thread” that handles all incoming transport from all connections. This should solve all threading issues once and for all.
MockClassicConnection- a mock RPyC “connection” that allows you to write code that runs either locally or remotely without modification
- Fix (issue #76) for real this time
- Fix issue with
- Fix issue with
- Remove RPyC’s
excepthookin favor of chaining the exception’s remote tracebacks in the exception class’
__str__method. This solves numerous issues with logging and debugging.
- Add UNIX domain sockets (#100)
- Windows: make SSH tunnels windowless (#68)
- Fixes a compatibility issue with IronPython on Mono (#72)
- Fixes an issue with introspection when an
AttributeErroris expected (#71)
- The server now logs all exceptions (#73)
- Forking server: call
siginterrupt(False)in forked child (#76)
- Shutting down the old wikidot site
- Adding Travis CI integration
- Added support for IPv6 (#28)
- Added SSH tunneling support (
- Several fixes to
AsyncResultand weak references
- Added the
- Fixed some minor (harmless) races that caused tracebacks occasionally when server-threads terminated
- Fixes issues #8, #41, #42, #43, #46, and #49.
- Converted all
- Dropped TLSlite integration (#45). We’ve been dragging this corpse for too long.
- New documentation (both the website and docstrings) written in Sphinx
- The site has moved to sourceforge. Wikidot
had served us well over the past three years, but they began displaying way too
many ads and didn’t support uploading files over
rsync, which made my life hard.
- New docs are part of the git repository. Updating the site is as easy as
- The site has moved to sourceforge. Wikidot had served us well over the past three years, but they began displaying way too many ads and didn’t support uploading files over
- Python 3.0-3.2 support
- Supports CPython 2.4-2.7, IronPython, and Jython
- tlslite has been ported to python 2.5-2.7 (the original library targeted 2.3 and 2.4)
- Initial python 3 support – not finished!
- Moves to a more conventional directory structure
- Moves to more standard facilities (
- Solves a major performance issue with the
BgServingThread(#32), by removing the contention between the two threads that share the connection
- Fixes lots of issues concerning the ForkingServer (#3, #7, and #15)
- Many small bug fixes (#16, #13, #4, etc.)
- Integrates with the built-in
sslmodule for SSL support
rpyc_classic.pynow takes several
--helpfor more info)
- Fixes typos, running pylint, etc.
Breakage from 3.0.7¶
- Removing egg builds (we’re pure python, and eggs just messed up the build)
- Package layout changed drastically, and some files were renamed
servers/directory was renamed
- They scripts now install to your python scripts directory (no longer part
of the package), e.g.
--registerin order to register, instead of
--dont-register, which was a silly choice.
tlslite_connect, to distinguish it from the new
- Moving to git as source control
- Build script: more egg formats; register in pypi ;
remove svn; auto-generate
- Cosmetic touches to
- Shutdown socket before closing (
SHUT_RDWR) to prevent
TIME_WAITand other problems with various Unixes
PipeStream: use low-level file APIs (
os.write) to prevent stdio-level buffering that messed up
classic_server.py: open logfile for writing (was opened for reading)
registry_server.py: type of
utils/server.py: better handling of sockets; fix python 2.4 syntax issue
SIGCHLDhandler after handling that signal, to support non-BSD-compliant platforms where after the invocation of the signal handler, the handler is reset
- Handle metaclasses better in
vinegar.py: handle old-style-class exceptions better; python 2.4 issues
VdbAuthenticator: when loading files, open for read only; API changes (
ForkingServer: better handling of SIGCHLD
setup.pynow also creates egg files
- Slightly improved
- Fixes to
- The authenticator is now invoked by
_accept_client, which means it is invoked on the client’s context (thread or child process). This solves a problem with the forking server having a TLS authenticator.
- Changed the forking server to handle
SIGCHLDinstead of using double-fork.
- The authenticator is now invoked by
getattrto inspect the given object; this caused a problem with premature activation of properties (as they are activated by
getattr). Now it inspects the object’s type instead, following the MRO by itself, to avoid possible side effects.
- Changed versioning scheme: now 3.0.3 instead of 3.03, and the version tuple is (3, 0, 3)
servers/vdbconf.py- a utility to manage verifier databases (used by
- Added the
classic_server.py, which invokes a secure server (TLS) with the given VDB file.
- Authenticators: authenticated servers now store the credentials of the connection in conn._config.credentials
Registry: added UDP and TCP registry servers and clients (
from rpyc.utils.registry import ...)
- Minor bug fixes
- More tests
- The test-suite now runs under python 2.4 too
- Fixes some minor issues/bugs
- The registry server can now be instantiated (no longer a singleton) and customized, and RPyC server can be customized to use the different registry.
- comparison - comparing remote and local objects will usually not work, but there’s nothing to do about it.
- 64bit platforms: since channels use 32bit length field, you can’t pass data/strings over 4gb. this is not a real limitation (unless you have a super-fast local network and tons of RAM), but as 64bit python becomes the defacto standard, I will upgrade channels to 64bit length field.
- threads - in face of no better solution, and after consulting many people, I resorted to setting a timeout on the underlying recv(). This is not an elegant way, but all other solution required rewriting all sorts of threading primitives and were not necessarily deadlock/race-free. as the zen says, “practicality beats purity”.
- Windows - pipes supported, but Win32 pipes work like shit