summaryrefslogtreecommitdiffstats
path: root/Doc/howto
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2008-09-28 02:06:32 (GMT)
committerBenjamin Peterson <benjamin@python.org>2008-09-28 02:06:32 (GMT)
commite9bbc8b2571b0f39da7810e9e6fc5511691ab7ac (patch)
tree9cfc2f7830bd170b48f3346503551c74d5627274 /Doc/howto
parentd61de7f18db0eb9763a046f547053ccc59f2bfc5 (diff)
downloadcpython-e9bbc8b2571b0f39da7810e9e6fc5511691ab7ac.zip
cpython-e9bbc8b2571b0f39da7810e9e6fc5511691ab7ac.tar.gz
cpython-e9bbc8b2571b0f39da7810e9e6fc5511691ab7ac.tar.bz2
Devil merge!
Merged revisions 66561,66564,66580,66610,66614,66618,66624-66625,66628-66629,66643,66645,66660-66665 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r66561 | benjamin.peterson | 2008-09-22 17:13:29 -0500 (Mon, 22 Sep 2008) | 1 line clean up docs for platform's linux_distribution and dist functions ........ r66564 | benjamin.peterson | 2008-09-23 08:32:46 -0500 (Tue, 23 Sep 2008) | 1 line mention how to override boolean evaluation ........ r66580 | georg.brandl | 2008-09-24 04:47:55 -0500 (Wed, 24 Sep 2008) | 2 lines Indentation normalization. ........ r66610 | andrew.kuchling | 2008-09-24 12:27:55 -0500 (Wed, 24 Sep 2008) | 1 line Improve wording ........ r66614 | benjamin.peterson | 2008-09-24 17:11:59 -0500 (Wed, 24 Sep 2008) | 4 lines #3950 fix missing scale factors in turtle.py reviewers: Georg, Benjamin ........ r66618 | benjamin.peterson | 2008-09-25 15:35:45 -0500 (Thu, 25 Sep 2008) | 1 line add a NEWs entry for r66614 ........ r66624 | raymond.hettinger | 2008-09-25 18:31:52 -0500 (Thu, 25 Sep 2008) | 1 line Fix namedtuple bug reported by Glenn Linderman. Template did not form correctly if the field names were input in Unicode. ........ r66625 | benjamin.peterson | 2008-09-25 21:58:36 -0500 (Thu, 25 Sep 2008) | 1 line add the beginnings of a C-API 2 -> 3 porting guide ........ r66628 | benjamin.peterson | 2008-09-26 15:52:06 -0500 (Fri, 26 Sep 2008) | 1 line add an 'other options' section ........ r66629 | georg.brandl | 2008-09-26 16:15:21 -0500 (Fri, 26 Sep 2008) | 2 lines typos. ........ r66643 | andrew.kuchling | 2008-09-27 09:12:33 -0500 (Sat, 27 Sep 2008) | 1 line Add a last bunch of items ........ r66645 | benjamin.peterson | 2008-09-27 11:23:55 -0500 (Sat, 27 Sep 2008) | 1 line 2to3's api should be considered unstable ........ r66660 | andrew.kuchling | 2008-09-27 17:54:08 -0500 (Sat, 27 Sep 2008) | 1 line #3510: future-proof text ........ r66661 | benjamin.peterson | 2008-09-27 18:28:43 -0500 (Sat, 27 Sep 2008) | 1 line clarify a few things ........ r66662 | andrew.kuchling | 2008-09-27 19:15:27 -0500 (Sat, 27 Sep 2008) | 1 line #1579477: mention necessity to flush output before exec'ing ........ r66663 | andrew.kuchling | 2008-09-27 20:08:47 -0500 (Sat, 27 Sep 2008) | 1 line #1415508: Document two functions ........ r66664 | benjamin.peterson | 2008-09-27 20:51:36 -0500 (Sat, 27 Sep 2008) | 1 line better grammar ........ r66665 | benjamin.peterson | 2008-09-27 20:53:29 -0500 (Sat, 27 Sep 2008) | 1 line note the 2to3 -d could be useful for other refactoring ........
Diffstat (limited to 'Doc/howto')
-rw-r--r--Doc/howto/cporting.rst216
-rw-r--r--Doc/howto/index.rst1
2 files changed, 217 insertions, 0 deletions
diff --git a/Doc/howto/cporting.rst b/Doc/howto/cporting.rst
new file mode 100644
index 0000000..3451f5c
--- /dev/null
+++ b/Doc/howto/cporting.rst
@@ -0,0 +1,216 @@
+.. highlightlang:: c
+
+********************************
+Porting Extension Modules to 3.0
+********************************
+
+:author: Benjamin Peterson
+
+
+.. topic:: Abstract
+
+ Although changing the C-API was not one of Python 3.0's objectives, the many
+ Python level changes made leaving 2.x's API intact impossible. In fact, some
+ changes such as :func:`int` and :func:`long` unification are more obvious on
+ the C level. This document endeavors to document incompatibilities and how
+ they can be worked around.
+
+
+Conditional compilation
+=======================
+
+The easiest way to compile only some code for 3.0 is to check if
+:cmacro:`PY_MAJOR_VERSION` is greater than or equal to 3. ::
+
+ #if PY_MAJOR_VERSION >= 3
+ #define IS_PY3K
+ #endif
+
+API functions that are not present can be aliased to their equivalents within
+conditional blocks.
+
+
+Changes to Object APIs
+======================
+
+Python 3.0 merged together some types with similar functions while cleanly
+separating others.
+
+
+str/unicode Unification
+-----------------------
+
+
+Python 3.0's :func:`str` (``PyString_*`` functions in C) type is equivalent to
+2.x's :func:`unicode` (``PyUnicode_*``). The old 8-bit string type has become
+:func:`bytes`. Python 2.6 and later provide a compatibility header,
+:file:`bytesobject.h`, mapping ``PyBytes`` names to ``PyString`` ones. For best
+compatibility with 3.0, :ctype:`PyUnicode` should be used for textual data and
+:ctype:`PyBytes` for binary data. It's also important to remember that
+:ctype:`PyBytes` and :ctype:`PyUnicode` in 3.0 are not interchangeable like
+:ctype:`PyString` and :ctype:`PyString` are in 2.x. The following example shows
+best practices with regards to :ctype:`PyUnicode`, :ctype:`PyString`, and
+:ctype:`PyBytes`. ::
+
+ #include "stdlib.h"
+ #include "Python.h"
+ #include "bytesobject.h"
+
+ /* text example */
+ static PyObject *
+ say_hello(PyObject *self, PyObject *args) {
+ PyObject *name, *result;
+
+ if (!PyArg_ParseTuple(args, "U:say_hello", &name))
+ return NULL;
+
+ result = PyUnicode_FromFormat("Hello, %S!", name);
+ return result;
+ }
+
+ /* just a forward */
+ static char * do_encode(PyObject *);
+
+ /* bytes example */
+ static PyObject *
+ encode_object(PyObject *self, PyObject *args) {
+ char *encoded;
+ PyObject *result, *myobj;
+
+ if (!PyArg_ParseTuple(args, "O:encode_object", &myobj))
+ return NULL;
+
+ encoded = do_encode(myobj);
+ if (encoded == NULL)
+ return NULL;
+ result = PyBytes_FromString(encoded);
+ free(encoded);
+ return result;
+ }
+
+
+long/int Unification
+--------------------
+
+In Python 3.0, there is only one integer type. It is called :func:`int` on the
+Python level, but actually corresponds to 2.x's :func:`long` type. In the
+C-API, ``PyInt_*`` functions are replaced by their ``PyLong_*`` neighbors. The
+best course of action here is using the ``PyInt_*`` functions aliased to
+``PyLong_*`` found in :file:`intobject.h`. The the abstract ``PyNumber_*`` APIs
+can also be used in some cases. ::
+
+ #include "Python.h"
+ #include "intobject.h"
+
+ static PyObject *
+ add_ints(PyObject *self, PyObject *args) {
+ int one, two;
+ PyObject *result;
+
+ if (!PyArg_ParseTuple(args, "ii:add_ints", &one, &two))
+ return NULL;
+
+ return PyInt_FromLong(one + two);
+ }
+
+
+
+Module initialization and state
+===============================
+
+Python 3.0 has a revamped extension module initialization system. (See PEP
+:pep:`3121`.) Instead of storing module state in globals, they should be stored
+in an interpreter specific structure. Creating modules that act correctly in
+both 2.x and 3.0 is tricky. The following simple example demonstrates how. ::
+
+ #include "Python.h"
+
+ struct module_state {
+ PyObject *error;
+ };
+
+ #if PY_MAJOR_VERSION >= 3
+ #define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
+ #else
+ #define GETSTATE(m) (&_state)
+ static struct module_state _state;
+ #endif
+
+ static PyObject *
+ error_out(PyObject *m) {
+ struct module_state *st = GETSTATE(m);
+ PyErr_SetString(st->error, "something bad happened");
+ return NULL;
+ }
+
+ static PyMethodDef myextension_methods[] = {
+ {"error_out", (PyCFunction)error_out, METH_NOARGS, NULL},
+ {NULL, NULL}
+ };
+
+ #if PY_MAJOR_VERSION >= 3
+
+ static int myextension_traverse(PyObject *m, visitproc visit, void *arg) {
+ Py_VISIT(GETSTATE(m)->error);
+ return 0;
+ }
+
+ static int myextension_clear(PyObject *m) {
+ Py_CLEAR(GETSTATE(m)->error);
+ return 0;
+ }
+
+
+ static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ "myextension",
+ NULL,
+ sizeof(struct module_state),
+ myextension_methods,
+ NULL,
+ myextension_traverse,
+ myextension_clear,
+ NULL
+ };
+
+ #define INITERROR return NULL
+
+ PyObject *
+ PyInit_myextension(void)
+
+ #else
+ #define INITERROR return
+
+ void
+ initmyextension(void)
+ #endif
+ {
+ #if PY_MAJOR_VERSION >= 3
+ PyObject *module = PyModule_Create(&moduledef);
+ #else
+ PyObject *module = Py_InitModule("myextension", myextension_methods);
+ #endif
+
+ if (module == NULL)
+ INITERROR;
+ struct module_state *st = GETSTATE(module);
+
+ st->error = PyErr_NewException("myextension.Error", NULL, NULL);
+ if (st->error == NULL) {
+ Py_DECREF(module);
+ INITERROR;
+ }
+
+ #if PY_MAJOR_VERSION >= 3
+ return module;
+ #endif
+ }
+
+
+Other options
+=============
+
+If you are writing a new extension module, you might consider `Cython
+<http://www.cython.org>`_. It translates a Python-like language to C. The
+extension modules it creates are compatible with Python 3.x and 2.x.
+
diff --git a/Doc/howto/index.rst b/Doc/howto/index.rst
index 5a1f397..7d64688 100644
--- a/Doc/howto/index.rst
+++ b/Doc/howto/index.rst
@@ -14,6 +14,7 @@ Currently, the HOWTOs are:
:maxdepth: 1
advocacy.rst
+ cporting.rst
curses.rst
doanddont.rst
functional.rst