Should you use Pyro 4 or Pyro 3 for your project? This depends on a few things.
Dependencies on older systems
Pyro 4 has more modern system requirements than Pyro 3. It is unsupported on Python versions below 2.6 (except Jython 2.5). Pyro 3 runs fine on Python 2.5, and Pyro versions before 3.13 should run on even older Python versions. So if you cannot use Python 2.6 or newer, you should use Pyro 3.
Pyro 4 has been written from scratch. While it looks and feels much like Pyro 3 did, its API and implementation are incompatible. If you need to connect to existing systems that use Pyro 3, you can only do that with Pyro 3. Pyro 4 can’t talk to them.
Pyro 4 has several features that are not present in Pyro 3, but the reverse is also true. If you require one of the following features for your system, you can only find them -for now- in Pyro 3:
Some of them may appear in the future in Pyro 4, but for now they’re all exclusive to Pyro 3.
Availability in package forms
Some people can’t or won’t install software from source and rather use the package manager of their OS. Pyro 4 might not yet be available in your package manager because it is rather new. Pyro 3 is available as a Debian package. So if you are on Debian (or a derivative like Ubuntu or Mint) and you only accept software from the distribution packages, Pyro 3 is your only choice for now.
The Pyro project itself does not provide any OS-specific packaging. Things like the Debian Pyro package are created and maintained by different people (thanks for that!)
Pyro 3 has been around for many years and has a proven track record. It also has a very stable API. It only gets bug fixes and much effort is taken to keep it backward compatible with previous 3.x versions. Pyro 4 on the other hand is still under active development. The important API parts are more or less stabilized but as features are being added or changed, stuff might break. So depending on your requirements of maturity and API stability you might choose one or the other.
Here you can find what is different in Pyro4 compared to Pyro3. This should help with converting existing Pyro3 applications to Pyro4. It also serves as a quick overview for developers that are used to Pyro3, to see what the new API and features of Pyro4 are like.
Pyro4 requires Python 2.6 or newer. Pyro 3.x supports Python 2.5 (Pyro 3.12 and older, even support Python 2.4)
Toplevel package name has been changed from Pyro into Pyro4
Mobile code support has been removed.
Remote attribute access (DynamicProxyWithAttrs) has been removed (slight chance it appears again in the future in a different form)
Event server has been removed (slight chance it appears again in the future in a different form).
SSL support has been removed. Likely to appear again in a future version.
You don’t need to import the various sub packages. Just import Pyro4 and you’re done: the main Pyro API elements are available directly in the Pyro4 package.
Pyro.core.PyroURI has been renamed to Pyro4.URI
You can choose from two server types to use in your daemon, a threadpool server (that can process requests concurrently, most similar to Pyro3) and a select/poll based server (that processes requests in a single thread by multiplexing all client connections).
Pyro objects in the daemon don’t have a forced objectId UUID anymore. They just use the name you give them, or an auto generated one if you don’t provide a name yourself.
PYROLOC protocol has been removed. Just use the PYRO protocol with the logical name instead of the object id in the URI.
Pyro daemon binds on a random free port by default, instead of on a fixed port. Name server still is on a fixed port by default.
Pyro daemons (including the Name server) bind on localhost by default. This prevents exposure to the outside world in a default install. You have to explicitly tell Pyro4 to bind on another network interface. With Pyro3, it was the other way around, it would bind on all network interfaces by default (potentially exposing unwanted servers).
Logging is done using Python’s standard logging module instead of custom logger stuff from Pyro.util. There is some autoconfig voodoo in the package init code that reacts to some environment variable settings.
All classes are new style classes, so you can use super() etc. (this was already the case in the later Pyro 3.x releases but not in earlier ones)
The command line syntax of these tools has changed, just check out the new usage with ‘-h’.
The name server doesn’t have any groups anymore. The namespace is now ‘flat’. You don’t have to use the ‘:’ in front of names, or separate parts using ‘.’ anymore. You can look up names matching a prefix string or a regular expression now, so with clever names you can still achieve mostly the same as with the old group based namespace.
The name server doesn’t have a default group any longer. Name server proxies are regular Pyro proxies and don’t perform any voodoo magic on the names anymore.
Config items are in Pyro4.config (as they were in Pyro.config in Pyro3) but have changed quite a bit. Most of them have been removed. Some may return in a later version.
Exception traceback processing: Pyro4.util.getPyroTraceback shouldn’t be called with an exception object anymore. Either simply call it without parameters, or supply the usual ex_type, ex_value, ex_tb objects that you can get from sys.exc_info. Or even easier, install Pyro4’s custom excepthook.
Pyro.core.initServer was deprecated for a long time already, and has been removed.
Pyro.core.ObjBase is gone, just use any class directly as a Pyro object. Pyro4 injects a few magic attributes in your object. Their names start with _pyro for easy identification.
Pyro.core.SynchronizedObjBase is gone as well, you need to create your own thread safety measures if required (locks, Queues, etc)
see above for changes concerning how to locate the name server.
Daemons are created much in the same way as before. But they don’t automagically register anything in the name server anymore so you have to do that yourself (daemon.useNameServer is gone)
Daemons now bind on a random free port by default instead of a fixed port. You need to specify a port yourself when creating a daemon if you want a fixed port.
Daemons bind on localhost by default, instead of 0.0.0.0. If you want to expose to the network, you’ll have to provide a proper hostname or ip address yourself. There is a utility method in the Pyro4.socketutil module that can help you with that: getIpAddress.
daemon.connect has been renamed to daemon.register. It still returns the URI for the object, as usual.
daemon.disconnect has been renamed to daemon.unregister
daemon.connectPersistent is gone, just pass the existing object id as a parameter to the normal register.
getting an object’s uri and registering in the name server: use the URI you got from the register call, or use daemon.uriFor to get a new URI for a given object. Use ns.register(objName, uri) as usual to register it in the name server.
creating new pyro objects on the server and returning them (factory methods): server.getDaemon() is replaced by the _pyroDaemon attribute, and obj.getProxy() is gone. Typical pattern is now:
uri=self._pyroDaemon.register(object) return Pyro4.Proxy(uri)
However Pyro4 has an ‘AUTOPROXY’ feature (on by default) that makes the above unneeded (Pyro4 will wrap pyro objects with a proxy automatically for you). You can turn this feature off to make it look more like Pyro3’s behavior.
Unregistering objects from the daemon is done with some_pyro_object._pyroDaemon.unregister(some_pyro_object) (or use the object’s URI).
Pyro4 introduces several new features that weren’t available in Pyro3, so there is no migration path needed for those. (Things like batched calls, async calls, new config items etc).