Commit 9498a6e4 authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

Merge

parents 5e001476 26ff1371
...@@ -149,8 +149,8 @@ class CodeWriter(TreeVisitor): ...@@ -149,8 +149,8 @@ class CodeWriter(TreeVisitor):
def visit_PrintStatNode(self, node): def visit_PrintStatNode(self, node):
self.startline(u"print ") self.startline(u"print ")
self.comma_seperated_list(node.args) self.comma_seperated_list(node.arg_tuple.args)
if node.ends_with_comma: if not node.append_newline:
self.put(u",") self.put(u",")
self.endline() self.endline()
......
...@@ -2,8 +2,9 @@ ...@@ -2,8 +2,9 @@
# Pyrex - Builtin Definitions # Pyrex - Builtin Definitions
# #
from Symtab import BuiltinScope from Symtab import BuiltinScope, StructOrUnionScope
from TypeSlots import Signature from TypeSlots import Signature
import PyrexTypes
builtin_function_table = [ builtin_function_table = [
# name, args, return, C API func, py equiv = "*" # name, args, return, C API func, py equiv = "*"
...@@ -24,7 +25,7 @@ builtin_function_table = [ ...@@ -24,7 +25,7 @@ builtin_function_table = [
#('hex', "", "", ""), #('hex', "", "", ""),
#('id', "", "", ""), #('id', "", "", ""),
#('input', "", "", ""), #('input', "", "", ""),
('intern', "s", "O", "PyString_InternFromString"), ('intern', "s", "O", "__Pyx_InternFromString"),
('isinstance', "OO", "b", "PyObject_IsInstance"), ('isinstance', "OO", "b", "PyObject_IsInstance"),
('issubclass', "OO", "b", "PyObject_IsSubclass"), ('issubclass', "OO", "b", "PyObject_IsSubclass"),
('iter', "O", "O", "PyObject_GetIter"), ('iter', "O", "O", "PyObject_GetIter"),
...@@ -100,6 +101,21 @@ builtin_types_table = [ ...@@ -100,6 +101,21 @@ builtin_types_table = [
("values","O", "O", "PyDict_Values")]), ("values","O", "O", "PyDict_Values")]),
] ]
builtin_structs_table = [
('Py_buffer', 'Py_buffer',
[("buf", PyrexTypes.c_void_ptr_type),
("len", PyrexTypes.c_py_ssize_t_type),
("readonly", PyrexTypes.c_bint_type),
("format", PyrexTypes.c_char_ptr_type),
("ndim", PyrexTypes.c_int_type),
("shape", PyrexTypes.c_py_ssize_t_ptr_type),
("strides", PyrexTypes.c_py_ssize_t_ptr_type),
("suboffsets", PyrexTypes.c_py_ssize_t_ptr_type),
("itemsize", PyrexTypes.c_py_ssize_t_type),
("internal", PyrexTypes.c_void_ptr_type),
])
]
getattr3_utility_code = [""" getattr3_utility_code = ["""
static PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); /*proto*/ static PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); /*proto*/
""",""" ""","""
...@@ -118,8 +134,18 @@ bad: ...@@ -118,8 +134,18 @@ bad:
} }
"""] """]
intern_utility_code = ["""
#if PY_MAJOR_VERSION >= 3
# define __Pyx_InternFromString(s) PyUnicode_InternFromString(s)
#else
# define __Pyx_InternFromString(s) PyString_InternFromString(s)
#endif
""","""
"""]
builtin_utility_code = { builtin_utility_code = {
'getattr3': getattr3_utility_code, 'getattr3': getattr3_utility_code,
'intern' : intern_utility_code,
} }
builtin_scope = BuiltinScope() builtin_scope = BuiltinScope()
...@@ -141,12 +167,22 @@ def init_builtin_types(): ...@@ -141,12 +167,22 @@ def init_builtin_types():
sig = Signature(args, ret) sig = Signature(args, ret)
the_type.scope.declare_cfunction(name, sig.function_type(), None, cname) the_type.scope.declare_cfunction(name, sig.function_type(), None, cname)
def init_builtin_structs():
for name, cname, attribute_types in builtin_structs_table:
scope = StructOrUnionScope(name)
for attribute_name, attribute_type in attribute_types:
scope.declare_var(
attribute_name, attribute_type, None, attribute_name)
builtin_scope.declare_struct_or_union(
name, "struct", scope, 1, None, cname = cname)
def init_builtins(): def init_builtins():
init_builtin_funcs() init_builtin_funcs()
init_builtin_types() init_builtin_types()
init_builtin_structs()
global list_type, tuple_type, dict_type global list_type, tuple_type, dict_type
list_type = builtin_scope.lookup('list').type list_type = builtin_scope.lookup('list').type
tuple_type = builtin_scope.lookup('tuple').type tuple_type = builtin_scope.lookup('tuple').type
dict_type = builtin_scope.lookup('dict').type dict_type = builtin_scope.lookup('dict').type
init_builtins() init_builtins()
This diff is collapsed.
def _get_feature(name):
import __future__
try:
return getattr(__future__, name)
except AttributeError:
# unique fake object for earlier Python versions
return object()
unicode_literals = _get_feature("unicode_literals")
del _get_feature
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
# to be rebuilt next time pyrexc is run. # to be rebuilt next time pyrexc is run.
# #
string_prefixes = "cCrRuU" raw_prefixes = "rR"
string_prefixes = "cCuUbB"
def make_lexicon(): def make_lexicon():
from Cython.Plex import \ from Cython.Plex import \
...@@ -55,9 +56,8 @@ def make_lexicon(): ...@@ -55,9 +56,8 @@ def make_lexicon():
+ Rep(non_dq | (Str('"') + non_dq) | (Str('""') + non_dq)) + Rep(non_dq | (Str('"') + non_dq) | (Str('""') + non_dq))
+ Str('"""') + Str('"""')
) )
stringlit = Opt(Any(string_prefixes)) + (sq_string | dq_string | tsq_string| tdq_string)
beginstring = Opt(Any(string_prefixes)) + (Str("'") | Str('"') | Str("'''") | Str('"""')) beginstring = Opt(Any(string_prefixes)) + Opt(Any(raw_prefixes)) + (Str("'") | Str('"') | Str("'''") | Str('"""'))
two_oct = octdigit + octdigit two_oct = octdigit + octdigit
three_oct = octdigit + octdigit + octdigit three_oct = octdigit + octdigit + octdigit
two_hex = hexdigit + hexdigit two_hex = hexdigit + hexdigit
......
...@@ -7,6 +7,12 @@ if sys.version_info[:2] < (2, 2): ...@@ -7,6 +7,12 @@ if sys.version_info[:2] < (2, 2):
sys.stderr.write("Sorry, Cython requires Python 2.2 or later\n") sys.stderr.write("Sorry, Cython requires Python 2.2 or later\n")
sys.exit(1) sys.exit(1)
try:
set
except NameError:
# Python 2.3
from sets import Set as set
from time import time from time import time
import Version import Version
from Scanning import PyrexScanner, FileSourceDescriptor from Scanning import PyrexScanner, FileSourceDescriptor
...@@ -45,12 +51,14 @@ class Context: ...@@ -45,12 +51,14 @@ class Context:
# #
# modules {string : ModuleScope} # modules {string : ModuleScope}
# include_directories [string] # include_directories [string]
# future_directives [object]
def __init__(self, include_directories): def __init__(self, include_directories):
#self.modules = {"__builtin__" : BuiltinScope()} #self.modules = {"__builtin__" : BuiltinScope()}
import Builtin import Builtin
self.modules = {"__builtin__" : Builtin.builtin_scope} self.modules = {"__builtin__" : Builtin.builtin_scope}
self.include_directories = include_directories self.include_directories = include_directories
self.future_directives = set()
def find_module(self, module_name, def find_module(self, module_name,
relative_to = None, pos = None, need_pxd = 1): relative_to = None, pos = None, need_pxd = 1):
......
This diff is collapsed.
...@@ -62,6 +62,8 @@ c_api_tab_cname = pyrex_prefix + "c_api_tab" ...@@ -62,6 +62,8 @@ c_api_tab_cname = pyrex_prefix + "c_api_tab"
gilstate_cname = pyrex_prefix + "state" gilstate_cname = pyrex_prefix + "state"
skip_dispatch_cname = pyrex_prefix + "skip_dispatch" skip_dispatch_cname = pyrex_prefix + "skip_dispatch"
empty_tuple = pyrex_prefix + "empty_tuple" empty_tuple = pyrex_prefix + "empty_tuple"
print_function = pyrex_prefix + "print"
print_function_kwargs = pyrex_prefix + "print_kwargs"
cleanup_cname = pyrex_prefix + "module_cleanup" cleanup_cname = pyrex_prefix + "module_cleanup"
optional_args_cname = pyrex_prefix + "optional_args" optional_args_cname = pyrex_prefix + "optional_args"
no_opt_args = pyrex_prefix + "no_opt_args" no_opt_args = pyrex_prefix + "no_opt_args"
......
This diff is collapsed.
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
# Pyrex - Compilation-wide options # Pyrex - Compilation-wide options
# #
intern_names = 1 # Intern global variable and attribute names
cache_builtins = 1 # Perform lookups on builtin names only once cache_builtins = 1 # Perform lookups on builtin names only once
embed_pos_in_docstring = 0 embed_pos_in_docstring = 0
......
This diff is collapsed.
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# Pyrex - Types # Pyrex - Types
# #
from Cython import Utils
import Naming import Naming
class BaseType: class BaseType:
...@@ -249,7 +250,7 @@ class BuiltinObjectType(PyObjectType): ...@@ -249,7 +250,7 @@ class BuiltinObjectType(PyObjectType):
return type.is_pyobject and self.assignable_from(type) return type.is_pyobject and self.assignable_from(type)
def type_test_code(self, arg): def type_test_code(self, arg):
return 'likely(Py%s_CheckExact(%s)) || (%s) == Py_None || (PyErr_Format(PyExc_TypeError, "Expected %s, got %%s", %s->ob_type->tp_name), 0)' % (self.name[0].upper() + self.name[1:], arg, arg, self.name, arg) return 'likely(Py%s_CheckExact(%s)) || (%s) == Py_None || (PyErr_Format(PyExc_TypeError, "Expected %s, got %%s", Py_TYPE(%s)->tp_name), 0)' % (self.name[0].upper() + self.name[1:], arg, arg, self.name, arg)
class PyExtensionType(PyObjectType): class PyExtensionType(PyObjectType):
...@@ -922,23 +923,6 @@ class CEnumType(CType): ...@@ -922,23 +923,6 @@ class CEnumType(CType):
return self.base_declaration_code(public_decl(base, dll_linkage), entity_code) return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
def _escape_byte_string(s):
s = s.replace('\0', r'\x00')
try:
s.decode("ASCII")
return s
except UnicodeDecodeError:
pass
l = []
append = l.append
for c in s:
o = ord(c)
if o >= 128:
append('\\x%X' % o)
else:
append(c)
return ''.join(l)
class CStringType: class CStringType:
# Mixin class for C string types. # Mixin class for C string types.
...@@ -951,7 +935,7 @@ class CStringType: ...@@ -951,7 +935,7 @@ class CStringType:
def literal_code(self, value): def literal_code(self, value):
assert isinstance(value, str) assert isinstance(value, str)
return '"%s"' % _escape_byte_string(value) return '"%s"' % Utils.escape_byte_string(value)
class CUTF8StringType: class CUTF8StringType:
...@@ -965,7 +949,7 @@ class CUTF8StringType: ...@@ -965,7 +949,7 @@ class CUTF8StringType:
def literal_code(self, value): def literal_code(self, value):
assert isinstance(value, str) assert isinstance(value, str)
return '"%s"' % _escape_byte_string(value) return '"%s"' % Utils.escape_byte_string(value)
class CCharArrayType(CStringType, CArrayType): class CCharArrayType(CStringType, CArrayType):
...@@ -998,16 +982,6 @@ class CCharPtrType(CStringType, CPtrType): ...@@ -998,16 +982,6 @@ class CCharPtrType(CStringType, CPtrType):
CPtrType.__init__(self, c_char_type) CPtrType.__init__(self, c_char_type)
class CUTF8CharPtrType(CUTF8StringType, CPtrType):
# C 'char *' type, encoded in UTF-8.
parsetuple_format = "s"
pymemberdef_typecode = "T_STRING"
def __init__(self):
CPtrType.__init__(self, c_char_type)
class ErrorType(PyrexType): class ErrorType(PyrexType):
# Used to prevent propagation of error messages. # Used to prevent propagation of error messages.
...@@ -1074,14 +1048,17 @@ c_null_ptr_type = CNullPtrType(c_void_type) ...@@ -1074,14 +1048,17 @@ c_null_ptr_type = CNullPtrType(c_void_type)
c_char_array_type = CCharArrayType(None) c_char_array_type = CCharArrayType(None)
c_utf8_char_array_type = CUTF8CharArrayType(None) c_utf8_char_array_type = CUTF8CharArrayType(None)
c_char_ptr_type = CCharPtrType() c_char_ptr_type = CCharPtrType()
c_utf8_char_ptr_type = CUTF8CharPtrType()
c_char_ptr_ptr_type = CPtrType(c_char_ptr_type) c_char_ptr_ptr_type = CPtrType(c_char_ptr_type)
c_py_ssize_t_ptr_type = CPtrType(c_py_ssize_t_type)
c_int_ptr_type = CPtrType(c_int_type) c_int_ptr_type = CPtrType(c_int_type)
c_returncode_type = CIntType(2, 1, "T_INT", is_returncode = 1) c_returncode_type = CIntType(2, 1, "T_INT", is_returncode = 1)
c_anon_enum_type = CAnonEnumType(-1, 1) c_anon_enum_type = CAnonEnumType(-1, 1)
# the Py_buffer type is defined in Builtin.py
c_py_buffer_ptr_type = CPtrType(CStructOrUnionType("Py_buffer", "struct", None, 1, "Py_buffer"))
error_type = ErrorType() error_type = ErrorType()
lowest_float_rank = 6 lowest_float_rank = 6
......
...@@ -11,11 +11,11 @@ import stat ...@@ -11,11 +11,11 @@ import stat
import sys import sys
from time import time from time import time
from Cython import Plex from Cython import Plex, Utils
from Cython.Plex import Scanner from Cython.Plex import Scanner
from Cython.Plex.Errors import UnrecognizedInput from Cython.Plex.Errors import UnrecognizedInput
from Errors import CompileError, error from Errors import CompileError, error
from Lexicon import string_prefixes, make_lexicon from Lexicon import string_prefixes, raw_prefixes, make_lexicon
from Cython import Utils from Cython import Utils
...@@ -322,6 +322,8 @@ class PyrexScanner(Scanner): ...@@ -322,6 +322,8 @@ class PyrexScanner(Scanner):
def begin_string_action(self, text): def begin_string_action(self, text):
if text[:1] in string_prefixes: if text[:1] in string_prefixes:
text = text[1:] text = text[1:]
if text[:1] in raw_prefixes:
text = text[1:]
self.begin(self.string_states[text]) self.begin(self.string_states[text])
self.produce('BEGIN_STRING') self.produce('BEGIN_STRING')
...@@ -380,8 +382,12 @@ class PyrexScanner(Scanner): ...@@ -380,8 +382,12 @@ class PyrexScanner(Scanner):
sy, systring = self.read() sy, systring = self.read()
except UnrecognizedInput: except UnrecognizedInput:
self.error("Unrecognized character") self.error("Unrecognized character")
if sy == 'IDENT' and systring in self.resword_dict: if sy == 'IDENT':
sy = systring if systring in self.resword_dict:
sy = systring
else:
systring = Utils.EncodedString(systring)
systring.encoding = self.source_encoding
self.sy = sy self.sy = sy
self.systring = systring self.systring = systring
if debug_scanner: if debug_scanner:
......
This diff is collapsed.
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
# and associated know-how. # and associated know-how.
# #
from Cython import Utils
import Naming import Naming
import PyrexTypes import PyrexTypes
import sys import sys
...@@ -25,12 +26,14 @@ class Signature: ...@@ -25,12 +26,14 @@ class Signature:
# 'p' void * # 'p' void *
# 'P' void ** # 'P' void **
# 'i' int # 'i' int
# 'b' bint
# 'I' int * # 'I' int *
# 'l' long # 'l' long
# 'Z' Py_ssize_t # 'Z' Py_ssize_t
# 's' char * # 's' char *
# 'S' char ** # 'S' char **
# 'r' int used only to signal exception # 'r' int used only to signal exception
# 'B' Py_buffer *
# '-' dummy 'self' argument (not used) # '-' dummy 'self' argument (not used)
# '*' rest of args passed as generic Python # '*' rest of args passed as generic Python
# arg tuple and kw dict (must be last # arg tuple and kw dict (must be last
...@@ -49,6 +52,7 @@ class Signature: ...@@ -49,6 +52,7 @@ class Signature:
's': PyrexTypes.c_char_ptr_type, 's': PyrexTypes.c_char_ptr_type,
'S': PyrexTypes.c_char_ptr_ptr_type, 'S': PyrexTypes.c_char_ptr_ptr_type,
'r': PyrexTypes.c_returncode_type, 'r': PyrexTypes.c_returncode_type,
'B': PyrexTypes.c_py_buffer_ptr_type,
# 'T', '-' and '*' are handled otherwise # 'T', '-' and '*' are handled otherwise
# and are not looked up in here # and are not looked up in here
} }
...@@ -121,11 +125,15 @@ class SlotDescriptor: ...@@ -121,11 +125,15 @@ class SlotDescriptor:
# slot_name string Member name of the slot in the type object # slot_name string Member name of the slot in the type object
# is_initialised_dynamically Is initialised by code in the module init function # is_initialised_dynamically Is initialised by code in the module init function
# flag Py_TPFLAGS_XXX value indicating presence of slot # flag Py_TPFLAGS_XXX value indicating presence of slot
# py3k Indicates presence of slot in Python 3
def __init__(self, slot_name, dynamic = 0, flag = None): # py2 Indicates presence of slot in Python 2
def __init__(self, slot_name, dynamic = 0, flag = None, py3k = True, py2 = True):
self.slot_name = slot_name self.slot_name = slot_name
self.is_initialised_dynamically = dynamic self.is_initialised_dynamically = dynamic
self.flag = flag self.flag = flag
self.py3k = py3k
self.py2 = py2
def generate(self, scope, code): def generate(self, scope, code):
if self.is_initialised_dynamically: if self.is_initialised_dynamically:
...@@ -133,11 +141,19 @@ class SlotDescriptor: ...@@ -133,11 +141,19 @@ class SlotDescriptor:
else: else:
value = self.slot_code(scope) value = self.slot_code(scope)
flag = self.flag flag = self.flag
py3k = self.py3k
py2 = self.py2
if not py3k:
code.putln("#if PY_MAJOR_VERSION < 3")
elif not py2:
code.putln("#if PY_MAJOR_VERSION >= 3")
if flag: if flag:
code.putln("#if Py_TPFLAGS_DEFAULT & %s" % flag) code.putln("#if (PY_MAJOR_VERSION >= 3) || (Py_TPFLAGS_DEFAULT & %s)" % flag)
code.putln("%s, /*%s*/" % (value, self.slot_name)) code.putln("%s, /*%s*/" % (value, self.slot_name))
if flag: if flag:
code.putln("#endif") code.putln("#endif")
if not py3k or not py2:
code.putln("#endif")
# Some C implementations have trouble statically # Some C implementations have trouble statically
# initialising a global with a pointer to an extern # initialising a global with a pointer to an extern
...@@ -183,8 +199,8 @@ class MethodSlot(SlotDescriptor): ...@@ -183,8 +199,8 @@ class MethodSlot(SlotDescriptor):
# method_name string The __xxx__ name of the method # method_name string The __xxx__ name of the method
# default string or None Default value of the slot # default string or None Default value of the slot
def __init__(self, signature, slot_name, method_name, default = None, flag = None): def __init__(self, signature, slot_name, method_name, default = None, flag = None, py3k=True, py2=True):
SlotDescriptor.__init__(self, slot_name, flag = flag) SlotDescriptor.__init__(self, slot_name, flag = flag, py3k = py3k, py2=py2)
self.signature = signature self.signature = signature
self.slot_name = slot_name self.slot_name = slot_name
self.method_name = method_name self.method_name = method_name
...@@ -205,8 +221,8 @@ class InternalMethodSlot(SlotDescriptor): ...@@ -205,8 +221,8 @@ class InternalMethodSlot(SlotDescriptor):
# #
# slot_name string Member name of the slot in the type object # slot_name string Member name of the slot in the type object
def __init__(self, slot_name): def __init__(self, slot_name, py2 = True):
SlotDescriptor.__init__(self, slot_name) SlotDescriptor.__init__(self, slot_name, py2 = py2)
def slot_code(self, scope): def slot_code(self, scope):
return scope.mangle_internal(self.slot_name) return scope.mangle_internal(self.slot_name)
...@@ -264,8 +280,8 @@ class SyntheticSlot(InternalMethodSlot): ...@@ -264,8 +280,8 @@ class SyntheticSlot(InternalMethodSlot):
# alternative default value will be placed in the type # alternative default value will be placed in the type
# slot. # slot.
def __init__(self, slot_name, user_methods, default_value): def __init__(self, slot_name, user_methods, default_value, py2 = True):
InternalMethodSlot.__init__(self, slot_name) InternalMethodSlot.__init__(self, slot_name, py2 = py2)
self.user_methods = user_methods self.user_methods = user_methods
self.default_value = default_value self.default_value = default_value
...@@ -291,7 +307,11 @@ class DocStringSlot(SlotDescriptor): ...@@ -291,7 +307,11 @@ class DocStringSlot(SlotDescriptor):
def slot_code(self, scope): def slot_code(self, scope):
if scope.doc is not None: if scope.doc is not None:
return '"%s"' % scope.doc if scope.doc.is_unicode:
doc = scope.doc.utf8encode()
else:
doc = scope.doc.byteencode()
return '"%s"' % Utils.escape_byte_string(doc)
else: else:
return "0" return "0"
...@@ -492,6 +512,10 @@ initproc = Signature("T*", 'r') # typedef int (*initproc)(PyObject *, ...@@ -492,6 +512,10 @@ initproc = Signature("T*", 'r') # typedef int (*initproc)(PyObject *,
# typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *); # typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *);
# typedef PyObject *(*allocfunc)(struct _typeobject *, int); # typedef PyObject *(*allocfunc)(struct _typeobject *, int);
getbufferproc = Signature("TBi", "r") # typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
releasebufferproc = Signature("TB", "v") # typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
#------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------
# #
# Signatures for accessor methods of properties. # Signatures for accessor methods of properties.
...@@ -515,7 +539,7 @@ PyNumberMethods = ( ...@@ -515,7 +539,7 @@ PyNumberMethods = (
MethodSlot(binaryfunc, "nb_add", "__add__"), MethodSlot(binaryfunc, "nb_add", "__add__"),
MethodSlot(binaryfunc, "nb_subtract", "__sub__"), MethodSlot(binaryfunc, "nb_subtract", "__sub__"),
MethodSlot(binaryfunc, "nb_multiply", "__mul__"), MethodSlot(binaryfunc, "nb_multiply", "__mul__"),
MethodSlot(binaryfunc, "nb_divide", "__div__"), MethodSlot(binaryfunc, "nb_divide", "__div__", py3k = False),
MethodSlot(binaryfunc, "nb_remainder", "__mod__"), MethodSlot(binaryfunc, "nb_remainder", "__mod__"),
MethodSlot(binaryfunc, "nb_divmod", "__divmod__"), MethodSlot(binaryfunc, "nb_divmod", "__divmod__"),
MethodSlot(ternaryfunc, "nb_power", "__pow__"), MethodSlot(ternaryfunc, "nb_power", "__pow__"),
...@@ -540,7 +564,7 @@ PyNumberMethods = ( ...@@ -540,7 +564,7 @@ PyNumberMethods = (
MethodSlot(ibinaryfunc, "nb_inplace_add", "__iadd__"), MethodSlot(ibinaryfunc, "nb_inplace_add", "__iadd__"),
MethodSlot(ibinaryfunc, "nb_inplace_subtract", "__isub__"), MethodSlot(ibinaryfunc, "nb_inplace_subtract", "__isub__"),
MethodSlot(ibinaryfunc, "nb_inplace_multiply", "__imul__"), MethodSlot(ibinaryfunc, "nb_inplace_multiply", "__imul__"),
MethodSlot(ibinaryfunc, "nb_inplace_divide", "__idiv__"), MethodSlot(ibinaryfunc, "nb_inplace_divide", "__idiv__", py3k = False),
MethodSlot(ibinaryfunc, "nb_inplace_remainder", "__imod__"), MethodSlot(ibinaryfunc, "nb_inplace_remainder", "__imod__"),
MethodSlot(ternaryfunc, "nb_inplace_power", "__ipow__"), # NOT iternaryfunc!!! MethodSlot(ternaryfunc, "nb_inplace_power", "__ipow__"), # NOT iternaryfunc!!!
MethodSlot(ibinaryfunc, "nb_inplace_lshift", "__ilshift__"), MethodSlot(ibinaryfunc, "nb_inplace_lshift", "__ilshift__"),
...@@ -580,10 +604,13 @@ PyMappingMethods = ( ...@@ -580,10 +604,13 @@ PyMappingMethods = (
) )
PyBufferProcs = ( PyBufferProcs = (
MethodSlot(getreadbufferproc, "bf_getreadbuffer", "__getreadbuffer__"), MethodSlot(getreadbufferproc, "bf_getreadbuffer", "__getreadbuffer__", py3k = False),
MethodSlot(getwritebufferproc, "bf_getwritebuffer", "__getwritebuffer__"), MethodSlot(getwritebufferproc, "bf_getwritebuffer", "__getwritebuffer__", py3k = False),
MethodSlot(getsegcountproc, "bf_getsegcount", "__getsegcount__"), MethodSlot(getsegcountproc, "bf_getsegcount", "__getsegcount__", py3k = False),
MethodSlot(getcharbufferproc, "bf_getcharbuffer", "__getcharbuffer__"), MethodSlot(getcharbufferproc, "bf_getcharbuffer", "__getcharbuffer__", py3k = False),
MethodSlot(getbufferproc, "bf_getbuffer", "__getbuffer__", flag = "Py_TPFLAGS_HAVE_NEWBUFFER"),
MethodSlot(releasebufferproc, "bf_releasebuffer", "__releasebuffer__", flag = "Py_TPFLAGS_HAVE_NEWBUFFER"),
) )
#------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------
......
...@@ -91,3 +91,20 @@ class EncodedString(unicode): ...@@ -91,3 +91,20 @@ class EncodedString(unicode):
# def __eq__(self, other): # def __eq__(self, other):
# return unicode.__eq__(self, other) and \ # return unicode.__eq__(self, other) and \
# getattr(other, 'encoding', '') == self.encoding # getattr(other, 'encoding', '') == self.encoding
def escape_byte_string(s):
s = s.replace('\0', r'\x00')
try:
s.decode("ASCII")
return s
except UnicodeDecodeError:
pass
l = []
append = l.append
for c in s:
o = ord(c)
if o >= 128:
append('\\x%X' % o)
else:
append(c)
return ''.join(l)
...@@ -17,3 +17,7 @@ testclean: ...@@ -17,3 +17,7 @@ testclean:
test: testclean test: testclean
${PYTHON} runtests.py ${PYTHON} runtests.py
test3: testclean
${PYTHON} runtests.py --no-cleanup
python3.0 runtests.py --no-cython
...@@ -2,11 +2,7 @@ ...@@ -2,11 +2,7 @@
import os, sys, re, shutil, unittest, doctest import os, sys, re, shutil, unittest, doctest
from Cython.Compiler.Version import version WITH_CYTHON = True
from Cython.Compiler.Main import \
CompilationOptions, \
default_options as pyrex_default_options, \
compile as cython_compile
from distutils.dist import Distribution from distutils.dist import Distribution
from distutils.core import Extension from distutils.core import Extension
...@@ -37,17 +33,21 @@ class ErrorWriter(object): ...@@ -37,17 +33,21 @@ class ErrorWriter(object):
return errors return errors
class TestBuilder(object): class TestBuilder(object):
def __init__(self, rootdir, workdir, selectors, annotate): def __init__(self, rootdir, workdir, selectors, annotate, cleanup_workdir):
self.rootdir = rootdir self.rootdir = rootdir
self.workdir = workdir self.workdir = workdir
self.selectors = selectors self.selectors = selectors
self.annotate = annotate self.annotate = annotate
self.cleanup_workdir = cleanup_workdir
def build_suite(self): def build_suite(self):
suite = unittest.TestSuite() suite = unittest.TestSuite()
filenames = os.listdir(self.rootdir) filenames = os.listdir(self.rootdir)
filenames.sort() filenames.sort()
for filename in filenames: for filename in filenames:
if not WITH_CYTHON and filename == "errors":
# we won't get any errors without running Cython
continue
path = os.path.join(self.rootdir, filename) path = os.path.join(self.rootdir, filename)
if os.path.isdir(path) and filename in TEST_DIRS: if os.path.isdir(path) and filename in TEST_DIRS:
suite.addTest( suite.addTest(
...@@ -55,6 +55,12 @@ class TestBuilder(object): ...@@ -55,6 +55,12 @@ class TestBuilder(object):
return suite return suite
def handle_directory(self, path, context): def handle_directory(self, path, context):
workdir = os.path.join(self.workdir, context)
if not os.path.exists(workdir):
os.makedirs(workdir)
if workdir not in sys.path:
sys.path.insert(0, workdir)
expect_errors = (context == 'errors') expect_errors = (context == 'errors')
suite = unittest.TestSuite() suite = unittest.TestSuite()
filenames = os.listdir(path) filenames = os.listdir(path)
...@@ -69,29 +75,38 @@ class TestBuilder(object): ...@@ -69,29 +75,38 @@ class TestBuilder(object):
continue continue
if context in TEST_RUN_DIRS: if context in TEST_RUN_DIRS:
test = CythonRunTestCase( test = CythonRunTestCase(
path, self.workdir, module, self.annotate) path, workdir, module,
annotate=self.annotate,
cleanup_workdir=self.cleanup_workdir)
else: else:
test = CythonCompileTestCase( test = CythonCompileTestCase(
path, self.workdir, module, expect_errors, self.annotate) path, workdir, module,
expect_errors=expect_errors,
annotate=self.annotate,
cleanup_workdir=self.cleanup_workdir)
suite.addTest(test) suite.addTest(test)
return suite return suite
class CythonCompileTestCase(unittest.TestCase): class CythonCompileTestCase(unittest.TestCase):
def __init__(self, directory, workdir, module, def __init__(self, directory, workdir, module,
expect_errors=False, annotate=False): expect_errors=False, annotate=False, cleanup_workdir=True):
self.directory = directory self.directory = directory
self.workdir = workdir self.workdir = workdir
self.module = module self.module = module
self.expect_errors = expect_errors self.expect_errors = expect_errors
self.annotate = annotate self.annotate = annotate
self.cleanup_workdir = cleanup_workdir
unittest.TestCase.__init__(self) unittest.TestCase.__init__(self)
def shortDescription(self): def shortDescription(self):
return "compiling " + self.module return "compiling " + self.module
def tearDown(self): def tearDown(self):
cleanup_c_files = WITH_CYTHON and self.cleanup_workdir
if os.path.exists(self.workdir): if os.path.exists(self.workdir):
for rmfile in os.listdir(self.workdir): for rmfile in os.listdir(self.workdir):
if not cleanup_c_files and rmfile[-2:] in (".c", ".h"):
continue
if self.annotate and rmfile.endswith(".html"): if self.annotate and rmfile.endswith(".html"):
continue continue
try: try:
...@@ -171,13 +186,14 @@ class CythonCompileTestCase(unittest.TestCase): ...@@ -171,13 +186,14 @@ class CythonCompileTestCase(unittest.TestCase):
directory, module, workdir) directory, module, workdir)
directory = workdir directory = workdir
old_stderr = sys.stderr if WITH_CYTHON:
try: old_stderr = sys.stderr
sys.stderr = ErrorWriter() try:
self.run_cython(directory, module, workdir, incdir, annotate) sys.stderr = ErrorWriter()
errors = sys.stderr.geterrors() self.run_cython(directory, module, workdir, incdir, annotate)
finally: errors = sys.stderr.geterrors()
sys.stderr = old_stderr finally:
sys.stderr = old_stderr
if errors or expected_errors: if errors or expected_errors:
for expected, error in zip(expected_errors, errors): for expected, error in zip(expected_errors, errors):
...@@ -198,11 +214,11 @@ class CythonRunTestCase(CythonCompileTestCase): ...@@ -198,11 +214,11 @@ class CythonRunTestCase(CythonCompileTestCase):
def run(self, result=None): def run(self, result=None):
if result is None: if result is None:
result = self.defaultTestResult() result = self.defaultTestResult()
result.startTest(self)
try: try:
self.runTest() self.runTest()
doctest.DocTestSuite(self.module).run(result) doctest.DocTestSuite(self.module).run(result)
except Exception: except Exception:
result.startTest(self)
result.addError(self, sys.exc_info()) result.addError(self, sys.exc_info())
result.stopTest(self) result.stopTest(self)
try: try:
...@@ -211,49 +227,68 @@ class CythonRunTestCase(CythonCompileTestCase): ...@@ -211,49 +227,68 @@ class CythonRunTestCase(CythonCompileTestCase):
pass pass
if __name__ == '__main__': if __name__ == '__main__':
# RUN ALL TESTS! from optparse import OptionParser
ROOTDIR = os.path.join(os.getcwd(), os.path.dirname(sys.argv[0]), 'tests') parser = OptionParser()
WORKDIR = os.path.join(os.getcwd(), 'BUILD') parser.add_option("--no-cleanup", dest="cleanup_workdir",
if os.path.exists(WORKDIR): action="store_false", default=True,
shutil.rmtree(WORKDIR, ignore_errors=True) help="do not delete the generated C files (allows passing --no-cython on next run)")
os.makedirs(WORKDIR) parser.add_option("--no-cython", dest="with_cython",
action="store_false", default=True,
if not sys.path or sys.path[0] != WORKDIR: help="do not run the Cython compiler, only the C compiler")
sys.path.insert(0, WORKDIR) parser.add_option("-C", "--coverage", dest="coverage",
action="store_true", default=False,
print "Running tests against Cython %s" % version help="collect source coverage data for the Compiler")
print "Python", sys.version parser.add_option("-A", "--annotate", dest="annotate_source",
print action="store_true", default=False,
help="generate annotated HTML versions of the test source files")
try: parser.add_option("-v", "--verbose", dest="verbosity",
sys.argv.remove("-C") action="count", default=0,
except ValueError: help="display test progress, pass twice to print test names")
coverage = None
else: options, cmd_args = parser.parse_args()
if options.coverage:
import coverage import coverage
coverage.erase() coverage.erase()
coverage.start()
WITH_CYTHON = options.with_cython
if WITH_CYTHON:
from Cython.Compiler.Main import \
CompilationOptions, \
default_options as pyrex_default_options, \
compile as cython_compile
try: # RUN ALL TESTS!
sys.argv.remove("-a") ROOTDIR = os.path.join(os.getcwd(), os.path.dirname(sys.argv[0]), 'tests')
except ValueError: WORKDIR = os.path.join(os.getcwd(), 'BUILD')
annotate_source = False if WITH_CYTHON:
if os.path.exists(WORKDIR):
shutil.rmtree(WORKDIR, ignore_errors=True)
if not os.path.exists(WORKDIR):
os.makedirs(WORKDIR)
if WITH_CYTHON:
from Cython.Compiler.Version import version
print("Running tests against Cython %s" % version)
else: else:
annotate_source = True print("Running tests without Cython.")
print("Python %s" % sys.version)
print("")
import re import re
selectors = [ re.compile(r, re.I).search for r in sys.argv[1:] ] selectors = [ re.compile(r, re.I|re.U).search for r in cmd_args ]
if not selectors: if not selectors:
selectors = [ lambda x:True ] selectors = [ lambda x:True ]
tests = TestBuilder(ROOTDIR, WORKDIR, selectors, annotate_source) tests = TestBuilder(ROOTDIR, WORKDIR, selectors,
options.annotate_source, options.cleanup_workdir)
test_suite = tests.build_suite() test_suite = tests.build_suite()
if coverage is not None: unittest.TextTestRunner(verbosity=options.verbosity).run(test_suite)
coverage.start()
unittest.TextTestRunner(verbosity=2).run(test_suite)
if coverage is not None: if options.coverage:
coverage.stop() coverage.stop()
ignored_modules = ('Options', 'Version', 'DebugFlags') ignored_modules = ('Options', 'Version', 'DebugFlags')
modules = [ module for name, module in sys.modules.items() modules = [ module for name, module in sys.modules.items()
......
cdef int i
cdef x
def f(a):
global i, x
i = 42
x = a
cdef class Parrot:
cdef void describe(self):
pass
cdef class Norwegian(Parrot):
cdef void describe(self):
Parrot.describe(self)
__doc__ = """ __doc__ = u"""
>>> s = Swallow() >>> s = Swallow()
>>> s.spam(1) >>> s.spam(1)
1 42 'grail' True 1 42 'grail' True
......
cimport dotted_cimport_submodule.a
import dotted_cimport_submodule.b
...@@ -4,7 +4,6 @@ cdef void foo(): ...@@ -4,7 +4,6 @@ cdef void foo():
cdef char *ptr1, *ptr2 cdef char *ptr1, *ptr2
cdef int *ptr3 cdef int *ptr3
bool = int1 == int2 bool = int1 == int2
bool = int1 <> int2
bool = int1 != int2 bool = int1 != int2
bool = float1 == float2 bool = float1 == float2
bool = ptr1 == ptr2 bool = ptr1 == ptr2
......
...@@ -2,12 +2,6 @@ cdef class Grail: ...@@ -2,12 +2,6 @@ cdef class Grail:
def __add__(int x, float y): def __add__(int x, float y):
pass pass
def __getslice__(self, i, j):
pass
def __setslice__(self, Py_ssize_t i, float j, x):
pass
cdef class Swallow: cdef class Swallow:
pass pass
......
...@@ -5,9 +5,6 @@ cdef class Norwegian(Parrot): ...@@ -5,9 +5,6 @@ cdef class Norwegian(Parrot):
def __delitem__(self, i): def __delitem__(self, i):
pass pass
def __delslice__(self, i, j):
pass
def __delattr__(self, n): def __delattr__(self, n):
pass pass
......
...@@ -5,9 +5,6 @@ cdef class Norwegian(Parrot): ...@@ -5,9 +5,6 @@ cdef class Norwegian(Parrot):
def __setitem__(self, i, x): def __setitem__(self, i, x):
pass pass
def __setslice__(self, i, j, x):
pass
def __setattr__(self, n, x): def __setattr__(self, n, x):
pass pass
......
struct Tomato { PyObject_HEAD}; struct Bicycle{ PyObject_HEAD};
\ No newline at end of file
__doc__ = """ __doc__ = u"""
>>> fiches_CP >>> fiches_CP
[] []
""" """
......
__doc__ = u"""
>>> main()
3.14159265358979323846
3.14159265358979323846
3.14159265358979323846
"""
cdef extern from "math.h": cdef extern from "math.h":
double M_PI double M_PI
......
def call5():
b(1,2,3,4,5)
cdef b(a, b, c=1, d=2):
pass
_ERRORS = """
2:5:Call with wrong number of arguments (expected at most 4, got 5)
"""
__doc__ = """ __doc__ = u"""
__getattribute__ and __getattr__ special methods for a single class. __getattribute__ and __getattr__ special methods for a single class.
>>> a = just_getattribute() >>> a = just_getattribute()
...@@ -29,7 +29,7 @@ __getattribute__ and __getattr__ special methods for a single class. ...@@ -29,7 +29,7 @@ __getattribute__ and __getattr__ special methods for a single class.
cdef class just_getattribute: cdef class just_getattribute:
def __getattribute__(self,n): def __getattribute__(self,n):
if n == 'bar': if n == u'bar':
return n return n
else: else:
raise AttributeError raise AttributeError
...@@ -39,7 +39,7 @@ cdef class just_getattr: ...@@ -39,7 +39,7 @@ cdef class just_getattr:
def __init__(self): def __init__(self):
self.foo = 10 self.foo = 10
def __getattr__(self,n): def __getattr__(self,n):
if n == 'bar': if n == u'bar':
return n return n
else: else:
raise AttributeError raise AttributeError
...@@ -49,12 +49,12 @@ cdef class both: ...@@ -49,12 +49,12 @@ cdef class both:
def __init__(self): def __init__(self):
self.foo = 10 self.foo = 10
def __getattribute__(self,n): def __getattribute__(self,n):
if n == 'foo': if n == u'foo':
return self.foo return self.foo
else: else:
raise AttributeError raise AttributeError
def __getattr__(self,n): def __getattr__(self,n):
if n == 'bar': if n == u'bar':
return n return n
else: else:
raise AttributeError raise AttributeError
__doc__ = """ __doc__ = u"""
__getattribute__ and __getattr__ special methods and subclasses. __getattribute__ and __getattr__ special methods and subclasses.
getattr does not override members. getattr does not override members.
>>> a = getattr_boring() >>> a = getattr_boring()
>>> a.boring_member >>> a.boring_member
10 10
>>> a.resolved_by >>> print(a.resolved_by)
'getattr_boring' getattr_boring
getattribute does. getattribute does.
>>> a = getattribute_boring() >>> a = getattribute_boring()
>>> a.boring_member >>> a.boring_member
Traceback (most recent call last): Traceback (most recent call last):
AttributeError AttributeError
>>> a.resolved_by >>> print(a.resolved_by)
'getattribute_boring' getattribute_boring
Is inherited. Is inherited.
>>> a = boring_boring_getattribute() >>> a = boring_boring_getattribute()
...@@ -24,8 +24,8 @@ Is inherited. ...@@ -24,8 +24,8 @@ Is inherited.
>>> a.boring_boring_getattribute_member >>> a.boring_boring_getattribute_member
Traceback (most recent call last): Traceback (most recent call last):
AttributeError AttributeError
>>> a.resolved_by >>> print(a.resolved_by)
'_getattribute' _getattribute
__getattribute__ is always tried first, then __getattr__, regardless of where __getattribute__ is always tried first, then __getattr__, regardless of where
in the inheritance hiarchy they came from. in the inheritance hiarchy they came from.
...@@ -33,8 +33,8 @@ in the inheritance hiarchy they came from. ...@@ -33,8 +33,8 @@ in the inheritance hiarchy they came from.
>>> a.foo >>> a.foo
Traceback (most recent call last): Traceback (most recent call last):
AttributeError AttributeError
>>> a.resolved_by >>> print(a.resolved_by)
'getattribute_boring_boring_getattr' getattribute_boring_boring_getattr
>>> a.getattribute_boring_boring_getattr >>> a.getattribute_boring_boring_getattr
True True
>>> a._getattr >>> a._getattr
...@@ -44,8 +44,8 @@ in the inheritance hiarchy they came from. ...@@ -44,8 +44,8 @@ in the inheritance hiarchy they came from.
>>> a.foo >>> a.foo
Traceback (most recent call last): Traceback (most recent call last):
AttributeError AttributeError
>>> a.resolved_by >>> print(a.resolved_by)
'_getattribute' _getattribute
>>> a.getattr_boring_boring_getattribute >>> a.getattr_boring_boring_getattribute
True True
>>> a._getattribute >>> a._getattribute
...@@ -60,36 +60,36 @@ cdef class boring: ...@@ -60,36 +60,36 @@ cdef class boring:
cdef class getattr_boring(boring): cdef class getattr_boring(boring):
def __getattr__(self,n): def __getattr__(self,n):
if n == 'resolved_by': if n == u'resolved_by':
return 'getattr_boring' return u'getattr_boring'
elif n == 'getattr_boring': elif n == u'getattr_boring':
return True return True
else: else:
raise AttributeError raise AttributeError
cdef class getattribute_boring(boring): cdef class getattribute_boring(boring):
def __getattribute__(self,n): def __getattribute__(self,n):
if n == 'resolved_by': if n == u'resolved_by':
return 'getattribute_boring' return u'getattribute_boring'
elif n == 'getattribute_boring': elif n == u'getattribute_boring':
return True return True
else: else:
raise AttributeError raise AttributeError
cdef class _getattr: cdef class _getattr:
def __getattr__(self,n): def __getattr__(self,n):
if n == 'resolved_by': if n == u'resolved_by':
return '_getattr' return u'_getattr'
elif n == '_getattr': elif n == u'_getattr':
return True return True
else: else:
raise AttributeError raise AttributeError
cdef class _getattribute(boring): cdef class _getattribute(boring):
def __getattribute__(self,n): def __getattribute__(self,n):
if n == 'resolved_by': if n == u'resolved_by':
return '_getattribute' return u'_getattribute'
elif n == '_getattribute': elif n == u'_getattribute':
return True return True
else: else:
raise AttributeError raise AttributeError
...@@ -108,19 +108,18 @@ cdef class boring_boring_getattr(boring_getattr): ...@@ -108,19 +108,18 @@ cdef class boring_boring_getattr(boring_getattr):
cdef class getattribute_boring_boring_getattr(boring_boring_getattr): cdef class getattribute_boring_boring_getattr(boring_boring_getattr):
def __getattribute__(self,n): def __getattribute__(self,n):
if n == 'resolved_by': if n == u'resolved_by':
return 'getattribute_boring_boring_getattr' return u'getattribute_boring_boring_getattr'
elif n == 'getattribute_boring_boring_getattr': elif n == u'getattribute_boring_boring_getattr':
return True return True
else: else:
raise AttributeError raise AttributeError
cdef class getattr_boring_boring_getattribute(boring_boring_getattribute): cdef class getattr_boring_boring_getattribute(boring_boring_getattribute):
def __getattr__(self,n): def __getattr__(self,n):
if n == 'resolved_by': if n == u'resolved_by':
return 'getattr_boring_boring_getattribute' return u'getattr_boring_boring_getattribute'
elif n == 'getattr_boring_boring_getattribute': elif n == u'getattr_boring_boring_getattribute':
return True return True
else: else:
raise AttributeError raise AttributeError
__doc__ = """ __doc__ = u"""
>>> x = 1 >>> x = 1
>>> for i in range(10): >>> for i in range(10):
... x = x + i ... x = x + i
......
__doc__ = """ __doc__ = u"""
>>> f() >>> f()
(30, 22) (30, 22)
""" """
......
__doc__ = """ __doc__ = u"""
>>> f(5) >>> f(5)
5 5
""" """
......
__doc__ = """ __doc__ = u"""
>>> iter(C()) >>> iter(C())
Traceback (most recent call last): Traceback (most recent call last):
TypeError: iter() returned non-iterator of type 'NoneType' TypeError: iter() returned non-iterator of type 'NoneType'
......
__doc__ = u"""
>>> p
42
"""
cdef enum: cdef enum:
spam = 42 spam = 42
grail = 17 grail = 17
...@@ -5,3 +10,4 @@ cdef enum: ...@@ -5,3 +10,4 @@ cdef enum:
cdef int i cdef int i
i = spam i = spam
p = i
__doc__ = """ __doc__ = u"""
>>> test_append([]) >>> test_append([])
None None
None None
...@@ -23,9 +23,9 @@ None ...@@ -23,9 +23,9 @@ None
class A: class A:
def append(self, x): def append(self, x):
print "appending" print u"appending"
return x return x
class B(list): class B(list):
def append(self, *args): def append(self, *args):
for arg in args: for arg in args:
...@@ -38,6 +38,6 @@ def test_append(L): ...@@ -38,6 +38,6 @@ def test_append(L):
try: try:
print L.append(5,6) print L.append(5,6)
except TypeError: except TypeError:
print "got error" print u"got error"
return L return L
__doc__ = u"""
>>> what()
0 5
>>> f(5)
>>> what()
42 5
>>> f(6)
>>> what()
42 6
>>> f("spam")
>>> what()
42 spam
"""
cdef int i = 0
cdef x = 5
def f(a):
global i, x
i = 42
x = a
def what():
print i,x
__doc__ = """ __doc__ = u"""
>>> getg() >>> getg()
5 5
>>> f(42) >>> f(42)
......
__doc__ = """ __doc__ = u"""
>>> f() >>> f()
42 42
""" """
......
__doc__ = """ __doc__ = u"""
>>> f(1, 2, 1) >>> f(1, 2, 1)
>>> f(0, 2, 1) >>> f(0, 2, 1)
Traceback (most recent call last): Traceback (most recent call last):
......
__doc__ = """ __doc__ = u"""
>>> class Test: >>> class Test(object):
... def __init__(self, i): ... def __init__(self, i):
... self.i = i ... self.i = i
>>> b = Test(1) >>> b = Test(1)
...@@ -9,50 +9,50 @@ __doc__ = """ ...@@ -9,50 +9,50 @@ __doc__ = """
>>> b.spam.eggs.spam.eggs = Test(5) >>> b.spam.eggs.spam.eggs = Test(5)
>>> a = f(b) >>> a = f(b)
>>> print a.i >>> a.i
2 2
>>> print b.i >>> b.i
1 1
>>> print a.spam.i >>> a.spam.i
1 1
>>> print b.spam.i >>> b.spam.i
2 2
>>> print a.spam.eggs.i >>> a.spam.eggs.i
Traceback (most recent call last): Traceback (most recent call last):
AttributeError: Test instance has no attribute 'eggs' AttributeError: 'Test' object has no attribute 'eggs'
>>> print b.spam.eggs.i >>> b.spam.eggs.i
3 3
>>> print a.spam.spam.i >>> a.spam.spam.i
2 2
>>> print b.spam.spam.i >>> b.spam.spam.i
1 1
>>> print a.spam.eggs.spam.i >>> a.spam.eggs.spam.i
Traceback (most recent call last): Traceback (most recent call last):
AttributeError: Test instance has no attribute 'eggs' AttributeError: 'Test' object has no attribute 'eggs'
>>> print b.spam.eggs.spam.i >>> b.spam.eggs.spam.i
4 4
>>> a = g(b) >>> a = g(b)
>>> print a.i >>> a.i
3 3
>>> print b.i >>> b.i
1 1
>>> print a.spam.i >>> a.spam.i
4 4
>>> print b.spam.i >>> b.spam.i
2 2
>>> print a.spam.eggs.i >>> a.spam.eggs.i
1 1
>>> print b.spam.eggs.i >>> b.spam.eggs.i
3 3
>>> print a.spam.spam.i >>> a.spam.spam.i
Traceback (most recent call last): Traceback (most recent call last):
AttributeError: Test instance has no attribute 'spam' AttributeError: 'Test' object has no attribute 'spam'
>>> print b.spam.spam.i >>> b.spam.spam.i
1 1
>>> print a.spam.eggs.spam.i >>> a.spam.eggs.spam.i
2 2
>>> print b.spam.eggs.spam.i >>> b.spam.eggs.spam.i
4 4
""" """
......
__doc__ = """ __doc__ = u"""
>>> m = MyClass() >>> m = MyClass()
>>> m is foo(m) >>> m is foo(m)
True True
......
__doc__ = """ __doc__ = u"""
>>> f(20) >>> f(20)
'20' '20'
>>> f('test') >>> f('test')
......
__doc__ = """ __doc__ = u"""
>>> viking(5) >>> viking(5)
5 5
""" """
......
__doc__ = """ __doc__ = u"""
>>> y >>> y
1 1
>>> y and {} >>> y and {}
......
__doc__ = """ __doc__ = u"""
>>> y >>> y
>>> y or {} >>> y or {}
{} {}
......
__doc__ = """ __doc__ = u"""
>>> m = fmatrix() >>> m = fmatrix()
>>> m[1] = True >>> m[1] = True
>>> m.getfoo() >>> m.getfoo()
......
__doc__ = """ __doc__ = u"""
>>> f = foo() >>> f = foo()
>>> 'a' in f >>> 'a' in f
True True
......
__doc__ = """ __doc__ = u"""
>>> foo(True, False, 23, 'test', 1) >>> foo(True, False, 23, 'test', 1)
(0, 1, False, False) (0, 1, False, False)
""" """
......
__doc__ = u"""
>>> b1 = TestBuffer()
>>> b2 = TestBufferRelease()
"""
import sys
if sys.version_info[0] >= 3:
__doc__ += u"""
>>> ms = memoryview(s)
>>> ms.tobytes()
bytearray(b'abcdefg')
>>> m1 = memoryview(b1)
>>> m1.tobytes()
locking!
bytearray(b'abcdefg')
>>> m2 = memoryview(b2)
>>> m2.tobytes()
locking!
unlocking!
bytearray(b'abcdefg')
>>> del m1
>>> del m2
releasing!
"""
s = "abcdefg"
cdef class TestBuffer:
def __getbuffer__(self, Py_buffer* buffer, int flags):
if buffer is NULL:
print u"locking!"
return
buffer.buf = <char*>s
buffer.len = len(s)
buffer.readonly = 0
buffer.format = "B"
buffer.ndim = 0
buffer.shape = NULL
buffer.strides = NULL
buffer.suboffsets = NULL
buffer.itemsize = 1
buffer.internal = NULL
cdef class TestBufferRelease(TestBuffer):
def __releasebuffer__(self, Py_buffer* buffer):
if buffer is NULL:
print u"unlocking!"
else:
print u"releasing!"
__doc__ = u"""
>>> call2()
>>> call3()
>>> call4()
"""
# the calls:
def call2():
b(1,2)
def call3():
b(1,2,3)
def call4():
b(1,2,3,4)
# the called function:
cdef b(a, b, c=1, d=2):
pass
__doc__ = """ __doc__ = u"""
>>> test() >>> test()
""" """
......
__doc__ = """ __doc__ = u"""
>>> int2 = 42 >>> int2 = 42
>>> int3 = 7 >>> int3 = 7
>>> char1 = ord('C') >>> char1 = ord('C')
...@@ -10,7 +10,7 @@ __doc__ = """ ...@@ -10,7 +10,7 @@ __doc__ = """
>>> int1 ^= int2 >> int3 >>> int1 ^= int2 >> int3
>>> int1 ^= int2 << int3 | int2 >> int3 >>> int1 ^= int2 << int3 | int2 >> int3
>>> long1 = char1 | int1 >>> long1 = char1 | int1
>>> print (int1, long1) == f() >>> (int1, long1) == f()
True True
>>> f() >>> f()
......
__doc__ = """ __doc__ = u"""
>>> spam = Spam() >>> spam = Spam()
>>> b,c,d,e,f,g,h,k = spam.b,spam.c,spam.d,spam.e,spam.f,spam.g,spam.h,spam.k >>> b,c,d,e,f,g,h,k = spam.b,spam.c,spam.d,spam.e,spam.f,spam.g,spam.h,spam.k
...@@ -49,7 +49,7 @@ __doc__ = """ ...@@ -49,7 +49,7 @@ __doc__ = """
>>> g(1,2, c=1, e=0, f=2, d=11) >>> g(1,2, c=1, e=0, f=2, d=11)
>>> g(1,2, c=1, f=2, e=0, x=25) >>> g(1,2, c=1, f=2, e=0, x=25)
>>> g(1,2,3) >>> g(1,2,3) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given) TypeError: function takes at most 3 positional arguments (4 given)
>>> g(1,2) >>> g(1,2)
...@@ -84,6 +84,14 @@ __doc__ = """ ...@@ -84,6 +84,14 @@ __doc__ = """
TypeError: required keyword argument 'f' is missing TypeError: required keyword argument 'f' is missing
""" """
import sys, re
if sys.version_info >= (2,6):
__doc__ = re.sub(u"Error: (.*)exactly(.*)", u"Error: \\1at most\\2", __doc__)
import sys, re
if sys.version_info >= (2,6):
__doc__ = re.sub(u"(ELLIPSIS[^>]*Error: )[^\n]*\n", u"\\1...\n", __doc__, re.M)
class Spam: class Spam:
def b(self, a, b, c): def b(self, a, b, c):
pass pass
......
__doc__ = u"""
>>> class1.view()
class1
>>> class1.plus(1)
6
>>> class2.view()
class2
>>> class2.plus(1)
7
>>> class3.view()
class3
>>> class3.plus(1)
8
"""
def f_plus(cls, a):
return cls.a + a
class class1:
a = 5
plus = classmethod(f_plus)
def view(cls):
print cls.__name__
view = classmethod(view)
class class2(object):
a = 6
plus = classmethod(f_plus)
def view(cls):
print cls.__name__
view = classmethod(view)
cdef class class3:
a = 7
plus = classmethod(f_plus)
def view(cls):
print cls.__name__
view = classmethod(view)
__doc__ = """ __doc__ = u"""
>>> s = Spam() >>> s = Spam()
>>> print s.__class__.__name__ >>> s.__class__.__name__
Spam 'Spam'
>>> s = SpamT() >>> s = SpamT()
>>> print type(s).__name__ >>> type(s).__name__
SpamT 'SpamT'
""" """
class Spam: pass class Spam: pass
......
__doc__ = """ __doc__ = u"""
>>> t >>> t
True True
>>> f >>> f
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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