Differences between CPython and JPython
CPython and JPython are two different implementations of the Python language. While a Language
Reference exists for the Python language, there are a number of features of the language that are incompletely
specified. The following lists all known differences between the two implementations of the Python language. These
differences range from the trivial -- JPython prints "1.0E20" where CPython prints "1e+020"
-- to the dramatic -- everything in JPython is an instance of a class. At some point more effort should be made
to separate the interesting differences from the mundane. These differences are based on JPython-1.0.0 and CPython-1.5.1.
Syntax
- JPython has a different interpretation of floating point literals. CPython doesn't allow 001.1, and does allow
0e and even 0e-. CPython should be fixed.
- JPython supports continue in a try clause. CPython should be fixed - but don't hold your breath.
Standard types, functions and behavior
- JPython string objects support full two-byte Unicode characters and the functions in the string module are
Unicode-aware. CPython should add Unicode support in the future, though the details of this are still unclear.
- JPython formats floating point numbers differently, e.g. an upper case 'E' is used, and it switches over to
E notation sooner than CPython does. Both behaviors are acceptable.
- In JPython, 0.1**4 is printed as 1.0000000000000002E-4. In CPython, it is printed 0.0001, even though it is
not actually equal to 0.0001. Both behaviors are acceptable for now -- this is still being discussed.
- JPython supports looping over a dictionary. JPython should be fixed in v1.1
- JPython sequences support three argument slices. i.e. range(3)[::-1] == [2,1,0]. CPython should be fixed.
- Every object in JPython is an instance of a class -- there are no types in JPython. i.e. [].__class__ is a
sensible thing to write in JPython. CPython should be fixed - but don't hold your breath.
- The .tell() method on JPython file objects returns a Python long, while the .tell() method on CPython file
objects returns a Python int. Whether or not both behaviors are acceptable is still unclear.
- JPython file objects are still missing some functionality -- see todo list in PyFile.java. (Hopefully in the
near future this can be changed to read -- JPython file objects include the following extra functionality to properly
handle non-ascii files...) JPython should be fixed in v1.1
- In JPython, standard exceptions are still strings. JPython should be fixed in v1.1
- In CPython, range(0.1, 3.2) yields the surprising [0, 1, 2]. JPython does the right thing (reject float arguments).
-- Many other functions taking int arguments have the same problem. CPython should be fixed.
- In JPython, ord(None) yields a surprising deep Java stack trace and a NullPointerException. In CPython, this
throws a type error insisting on a string argument. Many other functions taking String arguments have the same
problem. Whether or not JPython needs to be fixed is still unclear.
- In CPython, the list.append() method takes multiple arguments and forms a tuple. JPython's append() method
requires one argument only. CPython should be fixed -- but probably won't be due to backwards compatibility..
- In JPython, printing a recursive list or dictionary causes a stack overflow. CPython now uses ellipses to indicate
recursive items, e.g. ``l = []; l.append(l); print l'' prints ``[[...]]''. JPython should be fixed in v1.1
- In JPython, when an AttributeError is raised, it prints the name of the class of the object for which the attribute
is not found in the error message -- even for Python instances. CPython only includes this information for instances
of built-in types. Proper behavior here is still unclear.
- The __name__ attribute of built-in extension modules (e.g. 'sys') is different. Both behaviors are acceptable.
- In many cases, introspection yields different results; e.g. dir([]) yields an empty list in JPython but a list
of list methods in CPython. Arguably, JPython is right, although I find CPython's behavior more convenient. Both
behaviors are acceptable.
- In JPython, dir() doesn't return __name__ even if it is supported. JPython should be fixed in v1.1
- The locals() dictionary in JPython is mutable from within a function. After "def foo(x=1): locals()['x']
= 2; print x" foo() prints 1 in CPython and 2 in JPython. Jim thinks that JPython's behavior is better here
-- but the best answer might be that locals() should be considered a read-only dictionary. Proper behavior here
is still unclear.
- JPython doesn't support restricted execution mode and doesn't have the magic __builtins__ in every namespace.
JPython will probably never support restricted execution mode -- Java's security model is recommended instead.
- JPython uses different values for the IOError argument. This causes trouble for people who unpack the value
into an (errno, message) tuple. Both behaviors are acceptable.
- JPython function objects don't have the func_name attribute (an alias for __name__). This attribute is considered
obsolete and won't be supported by JPython.
- JPython code objects are missing other attributes -- co_code, co_consts, co_flags, co_lnotab, co_names, co_nlocals,
co_stacksize. These attributes will probably never be supported in JPython due to its implementation of code
objects as compiled Java bytecodes.
- JPython has "true" garbage collection whereas CPython uses reference counting. This means that in
JPython users don't need to worry about handling circular references as these are guaranteed to be collected properly.
On the other hand, users of JPython have no guarantees of when an object will be finalized -- this can cause problems
for people who use open("foo", 'r').read() excessively. Both behaviors are acceptable -- and highly
unlikely to change.
- The dictionaries used by classes, instances, and modules in JPython are not the same as the dictionaries created
by {}. They are StringMap's which require all of their keys to be strings. After "class c: pass", c.__dict__[1]
= 2 will work in CPython, but will raise a "TypeError: keys in namespace must be strings" error in JPython.
Both behaviors are acceptable -- CPython might adopt JPython's approach in the future for the performance gains
it can provide.
- CPython throws a TypeError when a two-element slice has non-integer values (i.e. f['a':'b']). JPython simply
calls the object's __getslice__ method with those objects as the start and stop arguments. CPython should be
fixed.
- CPython throws an attribute error when slicing is performed on an object with no __getslice__ method, but which
has a __getitem__ method. JPython simply calls the __getitem__ method with a slice object. CPython should
be fixed.
Extension modules
- JPython supports all java packages as extension modules. i.e. from "java.lang import System" will
work in any JPython implementation. This functionality might be added as an optional extension to some future
version of CPython.
- JPython includes the builtin module jarray -- which allows Python programmers to create and manipulate Java
array objects.
- Lots of builtin extension modules don't exist in JPython.
- The following are likely to be implemented in JPython v1.1 -- cmath, struct, CPickle, CStringIO, and operator.
- The following are under consideration (working code would make the decision much easier ;-) -- array, select,
a dbm/gdbm/bsddb style module, Numeric.
- The following are highly unlikely any time soon -- Tkinter.
- Let me know if something should be added to this list.
- __builtin__ module
- Missing the input function. JPython should be fixed in v1.1
- Incomplete implementation of __import__ -- only one argument is allowed and replacing this with a user-defined
function has no effect. JPython might be fixed in a future release.
- os module
- popen and system are missing. JPython should be fixed, patcheds would be graciously accepted.
- path.normcase. This one is extremely frustrating as there seems no portable way to implement in Java.
- chmod, chown, getpid, fork, stat, ... are missing. These functions are all very Unix specific and it is unlikely
they will ever be properly supported in a 100% Pure Java implementation. Perhaps somebody should create a JNI/C
package for Java called posix which provides this functionality.
- The socket module is limited.
- sys module
- In JPython, the exception state (sys.exc_{type,value,traceback} and also what sys.exc_info() returns) isn't
saved and restored across function calls. JPython should be fixed in v1.1
- JPython ignores assignment to sys.stdin. In CPython, this affects raw_input() and input() but not the interactive
interpreter. JPython should be fixed in v1.1
- JPython missing attributes __stderr__, __stdin__, __stdout__, builtin_module_names, exc_type, exec_prefix,
exitfunc. JPython should be fixed in v1.1
- Also missing executable, getrefcount, setcheckinterval which don't make much sense for JPython.
- JPython adds the function add_package to deal with Java packages. CPython will probably never have this function.
- thread module
- CPython's thread modules defines some aliases that JPython's doesn't. These aliases are considered obsolete
and won't be supported by JPython.
Interpreter and environment
- JPython doesn't catch interrupts. Only fixable with a GUI console - probably standard in v1.1.
- JPython doesn't have command line editing. Only fixable with a GUI console - probably standard in v1.1.
- JPython doesn't import "site" on startup. This is a standard module that tries to import sitecustomize
which a site could use to customize things. Should also have a feature similar to $PYTHONSTARTUP, which specifies
a script to run at the start of *interactive* mode only. JPython should be fixed in v1.1
- JPython supports fewer command line options than CPython, e.g. it doesn't support "-c command". It
also has a different convention for indicating non-interactive standard input (the Java runtime needs help). It
is still unclear what set of command line options will be supported in JPython-1.1.