rethinkdb/rethinkdb — pull request #2554 by barosl (2014-06-16 19:00:34+00:00)
Title: Python 3 compatible driver with tests

As a supplement to the existing Python 3 patch, I made more complete patch to add Python 3 compatibility.

## Driver

While the basic semantics remain the same, the following changes were made.

1. It uses the iterative version of a function on Python 2 if possible. The existing patch simply replaced all the occurrences of `xrange` to `range`, `iteritems` to `items`, `iterkeys` to `keys`, and so on. These changes may slow down the Python 2 clients. Although the impact may not be significant, I thought keeping the original performance is preferable.
2. Type checks involving `str` and `unicode` are done correctly. In Python 2, `basestring` is checked against `isinstance()`. In Python 3, `str` is checked similarly.
3. `multiprocessing.queues.SimpleQueue` is renamed to `multiprocessing.SimpleQueue` in the Python 3 version.
4. Use `cPickle` on Python 2.

The common code needed to make compatibility resides in `_compat.py`.

## Documentation

I changed the gen_python.py script to generate the output which is suitable for both Python 2 and 3. It uses a function to properly inject __doc__ to the target objects.

I will send a pull request to `rethinkdb/docs` separately.

## Test cases

All of the tests from `rql_test` are passed except one, which is `TestBatching` of `conections/connection.py`. It complains about the iterator behavior of the driver. As the same failure occurs with Python 2, I guess this problem is not related to Python 3.

```
Traceback (most recent call last):
File "/Users/barosl/work/rethinkdb/test/rql_test/connections/connection.py", line 385, in runTest
self.assertGreaterEqual(len(cursor.responses), 1)
AssertionError: 0 not greater than or equal to 1
```

The test procedure I used is:

```
$ (cd drivers/python && make install PYTHON=python3)
$ (cd test/rql_test && PYTHON=/usr/bin/python3 ./test-runner '.*py')
```

## Build scripts

Some build scripts including `convert_protofile` and `test-runner` are converted to support Python 3. They are backward-compatible, so the dependency on Python 2 need not be changed. However one might think of allowing either Python 2 *or* 3 as a dependency, though I hardly think of a UNIX system that supports only Python 3 and not 2.