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
This diff is collapsed.
This diff is collapsed.
/* 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>
......
This diff is collapsed.
......@@ -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
......
This diff is collapsed.
......@@ -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)
......
This diff is collapsed.
......@@ -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