Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Replace cython-based extension module with a hand-written one.

This avoids the complexity of ensuring that cython is installed
at build time.
  • Loading branch information...
commit 0ca7fa01d10298bfda27634a450b2e8492b2d791 1 parent 4a5fdb1
Ben Darnell bdarnell authored
3  .gitignore
View
@@ -14,6 +14,3 @@ MANIFEST
/env/
# Used in demo apps
secrets.cfg
-
-# cython-generated
-tornado/speedups.c
2  MANIFEST.in
View
@@ -1,5 +1,5 @@
recursive-include demos *.py *.yaml *.html *.css *.js *.xml *.sql README
-include tornado/speedups.pyx
+include tornado/speedups.c
include tornado/ca-certificates.crt
include tornado/test/README
include tornado/test/csv_translations/fr_FR.csv
15 setup.py
View
@@ -14,6 +14,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import platform
import sys
try:
@@ -24,10 +25,7 @@
setuptools = None
from distutils.core import setup
-try:
- from Cython.Build import cythonize
-except ImportError:
- cythonize = None
+from distutils.core import Extension
kwargs = {}
@@ -36,8 +34,13 @@
with open('README.rst') as f:
kwargs['long_description'] = f.read()
-if cythonize is not None:
- kwargs['ext_modules'] = cythonize('tornado/speedups.pyx')
+if platform.python_implementation() == 'CPython':
+ # This extension builds and works on pypy as well, although pypy's jit
+ # produces equivalent performance.
+ kwargs['ext_modules'] = [
+ Extension('tornado.speedups',
+ sources=['tornado/speedups.c']),
+ ]
if setuptools is not None:
# If setuptools is not available, you're on your own for dependencies.
48 tornado/speedups.c
View
@@ -0,0 +1,48 @@
+#include <Python.h>
+
+static PyObject* websocket_mask(PyObject* self, PyObject* args) {
+ const char* mask;
+ int mask_len;
+ const char* data;
+ int data_len;
+
+ if (!PyArg_ParseTuple(args, "s#s#", &mask, &mask_len, &data, &data_len)) {
+ return NULL;
+ }
+
+ PyObject* result = PyBytes_FromStringAndSize(NULL, data_len);
+ if (!result) {
+ return NULL;
+ }
+ char* buf = PyBytes_AsString(result);
+ for (int i = 0; i < data_len; i++) {
+ buf[i] = data[i] ^ mask[i % 4];
+ }
+
+ return result;
+}
+
+static PyMethodDef methods[] = {
+ {"websocket_mask", websocket_mask, METH_VARARGS, ""},
+ {NULL, NULL, 0, NULL}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef speedupsmodule = {
+ PyModuleDef_HEAD_INIT,
+ "speedups",
+ NULL,
+ -1,
+ methods
+};
+
+PyMODINIT_FUNC
+PyInit_speedups() {
+ return PyModule_Create(&speedupsmodule);
+}
+#else // Python 2.x
+PyMODINIT_FUNC
+initspeedups() {
+ Py_InitModule("tornado.speedups", methods);
+}
+#endif
16 tornado/speedups.pyx
View
@@ -1,16 +0,0 @@
-# -*- python -*-
-from cpython.mem cimport PyMem_Malloc, PyMem_Free
-
-def websocket_mask(bytes mask_bytes, bytes data_bytes):
- cdef size_t data_len = len(data_bytes)
- cdef char* data = data_bytes
- cdef char* mask = mask_bytes
- cdef size_t i
- cdef char* buf = <char*> PyMem_Malloc(data_len)
- try:
- for i in xrange(data_len):
- buf[i] = data[i] ^ mask[i % 4]
- # Is there a zero-copy equivalent of this?
- return <bytes>(buf[:data_len])
- finally:
- PyMem_Free(buf)
11 tornado/websocket.py
View
@@ -908,7 +908,12 @@ def _websocket_mask_python(mask, data):
else:
return unmasked.tostring()
-try:
- from tornado.speedups import websocket_mask as _websocket_mask
-except ImportError:
+if os.environ.get('TORNADO_NO_EXTENSION'):
+ # This environment variable exists to make it easier to do performance comparisons;
+ # it's not guaranteed to remain supported in the future.
_websocket_mask = _websocket_mask_python
+else:
+ try:
+ from tornado.speedups import websocket_mask as _websocket_mask
+ except ImportError:
+ _websocket_mask = _websocket_mask_python
4 tox.ini
View
@@ -30,7 +30,6 @@ deps = unittest2
[testenv:py26-full]
basepython = python2.6
deps =
- Cython
futures
mock
pycurl
@@ -40,7 +39,6 @@ deps =
[testenv:py27-full]
basepython = python2.7
deps =
- Cython
futures
mock
pycurl
@@ -150,7 +148,6 @@ commands = python -m tornado.test.runtests --locale=zh_TW {posargs:}
# there.
basepython = pypy
deps =
- Cython
futures
mock
@@ -171,7 +168,6 @@ setenv = LANG=en_US.utf-8
[testenv:py32-full]
basepython = python3.2
deps =
- Cython
mock
[testenv:py33]
Please sign in to comment.
Something went wrong with that request. Please try again.