Commit 39df7ffd authored by scoder's avatar scoder Committed by GitHub

Merge pull request #1578 from mathbunnyru/delete_trailing_spaces

Delete trailing spaces
parents 4374001f 2748f9ef
......@@ -71,7 +71,7 @@ def runcmd(cmd, shell=True):
returncode = os.system(cmd)
else:
returncode = subprocess.call(cmd, shell=shell)
if returncode:
sys.exit(returncode)
......
......@@ -65,7 +65,7 @@ changes/contributions they have specific copyright on, they should indicate
their copyright in the commit message of the change, when they commit the
change to one of the IPython repositories.
With this in mind, the following banner should be used in any source code file
With this in mind, the following banner should be used in any source code file
to indicate the copyright and license terms:
::
......
......@@ -85,7 +85,7 @@ class DeclarationWriter(TreeVisitor):
def visit_StatListNode(self, node):
self.visitchildren(node)
def visit_CDefExternNode(self, node):
if node.include_file is None:
file = u'*'
......@@ -516,6 +516,6 @@ class PxdWriter(DeclarationWriter):
if node.api:
self.put(u'api ')
self.visit(node.declarator)
def visit_StatNode(self, node):
pass
......@@ -13,7 +13,7 @@ class TestMemviewParsing(CythonTest):
def not_parseable(self, expected_error, s):
e = self.should_fail(lambda: self.fragment(s), Errors.CompileError)
self.assertEqual(expected_error, e.message_only)
def test_default_1dim(self):
self.parse(u"cdef int[:] x")
self.parse(u"cdef short int[:] x")
......
......@@ -12,9 +12,9 @@ python_var = 13
def spam(a=0):
cdef:
int b, c
b = c = d = 0
b = 1
c = 2
int(10)
......@@ -23,11 +23,11 @@ def spam(a=0):
some_c_function()
cpdef eggs():
pass
pass
cdef ham():
pass
cdef class SomeClass(object):
def spam(self):
pass
......
......@@ -2517,8 +2517,8 @@ class FixGdbCommand(gdb.Command):
def fix_gdb(self):
"""
It seems that invoking either 'cy exec' and 'py-exec' work perfectly
fine, but after this gdb's python API is entirely broken.
It seems that invoking either 'cy exec' and 'py-exec' work perfectly
fine, but after this gdb's python API is entirely broken.
Maybe some uncleared exception value is still set?
sys.exc_clear() didn't help. A demonstration:
......
"""
array.pxd
Cython interface to Python's array.array module.
* 1D contiguous data view
* tools for fast array creation, maximum C-speed and handiness
* suitable as allround light weight auto-array within Cython code too
Usage:
>>> cimport array
Usage through Cython buffer interface (Py2.3+):
Usage through Cython buffer interface (Py2.3+):
>>> def f(arg1, unsigned i, double dx)
... array.array[double] a = arg1
... a[i] += dx
Fast C-level new_array(_zeros), resize_array, copy_array, Py_SIZE(obj),
zero_array
cdef array.array[double] k = array.copy(d)
cdef array.array[double] k = array.copy(d)
cdef array.array[double] n = array.array(d, Py_SIZE(d) * 2 )
cdef array.array[double] m = array.zeros_like(FLOAT_TEMPLATE)
array.resize(f, 200000)
Zero overhead with naked data pointer views by union:
_f, _d, _i, _c, _u, ...
Zero overhead with naked data pointer views by union:
_f, _d, _i, _c, _u, ...
=> Original C array speed + Python dynamic memory management
cdef array.array a = inarray
if
if
a._d[2] += 0.66 # use as double array without extra casting
float *subview = vector._f + 10 # starting from 10th element
unsigned char *subview_buffer = vector._B + 4
Suitable as lightweight arrays intra Cython without speed penalty.
Replacement for C stack/malloc arrays; no trouble with refcounting,
unsigned char *subview_buffer = vector._B + 4
Suitable as lightweight arrays intra Cython without speed penalty.
Replacement for C stack/malloc arrays; no trouble with refcounting,
mem.leaks; seamless Python compatibility, buffer() optional
last changes: 2009-05-15 rk
: 2009-12-06 bp
......
......@@ -5,7 +5,7 @@ cdef extern from "Python.h":
pass
cdef extern from "datetime.h":
ctypedef extern class datetime.date[object PyDateTime_Date]:
pass
......@@ -23,11 +23,11 @@ cdef extern from "datetime.h":
ctypedef struct PyDateTime_Date:
pass
ctypedef struct PyDateTime_Time:
char hastzinfo
PyObject *tzinfo
ctypedef struct PyDateTime_DateTime:
char hastzinfo
PyObject *tzinfo
......@@ -36,22 +36,22 @@ cdef extern from "datetime.h":
int days
int seconds
int microseconds
# Define structure for C API.
ctypedef struct PyDateTime_CAPI:
# type objects
# type objects
PyTypeObject *DateType
PyTypeObject *DateTimeType
PyTypeObject *TimeType
PyTypeObject *DeltaType
PyTypeObject *TZInfoType
# constructors
object (*Date_FromDate)(int, int, int, PyTypeObject*)
object (*DateTime_FromDateAndTime)(int, int, int, int, int, int, int, object, PyTypeObject*)
object (*Time_FromTime)(int, int, int, int, object, PyTypeObject*)
object (*Delta_FromDelta)(int, int, int, int, PyTypeObject*)
# constructors for the DB API
object (*DateTime_FromTimestamp)(object, object, object)
object (*Date_FromTimestamp)(object, object)
......@@ -96,7 +96,7 @@ cdef extern from "datetime.h":
# PyDateTime CAPI object.
PyDateTime_CAPI *PyDateTimeAPI
void PyDateTime_IMPORT()
# Datetime C API initialization function.
......@@ -108,7 +108,7 @@ cdef inline void import_datetime():
# Note, there are no range checks for any of the arguments.
cdef inline object date_new(int year, int month, int day):
return PyDateTimeAPI.Date_FromDate(year, month, day, PyDateTimeAPI.DateType)
# Create time object using DateTime CAPI factory function
# Note, there are no range checks for any of the arguments.
cdef inline object time_new(int hour, int minute, int second, int microsecond, object tz):
......@@ -127,7 +127,7 @@ cdef inline object timedelta_new(int days, int seconds, int useconds):
# More recognizable getters for date/time/datetime/timedelta.
# There are no setters because datetime.h hasn't them.
# This is because of immutable nature of these objects by design.
# If you would change time/date/datetime/timedelta object you need to recreate.
# If you would change time/date/datetime/timedelta object you need to recreate.
# Get tzinfo of time
cdef inline object time_tzinfo(object o):
......@@ -136,7 +136,7 @@ cdef inline object time_tzinfo(object o):
else:
return None
# Get tzinfo of datetime
# Get tzinfo of datetime
cdef inline object datetime_tzinfo(object o):
if (<PyDateTime_DateTime*>o).hastzinfo:
return <object>(<PyDateTime_DateTime*>o).tzinfo
......@@ -146,7 +146,7 @@ cdef inline object datetime_tzinfo(object o):
# Get year of date
cdef inline int date_year(object o):
return PyDateTime_GET_YEAR(o)
# Get month of date
cdef inline int date_month(object o):
return PyDateTime_GET_MONTH(o)
......@@ -158,7 +158,7 @@ cdef inline int date_day(object o):
# Get year of datetime
cdef inline int datetime_year(object o):
return PyDateTime_GET_YEAR(o)
# Get month of datetime
cdef inline int datetime_month(object o):
return PyDateTime_GET_MONTH(o)
......
......@@ -14,7 +14,7 @@ cdef extern from "<iterator>" namespace "std" nogil:
pass
cdef cppclass random_access_iterator_tag(bidirectional_iterator_tag):
pass
cdef cppclass back_insert_iterator[T](iterator[output_iterator_tag,void,void,void,void]):
pass
cdef cppclass front_insert_iterator[T](iterator[output_iterator_tag,void,void,void,void]):
......@@ -29,4 +29,4 @@ cdef extern from "<iterator>" namespace "std" nogil:
##insert_iterator<Container> inserter (Container& x, typename Container::iterator it)
insert_iterator[CONTAINER] inserter[CONTAINER,ITERATOR](CONTAINER &, ITERATOR)
......@@ -5,7 +5,7 @@ cdef extern from "<limits>" namespace "std" nogil:
round_to_nearest = 1
round_toward_infinity = 2
round_toward_neg_infinity = 3
enum float_denorm_style:
denorm_indeterminate = -1
denorm_absent = 0
......@@ -37,7 +37,7 @@ cdef extern from "<limits>" namespace "std" nogil:
const int min_exponent10
const int max_exponent
const int max_exponent10
const bint has_infinity
const bint has_quiet_NaN
const bint has_signaling_NaN
......
......@@ -16,8 +16,8 @@ cdef extern from "<memory>" namespace "std" nogil:
void construct( T *, const T &) #C++98. The C++11 version is variadic AND perfect-forwarding
void destroy(T *) #C++98
void destroy[U](U *) #unique_ptr unit tests fail w/this
cdef cppclass unique_ptr[T,DELETER=*]:
unique_ptr()
unique_ptr(nullptr_t)
......
......@@ -113,7 +113,7 @@ class Template(object):
self.default_namespace['start_braces'] = delimeters[0]
self.default_namespace['end_braces'] = delimeters[1]
self.delimeters = delimeters
self._unicode = is_unicode(content)
if name is None and stacklevel is not None:
try:
......
......@@ -129,7 +129,7 @@ class TestJediTyper(TransformTest):
variables = types.pop((None, (1, 0)))
self.assertFalse(types)
self.assertEqual({'a': set(['list']), 'b': set(['list']), 'c': set(['list']), 'd': set(['list'])}, variables)
def test_typing_function_list(self):
code = '''\
def func(x):
......@@ -149,14 +149,14 @@ class TestJediTyper(TransformTest):
code = '''\
a = dict()
b = {i: i**2 for i in range(10)}
c = a
c = a
'''
types = self._test(code)
self.assertIn((None, (1, 0)), types)
variables = types.pop((None, (1, 0)))
self.assertFalse(types)
self.assertEqual({'a': set(['dict']), 'b': set(['dict']), 'c': set(['dict'])}, variables)
def test_typing_function_dict(self):
code = '''\
def func(x):
......@@ -186,7 +186,7 @@ class TestJediTyper(TransformTest):
variables = types.pop((None, (1, 0)))
self.assertFalse(types)
self.assertEqual({'a': set(['set']), 'c': set(['set']), 'd': set(['set']), 'e': set(['set'])}, variables)
def test_typing_function_set(self):
code = '''\
def func(x):
......
......@@ -29,7 +29,7 @@ typedef struct arraydescr {
int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
#if PY_MAJOR_VERSION >= 3
char *formats;
#endif
#endif
} arraydescr;
......@@ -110,7 +110,7 @@ static CYTHON_INLINE int resize(arrayobject *self, Py_ssize_t n) {
if (items == NULL) {
PyErr_NoMemory();
return -1;
}
}
self->data.ob_item = (char*) items;
self->ob_size = n;
self->allocated = n;
......
......@@ -24,12 +24,12 @@
make
./nCr 10 5
./python
* Build notes
* benchmarks/chaos.py requires cython 0.24 or newer
* embed and freeze work for python2, require cython 0.24 or higher
for python 3.5
#!/usr/bin/python
# Back-Propagation Neural Networks
#
#
# Written in Python. See http://www.python.org/
#
# Neil Schemenauer <nascheme@enme.ucalgary.ca>
......@@ -26,7 +26,7 @@ def makeMatrix(I, J, fill=0.0):
return m
class NN(object):
# print 'class NN'
# print 'class NN'
def __init__(self, ni, nh, no):
# number of input, hidden, and output nodes
self.ni = ni + 1 # +1 for bias node
......@@ -37,7 +37,7 @@ class NN(object):
self.ai = [1.0]*self.ni
self.ah = [1.0]*self.nh
self.ao = [1.0]*self.no
# create weights
self.wi = makeMatrix(self.ni, self.nh)
self.wo = makeMatrix(self.nh, self.no)
......@@ -49,7 +49,7 @@ class NN(object):
for k in range(self.no):
self.wo[j][k] = rand(-2.0, 2.0)
# last change in weights for momentum
# last change in weights for momentum
self.ci = makeMatrix(self.ni, self.nh)
self.co = makeMatrix(self.nh, self.no)
......
......@@ -17,7 +17,7 @@ class Dir(object):
def __init__(self, x, y):
self.x = x
self.y = y
DIRS = [ Dir(1, 0),
Dir(-1, 0),
Dir(0, 1),
......@@ -35,7 +35,7 @@ class Done(object):
FIRST_STRATEGY = 3
MAX_NEIGHBORS_STRATEGY = 4
MIN_NEIGHBORS_STRATEGY = 5
def __init__(self, count, empty=False):
self.count = count
self.cells = None if empty else [[0, 1, 2, 3, 4, 5, 6, EMPTY] for i in range(count)]
......@@ -60,11 +60,11 @@ class Done(object):
return True
else:
return False
def remove_all(self, v):
for i in range(self.count):
self.remove(i, v)
def remove_unfixed(self, v):
changed = False
for i in range(self.count):
......@@ -72,7 +72,7 @@ class Done(object):
if self.remove(i, v):
changed = True
return changed
def filter_tiles(self, tiles):
for v in range(8):
if tiles[v] == 0:
......@@ -206,14 +206,14 @@ class Hex(object):
def contains_pos(self, pos):
return pos in self.nodes_by_pos
def get_by_pos(self, pos):
return self.nodes_by_pos[pos]
def get_by_id(self, id):
return self.nodes_by_id[id]
##################################
class Pos(object):
def __init__(self, hex, tiles, done = None):
......@@ -223,7 +223,7 @@ class Pos(object):
def clone(self):
return Pos(self.hex, self.tiles, self.done.clone())
##################################
@cython.locals(pos=Pos, i=cython.long, v=cython.int,
......@@ -260,7 +260,7 @@ def constraint_pass(pos, last_move=None):
for cell in done.cells:
if len(cell) == 1:
left[cell[0]] -= 1
for v in range(8):
# If there is none, remove the possibility from all tiles
if (pos.tiles[v] > 0) and (left[v] == 0):
......@@ -276,7 +276,7 @@ def constraint_pass(pos, last_move=None):
if (not done.already_done(i)) and (v in cell):
done.set_done(i, v)
changed = True
# Force empty or non-empty around filled cells
filled_cells = (range(done.count) if last_move is None
else [last_move])
......@@ -307,7 +307,7 @@ def constraint_pass(pos, last_move=None):
for u in unknown:
if done.remove(u, EMPTY):
changed = True
return changed
ASCENDING = 1
......@@ -402,7 +402,7 @@ def solved(pos, output, verbose=False):
if (not all_done) or (not exact):
return OPEN
print_pos(pos, output)
return SOLVED
......@@ -414,7 +414,7 @@ def solve_step(prev, strategy, order, output, first=False):
pass
else:
pos = prev
moves = find_moves(pos, strategy, order)
if len(moves) == 0:
return solved(pos, output)
......@@ -481,12 +481,12 @@ def read_file(file):
else:
inctile = int(tile)
tiles[inctile] += 1
# Look for locked tiles
# Look for locked tiles
if tile[0] == "+":
print("Adding locked tile: %d at pos %d, %d, id=%d" %
(inctile, x, y, hex.get_by_pos((x, y)).id))
done.set_done(hex.get_by_pos((x, y)).id, inctile)
linei += 1
for y in range(1, size):
ry = size - 1 + y
......@@ -500,7 +500,7 @@ def read_file(file):
else:
inctile = int(tile)
tiles[inctile] += 1
# Look for locked tiles
# Look for locked tiles
if tile[0] == "+":
print("Adding locked tile: %d at pos %d, %d, id=%d" %
(inctile, x, ry, hex.get_by_pos((x, ry)).id))
......@@ -530,13 +530,13 @@ def run_level36():
output = StringIO()
solve_file(f, strategy, order, output)
expected = """\
3 4 3 2
3 4 4 . 3
2 . . 3 4 3
2 . 1 . 3 . 2
3 3 . 2 . 2
3 . 2 . 2
2 2 . 1
3 4 3 2
3 4 4 . 3
2 . . 3 4 3
2 . 1 . 3 . 2
3 3 . 2 . 2
3 . 2 . 2
2 2 . 1
"""
if output.getvalue() != expected:
raise AssertionError("got a wrong answer:\n%s" % output.getvalue())
......
......@@ -143,7 +143,7 @@ def main(n):
tk = time.time()
times.append(tk - t0)
return times
if __name__ == "__main__":
parser = optparse.OptionParser(
usage="%prog [options]",
......
......@@ -102,13 +102,13 @@ class TaskState(object):
self.task_waiting = False
self.task_holding = False
return self
def waitingWithPacket(self):
self.packet_pending = True
self.task_waiting = True
self.task_holding = False
return self
def isPacketPending(self):
return self.packet_pending
......@@ -233,7 +233,7 @@ class Task(TaskState):
if t is None:
raise Exception("Bad task id %d" % id)
return t
# DeviceTask
......@@ -307,7 +307,7 @@ class IdleTask(Task):
else:
i.control = i.control//2 ^ 0xd008
return self.release(I_DEVB)
# WorkTask
......@@ -385,7 +385,7 @@ class Richards(object):
wkq = None;
DeviceTask(I_DEVA, 4000, wkq, TaskState().waiting(), DeviceTaskRec());
DeviceTask(I_DEVB, 5000, wkq, TaskState().waiting(), DeviceTaskRec());
schedule()
if taskWorkArea.holdCount == 9297 and taskWorkArea.qpktCount == 23246:
......@@ -431,7 +431,7 @@ else:
for it in item.__dict__.values():
if isinstance(it, types.FunctionType):
pypyjit.enable(it.func_code)
if __name__ == '__main__':
import sys
if len(sys.argv) >= 2:
......
......@@ -55,7 +55,7 @@ def main(n):
tk = time()
times.append(tk - t0)
return times
if __name__ == "__main__":
parser = optparse.OptionParser(
usage="%prog [options]",
......
......@@ -8,7 +8,7 @@ cdef extern from "cheesefinder.h":
def find(f):
find_cheeses(callback, <void*>f)
cdef void callback(char *name, void *f):
(<object>f)(name.decode('utf-8'))
......@@ -18,7 +18,7 @@ except:
print("Error building external library, please create libmymath.a manually.")
sys.exit(1)
# Here is how to use the library built above.
# Here is how to use the library built above.
ext_modules = cythonize([
Extension("call_mymath",
sources=["call_mymath.pyx"],
......
......@@ -4,7 +4,7 @@
<meta name="GENERATOR" content="Mozilla/4.51 (Macintosh; I; PPC) [Netscape]"><title>FAQ.html</title></head>
<body>
<center> <h1> <hr width="100%">Cython FAQ
<center> <h1> <hr width="100%">Cython FAQ
<hr width="100%"></h1>
</center>
<h2> Contents</h2>
......@@ -21,22 +21,22 @@
</ul>
<hr width="100%"> <h2> <a name="CallCAPI"></a>How do I call Python/C API routines?</h2>
Declare them as C functions inside a <tt>cdef extern from</tt> block.
Use the type name <tt>object</tt> for any parameters and return types which
are Python object references. Don't use the word <tt>const</tt> anywhere.
Here is an example which defines and uses the <tt>PyString_FromStringAndSize</tt> routine:
Use the type name <tt>object</tt> for any parameters and return types which
are Python object references. Don't use the word <tt>const</tt> anywhere.
Here is an example which defines and uses the <tt>PyString_FromStringAndSize</tt> routine:
<blockquote><tt>cdef extern from "Python.h":</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; object PyString_FromStringAndSize(char *, int)</tt> <p><tt>cdef char buf[42]</tt> <br>
<tt>my_string = PyString_FromStringAndSize(buf, 42)</tt></p>
</blockquote>
<h2> <a name="NullBytes"></a>How do I convert a C string containing null
bytes to a Python string?</h2>
Put in a declaration for the <tt>PyString_FromStringAndSize</tt> API routine
and use that<tt>.</tt> See <a href="#CallCAPI">How do I call Python/C API
Put in a declaration for the <tt>PyString_FromStringAndSize</tt> API routine
and use that<tt>.</tt> See <a href="#CallCAPI">How do I call Python/C API
routines?</a> <h2> <a name="NumericAccess"></a>How do I access the data inside a Numeric
array object?</h2>
Use a <tt>cdef extern from</tt> block to include the Numeric header file
and declare the array object as an external extension type. The following
code illustrates how to do this:
Use a <tt>cdef extern from</tt> block to include the Numeric header file
and declare the array object as an external extension type. The following
code illustrates how to do this:
<blockquote><tt>cdef extern from "Numeric/arrayobject.h":</tt> <p><tt>&nbsp;&nbsp;&nbsp; struct PyArray_Descr:</tt> <br>
<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int type_num, elsize</tt> <br>
<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char type</tt> </p>
......@@ -73,5 +73,5 @@ section of the <a href="extension_types.html">"Extension
Types"</a> documentation page.<br>
<h2><a name="Quack"></a>Python says my extension type has no method called 'quack', but I know it does. What gives?</h2>
You may have declared the method using <span style="font-family: monospace;">cdef</span> instead of <span style="font-family: monospace;">def</span>. Only functions and methods declared with <span style="font-family: monospace;">def</span> are callable from Python code.<br>
---
---
</body></html>
\ No newline at end of file
......@@ -3,7 +3,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.61 (Macintosh; I; PPC) [Netscape]"><title>Extension Types</title></head>
<body>
<h1> <hr width="100%">Extension Types
<h1> <hr width="100%">Extension Types
<hr width="100%"></h1>
<h2> Contents</h2>
<ul>
......@@ -11,7 +11,7 @@
<li> <a href="#ExtTypeAttrs">Attributes</a></li>
<li> <a href="#NotNone">Extension types and None</a></li>
<li> <a href="special_methods.html">Special methods</a></li>
<li> <a href="#Properties">Properties</a> <font style="color: rgb(0, 153, 0);" color="#ed181e">(NEW in
<li> <a href="#Properties">Properties</a> <font style="color: rgb(0, 153, 0);" color="#ed181e">(NEW in
0.9)</font></li>
<li><a href="#SubclassingExtTypes">Subclassing</a></li>
<li> <a href="#CMethods">C Methods</a> <font style="color: rgb(0, 153, 0);" color="#ff0000">(NEW in 0.9)</font><br>
......@@ -31,14 +31,14 @@
</ul>
<h2> <a name="Introduction"></a>Introduction</h2>
As well as creating normal user-defined classes with the Python <b>class</b>
statement, Cython also lets you create new built-in Python types, known as
<i>extension types</i>. You define an extension type using the <b>cdef class</b> statement. Here's an example:
statement, Cython also lets you create new built-in Python types, known as
<i>extension types</i>. You define an extension type using the <b>cdef class</b> statement. Here's an example:
<blockquote><tt>cdef class Shrubbery:</tt> <p><tt>&nbsp;&nbsp;&nbsp; cdef int width, height</tt> </p>
<p><tt>&nbsp;&nbsp;&nbsp; def __init__(self, w, h):</tt> <br>
<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.width = w</tt> <br>
<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.height = h</tt> </p>
<p><tt>&nbsp;&nbsp;&nbsp; def describe(self):</tt> <br>
<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "This shrubbery is",
<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "This shrubbery is",
self.width, \</tt> <br>
<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
"by", self.height, "cubits."</tt></p>
......@@ -46,8 +46,8 @@ self.width, \</tt> <br>
As you can see, a Cython extension type definition looks a lot like a Python
class definition. Within it, you use the <b>def</b> statement to define
methods that can be called from Python code. You can even define many of
the special methods such as <tt>__init__</tt> as you would in Python.
<p>The main difference is that you can use the <b>cdef</b> statement to define
the special methods such as <tt>__init__</tt> as you would in Python.
<p>The main difference is that you can use the <b>cdef</b> statement to define
attributes. The attributes may be Python objects (either generic or of a particular
extension type), or they may be of any C data type. So you can use extension
types to wrap arbitrary C data structures and provide a Python-like interface
......@@ -56,50 +56,50 @@ to them. </p>
Attributes of an extension type are stored directly in the object's C struct.
The set of attributes is fixed at compile time; you can't add attributes
to an extension type instance at run time simply by assigning to them, as
you could with a Python class instance. (You can subclass the extension type
in Python and add attributes to instances of the subclass, however.)
you could with a Python class instance. (You can subclass the extension type
in Python and add attributes to instances of the subclass, however.)
<p>There are two ways that attributes of an extension type can be accessed:
by Python attribute lookup, or by direct access to the C struct from Cython
code. Python code is only able to access attributes of an extension type
by the first method, but Cython code can use either method. </p>
<p>By default, extension type attributes are only accessible by direct access,
not Python access, which means that they are not accessible from Python code.
<p>By default, extension type attributes are only accessible by direct access,
not Python access, which means that they are not accessible from Python code.
To make them accessible from Python code, you need to declare them as <tt>public</tt> or <tt>readonly</tt>. For example, </p>
<blockquote><tt>cdef class Shrubbery:</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; cdef public int width, height</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; cdef readonly float depth</tt></blockquote>
makes the <tt>width</tt> and <tt>height</tt> attributes readable and writable
from Python code, and the <tt>depth</tt> attribute readable but not writable.
<p>Note that you can only expose simple C types, such as ints, floats and
strings, for Python access. You can also expose Python-valued attributes,
although read-write exposure is only possible for generic Python attributes
(of type <tt>object</tt>). If the attribute is declared to be of an extension
type, it must be exposed <tt>readonly</tt>. </p>
<p>Note also that the <tt>public</tt> and <tt>readonly</tt> options apply
only to <i>Python</i> access, not direct access. All the attributes of an
only to <i>Python</i> access, not direct access. All the attributes of an
extension type are always readable and writable by direct access. </p>
<p>Howerver, for direct access to be possible, the Cython compiler must know
that you have an instance of that type, and not just a generic Python object.
<p>Howerver, for direct access to be possible, the Cython compiler must know
that you have an instance of that type, and not just a generic Python object.
It knows this already in the case of the "self" parameter of the methods of
that type, but in other cases you will have to tell it by means of a declaration.
that type, but in other cases you will have to tell it by means of a declaration.
For example, </p>
<blockquote><tt>cdef widen_shrubbery(Shrubbery sh, extra_width):</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; sh.width = sh.width + extra_width</tt></blockquote>
If you attempt to access an extension type attribute through a generic
object reference, Cython will use a Python attribute lookup. If the attribute
is exposed for Python access (using <tt>public</tt> or <tt>readonly</tt>)
then this will work, but it will be much slower than direct access.
then this will work, but it will be much slower than direct access.
<h2> <a name="NotNone"></a>Extension types and None</h2>
When you declare a parameter or C variable as being of an extension type,
Cython will allow it to take on the value None as well as values of its declared
type. This is analogous to the way a C pointer can take on the value NULL,
and you need to exercise the same caution because of it. There is no problem
as long as you are performing Python operations on it, because full dynamic
type checking will be applied. However, when you access C attributes of an
Cython will allow it to take on the value None as well as values of its declared
type. This is analogous to the way a C pointer can take on the value NULL,
and you need to exercise the same caution because of it. There is no problem
as long as you are performing Python operations on it, because full dynamic
type checking will be applied. However, when you access C attributes of an
extension type (as in the <tt>widen_shrubbery</tt> function above), it's up
to you to make sure the reference you're using is not None -- in the interests
of efficiency, Cython does <i>not</i> check this.
to you to make sure the reference you're using is not None -- in the interests
of efficiency, Cython does <i>not</i> check this.
<p>You need to be particularly careful when exposing Python functions which
take extension types as arguments. If we wanted to make <tt>widen_shrubbery</tt>
a Python function, for example, if we simply wrote </p>
......@@ -107,7 +107,7 @@ a Python function, for example, if we simply wrote </p>
<tt>&nbsp;&nbsp;&nbsp; sh.width = sh.width + extra_width&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
# <font color="#ed181e">dangerous!</font></tt></blockquote>
then users of our module could crash it by passing None for the <tt>sh</tt>
parameter.
parameter.
<p>One way to fix this would be </p>
<blockquote><tt>def widen_shrubbery(Shrubbery sh, extra_width):</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; if sh is None:</tt> <br>
......@@ -115,12 +115,12 @@ parameter.
<tt>&nbsp;&nbsp;&nbsp; sh.width = sh.width + extra_width</tt></blockquote>
but since this is anticipated to be such a frequent requirement, Cython
provides a more convenient way. Parameters of a Python function declared
as an extension type can have a <b><tt>not None</tt></b> clause:
as an extension type can have a <b><tt>not None</tt></b> clause:
<blockquote><tt>def widen_shrubbery(Shrubbery sh not None, extra_width):</tt>
<br>
<tt>&nbsp;&nbsp;&nbsp; sh.width = sh.width + extra_width</tt></blockquote>
Now the function will automatically check that <tt>sh</tt> is not None
along with checking that it has the right type.
along with checking that it has the right type.
<p>Note, however that the <tt>not None</tt> clause can <i>only</i> be used
in Python functions (defined with <tt>def</tt>) and not C functions (defined
with <tt>cdef</tt>). If you need to check whether a parameter to a C function
......@@ -131,19 +131,19 @@ along with checking that it has the right type.
never to be None.</li>
</ul>
<ul>
<li> When comparing a value with None, keep in mind that, if <tt>x</tt> is a Python object, <tt>x is None</tt> and <tt>x is not None</tt> are very
efficient because they translate directly to C pointer comparisons, whereas
<tt>x == None</tt> and <tt>x != None</tt>, or simply using <tt>x</tt> as a boolean value (as in <tt>if x: ...</tt>) will invoke Python operations
<li> When comparing a value with None, keep in mind that, if <tt>x</tt> is a Python object, <tt>x is None</tt> and <tt>x is not None</tt> are very
efficient because they translate directly to C pointer comparisons, whereas
<tt>x == None</tt> and <tt>x != None</tt>, or simply using <tt>x</tt> as a boolean value (as in <tt>if x: ...</tt>) will invoke Python operations
and therefore be much slower.</li>
</ul>
<h2> <a name="ExtTypeSpecialMethods"></a>Special methods</h2>
Although the principles are similar, there are substantial differences
between many of the <span style="font-family: monospace;">__xxx__</span> special methods of extension types and their
Python counterparts. There is a <a href="special_methods.html">separate page</a> devoted to this subject, and you should read it carefully before attempting
to use any special methods in your extension types.
Python counterparts. There is a <a href="special_methods.html">separate page</a> devoted to this subject, and you should read it carefully before attempting
to use any special methods in your extension types.
<h2> <a name="Properties"></a>Properties</h2>
There is a special syntax for defining <b>properties</b> in an extension
class:
class:
<blockquote><tt>cdef class Spam:</tt> <p><tt>&nbsp;&nbsp;&nbsp; property cheese:</tt> </p>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "A doc string can go
here."</tt> </p>
......@@ -166,8 +166,8 @@ here."</tt> </p>
&nbsp;</p>
</blockquote>
The <tt>__get__</tt>, <tt>__set__</tt> and <tt>__del__</tt> methods are
all optional; if they are omitted, an exception will be raised when the corresponding
operation is attempted.
all optional; if they are omitted, an exception will be raised when the corresponding
operation is attempted.
<p>Here's a complete example. It defines a property which adds to a list
each time it is written to, returns the list when it is read, and empties
the list when it is deleted. <br>
......@@ -217,16 +217,16 @@ the list when it is deleted. <br>
</center>
<h2> <a name="SubclassingExtTypes"></a>Subclassing</h2>
An extension type may inherit from a built-in type or another extension
type:
type:
<blockquote><tt>cdef class Parrot:</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; ...</tt><tt></tt> <p><tt>cdef class Norwegian(Parrot):</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; ...</tt></p>
</blockquote>
<p><br>
A complete definition of the base type must be available to Cython, so if
the base type is a built-in type, it must have been previously declared as
an <b>extern</b> extension type. If the base type is defined in another Cython
module, it must either be declared as an extern extension type or imported
A complete definition of the base type must be available to Cython, so if
the base type is a built-in type, it must have been previously declared as
an <b>extern</b> extension type. If the base type is defined in another Cython
module, it must either be declared as an extern extension type or imported
using the <b><a href="sharing.html">cimport</a></b> statement. </p>
<p>An extension type can only have one base class (no multiple inheritance).
</p>
......@@ -236,8 +236,8 @@ rules for multiple inheritance are followed (i.e. the C layouts of all the
base classes must be compatible).<br>
</p>
<h2><a name="CMethods"></a>C methods</h2>
Extension types can have C methods as well as Python methods. Like C functions,
C methods are declared using <tt>cdef</tt> instead of <tt>def</tt>. C methods
Extension types can have C methods as well as Python methods. Like C functions,
C methods are declared using <tt>cdef</tt> instead of <tt>def</tt>. C methods
are "virtual", and may be overridden in derived extension types.<br>
<br>
<table align="center" cellpadding="5">
......@@ -285,7 +285,7 @@ C method using the usual Python technique, i.e.<br>
<h2><a name="ForwardDeclaringExtTypes"></a>Forward-declaring extension types</h2>
Extension types can be forward-declared, like struct and union types. This
will be necessary if you have two extension types that need to refer to
each other, e.g.
each other, e.g.
<blockquote><tt>cdef class Shrubbery # forward declaration</tt> <p><tt>cdef class Shrubber:</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; cdef Shrubbery work_in_progress</tt> </p>
<p><tt>cdef class Shrubbery:</tt> <br>
......@@ -315,21 +315,21 @@ type <span style="font-family: monospace;">object</span> called <span style="fon
<br>
<h2><a name="PublicAndExtern"></a>Public and external extension types</h2>
Extension types can be declared <b>extern</b> or <b>public</b>. An <a href="#ExternalExtTypes"><b>extern</b> extension type declaration</a> makes
an extension type defined in external C code available to a Cython module.
A <a href="#PublicExtensionTypes"><b>public</b> extension type declaration</a> makes an extension type defined in a Cython module available to external C
code.
Extension types can be declared <b>extern</b> or <b>public</b>. An <a href="#ExternalExtTypes"><b>extern</b> extension type declaration</a> makes
an extension type defined in external C code available to a Cython module.
A <a href="#PublicExtensionTypes"><b>public</b> extension type declaration</a> makes an extension type defined in a Cython module available to external C
code.
<h3> <a name="ExternalExtTypes"></a>External extension types</h3>
An <b>extern</b> extension type allows you to gain access to the internals
of Python objects defined in the Python core or in a non-Cython extension
module.
module.
<blockquote><b>NOTE:</b> In Cython versions before 0.8, <b>extern</b> extension
types were also used to reference extension types defined in another Cython
module. While you can still do that, Cython 0.8 and later provides a better
mechanism for this. See <a href="sharing.html">Sharing C Declarations Between
Cython Modules</a>.</blockquote>
Here is an example which will let you get at the C-level members of the
built-in <i>complex</i> object.
built-in <i>complex</i> object.
<blockquote><tt>cdef extern from "complexobject.h":</tt> <p><tt>&nbsp;&nbsp;&nbsp; struct Py_complex:</tt> <br>
<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double real</tt> <br>
<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double imag</tt> </p>
......@@ -342,7 +342,7 @@ built-in <i>complex</i> object.
<tt>&nbsp;&nbsp;&nbsp; print "Real:", c.cval.real</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; print "Imag:", c.cval.imag</tt></p>
</blockquote>
Some important things to note are:
Some important things to note are:
<ol>
<li> In this example, <b>ctypedef class</b> has been used. This is because,
in the Python header files, the <tt>PyComplexObject</tt> struct is declared
......@@ -353,13 +353,13 @@ built-in <i>complex</i> object.
<tt>} PyComplexObject;<br>
<br>
</tt></div>
</li><li>As well as the name of the extension type, the <i>module</i> in which
</li><li>As well as the name of the extension type, the <i>module</i> in which
its type object can be found is also specified. See the <a href="#ImplicitImport">implicit importing</a> section below.&nbsp; <br>
<br>
</li>
<li> When declaring an external extension type, you don't declare
any methods. Declaration of methods is not required in order to call them,
because the calls are Python method calls. Also, as with structs and unions,
<li> When declaring an external extension type, you don't declare
any methods. Declaration of methods is not required in order to call them,
because the calls are Python method calls. Also, as with structs and unions,
if your extension class declaration is inside a <i>cdef extern from</i> block,
you only need to declare those C members which you wish to access.</li>
</ol>
......@@ -370,26 +370,26 @@ extension types. I apologise for this, but for complicated reasons it proved
to be too difficult to continue supporting the old way of doing these while
introducing the new features that I wanted.</blockquote>
Cython 0.8 and later requires you to include a module name in an extern
extension class declaration, for example,
extension class declaration, for example,
<blockquote><tt>cdef extern class MyModule.Spam:</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
The type object will be implicitly imported from the specified module and
bound to the corresponding name in this module. In other words, in this
example an implicit
example an implicit
<ol>
<pre>from <tt>MyModule</tt> import Spam</pre>
</ol>
statement will be executed at module load time.
statement will be executed at module load time.
<p>The module name can be a dotted name to refer to a module inside a package
hierarchy, for example, </p>
<blockquote><tt>cdef extern class My.Nested.Package.Spam:</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
You can also specify an alternative name under which to import the type
using an <b>as</b> clause, for example,
using an <b>as</b> clause, for example,
<ol>
<tt>cdef extern class My.Nested.Package.Spam as Yummy:</tt> <br>
<tt>&nbsp;&nbsp; ...</tt> </ol>
which corresponds to the implicit import statement
which corresponds to the implicit import statement
<ol>
<pre>from <tt>My.Nested.Package</tt> import <tt>Spam</tt> as <tt>Yummy</tt></pre>
</ol>
......@@ -398,7 +398,7 @@ using an <b>as</b> clause, for example,
purposes. When used in an expression, it refers to a module-level global
variable holding the type's constructor (i.e. its type-object). However,
it can also be used as a C type name to declare variables, arguments and
return values of that type.
return values of that type.
<p>When you declare </p>
<blockquote><tt>cdef extern class MyModule.Spam:</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
......@@ -406,35 +406,35 @@ return values of that type.
by which you can refer to the constructor, but only <tt>Spam</tt> can be
used as a type name. For example, if you were to explicity <tt>import MyModule</tt>,
you could use<tt> MyModule.Spam()</tt> to create a Spam instance, but you
wouldn't be able to use <tt>MyModule.Spam</tt> as a type name.
wouldn't be able to use <tt>MyModule.Spam</tt> as a type name.
<p>When an <b>as</b> clause is used, the name specified in the <b>as</b>
clause also takes over both roles. So if you declare </p>
<blockquote><tt>cdef extern class MyModule.Spam as Yummy:</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
then <tt>Yummy</tt> becomes both the type name and a name for the constructor.
Again, there are other ways that you could get hold of the constructor,
but only <tt>Yummy</tt> is usable as a type name.
but only <tt>Yummy</tt> is usable as a type name.
<h3> <a name="PublicExtensionTypes"></a>Public extension types</h3>
An extension type can be declared <b>public</b>, in which case a <b>.h</b>
file is generated containing declarations for its object struct and type
object. By including the <b>.h</b> file in external C code that you write,
that code can access the attributes of the extension type.
that code can access the attributes of the extension type.
<h3> <a name="NameSpecClause"></a>Name specification clause</h3>
The part of the class declaration in square brackets is a special feature
only available for <b>extern</b> or <b>public</b> extension types. The full
form of this clause is
only available for <b>extern</b> or <b>public</b> extension types. The full
form of this clause is
<blockquote><tt>[object </tt><i>object_struct_name</i><tt>, type </tt><i>type_object_name</i><span style="font-family: monospace;"> ]</span></blockquote>
where <i>object_struct_name</i> is the name to assume for the type's C
struct, and <i>type_object_name</i> is the name to assume for the type's
statically declared type object. (The object and type clauses can be written
in either order.)
in either order.)
<p>If the extension type declaration is inside a <b>cdef extern from</b>
block, the <b>object</b> clause is required, because Cython must be able to
generate code that is compatible with the declarations in the header file.
Otherwise, for <b>extern</b> extension types, the <b>object</b> clause is
optional. </p>
<p>For <b>public</b> extension types, the <b>object</b> and <b>type</b> clauses
are both required, because Cython must be able to generate code that is compatible
<p>For <b>public</b> extension types, the <b>object</b> and <b>type</b> clauses
are both required, because Cython must be able to generate code that is compatible
with external C code. </p>
<p> </p>
<hr width="100%"> <br>
......
<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.61 (Macintosh; I; PPC) [Netscape]">
<title>Cython Language Overview</title>
</head>
<body>
<h1> <hr width="100%">Overview of the Cython Language&nbsp; <hr width="100%"></h1>
This document informally describes the extensions to the Python language
made by Cython. Some day there will be a reference manual covering everything
This document informally describes the extensions to the Python language
made by Cython. Some day there will be a reference manual covering everything
in more detail. <br>
&nbsp;
&nbsp;
<h2> Contents</h2>
<ul>
<li> <a href="#Basics">Basics</a></li>
......@@ -65,90 +65,90 @@ expressions<br>
<li> <a href="#SemanticDifferences">Semantic differences between Python
and Cython</a></li>
</ul>
</ul>
<h2> <hr width="100%"><a name="Basics"></a>Basics
<h2> <hr width="100%"><a name="Basics"></a>Basics
<hr width="100%"></h2>
This section describes the basic features of the Cython language. The facilities
covered in this section allow you to create Python-callable functions that
manipulate C data structures and convert between Python and C data types.
Later sections will cover facilities for <a href="#InterfacingWithExternal">wrapping external C code</a>, <a href="extension_types.html">creating new Python types</a> and <a href="sharing.html">cooperation between Cython modules</a>.
This section describes the basic features of the Cython language. The facilities
covered in this section allow you to create Python-callable functions that
manipulate C data structures and convert between Python and C data types.
Later sections will cover facilities for <a href="#InterfacingWithExternal">wrapping external C code</a>, <a href="extension_types.html">creating new Python types</a> and <a href="sharing.html">cooperation between Cython modules</a>.
<h3> <a name="PyFuncsVsCFuncs"></a>Python functions vs. C functions</h3>
There are two kinds of function definition in Cython:
There are two kinds of function definition in Cython:
<p><b>Python functions</b> are defined using the <b>def</b> statement, as
in Python. They take Python objects as parameters and return Python objects.
in Python. They take Python objects as parameters and return Python objects.
</p>
<p><b>C functions</b> are defined using the new <b>cdef</b> statement. They
take either Python objects or C values as parameters, and can return either
Python objects or C values. </p>
<p>Within a Cython module, Python functions and C functions can call each other
freely, but only Python functions can be called from outside the module by
interpreted Python code. So, any functions that you want to "export" from
your Cython module must be declared as Python functions using <span style="font-weight: bold;">def</span>. </p>
<p>Parameters of either type of function can be declared to have C data types,
using normal C declaration syntax. For example, </p>
<blockquote> <pre>def spam(int i, char *s):<br>&nbsp;&nbsp;&nbsp; ...</pre>
<pre>cdef int eggs(unsigned long l, float f):<br>&nbsp;&nbsp;&nbsp; ...</pre>
</blockquote>
When a parameter of a Python function is declared to have a C data type,
it is passed in as a Python object and automatically converted to a C value,
if possible. Automatic conversion is currently only possible for numeric
types and string types; attempting to use any other type for the parameter
of a Python function will result in a compile-time error.
<p>C functions, on the other hand, can have parameters of any type, since
When a parameter of a Python function is declared to have a C data type,
it is passed in as a Python object and automatically converted to a C value,
if possible. Automatic conversion is currently only possible for numeric
types and string types; attempting to use any other type for the parameter
of a Python function will result in a compile-time error.
<p>C functions, on the other hand, can have parameters of any type, since
they're passed in directly using a normal C function call. </p>
<h3> <a name="PyObjParams"></a>Python objects as parameters and return values</h3>
If no type is specified for a parameter or return value, <i>it is assumed
to be a Python object.</i> (Note that this is different from the C convention,
where it would default to <tt>int</tt>.) For example, the following defines
If no type is specified for a parameter or return value, <i>it is assumed
to be a Python object.</i> (Note that this is different from the C convention,
where it would default to <tt>int</tt>.) For example, the following defines
a C function that takes two Python objects as parameters and returns a Python
object:
object:
<blockquote> <pre>cdef spamobjs(x, y):<br>&nbsp;&nbsp;&nbsp; ...</pre>
</blockquote>
Reference counting for these objects is performed automatically according
Reference counting for these objects is performed automatically according
to the standard Python/C API rules (i.e. borrowed references are taken as
parameters and a new reference is returned).
<p>The name <b>object</b> can also be used to explicitly declare something
parameters and a new reference is returned).
<p>The name <b>object</b> can also be used to explicitly declare something
as a Python object. This can be useful if the name being declared would otherwise
be taken as the name of a type, for example, </p>
<blockquote> <pre>cdef ftang(object int):<br>&nbsp;&nbsp;&nbsp; ...</pre>
</blockquote>
declares a parameter called <tt>int</tt> which is a Python object. You
can also use <b>object </b>as the explicit return type of a function, e.g.
declares a parameter called <tt>int</tt> which is a Python object. You
can also use <b>object </b>as the explicit return type of a function, e.g.
<blockquote> <pre>cdef object ftang(object int):<br>&nbsp;&nbsp;&nbsp; ...</pre>
</blockquote>
In the interests of clarity, it is probably a good idea to always be explicit
about <b>object </b>parameters in C functions.
In the interests of clarity, it is probably a good idea to always be explicit
about <b>object </b>parameters in C functions.
<h3> <a name="CVarAndTypeDecls"></a>C variable and type definitions</h3>
The <b>cdef</b> statement is also used to declare C variables, either
local or module-level:
local or module-level:
<blockquote> <pre>cdef int i, j, k<br>cdef float f, g[42], *h</pre>
</blockquote>
and C struct, union or enum types:
and C struct, union or enum types:
<blockquote> <pre>cdef struct Grail:<br>&nbsp;&nbsp;&nbsp; int age<br>&nbsp;&nbsp;&nbsp; float volume</pre>
<pre>cdef union Food:<br>&nbsp;&nbsp;&nbsp; char *spam<br>&nbsp;&nbsp;&nbsp; float *eggs</pre>
<pre>cdef enum CheeseType:<br>&nbsp;&nbsp;&nbsp; cheddar, edam,&nbsp;<br>&nbsp;&nbsp;&nbsp; camembert</pre>
......@@ -156,21 +156,21 @@ local or module-level:
</blockquote>
There is currently no special syntax for defining a constant, but you
can use an anonymous enum declaration for this purpose, for example,
can use an anonymous enum declaration for this purpose, for example,
<blockquote><tt>cdef enum:</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; tons_of_spam = 3</tt></blockquote>
Note that the words <span style="font-family: monospace;">struct</span>, <span style="font-family: monospace;">union</span> and <span style="font-family: monospace;">enum</span> are used only when <i>defining</i> a type, not when referring to it. For example, to declare a variable pointing
to a Grail you would write
Note that the words <span style="font-family: monospace;">struct</span>, <span style="font-family: monospace;">union</span> and <span style="font-family: monospace;">enum</span> are used only when <i>defining</i> a type, not when referring to it. For example, to declare a variable pointing
to a Grail you would write
<blockquote> <pre>cdef Grail *gp</pre>
</blockquote>
and <i>not</i>
and <i>not</i>
<blockquote> <pre>cdef struct Grail *gp <font color="#ed181e"># WRONG</font></pre>
</blockquote>
There is also a <b>ctypedef</b> statement for giving names to types, e.g.
There is also a <b>ctypedef</b> statement for giving names to types, e.g.
<blockquote> <pre>ctypedef unsigned long ULong</pre>
<pre>ctypedef int *IntPtr<br></pre></blockquote>
......@@ -222,9 +222,9 @@ unsigned long<br>
</td>
</tr>
<tr>
</tr>
<tr>
<td style="vertical-align: top; width: 40%; white-space: nowrap;">float, double, long double<br>
......@@ -289,26 +289,26 @@ understand the issue and be careful what you do.<br>
</blockquote>
<h3> <a name="ScopeRules"></a>Scope rules</h3>
Cython determines whether a variable belongs to a local scope, the module
scope, or the built-in scope <i>completely statically.</i> As with Python,
assigning to a variable which is not otherwise declared implicitly declares
Cython determines whether a variable belongs to a local scope, the module
scope, or the built-in scope <i>completely statically.</i> As with Python,
assigning to a variable which is not otherwise declared implicitly declares
it to be a Python variable residing in the scope where it is assigned. Unlike
Python, however, a name which is referred to but not declared or assigned
is assumed to reside in the <i>builtin scope, </i>not the module scope.
Names added to the module dictionary at run time will not shadow such names.
<p>You can use a <b>global</b> statement at the module level to explicitly
<p>You can use a <b>global</b> statement at the module level to explicitly
declare a name to be a module-level name when there would otherwise not be
any indication of this, for example, </p>
<blockquote><tt>global __name__</tt> <br>
<tt>print __name__</tt></blockquote>
Without the <b>global</b> statement, the above would print the name of
Without the <b>global</b> statement, the above would print the name of
the builtins module.<br>
<br>
......@@ -318,35 +318,35 @@ the builtins module.<br>
to it. In particular, tricks such as the following will <i>not</i> work
in Cython:<br>
<blockquote> <pre>try:<br>&nbsp; x = True<br>except NameError:<br>&nbsp; True = 1<br></pre>
</blockquote>
because, due to the assignment, the True will always be looked up in the
module-level scope. You would have to do something like this instead:<br>
<blockquote> <pre>import __builtin__<br>try:<br> True = __builtin__.True<br>except AttributeError:<br> True = 1<br></pre>
</blockquote>
<hr width="100%">
<hr width="100%">
<h3> <a name="StatsAndExprs"></a>Statements and expressions</h3>
Control structures and expressions follow Python syntax for the most part.
When applied to Python objects, they have the same semantics as in Python
(unless otherwise noted). Most of the Python operators can also be applied
to C values, with the obvious semantics.
<p>If Python objects and C values are mixed in an expression, conversions
are performed automatically between Python objects and C numeric or string
Control structures and expressions follow Python syntax for the most part.
When applied to Python objects, they have the same semantics as in Python
(unless otherwise noted). Most of the Python operators can also be applied
to C values, with the obvious semantics.
<p>If Python objects and C values are mixed in an expression, conversions
are performed automatically between Python objects and C numeric or string
types. </p>
<p>Reference counts are maintained automatically for all Python objects, and
all Python operations are automatically checked for errors, with appropriate
all Python operations are automatically checked for errors, with appropriate
action taken. </p>
<h4> <a name="ExprSyntaxDifferences"></a>Differences between C and Cython
expressions</h4>
There
......@@ -358,18 +358,18 @@ no direct equivalent in Python.<br>
<li>An integer literal without an <span style="font-family: monospace; font-weight: bold;">L</span> suffix is treated as a C constant, and will be truncated to whatever size your C compiler thinks appropriate. With an <span style="font-family: monospace; font-weight: bold;">L</span> suffix, it will be converted to Python long integer (even if it would be small enough to fit into a C int).<br>
<br>
</li>
<li> There is no <b><tt>-&gt;</tt></b> operator in Cython. Instead of <tt>p-&gt;x</tt>,
<li> There is no <b><tt>-&gt;</tt></b> operator in Cython. Instead of <tt>p-&gt;x</tt>,
use <tt>p.x</tt></li>
&nbsp; <li> There is no <b><tt>*</tt></b> operator in Cython. Instead of
&nbsp; <li> There is no <b><tt>*</tt></b> operator in Cython. Instead of
<tt>*p</tt>, use <tt>p[0]</tt></li>
&nbsp; <li> There is an <b><tt>&amp;</tt></b> operator, with the same semantics
as in C.</li>
&nbsp; <li> The null C pointer is called <b><tt>NULL</tt></b>, not 0 (and
<tt>NULL</tt> is a reserved word).</li>
&nbsp; <li> Character literals are written with a <b>c</b> prefix, for
example:</li>
<ul>
......@@ -380,29 +380,29 @@ example:</li>
<pre>cdef char *p, float *q<br>p = &lt;char*&gt;q</pre>
</ul>
<i><b>Warning</b>: Don't attempt to use a typecast to convert between
Python and C data types -- it won't do the right thing. Leave Cython to perform
the conversion automatically.</i>
Python and C data types -- it won't do the right thing. Leave Cython to perform
the conversion automatically.</i>
</ul>
<h4> <a name="ForFromLoop"></a>Integer for-loops</h4>
You should be aware that a for-loop such as
You should be aware that a for-loop such as
<blockquote><tt>for i in range(n):</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
won't be very fast, even if <tt>i</tt> and <tt>n</tt> are declared as
C integers, because <tt>range</tt> is a Python function. For iterating over
ranges of integers, Cython has another form of for-loop:
C integers, because <tt>range</tt> is a Python function. For iterating over
ranges of integers, Cython has another form of for-loop:
<blockquote><tt>for i from 0 &lt;= i &lt; n:</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
If the loop variable and the lower and upper bounds are all C integers,
this form of loop will be much faster, because Cython will translate it into
pure C code.
If the loop variable and the lower and upper bounds are all C integers,
this form of loop will be much faster, because Cython will translate it into
pure C code.
<p>Some things to note about the <tt>for-from</tt> loop: </p>
<ul>
<li> The target expression must be a variable name.</li>
......@@ -412,61 +412,61 @@ the target name.</li>
are both from the set {<tt>&lt;</tt>, <tt>&lt;=</tt>} then it is upwards;
if they are both from the set {<tt>&gt;</tt>, <tt>&gt;=</tt>} then it is
downwards. (Any other combination is disallowed.)</li>
</ul>
Like other Python looping statements, <tt>break</tt> and <tt>continue</tt> may be used in the body, and the loop may have an <tt>else</tt> clause.
Like other Python looping statements, <tt>break</tt> and <tt>continue</tt> may be used in the body, and the loop may have an <tt>else</tt> clause.
<h2> <hr width="100%"></h2>
<h3> <a name="ExceptionValues"></a>Error return values</h3>
If you don't do anything special, a function declared with <b>cdef</b> that does not return a Python object has no way of reporting Python exceptions
to its caller. If an exception is detected in such a function, a warning
message is printed and the exception is ignored.
If you don't do anything special, a function declared with <b>cdef</b> that does not return a Python object has no way of reporting Python exceptions
to its caller. If an exception is detected in such a function, a warning
message is printed and the exception is ignored.
<p>If you want a C function that does not return a Python object to be able
to propagate exceptions to its caller, you need to declare an <b>exception
to propagate exceptions to its caller, you need to declare an <b>exception
value</b> for it. Here is an example: </p>
<blockquote><tt>cdef int spam() except -1:</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
With this declaration, whenever an exception occurs inside <tt>spam</tt>,
it will immediately return with the value <tt>-1</tt>. Furthermore, whenever
a call to <tt>spam</tt> returns <tt>-1</tt>, an exception will be assumed
to have occurred and will be propagated.
With this declaration, whenever an exception occurs inside <tt>spam</tt>,
it will immediately return with the value <tt>-1</tt>. Furthermore, whenever
a call to <tt>spam</tt> returns <tt>-1</tt>, an exception will be assumed
to have occurred and will be propagated.
<p>When you declare an exception value for a function, you should never explicitly
return that value. If all possible return values are legal and you can't
reserve one entirely for signalling errors, you can use an alternative form
of exception value declaration: </p>
<blockquote><tt>cdef int spam() except? -1:</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
The "?" indicates that the value <tt>-1</tt> only indicates a <i>possible</i> error. In this case, Cython generates a call to <tt>PyErr_Occurred</tt>if the
exception value is returned, to make sure it really is an error.
exception value is returned, to make sure it really is an error.
<p>There is also a third form of exception value declaration: </p>
<blockquote><tt>cdef int spam() except *:</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
This form causes Cython to generate a call to <tt>PyErr_Occurred</tt> after
This form causes Cython to generate a call to <tt>PyErr_Occurred</tt> after
<i>every</i> call to spam, regardless of what value it returns. If you have
a function returning <tt>void</tt> that needs to propagate errors, you will
have to use this form, since there isn't any return value to test.
have to use this form, since there isn't any return value to test.
<p>Some things to note: </p>
<ul>
<li> Currently, exception values can only declared for functions returning
an integer, float or pointer type, and the value must be a <i>literal</i>,
not an expression (although it can be negative). The only possible pointer
exception value is <tt>NULL</tt>. Void functions can only use the <tt>except
an integer, float or pointer type, and the value must be a <i>literal</i>,
not an expression (although it can be negative). The only possible pointer
exception value is <tt>NULL</tt>. Void functions can only use the <tt>except
*</tt> form.</li>
<br>
&nbsp; <li> The exception value specification is part of the signature
......@@ -477,18 +477,18 @@ is an example of a pointer-to-function declaration with an exception value:</li>
<ul>
<pre><tt>int (*grail)(int, char *) except -1</tt></pre>
</ul>
<li> You don't need to (and shouldn't) declare exception values for functions
<li> You don't need to (and shouldn't) declare exception values for functions
which return Python objects. Remember that a function with no declared return
type implicitly returns a Python object.</li>
</ul>
<h4> <a name="CheckingReturnValues"></a>Checking return values of non-Cython
<h4> <a name="CheckingReturnValues"></a>Checking return values of non-Cython
functions</h4>
It's important to understand that the <tt>except</tt> clause does <i>not</i> cause an error to be <i>raised</i> when the specified value is returned. For
example, you can't write something like
example, you can't write something like
<blockquote> <pre>cdef extern FILE *fopen(char *filename, char *mode) except NULL <font color="#ed181e"># WRONG!</font></pre>
</blockquote>
......@@ -497,26 +497,26 @@ returns NULL. The except clause doesn't work that way; its only purpose
is for <i>propagating</i> exceptions that have already been raised, either
by a Cython function or a C function that calls Python/C API routines. To
get an exception from a non-Python-aware function such as fopen, you will
have to check the return value and raise it yourself, for example,
have to check the return value and raise it yourself, for example,
<blockquote> <pre>cdef FILE *p<br>p = fopen("spam.txt", "r")<br>if p == NULL:<br>&nbsp;&nbsp;&nbsp; raise SpamError("Couldn't open the spam file")</pre>
</blockquote>
<h4> <hr width="100%"></h4>
<h4> <a name="IncludeStatement"></a>The <tt>include</tt> statement</h4>
For convenience, a large Cython module can be split up into a number of
files which are put together using the <b>include</b> statement, for example
For convenience, a large Cython module can be split up into a number of
files which are put together using the <b>include</b> statement, for example
<blockquote> <pre>include "spamstuff.pxi"</pre>
</blockquote>
The contents of the named file are textually included at that point. The
included file can contain any complete top-level Cython statements, including
other <b>include</b> statements. The <b>include</b> statement itself can
only appear at the top level of a file.
The contents of the named file are textually included at that point. The
included file can contain any complete top-level Cython statements, including
other <b>include</b> statements. The <b>include</b> statement itself can
only appear at the top level of a file.
<p>The <b>include</b> statement can also be used in conjunction with <a href="#PublicDecls"><b>public</b> declarations</a> to make C functions and
variables defined in one Cython module accessible to another. However, note
that some of these uses have been superseded by the facilities described
......@@ -524,55 +524,55 @@ in <a href="sharing.html">Sharing Declarations Between Cython Modules</a>,
and it is expected that use of the <b>include</b> statement for this purpose
will be phased out altogether in future versions. </p>
<h2> <hr width="100%"><a name="InterfacingWithExternal"></a>Interfacing with External
C Code
C Code
<hr width="100%"></h2>
One of the main uses of Cython is wrapping existing libraries of C code.
One of the main uses of Cython is wrapping existing libraries of C code.
This is achieved by using <a href="#ExternDecls">external declarations</a> to declare the C functions and variables from the library that you want to
use.
<p>You can also use <a href="#PublicDecls">public declarations</a> to make
C functions and variables defined in a Cython module available to external
C code. The need for this is expected to be less frequent, but you might
want to do it, for example, if you are embedding Python in another application
use.
<p>You can also use <a href="#PublicDecls">public declarations</a> to make
C functions and variables defined in a Cython module available to external
C code. The need for this is expected to be less frequent, but you might
want to do it, for example, if you are embedding Python in another application
as a scripting language. Just as a Cython module can be used as a bridge to
allow Python code to call C code, it can also be used to allow C code to
call Python code. </p>
<h3> <a name="ExternDecls"></a>External declarations</h3>
By default, C functions and variables declared at the module level are
local to the module (i.e. they have the C <b>static</b> storage class). They
By default, C functions and variables declared at the module level are
local to the module (i.e. they have the C <b>static</b> storage class). They
can also be declared <b>extern</b> to specify that they are defined elsewhere,
for example:
for example:
<blockquote> <pre>cdef extern int spam_counter</pre>
<pre>cdef extern void order_spam(int tons)</pre>
</blockquote>
<blockquote> </blockquote>
<h4> <a name="ReferencingHeaders"></a>Referencing C header files</h4>
When you use an extern definition on its own as in the examples above,
Cython includes a declaration for it in the generated C file. This can cause
problems if the declaration doesn't exactly match the declaration that will
be seen by other C code. If you're wrapping an existing C library, for example,
it's important that the generated C code is compiled with exactly the same
declarations as the rest of the library.
When you use an extern definition on its own as in the examples above,
Cython includes a declaration for it in the generated C file. This can cause
problems if the declaration doesn't exactly match the declaration that will
be seen by other C code. If you're wrapping an existing C library, for example,
it's important that the generated C code is compiled with exactly the same
declarations as the rest of the library.
<p>To achieve this, you can tell Cython that the declarations are to be found
in a C header file, like this: </p>
<blockquote> <pre>cdef extern from "spam.h":</pre>
<pre>&nbsp;&nbsp;&nbsp; int spam_counter</pre>
<pre>&nbsp;&nbsp;&nbsp; void order_spam(int tons)</pre>
</blockquote>
The <b>cdef extern from</b> clause does three things:
The <b>cdef extern from</b> clause does three things:
<ol>
<li> It directs Cython to place a <b>#include</b> statement for the named
......@@ -583,14 +583,14 @@ declarations as the rest of the library.
</li>
&nbsp; <li> It treats all declarations within the block as though they
started with <b>cdef extern</b>.</li>
</ol>
It's important to understand that Cython does <i>not</i> itself read the
C header file, so you still need to provide Cython versions of any declarations
It's important to understand that Cython does <i>not</i> itself read the
C header file, so you still need to provide Cython versions of any declarations
from it that you use. However, the Cython declarations don't always have to
exactly match the C ones, and in some cases they shouldn't or can't. In particular:
<ol>
<li> Don't use <b>const</b>. Cython doesn't know anything about const,
......@@ -601,8 +601,8 @@ although on rare occasions you might have to use a cast.<sup><a href="#Footnote
such as <b>__declspec()</b>.<br>
</li>
&nbsp; <li> If the header file declares a big struct and you only want
to use a few members, you only need to declare the members you're interested
in. Leaving the rest out doesn't do any harm, because the C compiler will
to use a few members, you only need to declare the members you're interested
in. Leaving the rest out doesn't do any harm, because the C compiler will
use the full definition from the header file.<br>
<br>
In some cases, you might not need <i>any</i> of the struct's members, in
......@@ -617,14 +617,14 @@ Note that you can only do this inside a <b>cdef extern from</b> block; struct
declarations anywhere else must be non-empty.<br>
<br>
</li>
<li> If the header file uses typedef names such as <b>size_t </b>to refer
to platform-dependent flavours of numeric types, you will need a corresponding
<li> If the header file uses typedef names such as <b>size_t </b>to refer
to platform-dependent flavours of numeric types, you will need a corresponding
<b>ctypedef</b> statement, but you don't need to match the type exactly,
just use something of the right general kind (int, float, etc). For example,</li>
<ol>
<pre>ctypedef int size_t</pre>
</ol>
will work okay whatever the actual size of a size_t is (provided the header
will work okay whatever the actual size of a size_t is (provided the header
file defines it correctly). <br>
&nbsp; <li> If the header file uses macros to define constants, translate
them into a dummy <b>enum</b> declaration.<br>
......@@ -632,47 +632,47 @@ to platform-dependent flavours of numeric types, you will need a corresponding
&nbsp; <li> If the header file defines a function using a macro, declare
it as though it were an ordinary function, with appropriate argument and
result types.</li>
</ol>
A few more tricks and tips:
A few more tricks and tips:
<ul>
<li> If you want to include a C header because it's needed by another
header, but don't want to use any declarations from it, put <tt><font size="+1">pass</font></tt> in the extern-from block:</li>
</ul>
<ul>
<ul>
<tt>cdef extern from "spam.h":</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; pass</tt> </ul>
</ul>
<ul>
<li> If you want to include some external declarations, but don't want
to specify a header file (because it's included by some other header that
you've already included) you can put <tt>*</tt> in place of the header file
<li> If you want to include some external declarations, but don't want
to specify a header file (because it's included by some other header that
you've already included) you can put <tt>*</tt> in place of the header file
name:</li>
</ul>
<blockquote> <blockquote><tt>cdef extern from *:</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
</blockquote>
<h4> <a name="StructDeclStyles"></a>Styles of struct, union and enum declaration</h4>
There are two main ways that structs, unions and enums can be declared
There are two main ways that structs, unions and enums can be declared
in C header files: using a tag name, or using a typedef. There are also some
variations based on various combinations of these.
variations based on various combinations of these.
<p>It's important to make the Cython declarations match the style used in the
header file, so that Cython can emit the right sort of references to the type
in the code it generates. To make this possible, Cython provides two different
......@@ -680,13 +680,13 @@ syntaxes for declaring a struct, union or enum type. The style introduced
above corresponds to the use of a tag name. To get the other style, you prefix
the declaration with <b>ctypedef</b>, as illustrated below. </p>
<p>The following table shows the various possible styles that can be found
in a header file, and the corresponding Cython declaration that you should
put in the <b>cdef exern from </b>block. Struct declarations are used as
<p>The following table shows the various possible styles that can be found
in a header file, and the corresponding Cython declaration that you should
put in the <b>cdef exern from </b>block. Struct declarations are used as
an example; the same applies equally to union and enum declarations. </p>
<p>Note that in all the cases below, you refer to the type in Cython code simply
as <tt><font size="+1">Foo</font></tt>, not <tt><font size="+1">struct Foo</font></tt>.
<br>
......@@ -695,7 +695,7 @@ as <tt><font size="+1">Foo</font></tt>, not <tt><font size="+1">struct Foo</font
<tr bgcolor="#8cbc1c" valign="top">
<td bgcolor="#8cbc1c">&nbsp;</td>
<td bgcolor="#ff9933" nowrap="nowrap"><b>C code</b></td>
<td bgcolor="#66cccc" valign="top"><b>Possibilities for corresponding
<td bgcolor="#66cccc" valign="top"><b>Possibilities for corresponding
Cython code</b></td>
<td bgcolor="#99cc33" valign="top"><b>Comments</b></td>
</tr>
......@@ -706,7 +706,7 @@ Cython code</b></td>
<tt>};</tt></td>
<td bgcolor="#66cccc"><tt>cdef struct Foo:</tt> <br>
<tt>&nbsp; ...</tt></td>
<td>Cython will refer to the type as <tt>struct Foo </tt>in the generated
<td>Cython will refer to the type as <tt>struct Foo </tt>in the generated
C code<tt>.</tt></td>
</tr>
<tr bgcolor="#8cbc1c" valign="top">
......@@ -728,7 +728,7 @@ foo {</tt> <br>
<td bgcolor="#66cccc" nowrap="nowrap" valign="top"><tt>cdef struct foo:</tt> <br>
<tt>&nbsp; ...</tt> <br>
<tt>ctypedef foo Foo #optional</tt></td>
<td rowspan="2" valign="top">If the C header uses both a tag and a typedef
<td rowspan="2" valign="top">If the C header uses both a tag and a typedef
with <i>different</i> names, you can use either form of declaration in Cython
(although if you need to forward reference the type, you'll have to use
the first form).</td>
......@@ -744,84 +744,84 @@ the first form).</td>
<tt>} Foo;</tt></td>
<td bgcolor="#66cccc" valign="top"><tt>cdef struct Foo:</tt> <br>
<tt>&nbsp; ...</tt></td>
<td>If the header uses the <i>same</i> name for the tag and the typedef,
<td>If the header uses the <i>same</i> name for the tag and the typedef,
you won't be able to include a <b>ctypedef</b> for it -- but then, it's not
necessary.</td>
</tr>
</tbody> </table>
</p>
<h4> <a name="AccessingAPI"></a>Accessing Python/C API routines</h4>
One particular use of the <b>cdef extern from</b> statement is for gaining
access to routines in the Python/C API. For example,
One particular use of the <b>cdef extern from</b> statement is for gaining
access to routines in the Python/C API. For example,
<blockquote> <pre>cdef extern from "Python.h":</pre>
<pre>&nbsp;&nbsp;&nbsp; object PyString_FromStringAndSize(char *s, int len)</pre>
</blockquote>
will allow you to create Python strings containing null bytes.
will allow you to create Python strings containing null bytes.
<p> </p>
<hr width="100%">
<hr width="100%">
<h3> <a name="CNameSpecs"></a>Resolving naming conflicts - C name specifications</h3>
Each Cython module has a single module-level namespace for both Python
and C names. This can be inconvenient if you want to wrap some external
C functions and provide the Python user with Python functions of the same
names.
<p>Cython 0.8 provides a couple of different ways of solving this problem.
The best way, especially if you have many C functions to wrap, is probably
to put the extern C function declarations into a different namespace using
the facilities described in the section on <a href="sharing.html">sharing
names.
<p>Cython 0.8 provides a couple of different ways of solving this problem.
The best way, especially if you have many C functions to wrap, is probably
to put the extern C function declarations into a different namespace using
the facilities described in the section on <a href="sharing.html">sharing
declarations between Cython modules</a>. </p>
<p>The other way is to use a <b>c name specification</b> to give different
Cython and C names to the C function. Suppose, for example, that you want
to wrap an external function called <tt>eject_tomato</tt>. If you declare
<p>The other way is to use a <b>c name specification</b> to give different
Cython and C names to the C function. Suppose, for example, that you want
to wrap an external function called <tt>eject_tomato</tt>. If you declare
it as </p>
<blockquote> <pre>cdef extern void c_eject_tomato "eject_tomato" (float speed)</pre>
</blockquote>
then its name inside the Cython module will be <tt>c_eject_tomato</tt>,
whereas its name in C will be <tt>eject_tomato</tt>. You can then wrap it
with
then its name inside the Cython module will be <tt>c_eject_tomato</tt>,
whereas its name in C will be <tt>eject_tomato</tt>. You can then wrap it
with
<blockquote> <pre>def eject_tomato(speed):<br>&nbsp; c_eject_tomato(speed)</pre>
</blockquote>
so that users of your module can refer to it as <tt>eject_tomato</tt>.
<p>Another use for this feature is referring to external names that happen
to be Cython keywords. For example, if you want to call an external function
called <tt>print</tt>, you can rename it to something else in your Cython
so that users of your module can refer to it as <tt>eject_tomato</tt>.
<p>Another use for this feature is referring to external names that happen
to be Cython keywords. For example, if you want to call an external function
called <tt>print</tt>, you can rename it to something else in your Cython
module. </p>
<p>As well as functions, C names can be specified for variables, structs,
<p>As well as functions, C names can be specified for variables, structs,
unions, enums, struct and union members, and enum values. For example, </p>
<blockquote> <pre>cdef extern int one "ein", two "zwei"<br>cdef extern float three "drei"<br><br>cdef struct spam "SPAM":<br>&nbsp; int i "eye"</pre>
<tt>cdef enum surprise "inquisition":</tt> <br>
<tt>&nbsp; first "alpha"</tt> <br>
<tt>&nbsp; second "beta" = 3</tt></blockquote>
<hr width="100%">
<hr width="100%">
<h3> <a name="PublicDecls"></a>Public Declarations</h3>
You can make C variables and functions defined in a Cython module accessible
to external C code (or another Cython module) using the <b><tt>public</tt></b> keyword, as follows:
You can make C variables and functions defined in a Cython module accessible
to external C code (or another Cython module) using the <b><tt>public</tt></b> keyword, as follows:
<blockquote><tt>cdef public int spam # public variable declaration</tt> <p><tt>cdef public void grail(int num_nuns): # public function declaration</tt> <br>
<tt>&nbsp;&nbsp;&nbsp; ...</tt></p>
</blockquote>
If there are any <tt>public</tt> declarations in a Cython module, a <b>.h</b> file is generated containing equivalent C declarations for inclusion in other
C code.
C code.
<p>Cython also generates a <b>.pxi</b> file containing Cython versions of the
declarations for inclusion in another Cython module using the <b><a href="#IncludeStatement">include</a></b> statement. If you use this, you
will need to arrange for the module using the declarations to be linked
......@@ -829,35 +829,35 @@ against the module defining them, and for both modules to be available to
the dynamic linker at run time. I haven't tested this, so I can't say how
well it will work on the various platforms. </p>
<blockquote>NOTE: If all you want to export is an extension type, there is
now a better way -- see <a href="sharing.html">Sharing Declarations Between
Cython Modules</a>.</blockquote>
<h2> <hr width="100%">Extension Types
<h2> <hr width="100%">Extension Types
<hr width="100%"></h2>
One of the most powerful features of Cython is the ability to easily create
new built-in Python types, called <b>extension types</b>. This is a major
topic in itself, so there is a&nbsp; <a href="extension_types.html">separate
page</a> devoted to it.
<h2> <hr width="100%">Sharing Declarations Between Cython Modules
One of the most powerful features of Cython is the ability to easily create
new built-in Python types, called <b>extension types</b>. This is a major
topic in itself, so there is a&nbsp; <a href="extension_types.html">separate
page</a> devoted to it.
<h2> <hr width="100%">Sharing Declarations Between Cython Modules
<hr width="100%"></h2>
Cython 0.8 introduces a substantial new set of facilities allowing a Cython
Cython 0.8 introduces a substantial new set of facilities allowing a Cython
module to easily import and use C declarations and extension types from another
Cython module. You can now create a set of co-operating Cython modules just
as easily as you can create a set of co-operating Python modules. There is
a <a href="sharing.html">separate page</a> devoted to this topic.
<h2> <hr width="100%"><a name="Limitations"></a>Limitations
a <a href="sharing.html">separate page</a> devoted to this topic.
<h2> <hr width="100%"><a name="Limitations"></a>Limitations
<hr width="100%"></h2>
<h3> <a name="Unsupported"></a>Unsupported Python features</h3>
Cython is not quite a full superset of Python. The following restrictions
apply:
Cython is not quite a full superset of Python. The following restrictions
apply:
<blockquote> <li> Function definitions (whether using <b>def</b> or <b>cdef</b>)
cannot be nested within other function definitions.<br>
</li>
......@@ -870,17 +870,17 @@ a <a href="sharing.html">separate page</a> devoted to this topic.
&nbsp; <li> Generators cannot be defined in Cython.<br>
<br>
</li>
<li> The <tt>globals()</tt> and <tt>locals()</tt> functions cannot be
<li> The <tt>globals()</tt> and <tt>locals()</tt> functions cannot be
used.</li>
</blockquote>
The above restrictions will most likely remain, since removing them would
be difficult and they're not really needed for Cython's intended applications.
<p>There are also some temporary limitations, which may eventually be lifted, including:
The above restrictions will most likely remain, since removing them would
be difficult and they're not really needed for Cython's intended applications.
<p>There are also some temporary limitations, which may eventually be lifted, including:
</p>
<blockquote> <li> Class and function definitions cannot be placed inside
control structures.<br>
</li>
......@@ -898,54 +898,54 @@ docstrings.<br>
because Cython doesn't optimize them away, and won't even accept them in
places where executable statements are not allowed.</li>
</blockquote>
<h3> <a name="SemanticDifferences"></a>Semantic differences between Python
and Cython</h3>
<h4> Behaviour of class scopes</h4>
In Python, referring to a method of a class inside the class definition,
In Python, referring to a method of a class inside the class definition,
i.e. while the class is being defined, yields a plain function object, but
in Cython it yields an unbound method<sup><font size="-2"><a href="#Footnote2">2</a></font></sup>. A consequence of this is that the
usual idiom for using the classmethod and staticmethod functions, e.g.
usual idiom for using the classmethod and staticmethod functions, e.g.
<blockquote> <pre>class Spam:</pre>
<pre>&nbsp; def method(cls):<br>&nbsp;&nbsp;&nbsp; ...</pre>
<pre>&nbsp; method = classmethod(method)</pre>
</blockquote>
will not work in Cython. This can be worked around by defining the function
will not work in Cython. This can be worked around by defining the function
<i>outside</i> the class, and then assigning the result of classmethod or
staticmethod inside the class, i.e.
staticmethod inside the class, i.e.
<blockquote> <pre>def Spam_method(cls):<br>&nbsp; ...</pre>
<pre>class Spam:</pre>
<pre>&nbsp; method = classmethod(Spam_method)</pre>
</blockquote>
<h1> <hr width="100%"><font size="+0">Footnotes</font> <hr width="100%"></h1>
<a name="Footnote1"></a>1. A problem with const could arise if you have
something like
<a name="Footnote1"></a>1. A problem with const could arise if you have
something like
<blockquote> <pre>cdef extern from "grail.h":<br>&nbsp; char *nun</pre>
</blockquote>
where grail.h actually contains
where grail.h actually contains
<blockquote> <pre>extern const char *nun;</pre>
</blockquote>
and you do
and you do
<blockquote> <pre>cdef void languissement(char *s):<br>&nbsp; #something that doesn't change s</pre>
<pre>...</pre>
<pre>languissement(nun)</pre>
</blockquote>
which will cause the C compiler to complain. You can work around it by
casting away the constness:
which will cause the C compiler to complain. You can work around it by
casting away the constness:
<blockquote> <pre>languissement(&lt;char *&gt;nun)</pre>
</blockquote>
<hr width="100%"><a name="Footnote2"></a>2. The reason for the different behaviour
of class scopes is that Cython-defined Python functions are PyCFunction objects,
not PyFunction objects, and are not recognised by the machinery that creates
......
/* The following styles size, place, and layer the slide components.
Edit these if you want to change the overall slide layout.
The commented lines can be uncommented (and modified, if necessary)
The commented lines can be uncommented (and modified, if necessary)
to help you with the rearrangement process. */
/* target = 1024x768 */
......
......@@ -59,7 +59,7 @@ html>body div#controls {position: fixed; padding: 0 0 1em 0;
top: auto;}
div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
margin: 0; padding: 0;}
#controls #navLinks a {padding: 0; margin: 0 0.5em;
#controls #navLinks a {padding: 0; margin: 0 0.5em;
background: #f0f0f0; border: none; color: #545454;
cursor: pointer;}
#controls #navList {height: 1em;}
......
/* Do not edit or override these styles! The system will likely break if you do. */
div#header, div#footer, div#controls, .slide {position: absolute;}
html>body div#header, html>body div#footer,
html>body div#header, html>body div#footer,
html>body div#controls, html>body .slide {position: fixed;}
.handout {display: none;}
.layout {display: block;}
......
// S5 v1.1 slides.js -- released into the Public Domain
//
// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for information
// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for information
// about all the wonderful and talented contributors to this code!
var undef;
......@@ -64,7 +64,7 @@ function nodeValue(node) {
var children = node.childNodes;
for (var i = 0; i < children.length; ++i) {
result += nodeValue(children[i]);
}
}
}
else if (node.nodeType == 3) {
result = node.nodeValue;
......@@ -106,8 +106,8 @@ function currentSlide() {
} else {
cs = document.currentSlide;
}
cs.innerHTML = '<span id="csHere">' + snum + '<\/span> ' +
'<span id="csSep">\/<\/span> ' +
cs.innerHTML = '<span id="csHere">' + snum + '<\/span> ' +
'<span id="csSep">\/<\/span> ' +
'<span id="csTotal">' + (smax-1) + '<\/span>';
if (snum == 0) {
cs.style.visibility = 'hidden';
......@@ -460,7 +460,7 @@ function notOperaFix() {
function getIncrementals(obj) {
var incrementals = new Array();
if (!obj)
if (!obj)
return incrementals;
var children = obj.childNodes;
for (var i = 0; i < children.length; i++) {
......
......@@ -4,13 +4,13 @@
<meta name="GENERATOR" content="Mozilla/4.61 (Macintosh; I; PPC) [Netscape]"><title>Sharing Declarations Between Cython Modules</title></head>
<body>
<h1> <hr width="100%">Sharing Declarations Between Cython Modules
<h1> <hr width="100%">Sharing Declarations Between Cython Modules
<hr width="100%"></h1>
This section describes a new set of facilities introduced in Cython 0.8
for making C declarations and extension types in one Cython module available
for use in another Cython module. These facilities are closely modelled on
the Python import mechanism, and can be thought of as a compile-time version
of it.
the Python import mechanism, and can be thought of as a compile-time version
of it.
<h2> Contents</h2>
<ul>
<li> <a href="#DefAndImpFiles">Definition and Implementation files</a></li>
......@@ -21,7 +21,7 @@ of it.
<li> <a href="#CImportStatement">The <tt>cimport</tt> statement</a></li>
<ul>
<li> <a href="#SearchPaths">Search paths for definition files</a></li>
<li> <a href="#ResolvingNamingConflicts">Using <tt>cimport</tt> to resolve
<li> <a href="#ResolvingNamingConflicts">Using <tt>cimport</tt> to resolve
naming conflicts</a></li>
</ul>
<li> <a href="#SharingExtensionTypes">Sharing extension types</a></li>
......@@ -31,31 +31,31 @@ naming conflicts</a></li>
a <tt>.pxd</tt> suffix, containing C declarations that are to be available
to other Cython modules, and an <i>implementation file</i> with a <tt>.pyx</tt>
suffix, containing everything else. When a module wants to use something
declared in another module's definition file, it imports it using the <a href="#CImportStatement"><b>cimport</b> statement</a>.
declared in another module's definition file, it imports it using the <a href="#CImportStatement"><b>cimport</b> statement</a>.
<h3> <a name="WhatDefFileContains"></a>What a Definition File contains</h3>
A definition file can contain:
A definition file can contain:
<ul>
<li> Any kind of C type declaration.</li>
<li> <b>extern</b> C function or variable declarations.</li>
<li> The definition part of an extension type (<a href="#SharingExtensionTypes">see below</a>).</li>
</ul>
It cannot currently contain any non-extern C function or variable declarations
(although this may be possible in a future version).
<p>It cannot contain the implementations of any C or Python functions, or
(although this may be possible in a future version).
<p>It cannot contain the implementations of any C or Python functions, or
any Python class definitions, or any executable statements. </p>
<blockquote>NOTE: You don't need to (and shouldn't) declare anything in a
declaration file <b>public</b> in order to make it available to other Cython
<blockquote>NOTE: You don't need to (and shouldn't) declare anything in a
declaration file <b>public</b> in order to make it available to other Cython
modules; its mere presence in a definition file does that. You only need a
public declaration if you want to make something available to external C code.</blockquote>
<h3> <a name="WhatImpFileContains"></a>What an Implementation File contains</h3>
An implementation file can contain any kind of Cython statement, although
there are some restrictions on the implementation part of an extension type
there are some restrictions on the implementation part of an extension type
if the corresponding definition file also defines that type (see below).
<h2> <a name="CImportStatement"></a>The <tt>cimport</tt> statement</h2>
The <b>cimport</b> statement is used in a definition or implementation
file to gain access to names declared in another definition file. Its syntax
exactly parallels that of the normal Python import statement:
exactly parallels that of the normal Python import statement:
<blockquote><tt>cimport </tt><i>module</i><tt> [, </tt><i>module</i><tt>...]</tt></blockquote>
<blockquote><tt>from </tt><i>module</i><tt> cimport </tt><i>name</i><tt>
[as </tt><i>name</i><tt>] [, </tt><i>name</i><tt> [as </tt><i>name</i><tt>]
......@@ -90,10 +90,10 @@ exactly parallels that of the normal Python import statement:
</tr>
</tbody> </table>
<p>It is important to understand that the <b>cimport</b> statement can <i>only</i>
be used to import C data types, external C functions and variables, and extension
types. It cannot be used to import any Python objects, and (with one exception)
it doesn't imply any Python import at run time. If you want to refer to any
Python names from a module that you have cimported, you will have to include
be used to import C data types, external C functions and variables, and extension
types. It cannot be used to import any Python objects, and (with one exception)
it doesn't imply any Python import at run time. If you want to refer to any
Python names from a module that you have cimported, you will have to include
a regular <b>import</b> statement for it as well. </p>
<p>The exception is that when you use <b>cimport</b> to import an extension
type, its type object is imported at run time and made available by the
......@@ -103,7 +103,7 @@ types is covered in more detail <a href="#SharingExtensionTypes">below</a>.
<h3> <a name="SearchPaths"></a>Search paths for definition files</h3>
When you <b>cimport</b> a module called <tt>modulename</tt>, the Cython
compiler searches for a file called <tt>modulename.pxd</tt> along the search
path for include files, as specified by <b>-I</b> command line options.
path for include files, as specified by <b>-I</b> command line options.
<p>Also, whenever you compile a file <tt>modulename.pyx</tt>, the corresponding
definition file <tt>modulename.pxd</tt> is first searched for along the
same path, and if found, it is processed before processing the <tt>.pyx</tt>
......@@ -146,7 +146,7 @@ type's C attributes and C methods.<br>
<br>
The implementation part must implement all of the C methods declared in
the definition part, and may not add any further C attributes. It may also
define Python methods.
define Python methods.
<p>Here is an example of a module which defines and exports an extension
type, and another module which uses it. <br>
&nbsp; <table cellpadding="5" cols="2" width="100%">
......@@ -188,9 +188,9 @@ type, and another module which uses it. <br>
<li> There is a <tt>cdef class Shrubbery</tt> declaration in both Shrubbing.pxd
and Shrubbing.pyx. When the Shrubbing module is compiled, these two declarations
are combined into one.</li>
&nbsp; <li> In Landscaping.pyx, the <tt>cimport Shrubbing</tt> declaration
allows us to refer to the Shrubbery type as <tt>Shrubbing.Shrubbery</tt>.
&nbsp; <li> In Landscaping.pyx, the <tt>cimport Shrubbing</tt> declaration
allows us to refer to the Shrubbery type as <tt>Shrubbing.Shrubbery</tt>.
But it doesn't bind the name <tt>Shrubbery</tt> in Landscaping's module namespace
at run time, so to access <tt>Shrubbery.standard_shrubbery</tt> we also
need to <tt>import Shrubbing</tt>.</li>
......
......@@ -3,12 +3,12 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.61 (Macintosh; I; PPC) [Netscape]"><title>Special Methods of Extenstion Types</title></head>
<body>
<h1> <hr width="100%">Special Methods of Extension Types
<h1> <hr width="100%">Special Methods of Extension Types
<hr width="100%"></h1>
This page describes the special methods currently supported by Cython extension
types. A complete list of all the special methods appears in the table at
the bottom. Some of these methods behave differently from their Python counterparts
or have no direct Python counterparts, and require special mention.
types. A complete list of all the special methods appears in the table at
the bottom. Some of these methods behave differently from their Python counterparts
or have no direct Python counterparts, and require special mention.
<p><span style="font-weight: bold;">Note:</span><i> Everything said on this page applies only to </i><span style="font-weight: bold;">extension</span><i style="font-weight: bold;">
</i><span style="font-weight: bold;">types</span><i>, defined with the </i><span style="font-weight: bold; font-family: monospace;">cdef class</span><i> statement. It doesn't apply&nbsp;
to classes defined with the Python </i><span style="font-family: monospace;">class</span><i><span style="font-family: monospace;"> </span>statement, where the normal
......@@ -20,19 +20,19 @@ to classes defined with the Python </i><span style="font-family: monospace;">cla
types. You can place a docstring in the source to serve as a comment, but
it won't show up in the corresponding <span style="font-family: monospace;">__doc__</span> attribute at run time. (This
is a Python limitation -- there's nowhere in the PyTypeObject data structure
to put such docstrings.)
to put such docstrings.)
<h2> <font size="+1">Initialisation methods: <tt>__new__</tt> and <tt>__init__</tt></font></h2>
There are two methods concerned with initialising the object<tt>.</tt>
<p>The <b><tt>__new__</tt></b> method is where you should perform basic C-level
initialisation of the object, including allocation of any C data structures
that your object will own. You need to be careful what you do in the __new__
method, because the object may not yet be a valid Python object when it is
<p>The <b><tt>__new__</tt></b> method is where you should perform basic C-level
initialisation of the object, including allocation of any C data structures
that your object will own. You need to be careful what you do in the __new__
method, because the object may not yet be a valid Python object when it is
called. Therefore, you must not invoke any Python operations which might touch
the object; in particular, do not try to call any of its methods. </p>
<p>Unlike the corresponding method in Python, your <tt>__new__</tt> method
is <i>not</i> responsible for <i>creating</i> the object. By the time your
<tt>__new__</tt> method is called, memory has been allocated for the object
and any C attributes it has have been initialised to 0 or null. (Any Python
<tt>__new__</tt> method is called, memory has been allocated for the object
and any C attributes it has have been initialised to 0 or null. (Any Python
attributes have also been initialised to <tt>None</tt>, but you probably shouldn't
rely on that.) Your <tt>__new__</tt> method is guaranteed to be called exactly
once.<br>
......@@ -44,11 +44,11 @@ If you need to pass a modified argument list to the base type, you will have
to do the relevant part of the initialisation in the <tt>__init__</tt> method
instead (where the normal rules for calling inherited methods apply).<br>
</p>
<p>Note that the first parameter of the <tt>__new__</tt> method is the object
<p>Note that the first parameter of the <tt>__new__</tt> method is the object
to be initialised, not the class of the object as it is in Python. </p>
<p>Any initialisation which cannot safely be done in the <tt>__new__</tt>
method should be done in the <b><tt>__init__</tt></b> method. By the time
<tt>__init__</tt> is called, the object is a fully valid Python object and
<tt>__init__</tt> is called, the object is a fully valid Python object and
all operations are safe. Under some circumstances it is possible for <tt>__init__</tt>
to be called more than once or not to be called at all, so your other methods
should be designed to be robust in such situations. </p>
......@@ -57,27 +57,27 @@ to be called more than once or not to be called at all, so your other methods
If you anticipate subclassing your extension type in Python, you may find
it useful to give the <tt>__new__</tt> method * and ** arguments so that
it can accept and ignore extra arguments. Otherwise, any Python subclass
which has an <tt>__init__</tt> with a different signature will have to override
<tt>__new__</tt> as well as <tt>__init__</tt>, which the writer of a Python
which has an <tt>__init__</tt> with a different signature will have to override
<tt>__new__</tt> as well as <tt>__init__</tt>, which the writer of a Python
class wouldn't expect to have to do. </p>
<h2> <font size="+1">Finalization method: <tt>__dealloc__</tt><tt></tt></font></h2>
The counterpart to the <tt>__new__</tt> method is the <b><tt>__dealloc__</tt></b>
method, which should perform the inverse of the <tt>__new__</tt> method.
Any C data structures that you allocated in your <tt>__new__</tt> method
should be freed in your <tt>__dealloc__</tt> method.
<p>You need to be careful what you do in a <tt>__dealloc__</tt> method. By
the time your <tt>__dealloc__</tt> method is called, the object may already
have been partially destroyed and may not be in a valid state as far as Python
is concerned, so you should avoid invoking any Python operations which might
touch the object. In particular, don't call any other methods of the object
should be freed in your <tt>__dealloc__</tt> method.
<p>You need to be careful what you do in a <tt>__dealloc__</tt> method. By
the time your <tt>__dealloc__</tt> method is called, the object may already
have been partially destroyed and may not be in a valid state as far as Python
is concerned, so you should avoid invoking any Python operations which might
touch the object. In particular, don't call any other methods of the object
or do anything which might cause the object to be resurrected. It's best if
you stick to just deallocating C data. </p>
<p>You don't need to worry about deallocating Python attributes of your object,
<p>You don't need to worry about deallocating Python attributes of your object,
because that will be done for you by Cython after your <tt>__dealloc__</tt>
method returns.<br>
<br>
<b>Note:</b> There is no <tt>__del__</tt> method for extension types. (Earlier
versions of the Cython documentation stated that there was, but this turned
<b>Note:</b> There is no <tt>__del__</tt> method for extension types. (Earlier
versions of the Cython documentation stated that there was, but this turned
out to be incorrect.)<br>
</p>
<h2><font size="+1">Arithmetic methods</font></h2>
......@@ -85,7 +85,7 @@ out to be incorrect.)<br>
from their Python counterparts. There are no separate "reversed" versions
of these methods (<tt>__radd__</tt>, etc.) Instead, if the first operand
cannot perform the operation, the <i>same</i> method of the second operand
is called, with the operands in the <i>same order</i>.
is called, with the operands in the <i>same order</i>.
<p>This means that you can't rely on the first parameter of these methods
being "self", and you should test the types of both operands before deciding
what to do. If you can't handle the combination of types you've been given,
......@@ -96,8 +96,8 @@ is called, with the operands in the <i>same order</i>.
<h2> <font size="+1">Rich comparisons</font></h2>
There are no separate methods for the individual rich comparison operations
(<tt>__eq__</tt>, <tt>__le__</tt>, etc.) Instead there is a single method
<tt>__richcmp__</tt> which takes an integer indicating which operation is
to be performed, as follows:
<tt>__richcmp__</tt> which takes an integer indicating which operation is
to be performed, as follows:
<ul>
<ul>
&nbsp; <table nosave="" border="0" cellpadding="5" cellspacing="0">
......@@ -140,11 +140,11 @@ to be performed, as follows:
a method called <b><tt>__next__</tt></b>, <i>not</i> <tt>next</tt>. The Python
system will automatically supply a <tt>next</tt> method which calls your
<span style="font-family: monospace;">__next__</span>. <b>Do NOT explicitly give your type a <tt>next</tt> method</b>,
or bad things could happen (see note 3).
or bad things could happen (see note 3).
<h2> <font size="+1">Special Method Table</font></h2>
This table lists all of the special methods together with their parameter
and return types. A parameter named <b>self</b> is of the type the method
belongs to. Other untyped parameters are generic Python objects.
belongs to. Other untyped parameters are generic Python objects.
<p>You don't have to declare your method as taking these parameter types.
If you declare different types, conversions will be performed as necessary.
<br>
......@@ -586,14 +586,14 @@ or bad things could happen (see note 3).
</tbody> </table>
</p>
<p>Note 1: The buffer interface is intended for use by C code and is not
directly accessible from Python. It is described in the <a href="http://www.python.org/doc/current/api/api.html">Python/C API Reference
directly accessible from Python. It is described in the <a href="http://www.python.org/doc/current/api/api.html">Python/C API Reference
Manual</a> under sections <a href="http://www.python.org/doc/current/api/abstract-buffer.html">6.6</a>
and <a href="http://www.python.org/doc/current/api/buffer-structs.html">10.6</a>.
</p>
<p>Note 2: Descriptor objects are part of the support mechanism for new-style
Python classes. See the <a href="http://www.python.org/doc/2.2.1/whatsnew/sect-rellinks.html#SECTION000320000000000000000">discussion
of descriptors in the Python documentation</a>. See also <a href="http://www.python.org/peps/pep-0252.html">PEP 252, "Making Types Look
More Like Classes"</a>, and <a href="http://www.python.org/peps/pep-0253.html">PEP 253, "Subtyping Built-In
of descriptors in the Python documentation</a>. See also <a href="http://www.python.org/peps/pep-0252.html">PEP 252, "Making Types Look
More Like Classes"</a>, and <a href="http://www.python.org/peps/pep-0253.html">PEP 253, "Subtyping Built-In
Types"</a>. </p>
<p>Note 3: If your type defines a <tt>__new__</tt> method, any method called
<tt>new</tt> that you define will be overwritten with the system-supplied
......
......@@ -2,7 +2,7 @@ PYTHON?=python
TESTOPTS?=
REPO = git://github.com/cython/cython.git
all: local
all: local
local:
${PYTHON} setup.py build_ext --inplace
......@@ -23,8 +23,8 @@ clean:
@echo Cleaning Source
@rm -fr build
@rm -f *.py[co] */*.py[co] */*/*.py[co] */*/*/*.py[co]
@rm -f *.so */*.so */*/*.so
@rm -f *.pyd */*.pyd */*/*.pyd
@rm -f *.so */*.so */*/*.so
@rm -f *.pyd */*.pyd */*/*.pyd
@rm -f *~ */*~ */*/*~
@rm -f core */core
@rm -f Cython/Compiler/*.c
......
......@@ -9,14 +9,14 @@
<!--
Disclaimer: IANAL. This file is a derivative work of KDE's Python
syntax file. KDE does not specify a license for the syntax file python.xml
in it's katepart component. However, katepart and KATE as a whole is
released with LGPL v2. Assuing python.xml is LGPL'd, this file is hereby
released with the same license. Note that this only applies to this XML
Disclaimer: IANAL. This file is a derivative work of KDE's Python
syntax file. KDE does not specify a license for the syntax file python.xml
in it's katepart component. However, katepart and KATE as a whole is
released with LGPL v2. Assuing python.xml is LGPL'd, this file is hereby
released with the same license. Note that this only applies to this XML
file. It does not apply to any work written using this file to highlighting
syntax. Any changes you make to this file will be covered by the LGPL,
but it does not to my knowledge taint your source code. At least not
syntax. Any changes you make to this file will be covered by the LGPL,
but it does not to my knowledge taint your source code. At least not
any more than using KDE would do. Sturla Molden
Thus:
......@@ -69,10 +69,10 @@ Boston, MA 02110-1301, USA.
</list>
<list name="keyw" >
<item> extern </item>
<item> api </item>
<item> api </item>
<item> del </item>
<item> global </item>
<item> property </item>
<item> property </item>
<item> nogil </item>
<item> gil </item>
<item> inline </item>
......@@ -80,7 +80,7 @@ Boston, MA 02110-1301, USA.
<list name="access">
<item> readonly </item>
<item> public </item>
</list>
</list>
<list name="operators">
<item> and </item>
<item> assert </item>
......@@ -89,7 +89,7 @@ Boston, MA 02110-1301, USA.
<item> by </item>
<item> not </item>
<item> or </item>
<item> sizeof </item>
<item> sizeof </item>
</list>
<list name="commands">
<!-- <item> exec </item> -->
......@@ -216,7 +216,7 @@ Boston, MA 02110-1301, USA.
</list>
<list name="cythonmodule">
<item> cython </item>
</list>
</list>
<list name="numpytypes">
<item> dtype </item>
<item> flatiter </item>
......@@ -244,48 +244,48 @@ Boston, MA 02110-1301, USA.
<item> cfloat_t </item>
<item> cdouble_t </item>
<item> clongdouble_t </item>
<item> complex_t </item>
<item> npy_int8 </item>
<item> npy_int16 </item>
<item> npy_int32 </item>
<item> npy_int64 </item>
<item> npy_int96 </item>
<item> npy_int128 </item>
<item> npy_uint8 </item>
<item> npy_uint16 </item>
<item> npy_uint32 </item>
<item> npy_uint64 </item>
<item> npy_uint96 </item>
<item> npy_uint128 </item>
<item> npy_float32 </item>
<item> npy_float64 </item>
<item> npy_float80 </item>
<item> npy_float96 </item>
<item> npy_float128 </item>
<item> npy_complex64 </item>
<item> npy_complex128 </item>
<item> npy_complex120 </item>
<item> npy_complex192 </item>
<item> npy_complex256 </item>
<item> npy_cfloat </item>
<item> npy_cdouble </item>
<item> npy_clongdouble </item>
<item> npy_bool </item>
<item> npy_byte </item>
<item> npy_short </item>
<item> npy_int </item>
<item> npy_long </item>
<item> npy_longlong </item>
<item> npy_ubyte </item>
<item> npy_ushort </item>
<item> npy_uint </item>
<item> npy_ulong </item>
<item> npy_ulonglong </item>
<item> npy_float </item>
<item> npy_double </item>
<item> npy_longdouble </item>
<item> complex_t </item>
<item> npy_int8 </item>
<item> npy_int16 </item>
<item> npy_int32 </item>
<item> npy_int64 </item>
<item> npy_int96 </item>
<item> npy_int128 </item>
<item> npy_uint8 </item>
<item> npy_uint16 </item>
<item> npy_uint32 </item>
<item> npy_uint64 </item>
<item> npy_uint96 </item>
<item> npy_uint128 </item>
<item> npy_float32 </item>
<item> npy_float64 </item>
<item> npy_float80 </item>
<item> npy_float96 </item>
<item> npy_float128 </item>
<item> npy_complex64 </item>
<item> npy_complex128 </item>
<item> npy_complex120 </item>
<item> npy_complex192 </item>
<item> npy_complex256 </item>
<item> npy_cfloat </item>
<item> npy_cdouble </item>
<item> npy_clongdouble </item>
<item> npy_bool </item>
<item> npy_byte </item>
<item> npy_short </item>
<item> npy_int </item>
<item> npy_long </item>
<item> npy_longlong </item>
<item> npy_ubyte </item>
<item> npy_ushort </item>
<item> npy_uint </item>
<item> npy_ulong </item>
<item> npy_ulonglong </item>
<item> npy_float </item>
<item> npy_double </item>
<item> npy_longdouble </item>
<item> npy_intp </item>
</list>
</list>
<list name="numpyfuncs">
<item> DataSource </item>
<item> MachAr </item>
......@@ -868,43 +868,43 @@ Boston, MA 02110-1301, USA.
<item>WindowsError</item>
<item>ZeroDivisionError</item>
</list>
<contexts>
<context name="Normal" attribute="Normal Text" lineEndContext="#stay">
<keyword attribute="Definition Keyword" String="cdef" context="cdefname"/>
<keyword attribute="Definition Keyword" String="defs" context="defname"/>
<keyword attribute="Definition Keyword" String="keyw" context="#stay"/>
<keyword attribute="Import Keyword" String="imports" context="#stay"/>
<keyword attribute="Preprocessor" String="prep" context="#stay"/>
<keyword attribute="Operator" String="operators" context="#stay"/>
<keyword attribute="Command Keyword" String="commands" context="#stay"/>
<keyword attribute="Flow Control Keyword" String="flow" context="#stay"/>
<keyword attribute="Builtin Function" String="builtinfuncs" context="#stay"/>
<keyword attribute="Special Variable" String="specialvars" context="#stay"/>
<keyword attribute="Special Variable" String="exceptions" context="#stay"/>
<keyword attribute="Special Variable" String="overloaders" context="#stay"/>
<keyword attribute="C Type" context="#stay" String="ctypes" />
<keyword attribute="Python Type" context="#stay" String="pytypes" />
<RegExpr attribute="Hex" String="0[Xx][0-9a-fA-F]+" context="#stay"/>
<RegExpr attribute="Octal" String="0[1-9][0-9]*" context="#stay"/>
<RegExpr attribute="Binary" String="0[Bb][0-9a-fA-F]+" context="#stay"/>
<RegExpr attribute="Complex" String=" ((([0-9]*\.[0-9]+|[0-9]+\.)|([0-9]+|([0-9]*\.[0-9]+|[0-9]+\.))[eE](\+|-)?[0-9]+)|[0-9]+)[jJ]" context="#stay"/>
<RegExpr attribute="Float" String="([0-9]+\.[0-9]*|\.[0-9]+)([eE][0-9]+)?" context="#stay"/>
<RegExpr attribute="Int" String="([1-9][0-9]*([eE][0-9]+)?|0)" context="#stay"/>
<RegExpr attribute="Long" String="[1-9][0-9]*([eE][0-9.]+)?[Ll]" context="#stay"/>
<keyword attribute="NumPyAttr" String="numpyselector" context="numpy"/>
<RegExpr attribute="Decorator" String="@[a-zA-Z_][a-zA-Z_0-9\.]+" context="#stay"/>
<RegExpr attribute="Normal" String="[a-zA-Z_][a-zA-Z_0-9]+" context="#stay"/>
<RegExpr attribute="Raw String" String="[rR]'''" context="Raw Tripple A-string"/>
......@@ -916,115 +916,115 @@ Boston, MA 02110-1301, USA.
<RegExpr attribute="Comment" String="#.*$" context="#stay"/>
<RegExpr attribute="Comment" String="^\s*'''" context="Tripple A-comment" beginRegion="Tripple A-region"/>
<RegExpr attribute="Comment" String="^\s*&quot;&quot;&quot;" context="Tripple Q-comment" beginRegion="Tripple Q-region"/>
<StringDetect attribute="String" String="'''" context="Tripple A-string" beginRegion="Tripple A-region"/>
<StringDetect attribute="String" String="&quot;&quot;&quot;" context="Tripple Q-string" beginRegion="Tripple Q-region"/>
<DetectChar attribute="String" char="'" context="Single A-string"/>
<DetectChar attribute="String" char="&quot;" context="Single Q-string"/>
<DetectChar attribute="Operator" char="(" context="parenthesis" />
<DetectChar attribute="Operator" char="[" context="bracet" />
<DetectChar attribute="Operator" char="{" context="dict" />
<RegExpr attribute="Operator" String="[+*/%\|=;\!&lt;&gt;!^&amp;~-]" context="#stay"/>
<RegExpr attribute="String Substitution" String="%[a-zA-Z]" context="#stay"/>
</context>
<context name="numpy" attribute="Normal Text" lineEndContext="#pop" noIndentationBasedFolding="True">
<!-- highlight types in numpy.pxd after cimport numpy -->
<!-- highlight types in numpy.pxd after cimport numpy -->
<keyword attribute="Import Keyword" context="#pop" String="as" />
<DetectChar attribute="Dot" context="#stay" char="." />
<keyword attribute="NumPy Type" context="#pop" String="numpytypes" />
<keyword attribute="NumPy Function" context="#pop" String="numpyfuncs" />
</context>
<context name="parenthesis" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="True">
<DetectChar attribute="Operator" char=")" context="#pop" />
<DetectChar attribute="Operator" char=")" context="#pop" />
<IncludeRules context="Normal" />
</context>
<context name="bracet" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="True">
<StringDetect attribute="Normal" String="readonly" context="#stay" />
<DetectChar attribute="Operator" char="]" context="#pop" />
<StringDetect attribute="Normal" String="readonly" context="#stay" />
<DetectChar attribute="Operator" char="]" context="#pop" />
<IncludeRules context="Normal" />
</context>
<context name="dict" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="True">
<DetectChar attribute="Operator" char="}" context="#pop" />
<IncludeRules context="Normal" />
</context>
<context name="defname" attribute="Normal Text" lineEndContext="#pop" noIndentationBasedFolding="True">
<RegExpr attribute="Definition Name" String="[a-zA-Z_][a-zA-Z_0-9]+" context="#stay"/>
<DetectChar attribute="Operator" char="(" context="callargs" />
<DetectChar attribute="Operator" char="[" context="callbracket" />
<IncludeRules context="Normal" />
</context>
<context name="callargs" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="True">
<DetectChar attribute="Operator" char=")" context="#pop#pop" />
<IncludeRules context="Normal" />
</context>
<context name="callbracket" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="True">
<DetectChar attribute="Operator" char="]" context="#pop#pop" />
<IncludeRules context="Normal" />
</context>
<context name="cdefname" attribute="Normal Text" lineEndContext="#pop" noIndentationBasedFolding="True">
<keyword attribute="Definition Keyword" String="defs" context="defname"/>
<keyword attribute="Definition Keyword" String="keyw" context="#stay"/>
<keyword attribute="Definition Keyword" String="access" context="#stay"/>
<keyword attribute="Import Keyword" String="imports" context="#stay"/>
<keyword attribute="Special Variable" String="specialvars" context="#stay"/>
<keyword attribute="C Type" context="#pop" String="ctypes" />
<keyword attribute="Python Type" context="#pop" String="pytypes" />
<RegExpr attribute="Hex" String="0[Xx][0-9a-fA-F]+" context="#stay"/>
<RegExpr attribute="Octal" String="0[1-9][0-9]*" context="#stay"/>
<RegExpr attribute="Binary" String="0[Bb][0-9a-fA-F]+" context="#stay"/>
<RegExpr attribute="Complex" String=" ((([0-9]*\.[0-9]+|[0-9]+\.)|([0-9]+|([0-9]*\.[0-9]+|[0-9]+\.))[eE](\+|-)?[0-9]+)|[0-9]+)[jJ]" context="#stay"/>
<RegExpr attribute="Float" String="([0-9]+\.[0-9]*|\.[0-9]+)([eE][0-9]+)?" context="#stay"/>
<RegExpr attribute="Int" String="([1-9][0-9]*([eE][0-9]+)?|0)" context="#stay"/>
<RegExpr attribute="Long" String="[1-9][0-9]*([eE][0-9.]+)?[Ll]" context="#stay"/>
<keyword attribute="NumPyAttr" String="numpyselector" context="numpy2"/>
<RegExpr attribute="C Definition Name" String="[a-zA-Z_][a-zA-Z_0-9]+" context="#stay"/>
<DetectChar attribute="Operator" char="(" context="callargs" />
<IncludeRules context="Normal" />
</context>
<context name="callargs" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="True">
<DetectChar attribute="Operator" char=")" context="#pop#pop" />
<IncludeRules context="Normal" />
</context>
<context name="numpy2" attribute="Normal Text" lineEndContext="#pop" noIndentationBasedFolding="True">
<!-- highlight types in numpy.pxd after cimport numpy -->
<DetectChar attribute="Dot" context="#stay" char="." />
<keyword attribute="NumPy Type" context="#pop#pop" String="numpytypes" />
</context>
<context name="Tripple A-comment" attribute="Comment" lineEndContext="#stay" noIndentationBasedFolding="True">
<StringDetect attribute="Comment" String="'''" context="#pop" endRegion="Tripple A-region"/>
</context>
......
......@@ -31,7 +31,7 @@ def analyse(source_path=None, code=None):
raise ValueError("Either 'source_path' or 'code' is required.")
scoped_names = {}
statement_iter = jedi.names(source=code, path=source_path, all_scopes=True)
for statement in statement_iter:
parent = statement.parent()
scope = parent._definition
......@@ -45,7 +45,7 @@ def analyse(source_path=None, code=None):
names = scoped_names[key]
except KeyError:
names = scoped_names[key] = defaultdict(set)
position = statement.start_pos if statement.name in names else None
for name_type in evaluator.find_types(scope, statement.name, position=position ,search_global=True):
......@@ -60,8 +60,8 @@ def analyse(source_path=None, code=None):
type_name = None
else:
try:
type_name = type(name_type.obj).__name__
except AttributeError as error:
type_name = type(name_type.obj).__name__
except AttributeError as error:
type_name = None
if type_name is not None:
names[str(statement.name)].add(type_name)
......
......@@ -20,14 +20,14 @@ diff -r db4133d43a7e -r 0a6ce52272f6 Tools/cython-numpy-mode-kate.xml
+
+<!--
+
+Disclaimer: IANAL. This file is a derivative work of KDE's Python
+syntax file. KDE does not specify a license for the syntax file python.xml
+in it's katepart component. However, katepart and KATE as a whole is
+released with LGPL v2. Assuing python.xml is LGPL'd, this file is hereby
+released with the same license. Note that this only applies to this XML
+Disclaimer: IANAL. This file is a derivative work of KDE's Python
+syntax file. KDE does not specify a license for the syntax file python.xml
+in it's katepart component. However, katepart and KATE as a whole is
+released with LGPL v2. Assuing python.xml is LGPL'd, this file is hereby
+released with the same license. Note that this only applies to this XML
+file. It does not apply to any work written using this file to highlighting
+syntax. Any changes you make to this file will be covered by the LGPL,
+but it does not to my knowledge taint your source code. At least not
+syntax. Any changes you make to this file will be covered by the LGPL,
+but it does not to my knowledge taint your source code. At least not
+any more than using KDE would do. Sturla Molden
+
+Thus:
......@@ -80,10 +80,10 @@ diff -r db4133d43a7e -r 0a6ce52272f6 Tools/cython-numpy-mode-kate.xml
+ </list>
+ <list name="keyw" >
+ <item> extern </item>
+ <item> api </item>
+ <item> api </item>
+ <item> del </item>
+ <item> global </item>
+ <item> property </item>
+ <item> property </item>
+ <item> nogil </item>
+ <item> gil </item>
+ <item> inline </item>
......@@ -91,7 +91,7 @@ diff -r db4133d43a7e -r 0a6ce52272f6 Tools/cython-numpy-mode-kate.xml
+ <list name="access">
+ <item> readonly </item>
+ <item> public </item>
+ </list>
+ </list>
+ <list name="operators">
+ <item> and </item>
+ <item> assert </item>
......@@ -100,7 +100,7 @@ diff -r db4133d43a7e -r 0a6ce52272f6 Tools/cython-numpy-mode-kate.xml
+ <item> by </item>
+ <item> not </item>
+ <item> or </item>
+ <item> sizeof </item>
+ <item> sizeof </item>
+ </list>
+ <list name="commands">
+ <!-- <item> exec </item> -->
......@@ -227,7 +227,7 @@ diff -r db4133d43a7e -r 0a6ce52272f6 Tools/cython-numpy-mode-kate.xml
+ </list>
+ <list name="cythonmodule">
+ <item> cython </item>
+ </list>
+ </list>
+ <list name="numpytypes">
+ <item> dtype </item>
+ <item> flatiter </item>
......@@ -255,48 +255,48 @@ diff -r db4133d43a7e -r 0a6ce52272f6 Tools/cython-numpy-mode-kate.xml
+ <item> cfloat_t </item>
+ <item> cdouble_t </item>
+ <item> clongdouble_t </item>
+ <item> complex_t </item>
+ <item> npy_int8 </item>
+ <item> npy_int16 </item>
+ <item> npy_int32 </item>
+ <item> npy_int64 </item>
+ <item> npy_int96 </item>
+ <item> npy_int128 </item>
+ <item> npy_uint8 </item>
+ <item> npy_uint16 </item>
+ <item> npy_uint32 </item>
+ <item> npy_uint64 </item>
+ <item> npy_uint96 </item>
+ <item> npy_uint128 </item>
+ <item> npy_float32 </item>
+ <item> npy_float64 </item>
+ <item> npy_float80 </item>
+ <item> npy_float96 </item>
+ <item> npy_float128 </item>
+ <item> npy_complex64 </item>
+ <item> npy_complex128 </item>
+ <item> npy_complex120 </item>
+ <item> npy_complex192 </item>
+ <item> npy_complex256 </item>
+ <item> npy_cfloat </item>
+ <item> npy_cdouble </item>
+ <item> npy_clongdouble </item>
+ <item> npy_bool </item>
+ <item> npy_byte </item>
+ <item> npy_short </item>
+ <item> npy_int </item>
+ <item> npy_long </item>
+ <item> npy_longlong </item>
+ <item> npy_ubyte </item>
+ <item> npy_ushort </item>
+ <item> npy_uint </item>
+ <item> npy_ulong </item>
+ <item> npy_ulonglong </item>
+ <item> npy_float </item>
+ <item> npy_double </item>
+ <item> npy_longdouble </item>
+ <item> complex_t </item>
+ <item> npy_int8 </item>
+ <item> npy_int16 </item>
+ <item> npy_int32 </item>
+ <item> npy_int64 </item>
+ <item> npy_int96 </item>
+ <item> npy_int128 </item>
+ <item> npy_uint8 </item>
+ <item> npy_uint16 </item>
+ <item> npy_uint32 </item>
+ <item> npy_uint64 </item>
+ <item> npy_uint96 </item>
+ <item> npy_uint128 </item>
+ <item> npy_float32 </item>
+ <item> npy_float64 </item>
+ <item> npy_float80 </item>
+ <item> npy_float96 </item>
+ <item> npy_float128 </item>
+ <item> npy_complex64 </item>
+ <item> npy_complex128 </item>
+ <item> npy_complex120 </item>
+ <item> npy_complex192 </item>
+ <item> npy_complex256 </item>
+ <item> npy_cfloat </item>
+ <item> npy_cdouble </item>
+ <item> npy_clongdouble </item>
+ <item> npy_bool </item>
+ <item> npy_byte </item>
+ <item> npy_short </item>
+ <item> npy_int </item>
+ <item> npy_long </item>
+ <item> npy_longlong </item>
+ <item> npy_ubyte </item>
+ <item> npy_ushort </item>
+ <item> npy_uint </item>
+ <item> npy_ulong </item>
+ <item> npy_ulonglong </item>
+ <item> npy_float </item>
+ <item> npy_double </item>
+ <item> npy_longdouble </item>
+ <item> npy_intp </item>
+ </list>
+ </list>
+ <list name="numpyfuncs">
+ <item> DataSource </item>
+ <item> MachAr </item>
......@@ -879,43 +879,43 @@ diff -r db4133d43a7e -r 0a6ce52272f6 Tools/cython-numpy-mode-kate.xml
+ <item>WindowsError</item>
+ <item>ZeroDivisionError</item>
+ </list>
+
+
+ <contexts>
+
+
+ <context name="Normal" attribute="Normal Text" lineEndContext="#stay">
+
+
+ <keyword attribute="Definition Keyword" String="cdef" context="cdefname"/>
+ <keyword attribute="Definition Keyword" String="defs" context="defname"/>
+ <keyword attribute="Definition Keyword" String="keyw" context="#stay"/>
+
+
+ <keyword attribute="Import Keyword" String="imports" context="#stay"/>
+ <keyword attribute="Preprocessor" String="prep" context="#stay"/>
+ <keyword attribute="Operator" String="operators" context="#stay"/>
+ <keyword attribute="Command Keyword" String="commands" context="#stay"/>
+ <keyword attribute="Flow Control Keyword" String="flow" context="#stay"/>
+ <keyword attribute="Builtin Function" String="builtinfuncs" context="#stay"/>
+
+
+ <keyword attribute="Special Variable" String="specialvars" context="#stay"/>
+ <keyword attribute="Special Variable" String="exceptions" context="#stay"/>
+ <keyword attribute="Special Variable" String="overloaders" context="#stay"/>
+
+
+ <keyword attribute="C Type" context="#stay" String="ctypes" />
+ <keyword attribute="Python Type" context="#stay" String="pytypes" />
+
+
+ <RegExpr attribute="Hex" String="0[Xx][0-9a-fA-F]+" context="#stay"/>
+ <RegExpr attribute="Octal" String="0[1-9][0-9]*" context="#stay"/>
+ <RegExpr attribute="Binary" String="0[Bb][0-9a-fA-F]+" context="#stay"/>
+
+
+ <RegExpr attribute="Complex" String=" ((([0-9]*\.[0-9]+|[0-9]+\.)|([0-9]+|([0-9]*\.[0-9]+|[0-9]+\.))[eE](\+|-)?[0-9]+)|[0-9]+)[jJ]" context="#stay"/>
+ <RegExpr attribute="Float" String="([0-9]+\.[0-9]*|\.[0-9]+)([eE][0-9]+)?" context="#stay"/>
+
+
+ <RegExpr attribute="Int" String="([1-9][0-9]*([eE][0-9]+)?|0)" context="#stay"/>
+ <RegExpr attribute="Long" String="[1-9][0-9]*([eE][0-9.]+)?[Ll]" context="#stay"/>
+
+
+ <keyword attribute="NumPyAttr" String="numpyselector" context="numpy"/>
+
+
+ <RegExpr attribute="Decorator" String="@[a-zA-Z_][a-zA-Z_0-9\.]+" context="#stay"/>
+
+
+ <RegExpr attribute="Normal" String="[a-zA-Z_][a-zA-Z_0-9]+" context="#stay"/>
+
+ <RegExpr attribute="Raw String" String="[rR]'''" context="Raw Tripple A-string"/>
......@@ -927,115 +927,115 @@ diff -r db4133d43a7e -r 0a6ce52272f6 Tools/cython-numpy-mode-kate.xml
+ <RegExpr attribute="Comment" String="#.*$" context="#stay"/>
+ <RegExpr attribute="Comment" String="^\s*'''" context="Tripple A-comment" beginRegion="Tripple A-region"/>
+ <RegExpr attribute="Comment" String="^\s*&quot;&quot;&quot;" context="Tripple Q-comment" beginRegion="Tripple Q-region"/>
+
+
+ <StringDetect attribute="String" String="'''" context="Tripple A-string" beginRegion="Tripple A-region"/>
+ <StringDetect attribute="String" String="&quot;&quot;&quot;" context="Tripple Q-string" beginRegion="Tripple Q-region"/>
+ <DetectChar attribute="String" char="'" context="Single A-string"/>
+ <DetectChar attribute="String" char="&quot;" context="Single Q-string"/>
+
+
+
+
+ <DetectChar attribute="Operator" char="(" context="parenthesis" />
+
+
+ <DetectChar attribute="Operator" char="[" context="bracet" />
+
+
+ <DetectChar attribute="Operator" char="{" context="dict" />
+
+
+ <RegExpr attribute="Operator" String="[+*/%\|=;\!&lt;&gt;!^&amp;~-]" context="#stay"/>
+
+
+ <RegExpr attribute="String Substitution" String="%[a-zA-Z]" context="#stay"/>
+
+
+ </context>
+
+
+ <context name="numpy" attribute="Normal Text" lineEndContext="#pop" noIndentationBasedFolding="True">
+ <!-- highlight types in numpy.pxd after cimport numpy -->
+ <!-- highlight types in numpy.pxd after cimport numpy -->
+ <keyword attribute="Import Keyword" context="#pop" String="as" />
+ <DetectChar attribute="Dot" context="#stay" char="." />
+ <keyword attribute="NumPy Type" context="#pop" String="numpytypes" />
+ <keyword attribute="NumPy Function" context="#pop" String="numpyfuncs" />
+ </context>
+
+
+ <context name="parenthesis" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="True">
+ <DetectChar attribute="Operator" char=")" context="#pop" />
+ <DetectChar attribute="Operator" char=")" context="#pop" />
+ <IncludeRules context="Normal" />
+ </context>
+
+
+ <context name="bracet" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="True">
+ <StringDetect attribute="Normal" String="readonly" context="#stay" />
+ <DetectChar attribute="Operator" char="]" context="#pop" />
+ <StringDetect attribute="Normal" String="readonly" context="#stay" />
+ <DetectChar attribute="Operator" char="]" context="#pop" />
+ <IncludeRules context="Normal" />
+ </context>
+
+
+ <context name="dict" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="True">
+ <DetectChar attribute="Operator" char="}" context="#pop" />
+ <IncludeRules context="Normal" />
+ </context>
+
+
+ <context name="defname" attribute="Normal Text" lineEndContext="#pop" noIndentationBasedFolding="True">
+ <RegExpr attribute="Definition Name" String="[a-zA-Z_][a-zA-Z_0-9]+" context="#stay"/>
+ <DetectChar attribute="Operator" char="(" context="callargs" />
+ <DetectChar attribute="Operator" char="[" context="callbracket" />
+ <IncludeRules context="Normal" />
+ </context>
+
+
+ <context name="callargs" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="True">
+ <DetectChar attribute="Operator" char=")" context="#pop#pop" />
+ <IncludeRules context="Normal" />
+ </context>
+
+
+ <context name="callbracket" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="True">
+ <DetectChar attribute="Operator" char="]" context="#pop#pop" />
+ <IncludeRules context="Normal" />
+ </context>
+
+
+
+
+ <context name="cdefname" attribute="Normal Text" lineEndContext="#pop" noIndentationBasedFolding="True">
+ <keyword attribute="Definition Keyword" String="defs" context="defname"/>
+ <keyword attribute="Definition Keyword" String="keyw" context="#stay"/>
+ <keyword attribute="Definition Keyword" String="access" context="#stay"/>
+ <keyword attribute="Import Keyword" String="imports" context="#stay"/>
+ <keyword attribute="Special Variable" String="specialvars" context="#stay"/>
+
+
+ <keyword attribute="C Type" context="#pop" String="ctypes" />
+ <keyword attribute="Python Type" context="#pop" String="pytypes" />
+
+
+ <RegExpr attribute="Hex" String="0[Xx][0-9a-fA-F]+" context="#stay"/>
+ <RegExpr attribute="Octal" String="0[1-9][0-9]*" context="#stay"/>
+ <RegExpr attribute="Binary" String="0[Bb][0-9a-fA-F]+" context="#stay"/>
+
+
+ <RegExpr attribute="Complex" String=" ((([0-9]*\.[0-9]+|[0-9]+\.)|([0-9]+|([0-9]*\.[0-9]+|[0-9]+\.))[eE](\+|-)?[0-9]+)|[0-9]+)[jJ]" context="#stay"/>
+ <RegExpr attribute="Float" String="([0-9]+\.[0-9]*|\.[0-9]+)([eE][0-9]+)?" context="#stay"/>
+
+
+ <RegExpr attribute="Int" String="([1-9][0-9]*([eE][0-9]+)?|0)" context="#stay"/>
+ <RegExpr attribute="Long" String="[1-9][0-9]*([eE][0-9.]+)?[Ll]" context="#stay"/>
+
+
+ <keyword attribute="NumPyAttr" String="numpyselector" context="numpy2"/>
+
+
+ <RegExpr attribute="C Definition Name" String="[a-zA-Z_][a-zA-Z_0-9]+" context="#stay"/>
+ <DetectChar attribute="Operator" char="(" context="callargs" />
+ <IncludeRules context="Normal" />
+ </context>
+
+
+ <context name="callargs" attribute="Normal Text" lineEndContext="#stay" noIndentationBasedFolding="True">
+ <DetectChar attribute="Operator" char=")" context="#pop#pop" />
+ <IncludeRules context="Normal" />
+ </context>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <context name="numpy2" attribute="Normal Text" lineEndContext="#pop" noIndentationBasedFolding="True">
+ <!-- highlight types in numpy.pxd after cimport numpy -->
+ <DetectChar attribute="Dot" context="#stay" char="." />
+ <keyword attribute="NumPy Type" context="#pop#pop" String="numpytypes" />
+ </context>
+
+
+
+
+
+
+
+
+ <context name="Tripple A-comment" attribute="Comment" lineEndContext="#stay" noIndentationBasedFolding="True">
+ <StringDetect attribute="Comment" String="'''" context="#pop" endRegion="Tripple A-region"/>
+ </context>
......
......@@ -133,7 +133,7 @@ def set_basic_vars(env):
# this work, we need to know whether PYEXTCC accepts /c and /Fo or -c -o.
# This is difficult with the current way tools work in scons.
pycc, pycxx, pylink = pyext_coms(sys.platform)
env['PYEXTLINKFLAGSEND'] = SCons.Util.CLVar('$LINKFLAGSEND')
env['PYEXTCCCOM'] = pycc
......@@ -157,7 +157,7 @@ def _set_configuration_nodistutils(env):
for k, v in def_cfg.items():
ifnotset(env, k, v)
ifnotset(env, 'PYEXT_ALLOW_UNDEFINED',
ifnotset(env, 'PYEXT_ALLOW_UNDEFINED',
SCons.Util.CLVar('$ALLOW_UNDEFINED'))
ifnotset(env, 'PYEXTLINKFLAGS', SCons.Util.CLVar('$LDMODULEFLAGS'))
......@@ -178,12 +178,12 @@ def set_configuration(env, use_distutils):
# We define commands as strings so that we can either execute them using
# eval (same python for scons and distutils) or by executing them through
# the shell.
dist_cfg = {'PYEXTCC': ("sysconfig.get_config_var('CC')", False),
'PYEXTCFLAGS': ("sysconfig.get_config_var('CFLAGS')", True),
'PYEXTCCSHARED': ("sysconfig.get_config_var('CCSHARED')", False),
'PYEXTLINKFLAGS': ("sysconfig.get_config_var('LDFLAGS')", True),
'PYEXTLINK': ("sysconfig.get_config_var('LDSHARED')", False),
'PYEXTINCPATH': ("sysconfig.get_python_inc()", False),
dist_cfg = {'PYEXTCC': ("sysconfig.get_config_var('CC')", False),
'PYEXTCFLAGS': ("sysconfig.get_config_var('CFLAGS')", True),
'PYEXTCCSHARED': ("sysconfig.get_config_var('CCSHARED')", False),
'PYEXTLINKFLAGS': ("sysconfig.get_config_var('LDFLAGS')", True),
'PYEXTLINK': ("sysconfig.get_config_var('LDSHARED')", False),
'PYEXTINCPATH': ("sysconfig.get_python_inc()", False),
'PYEXTSUFFIX': ("sysconfig.get_config_var('SO')", False)}
from distutils import sysconfig
......@@ -208,7 +208,7 @@ def generate(env):
if 'PYEXT_USE_DISTUTILS' not in env:
env['PYEXT_USE_DISTUTILS'] = False
# This sets all constructions variables used for pyext builders.
# This sets all constructions variables used for pyext builders.
set_basic_vars(env)
set_configuration(env, env['PYEXT_USE_DISTUTILS'])
......
......@@ -6,21 +6,21 @@ Background
The "Old Cython Users Guide" is a derivative of the old Pyrex documentation.
It underwent substantial editing by Peter Alexandar
to become the Reference Guide, which is oriented around bullet points
and lists rather than prose. This transition was incomplete.
and lists rather than prose. This transition was incomplete.
At nearly the same time, Robert, Dag, and Stefan wrote a tutorial as
part of the SciPy proceedings. It was felt that the content there was
cleaner and more up to date than anything else, and this became the
basis for the "Getting Started" and "Tutorials" sections. However,
it simply doesn't have as much content as the old documentation used to.
At nearly the same time, Robert, Dag, and Stefan wrote a tutorial as
part of the SciPy proceedings. It was felt that the content there was
cleaner and more up to date than anything else, and this became the
basis for the "Getting Started" and "Tutorials" sections. However,
it simply doesn't have as much content as the old documentation used to.
Eventually, it seems all of the old users manual could be whittled
down into independent tutorial topics. Much discussion of what we'd
like to see is at
like to see is at
http://www.mail-archive.com/cython-dev@codespeak.net/msg06945.html
There is currently a huge amount of redundancy, but no one section has
it all.
There is currently a huge amount of redundancy, but no one section has
it all.
Also, we should go through the wiki enhancement proposal list
and make sure to transfer the (done) ones into the user manual.
and make sure to transfer the (done) ones into the user manual.
......@@ -77,5 +77,5 @@ def integrate_f2(double a, double b, int N):
for i in range(N):
s += f2(a+i*dx)
return s * dx
timeit(integrate_f2, "Typed func")
......@@ -25,7 +25,7 @@ Originally based on the well-known Pyrex [Pyrex]_, the Cython project
has approached this problem by means of a source code compiler that
translates Python code to equivalent C code. This code is executed
within the CPython runtime environment, but at the speed of compiled C
and with the ability to call directly into C libraries.
and with the ability to call directly into C libraries.
At the same time, it keeps the original interface of the Python
source code, which makes it directly usable from Python code. These
two-fold characteristics enable Cython's two major use cases:
......@@ -48,7 +48,7 @@ language.
.. [IronPython] Jim Hugunin et al., http://www.codeplex.com/IronPython.
.. [Jython] J. Huginin, B. Warsaw, F. Bock, et al.,
Jython: Python for the Java platform, http://www.jython.org.
.. [PyPy] The PyPy Group, PyPy: a Python implementation written in Python,
.. [PyPy] The PyPy Group, PyPy: a Python implementation written in Python,
http://pypy.org.
.. [Pyrex] G. Ewing, Pyrex: C-Extensions for Python,
http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/
......
Appendix: Installing MinGW on Windows
=====================================
1. Download the MinGW installer from
http://www.mingw.org/wiki/HOWTO_Install_the_MinGW_GCC_Compiler_Suite.
1. Download the MinGW installer from
http://www.mingw.org/wiki/HOWTO_Install_the_MinGW_GCC_Compiler_Suite.
(As of this
writing, the download link is a bit difficult to find; it's under
"About" in the menu on the left-hand side). You want the file
......
......@@ -15,5 +15,5 @@ for Python users, so this list may change in the future.
print(range(-n, n))`` will print an empty list, since ``-n`` wraps
around to a large positive integer prior to being passed to the
``range`` function.
- Python's ``float`` type actually wraps C ``double`` values, and
- Python's ``float`` type actually wraps C ``double`` values, and
the ``int`` type in Python 2.x wraps C ``long`` values.
......@@ -2,11 +2,11 @@
'title': 'Cython Tutorial',
'paper_abstract': '''
Cython is a programming language based on Python with extra
syntax to provide static type declarations. This takes advantage of the
benefits of Python while allowing one to achieve the speed of C.
In this paper we describe the Cython language and show how it can
be used both to write optimized code and to interface with external
C libraries.
syntax to provide static type declarations. This takes advantage of the
benefits of Python while allowing one to achieve the speed of C.
In this paper we describe the Cython language and show how it can
be used both to write optimized code and to interface with external
C libraries.
''',
'authors': [
{'first_names': 'Stefan',
......
......@@ -6,7 +6,7 @@
Profiling
*********
This part describes the profiling abilities of Cython. If you are familiar
This part describes the profiling abilities of Cython. If you are familiar
with profiling pure Python code, you can only read the first section
(:ref:`profiling_basics`). If you are not familiar with Python profiling you
should also read the tutorial (:ref:`profiling_tutorial`) which takes you
......@@ -17,7 +17,7 @@ through a complete example step by step.
Cython Profiling Basics
=======================
Profiling in Cython is controlled by a compiler directive.
Profiling in Cython is controlled by a compiler directive.
It can be set either for an entire file or on a per function basis
via a Cython decorator.
......@@ -26,7 +26,7 @@ Enabling profiling for a complete source file
Profiling is enabled for a complete source file via a global directive to the
Cython compiler at the top of a file::
# cython: profile=True
Note that profiling gives a slight overhead to each function call therefore making
......@@ -35,7 +35,7 @@ often).
Once enabled, your Cython code will behave just like Python code when called
from the cProfile module. This means you can just profile your Cython code
together with your Python code using the same tools as for Python code alone.
together with your Python code using the same tools as for Python code alone.
Disabling profiling function wise
---------------------------------
......@@ -111,7 +111,7 @@ Profiling Tutorial
==================
This will be a complete tutorial, start to finish, of profiling Python code,
turning it into Cython code and keep profiling until it is fast enough.
turning it into Cython code and keep profiling until it is fast enough.
As a toy example, we would like to evaluate the summation of the reciprocals of
squares up to a certain integer :math:`n` for evaluating :math:`\pi`. The
......@@ -120,8 +120,8 @@ relation we want to use has been proven by Euler in 1735 and is known as the
.. math::
\pi^2 = 6 \sum_{k=1}^{\infty} \frac{1}{k^2} =
6 \lim_{k \to \infty} \big( \frac{1}{1^2} +
\pi^2 = 6 \sum_{k=1}^{\infty} \frac{1}{k^2} =
6 \lim_{k \to \infty} \big( \frac{1}{1^2} +
\frac{1}{2^2} + \dots + \frac{1}{k^2} \big) \approx
6 \big( \frac{1}{1^2} + \frac{1}{2^2} + \dots + \frac{1}{n^2} \big)
......@@ -139,7 +139,7 @@ A simple Python code for evaluating the truncated sum looks like this::
for k in range(1,n+1):
val += recip_square(k)
return (6 * val)**.5
On my box, this needs approximately 4 seconds to run the function with the
default n. The higher we choose n, the better will be the approximation for
:math:`\pi`. An experienced Python programmer will already see plenty of
......@@ -186,7 +186,7 @@ Python `profiling documentation <http://docs.python.org/library/profile.html>`_
for the nitty gritty details. The most important columns here are totime (total
time spent in this function **not** counting functions that were called by this
function) and cumtime (total time spent in this function **also** counting the
functions called by this function). Looking at the tottime column, we see that
functions called by this function). Looking at the tottime column, we see that
approximately half the time is spent in approx_pi and the other half is spent
in recip_square. Also half a second is spent in range ... of course we should
have used xrange for such a big iteration. And in fact, just changing range to
......@@ -213,7 +213,7 @@ anyway at some time to get the loop run faster. Here is our first Cython version
Note the second line: We have to tell Cython that profiling should be enabled.
This makes the Cython code slightly slower, but without this we would not get
meaningful output from the cProfile module. The rest of the code is mostly
unchanged, I only typed some variables which will likely speed things up a bit.
unchanged, I only typed some variables which will likely speed things up a bit.
We also need to modify our profiling script to import the Cython module directly.
Here is the complete version adding the import of the pyximport module::
......
......@@ -45,6 +45,6 @@ Python modules.
http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/
.. [ShedSkin] M. Dufour, J. Coughlan, ShedSkin,
http://code.google.com/p/shedskin/
.. [SWIG] David M. Beazley et al.,
SWIG: An Easy to Use Tool for Integrating Scripting Languages with C and C++,
.. [SWIG] David M. Beazley et al.,
SWIG: An Easy to Use Tool for Integrating Scripting Languages with C and C++,
http://www.swig.org.
......@@ -99,7 +99,7 @@ overheads. Consider this code:
rect = Rectangle(x0, y0, x1, y1)
return rect.area()
.. note::
.. note::
in earlier versions of Cython, the :keyword:`cpdef` keyword is
``rdef`` - but has the same effect).
......@@ -116,13 +116,13 @@ storing a Rectangle object, then invoking the area method will require:
* an attribute lookup for the area method
* packing a tuple for arguments and a dict for keywords (both empty in this case)
* using the Python API to call the method
* using the Python API to call the method
and within the area method itself:
* parsing the tuple and keywords
* executing the calculation code
* converting the result to a python object and returning it
* converting the result to a python object and returning it
So within Cython, it is possible to achieve massive optimisations by
using strong typing in declaration and casting of variables. For tight loops
......
......@@ -35,7 +35,7 @@ The main difference is that you can use the :keyword:`cdef` statement to define
attributes. The attributes may be Python objects (either generic or of a
particular extension type), or they may be of any C data type. So you can use
extension types to wrap arbitrary C data structures and provide a Python-like
interface to them.
interface to them.
.. _readonly:
......@@ -117,35 +117,35 @@ The same consideration applies to local variables, for example,::
Type Testing and Casting
------------------------
Suppose I have a method :meth:`quest` which returns an object of type :class:`Shrubbery`.
Suppose I have a method :meth:`quest` which returns an object of type :class:`Shrubbery`.
To access it's width I could write::
cdef Shrubbery sh = quest()
print sh.width
which requires the use of a local variable and performs a type test on assignment.
which requires the use of a local variable and performs a type test on assignment.
If you *know* the return value of :meth:`quest` will be of type :class:`Shrubbery`
you can use a cast to write::
print (<Shrubbery>quest()).width
This may be dangerous if :meth:`quest()` is not actually a :class:`Shrubbery`, as it
will try to access width as a C struct member which may not exist. At the C level,
rather than raising an :class:`AttributeError`, either an nonsensical result will be
This may be dangerous if :meth:`quest()` is not actually a :class:`Shrubbery`, as it
will try to access width as a C struct member which may not exist. At the C level,
rather than raising an :class:`AttributeError`, either an nonsensical result will be
returned (interpreting whatever data is at that address as an int) or a segfault
may result from trying to access invalid memory. Instead, one can write::
print (<Shrubbery?>quest()).width
which performs a type check (possibly raising a :class:`TypeError`) before making the
cast and allowing the code to proceed.
which performs a type check (possibly raising a :class:`TypeError`) before making the
cast and allowing the code to proceed.
To explicitly test the type of an object, use the :meth:`isinstance` method. By default,
in Python, the :meth:`isinstance` method checks the :class:`__class__` attribute of the
first argument to determine if it is of the required type. However, this is potentially
unsafe as the :class:`__class__` attribute can be spoofed or changed, but the C structure
of an extension type must be correct to access its :keyword:`cdef` attributes and call its :keyword:`cdef` methods. Cython detects if the second argument is a known extension
type and does a type check instead, analogous to Pyrex's :meth:`typecheck`.
To explicitly test the type of an object, use the :meth:`isinstance` method. By default,
in Python, the :meth:`isinstance` method checks the :class:`__class__` attribute of the
first argument to determine if it is of the required type. However, this is potentially
unsafe as the :class:`__class__` attribute can be spoofed or changed, but the C structure
of an extension type must be correct to access its :keyword:`cdef` attributes and call its :keyword:`cdef` methods. Cython detects if the second argument is a known extension
type and does a type check instead, analogous to Pyrex's :meth:`typecheck`.
The old behavior is always available by passing a tuple as the second parameter::
print isinstance(sh, Shrubbery) # Check the type of sh
......@@ -207,7 +207,7 @@ with checking that it has the right type.
be ``None``.
* When comparing a value with ``None``, keep in mind that, if ``x`` is a Python
object, ``x is None`` and ``x is not None`` are very efficient because they
translate directly to C pointer comparisons, whereas ``x == None`` and
translate directly to C pointer comparisons, whereas ``x == None`` and
``x != None``, or simply using ``x`` as a boolean value (as in ``if x: ...``)
will invoke Python operations and therefore be much slower.
......@@ -260,7 +260,7 @@ There is also a special (deprecated) legacy syntax for defining properties in an
def __del__(self):
# This is called when the property is deleted.
The :meth:`__get__`, :meth:`__set__` and :meth:`__del__` methods are all
optional; if they are omitted, an exception will be raised when the
......@@ -269,7 +269,7 @@ corresponding operation is attempted.
Here's a complete example. It defines a property which adds to a list each
time it is written to, returns the list when it is read, and empties the list
when it is deleted.::
# cheesy.pyx
cdef class CheeseShop:
......@@ -494,7 +494,7 @@ object called :attr:`__weakref__`. For example,::
cdef class ExplodingAnimal:
"""This animal will self-destruct when it is
no longer strongly referenced."""
cdef object __weakref__
......@@ -546,7 +546,7 @@ can participate in cycles could cause memory leaks ::
cdef str name
cdef tuple addresses
If you can be sure addresses will contain only references to strings,
If you can be sure addresses will contain only references to strings,
the above would be safe, and it may yield a significant speedup, depending on
your usage pattern.
......@@ -604,7 +604,7 @@ built-in complex object.::
2. As well as the name of the extension type, the module in which its type
object can be found is also specified. See the implicit importing section
below.
below.
3. When declaring an external extension type, you don't declare any
methods. Declaration of methods is not required in order to call them,
......@@ -662,7 +662,7 @@ You can also specify an alternative name under which to import the type using
an as clause, for example,::
cdef extern class My.Nested.Package.Spam as Yummy:
...
...
which corresponds to the implicit import statement::
......
......@@ -52,7 +52,7 @@ C header file, like this::
The ``cdef extern`` from clause does three things:
1. It directs Cython to place a ``#include`` statement for the named header file in
the generated C code.
the generated C code.
2. It prevents Cython from generating any C code
for the declarations found in the associated block.
3. It treats all declarations within the block as though they started with
......@@ -92,8 +92,8 @@ match the C ones, and in some cases they shouldn't or can't. In particular:
ctypedef int word
will work okay whatever the actual size of a :c:type:`word` is (provided the header
file defines it correctly). Conversion to and from Python types, if any, will also
be used for this new type.
file defines it correctly). Conversion to and from Python types, if any, will also
be used for this new type.
#. If the header file uses macros to define constants, translate them into a
normal external variable declaration. You can also declare them as an
......@@ -118,7 +118,7 @@ A few more tricks and tips:
pass
* If you want to include a system header, put angle brackets inside the quotes::
cdef extern from "<sysheader.h>":
...
......@@ -390,8 +390,8 @@ C code wanting to use these functions or extension types needs to include the
header and call the :func:`import_modulename` function. The other functions
can then be called and the extension types used as usual.
If the C code wanting to use these functions is part of more than one shared
library or executable, then :func:`import_modulename` function needs to be
If the C code wanting to use these functions is part of more than one shared
library or executable, then :func:`import_modulename` function needs to be
called in each of the shared libraries which use these functions. If you
crash with a segmentation fault (SIGSEGV on linux) when calling into one of
these api calls, this is likely an indication that the shared library which
......@@ -411,7 +411,7 @@ made available when you include :file:`modulename_api.h`.::
print "Time travel achieved"
.. sourcecode:: c
# marty.c
#include "delorean_api.h"
......@@ -420,7 +420,7 @@ made available when you include :file:`modulename_api.h`.::
int main(int argc, char *argv[]) {
import_delorean();
car.speed = atoi(argv[1]);
car.power = atof(argv[2]);
car.power = atof(argv[2]);
activate(&car);
}
......
......@@ -169,7 +169,7 @@ passed in directly using a normal C function call.
Functions declared using :keyword:`cdef`, like Python functions, will return a :keyword:`False`
value when execution leaves the function body without an explicit return value. This is in
contrast to C/C++, which leaves the return value undefined.
contrast to C/C++, which leaves the return value undefined.
A more complete comparison of the pros and cons of these different method
types can be found at :ref:`early-binding-for-speed`.
......
......@@ -398,10 +398,10 @@ If you pass a non-contiguous buffer, for example
you will get a ``ValueError`` at runtime::
/Users/mb312/dev_trees/minimal-cython/mincy.pyx in init mincy (mincy.c:17267)()
69
69
70 # But this isn't
---> 71 c_contiguous = np.array(c_contig, order='F')
72
72
73 # Show the sum of all the arrays before altering it
/Users/mb312/dev_trees/minimal-cython/stringsource in View.MemoryView.memoryview_cwrapper (mincy.c:9995)()
......
......@@ -20,13 +20,13 @@ information on this.
The style of this tutorial will not fit everybody, so you can also consider:
* Robert Bradshaw's `slides on cython for SciPy2008
<http://wiki.sagemath.org/scipy08?action=AttachFile&do=get&target=scipy-cython.tgz>`_
* Robert Bradshaw's `slides on cython for SciPy2008
<http://wiki.sagemath.org/scipy08?action=AttachFile&do=get&target=scipy-cython.tgz>`_
(a higher-level and quicker introduction)
* Basic Cython documentation (see `Cython front page <http://cython.org>`_).
* ``[:enhancements/buffer:Spec for the efficient indexing]``
.. Note::
.. Note::
The fast array access documented below is a completely new feature, and
there may be bugs waiting to be discovered. It might be a good idea to do
a manual sanity check on the C code Cython generates before using this for
......@@ -71,7 +71,7 @@ However there are several options to automate these steps:
excellent support for using Cython and NumPy from an interactive command
line (like IPython) or through a notebook interface (like
Maple/Mathematica). See `this documentation
<http://www.sagemath.org/doc/prog/node40.html>`_.
<http://www.sagemath.org/doc/prog/node40.html>`_.
2. A version of `pyximport <http://www.prescod.net/pyximport/>`_ is shipped
with Cython, so that you can import pyx-files dynamically into Python and
have them compiled automatically (See :ref:`pyximport`).
......@@ -79,7 +79,7 @@ However there are several options to automate these steps:
which automate the process, this is the preferred method for full programs.
4. Manual compilation (see below)
.. Note::
.. Note::
If using another interactive command line environment than SAGE, like
IPython or Python itself, it is important that you restart the process
when you recompile the module. It is not enough to issue an "import"
......@@ -200,7 +200,7 @@ run a Python session to test both the Python version (imported from
[2, 2, 2],
[1, 1, 1]])
In [4]: import convolve1
In [4]: convolve1.naive_convolve(np.array([[1, 1, 1]], dtype=np.int),
In [4]: convolve1.naive_convolve(np.array([[1, 1, 1]], dtype=np.int),
... np.array([[1],[2],[1]], dtype=np.int))
Out [4]:
array([[1, 1, 1],
......@@ -347,7 +347,7 @@ Showing the changes needed to produce :file:`convolve3.pyx` only::
def naive_convolve(np.ndarray[DTYPE_t, ndim=2] f, np.ndarray[DTYPE_t, ndim=2] g):
...
cdef np.ndarray[DTYPE_t, ndim=2] h = ...
Usage:
.. sourcecode:: ipython
......@@ -381,7 +381,7 @@ The array lookups are still slowed down by two factors:
@cython.boundscheck(False) # turn off bounds-checking for entire function
def naive_convolve(np.ndarray[DTYPE_t, ndim=2] f, np.ndarray[DTYPE_t, ndim=2] g):
...
Now bounds checking is not performed (and, as a side-effect, if you ''do''
happen to access out of bounds you will in the best case crash your program
and in the worst case corrupt data). It is possible to switch bounds-checking
......@@ -477,14 +477,14 @@ or may not happen depending on available developer time and resources for
Cython.
1. Support for efficient access to structs/records stored in arrays; currently
only primitive types are allowed.
only primitive types are allowed.
2. Support for efficient access to complex floating point types in arrays. The
main obstacle here is getting support for efficient complex datatypes in
Cython.
3. Calling NumPy/SciPy functions currently has a Python call overhead; it
would be possible to take a short-cut from Cython directly to C. (This does
however require some isolated and incremental changes to those libraries;
mail the Cython mailing list for details).
mail the Cython mailing list for details).
4. Efficient code that is generic with respect to the number of dimensions.
This can probably be done today by calling the NumPy C multi-dimensional
iterator API directly; however it would be nice to have for-loops over
......
......@@ -6,14 +6,14 @@
Differences between Cython and Pyrex
**************************************
.. warning::
Both Cython and Pyrex are moving targets. It has come to the point
that an explicit list of all the differences between the two
projects would be laborious to list and track, but hopefully
this high-level list gives an idea of the differences that
.. warning::
Both Cython and Pyrex are moving targets. It has come to the point
that an explicit list of all the differences between the two
projects would be laborious to list and track, but hopefully
this high-level list gives an idea of the differences that
are present. It should be noted that both projects make an effort
at mutual compatibility, but Cython's goal is to be as close to
and complete as Python as reasonable.
at mutual compatibility, but Cython's goal is to be as close to
and complete as Python as reasonable.
Python 3 Support
......@@ -75,7 +75,7 @@ Conditional expressions as described in
http://www.python.org/dev/peps/pep-0308/::
X if C else Y
Only one of ``X`` and ``Y`` is evaluated (depending on the value of C).
......@@ -89,10 +89,10 @@ keyword passed on to the C compiler. These can be as fast as macros.::
cdef inline int something_fast(int a, int b):
return a*a + b
Note that class-level :keyword:`cdef` functions are handled via a virtual
function table, so the compiler won't be able to inline them in almost all
cases.
cases.
Assignment on declaration (e.g. "cdef int spam = 5")
======================================================
......@@ -103,24 +103,24 @@ In Pyrex, one must write::
i = 2
j = 5
k = 7
Now, with cython, one can write::
cdef int i = 2, j = 5, k = 7
The expression on the right hand side can be arbitrarily complicated, e.g.::
cdef int n = python_call(foo(x,y), a + b + c) - 32
'by' expression in for loop (e.g. "for i from 0 <= i < 10 by 2")
==================================================================
::
for i from 0 <= i < 10 by 2:
print i
yields::
......@@ -207,7 +207,7 @@ method on the class directly, e.g.::
x.foo() # will check to see if overridden
A.foo(x) # will call A's implementation whether overridden or not
See :ref:`early-binding-for-speed` for explanation and usage tips.
See :ref:`early-binding-for-speed` for explanation and usage tips.
.. _automatic-range-conversion:
......@@ -216,9 +216,9 @@ Automatic range conversion
This will convert statements of the form ``for i in range(...)`` to ``for i
from ...`` when ``i`` is any cdef'd integer type, and the direction (i.e. sign
of step) can be determined.
of step) can be determined.
.. warning::
.. warning::
This may change the semantics if the range causes
assignment to ``i`` to overflow. Specifically, if this option is set, an error
......@@ -256,7 +256,7 @@ functions in the ``.pxd`` file by writing ``cdef foo(x=*)``. The number of
arguments may increase on subclassing, but the argument types and order must
remain the same. There is a slight performance penalty in some cases when a
cdef/cpdef function without any optional is overridden with one that does have
default argument values.
default argument values.
For example, one can have the ``.pxd`` file::
......@@ -279,7 +279,7 @@ with corresponding ``.pyx`` file::
cpdef foo(self, x=True, int k=3)
print "C", x, k
.. note::
.. note::
this also demonstrates how :keyword:`cpdef` functions can override
:keyword:`cdef` functions.
......@@ -330,13 +330,13 @@ From __future__ directives
Cython supports several ``from __future__ import ...`` directives, namely
``absolute_import``, ``unicode_literals``, ``print_function`` and ``division``.
With statements are always enabled.
With statements are always enabled.
Pure Python mode
================
Cython has support for compiling ``.py`` files, and
Cython has support for compiling ``.py`` files, and
accepting type annotations using decorators and other
valid Python syntax. This allows the same source to
be interpreted as straight Python, or compiled for
valid Python syntax. This allows the same source to
be interpreted as straight Python, or compiled for
optimized results. See :ref:`pure-mode` for more details.
......@@ -24,9 +24,9 @@ statement.
A ``.pxd`` file that consists solely of extern declarations does not need
to correspond to an actual ``.pyx`` file or Python module. This can make it a
convenient place to put common declarations, for example declarations of
convenient place to put common declarations, for example declarations of
functions from an :ref:`external library <external-C-code>` that one
wants to use in several modules.
wants to use in several modules.
What a Definition File contains
......@@ -40,9 +40,9 @@ A definition file can contain:
* The definition part of an extension type (see below).
It cannot contain the implementations of any C or Python functions, or any
Python class definitions, or any executable statements. It is needed when one
wants to access :keyword:`cdef` attributes and methods, or to inherit from
:keyword:`cdef` classes defined in this module.
Python class definitions, or any executable statements. It is needed when one
wants to access :keyword:`cdef` attributes and methods, or to inherit from
:keyword:`cdef` classes defined in this module.
.. note::
......@@ -57,9 +57,9 @@ What an Implementation File contains
An implementation file can contain any kind of Cython statement, although there
are some restrictions on the implementation part of an extension type if the
corresponding definition file also defines that type (see below).
corresponding definition file also defines that type (see below).
If one doesn't need to :keyword:`cimport` anything from this module, then this
is the only file one needs.
is the only file one needs.
.. _cimport:
......@@ -79,16 +79,16 @@ statement::
Here is an example. :file:`dishes.pxd` is a definition file which exports a
C data type. :file:`restaurant.pyx` is an implementation file which imports and
uses it.
:file:`dishes.pxd`::
cdef enum otherstuff:
sausage, eggs, lettuce
cdef struct spamdish:
int oz_of_spam
otherstuff filler
cdef enum otherstuff:
sausage, eggs, lettuce
cdef struct spamdish:
int oz_of_spam
otherstuff filler
:file:`restaurant.pyx`::
cimport dishes
......@@ -102,7 +102,7 @@ uses it.
cdef spamdish d
prepare(&d)
print "%d oz spam, filler no. %d" % (d.oz_of_spam, d.filler)
It is important to understand that the :keyword:`cimport` statement can only
be used to import C data types, C functions and variables, and extension
types. It cannot be used to import any Python objects, and (with one
......@@ -113,9 +113,9 @@ to include a regular import statement for it as well.
The exception is that when you use :keyword:`cimport` to import an extension type, its
type object is imported at run time and made available by the name under which
you imported it. Using :keyword:`cimport` to import extension types is covered in more
detail below.
detail below.
If a ``.pxd`` file changes, any modules that :keyword:`cimport` from it may need to be
If a ``.pxd`` file changes, any modules that :keyword:`cimport` from it may need to be
recompiled. The ``Cython.Build.cythonize`` utility can take care of this for you.
......@@ -137,7 +137,7 @@ include path (but not ``sys.path``), and if found, it is processed before
processing the ``.pyx`` file.
Using cimport to resolve naming conflicts
Using cimport to resolve naming conflicts
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The :keyword:`cimport` mechanism provides a clean and simple way to solve the
......@@ -146,11 +146,11 @@ name. All you need to do is put the extern C declarations into a ``.pxd`` file
for an imaginary module, and :keyword:`cimport` that module. You can then
refer to the C functions by qualifying them with the name of the module.
Here's an example:
:file:`c_lunch.pxd`::
cdef extern from "lunch.h":
void eject_tomato(float)
void eject_tomato(float)
:file:`lunch.pyx`::
......@@ -163,7 +163,7 @@ You don't need any :file:`c_lunch.pyx` file, because the only things defined
in :file:`c_lunch.pxd` are extern C entities. There won't be any actual
``c_lunch`` module at run time, but that doesn't matter; the
:file:`c_lunch.pxd` file has done its job of providing an additional namespace
at compile time.
at compile time.
Sharing C Functions
......@@ -199,7 +199,7 @@ example:
When a module exports a C function in this way, an object appears in the
module dictionary under the function's name. However, you can't make use of
this object from Python, nor can you use it from Cython using a normal import
statement; you have to use :keyword:`cimport`.
statement; you have to use :keyword:`cimport`.
Sharing Extension Types
......
......@@ -44,7 +44,7 @@ would be::
setup(
ext_modules = cythonize("example.pyx")
)
)
To understand the :file:`setup.py` more fully look at the official
:mod:`distutils` documentation. To compile the extension for use in the
......
......@@ -11,22 +11,22 @@ mention.
.. Note: Everything said on this page applies only to extension types, defined
with the :keyword:`cdef class` statement. It doesn't apply to classes defined with the
Python :keyword:`class` statement, where the normal Python rules apply.
Python :keyword:`class` statement, where the normal Python rules apply.
Declaration
------------
Special methods of extension types must be declared with :keyword:`def`, not
:keyword:`cdef`. This does not impact their performance--Python uses different
calling conventions to invoke these special methods.
calling conventions to invoke these special methods.
Docstrings
-----------
Currently, docstrings are not fully supported in some special methods of extension
types. You can place a docstring in the source to serve as a comment, but it
won't show up in the corresponding :attr:`__doc__` attribute at run time. (This
seems to be is a Python limitation -- there's nowhere in the `PyTypeObject`
data structure to put such docstrings.)
won't show up in the corresponding :attr:`__doc__` attribute at run time. (This
seems to be is a Python limitation -- there's nowhere in the `PyTypeObject`
data structure to put such docstrings.)
Initialisation methods: :meth:`__cinit__` and :meth:`__init__`
---------------------------------------------------------------
......@@ -36,7 +36,7 @@ The :meth:`__cinit__` method is where you should perform basic C-level
initialisation of the object, including allocation of any C data structures
that your object will own. You need to be careful what you do in the
:meth:`__cinit__` method, because the object may not yet be fully valid Python
object when it is called. Therefore, you should be careful invoking any Python
object when it is called. Therefore, you should be careful invoking any Python
operations which might touch the object; in particular, its methods.
By the time your :meth:`__cinit__` method is called, memory has been allocated for the
......@@ -67,15 +67,15 @@ ignore extra arguments. Otherwise, any Python subclass which has an
:meth:`__init__` with a different signature will have to override
:meth:`__new__` [#]_ as well as :meth:`__init__`, which the writer of a Python
class wouldn't expect to have to do. Alternatively, as a convenience, if you declare
your :meth:`__cinit__`` method to take no arguments (other than self) it
your :meth:`__cinit__`` method to take no arguments (other than self) it
will simply ignore any extra arguments passed to the constructor without
complaining about the signature mismatch.
complaining about the signature mismatch.
.. Note: Older Cython files may use :meth:`__new__` rather than :meth:`__cinit__`. The two are synonyms.
The name change from :meth:`__new__` to :meth:`__cinit__` was to avoid
confusion with Python :meth:`__new__` (which is an entirely different
concept) and eventually the use of :meth:`__new__` in Cython will be
disallowed to pave the way for supporting Python-style :meth:`__new__`
.. Note: Older Cython files may use :meth:`__new__` rather than :meth:`__cinit__`. The two are synonyms.
The name change from :meth:`__new__` to :meth:`__cinit__` was to avoid
confusion with Python :meth:`__new__` (which is an entirely different
concept) and eventually the use of :meth:`__new__` in Cython will be
disallowed to pave the way for supporting Python-style :meth:`__new__`
.. [#] http://docs.python.org/reference/datamodel.html#object.__new__
......@@ -84,8 +84,8 @@ Finalization method: :meth:`__dealloc__`
The counterpart to the :meth:`__cinit__` method is the :meth:`__dealloc__`
method, which should perform the inverse of the :meth:`__cinit__` method. Any
C data that you explicitly allocated (e.g. via malloc) in your
:meth:`__cinit__` method should be freed in your :meth:`__dealloc__` method.
C data that you explicitly allocated (e.g. via malloc) in your
:meth:`__cinit__` method should be freed in your :meth:`__dealloc__` method.
You need to be careful what you do in a :meth:`__dealloc__` method. By the time your
:meth:`__dealloc__` method is called, the object may already have been partially
......@@ -97,7 +97,7 @@ deallocating C data.
You don't need to worry about deallocating Python attributes of your object,
because that will be done for you by Cython after your :meth:`__dealloc__` method
returns.
returns.
When subclassing extension types, be aware that the :meth:`__dealloc__` method
of the superclass will always be called, even if it is overridden. This is in
......@@ -116,8 +116,8 @@ operation, the same method of the second operand is called, with the operands
in the same order.
This means that you can't rely on the first parameter of these methods being
"self" or being the right type, and you should test the types of both operands
before deciding what to do. If you can't handle the combination of types you've
"self" or being the right type, and you should test the types of both operands
before deciding what to do. If you can't handle the combination of types you've
been given, you should return `NotImplemented`.
This also applies to the in-place arithmetic method :meth:`__ipow__`. It doesn't apply
......@@ -131,17 +131,17 @@ There are no separate methods for the individual rich comparison operations
(:meth:`__eq__`, :meth:`__le__`, etc.) Instead there is a single method
:meth:`__richcmp__` which takes an integer indicating which operation is to be
performed, as follows:
+-----+-----+
| < | 0 |
| < | 0 |
+-----+-----+
| == | 2 |
+-----+-----+
| > | 4 |
+-----+-----+
| <= | 1 |
| <= | 1 |
+-----+-----+
| != | 3 |
| != | 3 |
+-----+-----+
| >= | 5 |
+-----+-----+
......@@ -164,7 +164,7 @@ with no type specified in the table are generic Python objects.
You don't have to declare your method as taking these parameter types. If you
declare different types, conversions will be performed as necessary.
General
^^^^^^^
......@@ -335,7 +335,7 @@ Buffer interface [:PEP:`3118`] (no Python equivalents - see note 1)
+-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
| Name | Parameters | Return type | Description |
+=======================+=======================================+=============+=====================================================+
| __getbuffer__ | self, Py_buffer `*view`, int flags | | |
| __getbuffer__ | self, Py_buffer `*view`, int flags | | |
+-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
| __releasebuffer__ | self, Py_buffer `*view` | | |
+-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
......@@ -346,7 +346,7 @@ Buffer interface [legacy] (no Python equivalents - see note 1)
+-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
| Name | Parameters | Return type | Description |
+=======================+=======================================+=============+=====================================================+
| __getreadbuffer__ | self, Py_ssize_t i, void `**p` | | |
| __getreadbuffer__ | self, Py_ssize_t i, void `**p` | | |
+-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
| __getwritebuffer__ | self, Py_ssize_t i, void `**p` | | |
+-----------------------+---------------------------------------+-------------+-----------------------------------------------------+
......
== Pyximport ==
== Pyximport ==
Download: pyx-import-1.0.tar.gz
<http://www.prescod.net/pyximport/pyximport-1.0.tar.gz>
......@@ -31,7 +31,7 @@ python -c "import foo"
See help(pyximport.install) to learn its options for controlling the
default behavior of "import" and "reload".
== Dependency Handling ==
== Dependency Handling ==
In Pyximport 1.1 it is possible to declare that your module depends on
multiple files, (likely ".h" and ".pxd" files). If your Pyrex module is
......@@ -46,7 +46,7 @@ modification time of your ".pyx" source file. Future versions may do
something more sophisticated like informing distutils of the
dependencies directly.
== Limitations ==
== Limitations ==
Pyximport does not give you any control over how your Pyrex file is
compiled. Usually the defaults are fine. You might run into problems if
......@@ -59,7 +59,7 @@ something went wrong and why. And if nothing went wrong it will give you
the warm fuzzy that pyximport really did rebuild your module as it was
supposed to.
== For further thought and discussion ==
== For further thought and discussion ==
"setup.py install" does not modify sitecustomize.py for you. Should it?
Modifying Python's "standard interpreter" behaviour may be more than
......
"""
Import hooks; when installed with the install() function, these hooks
Import hooks; when installed with the install() function, these hooks
allow importing .pyx files as if they were Python modules.
If you want the hook installed every time you run Python
you can add it to your Python version by adding these lines to
sitecustomize.py (which you can create from scratch in site-packages
sitecustomize.py (which you can create from scratch in site-packages
if it doesn't exist there or somewhere else on your python path)::
import pyximport
......@@ -79,8 +79,8 @@ def _info(message, *args):
# Performance problem: for every PYX file that is imported, we will
# invoke the whole distutils infrastructure even if the module is
# already built. It might be more efficient to only do it when the
# invoke the whole distutils infrastructure even if the module is
# already built. It might be more efficient to only do it when the
# mod time of the .pyx is newer than the mod time of the .so but
# the question is how to get distutils to tell me the name of the .so
# before it builds it. Maybe it is easy...but maybe the peformance
......@@ -94,7 +94,7 @@ def get_distutils_extension(modname, pyxfilename, language_level=None):
# import hashlib
# except ImportError:
# import md5 as hashlib
# extra = "_" + hashlib.md5(open(pyxfilename).read()).hexdigest()
# extra = "_" + hashlib.md5(open(pyxfilename).read()).hexdigest()
# modname = modname + extra
extension_mod,setup_args = handle_special_build(modname, pyxfilename)
if not extension_mod:
......@@ -113,7 +113,7 @@ def handle_special_build(modname, pyxfilename):
special_build = os.path.splitext(pyxfilename)[0] + PYXBLD_EXT
ext = None
setup_args={}
if os.path.exists(special_build):
if os.path.exists(special_build):
# globls = {}
# locs = {}
# execfile(special_build, globls, locs)
......@@ -126,11 +126,11 @@ def handle_special_build(modname, pyxfilename):
make_setup_args = getattr(mod, 'make_setup_args',None)
if make_setup_args:
setup_args = make_setup_args()
assert isinstance(setup_args,dict), ("make_setup_args in %s did not return a dict"
assert isinstance(setup_args,dict), ("make_setup_args in %s did not return a dict"
% special_build)
assert set or setup_args, ("neither make_ext nor make_setup_args %s"
assert set or setup_args, ("neither make_ext nor make_setup_args %s"
% special_build)
ext.sources = [os.path.join(os.path.dirname(special_build), source)
ext.sources = [os.path.join(os.path.dirname(special_build), source)
for source in ext.sources]
return ext, setup_args
......@@ -142,7 +142,7 @@ def handle_dependencies(pyxfilename):
# by default let distutils decide whether to rebuild on its own
# (it has a better idea of what the output file will be)
# but we know more about dependencies so force a rebuild if
# but we know more about dependencies so force a rebuild if
# some of the dependencies are newer than the pyxfile.
if os.path.exists(dependfile):
depends = open(dependfile).readlines()
......@@ -153,7 +153,7 @@ def handle_dependencies(pyxfilename):
files = [dependfile]
for depend in depends:
fullpath = os.path.join(os.path.dirname(dependfile),
depend)
depend)
files.extend(glob.glob(fullpath))
# only for unit testing to see we did the right thing
......@@ -191,7 +191,7 @@ def build_module(name, pyxfilename, pyxbuild_dir=None, inplace=False, language_l
inplace=inplace,
reload_support=pyxargs.reload_support)
assert os.path.exists(so_path), "Cannot find: %s" % so_path
junkpath = os.path.join(os.path.dirname(so_path), name+"_*") #very dangerous with --inplace ? yes, indeed, trying to eat my files ;)
junkstuff = glob.glob(junkpath)
for path in junkstuff:
......@@ -249,7 +249,7 @@ class PyxImporter(object):
def find_module(self, fullname, package_path=None):
if fullname in sys.modules and not pyxargs.reload_support:
return None # only here when reload()
return None # only here when reload()
try:
fp, pathname, (ext,mode,ty) = imp.find_module(fullname,package_path)
if fp: fp.close() # Python should offer a Default-Loader to avoid this double find/open!
......@@ -520,7 +520,7 @@ def install(pyximport=True, pyimport=False, build_dir=None, build_in_temp=True,
setup_args = {}
if not build_dir:
build_dir = os.path.join(os.path.expanduser('~'), '.pyxbld')
global pyxargs
pyxargs = PyxArgs() #$pycheck_no
pyxargs.build_dir = build_dir
......
......@@ -46,7 +46,7 @@ def test():
build_file.write("""
from distutils.extension import Extension
def make_ext(name, filename):
return Extension(name=name, sources=[filename])
return Extension(name=name, sources=[filename])
""")
build_file.close()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment