Commit e7b5c5da authored by scoder's avatar scoder Committed by GitHub

Merge pull request #2286 from gabrieldemarmiesse/compat_py2_py3

Made code examples in the docs compatible with python 2 and 3.
parents 532bf275 82e01e1c
...@@ -25,7 +25,7 @@ Safe usage with memory views ...@@ -25,7 +25,7 @@ Safe usage with memory views
cdef array.array a = array.array('i', [1, 2, 3]) cdef array.array a = array.array('i', [1, 2, 3])
cdef int[:] ca = a cdef int[:] ca = a
print ca[0] print(ca[0])
NB: the import brings the regular Python array object into the namespace NB: the import brings the regular Python array object into the namespace
while the cimport adds functions accessible from Cython. while the cimport adds functions accessible from Cython.
...@@ -51,8 +51,8 @@ functions without overhead, so long as it is typed:: ...@@ -51,8 +51,8 @@ functions without overhead, so long as it is typed::
cdef int no_overhead(int[:] ca): cdef int no_overhead(int[:] ca):
return ca[0] return ca[0]
print overhead(a) # new memory view will be constructed, overhead print(overhead(a)) # new memory view will be constructed, overhead
print no_overhead(ca) # ca is already a memory view, so no overhead print(no_overhead(ca)) # ca is already a memory view, so no overhead
Zero-overhead, unsafe access to raw C pointer Zero-overhead, unsafe access to raw C pointer
--------------------------------------------- ---------------------------------------------
...@@ -69,7 +69,7 @@ right type and signedness. ...@@ -69,7 +69,7 @@ right type and signedness.
cdef array.array a = array.array('i', [1, 2, 3]) cdef array.array a = array.array('i', [1, 2, 3])
# access underlying pointer: # access underlying pointer:
print a.data.as_ints[0] print(a.data.as_ints[0])
from libc.string cimport memset from libc.string cimport memset
memset(a.data.as_voidptr, 0, len(a) * sizeof(int)) memset(a.data.as_voidptr, 0, len(a) * sizeof(int))
......
...@@ -57,7 +57,7 @@ file to be of the declared type. Thus if one has a file :file:`A.py`:: ...@@ -57,7 +57,7 @@ file to be of the declared type. Thus if one has a file :file:`A.py`::
self.b = b self.b = b
def foo(self, x): def foo(self, x):
print x + _helper(1.0) print(x + _helper(1.0))
and adds :file:`A.pxd`:: and adds :file:`A.pxd`::
...@@ -84,7 +84,7 @@ then Cython will compile the :file:`A.py` as if it had been written as follows:: ...@@ -84,7 +84,7 @@ then Cython will compile the :file:`A.py` as if it had been written as follows::
self.b = b self.b = b
cpdef foo(self, double x): cpdef foo(self, double x):
print x + _helper(1.0) print(x + _helper(1.0))
Notice how in order to provide the Python wrappers to the definitions Notice how in order to provide the Python wrappers to the definitions
in the :file:`.pxd`, that is, to be accessible from Python, in the :file:`.pxd`, that is, to be accessible from Python,
...@@ -312,8 +312,8 @@ Further Cython functions and declarations ...@@ -312,8 +312,8 @@ Further Cython functions and declarations
:: ::
cython.declare(n=cython.longlong) cython.declare(n=cython.longlong)
print cython.sizeof(cython.longlong) print(cython.sizeof(cython.longlong))
print cython.sizeof(n) print(cython.sizeof(n))
* ``struct`` can be used to create struct types.:: * ``struct`` can be used to create struct types.::
......
...@@ -14,6 +14,8 @@ statement, Cython also lets you create new built-in Python types, known as ...@@ -14,6 +14,8 @@ statement, Cython also lets you create new built-in Python types, known as
extension types. You define an extension type using the :keyword:`cdef` class extension types. You define an extension type using the :keyword:`cdef` class
statement. Here's an example:: statement. Here's an example::
from __future__ import print_function
cdef class Shrubbery: cdef class Shrubbery:
cdef int width, height cdef int width, height
...@@ -23,8 +25,8 @@ statement. Here's an example:: ...@@ -23,8 +25,8 @@ statement. Here's an example::
self.height = h self.height = h
def describe(self): def describe(self):
print "This shrubbery is", self.width, \ print("This shrubbery is", self.width,
"by", self.height, "cubits." "by", self.height, "cubits.")
As you can see, a Cython extension type definition looks a lot like a Python As you can see, a Cython extension type definition looks a lot like a Python
class definition. Within it, you use the def statement to define methods that class definition. Within it, you use the def statement to define methods that
...@@ -164,13 +166,13 @@ Suppose I have a method :meth:`quest` which returns an object of type :class:`Sh ...@@ -164,13 +166,13 @@ Suppose I have a method :meth:`quest` which returns an object of type :class:`Sh
To access it's width I could write:: To access it's width I could write::
cdef Shrubbery sh = quest() cdef Shrubbery sh = quest()
print sh.width 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` If you *know* the return value of :meth:`quest` will be of type :class:`Shrubbery`
you can use a cast to write:: you can use a cast to write::
print (<Shrubbery>quest()).width print( (<Shrubbery>quest()).width )
This may be dangerous if :meth:`quest()` is not actually a :class:`Shrubbery`, as it 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, will try to access width as a C struct member which may not exist. At the C level,
...@@ -178,21 +180,17 @@ rather than raising an :class:`AttributeError`, either an nonsensical result wil ...@@ -178,21 +180,17 @@ rather than raising an :class:`AttributeError`, either an nonsensical result wil
returned (interpreting whatever data is at that address as an int) or a segfault 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:: may result from trying to access invalid memory. Instead, one can write::
print (<Shrubbery?>quest()).width print( (<Shrubbery?>quest()).width )
which performs a type check (possibly raising a :class:`TypeError`) before making the which performs a type check (possibly raising a :class:`TypeError`) before making the
cast and allowing the code to proceed. cast and allowing the code to proceed.
To explicitly test the type of an object, use the :meth:`isinstance` method. By default, To explicitly test the type of an object, use the :meth:`isinstance` method.
in Python, the :meth:`isinstance` method checks the :class:`__class__` attribute of the For known builtin or extension types, Cython translates these into a
first argument to determine if it is of the required type. However, this is potentially fast and safe type check that ignores changes to
unsafe as the :class:`__class__` attribute can be spoofed or changed, but the C structure the object's ``__class__`` attribute etc., so that after a successful
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 :meth:`isinstance` test, code can rely on the expected C structure of the
type and does a type check instead, analogous to Pyrex's :meth:`typecheck`. extension type and its :keyword:`cdef` attributes and methods.
The old behavior is always available by passing a tuple as the second parameter::
print isinstance(sh, Shrubbery) # Check the type of sh
print isinstance(sh, (Shrubbery,)) # Check sh.__class__
.. _extension_types_and_none: .. _extension_types_and_none:
...@@ -340,16 +338,16 @@ when it is deleted.:: ...@@ -340,16 +338,16 @@ when it is deleted.::
from cheesy import CheeseShop from cheesy import CheeseShop
shop = CheeseShop() shop = CheeseShop()
print shop.cheese print(shop.cheese)
shop.cheese = "camembert" shop.cheese = "camembert"
print shop.cheese print(shop.cheese)
shop.cheese = "cheddar" shop.cheese = "cheddar"
print shop.cheese print(shop.cheese)
del shop.cheese del shop.cheese
print shop.cheese print(shop.cheese)
.. sourcecode:: text .. sourcecode:: text
...@@ -419,21 +417,21 @@ compared to a :keyword:`cdef` method:: ...@@ -419,21 +417,21 @@ compared to a :keyword:`cdef` method::
cdef class Parrot: cdef class Parrot:
cdef void describe(self): cdef void describe(self):
print "This parrot is resting." print("This parrot is resting.")
cdef class Norwegian(Parrot): cdef class Norwegian(Parrot):
cdef void describe(self): cdef void describe(self):
Parrot.describe(self) Parrot.describe(self)
print "Lovely plumage!" print("Lovely plumage!")
cdef Parrot p1, p2 cdef Parrot p1, p2
p1 = Parrot() p1 = Parrot()
p2 = Norwegian() p2 = Norwegian()
print "p1:" print("p1:")
p1.describe() p1.describe()
print "p2:" print("p2:")
p2.describe() p2.describe()
.. sourcecode:: text .. sourcecode:: text
...@@ -643,6 +641,8 @@ objects defined in the Python core or in a non-Cython extension module. ...@@ -643,6 +641,8 @@ objects defined in the Python core or in a non-Cython extension module.
Here is an example which will let you get at the C-level members of the Here is an example which will let you get at the C-level members of the
built-in complex object.:: built-in complex object.::
from __future__ import print_function
cdef extern from "complexobject.h": cdef extern from "complexobject.h":
struct Py_complex: struct Py_complex:
...@@ -654,8 +654,8 @@ built-in complex object.:: ...@@ -654,8 +654,8 @@ built-in complex object.::
# A function which uses the above type # A function which uses the above type
def spam(complex c): def spam(complex c):
print "Real:", c.cval.real print("Real:", c.cval.real)
print "Imag:", c.cval.imag print("Imag:", c.cval.imag)
.. note:: .. note::
......
...@@ -475,7 +475,7 @@ made available when you include :file:`modulename_api.h`.:: ...@@ -475,7 +475,7 @@ made available when you include :file:`modulename_api.h`.::
cdef api void activate(Vehicle *v): cdef api void activate(Vehicle *v):
if v.speed >= 88 and v.power >= 1.21: if v.speed >= 88 and v.power >= 1.21:
print "Time travel achieved" print("Time travel achieved")
.. sourcecode:: c .. sourcecode:: c
......
...@@ -26,6 +26,7 @@ Quickstart ...@@ -26,6 +26,7 @@ Quickstart
:: ::
from __future__ import print_function
cimport cython cimport cython
ctypedef fused char_or_float: ctypedef fused char_or_float:
...@@ -41,8 +42,8 @@ Quickstart ...@@ -41,8 +42,8 @@ Quickstart
cdef: cdef:
cython.char a = 127 cython.char a = 127
cython.float b = 127 cython.float b = 127
print 'char', plus_one(a) print('char', plus_one(a))
print 'float', plus_one(b) print('float', plus_one(b))
This gives:: This gives::
...@@ -267,7 +268,7 @@ to figure out whether a specialization is part of another set of types ...@@ -267,7 +268,7 @@ to figure out whether a specialization is part of another set of types
long_pointer = &i long_pointer = &i
if bunch_of_types in string_t: if bunch_of_types in string_t:
print "s is a string!" print("s is a string!")
__signatures__ __signatures__
============== ==============
......
...@@ -124,6 +124,8 @@ internally to store attributes. ...@@ -124,6 +124,8 @@ internally to store attributes.
Here is a simple example:: Here is a simple example::
from __future__ import print_function
cdef class Shrubbery: cdef class Shrubbery:
cdef int width, height cdef int width, height
...@@ -133,8 +135,8 @@ Here is a simple example:: ...@@ -133,8 +135,8 @@ Here is a simple example::
self.height = h self.height = h
def describe(self): def describe(self):
print "This shrubbery is", self.width, \ print("This shrubbery is", self.width,
"by", self.height, "cubits." "by", self.height, "cubits.")
You can read more about them in :ref:`extension-types`. You can read more about them in :ref:`extension-types`.
...@@ -194,6 +196,8 @@ Grouping multiple C declarations ...@@ -194,6 +196,8 @@ Grouping multiple C declarations
If you have a series of declarations that all begin with :keyword:`cdef`, you If you have a series of declarations that all begin with :keyword:`cdef`, you
can group them into a :keyword:`cdef` block like this:: can group them into a :keyword:`cdef` block like this::
from __future__ import print_function
cdef: cdef:
struct Spam: struct Spam:
int tons int tons
...@@ -203,7 +207,7 @@ can group them into a :keyword:`cdef` block like this:: ...@@ -203,7 +207,7 @@ can group them into a :keyword:`cdef` block like this::
Spam *p Spam *p
void f(Spam *s): void f(Spam *s):
print s.tons, "Tons of spam" print(s.tons, "Tons of spam")
.. _cpdef: .. _cpdef:
.. _cdef: .. _cdef:
...@@ -645,7 +649,6 @@ with ``<object>``, or a more specific builtin or extension type ...@@ -645,7 +649,6 @@ with ``<object>``, or a more specific builtin or extension type
the object by one, i.e. the cast returns an owned reference. the object by one, i.e. the cast returns an owned reference.
Here is an example:: Here is an example::
from __future__ import print_function
from cpython.ref cimport PyObject from cpython.ref cimport PyObject
from libc.stdint cimport uintptr_t from libc.stdint cimport uintptr_t
...@@ -985,9 +988,11 @@ expression must evaluate to a Python value of type ``int``, ``long``, ...@@ -985,9 +988,11 @@ expression must evaluate to a Python value of type ``int``, ``long``,
:: ::
from __future__ import print_function
cdef int a1[ArraySize] cdef int a1[ArraySize]
cdef int a2[OtherArraySize] cdef int a2[OtherArraySize]
print "I like", FavouriteFood print("I like", FavouriteFood)
Conditional Statements Conditional Statements
---------------------- ----------------------
......
...@@ -60,4 +60,4 @@ Identity vs. equality for inferred literals ...@@ -60,4 +60,4 @@ Identity vs. equality for inferred literals
if some_runtime_expression: if some_runtime_expression:
b = a # creates a new Python float object b = a # creates a new Python float object
c = a # creates a new Python float object c = a # creates a new Python float object
print b is c # most likely not the same object print(b is c) # most likely not the same object
...@@ -101,7 +101,7 @@ uses it. ...@@ -101,7 +101,7 @@ uses it.
def serve(): def serve():
cdef spamdish d cdef spamdish d
prepare(&d) prepare(&d)
print "%d oz spam, filler no. %d" % (d.oz_of_spam, d.filler) 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 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 be used to import C data types, C functions and variables, and extension
...@@ -184,11 +184,13 @@ example: ...@@ -184,11 +184,13 @@ example:
:file:`spammery.pyx`:: :file:`spammery.pyx`::
from __future__ import print_function
from volume cimport cube from volume cimport cube
def menu(description, size): def menu(description, size):
print description, ":", cube(size), \ print(description, ":", cube(size),
"cubic metres of spam" "cubic metres of spam")
menu("Entree", 1) menu("Entree", 1)
menu("Main course", 3) menu("Main course", 3)
...@@ -243,7 +245,7 @@ and another module which uses it: ...@@ -243,7 +245,7 @@ and another module which uses it:
cdef Shrubbing.Shrubbery sh cdef Shrubbing.Shrubbery sh
sh = Shrubbing.standard_shrubbery() sh = Shrubbing.standard_shrubbery()
print "Shrubbery size is %d x %d" % (sh.width, sh.length) print("Shrubbery size is %d x %d" % (sh.width, sh.length))
One would then need to compile both of these modules, e.g. using One would then need to compile both of these modules, e.g. using
......
...@@ -428,7 +428,7 @@ Cython uses a bracket syntax for templating. A simple example for wrapping C++ v ...@@ -428,7 +428,7 @@ Cython uses a bracket syntax for templating. A simple example for wrapping C++ v
cdef vector[int].iterator it = v.begin() cdef vector[int].iterator it = v.begin()
while it != v.end(): while it != v.end():
print deref(it) print(deref(it))
inc(it) inc(it)
del v del v
...@@ -447,8 +447,8 @@ the template parameter list following the function name:: ...@@ -447,8 +447,8 @@ the template parameter list following the function name::
cdef extern from "<algorithm>" namespace "std": cdef extern from "<algorithm>" namespace "std":
T max[T](T a, T b) T max[T](T a, T b)
print max[long](3, 4) print(max[long](3, 4))
print max(1.5, 2.5) # simple template argument deduction print(max(1.5, 2.5)) # simple template argument deduction
Standard library Standard library
...@@ -467,7 +467,7 @@ For example:: ...@@ -467,7 +467,7 @@ For example::
for i in range(10): for i in range(10):
vect.push_back(i) vect.push_back(i)
for i in range(10): for i in range(10):
print vect[i] print(vect[i])
The pxd files in ``/Cython/Includes/libcpp`` also work as good examples on The pxd files in ``/Cython/Includes/libcpp`` also work as good examples on
how to declare C++ classes. how to declare C++ classes.
......
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