-
-
Notifications
You must be signed in to change notification settings - Fork 564
/
capi.txt
94 lines (69 loc) · 2.85 KB
/
capi.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
==============================
The public C-API of lxml.etree
==============================
As of version 1.1, lxml.etree provides a public C-API. This allows external
C extensions to efficiently access public functions and classes of lxml,
without going through the Python API.
The API is described in the file `etreepublic.pxd`_, which is directly
c-importable by extension modules implemented in Pyrex_ or Cython_.
.. _`etreepublic.pxd`: https://github.com/lxml/lxml/blob/master/src/lxml/include/etreepublic.pxd
.. _Cython: http://cython.org
.. _Pyrex: http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/
.. contents::
..
1 Writing external modules in Cython
2 Writing external modules in C
Writing external modules in Cython
----------------------------------
This is the easiest way of extending lxml at the C level. A Cython_
(or Pyrex_) module should start like this::
# My Cython extension
# import the public functions and classes of lxml.etree
cimport etreepublic as cetree
# import the lxml.etree module in Python
cdef object etree
from lxml import etree
# initialize the access to the C-API of lxml.etree
cetree.import_lxml__etree()
From this line on, you can access all public functions of lxml.etree
from the ``cetree`` namespace like this::
# build a tag name from namespace and element name
py_tag = cetree.namespacedNameFromNsName("http://some/url", "myelement")
Public lxml classes are easily subclassed. For example, to implement
and set a new default element class, you can write Cython code like
the following::
from etreepublic cimport ElementBase
cdef class NewElementClass(ElementBase):
def set_value(self, myval):
self.set("my_attribute", myval)
etree.set_element_class_lookup(
etree.DefaultElementClassLookup(element=NewElementClass))
Writing external modules in C
-----------------------------
If you really feel like it, you can also interface with lxml.etree straight
from C code. All you have to do is include the header file for the public
API, import the ``lxml.etree`` module and then call the import function:
.. sourcecode:: c
/* My C extension */
/* common includes */
#include "Python.h"
#include "stdio.h"
#include "string.h"
#include "stdarg.h"
#include "libxml/xmlversion.h"
#include "libxml/encoding.h"
#include "libxml/hash.h"
#include "libxml/tree.h"
#include "libxml/xmlIO.h"
#include "libxml/xmlsave.h"
#include "libxml/globals.h"
#include "libxml/xmlstring.h"
/* lxml.etree specific includes */
#include "lxml-version.h"
#include "etree_defs.h"
#include "etree.h"
/* setup code */
import_lxml__etree()
Note that including ``etree.h`` does not automatically include the
header files it requires. Note also that the above list of common
includes may not be sufficient.