@@ -14,7 +14,7 @@ statement, Cython also lets you create new built-in Python types, known as
...
@@ -14,7 +14,7 @@ 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
from __future__ import print_function
cdef class Shrubbery:
cdef class Shrubbery:
...
@@ -129,7 +129,7 @@ which requires the use of a local variable and performs a type test on assignmen
...
@@ -129,7 +129,7 @@ which requires the use of a local variable and performs a type test on assignmen
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,
...
@@ -137,21 +137,17 @@ rather than raising an :class:`AttributeError`, either an nonsensical result wil
...
@@ -137,21 +137,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