Server IP : 85.214.239.14 / Your IP : 3.145.32.238 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /usr/share/doc/python/faq/ |
Upload File : |
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="generator" content="Docutils 0.12: http://docutils.sourceforge.net/" /> <title>Extending/Embedding FAQ</title> <meta name="date" content="2004-04-08" /> <style type="text/css"> /* :Author: David Goodger (goodger@python.org) :Id: $Id: html4css1.css 7614 2013-02-21 15:55:51Z milde $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to customize this style sheet. */ /* used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { border: 0 } table.borderless td, table.borderless th { /* Override padding for "table.docutils td" with "! important". The right padding separates the table cells. */ padding: 0 0.5em 0 0 ! important } .first { /* Override more specific margin styles with "! important". */ margin-top: 0 ! important } .last, .with-subtitle { margin-bottom: 0 ! important } .hidden { display: none } a.toc-backref { text-decoration: none ; color: black } blockquote.epigraph { margin: 2em 5em ; } dl.docutils dd { margin-bottom: 0.5em } object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { overflow: hidden; } /* Uncomment (and remove this text!) to get bold-faced definition list terms dl.docutils dt { font-weight: bold } */ div.abstract { margin: 2em 5em } div.abstract p.topic-title { font-weight: bold ; text-align: center } div.admonition, div.attention, div.caution, div.danger, div.error, div.hint, div.important, div.note, div.tip, div.warning { margin: 2em ; border: medium outset ; padding: 1em } div.admonition p.admonition-title, div.hint p.admonition-title, div.important p.admonition-title, div.note p.admonition-title, div.tip p.admonition-title { font-weight: bold ; font-family: sans-serif } div.attention p.admonition-title, div.caution p.admonition-title, div.danger p.admonition-title, div.error p.admonition-title, div.warning p.admonition-title, .code .error { color: red ; font-weight: bold ; font-family: sans-serif } /* Uncomment (and remove this text!) to get reduced vertical space in compound paragraphs. div.compound .compound-first, div.compound .compound-middle { margin-bottom: 0.5em } div.compound .compound-last, div.compound .compound-middle { margin-top: 0.5em } */ div.dedication { margin: 2em 5em ; text-align: center ; font-style: italic } div.dedication p.topic-title { font-weight: bold ; font-style: normal } div.figure { margin-left: 2em ; margin-right: 2em } div.footer, div.header { clear: both; font-size: smaller } div.line-block { display: block ; margin-top: 1em ; margin-bottom: 1em } div.line-block div.line-block { margin-top: 0 ; margin-bottom: 0 ; margin-left: 1.5em } div.sidebar { margin: 0 0 0.5em 1em ; border: medium outset ; padding: 1em ; background-color: #ffffee ; width: 40% ; float: right ; clear: right } div.sidebar p.rubric { font-family: sans-serif ; font-size: medium } div.system-messages { margin: 5em } div.system-messages h1 { color: red } div.system-message { border: medium outset ; padding: 1em } div.system-message p.system-message-title { color: red ; font-weight: bold } div.topic { margin: 2em } h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { margin-top: 0.4em } h1.title { text-align: center } h2.subtitle { text-align: center } hr.docutils { width: 75% } img.align-left, .figure.align-left, object.align-left { clear: left ; float: left ; margin-right: 1em } img.align-right, .figure.align-right, object.align-right { clear: right ; float: right ; margin-left: 1em } img.align-center, .figure.align-center, object.align-center { display: block; margin-left: auto; margin-right: auto; } .align-left { text-align: left } .align-center { clear: both ; text-align: center } .align-right { text-align: right } /* reset inner alignment in figures */ div.align-right { text-align: inherit } /* div.align-center * { */ /* text-align: left } */ ol.simple, ul.simple { margin-bottom: 1em } ol.arabic { list-style: decimal } ol.loweralpha { list-style: lower-alpha } ol.upperalpha { list-style: upper-alpha } ol.lowerroman { list-style: lower-roman } ol.upperroman { list-style: upper-roman } p.attribution { text-align: right ; margin-left: 50% } p.caption { font-style: italic } p.credits { font-style: italic ; font-size: smaller } p.label { white-space: nowrap } p.rubric { font-weight: bold ; font-size: larger ; color: maroon ; text-align: center } p.sidebar-title { font-family: sans-serif ; font-weight: bold ; font-size: larger } p.sidebar-subtitle { font-family: sans-serif ; font-weight: bold } p.topic-title { font-weight: bold } pre.address { margin-bottom: 0 ; margin-top: 0 ; font: inherit } pre.literal-block, pre.doctest-block, pre.math, pre.code { margin-left: 2em ; margin-right: 2em } pre.code .ln { color: grey; } /* line numbers */ pre.code, code { background-color: #eeeeee } pre.code .comment, code .comment { color: #5C6576 } pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } pre.code .literal.string, code .literal.string { color: #0C5404 } pre.code .name.builtin, code .name.builtin { color: #352B84 } pre.code .deleted, code .deleted { background-color: #DEB0A1} pre.code .inserted, code .inserted { background-color: #A3D289} span.classifier { font-family: sans-serif ; font-style: oblique } span.classifier-delimiter { font-family: sans-serif ; font-weight: bold } span.interpreted { font-family: sans-serif } span.option { white-space: nowrap } span.pre { white-space: pre } span.problematic { color: red } span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80% } table.citation { border-left: solid 1px gray; margin-left: 1px } table.docinfo { margin: 2em 4em } table.docutils { margin-top: 0.5em ; margin-bottom: 0.5em } table.footnote { border-left: solid 1px black; margin-left: 1px } table.docutils td, table.docutils th, table.docinfo td, table.docinfo th { padding-left: 0.5em ; padding-right: 0.5em ; vertical-align: top } table.docutils th.field-name, table.docinfo th.docinfo-name { font-weight: bold ; text-align: left ; white-space: nowrap ; padding-left: 0 } /* "booktabs" style (no vertical lines) */ table.docutils.booktabs { border: 0px; border-top: 2px solid; border-bottom: 2px solid; border-collapse: collapse; } table.docutils.booktabs * { border: 0px; } table.docutils.booktabs th { border-bottom: thin solid; text-align: left; } h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { font-size: 100% } ul.auto-toc { list-style-type: none } </style> </head> <body> <div class="document" id="extending-embedding-faq"> <h1 class="title">Extending/Embedding FAQ</h1> <table class="docinfo" frame="void" rules="none"> <col class="docinfo-name" /> <col class="docinfo-content" /> <tbody valign="top"> <tr><th class="docinfo-name">Date:</th> <td>2004-04-08</td></tr> <tr><th class="docinfo-name">Version:</th> <td>7294</td></tr> <tr class="field"><th class="docinfo-name">Web site:</th><td class="field-body"><a class="reference external" href="http://www.python.org/">http://www.python.org/</a></td> </tr> </tbody> </table> <div class="contents topic" id="contents"> <p class="topic-title first">Contents</p> <ul class="auto-toc simple"> <li><a class="reference internal" href="#can-i-create-my-own-functions-in-c" id="id7">1 Can I create my own functions in C?</a></li> <li><a class="reference internal" href="#id1" id="id8">2 Can I create my own functions in C++?</a></li> <li><a class="reference internal" href="#writing-c-is-hard-are-there-any-alternatives" id="id9">3 Writing C is hard; are there any alternatives?</a></li> <li><a class="reference internal" href="#how-can-i-execute-arbitrary-python-statements-from-c" id="id10">4 How can I execute arbitrary Python statements from C?</a></li> <li><a class="reference internal" href="#how-can-i-evaluate-an-arbitrary-python-expression-from-c" id="id11">5 How can I evaluate an arbitrary Python expression from C?</a></li> <li><a class="reference internal" href="#how-do-i-extract-c-values-from-a-python-object" id="id12">6 How do I extract C values from a Python object?</a></li> <li><a class="reference internal" href="#how-do-i-use-py-buildvalue-to-create-a-tuple-of-arbitrary-length" id="id13">7 How do I use Py_BuildValue() to create a tuple of arbitrary length?</a></li> <li><a class="reference internal" href="#how-do-i-call-an-object-s-method-from-c" id="id14">8 How do I call an object's method from C?</a></li> <li><a class="reference internal" href="#how-do-i-catch-the-output-from-pyerr-print-or-anything-that-prints-to-stdout-stderr" id="id15">9 How do I catch the output from PyErr_Print() (or anything that prints to stdout/stderr)?</a></li> <li><a class="reference internal" href="#how-do-i-access-a-module-written-in-python-from-c" id="id16">10 How do I access a module written in Python from C?</a></li> <li><a class="reference internal" href="#how-do-i-interface-to-c-objects-from-python" id="id17">11 How do I interface to C++ objects from Python?</a></li> <li><a class="reference internal" href="#i-added-a-module-using-the-setup-file-and-the-make-fails-why" id="id18">12 I added a module using the Setup file and the make fails; why?</a></li> <li><a class="reference internal" href="#how-do-i-debug-an-extension" id="id19">13 How do I debug an extension?</a></li> <li><a class="reference internal" href="#i-want-to-compile-a-python-module-on-my-linux-system-but-some-files-are-missing-why" id="id20">14 I want to compile a Python module on my Linux system, but some files are missing. Why?</a></li> <li><a class="reference internal" href="#what-does-systemerror-pyimport-fixupextension-module-yourmodule-not-loaded-mean" id="id21">15 What does "SystemError: _PyImport_FixupExtension: module yourmodule not loaded" mean?</a></li> <li><a class="reference internal" href="#how-do-i-tell-incomplete-input-from-invalid-input" id="id22">16 How do I tell "incomplete input" from "invalid input"?</a></li> <li><a class="reference internal" href="#how-do-i-find-undefined-g-symbols-builtin-new-or-pure-virtual" id="id23">17 How do I find undefined g++ symbols __builtin_new or __pure_virtual?</a></li> <li><a class="reference internal" href="#can-i-create-an-object-class-with-some-methods-implemented-in-c-and-others-in-python-e-g-through-inheritance" id="id24">18 Can I create an object class with some methods implemented in C and others in Python (e.g. through inheritance)?</a></li> <li><a class="reference internal" href="#when-importing-module-x-why-do-i-get-undefined-symbol-pyunicodeucs2" id="id25">19 When importing module X, why do I get "undefined symbol: PyUnicodeUCS2*"?</a></li> </ul> </div> <div class="section" id="can-i-create-my-own-functions-in-c"> <h1><a class="toc-backref" href="#id7">1 Can I create my own functions in C?</a></h1> <p>Yes, you can create built-in modules containing functions, variables, exceptions and even new types in C. This is explained in the document "Extending and Embedding the Python Interpreter" (<a class="reference external" href="http://docs.python.org/ext/ext.html">http://docs.python.org/ext/ext.html</a>).</p> <p>Most intermediate or advanced Python books will also cover this topic.</p> </div> <div class="section" id="id1"> <h1><a class="toc-backref" href="#id8">2 Can I create my own functions in C++?</a></h1> <p>Yes, using the C compatibility features found in C++. Place <tt class="docutils literal">extern "C" { ... }</tt> around the Python include files and put <tt class="docutils literal">extern "C"</tt> before each function that is going to be called by the Python interpreter. Global or static C++ objects with constructors are probably not a good idea.</p> </div> <div class="section" id="writing-c-is-hard-are-there-any-alternatives"> <h1><a class="toc-backref" href="#id9">3 Writing C is hard; are there any alternatives?</a></h1> <p>There are a number of alternatives to writing your own C extensions, depending on what you're trying to do.</p> <p>If you need more speed, <a class="reference external" href="http://psyco.sourceforge.net/">Psyco</a> generates x86 assembly code from Python bytecode. You can use Psyco to compile the most time-critical functions in your code, and gain a significant improvement with very little effort, as long as you're running on a machine with an x86-compatible processor.</p> <p><a class="reference external" href="http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/">Pyrex</a> is a compiler that accepts a slightly modified form of Python and generates the corresponding C code. Pyrex makes it possible to write an extension without having to learn Python's C API.</p> <p>If you need to interface to some C library for which no Python extension currently exists, you can try wrapping the library's data types and functions with a tool such as <a class="reference external" href="http://www.swig.org">SWIG</a>. For C++ libraries, you can look at <a class="reference external" href="http://www.riverbankcomputing.co.uk/sip/">SIP</a>, <a class="reference external" href="http://cxx.sourceforge.net/">CXX</a>, <a class="reference external" href="http://www.boost.org/libs/python/doc/index.html">Boost</a>, or <a class="reference external" href="http://www.scipy.org/site_content/weave">Weave</a>.</p> </div> <div class="section" id="how-can-i-execute-arbitrary-python-statements-from-c"> <h1><a class="toc-backref" href="#id10">4 How can I execute arbitrary Python statements from C?</a></h1> <p>The highest-level function to do this is <tt class="docutils literal">PyRun_SimpleString()</tt> which takes a single string argument to be executed in the context of the module <tt class="docutils literal">__main__</tt> and returns 0 for success and -1 when an exception occurred (including <tt class="docutils literal">SyntaxError</tt>). If you want more control, use <tt class="docutils literal">PyRun_String()</tt>; see the source for <tt class="docutils literal">PyRun_SimpleString()</tt> in Python/pythonrun.c.</p> </div> <div class="section" id="how-can-i-evaluate-an-arbitrary-python-expression-from-c"> <h1><a class="toc-backref" href="#id11">5 How can I evaluate an arbitrary Python expression from C?</a></h1> <p>Call the function <tt class="docutils literal">PyRun_String()</tt> from the previous question with the start symbol <tt class="docutils literal">Py_eval_input</tt>; it parses an expression, evaluates it and returns its value.</p> </div> <div class="section" id="how-do-i-extract-c-values-from-a-python-object"> <h1><a class="toc-backref" href="#id12">6 How do I extract C values from a Python object?</a></h1> <p>That depends on the object's type. If it's a tuple, <tt class="docutils literal">PyTupleSize(o)</tt> returns its length and <tt class="docutils literal">PyTuple_GetItem(o, i)</tt> returns its i'th item. Lists have similar functions, <tt class="docutils literal">PyListSize(o)</tt> and <tt class="docutils literal">PyList_GetItem(o, i)</tt>.</p> <p>For strings, <tt class="docutils literal">PyString_Size(o)</tt> returns its length and <tt class="docutils literal">PyString_AsString(o)</tt> a pointer to its value. Note that Python strings may contain null bytes so C's <tt class="docutils literal">strlen()</tt> should not be used.</p> <p>To test the type of an object, first make sure it isn't NULL, and then use <tt class="docutils literal">PyString_Check(o)</tt>, <tt class="docutils literal">PyTuple_Check(o)</tt>, <tt class="docutils literal">PyList_Check(o)</tt>, etc.</p> <p>There is also a high-level API to Python objects which is provided by the so-called 'abstract' interface -- read <tt class="docutils literal">Include/abstract.h</tt> for further details. It allows interfacing with any kind of Python sequence using calls like <tt class="docutils literal">PySequence_Length()</tt>, <tt class="docutils literal">PySequence_GetItem()</tt>, etc.) as well as many other useful protocols.</p> </div> <div class="section" id="how-do-i-use-py-buildvalue-to-create-a-tuple-of-arbitrary-length"> <h1><a class="toc-backref" href="#id13">7 How do I use Py_BuildValue() to create a tuple of arbitrary length?</a></h1> <p>You can't. Use <tt class="docutils literal">t = PyTuple_New(n)</tt> instead, and fill it with objects using <tt class="docutils literal">PyTuple_SetItem(t, i, o)</tt> -- note that this "eats" a reference count of <tt class="docutils literal">o</tt>, so you have to <tt class="docutils literal">Py_INCREF</tt> it. Lists have similar functions <tt class="docutils literal">PyList_New(n)</tt> and <tt class="docutils literal">PyList_SetItem(l, i, o)</tt>. Note that you <em>must</em> set all the tuple items to some value before you pass the tuple to Python code -- <tt class="docutils literal">PyTuple_New(n)</tt> initializes them to NULL, which isn't a valid Python value.</p> </div> <div class="section" id="how-do-i-call-an-object-s-method-from-c"> <h1><a class="toc-backref" href="#id14">8 How do I call an object's method from C?</a></h1> <p>The <tt class="docutils literal">PyObject_CallMethod()</tt> function can be used to call an arbitrary method of an object. The parameters are the object, the name of the method to call, a format string like that used with <tt class="docutils literal">Py_BuildValue()</tt>, and the argument values:</p> <pre class="literal-block"> PyObject * PyObject_CallMethod(PyObject *object, char *method_name, char *arg_format, ...); </pre> <p>This works for any object that has methods -- whether built-in or user-defined. You are responsible for eventually <tt class="docutils literal">Py_DECREF</tt>'ing the return value.</p> <p>To call, e.g., a file object's "seek" method with arguments 10, 0 (assuming the file object pointer is "f"):</p> <pre class="literal-block"> res = PyObject_CallMethod(f, "seek", "(ii)", 10, 0); if (res == NULL) { ... an exception occurred ... } else { Py_DECREF(res); } </pre> <p>Note that since <tt class="docutils literal">PyObject_CallObject()</tt> <em>always</em> wants a tuple for the argument list, to call a function without arguments, pass "()" for the format, and to call a function with one argument, surround the argument in parentheses, e.g. "(i)".</p> </div> <div class="section" id="how-do-i-catch-the-output-from-pyerr-print-or-anything-that-prints-to-stdout-stderr"> <h1><a class="toc-backref" href="#id15">9 How do I catch the output from PyErr_Print() (or anything that prints to stdout/stderr)?</a></h1> <p>In Python code, define an object that supports the <tt class="docutils literal">write()</tt> method. Assign this object to <tt class="docutils literal">sys.stdout</tt> and <tt class="docutils literal">sys.stderr</tt>. Call print_error, or just allow the standard traceback mechanism to work. Then, the output will go wherever your <tt class="docutils literal">write()</tt> method sends it.</p> <p>The easiest way to do this is to use the StringIO class in the standard library.</p> <p>Sample code and use for catching stdout:</p> <pre class="literal-block"> >>> class StdoutCatcher: ... def __init__(self): ... self.data = '' ... def write(self, stuff): ... self.data = self.data + stuff ... >>> import sys >>> sys.stdout = StdoutCatcher() >>> print 'foo' >>> print 'hello world!' >>> sys.stderr.write(sys.stdout.data) foo hello world! </pre> </div> <div class="section" id="how-do-i-access-a-module-written-in-python-from-c"> <h1><a class="toc-backref" href="#id16">10 How do I access a module written in Python from C?</a></h1> <p>You can get a pointer to the module object as follows:</p> <pre class="literal-block"> module = PyImport_ImportModule("<modulename>"); </pre> <p>If the module hasn't been imported yet (i.e. it is not yet present in <tt class="docutils literal">sys.modules</tt>), this initializes the module; otherwise it simply returns the value of <tt class="docutils literal"><span class="pre">sys.modules["<modulename>"]</span></tt>. Note that it doesn't enter the module into any namespace -- it only ensures it has been initialized and is stored in <tt class="docutils literal">sys.modules</tt>.</p> <p>You can then access the module's attributes (i.e. any name defined in the module) as follows:</p> <pre class="literal-block"> attr = PyObject_GetAttrString(module, "<attrname>"); </pre> <p>Calling <tt class="docutils literal">PyObject_SetAttrString()</tt> to assign to variables in the module also works.</p> </div> <div class="section" id="how-do-i-interface-to-c-objects-from-python"> <h1><a class="toc-backref" href="#id17">11 How do I interface to C++ objects from Python?</a></h1> <p>Depending on your requirements, there are many approaches. To do this manually, begin by reading <a class="reference external" href="http://docs.python.org/ext/ext.html">the "Extending and Embedding" document</a>. Realize that for the Python run-time system, there isn't a whole lot of difference between C and C++ -- so the strategy of building a new Python type around a C structure (pointer) type will also work for C++ objects.</p> <p>For C++ libraries, you can look at <a class="reference external" href="http://www.riverbankcomputing.co.uk/sip/">SIP</a>, <a class="reference external" href="http://cxx.sourceforge.net/">CXX</a>, <a class="reference external" href="http://www.boost.org/libs/python/doc/index.html">Boost</a>, or <a class="reference external" href="http://www.scipy.org/site_content/weave">Weave</a>. <a class="reference external" href="http://www.swig.org">SWIG</a> is a similar automated tool that only supports C libraries.</p> </div> <div class="section" id="i-added-a-module-using-the-setup-file-and-the-make-fails-why"> <h1><a class="toc-backref" href="#id18">12 I added a module using the Setup file and the make fails; why?</a></h1> <p>Setup must end in a newline, if there is no newline there, the build process fails. (Fixing this requires some ugly shell script hackery, and this bug is so minor that it doesn't seem worth the effort.)</p> </div> <div class="section" id="how-do-i-debug-an-extension"> <h1><a class="toc-backref" href="#id19">13 How do I debug an extension?</a></h1> <p>When using GDB with dynamically loaded extensions, you can't set a breakpoint in your extension until your extension is loaded.</p> <p>In your <tt class="docutils literal">.gdbinit</tt> file (or interactively), add the command:</p> <pre class="literal-block"> br _PyImport_LoadDynamicModule </pre> <p>Then, when you run GDB:</p> <pre class="literal-block"> $ gdb /local/bin/python gdb) run myscript.py gdb) continue # repeat until your extension is loaded gdb) finish # so that your extension is loaded gdb) br myfunction.c:50 gdb) continue </pre> </div> <div class="section" id="i-want-to-compile-a-python-module-on-my-linux-system-but-some-files-are-missing-why"> <h1><a class="toc-backref" href="#id20">14 I want to compile a Python module on my Linux system, but some files are missing. Why?</a></h1> <p>Most packaged versions of Python don't include the /usr/lib/python2.x/config/ directory, which contains various files required for compiling Python extensions.</p> <p>For Red Hat, install the python-devel RPM to get the necessary files.</p> <p>For Debian, run <tt class="docutils literal"><span class="pre">apt-get</span> install <span class="pre">python-dev</span></tt>.</p> </div> <div class="section" id="what-does-systemerror-pyimport-fixupextension-module-yourmodule-not-loaded-mean"> <h1><a class="toc-backref" href="#id21">15 What does "SystemError: _PyImport_FixupExtension: module yourmodule not loaded" mean?</a></h1> <p>This means that you have created an extension module named "yourmodule", but your module init function does not initialize with that name.</p> <p>Every module init function will have a line similar to:</p> <pre class="literal-block"> module = Py_InitModule("yourmodule", yourmodule_functions); </pre> <p>If the string passed to this function is not the same name as your extenion module, the <tt class="docutils literal">SystemError</tt> exception will be raised.</p> </div> <div class="section" id="how-do-i-tell-incomplete-input-from-invalid-input"> <h1><a class="toc-backref" href="#id22">16 How do I tell "incomplete input" from "invalid input"?</a></h1> <p>Sometimes you want to emulate the Python interactive interpreter's behavior, where it gives you a continuation prompt when the input is incomplete (e.g. you typed the start of an "if" statement or you didn't close your parentheses or triple string quotes), but it gives you a syntax error message immediately when the input is invalid.</p> <p>In Python you can use the <tt class="docutils literal">codeop</tt> module, which approximates the parser's behavior sufficiently. IDLE uses this, for example.</p> <p>The easiest way to do it in C is to call <tt class="docutils literal">PyRun_InteractiveLoop()</tt> (perhaps in a separate thread) and let the Python interpreter handle the input for you. You can also set the <tt class="docutils literal">PyOS_ReadlineFunctionPointer</tt> to point at your custom input function. See <tt class="docutils literal">Modules/readline.c</tt> and <tt class="docutils literal">Parser/myreadline.c</tt> for more hints.</p> <p>However sometimes you have to run the embedded Python interpreter in the same thread as your rest application and you can't allow the <tt class="docutils literal">PyRun_InteractiveLoop()</tt> to stop while waiting for user input. The one solution then is to call <tt class="docutils literal">PyParser_ParseString()</tt> and test for <tt class="docutils literal">e.error</tt> equal to <tt class="docutils literal">E_EOF</tt>, which means the input is incomplete). Here's a sample code fragment, untested, inspired by code from Alex Farber:</p> <pre class="literal-block"> #include <Python.h> #include <node.h> #include <errcode.h> #include <grammar.h> #include <parsetok.h> #include <compile.h> int testcomplete(char *code) /* code should end in \n */ /* return -1 for error, 0 for incomplete, 1 for complete */ { node *n; perrdetail e; n = PyParser_ParseString(code, &_PyParser_Grammar, Py_file_input, &e); if (n == NULL) { if (e.error == E_EOF) return 0; return -1; } PyNode_Free(n); return 1; } </pre> <p>Another solution is trying to compile the received string with <tt class="docutils literal">Py_CompileString()</tt>. If it compiles without errors, try to execute the returned code object by calling <tt class="docutils literal">PyEval_EvalCode()</tt>. Otherwise save the input for later. If the compilation fails, find out if it's an error or just more input is required - by extracting the message string from the exception tuple and comparing it to the string "unexpected EOF while parsing". Here is a complete example using the GNU readline library (you may want to ignore SIGINT while calling readline()):</p> <pre class="literal-block"> #include <stdio.h> #include <readline.h> #include <Python.h> #include <object.h> #include <compile.h> #include <eval.h> int main (int argc, char* argv[]) { int i, j, done = 0; /* lengths of line, code */ char ps1[] = ">>> "; char ps2[] = "... "; char *prompt = ps1; char *msg, *line, *code = NULL; PyObject *src, *glb, *loc; PyObject *exc, *val, *trb, *obj, *dum; Py_Initialize (); loc = PyDict_New (); glb = PyDict_New (); PyDict_SetItemString (glb, "__builtins__", PyEval_GetBuiltins ()); while (!done) { line = readline (prompt); if (NULL == line) /* CTRL-D pressed */ { done = 1; } else { i = strlen (line); if (i > 0) add_history (line); /* save non-empty lines */ if (NULL == code) /* nothing in code yet */ j = 0; else j = strlen (code); code = realloc (code, i + j + 2); if (NULL == code) /* out of memory */ exit (1); if (0 == j) /* code was empty, so */ code[0] = '\0'; /* keep strncat happy */ strncat (code, line, i); /* append line to code */ code[i + j] = '\n'; /* append '\n' to code */ code[i + j + 1] = '\0'; src = Py_CompileString (code, "<stdin>", Py_single_input); if (NULL != src) /* compiled just fine - */ { if (ps1 == prompt || /* ">>> " or */ '\n' == code[i + j - 1]) /* "... " and double '\n' */ { /* so execute it */ dum = PyEval_EvalCode ((PyCodeObject *)src, glb, loc); Py_XDECREF (dum); Py_XDECREF (src); free (code); code = NULL; if (PyErr_Occurred ()) PyErr_Print (); prompt = ps1; } } /* syntax error or E_EOF? */ else if (PyErr_ExceptionMatches (PyExc_SyntaxError)) { PyErr_Fetch (&exc, &val, &trb); /* clears exception! */ if (PyArg_ParseTuple (val, "sO", &msg, &obj) && !strcmp (msg, "unexpected EOF while parsing")) /* E_EOF */ { Py_XDECREF (exc); Py_XDECREF (val); Py_XDECREF (trb); prompt = ps2; } else /* some other syntax error */ { PyErr_Restore (exc, val, trb); PyErr_Print (); free (code); code = NULL; prompt = ps1; } } else /* some non-syntax error */ { PyErr_Print (); free (code); code = NULL; prompt = ps1; } free (line); } } Py_XDECREF(glb); Py_XDECREF(loc); Py_Finalize(); exit(0); } </pre> </div> <div class="section" id="how-do-i-find-undefined-g-symbols-builtin-new-or-pure-virtual"> <h1><a class="toc-backref" href="#id23">17 How do I find undefined g++ symbols __builtin_new or __pure_virtual?</a></h1> <p>To dynamically load g++ extension modules, you must recompile Python, relink it using g++ (change LINKCC in the python Modules Makefile), and link your extension module using g++ (e.g., "g++ -shared -o mymodule.so mymodule.o").</p> </div> <div class="section" id="can-i-create-an-object-class-with-some-methods-implemented-in-c-and-others-in-python-e-g-through-inheritance"> <h1><a class="toc-backref" href="#id24">18 Can I create an object class with some methods implemented in C and others in Python (e.g. through inheritance)?</a></h1> <p>In Python 2.2, you can inherit from builtin classes such as int, list, dict, etc.</p> <p>The Boost Python Library (BPL, <a class="reference external" href="http://www.boost.org/libs/python/doc/index.html">http://www.boost.org/libs/python/doc/index.html</a>) provides a way of doing this from C++ (i.e. you can inherit from an extension class written in C++ using the BPL).</p> </div> <div class="section" id="when-importing-module-x-why-do-i-get-undefined-symbol-pyunicodeucs2"> <h1><a class="toc-backref" href="#id25">19 When importing module X, why do I get "undefined symbol: PyUnicodeUCS2*"?</a></h1> <p>You are using a version of Python that uses a 4-byte representation for Unicode characters, but some C extension module you are importing was compiled using a Python that uses a 2-byte representation for Unicode characters (the default).</p> <p>If instead the name of the undefined symbol starts with <tt class="docutils literal">PyUnicodeUCS4</tt>, the problem is the reverse: Python was built using 2-byte Unicode characters, and the extension module was compiled using a Python with 4-byte Unicode characters.</p> <p>This can easily occur when using pre-built extension packages. RedHat Linux 7.x, in particular, provided a "python2" binary that is compiled with 4-byte Unicode. This only causes the link failure if the extension uses any of the <tt class="docutils literal"><span class="pre">PyUnicode_*()</span></tt> functions. It is also a problem if an extension uses any of the Unicode-related format specifiers for <tt class="docutils literal">Py_BuildValue</tt> (or similar) or parameter specifications for <tt class="docutils literal">PyArg_ParseTuple()</tt>.</p> <p>You can check the size of the Unicode character a Python interpreter is using by checking the value of sys.maxunicode:</p> <pre class="literal-block"> >>> import sys >>> if sys.maxunicode > 65535: ... print 'UCS4 build' ... else: ... print 'UCS2 build' </pre> <p>The only way to solve this problem is to use extension modules compiled with a Python binary built using the same size for Unicode characters.</p> </div> </div> </body> </html>