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()
...@@ -739,6 +739,18 @@ class StringNode(ConstNode): ...@@ -739,6 +739,18 @@ class StringNode(ConstNode):
return self.entry.cname return self.entry.cname
class IdentifierStringNode(ConstNode):
# A Python string that behaves like an identifier, e.g. for
# keyword arguments in a call, or for imported names
type = PyrexTypes.py_object_type
def analyse_types(self, env):
self.cname = env.intern_identifier(self.value)
def calculate_result_code(self):
return self.cname
class LongNode(AtomicExprNode): class LongNode(AtomicExprNode):
# Python long integer literal # Python long integer literal
# #
...@@ -838,6 +850,8 @@ class NameNode(AtomicExprNode): ...@@ -838,6 +850,8 @@ class NameNode(AtomicExprNode):
env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment') env.control_flow.set_state(self.pos, (self.name, 'source'), 'assignment')
if self.entry.is_declared_generic: if self.entry.is_declared_generic:
self.result_ctype = py_object_type self.result_ctype = py_object_type
if self.entry.is_pyglobal and self.entry.is_member:
env.use_utility_code(type_cache_invalidation_code)
def analyse_types(self, env): def analyse_types(self, env):
self.entry = env.lookup(self.name) self.entry = env.lookup(self.name)
...@@ -868,10 +882,7 @@ class NameNode(AtomicExprNode): ...@@ -868,10 +882,7 @@ class NameNode(AtomicExprNode):
self.is_temp = 0 self.is_temp = 0
else: else:
self.is_temp = 1 self.is_temp = 1
if Options.intern_names: env.use_utility_code(get_name_interned_utility_code)
env.use_utility_code(get_name_interned_utility_code)
else:
env.use_utility_code(get_name_utility_code)
def analyse_entry(self, env): def analyse_entry(self, env):
#print "NameNode.analyse_entry:", self.name ### #print "NameNode.analyse_entry:", self.name ###
...@@ -881,8 +892,8 @@ class NameNode(AtomicExprNode): ...@@ -881,8 +892,8 @@ class NameNode(AtomicExprNode):
self.type = type self.type = type
if entry.is_pyglobal or entry.is_builtin: if entry.is_pyglobal or entry.is_builtin:
assert type.is_pyobject, "Python global or builtin not a Python object" assert type.is_pyobject, "Python global or builtin not a Python object"
if Options.intern_names: self.interned_cname = self.entry.interned_cname = \
self.interned_cname = self.entry.interned_cname = env.intern(self.entry.name) env.intern_identifier(self.entry.name)
def check_identifier_kind(self): def check_identifier_kind(self):
#print "NameNode.check_identifier_kind:", self.entry.name ### #print "NameNode.check_identifier_kind:", self.entry.name ###
...@@ -950,20 +961,12 @@ class NameNode(AtomicExprNode): ...@@ -950,20 +961,12 @@ class NameNode(AtomicExprNode):
namespace = Naming.builtins_cname namespace = Naming.builtins_cname
else: # entry.is_pyglobal else: # entry.is_pyglobal
namespace = entry.namespace_cname namespace = entry.namespace_cname
if Options.intern_names: code.putln(
code.putln( '%s = __Pyx_GetName(%s, %s); %s' % (
'%s = __Pyx_GetName(%s, %s); %s' % ( self.result_code,
self.result_code, namespace,
namespace, self.interned_cname,
self.interned_cname, code.error_goto_if_null(self.result_code, self.pos)))
code.error_goto_if_null(self.result_code, self.pos)))
else:
code.putln(
'%s = __Pyx_GetName(%s, "%s"); %s' % (
self.result_code,
namespace,
self.entry.name,
code.error_goto_if_null(self.result_code, self.pos)))
elif entry.is_local and False: elif entry.is_local and False:
# control flow not good enough yet # control flow not good enough yet
assigned = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos) assigned = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos)
...@@ -984,34 +987,22 @@ class NameNode(AtomicExprNode): ...@@ -984,34 +987,22 @@ class NameNode(AtomicExprNode):
if entry.is_pyglobal: if entry.is_pyglobal:
namespace = self.entry.namespace_cname namespace = self.entry.namespace_cname
if entry.is_member: if entry.is_member:
# if we entry is a member we have to cheat: SetAttr does not work # if the entry is a member we have to cheat: SetAttr does not work
# on types, so we create a descriptor which is then added to tp_dict # on types, so we create a descriptor which is then added to tp_dict
if Options.intern_names: code.put_error_if_neg(self.pos,
code.put_error_if_neg(self.pos, 'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
'PyDict_SetItem(%s->tp_dict, %s, %s)' % ( namespace,
namespace, self.interned_cname,
self.interned_cname, rhs.py_result()))
rhs.py_result())) # in Py2.6+, we need to invalidate the method cache
else: code.putln("__Pyx_TypeModified((PyTypeObject*)%s);" %
code.put_error_if_neg(self.pos, entry.scope.parent_type.typeptr_cname)
'PyDict_SetItemString(%s->tp_dict, %s, %s)' % (
namespace,
entry.name,
rhs.py_result()))
else: else:
if Options.intern_names: code.put_error_if_neg(self.pos,
code.put_error_if_neg(self.pos, 'PyObject_SetAttr(%s, %s, %s)' % (
'PyObject_SetAttr(%s, %s, %s)' % ( namespace,
namespace, self.interned_cname,
self.interned_cname, rhs.py_result()))
rhs.py_result()))
else:
code.put_error_if_neg(self.pos,
'PyObject_SetAttrString(%s, "%s", %s)' % (
namespace,
entry.name,
rhs.py_result()))
if debug_disposal_code: if debug_disposal_code:
print("NameNode.generate_assignment_code:") print("NameNode.generate_assignment_code:")
print("...generating disposal code for %s" % rhs) print("...generating disposal code for %s" % rhs)
...@@ -1084,8 +1075,8 @@ class ImportNode(ExprNode): ...@@ -1084,8 +1075,8 @@ class ImportNode(ExprNode):
# Implements result = # Implements result =
# __import__(module_name, globals(), None, name_list) # __import__(module_name, globals(), None, name_list)
# #
# module_name StringNode dotted name of module # module_name IdentifierStringNode dotted name of module
# name_list ListNode or None list of names to be imported # name_list ListNode or None list of names to be imported
subexprs = ['module_name', 'name_list'] subexprs = ['module_name', 'name_list']
...@@ -1836,7 +1827,7 @@ class AttributeNode(ExprNode): ...@@ -1836,7 +1827,7 @@ class AttributeNode(ExprNode):
# member string C name of struct member # member string C name of struct member
# is_called boolean Function call is being done on result # is_called boolean Function call is being done on result
# entry Entry Symbol table entry of attribute # entry Entry Symbol table entry of attribute
# interned_attr_cname string C name of interned attribute name # interned_attr_cname string C name of interned attribute name
is_attribute = 1 is_attribute = 1
subexprs = ['obj'] subexprs = ['obj']
...@@ -2019,8 +2010,7 @@ class AttributeNode(ExprNode): ...@@ -2019,8 +2010,7 @@ class AttributeNode(ExprNode):
if obj_type.is_pyobject: if obj_type.is_pyobject:
self.type = py_object_type self.type = py_object_type
self.is_py_attr = 1 self.is_py_attr = 1
if Options.intern_names: self.interned_attr_cname = env.intern_identifier(self.attribute)
self.interned_attr_cname = env.intern(self.attribute)
else: else:
if not obj_type.is_error: if not obj_type.is_error:
error(self.pos, error(self.pos,
...@@ -2064,36 +2054,21 @@ class AttributeNode(ExprNode): ...@@ -2064,36 +2054,21 @@ class AttributeNode(ExprNode):
def generate_result_code(self, code): def generate_result_code(self, code):
if self.is_py_attr: if self.is_py_attr:
if Options.intern_names: code.putln(
code.putln( '%s = PyObject_GetAttr(%s, %s); %s' % (
'%s = PyObject_GetAttr(%s, %s); %s' % ( self.result_code,
self.result_code, self.obj.py_result(),
self.obj.py_result(), self.interned_attr_cname,
self.interned_attr_cname, code.error_goto_if_null(self.result_code, self.pos)))
code.error_goto_if_null(self.result_code, self.pos)))
else:
code.putln(
'%s = PyObject_GetAttrString(%s, "%s"); %s' % (
self.result_code,
self.obj.py_result(),
self.attribute,
code.error_goto_if_null(self.result_code, self.pos)))
def generate_assignment_code(self, rhs, code): def generate_assignment_code(self, rhs, code):
self.obj.generate_evaluation_code(code) self.obj.generate_evaluation_code(code)
if self.is_py_attr: if self.is_py_attr:
if Options.intern_names: code.put_error_if_neg(self.pos,
code.put_error_if_neg(self.pos, 'PyObject_SetAttr(%s, %s, %s)' % (
'PyObject_SetAttr(%s, %s, %s)' % ( self.obj.py_result(),
self.obj.py_result(), self.interned_attr_cname,
self.interned_attr_cname, rhs.py_result()))
rhs.py_result()))
else:
code.put_error_if_neg(self.pos,
'PyObject_SetAttrString(%s, "%s", %s)' % (
self.obj.py_result(),
self.attribute,
rhs.py_result()))
rhs.generate_disposal_code(code) rhs.generate_disposal_code(code)
else: else:
select_code = self.result_code select_code = self.result_code
...@@ -2111,16 +2086,10 @@ class AttributeNode(ExprNode): ...@@ -2111,16 +2086,10 @@ class AttributeNode(ExprNode):
def generate_deletion_code(self, code): def generate_deletion_code(self, code):
self.obj.generate_evaluation_code(code) self.obj.generate_evaluation_code(code)
if self.is_py_attr: if self.is_py_attr:
if Options.intern_names: code.put_error_if_neg(self.pos,
code.put_error_if_neg(self.pos, 'PyObject_DelAttr(%s, %s)' % (
'PyObject_DelAttr(%s, %s)' % ( self.obj.py_result(),
self.obj.py_result(), self.interned_attr_cname))
self.interned_attr_cname))
else:
code.put_error_if_neg(self.pos,
'PyObject_DelAttrString(%s, "%s")' % (
self.obj.py_result(),
self.attribute))
else: else:
error(self.pos, "Cannot delete C attribute of extension type") error(self.pos, "Cannot delete C attribute of extension type")
self.obj.generate_disposal_code(code) self.obj.generate_disposal_code(code)
...@@ -2463,22 +2432,23 @@ class DictItemNode(ExprNode): ...@@ -2463,22 +2432,23 @@ class DictItemNode(ExprNode):
self.key.generate_disposal_code(code) self.key.generate_disposal_code(code)
self.value.generate_disposal_code(code) self.value.generate_disposal_code(code)
class ClassNode(ExprNode): class ClassNode(ExprNode):
# Helper class used in the implementation of Python # Helper class used in the implementation of Python
# class definitions. Constructs a class object given # class definitions. Constructs a class object given
# a name, tuple of bases and class dictionary. # a name, tuple of bases and class dictionary.
# #
# name ExprNode Name of the class # name EncodedString Name of the class
# cname string Class name as a Python string
# bases ExprNode Base class tuple # bases ExprNode Base class tuple
# dict ExprNode Class dict (not owned by this node) # dict ExprNode Class dict (not owned by this node)
# doc ExprNode or None Doc string # doc ExprNode or None Doc string
# module_name string Name of defining module # module_name string Name of defining module
subexprs = ['name', 'bases', 'doc'] subexprs = ['bases', 'doc']
def analyse_types(self, env): def analyse_types(self, env):
self.name.analyse_types(env) self.cname = env.intern_identifier(self.name)
self.name = self.name.coerce_to_pyobject(env)
self.bases.analyse_types(env) self.bases.analyse_types(env)
if self.doc: if self.doc:
self.doc.analyse_types(env) self.doc.analyse_types(env)
...@@ -2487,7 +2457,7 @@ class ClassNode(ExprNode): ...@@ -2487,7 +2457,7 @@ class ClassNode(ExprNode):
self.type = py_object_type self.type = py_object_type
self.is_temp = 1 self.is_temp = 1
env.use_utility_code(create_class_utility_code); env.use_utility_code(create_class_utility_code);
def generate_result_code(self, code): def generate_result_code(self, code):
if self.doc: if self.doc:
code.put_error_if_neg(self.pos, code.put_error_if_neg(self.pos,
...@@ -2499,7 +2469,7 @@ class ClassNode(ExprNode): ...@@ -2499,7 +2469,7 @@ class ClassNode(ExprNode):
self.result_code, self.result_code,
self.bases.py_result(), self.bases.py_result(),
self.dict.py_result(), self.dict.py_result(),
self.name.py_result(), self.cname,
self.module_name, self.module_name,
code.error_goto_if_null(self.result_code, self.pos))) code.error_goto_if_null(self.result_code, self.pos)))
...@@ -3907,19 +3877,6 @@ class CloneNode(CoercionNode): ...@@ -3907,19 +3877,6 @@ class CloneNode(CoercionNode):
# #
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
get_name_utility_code = [
"""
static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/
""","""
static PyObject *__Pyx_GetName(PyObject *dict, char *name) {
PyObject *result;
result = PyObject_GetAttrString(dict, name);
if (!result)
PyErr_SetString(PyExc_NameError, name);
return result;
}
"""]
get_name_interned_utility_code = [ get_name_interned_utility_code = [
""" """
static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/ static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
...@@ -4069,7 +4026,7 @@ static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { ...@@ -4069,7 +4026,7 @@ static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
if (obj == Py_None || PyObject_TypeCheck(obj, type)) if (obj == Py_None || PyObject_TypeCheck(obj, type))
return 1; return 1;
PyErr_Format(PyExc_TypeError, "Cannot convert %s to %s", PyErr_Format(PyExc_TypeError, "Cannot convert %s to %s",
obj->ob_type->tp_name, type->tp_name); Py_TYPE(obj)->tp_name, type->tp_name);
return 0; return 0;
} }
"""] """]
...@@ -4085,13 +4042,21 @@ static PyObject *__Pyx_CreateClass( ...@@ -4085,13 +4042,21 @@ static PyObject *__Pyx_CreateClass(
{ {
PyObject *py_modname; PyObject *py_modname;
PyObject *result = 0; PyObject *result = 0;
#if PY_MAJOR_VERSION < 3
py_modname = PyString_FromString(modname); py_modname = PyString_FromString(modname);
#else
py_modname = PyUnicode_FromString(modname);
#endif
if (!py_modname) if (!py_modname)
goto bad; goto bad;
if (PyDict_SetItemString(dict, "__module__", py_modname) < 0) if (PyDict_SetItemString(dict, "__module__", py_modname) < 0)
goto bad; goto bad;
#if PY_MAJOR_VERSION < 3
result = PyClass_New(bases, dict, name); result = PyClass_New(bases, dict, name);
#else
result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases, dict, NULL);
#endif
bad: bad:
Py_XDECREF(py_modname); Py_XDECREF(py_modname);
return result; return result;
...@@ -4139,3 +4104,39 @@ static INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) { ...@@ -4139,3 +4104,39 @@ static INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
} }
""","" """,""
] ]
#------------------------------------------------------------------------------------
type_cache_invalidation_code = [
"""
#if PY_VERSION_HEX >= 0x02060000
static void __Pyx_TypeModified(PyTypeObject* type); /*proto*/
#else
#define __Pyx_TypeModified(t)
#endif
""","""
#if PY_VERSION_HEX >= 0x02060000
/* copied from typeobject.c in Python 3.0a5 */
static void __Pyx_TypeModified(PyTypeObject* type) {
PyObject *raw, *ref;
Py_ssize_t i, n;
if (!PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG))
return;
raw = type->tp_subclasses;
if (raw != NULL) {
n = PyList_GET_SIZE(raw);
for (i = 0; i < n; i++) {
ref = PyList_GET_ITEM(raw, i);
ref = PyWeakref_GET_OBJECT(ref);
if (ref != Py_None) {
__Pyx_TypeModified((PyTypeObject *)ref);
}
}
}
type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
}
#endif
"""
]
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):
......
...@@ -20,7 +20,7 @@ import PyrexTypes ...@@ -20,7 +20,7 @@ import PyrexTypes
import TypeSlots import TypeSlots
import Version import Version
from Errors import error from Errors import error, warning
from PyrexTypes import py_object_type from PyrexTypes import py_object_type
from Cython.Utils import open_new_file, replace_suffix from Cython.Utils import open_new_file, replace_suffix
...@@ -221,12 +221,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -221,12 +221,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("/* Implementation of %s */" % env.qualified_name) code.putln("/* Implementation of %s */" % env.qualified_name)
self.generate_const_definitions(env, code) self.generate_const_definitions(env, code)
self.generate_interned_num_decls(env, code) self.generate_interned_num_decls(env, code)
self.generate_interned_name_decls(env, code) self.generate_interned_string_decls(env, code)
self.generate_py_string_decls(env, code) self.generate_py_string_decls(env, code)
self.generate_cached_builtins_decls(env, code) self.generate_cached_builtins_decls(env, code)
self.body.generate_function_definitions(env, code, options.transforms) self.body.generate_function_definitions(env, code, options.transforms)
code.mark_pos(None) code.mark_pos(None)
self.generate_interned_name_table(env, code)
self.generate_py_string_table(env, code) self.generate_py_string_table(env, code)
self.generate_typeobj_definitions(env, code) self.generate_typeobj_definitions(env, code)
self.generate_method_table(env, code) self.generate_method_table(env, code)
...@@ -366,6 +365,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -366,6 +365,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("#ifndef PY_LONG_LONG") code.putln("#ifndef PY_LONG_LONG")
code.putln(" #define PY_LONG_LONG LONG_LONG") code.putln(" #define PY_LONG_LONG LONG_LONG")
code.putln("#endif") code.putln("#endif")
code.putln("#ifndef DL_EXPORT")
code.putln(" #define DL_EXPORT(t) t")
code.putln("#endif")
code.putln("#if PY_VERSION_HEX < 0x02040000")
code.putln(" #define METH_COEXIST 0")
code.putln("#endif")
code.putln("#if PY_VERSION_HEX < 0x02050000") code.putln("#if PY_VERSION_HEX < 0x02050000")
code.putln(" typedef int Py_ssize_t;") code.putln(" typedef int Py_ssize_t;")
code.putln(" #define PY_SSIZE_T_MAX INT_MAX") code.putln(" #define PY_SSIZE_T_MAX INT_MAX")
...@@ -375,9 +381,68 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -375,9 +381,68 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(" #define PyNumber_Index(o) PyNumber_Int(o)") code.putln(" #define PyNumber_Index(o) PyNumber_Int(o)")
code.putln(" #define PyIndex_Check(o) PyNumber_Check(o)") code.putln(" #define PyIndex_Check(o) PyNumber_Check(o)")
code.putln("#endif") code.putln("#endif")
code.putln("#if PY_VERSION_HEX < 0x02040000")
code.putln(" #define METH_COEXIST 0") code.putln("#if PY_VERSION_HEX < 0x02060000")
code.putln(" #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)")
code.putln(" #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)")
code.putln(" #define Py_SIZE(ob) ((PyVarObject*)(ob))->ob_size)")
code.putln(" #define PyVarObject_HEAD_INIT(type, size) \\")
code.putln(" PyObject_HEAD_INIT(type) size,")
code.putln("")
code.putln(" typedef struct {")
code.putln(" void *buf;")
code.putln(" Py_ssize_t len;")
code.putln(" int readonly;")
code.putln(" const char *format;")
code.putln(" int ndim;")
code.putln(" Py_ssize_t *shape;")
code.putln(" Py_ssize_t *strides;")
code.putln(" Py_ssize_t *suboffsets;")
code.putln(" Py_ssize_t itemsize;")
code.putln(" void *internal;")
code.putln(" } Py_buffer;")
code.putln("")
code.putln(" #define PyBUF_SIMPLE 0")
code.putln(" #define PyBUF_WRITABLE 0x0001")
code.putln(" #define PyBUF_LOCK 0x0002")
code.putln(" #define PyBUF_FORMAT 0x0004")
code.putln(" #define PyBUF_ND 0x0008")
code.putln(" #define PyBUF_STRIDES (0x0010 | PyBUF_ND)")
code.putln(" #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)")
code.putln(" #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)")
code.putln(" #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)")
code.putln(" #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)")
code.putln("#endif")
code.put(builtin_module_name_utility_code[0])
code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln(" #define Py_TPFLAGS_CHECKTYPES 0")
code.putln(" #define Py_TPFLAGS_HAVE_INDEX 0")
code.putln("#endif")
code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln(" #define PyBaseString_Type PyUnicode_Type")
code.putln(" #define PyInt_Type PyLong_Type")
code.putln(" #define PyInt_Check(op) PyLong_Check(op)")
code.putln(" #define PyInt_CheckExact(op) PyLong_CheckExact(op)")
code.putln(" #define PyInt_FromString PyLong_FromString")
code.putln(" #define PyInt_FromUnicode PyLong_FromUnicode")
code.putln(" #define PyInt_FromLong PyLong_FromLong")
code.putln(" #define PyInt_FromSize_t PyLong_FromSize_t")
code.putln(" #define PyInt_FromSsize_t PyLong_FromSsize_t")
code.putln(" #define PyInt_AsLong PyLong_AsLong")
code.putln(" #define PyInt_AS_LONG PyLong_AS_LONG")
code.putln(" #define PyInt_AsSsize_t PyLong_AsSsize_t")
code.putln(" #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask")
code.putln(" #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask")
code.putln(" #define PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)")
code.putln("#endif") code.putln("#endif")
code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln(" #define PyMethod_New(func, self, klass) PyInstanceMethod_New(func)")
code.putln("#endif")
code.putln("#ifndef __stdcall") code.putln("#ifndef __stdcall")
code.putln(" #define __stdcall") code.putln(" #define __stdcall")
code.putln("#endif") code.putln("#endif")
...@@ -664,6 +729,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -664,6 +729,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if scope.defines_any(["__setitem__", "__delitem__"]): if scope.defines_any(["__setitem__", "__delitem__"]):
self.generate_ass_subscript_function(scope, code) self.generate_ass_subscript_function(scope, code)
if scope.defines_any(["__setslice__", "__delslice__"]): if scope.defines_any(["__setslice__", "__delslice__"]):
warning(self.pos, "__setslice__ and __delslice__ are not supported by Python 3")
self.generate_ass_slice_function(scope, code) self.generate_ass_slice_function(scope, code)
if scope.defines_any(["__getattr__","__getattribute__"]): if scope.defines_any(["__getattr__","__getattribute__"]):
self.generate_getattro_function(scope, code) self.generate_getattro_function(scope, code)
...@@ -786,7 +852,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -786,7 +852,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"%s(o);" % tp_dealloc) "%s(o);" % tp_dealloc)
else: else:
code.putln( code.putln(
"(*o->ob_type->tp_free)(o);") "(*Py_TYPE(o)->tp_free)(o);")
code.putln( code.putln(
"}") "}")
...@@ -800,14 +866,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -800,14 +866,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln( code.putln(
"PyErr_Fetch(&etype, &eval, &etb);") "PyErr_Fetch(&etype, &eval, &etb);")
code.putln( code.putln(
"++o->ob_refcnt;") "++Py_REFCNT(o);")
code.putln( code.putln(
"%s(o);" % "%s(o);" %
entry.func_cname) entry.func_cname)
code.putln( code.putln(
"if (PyErr_Occurred()) PyErr_WriteUnraisable(o);") "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
code.putln( code.putln(
"--o->ob_refcnt;") "--Py_REFCNT(o);")
code.putln( code.putln(
"PyErr_Restore(etype, eval, etb);") "PyErr_Restore(etype, eval, etb);")
code.putln( code.putln(
...@@ -905,7 +971,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -905,7 +971,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln( code.putln(
"PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;") "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
code.putln( code.putln(
"r = o->ob_type->tp_as_mapping->mp_subscript(o, x);") "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);")
code.putln( code.putln(
"Py_DECREF(x);") "Py_DECREF(x);")
code.putln( code.putln(
...@@ -936,7 +1002,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -936,7 +1002,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln( code.putln(
"PyErr_Format(PyExc_NotImplementedError,") "PyErr_Format(PyExc_NotImplementedError,")
code.putln( code.putln(
' "Subscript assignment not supported by %s", o->ob_type->tp_name);') ' "Subscript assignment not supported by %s", Py_TYPE(o)->tp_name);')
code.putln( code.putln(
"return -1;") "return -1;")
code.putln( code.putln(
...@@ -953,7 +1019,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -953,7 +1019,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln( code.putln(
"PyErr_Format(PyExc_NotImplementedError,") "PyErr_Format(PyExc_NotImplementedError,")
code.putln( code.putln(
' "Subscript deletion not supported by %s", o->ob_type->tp_name);') ' "Subscript deletion not supported by %s", Py_TYPE(o)->tp_name);')
code.putln( code.putln(
"return -1;") "return -1;")
code.putln( code.putln(
...@@ -1003,7 +1069,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1003,7 +1069,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln( code.putln(
"PyErr_Format(PyExc_NotImplementedError,") "PyErr_Format(PyExc_NotImplementedError,")
code.putln( code.putln(
' "2-element slice assignment not supported by %s", o->ob_type->tp_name);') ' "2-element slice assignment not supported by %s", Py_TYPE(o)->tp_name);')
code.putln( code.putln(
"return -1;") "return -1;")
code.putln( code.putln(
...@@ -1020,7 +1086,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1020,7 +1086,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln( code.putln(
"PyErr_Format(PyExc_NotImplementedError,") "PyErr_Format(PyExc_NotImplementedError,")
code.putln( code.putln(
' "2-element slice deletion not supported by %s", o->ob_type->tp_name);') ' "2-element slice deletion not supported by %s", Py_TYPE(o)->tp_name);')
code.putln( code.putln(
"return -1;") "return -1;")
code.putln( code.putln(
...@@ -1261,9 +1327,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1261,9 +1327,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
#code.putln(header % scope.parent_type.typeobj_cname) #code.putln(header % scope.parent_type.typeobj_cname)
code.putln(header % type.typeobj_cname) code.putln(header % type.typeobj_cname)
code.putln( code.putln(
"PyObject_HEAD_INIT(0)") "PyVarObject_HEAD_INIT(0, 0)")
code.putln(
"0, /*ob_size*/")
code.putln( code.putln(
'"%s.%s", /*tp_name*/' % ( '"%s.%s", /*tp_name*/' % (
self.full_module_name, scope.class_name)) self.full_module_name, scope.class_name))
...@@ -1339,26 +1403,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1339,26 +1403,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"{0, 0, 0, 0, 0}") "{0, 0, 0, 0, 0}")
code.putln( code.putln(
"};") "};")
def generate_interned_name_table(self, env, code):
code.mark_pos(None)
items = env.intern_map.items()
if items:
items.sort()
code.putln("")
code.putln(
"static __Pyx_InternTabEntry %s[] = {" %
Naming.intern_tab_cname)
for (name, cname) in items:
code.putln(
'{&%s, "%s"},' % (
cname,
name))
code.putln(
"{0, 0}")
code.putln(
"};")
def generate_py_string_table(self, env, code): def generate_py_string_table(self, env, code):
entries = env.all_pystring_entries entries = env.all_pystring_entries
if entries: if entries:
...@@ -1368,18 +1413,19 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1368,18 +1413,19 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
Naming.stringtab_cname) Naming.stringtab_cname)
for entry in entries: for entry in entries:
code.putln( code.putln(
"{&%s, %s, sizeof(%s), %d}," % ( "{&%s, %s, sizeof(%s), %d, %d, %d}," % (
entry.pystring_cname, entry.pystring_cname,
entry.cname, entry.cname,
entry.cname, entry.cname,
entry.type.is_unicode entry.type.is_unicode,
entry.is_interned,
entry.is_identifier
)) ))
code.putln( code.putln(
"{0, 0, 0, 0}") "{0, 0, 0, 0, 0}")
code.putln( code.putln(
"};") "};")
def generate_filename_init_prototype(self, code): def generate_filename_init_prototype(self, code):
code.putln(""); code.putln("");
code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname) code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
...@@ -1390,6 +1436,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1390,6 +1436,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("%s; /*proto*/" % header) code.putln("%s; /*proto*/" % header)
code.putln("%s {" % header) code.putln("%s {" % header)
code.put_var_declarations(env.temp_entries) code.put_var_declarations(env.temp_entries)
code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
code.putln("/*--- Libary function declarations ---*/") code.putln("/*--- Libary function declarations ---*/")
env.generate_library_function_declarations(code) env.generate_library_function_declarations(code)
...@@ -1408,7 +1455,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1408,7 +1455,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("/*--- Builtin init code ---*/") code.putln("/*--- Builtin init code ---*/")
self.generate_builtin_init_code(env, code) self.generate_builtin_init_code(env, code)
code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
code.putln("%s = 0;" % Naming.skip_dispatch_cname); code.putln("%s = 0;" % Naming.skip_dispatch_cname);
code.putln("/*--- Global init code ---*/") code.putln("/*--- Global init code ---*/")
...@@ -1469,9 +1515,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1469,9 +1515,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("/*--- Intern cleanup code ---*/") code.putln("/*--- Intern cleanup code ---*/")
for entry in env.pynum_entries: for entry in env.pynum_entries:
code.put_var_decref_clear(entry) code.put_var_decref_clear(entry)
if env.intern_map: if env.all_pystring_entries:
for name, cname in env.intern_map.items(): for entry in env.all_pystring_entries:
code.put_decref_clear(cname, PyrexTypes.py_object_type) if entry.is_interned:
code.put_decref_clear(
entry.pystring_cname, PyrexTypes.py_object_type)
code.putln("Py_INCREF(Py_None); return Py_None;") code.putln("Py_INCREF(Py_None); return Py_None;")
code.putln('}') code.putln('}')
...@@ -1496,7 +1544,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1496,7 +1544,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
env.module_cname, env.module_cname,
code.error_goto(self.pos))); code.error_goto(self.pos)));
code.putln( code.putln(
'%s = PyImport_AddModule("__builtin__");' % '%s = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME);' %
Naming.builtins_cname) Naming.builtins_cname)
code.putln( code.putln(
"if (!%s) %s;" % ( "if (!%s) %s;" % (
...@@ -1523,12 +1571,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1523,12 +1571,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
entry.cname, entry.cname,
entry.init, entry.init,
code.error_goto_if_null(entry.cname, self.pos))) code.error_goto_if_null(entry.cname, self.pos)))
if env.intern_map:
env.use_utility_code(Nodes.init_intern_tab_utility_code);
code.putln(
"if (__Pyx_InternStrings(%s) < 0) %s;" % (
Naming.intern_tab_cname,
code.error_goto(self.pos)))
def generate_string_init_code(self, env, code): def generate_string_init_code(self, env, code):
if env.all_pystring_entries: if env.all_pystring_entries:
...@@ -1542,23 +1584,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1542,23 +1584,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# Lookup and cache builtin objects. # Lookup and cache builtin objects.
if Options.cache_builtins: if Options.cache_builtins:
for entry in env.cached_builtins: for entry in env.cached_builtins:
if Options.intern_names: #assert entry.interned_cname is not None
#assert entry.interned_cname is not None code.putln(
code.putln( '%s = __Pyx_GetName(%s, %s); if (!%s) %s' % (
'%s = __Pyx_GetName(%s, %s); if (!%s) %s' % ( entry.cname,
entry.cname, Naming.builtins_cname,
Naming.builtins_cname, entry.interned_cname,
entry.interned_cname, entry.cname,
entry.cname, code.error_goto(entry.pos)))
code.error_goto(entry.pos)))
else:
code.putln(
'%s = __Pyx_GetName(%s, "%s"); if (!%s) %s' % (
entry.cname,
Naming.builtins_cname,
entry.name,
entry.cname,
code.error_goto(entry.pos)))
def generate_global_init_code(self, env, code): def generate_global_init_code(self, env, code):
# Generate code to initialise global PyObject * # Generate code to initialise global PyObject *
...@@ -1657,17 +1690,35 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1657,17 +1690,35 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
env.use_utility_code(Nodes.get_vtable_utility_code) env.use_utility_code(Nodes.get_vtable_utility_code)
env.types_imported[type] = 1 env.types_imported[type] = 1
py3_type_name_map = {'str' : 'bytes', 'unicode' : 'str'}
def generate_type_import_call(self, type, code, error_code): def generate_type_import_call(self, type, code, error_code):
if type.typedef_flag: if type.typedef_flag:
objstruct = type.objstruct_cname objstruct = type.objstruct_cname
else: else:
objstruct = "struct %s" % type.objstruct_cname objstruct = "struct %s" % type.objstruct_cname
code.putln('%s = __Pyx_ImportType("%s", "%s", sizeof(%s)); %s' % ( module_name = type.module_name
type.typeptr_cname, if module_name not in ('__builtin__', 'builtins'):
type.module_name, module_name = '"%s"' % module_name
type.name, else:
objstruct, module_name = '__Pyx_BUILTIN_MODULE_NAME'
error_code)) if type.name in self.py3_type_name_map:
code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
type.typeptr_cname,
module_name,
self.py3_type_name_map[type.name],
objstruct,
error_code))
code.putln("#else")
code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s)); %s' % (
type.typeptr_cname,
module_name,
type.name,
objstruct,
error_code))
if type.name in self.py3_type_name_map:
code.putln("#endif")
def generate_type_ready_code(self, env, entry, code): def generate_type_ready_code(self, env, entry, code):
# Generate a call to PyType_Ready for an extension # Generate a call to PyType_Ready for an extension
...@@ -1759,6 +1810,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1759,6 +1810,16 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# #
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
builtin_module_name_utility_code = [
"""\
#if PY_MAJOR_VERSION < 3
#define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
#else
#define __Pyx_BUILTIN_MODULE_NAME "builtins"
#endif
"""]
import_module_utility_code = [ import_module_utility_code = [
""" """
static PyObject *__Pyx_ImportModule(char *name); /*proto*/ static PyObject *__Pyx_ImportModule(char *name); /*proto*/
...@@ -1768,8 +1829,12 @@ static PyObject *__Pyx_ImportModule(char *name); /*proto*/ ...@@ -1768,8 +1829,12 @@ static PyObject *__Pyx_ImportModule(char *name); /*proto*/
static PyObject *__Pyx_ImportModule(char *name) { static PyObject *__Pyx_ImportModule(char *name) {
PyObject *py_name = 0; PyObject *py_name = 0;
PyObject *py_module = 0; PyObject *py_module = 0;
#if PY_MAJOR_VERSION < 3
py_name = PyString_FromString(name); py_name = PyString_FromString(name);
#else
py_name = PyUnicode_FromString(name);
#endif
if (!py_name) if (!py_name)
goto bad; goto bad;
py_module = PyImport_Import(py_name); py_module = PyImport_Import(py_name);
...@@ -1796,8 +1861,12 @@ static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, ...@@ -1796,8 +1861,12 @@ static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
PyObject *py_module = 0; PyObject *py_module = 0;
PyObject *result = 0; PyObject *result = 0;
PyObject *py_name = 0; PyObject *py_name = 0;
#if PY_MAJOR_VERSION < 3
py_name = PyString_FromString(module_name); py_name = PyString_FromString(module_name);
#else
py_name = PyUnicode_FromString(module_name);
#endif
if (!py_name) if (!py_name)
goto bad; goto bad;
......
...@@ -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"
......
...@@ -245,28 +245,28 @@ class BlockNode: ...@@ -245,28 +245,28 @@ class BlockNode:
for entry in env.const_entries: for entry in env.const_entries:
if not entry.is_interned: if not entry.is_interned:
code.put_var_declaration(entry, static = 1) code.put_var_declaration(entry, static = 1)
def generate_interned_name_decls(self, env, code): def generate_interned_string_decls(self, env, code):
# Flush accumulated interned names from the global scope entries = env.global_scope().new_interned_string_entries
# and generate declarations for them. if entries:
genv = env.global_scope() code.putln("")
intern_map = genv.intern_map for entry in entries:
names = genv.interned_names code.put_var_declaration(entry, static = 1)
if names:
code.putln("") code.putln("")
for name in names: for entry in entries:
code.putln( code.putln(
"static PyObject *%s;" % intern_map[name]) "static PyObject *%s;" % entry.pystring_cname)
del names[:] del entries[:]
def generate_py_string_decls(self, env, code): def generate_py_string_decls(self, env, code):
entries = env.pystring_entries entries = env.pystring_entries
if entries: if entries:
code.putln("") code.putln("")
for entry in entries: for entry in entries:
code.putln( if not entry.is_interned:
"static PyObject *%s;" % entry.pystring_cname) code.putln(
"static PyObject *%s;" % entry.pystring_cname)
def generate_interned_num_decls(self, env, code): def generate_interned_num_decls(self, env, code):
# Flush accumulated interned nums from the global scope # Flush accumulated interned nums from the global scope
# and generate declarations for them. # and generate declarations for them.
...@@ -893,7 +893,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -893,7 +893,7 @@ class FuncDefNode(StatNode, BlockNode):
# if we supported them, which we probably won't. # if we supported them, which we probably won't.
# ----- Top-level constants used by this function # ----- Top-level constants used by this function
self.generate_interned_num_decls(lenv, code) self.generate_interned_num_decls(lenv, code)
self.generate_interned_name_decls(lenv, code) self.generate_interned_string_decls(lenv, code)
self.generate_py_string_decls(lenv, code) self.generate_py_string_decls(lenv, code)
self.generate_cached_builtins_decls(lenv, code) self.generate_cached_builtins_decls(lenv, code)
#code.putln("") #code.putln("")
...@@ -1100,8 +1100,8 @@ class CFuncDefNode(FuncDefNode): ...@@ -1100,8 +1100,8 @@ class CFuncDefNode(FuncDefNode):
self.entry.as_variable = self.py_func.entry self.entry.as_variable = self.py_func.entry
# Reset scope entry the above cfunction # Reset scope entry the above cfunction
env.entries[name] = self.entry env.entries[name] = self.entry
if Options.intern_names: self.py_func.interned_attr_cname = env.intern_identifier(
self.py_func.interned_attr_cname = env.intern(self.py_func.entry.name) self.py_func.entry.name)
if not env.is_module_scope or Options.lookup_module_cpdef: if not env.is_module_scope or Options.lookup_module_cpdef:
self.override = OverrideCheckNode(self.pos, py_func = self.py_func) self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
self.body = StatListNode(self.pos, stats=[self.override, self.body]) self.body = StatListNode(self.pos, stats=[self.override, self.body])
...@@ -1938,15 +1938,12 @@ class OverrideCheckNode(StatNode): ...@@ -1938,15 +1938,12 @@ class OverrideCheckNode(StatNode):
if self.py_func.is_module_scope: if self.py_func.is_module_scope:
code.putln("else {") code.putln("else {")
else: else:
code.putln("else if (unlikely(%s->ob_type->tp_dictoffset != 0)) {" % self_arg) code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
err = code.error_goto_if_null(self_arg, self.pos) err = code.error_goto_if_null(self_arg, self.pos)
# need to get attribute manually--scope would return cdef method # need to get attribute manually--scope would return cdef method
if Options.intern_names: code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result_code, self_arg, self.py_func.interned_attr_cname, err))
code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result_code, self_arg, self.py_func.interned_attr_cname, err))
else:
code.putln('%s = PyObject_GetAttrString(%s, "%s"); %s' % (self.func_node.result_code, self_arg, self.py_func.entry.name, err))
# It appears that this type is not anywhere exposed in the Python/C API # It appears that this type is not anywhere exposed in the Python/C API
is_builtin_function_or_method = '(strcmp(%s->ob_type->tp_name, "builtin_function_or_method") == 0)' % self.func_node.result_code is_builtin_function_or_method = '(strcmp(Py_TYPE(%s)->tp_name, "builtin_function_or_method") == 0)' % self.func_node.result_code
is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result_code, self.py_func.entry.func_cname) is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result_code, self.py_func.entry.func_cname)
code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden)) code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
self.body.generate_execution_code(code) self.body.generate_execution_code(code)
...@@ -1985,8 +1982,7 @@ class PyClassDefNode(StatNode, BlockNode): ...@@ -1985,8 +1982,7 @@ class PyClassDefNode(StatNode, BlockNode):
doc_node = ExprNodes.StringNode(pos, value = doc) doc_node = ExprNodes.StringNode(pos, value = doc)
else: else:
doc_node = None doc_node = None
self.classobj = ExprNodes.ClassNode(pos, self.classobj = ExprNodes.ClassNode(pos, name = name,
name = ExprNodes.StringNode(pos, value = name),
bases = bases, dict = self.dict, doc = doc_node) bases = bases, dict = self.dict, doc = doc_node)
self.target = ExprNodes.NameNode(pos, name = name) self.target = ExprNodes.NameNode(pos, name = name)
...@@ -2139,10 +2135,11 @@ class PropertyNode(StatNode): ...@@ -2139,10 +2135,11 @@ class PropertyNode(StatNode):
entry = env.declare_property(self.name, self.doc, self.pos) entry = env.declare_property(self.name, self.doc, self.pos)
if entry: if entry:
if self.doc and Options.docstrings: if self.doc and Options.docstrings:
doc_entry = env.get_string_const(self.doc) doc_entry = env.get_string_const(
self.doc, identifier = False)
entry.doc_cname = doc_entry.cname entry.doc_cname = doc_entry.cname
self.body.analyse_declarations(entry.scope) self.body.analyse_declarations(entry.scope)
def analyse_expressions(self, env): def analyse_expressions(self, env):
self.body.analyse_expressions(env) self.body.analyse_expressions(env)
...@@ -2513,12 +2510,17 @@ class InPlaceAssignmentNode(AssignmentNode): ...@@ -2513,12 +2510,17 @@ class InPlaceAssignmentNode(AssignmentNode):
class PrintStatNode(StatNode): class PrintStatNode(StatNode):
# print statement # print statement
# #
# args [ExprNode] # arg_tuple TupleNode
# ends_with_comma boolean # append_newline boolean
child_attrs = ["args"] child_attrs = ["arg_tuple"]
def analyse_expressions(self, env): def analyse_expressions(self, env):
self.arg_tuple.analyse_expressions(env)
self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
self.arg_tuple.release_temp(env)
env.use_utility_code(printing_utility_code)
return
for i in range(len(self.args)): for i in range(len(self.args)):
arg = self.args[i] arg = self.args[i]
arg.analyse_types(env) arg.analyse_types(env)
...@@ -2527,24 +2529,18 @@ class PrintStatNode(StatNode): ...@@ -2527,24 +2529,18 @@ class PrintStatNode(StatNode):
arg.release_temp(env) arg.release_temp(env)
self.args[i] = arg self.args[i] = arg
#env.recycle_pending_temps() # TEMPORARY #env.recycle_pending_temps() # TEMPORARY
env.use_utility_code(printing_utility_code)
def generate_execution_code(self, code): def generate_execution_code(self, code):
for arg in self.args: self.arg_tuple.generate_evaluation_code(code)
arg.generate_evaluation_code(code) code.putln(
code.putln( "if (__Pyx_Print(%s, %d) < 0) %s" % (
"if (__Pyx_PrintItem(%s) < 0) %s" % ( self.arg_tuple.py_result(),
arg.py_result(), self.append_newline,
code.error_goto(self.pos))) code.error_goto(self.pos)))
arg.generate_disposal_code(code) self.arg_tuple.generate_disposal_code(code)
if not self.ends_with_comma:
code.putln(
"if (__Pyx_PrintNewline() < 0) %s" %
code.error_goto(self.pos))
def annotate(self, code): def annotate(self, code):
for arg in self.args: self.arg_tuple.annotate(code)
arg.annotate(code)
class DelStatNode(StatNode): class DelStatNode(StatNode):
...@@ -3005,15 +3001,16 @@ class ForInStatNode(LoopNode, StatNode): ...@@ -3005,15 +3001,16 @@ class ForInStatNode(LoopNode, StatNode):
else: else:
step = args[2] step = args[2]
if isinstance(step, ExprNodes.UnaryMinusNode) and isinstance(step.operand, ExprNodes.IntNode): if isinstance(step, ExprNodes.UnaryMinusNode) and isinstance(step.operand, ExprNodes.IntNode):
step = ExprNodes.IntNode(pos = step.pos, value=-int(step.operand.value)) step = ExprNodes.IntNode(pos = step.pos, value=str(-int(step.operand.value, 0)))
if isinstance(step, ExprNodes.IntNode): if isinstance(step, ExprNodes.IntNode):
if step.value > 0: step_value = int(step.value, 0)
if step_value > 0:
self.step = step self.step = step
self.relation1 = '<=' self.relation1 = '<='
self.relation2 = '<' self.relation2 = '<'
return True return True
elif step.value < 0: elif step_value < 0:
self.step = ExprNodes.IntNode(pos = step.pos, value=-int(step.value)) self.step = ExprNodes.IntNode(pos = step.pos, value=str(-step_value))
self.relation1 = '>=' self.relation1 = '>='
self.relation2 = '>' self.relation2 = '>'
return True return True
...@@ -3628,7 +3625,7 @@ class CImportStatNode(StatNode): ...@@ -3628,7 +3625,7 @@ class CImportStatNode(StatNode):
return return
module_scope = env.find_module(self.module_name, self.pos) module_scope = env.find_module(self.module_name, self.pos)
if "." in self.module_name: if "." in self.module_name:
names = self.module_name.split(".") names = [EncodedString(name) for name in self.module_name.split(".")]
top_name = names[0] top_name = names[0]
top_module_scope = env.context.find_submodule(top_name) top_module_scope = env.context.find_submodule(top_name)
module_scope = top_module_scope module_scope = top_module_scope
...@@ -3699,8 +3696,8 @@ class FromImportStatNode(StatNode): ...@@ -3699,8 +3696,8 @@ class FromImportStatNode(StatNode):
self.item.allocate_temp(env) self.item.allocate_temp(env)
self.interned_items = [] self.interned_items = []
for name, target in self.items: for name, target in self.items:
if Options.intern_names: self.interned_items.append(
self.interned_items.append((env.intern(name), target)) (env.intern_identifier(name), target))
target.analyse_target_expression(env, None) target.analyse_target_expression(env, None)
#target.release_target_temp(env) # was release_temp ?!? #target.release_target_temp(env) # was release_temp ?!?
self.module.release_temp(env) self.module.release_temp(env)
...@@ -3708,24 +3705,14 @@ class FromImportStatNode(StatNode): ...@@ -3708,24 +3705,14 @@ class FromImportStatNode(StatNode):
def generate_execution_code(self, code): def generate_execution_code(self, code):
self.module.generate_evaluation_code(code) self.module.generate_evaluation_code(code)
if Options.intern_names: for cname, target in self.interned_items:
for cname, target in self.interned_items: code.putln(
code.putln( '%s = PyObject_GetAttr(%s, %s); %s' % (
'%s = PyObject_GetAttr(%s, %s); %s' % ( self.item.result_code,
self.item.result_code, self.module.py_result(),
self.module.py_result(), cname,
cname, code.error_goto_if_null(self.item.result_code, self.pos)))
code.error_goto_if_null(self.item.result_code, self.pos))) target.generate_assignment_code(self.item, code)
target.generate_assignment_code(self.item, code)
else:
for name, target in self.items:
code.putln(
'%s = PyObject_GetAttrString(%s, "%s"); %s' % (
self.item.result_code,
self.module.py_result(),
name,
code.error_goto_if_null(self.item.result_code, self.pos)))
target.generate_assignment_code(self.item, code)
self.module.generate_disposal_code(code) self.module.generate_disposal_code(code)
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
...@@ -3744,8 +3731,7 @@ utility_function_predeclarations = \ ...@@ -3744,8 +3731,7 @@ utility_function_predeclarations = \
#define INLINE #define INLINE
#endif #endif
typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/ typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
typedef struct {PyObject **p; char *s; long n; int is_unicode;} __Pyx_StringTabEntry; /*proto*/
""" + """ """ + """
...@@ -3788,9 +3774,13 @@ else: ...@@ -3788,9 +3774,13 @@ else:
printing_utility_code = [ printing_utility_code = [
""" """
static int __Pyx_PrintItem(PyObject *); /*proto*/ static int __Pyx_Print(PyObject *, int); /*proto*/
static int __Pyx_PrintNewline(void); /*proto*/ #if PY_MAJOR_VERSION >= 3
""",r""" static PyObject* %s = 0;
static PyObject* %s = 0;
#endif
""" % (Naming.print_function, Naming.print_function_kwargs), r"""
#if PY_MAJOR_VERSION < 3
static PyObject *__Pyx_GetStdout(void) { static PyObject *__Pyx_GetStdout(void) {
PyObject *f = PySys_GetObject("stdout"); PyObject *f = PySys_GetObject("stdout");
if (!f) { if (!f) {
...@@ -3799,39 +3789,75 @@ static PyObject *__Pyx_GetStdout(void) { ...@@ -3799,39 +3789,75 @@ static PyObject *__Pyx_GetStdout(void) {
return f; return f;
} }
static int __Pyx_PrintItem(PyObject *v) { static int __Pyx_Print(PyObject *arg_tuple, int newline) {
PyObject *f; PyObject *f;
PyObject* v;
int i;
if (!(f = __Pyx_GetStdout())) if (!(f = __Pyx_GetStdout()))
return -1; return -1;
if (PyFile_SoftSpace(f, 1)) { for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
if (PyFile_WriteString(" ", f) < 0) if (PyFile_SoftSpace(f, 1)) {
if (PyFile_WriteString(" ", f) < 0)
return -1;
}
v = PyTuple_GET_ITEM(arg_tuple, i);
if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
return -1; return -1;
if (PyString_Check(v)) {
char *s = PyString_AsString(v);
Py_ssize_t len = PyString_Size(v);
if (len > 0 &&
isspace(Py_CHARMASK(s[len-1])) &&
s[len-1] != ' ')
PyFile_SoftSpace(f, 0);
}
} }
if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0) if (newline) {
return -1; if (PyFile_WriteString("\n", f) < 0)
if (PyString_Check(v)) { return -1;
char *s = PyString_AsString(v); PyFile_SoftSpace(f, 0);
Py_ssize_t len = PyString_Size(v);
if (len > 0 &&
isspace(Py_CHARMASK(s[len-1])) &&
s[len-1] != ' ')
PyFile_SoftSpace(f, 0);
} }
return 0; return 0;
} }
static int __Pyx_PrintNewline(void) { #else /* Python 3 has a print function */
PyObject *f; static int __Pyx_Print(PyObject *arg_tuple, int newline) {
PyObject* kwargs = 0;
if (!(f = __Pyx_GetStdout())) PyObject* result = 0;
return -1; PyObject* end_string;
if (PyFile_WriteString("\n", f) < 0) if (!%(PRINT_FUNCTION)s) {
%(PRINT_FUNCTION)s = PyObject_GetAttrString(%(BUILTINS)s, "print");
if (!%(PRINT_FUNCTION)s)
return -1;
}
if (!newline) {
if (!%(PRINT_KWARGS)s) {
%(PRINT_KWARGS)s = PyDict_New();
if (!%(PRINT_KWARGS)s)
return -1;
end_string = PyUnicode_FromStringAndSize(" ", 1);
if (!end_string)
return -1;
if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
Py_DECREF(end_string);
return -1;
}
Py_DECREF(end_string);
}
kwargs = %(PRINT_KWARGS)s;
}
result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
if (!result)
return -1; return -1;
PyFile_SoftSpace(f, 0); Py_DECREF(result);
return 0; return 0;
} }
"""] #endif
""" % {'BUILTINS' : Naming.builtins_cname,
'PRINT_FUNCTION' : Naming.print_function,
'PRINT_KWARGS' : Naming.print_function_kwargs}
]
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
...@@ -3887,7 +3913,7 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) { ...@@ -3887,7 +3913,7 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
goto raise_error; goto raise_error;
} }
#else #else
type = (PyObject*) type->ob_type; type = (PyObject*) Py_TYPE(type);
Py_INCREF(type); Py_INCREF(type);
if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
...@@ -3937,14 +3963,14 @@ static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed ...@@ -3937,14 +3963,14 @@ static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed
} }
if (none_allowed && obj == Py_None) return 1; if (none_allowed && obj == Py_None) return 1;
else if (exact) { else if (exact) {
if (obj->ob_type == type) return 1; if (Py_TYPE(obj) == type) return 1;
} }
else { else {
if (PyObject_TypeCheck(obj, type)) return 1; if (PyObject_TypeCheck(obj, type)) return 1;
} }
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"Argument '%s' has incorrect type (expected %s, got %s)", "Argument '%s' has incorrect type (expected %s, got %s)",
name, type->tp_name, obj->ob_type->tp_name); name, type->tp_name, Py_TYPE(obj)->tp_name);
return 0; return 0;
} }
"""] """]
...@@ -4025,7 +4051,11 @@ static int __Pyx_CheckKeywordStrings( ...@@ -4025,7 +4051,11 @@ static int __Pyx_CheckKeywordStrings(
PyObject* key = 0; PyObject* key = 0;
Py_ssize_t pos = 0; Py_ssize_t pos = 0;
while (PyDict_Next(kwdict, &pos, &key, 0)) { while (PyDict_Next(kwdict, &pos, &key, 0)) {
#if PY_MAJOR_VERSION < 3
if (unlikely(!PyString_Check(key))) { if (unlikely(!PyString_Check(key))) {
#else
if (unlikely(!PyUnicode_Check(key))) {
#endif
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"%s() keywords must be strings", function_name); "%s() keywords must be strings", function_name);
return 0; return 0;
...@@ -4034,7 +4064,11 @@ static int __Pyx_CheckKeywordStrings( ...@@ -4034,7 +4064,11 @@ static int __Pyx_CheckKeywordStrings(
if (unlikely(!kw_allowed) && unlikely(key)) { if (unlikely(!kw_allowed) && unlikely(key)) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"'%s' is an invalid keyword argument for this function", "'%s' is an invalid keyword argument for this function",
#if PY_MAJOR_VERSION < 3
PyString_AsString(key)); PyString_AsString(key));
#else
PyUnicode_AsString(key));
#endif
return 0; return 0;
} }
return 1; return 1;
...@@ -4082,7 +4116,11 @@ static int __Pyx_SplitKeywords( ...@@ -4082,7 +4116,11 @@ static int __Pyx_SplitKeywords(
if (!*kwds2) if (!*kwds2)
goto bad; goto bad;
for (i = 0, p = kwd_list; *p; i++, p++) { for (i = 0, p = kwd_list; *p; i++, p++) {
#if PY_MAJOR_VERSION < 3
s = PyString_FromString(*p); s = PyString_FromString(*p);
#else
s = PyUnicode_FromString(*p);
#endif
x = PyDict_GetItem(*kwds, s); x = PyDict_GetItem(*kwds, s);
if (x) { if (x) {
if (PyDict_SetItem(kwds1, s, x) < 0) if (PyDict_SetItem(kwds1, s, x) < 0)
...@@ -4162,7 +4200,11 @@ static void __Pyx_WriteUnraisable(char *name) { ...@@ -4162,7 +4200,11 @@ static void __Pyx_WriteUnraisable(char *name) {
PyObject *old_exc, *old_val, *old_tb; PyObject *old_exc, *old_val, *old_tb;
PyObject *ctx; PyObject *ctx;
PyErr_Fetch(&old_exc, &old_val, &old_tb); PyErr_Fetch(&old_exc, &old_val, &old_tb);
#if PY_MAJOR_VERSION < 3
ctx = PyString_FromString(name); ctx = PyString_FromString(name);
#else
ctx = PyUnicode_FromString(name);
#endif
PyErr_Restore(old_exc, old_val, old_tb); PyErr_Restore(old_exc, old_val, old_tb);
if (!ctx) if (!ctx)
ctx = Py_None; ctx = Py_None;
...@@ -4187,22 +4229,37 @@ static void __Pyx_AddTraceback(char *funcname) { ...@@ -4187,22 +4229,37 @@ static void __Pyx_AddTraceback(char *funcname) {
PyObject *empty_string = 0; PyObject *empty_string = 0;
PyCodeObject *py_code = 0; PyCodeObject *py_code = 0;
PyFrameObject *py_frame = 0; PyFrameObject *py_frame = 0;
#if PY_MAJOR_VERSION < 3
py_srcfile = PyString_FromString(%(FILENAME)s); py_srcfile = PyString_FromString(%(FILENAME)s);
#else
py_srcfile = PyUnicode_FromString(%(FILENAME)s);
#endif
if (!py_srcfile) goto bad; if (!py_srcfile) goto bad;
if (%(CLINENO)s) { if (%(CLINENO)s) {
#if PY_MAJOR_VERSION < 3
py_funcname = PyString_FromFormat( "%%s (%%s:%%u)", funcname, %(CFILENAME)s, %(CLINENO)s); py_funcname = PyString_FromFormat( "%%s (%%s:%%u)", funcname, %(CFILENAME)s, %(CLINENO)s);
#else
py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%u)", funcname, %(CFILENAME)s, %(CLINENO)s);
#endif
} }
else { else {
#if PY_MAJOR_VERSION < 3
py_funcname = PyString_FromString(funcname); py_funcname = PyString_FromString(funcname);
#else
py_funcname = PyUnicode_FromString(funcname);
#endif
} }
if (!py_funcname) goto bad; if (!py_funcname) goto bad;
py_globals = PyModule_GetDict(%(GLOBALS)s); py_globals = PyModule_GetDict(%(GLOBALS)s);
if (!py_globals) goto bad; if (!py_globals) goto bad;
empty_string = PyString_FromString(""); empty_string = PyString_FromStringAndSize("", 0);
if (!empty_string) goto bad; if (!empty_string) goto bad;
py_code = PyCode_New( py_code = PyCode_New(
0, /*int argcount,*/ 0, /*int argcount,*/
#if PY_MAJOR_VERSION >= 3
0, /*int kwonlyargcount,*/
#endif
0, /*int nlocals,*/ 0, /*int nlocals,*/
0, /*int stacksize,*/ 0, /*int stacksize,*/
0, /*int flags,*/ 0, /*int flags,*/
...@@ -4298,32 +4355,26 @@ done: ...@@ -4298,32 +4355,26 @@ done:
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
init_intern_tab_utility_code = [
"""
static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/
""","""
static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
while (t->p) {
*t->p = PyString_InternFromString(t->s);
if (!*t->p)
return -1;
++t;
}
return 0;
}
"""]
#------------------------------------------------------------------------------------
init_string_tab_utility_code = [ init_string_tab_utility_code = [
""" """
static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
""",""" ""","""
static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
while (t->p) { while (t->p) {
if (t->is_unicode) { #if PY_MAJOR_VERSION < 3
if (t->is_unicode && (!t->is_identifier)) {
*t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
} else { } else if (t->intern) {
*t->p = PyString_InternFromString(t->s);
}
#else /* Python 3+ has unicode identifiers */
if (t->is_identifier || (t->is_unicode && t->intern)) {
*t->p = PyUnicode_InternFromString(t->s);
} else if (t->is_unicode) {
*t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
}
#endif
else {
*t->p = PyString_FromStringAndSize(t->s, t->n - 1); *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
} }
if (!*t->p) if (!*t->p)
......
...@@ -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
......
...@@ -11,6 +11,7 @@ import ExprNodes ...@@ -11,6 +11,7 @@ import ExprNodes
from ModuleNode import ModuleNode from ModuleNode import ModuleNode
from Errors import error, InternalError from Errors import error, InternalError
from Cython import Utils from Cython import Utils
import Future
def p_ident(s, message = "Expected an identifier"): def p_ident(s, message = "Expected an identifier"):
if s.sy == 'IDENT': if s.sy == 'IDENT':
...@@ -260,7 +261,7 @@ def p_trailer(s, node1): ...@@ -260,7 +261,7 @@ def p_trailer(s, node1):
return p_index(s, node1) return p_index(s, node1)
else: # s.sy == '.' else: # s.sy == '.'
s.next() s.next()
name = p_ident(s) name = Utils.EncodedString( p_ident(s) )
return ExprNodes.AttributeNode(pos, return ExprNodes.AttributeNode(pos,
obj = node1, attribute = name) obj = node1, attribute = name)
...@@ -283,8 +284,7 @@ def p_call(s, function): ...@@ -283,8 +284,7 @@ def p_call(s, function):
s.error("Expected an identifier before '='", s.error("Expected an identifier before '='",
pos = arg.pos) pos = arg.pos)
encoded_name = Utils.EncodedString(arg.name) encoded_name = Utils.EncodedString(arg.name)
encoded_name.encoding = s.source_encoding keyword = ExprNodes.IdentifierStringNode(arg.pos,
keyword = ExprNodes.StringNode(arg.pos,
value = encoded_name) value = encoded_name)
arg = p_simple_expr(s) arg = p_simple_expr(s)
keyword_args.append((keyword, arg)) keyword_args.append((keyword, arg))
...@@ -469,7 +469,7 @@ def p_atom(s): ...@@ -469,7 +469,7 @@ def p_atom(s):
else: else:
return ExprNodes.StringNode(pos, value = value) return ExprNodes.StringNode(pos, value = value)
elif sy == 'IDENT': elif sy == 'IDENT':
name = s.systring name = Utils.EncodedString( s.systring )
s.next() s.next()
if name == "None": if name == "None":
return ExprNodes.NoneNode(pos) return ExprNodes.NoneNode(pos)
...@@ -502,13 +502,8 @@ def p_name(s, name): ...@@ -502,13 +502,8 @@ def p_name(s, name):
return ExprNodes.LongNode(pos, value = rep) return ExprNodes.LongNode(pos, value = rep)
elif isinstance(value, float): elif isinstance(value, float):
return ExprNodes.FloatNode(pos, value = rep) return ExprNodes.FloatNode(pos, value = rep)
elif isinstance(value, str):
sval = Utils.EncodedString(rep[1:-1])
sval.encoding = value.encoding
return ExprNodes.StringNode(pos, value = sval)
elif isinstance(value, unicode): elif isinstance(value, unicode):
sval = Utils.EncodedString(rep[2:-1]) return ExprNodes.StringNode(pos, value = value)
return ExprNodes.StringNode(pos, value = sval)
else: else:
error(pos, "Invalid type for compile-time constant: %s" error(pos, "Invalid type for compile-time constant: %s"
% value.__class__.__name__) % value.__class__.__name__)
...@@ -516,7 +511,7 @@ def p_name(s, name): ...@@ -516,7 +511,7 @@ def p_name(s, name):
def p_cat_string_literal(s): def p_cat_string_literal(s):
# A sequence of one or more adjacent string literals. # A sequence of one or more adjacent string literals.
# Returns (kind, value) where kind in ('', 'c', 'r', 'u') # Returns (kind, value) where kind in ('b', 'c', 'u')
kind, value = p_string_literal(s) kind, value = p_string_literal(s)
if kind != 'c': if kind != 'c':
strings = [value] strings = [value]
...@@ -541,13 +536,23 @@ def p_opt_string_literal(s): ...@@ -541,13 +536,23 @@ def p_opt_string_literal(s):
def p_string_literal(s): def p_string_literal(s):
# A single string or char literal. # A single string or char literal.
# Returns (kind, value) where kind in ('', 'c', 'r', 'u') # Returns (kind, value) where kind in ('b', 'c', 'u')
# s.sy == 'BEGIN_STRING' # s.sy == 'BEGIN_STRING'
pos = s.position() pos = s.position()
#is_raw = s.systring[:1].lower() == "r" is_raw = 0
kind = s.systring[:1].lower() kind = s.systring[:1].lower()
if kind not in "cru": if kind == 'r':
kind = ''
is_raw = 1
elif kind in 'ub':
is_raw = s.systring[1:2].lower() == 'r'
elif kind != 'c':
kind = '' kind = ''
if Future.unicode_literals in s.context.future_directives:
if kind == '':
kind = 'u'
elif kind == '':
kind = 'b'
chars = [] chars = []
while 1: while 1:
s.next() s.next()
...@@ -560,7 +565,7 @@ def p_string_literal(s): ...@@ -560,7 +565,7 @@ def p_string_literal(s):
chars.append(systr) chars.append(systr)
elif sy == 'ESCAPE': elif sy == 'ESCAPE':
systr = s.systring systr = s.systring
if kind == 'r': if is_raw:
if systr == '\\\n': if systr == '\\\n':
chars.append(r'\\\n') chars.append(r'\\\n')
elif systr == r'\"': elif systr == r'\"':
...@@ -823,17 +828,18 @@ def p_print_statement(s): ...@@ -823,17 +828,18 @@ def p_print_statement(s):
if s.sy == '>>': if s.sy == '>>':
s.error("'print >>' not yet implemented") s.error("'print >>' not yet implemented")
args = [] args = []
ewc = 0 ends_with_comma = 0
if s.sy not in ('NEWLINE', 'EOF'): if s.sy not in ('NEWLINE', 'EOF'):
args.append(p_simple_expr(s)) args.append(p_simple_expr(s))
while s.sy == ',': while s.sy == ',':
s.next() s.next()
if s.sy in ('NEWLINE', 'EOF'): if s.sy in ('NEWLINE', 'EOF'):
ewc = 1 ends_with_comma = 1
break break
args.append(p_simple_expr(s)) args.append(p_simple_expr(s))
return Nodes.PrintStatNode(pos, arg_tuple = ExprNodes.TupleNode(pos, args = args)
args = args, ends_with_comma = ewc) return Nodes.PrintStatNode(pos,
arg_tuple = arg_tuple, append_newline = not ends_with_comma)
def p_del_statement(s): def p_del_statement(s):
# s.sy == 'del' # s.sy == 'del'
...@@ -905,6 +911,7 @@ def p_import_statement(s): ...@@ -905,6 +911,7 @@ def p_import_statement(s):
items.append(p_dotted_name(s, as_allowed = 1)) items.append(p_dotted_name(s, as_allowed = 1))
stats = [] stats = []
for pos, target_name, dotted_name, as_name in items: for pos, target_name, dotted_name, as_name in items:
dotted_name = Utils.EncodedString(dotted_name)
if kind == 'cimport': if kind == 'cimport':
stat = Nodes.CImportStatNode(pos, stat = Nodes.CImportStatNode(pos,
module_name = dotted_name, module_name = dotted_name,
...@@ -915,19 +922,17 @@ def p_import_statement(s): ...@@ -915,19 +922,17 @@ def p_import_statement(s):
ExprNodes.StringNode(pos, value = Utils.EncodedString("*"))]) ExprNodes.StringNode(pos, value = Utils.EncodedString("*"))])
else: else:
name_list = None name_list = None
dotted_name = Utils.EncodedString(dotted_name)
dotted_name.encoding = s.source_encoding
stat = Nodes.SingleAssignmentNode(pos, stat = Nodes.SingleAssignmentNode(pos,
lhs = ExprNodes.NameNode(pos, lhs = ExprNodes.NameNode(pos,
name = as_name or target_name), name = as_name or target_name),
rhs = ExprNodes.ImportNode(pos, rhs = ExprNodes.ImportNode(pos,
module_name = ExprNodes.StringNode(pos, module_name = ExprNodes.IdentifierStringNode(
value = dotted_name), pos, value = dotted_name),
name_list = name_list)) name_list = name_list))
stats.append(stat) stats.append(stat)
return Nodes.StatListNode(pos, stats = stats) return Nodes.StatListNode(pos, stats = stats)
def p_from_import_statement(s): def p_from_import_statement(s, first_statement = 0):
# s.sy == 'from' # s.sy == 'from'
pos = s.position() pos = s.position()
s.next() s.next()
...@@ -944,7 +949,20 @@ def p_from_import_statement(s): ...@@ -944,7 +949,20 @@ def p_from_import_statement(s):
while s.sy == ',': while s.sy == ',':
s.next() s.next()
imported_names.append(p_imported_name(s)) imported_names.append(p_imported_name(s))
if kind == 'cimport': dotted_name = Utils.EncodedString(dotted_name)
if dotted_name == '__future__':
if not first_statement:
s.error("from __future__ imports must occur at the beginning of the file")
else:
for (name_pos, name, as_name) in imported_names:
try:
directive = getattr(Future, name)
except AttributeError:
s.error("future feature %s is not defined" % name)
break
s.context.future_directives.add(directive)
return Nodes.PassStatNode(pos)
elif kind == 'cimport':
for (name_pos, name, as_name) in imported_names: for (name_pos, name, as_name) in imported_names:
local_name = as_name or name local_name = as_name or name
s.add_type_name(local_name) s.add_type_name(local_name)
...@@ -956,9 +974,8 @@ def p_from_import_statement(s): ...@@ -956,9 +974,8 @@ def p_from_import_statement(s):
items = [] items = []
for (name_pos, name, as_name) in imported_names: for (name_pos, name, as_name) in imported_names:
encoded_name = Utils.EncodedString(name) encoded_name = Utils.EncodedString(name)
encoded_name.encoding = s.source_encoding
imported_name_strings.append( imported_name_strings.append(
ExprNodes.StringNode(name_pos, value = encoded_name)) ExprNodes.IdentifierStringNode(name_pos, value = encoded_name))
items.append( items.append(
(name, (name,
ExprNodes.NameNode(name_pos, ExprNodes.NameNode(name_pos,
...@@ -966,11 +983,9 @@ def p_from_import_statement(s): ...@@ -966,11 +983,9 @@ def p_from_import_statement(s):
import_list = ExprNodes.ListNode( import_list = ExprNodes.ListNode(
imported_names[0][0], args = imported_name_strings) imported_names[0][0], args = imported_name_strings)
dotted_name = Utils.EncodedString(dotted_name) dotted_name = Utils.EncodedString(dotted_name)
dotted_name.encoding = s.source_encoding
return Nodes.FromImportStatNode(pos, return Nodes.FromImportStatNode(pos,
module = ExprNodes.ImportNode(dotted_name_pos, module = ExprNodes.ImportNode(dotted_name_pos,
module_name = ExprNodes.StringNode(dotted_name_pos, module_name = ExprNodes.IdentifierStringNode(pos, value = dotted_name),
value = dotted_name),
name_list = import_list), name_list = import_list),
items = items) items = items)
...@@ -1207,7 +1222,7 @@ def p_with_statement(s): ...@@ -1207,7 +1222,7 @@ def p_with_statement(s):
s.error("Only 'with gil' and 'with nogil' implemented", s.error("Only 'with gil' and 'with nogil' implemented",
pos = pos) pos = pos)
def p_simple_statement(s): def p_simple_statement(s, first_statement = 0):
#print "p_simple_statement:", s.sy, s.systring ### #print "p_simple_statement:", s.sy, s.systring ###
if s.sy == 'global': if s.sy == 'global':
node = p_global_statement(s) node = p_global_statement(s)
...@@ -1226,7 +1241,7 @@ def p_simple_statement(s): ...@@ -1226,7 +1241,7 @@ def p_simple_statement(s):
elif s.sy in ('import', 'cimport'): elif s.sy in ('import', 'cimport'):
node = p_import_statement(s) node = p_import_statement(s)
elif s.sy == 'from': elif s.sy == 'from':
node = p_from_import_statement(s) node = p_from_import_statement(s, first_statement = first_statement)
elif s.sy == 'assert': elif s.sy == 'assert':
node = p_assert_statement(s) node = p_assert_statement(s)
elif s.sy == 'pass': elif s.sy == 'pass':
...@@ -1235,10 +1250,10 @@ def p_simple_statement(s): ...@@ -1235,10 +1250,10 @@ def p_simple_statement(s):
node = p_expression_or_assignment(s) node = p_expression_or_assignment(s)
return node return node
def p_simple_statement_list(s): def p_simple_statement_list(s, first_statement = 0):
# Parse a series of simple statements on one line # Parse a series of simple statements on one line
# separated by semicolons. # separated by semicolons.
stat = p_simple_statement(s) stat = p_simple_statement(s, first_statement = first_statement)
if s.sy == ';': if s.sy == ';':
stats = [stat] stats = [stat]
while s.sy == ';': while s.sy == ';':
...@@ -1298,7 +1313,8 @@ def p_IF_statement(s, level, cdef_flag, visibility, api): ...@@ -1298,7 +1313,8 @@ def p_IF_statement(s, level, cdef_flag, visibility, api):
s.compile_time_eval = saved_eval s.compile_time_eval = saved_eval
return result return result
def p_statement(s, level, cdef_flag = 0, visibility = 'private', api = 0): def p_statement(s, level, cdef_flag = 0, visibility = 'private', api = 0,
first_statement = 0):
if s.sy == 'ctypedef': if s.sy == 'ctypedef':
if level not in ('module', 'module_pxd'): if level not in ('module', 'module_pxd'):
s.error("ctypedef statement not allowed here") s.error("ctypedef statement not allowed here")
...@@ -1361,16 +1377,18 @@ def p_statement(s, level, cdef_flag = 0, visibility = 'private', api = 0): ...@@ -1361,16 +1377,18 @@ def p_statement(s, level, cdef_flag = 0, visibility = 'private', api = 0):
elif s.sy == 'with': elif s.sy == 'with':
return p_with_statement(s) return p_with_statement(s)
else: else:
return p_simple_statement_list(s) return p_simple_statement_list(s, first_statement = first_statement)
def p_statement_list(s, level, def p_statement_list(s, level,
cdef_flag = 0, visibility = 'private', api = 0): cdef_flag = 0, visibility = 'private', api = 0, first_statement = 0):
# Parse a series of statements separated by newlines. # Parse a series of statements separated by newlines.
pos = s.position() pos = s.position()
stats = [] stats = []
while s.sy not in ('DEDENT', 'EOF'): while s.sy not in ('DEDENT', 'EOF'):
stats.append(p_statement(s, level, stats.append(p_statement(s, level,
cdef_flag = cdef_flag, visibility = visibility, api = api)) cdef_flag = cdef_flag, visibility = visibility, api = api,
first_statement = first_statement))
first_statement = 0
if len(stats) == 1: if len(stats) == 1:
return stats[0] return stats[0]
else: else:
...@@ -2119,13 +2137,14 @@ def p_doc_string(s): ...@@ -2119,13 +2137,14 @@ def p_doc_string(s):
def p_module(s, pxd, full_module_name): def p_module(s, pxd, full_module_name):
s.add_type_name("object") s.add_type_name("object")
s.add_type_name("Py_buffer")
pos = s.position() pos = s.position()
doc = p_doc_string(s) doc = p_doc_string(s)
if pxd: if pxd:
level = 'module_pxd' level = 'module_pxd'
else: else:
level = 'module' level = 'module'
body = p_statement_list(s, level) body = p_statement_list(s, level, first_statement = 1)
if s.sy != 'EOF': if s.sy != 'EOF':
s.error("Syntax error in statement [%s,%s]" % ( s.error("Syntax error in statement [%s,%s]" % (
repr(s.sy), repr(s.systring))) repr(s.sy), repr(s.systring)))
......
...@@ -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:
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
# #
import re import re
from Cython import Utils
from Errors import warning, error, InternalError from Errors import warning, error, InternalError
import Options import Options
import Naming import Naming
...@@ -15,7 +16,7 @@ from TypeSlots import \ ...@@ -15,7 +16,7 @@ from TypeSlots import \
import ControlFlow import ControlFlow
import __builtin__ import __builtin__
identifier_pattern = re.compile(r"[A-Za-z_][A-Za-z0-9_]*$") possible_identifier = re.compile(ur"(?![0-9])\w+$", re.U).match
class Entry: class Entry:
# A symbol table entry in a Scope or ModuleNamespace. # A symbol table entry in a Scope or ModuleNamespace.
...@@ -64,9 +65,9 @@ class Entry: ...@@ -64,9 +65,9 @@ class Entry:
# type is an extension type # type is an extension type
# as_module None Module scope, if a cimported module # as_module None Module scope, if a cimported module
# is_inherited boolean Is an inherited attribute of an extension type # is_inherited boolean Is an inherited attribute of an extension type
# #interned_cname string C name of interned name string
# pystring_cname string C name of Python version of string literal # pystring_cname string C name of Python version of string literal
# is_interned boolean For string const entries, value is interned # is_interned boolean For string const entries, value is interned
# is_identifier boolean For string const entries, value is an identifier
# used boolean # used boolean
# is_special boolean Is a special method or property accessor # is_special boolean Is a special method or property accessor
# of an extension type # of an extension type
...@@ -104,8 +105,8 @@ class Entry: ...@@ -104,8 +105,8 @@ class Entry:
in_cinclude = 0 in_cinclude = 0
as_module = None as_module = None
is_inherited = 0 is_inherited = 0
#interned_cname = None
pystring_cname = None pystring_cname = None
is_identifier = 0
is_interned = 0 is_interned = 0
used = 0 used = 0
is_special = 0 is_special = 0
...@@ -188,6 +189,7 @@ class Scope: ...@@ -188,6 +189,7 @@ class Scope:
self.cname_to_entry = {} self.cname_to_entry = {}
self.pow_function_used = 0 self.pow_function_used = 0
self.string_to_entry = {} self.string_to_entry = {}
self.identifier_to_entry = {}
self.num_to_entry = {} self.num_to_entry = {}
self.obj_to_entry = {} self.obj_to_entry = {}
self.pystring_entries = [] self.pystring_entries = []
...@@ -204,10 +206,10 @@ class Scope: ...@@ -204,10 +206,10 @@ class Scope:
def __str__(self): def __str__(self):
return "<%s %s>" % (self.__class__.__name__, self.qualified_name) return "<%s %s>" % (self.__class__.__name__, self.qualified_name)
def intern(self, name): def intern_identifier(self, name):
return self.global_scope().intern(name) return self.global_scope().intern_identifier(name)
def qualifying_scope(self): def qualifying_scope(self):
return self.parent_scope return self.parent_scope
...@@ -448,31 +450,36 @@ class Scope: ...@@ -448,31 +450,36 @@ class Scope:
self.const_entries.append(entry) self.const_entries.append(entry)
return entry return entry
def get_string_const(self, value): def get_string_const(self, value, identifier = False):
# Get entry for string constant. Returns an existing # Get entry for string constant. Returns an existing
# one if possible, otherwise creates a new one. # one if possible, otherwise creates a new one.
genv = self.global_scope() genv = self.global_scope()
entry = genv.string_to_entry.get(value) if identifier:
string_map = genv.identifier_to_entry
else:
string_map = genv.string_to_entry
entry = string_map.get(value)
if not entry: if not entry:
entry = self.add_string_const(value) entry = self.add_string_const(value)
genv.string_to_entry[value] = entry entry.is_identifier = identifier
string_map[value] = entry
return entry return entry
def add_py_string(self, entry): def add_py_string(self, entry, identifier = None):
# If not already done, allocate a C name for a Python version of # If not already done, allocate a C name for a Python version of
# a string literal, and add it to the list of Python strings to # a string literal, and add it to the list of Python strings to
# be created at module init time. If the string resembles a # be created at module init time. If the string resembles a
# Python identifier, it will be interned. # Python identifier, it will be interned.
if not entry.pystring_cname: if entry.pystring_cname:
value = entry.init return
if not entry.type.is_unicode and identifier_pattern.match(value): value = entry.init
entry.pystring_cname = self.intern(value) entry.pystring_cname = entry.cname + "p"
entry.is_interned = 1 self.pystring_entries.append(entry)
else: self.global_scope().all_pystring_entries.append(entry)
entry.pystring_cname = entry.cname + "p" if identifier or (identifier is None and possible_identifier(value)):
self.pystring_entries.append(entry) entry.is_interned = 1
self.global_scope().all_pystring_entries.append(entry) self.global_scope().new_interned_string_entries.append(entry)
def add_py_num(self, value): def add_py_num(self, value):
# Add an entry for an int constant. # Add an entry for an int constant.
cname = "%s%s" % (Naming.interned_num_prefix, value) cname = "%s%s" % (Naming.interned_num_prefix, value)
...@@ -605,11 +612,14 @@ class BuiltinScope(Scope): ...@@ -605,11 +612,14 @@ class BuiltinScope(Scope):
utility_code = None): utility_code = None):
# If python_equiv == "*", the Python equivalent has the same name # If python_equiv == "*", the Python equivalent has the same name
# as the entry, otherwise it has the name specified by python_equiv. # as the entry, otherwise it has the name specified by python_equiv.
name = Utils.EncodedString(name)
entry = self.declare_cfunction(name, type, None, cname) entry = self.declare_cfunction(name, type, None, cname)
entry.utility_code = utility_code entry.utility_code = utility_code
if python_equiv: if python_equiv:
if python_equiv == "*": if python_equiv == "*":
python_equiv = name python_equiv = name
else:
python_equiv = Utils.EncodedString(python_equiv)
var_entry = Entry(python_equiv, python_equiv, py_object_type) var_entry = Entry(python_equiv, python_equiv, py_object_type)
var_entry.is_variable = 1 var_entry.is_variable = 1
var_entry.is_builtin = 1 var_entry.is_builtin = 1
...@@ -617,6 +627,7 @@ class BuiltinScope(Scope): ...@@ -617,6 +627,7 @@ class BuiltinScope(Scope):
return entry return entry
def declare_builtin_type(self, name, cname): def declare_builtin_type(self, name, cname):
name = Utils.EncodedString(name)
type = PyrexTypes.BuiltinObjectType(name, cname) type = PyrexTypes.BuiltinObjectType(name, cname)
type.set_scope(CClassScope(name, outer_scope=None, visibility='extern')) type.set_scope(CClassScope(name, outer_scope=None, visibility='extern'))
self.type_names[name] = 1 self.type_names[name] = 1
...@@ -671,14 +682,14 @@ class ModuleScope(Scope): ...@@ -671,14 +682,14 @@ class ModuleScope(Scope):
# python_include_files [string] Standard Python headers to be included # python_include_files [string] Standard Python headers to be included
# include_files [string] Other C headers to be included # include_files [string] Other C headers to be included
# string_to_entry {string : Entry} Map string const to entry # string_to_entry {string : Entry} Map string const to entry
# identifier_to_entry {string : Entry} Map identifier string const to entry
# context Context # context Context
# parent_module Scope Parent in the import namespace # parent_module Scope Parent in the import namespace
# module_entries {string : Entry} For cimport statements # module_entries {string : Entry} For cimport statements
# type_names {string : 1} Set of type names (used during parsing) # type_names {string : 1} Set of type names (used during parsing)
# pxd_file_loaded boolean Corresponding .pxd file has been processed # pxd_file_loaded boolean Corresponding .pxd file has been processed
# cimported_modules [ModuleScope] Modules imported with cimport # cimported_modules [ModuleScope] Modules imported with cimport
# intern_map {string : string} Mapping from Python names to interned strs # new_interned_string_entries [Entry] New interned strings waiting to be declared
# interned_names [string] Interned names pending generation of declarations
# interned_nums [int/long] Interned numeric constants # interned_nums [int/long] Interned numeric constants
# all_pystring_entries [Entry] Python string consts from all scopes # all_pystring_entries [Entry] Python string consts from all scopes
# types_imported {PyrexType : 1} Set of types for which import code generated # types_imported {PyrexType : 1} Set of types for which import code generated
...@@ -705,8 +716,7 @@ class ModuleScope(Scope): ...@@ -705,8 +716,7 @@ class ModuleScope(Scope):
self.type_names = dict(outer_scope.type_names) self.type_names = dict(outer_scope.type_names)
self.pxd_file_loaded = 0 self.pxd_file_loaded = 0
self.cimported_modules = [] self.cimported_modules = []
self.intern_map = {} self.new_interned_string_entries = []
self.interned_names = []
self.interned_nums = [] self.interned_nums = []
self.interned_objs = [] self.interned_objs = []
self.all_pystring_entries = [] self.all_pystring_entries = []
...@@ -743,15 +753,11 @@ class ModuleScope(Scope): ...@@ -743,15 +753,11 @@ class ModuleScope(Scope):
else: else:
entry.is_builtin = 1 entry.is_builtin = 1
return entry return entry
def intern(self, name): def intern_identifier(self, name):
intern_map = self.intern_map string_entry = self.get_string_const(name, identifier = True)
cname = intern_map.get(name) self.add_py_string(string_entry, identifier = 1)
if not cname: return string_entry.pystring_cname
cname = Naming.interned_prefix + name
intern_map[name] = cname
self.interned_names.append(name)
return cname
def find_module(self, module_name, pos): def find_module(self, module_name, pos):
# Find a module in the import namespace, interpreting # Find a module in the import namespace, interpreting
...@@ -832,8 +838,6 @@ class ModuleScope(Scope): ...@@ -832,8 +838,6 @@ class ModuleScope(Scope):
"Non-cdef global variable is not a generic Python object") "Non-cdef global variable is not a generic Python object")
entry.is_pyglobal = 1 entry.is_pyglobal = 1
entry.namespace_cname = self.module_cname entry.namespace_cname = self.module_cname
#if Options.intern_names:
# entry.interned_cname = self.intern(name)
else: else:
entry.is_cglobal = 1 entry.is_cglobal = 1
self.var_entries.append(entry) self.var_entries.append(entry)
...@@ -1151,8 +1155,6 @@ class PyClassScope(ClassScope): ...@@ -1151,8 +1155,6 @@ class PyClassScope(ClassScope):
cname, visibility, is_cdef) cname, visibility, is_cdef)
entry.is_pyglobal = 1 entry.is_pyglobal = 1
entry.namespace_cname = self.class_obj_cname entry.namespace_cname = self.class_obj_cname
#if Options.intern_names:
# entry.interned_cname = self.intern(name)
return entry return entry
def allocate_temp(self, type): def allocate_temp(self, type):
...@@ -1250,10 +1252,9 @@ class CClassScope(ClassScope): ...@@ -1250,10 +1252,9 @@ class CClassScope(ClassScope):
# I keep it in for now. is_member should be enough # I keep it in for now. is_member should be enough
# later on # later on
entry.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname entry.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname
if Options.intern_names: entry.interned_cname = self.intern_identifier(name)
entry.interned_cname = self.intern(name)
return entry return entry
def declare_pyfunction(self, name, pos): def declare_pyfunction(self, name, pos):
# Add an entry for a method. # Add an entry for a method.
...@@ -1262,7 +1263,7 @@ class CClassScope(ClassScope): ...@@ -1262,7 +1263,7 @@ class CClassScope(ClassScope):
if name == "__new__": if name == "__new__":
warning(pos, "__new__ method of extension type will change semantics " warning(pos, "__new__ method of extension type will change semantics "
"in a future version of Pyrex and Cython. Use __cinit__ instead.") "in a future version of Pyrex and Cython. Use __cinit__ instead.")
name = "__cinit__" name = Utils.EncodedString("__cinit__")
entry = self.declare_var(name, py_object_type, pos) entry = self.declare_var(name, py_object_type, pos)
special_sig = get_special_method_signature(name) special_sig = get_special_method_signature(name)
if special_sig: if special_sig:
...@@ -1279,7 +1280,7 @@ class CClassScope(ClassScope): ...@@ -1279,7 +1280,7 @@ class CClassScope(ClassScope):
def lookup_here(self, name): def lookup_here(self, name):
if name == "__new__": if name == "__new__":
name = "__cinit__" name = Utils.EncodedString("__cinit__")
return ClassScope.lookup_here(self, name) return ClassScope.lookup_here(self, name)
def declare_cfunction(self, name, type, pos, def declare_cfunction(self, name, type, pos,
...@@ -1401,13 +1402,16 @@ static PyObject* __Pyx_Method_ClassMethod(PyObject *method); /*proto*/ ...@@ -1401,13 +1402,16 @@ static PyObject* __Pyx_Method_ClassMethod(PyObject *method); /*proto*/
static PyObject* __Pyx_Method_ClassMethod(PyObject *method) { static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
/* It appears that PyMethodDescr_Type is not anywhere exposed in the Python/C API */ /* It appears that PyMethodDescr_Type is not anywhere exposed in the Python/C API */
/* if (!PyObject_TypeCheck(method, &PyMethodDescr_Type)) { */ /* if (!PyObject_TypeCheck(method, &PyMethodDescr_Type)) { */
if (strcmp(method->ob_type->tp_name, "method_descriptor") == 0) { /* cdef classes */ if (strcmp(Py_TYPE(method)->tp_name, "method_descriptor") == 0) { /* cdef classes */
PyMethodDescrObject *descr = (PyMethodDescrObject *)method; PyMethodDescrObject *descr = (PyMethodDescrObject *)method;
return PyDescr_NewClassMethod(descr->d_type, descr->d_method); return PyDescr_NewClassMethod(descr->d_type, descr->d_method);
} }
else if (PyMethod_Check(method)) { /* python classes */ else if (PyMethod_Check(method)) { /* python classes */
return PyClassMethod_New(PyMethod_GET_FUNCTION(method)); return PyClassMethod_New(PyMethod_GET_FUNCTION(method));
} }
else if (PyCFunction_Check(method)) {
return PyClassMethod_New(method);
}
PyErr_Format(PyExc_TypeError, "Class-level classmethod() can only be called on a method_descriptor or instance method."); PyErr_Format(PyExc_TypeError, "Class-level classmethod() can only be called on a method_descriptor or instance method.");
return NULL; return NULL;
} }
......
...@@ -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
......
__doc__ = """ __doc__ = u"""
>>> spam == "C string 1" + "C string 2" >>> spam == u'C string 1' + u'C string 2'
True True
""" """
spam = "C string 1" + "C string 2" import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u" u'", u" '")
spam = u"C string 1" + u"C string 2"
__doc__ = u"""
>>> y
(b'1', b'2', b'3')
>>> x
b'1foo2foo3'
"""
import sys
if sys.version_info[0] < 3:
__doc__ = __doc__.replace(u"b'", u"'")
y = ('1','2','3')
x = 'foo'.join(y)
__doc__ = """ __doc__ = u"""
>>> print spam >>> print(spam)
eggseggseggseggs eggseggseggseggs
>>> print grail >>> print(grail)
tomatotomatotomatotomatotomatotomatotomato tomatotomatotomatotomatotomatotomatotomato
""" """
spam = "eggs" * 4 spam = u"eggs" * 4
grail = 7 * "tomato" grail = 7 * u"tomato"
__doc__ = """ __doc__ = u"""
>>> test_i() >>> test_i()
>>> test_c() >>> test_c()
>>> test_p() >>> test_p()
......
__doc__ = """ __doc__ = u"""
>>> c() >>> c()
120 120
>>> i0() == -1 >>> i0() == -1
...@@ -16,7 +16,7 @@ __doc__ = """ ...@@ -16,7 +16,7 @@ __doc__ = """
>>> f() >>> f()
12.5 12.5
>>> s() >>> s()
'spam' b'spam'
>>> two() >>> two()
2 2
>>> five() >>> five()
...@@ -27,7 +27,15 @@ __doc__ = """ ...@@ -27,7 +27,15 @@ __doc__ = """
False False
""" """
DEF TUPLE = (1, 2, "buckle my shoe") import sys
if sys.version_info[0] < 3:
__doc__ = __doc__.replace(u" b'", u" '")
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u" 042", u" 0o42")
DEF TUPLE = (1, 2, u"buckle my shoe")
DEF TRUE_FALSE = (True, False) DEF TRUE_FALSE = (True, False)
DEF CHAR = c'x' DEF CHAR = c'x'
......
__doc__ = """ __doc__ = u"""
>>> f() >>> f()
1 1
>>> g() >>> g()
......
__doc__ = """ __doc__ = u"""
>>> test_i() >>> test_i()
>>> test_c() >>> test_c()
>>> test_p() >>> test_p()
......
__doc__ = """ __doc__ = u"""
>>> f() >>> f()
""" """
......
__doc__ = """ __doc__ = u"""
>>> empty() >>> empty()
{} {}
>>> keyvalue(1, 2) >>> keyvalue(1, 2)
...@@ -11,9 +11,9 @@ __doc__ = """ ...@@ -11,9 +11,9 @@ __doc__ = """
>>> len(constant()) >>> len(constant())
2 2
>>> constant()['parrot'] >>> print(constant()['parrot'])
'resting' resting
>>> constant()['answer'] >>> print(constant()['answer'])
42 42
""" """
...@@ -34,6 +34,5 @@ def keyvalues2(key1, value1, key2, value2): ...@@ -34,6 +34,5 @@ def keyvalues2(key1, value1, key2, value2):
return d return d
def constant(): def constant():
d = {"parrot":"resting", "answer":42} d = {u"parrot":u"resting", u"answer":42}
return d return d
__doc__ = """ __doc__ = u"""
>>> test() >>> test()
1.0 1.0
""" """
......
__doc__ = """ __doc__ = u"""
>>> p = Point(1,2,3) >>> p = Point(1,2,3)
>>> p.gettuple() >>> p.gettuple()
(1.0, 2.0, 3.0) (1.0, 2.0, 3.0)
......
__doc__ = u"""
>>> s = Spam()
>>> s.a
2
>>> s.c
3
>>> s.test(5)
13
>>> s.b
5
"""
cdef class Spam:
a = 1
def test(self, a):
return a + self.b + self.c
b = a + 2 # 3
a = b - 1 # 2
c = 3 # 3
b = c + a # 5
__doc__ = """ __doc__ = u"""
>>> e = Eggs() >>> e = Eggs()
>>> print type(e).__name__ >>> type(e).__name__
Eggs 'Eggs'
""" """
cdef class Eggs: pass cdef class Eggs: pass
__doc__ = u"""
>>> test()
5
0
20
5
"""
cdef class Spam: cdef class Spam:
cdef int tons cdef int tons
...@@ -8,8 +16,27 @@ cdef class Spam: ...@@ -8,8 +16,27 @@ cdef class Spam:
cdef void eat(self): cdef void eat(self):
self.tons = 0 self.tons = 0
def lift(self):
print self.tons
cdef class SuperSpam(Spam): cdef class SuperSpam(Spam):
cdef void add_tons(self, int x): cdef void add_tons(self, int x):
self.tons = self.tons + 2 * x self.tons = self.tons + 2 * x
def test():
cdef Spam s
cdef SuperSpam ss
s = Spam()
s.eat()
s.add_tons(5)
s.lift()
ss = SuperSpam()
ss.eat()
ss.lift()
ss.add_tons(10)
ss.lift()
s.lift()
__doc__ = """ __doc__ = u"""
>>> p = create() >>> p = create()
>>> rest(p) >>> rest(p)
0 0
......
__doc__ = """ __doc__ = u"""
>>> print type(f()).__name__ >>> type(f()).__name__
Spam 'Spam'
""" """
cdef class Spam: cdef class Spam:
......
__doc__ = """ __doc__ = u"""
>>> ext = Ext() >>> ext = Ext()
>>> b,c,d,e,f,g,h,k = ext.b,ext.c,ext.d,ext.e,ext.f,ext.g,ext.h,ext.k >>> b,c,d,e,f,g,h,k = ext.b,ext.c,ext.d,ext.e,ext.f,ext.g,ext.h,ext.k
...@@ -84,6 +84,10 @@ __doc__ = """ ...@@ -84,6 +84,10 @@ __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__)
cdef class Ext: cdef class Ext:
def b(self, a, b, c): def b(self, a, b, c):
pass pass
......
__doc__ = """ __doc__ = u"""
>>> len(Spam()) >>> len(Spam())
0 0
""" """
......
__doc__ = u"""
>>> tomato()
42
"""
cdef class Spam: cdef class Spam:
property eggs: property eggs:
def __get__(self): def __get__(self):
pass return 42
cdef void tomato(): def tomato():
cdef Spam spam cdef Spam spam
cdef object lettuce cdef object lettuce
spam = Spam()
lettuce = spam.eggs lettuce = spam.eggs
return lettuce
__doc__ = """ __doc__ = u"""
>>> s = Silly(1,2,3, 'test') >>> s = Silly(1,2,3, 'test')
>>> (spam,grail,swallow,creosote,onlyt,onlyk,tk) = ( >>> (spam,grail,swallow,creosote,onlyt,onlyk,tk) = (
... s.spam,s.grail,s.swallow,s.creosote,s.onlyt,s.onlyk,s.tk) ... s.spam,s.grail,s.swallow,s.creosote,s.onlyt,s.onlyk,s.tk)
>>> spam(1,2,3) >>> spam(1,2,3)
(1, 2, 3) (1, 2, 3)
>>> spam(1,2) >>> spam(1,2) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (2 given) TypeError: function takes exactly 3 arguments (2 given)
>>> spam(1,2,3,4) >>> spam(1,2,3,4)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (4 given) TypeError: function takes exactly 3 arguments (4 given)
>>> spam(1,2,3, a=1) >>> spam(1,2,3, a=1) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: 'a' is an invalid keyword argument for this function TypeError: 'a' is an invalid keyword argument for this function
...@@ -21,10 +21,10 @@ __doc__ = """ ...@@ -21,10 +21,10 @@ __doc__ = """
(1, 2, 3, (4,)) (1, 2, 3, (4,))
>>> grail(1,2,3,4,5,6,7,8,9) >>> grail(1,2,3,4,5,6,7,8,9)
(1, 2, 3, (4, 5, 6, 7, 8, 9)) (1, 2, 3, (4, 5, 6, 7, 8, 9))
>>> grail(1,2) >>> grail(1,2) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (2 given) TypeError: function takes exactly 3 arguments (2 given)
>>> grail(1,2,3, a=1) >>> grail(1,2,3, a=1) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: 'a' is an invalid keyword argument for this function TypeError: 'a' is an invalid keyword argument for this function
...@@ -35,7 +35,7 @@ __doc__ = """ ...@@ -35,7 +35,7 @@ __doc__ = """
TypeError: function takes at most 3 positional arguments (4 given) TypeError: function takes at most 3 positional arguments (4 given)
>>> swallow(1,2,3, a=1, b=2) >>> swallow(1,2,3, a=1, b=2)
(1, 2, 3, (('a', 1), ('b', 2))) (1, 2, 3, (('a', 1), ('b', 2)))
>>> swallow(1,2,3, x=1) >>> swallow(1,2,3, x=1) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: keyword parameter 'x' was given by position and by name TypeError: keyword parameter 'x' was given by position and by name
...@@ -47,7 +47,7 @@ __doc__ = """ ...@@ -47,7 +47,7 @@ __doc__ = """
(1, 2, 3, (), (('a', 1),)) (1, 2, 3, (), (('a', 1),))
>>> creosote(1,2,3,4, a=1, b=2) >>> creosote(1,2,3,4, a=1, b=2)
(1, 2, 3, (4,), (('a', 1), ('b', 2))) (1, 2, 3, (4,), (('a', 1), ('b', 2)))
>>> creosote(1,2,3,4, x=1) >>> creosote(1,2,3,4, x=1) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: keyword parameter 'x' was given by position and by name TypeError: keyword parameter 'x' was given by position and by name
...@@ -88,8 +88,16 @@ __doc__ = """ ...@@ -88,8 +88,16 @@ __doc__ = """
(1, ('a', 1), ('b', 2)) (1, ('a', 1), ('b', 2))
""" """
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)
cdef sorteditems(d): cdef sorteditems(d):
l = d.items() l = list(d.items())
l.sort() l.sort()
return tuple(l) return tuple(l)
......
__doc__ = """ __doc__ = u"""
>>> s = Spam(12) >>> s = Spam(12)
>>> s.eat() >>> s.eat()
12 42 12 42
......
__doc__ = u"""
>>> print(spam)
ftang
>>> foo
42
"""
include "filenames.pxi" include "filenames.pxi"
foo = 42 foo = 42
......
from __future__ import unicode_literals
import sys
if sys.version_info[0] >= 3:
__doc__ = """
>>> u == 'test'
True
>>> isinstance(u, str)
True
"""
else:
__doc__ = """
>>> u == u'test'
True
>>> isinstance(u, unicode)
True
"""
u = "test"
__doc__ = """ __doc__ = u"""
>>> class test(object): a = 1 >>> class test(object): a = 1
>>> t = test() >>> t = test()
......
__doc__ = """ __doc__ = u"""
>>> f(0,0) >>> f(0,0)
0 0
>>> f(1,2) >>> f(1,2)
......
__doc__ = """ __doc__ = u"""
>>> D >>> D
2 2
""" """
......
__doc__ = u"""
>>> p = Norwegian()
>>> p.describe()
Norwegian
Parrot
"""
cdef class Parrot:
cdef void _describe(self):
print u"Parrot"
def describe(self):
self._describe()
cdef class Norwegian(Parrot):
cdef void _describe(self):
print u"Norwegian"
Parrot._describe(self)
__doc__ = """ __doc__ = u"""
>>> f(1,[1,2,3]) >>> f(1,[1,2,3])
True True
>>> f(5,[1,2,3]) >>> f(5,[1,2,3])
......
__doc__ = """ __doc__ = u"""
>>> C().xxx(5) >>> C().xxx(5)
5 5
>>> C().xxx() >>> C().xxx()
'a b' u'a b'
>>> C().xxx(42) >>> C().xxx(42)
42 42
>>> C().xxx() >>> C().xxx()
'a b' u'a b'
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u" u'", u" '")
class C: class C:
def xxx(self, p="a b"): def xxx(self, p=u"a b"):
return p return p
__doc__ = """ __doc__ = u"""
>>> c1 = C1() >>> c1 = C1()
>>> c2 = C2(c1) >>> c2 = C2(c1)
>>> c1 is c2.getc1() >>> c1 is c2.getc1()
......
__doc__ = """ __doc__ = u"""
>>> test_and(None, None) >>> test_and(None, None)
True True
>>> test_and(None, 1) >>> test_and(None, 1)
......
__doc__ = """ __doc__ = u"""
>>> py_x = r'\\\\' >>> py_x = br'\\\\'
>>> assert x == py_x >>> assert x == py_x
""" """
import sys
if sys.version_info[0] < 3:
__doc__ = __doc__.replace(u" br'", u" r'")
x = r'\\' x = r'\\'
__doc__ = u"""
>>> f()
It works!
"""
DEF STUFF = "Spam" DEF STUFF = "Spam"
cdef void f(): def f():
IF STUFF == "Spam": IF STUFF == "Spam":
print "It works!" print u"It works!"
ELSE: ELSE:
print "Doesn't work" print u"Doesn't work"
__doc__ = """ __doc__ = u"""
>>> t = TEST() >>> t = TEST()
>>> 1 in t >>> 1 in t
True True
......
__doc__ = """ __doc__ = u"""
>>> x = X() >>> x = X()
>>> x.slots >>> x.slots
[''] [b'']
""" """
import sys
if sys.version_info[0] < 3:
__doc__ = __doc__.replace(u"b'", u"'")
class X: class X:
slots = ["", ] slots = ["", ]
__doc__ = """ __doc__ = u"""
>>> d = {1 : 2} >>> d = {1 : 2}
>>> test(**d) >>> test(**d)
Traceback (most recent call last): Traceback (most recent call last):
...@@ -12,13 +12,18 @@ __doc__ = """ ...@@ -12,13 +12,18 @@ __doc__ = """
>>> d >>> d
{} {}
>>> d = {'arg' : 2} >>> d = {'arg' : 2} # this should be u'arg', but Py2 can't handle it...
>>> test(**d) >>> test(**d)
{'arg': 3} {'arg': 3}
>>> d >>> d
{'arg': 2} {'arg': 2}
""" """
import sys
def test(**kw): def test(**kw):
kw['arg'] = 3 if sys.version_info[0] >= 3:
kw[u'arg'] = 3
else:
kw['arg'] = 3
return kw return kw
__doc__ = """ __doc__ = u"""
>>> b(1,2,3) >>> b(1,2,3)
>>> b(1,2,3,4) >>> b(1,2,3,4)
Traceback (most recent call last): Traceback (most recent call last):
...@@ -81,6 +81,10 @@ __doc__ = """ ...@@ -81,6 +81,10 @@ __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__)
def b(a, b, c): def b(a, b, c):
pass pass
......
__doc__ = u"""
>>> call3(b)
>>> call4(b)
Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (4 given)
>>> call2(c)
>>> call3(c)
>>> call4(c)
Traceback (most recent call last):
TypeError: function takes at most 3 arguments (4 given)
>>> call2(d)
>>> call2c(d)
>>> call3(d)
Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given)
>>> call2d(d)
Traceback (most recent call last):
TypeError: 'd' is an invalid keyword argument for this function
>>> call2(e)
>>> call2c(e)
>>> call2d(e)
>>> call2cde(e)
>>> call3(e)
>>> call4(e)
Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given)
>>> call2c(f)
>>> call2cd(f)
>>> call3(f)
Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given)
>>> call2(f)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
>>> call2ce(f)
Traceback (most recent call last):
TypeError: 'e' is an invalid keyword argument for this function
>>> call2cf(g)
>>> call2cefd(g)
>>> call2cfex(g)
>>> call3(g)
Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given)
>>> call2(g)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
>>> call2c(g)
Traceback (most recent call last):
TypeError: required keyword argument 'f' is missing
>>> call2cf(h)
>>> call2cfe(h)
>>> call6cf(h)
>>> call6cfexy(h)
>>> call3(h)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
>>> call3d(h)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
>>> call2cf(k)
>>> call2cfe(k)
>>> call6df(k)
>>> call6dfexy(k)
>>> call3(k)
Traceback (most recent call last):
TypeError: required keyword argument 'f' is missing
>>> call2d(k)
Traceback (most recent call last):
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__)
# the calls:
def call2(f):
f(1,2)
def call3(f):
f(1,2,3)
def call4(f):
f(1,2,3,4)
def call2c(f):
f(1,2, c=1)
def call2d(f):
f(1,2, d=1)
def call3d(f):
f(1,2,3, d=1)
def call2cd(f):
f(1,2, c=1, d=2)
def call2ce(f):
f(1,2, c=1, e=2)
def call2cde(f):
f(1,2, c=1, d=2, e=3)
def call2cf(f):
f(1,2, c=1, f=2)
def call6cf(f):
f(1,2,3,4,5,6, c=1, f=2)
def call6df(f):
f(1,2,3,4,5,6, d=1, f=2)
def call2cfe(f):
f(1,2, c=1, f=2, e=3)
def call2cefd(f):
f(1,2, c=1, e=0, f=2, d=11)
def call2cfex(f):
f(1,2, c=1, f=2, e=0, x=25)
def call6cfexy(f):
f(1,2,3,4,5,6, c=1, f=2, e=3, x=25, y=11)
def call6dfexy(f):
f(1,2,3,4,5,6, d=1, f=2, e=3, x=25, y=11)
# the called functions:
def b(a, b, c):
pass
def c(a, b, c=1):
pass
def d(a, b, *, c = 88):
pass
def e(a, b, c = 88, **kwds):
pass
def f(a, b, *, c, d = 42):
pass
def g(a, b, *, c, d = 42, e = 17, f, **kwds):
pass
def h(a, b, *args, c, d = 42, e = 17, f, **kwds):
pass
def k(a, b, c=1, *args, d = 42, e = 17, f, **kwds):
pass
__doc__ = """ __doc__ = u"""
>>> a = A(1,2,3) >>> a = A(1,2,3)
>>> a[0] >>> a[0]
1.0 1.0
......
__doc__ = """ __doc__ = u"""
>>> f(1, 2, 3, 4, 5) >>> f(1, 2, 3, 4, 5)
[] []
>>> g(1, 2, 3, 4, 5) >>> g(1, 2, 3, 4, 5)
......
__doc__ = """ __doc__ = u"""
>>> foo() >>> foo()
""" """
......
cdef loops(): __doc__ = u"""
>>> loops()
5
"""
def loops():
cdef int k cdef int k
for i from 0 <= i < 5: for i from 0 <= i < 5:
for j from 0 <= j < 2: for j from 0 <= j < 2:
k = i + j k = i + j
return k
__doc__ = """ __doc__ = u"""
>>> f() >>> f()
>>> g >>> g
42 42
>>> x >>> x
'spam' u'spam'
>>> y >>> y
'eggs' u'eggs'
>>> z >>> z
'spameggs' u'spameggs'
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u" u'", u" '")
def f(): def f():
pass pass
g = 42 g = 42
x = "spam" x = u"spam"
y = "eggs" y = u"eggs"
if g: if g:
z = x + y z = x + y
__doc__ = """ __doc__ = u"""
>>> modobj(9,2) >>> modobj(9,2)
1 1
>>> modobj('%d', 5) >>> modobj('%d', 5)
......
__doc__ = """ __doc__ = u"""
>>> f() >>> f()
(1, 2, 1, 2) (1, 2, 1, 2)
>>> g() >>> g()
(1, 1, 2, 2, 3, 3) (1, 1, 2, 2, 3, 3)
>>> h() >>> h()
(1, 'test', 3, 1, 'test', 3) (1, b'test', 3, 1, b'test', 3)
>>> j() >>> j()
(2, 1, 4, 2, 6, 3) (2, 1, 4, 2, 6, 3)
""" """
import sys
if sys.version_info[0] < 3:
__doc__ = __doc__.replace(u" b'", u" '")
def f(): def f():
cdef object obj1a, obj2a, obj3a, obj1b, obj2b, obj3b cdef object obj1a, obj2a, obj3a, obj1b, obj2b, obj3b
obj1b, obj2b, obj3b = 1, 2, 3 obj1b, obj2b, obj3b = 1, 2, 3
......
__doc__ = """ __doc__ = u"""
>>> test(Exception('hi')) >>> test(Exception(u'hi'))
Raising: Exception('hi',) Raising: Exception(u'hi',)
Caught: Exception('hi',) Caught: Exception(u'hi',)
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u"u'", u"'")
import sys, types import sys, types
def test(obj): def test(obj):
print "Raising: %s%r" % (obj.__class__.__name__, obj.args) print u"Raising: %s%r" % (obj.__class__.__name__, obj.args)
try: try:
raise obj raise obj
except: except:
...@@ -16,4 +20,4 @@ def test(obj): ...@@ -16,4 +20,4 @@ def test(obj):
assert isinstance(info[0], type) assert isinstance(info[0], type)
else: else:
assert isinstance(info[0], types.ClassType) assert isinstance(info[0], types.ClassType)
print "Caught: %s%r" % (info[1].__class__.__name__, info[1].args) print u"Caught: %s%r" % (info[1].__class__.__name__, info[1].args)
__doc__ = u"""
>>> g()
"""
cdef class Spam: cdef class Spam:
pass pass
cdef f(Spam s): cdef f(Spam s):
pass pass
cdef g(): def g():
f(None) f(None)
__doc__ = """ __doc__ = u"""
>>> f(1,[1,2,3]) >>> f(1,[1,2,3])
False False
>>> f(5,[1,2,3]) >>> f(5,[1,2,3])
......
__doc__ = """ __doc__ = u"""
>>> f() >>> f()
""" """
......
__doc__ = """ __doc__ = u"""
>>> test() >>> test()
1 1
""" """
......
__doc__ = """ __doc__ = u"""
>>> x >>> x
(1, 2) (1, 2)
""" """
......
__doc__ = """ __doc__ = u"""
>>> c = build() >>> c = build()
>>> c.method() >>> c.method()
Traceback (most recent call last): Traceback (most recent call last):
......
__doc__ = """ __doc__ = u"""
>>> f = Fiche() >>> f = Fiche()
>>> f[0] = 1 >>> f[0] = 1
>>> f.geti() >>> f.geti()
......
__doc__ = """ __doc__ = u"""
>>> f(1.0, 2.95)[0] == f(1.0, 2.95)[1] >>> f(1.0, 2.95)[0] == f(1.0, 2.95)[1]
True True
...@@ -15,6 +15,10 @@ __doc__ = """ ...@@ -15,6 +15,10 @@ __doc__ = """
True True
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u"2L", u"2")
def f(obj2, obj3): def f(obj2, obj3):
cdef float flt1, flt2, flt3 cdef float flt1, flt2, flt3
flt2, flt3 = obj2, obj3 flt2, flt3 = obj2, obj3
......
__doc__ = """ __doc__ = u"""
>>> f(1, 'test') >>> f(1, 'test')
<BLANKLINE> <BLANKLINE>
1 1
...@@ -11,5 +11,4 @@ def f(a, b): ...@@ -11,5 +11,4 @@ def f(a, b):
print a print a
print a, b print a, b
print a, b, print a, b,
print 42, "spam" print 42, u"spam"
__doc__ = """ __doc__ = u"""
>>> f() >>> f()
>>> g() >>> g()
""" """
......
__doc__ = """ __doc__ = u"""
>>> s = Spam(Eggs("ham")) >>> s = Spam(Eggs("ham"))
>>> test(s) >>> test(s)
'ham' 'ham'
......
__doc__ = """ __doc__ = u"""
>>> f(1,2,3) >>> f(1,2,3)
3 3
>>> g(1,2,3) >>> g(1,2,3)
......
__doc__ = """ __doc__ = u"""
>>> l1 = Sub1([1,2,3]) >>> l1 = Sub1([1,2,3])
>>> len(l1) >>> len(l1)
3 3
......
__doc__ = """ __doc__ = u"""
>>> f() >>> f()
6 6
>>> g() >>> g()
0 2
""" """
def f(): def f():
...@@ -13,8 +13,8 @@ def f(): ...@@ -13,8 +13,8 @@ def f():
return obj1 return obj1
def g(): def g():
obj1 = 1 obj1 = 12
obj2 = 2 obj2 = 6
obj3 = 3 obj3 = 3
obj1 = obj2 / obj3 obj1 = obj2 / obj3
return obj1 return int(obj1)
__doc__ = """ __doc__ = u"""
>>> def test(a, b): >>> def test(a, b):
... print a, b, add(a, b) ... return (a, b, add(a, b))
>>> test(1, 2) >>> test(1, 2)
1 2 3 (1, 2, 3)
>>> test(17.3, 88.6) >>> [ str(f) for f in test(17.3, 88.6) ]
17.3 88.6 105.9 ['17.3', '88.6', '105.9']
>>> test("eggs", "spam") >>> test(u'eggs', u'spam')
eggs spam eggsspam (u'eggs', u'spam', u'eggsspam')
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u"u'", u"'")
def add(x, y): def add(x, y):
return x + y return x + y
__doc__ = """ __doc__ = u"""
>>> swallow(name = "Brian") >>> swallow(name = "Brian")
This swallow is called Brian This swallow is called Brian
>>> swallow(airspeed = 42) >>> swallow(airspeed = 42)
...@@ -9,9 +9,9 @@ __doc__ = """ ...@@ -9,9 +9,9 @@ __doc__ = """
def swallow(name = None, airspeed = None, coconuts = None): def swallow(name = None, airspeed = None, coconuts = None):
if name is not None: if name is not None:
print "This swallow is called", name print u"This swallow is called", name
if airspeed is not None: if airspeed is not None:
print "This swallow is flying at", airspeed, "furlongs per fortnight" print u"This swallow is flying at", airspeed, u"furlongs per fortnight"
if coconuts is not None: if coconuts is not None:
print "This swallow is carrying", coconuts, "coconuts" print u"This swallow is carrying", coconuts, u"coconuts"
__doc__ = """ __doc__ = u"""
>>> try: >>> try:
... B() ... B()
... except Exception, e: ... except Exception, e:
... print "%s: %s" % (e.__class__.__name__, e) ... print("%s: %s" % (e.__class__.__name__, e))
Exception: crash-me Exception: crash-me
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u"Exception, e", u"Exception as e")
cdef class A: cdef class A:
def __cinit__(self): def __cinit__(self):
raise Exception("crash-me") raise Exception(u"crash-me")
cdef class B(A): cdef class B(A):
def __cinit__(self): def __cinit__(self):
......
__doc__ = """ __doc__ = u"""
foo = Foo() >>> foo = Foo()
fee = Fee() >>> fee = Fee()
faa = Faa() >>> faa = Faa()
fee.bof() >>> fee.bof()
faa.bof() Fee bof 0
>>> faa.bof()
Foo bof 0
""" """
cdef class Foo: cdef class Foo:
...@@ -16,10 +18,10 @@ cdef class Foo: ...@@ -16,10 +18,10 @@ cdef class Foo:
cdef class Fee(Foo): cdef class Fee(Foo):
def bof(self): def bof(self):
print 'Fee bof', self.val print u'Fee bof', self.val
cdef class Faa(Fee): cdef class Faa(Fee):
def bof(self): def bof(self):
print 'Foo bof', self.val print u'Foo bof', self.val
__doc__ = """ __doc__ = u"""
print f(100) >>> f(100)
print g(3000000000) 101L
>>> g(3000000000)
3000000001L
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u"L", u"")
def f(x): def f(x):
cdef unsigned long long ull cdef unsigned long long ull
ull = x ull = x
......
__doc__ = """ __doc__ = u"""
try: >>> try:
eggs().eat() ... eggs().eat()
except RuntimeError, e: ... except RuntimeError:
print "%s: %s" % (e.__class__.__name__, e) ... import sys
... e = sys.exc_info()[1]
... print("%s: %s" % (e.__class__.__name__, e))
RuntimeError: I don't like that
""" """
cdef class eggs: cdef class eggs:
...@@ -11,5 +14,5 @@ cdef class eggs: ...@@ -11,5 +14,5 @@ cdef class eggs:
pass pass
def eat(self): def eat(self):
raise RuntimeError("I don't like that") raise RuntimeError(u"I don't like that")
__doc__ = """ __doc__ = u"""# Python 3 gets all of these right ...
>>> f.__doc__ >>> f.__doc__
'This is a function docstring.' 'This is a function docstring.'
>>> C.__doc__ >>> C.__doc__
'This is a class docstring.' u'This is a class docstring.'
>>> CS.__doc__ >>> CS.__doc__
'This is a subclass docstring.' u'This is a subclass docstring.'
>>> print CSS.__doc__ >>> print(CSS.__doc__)
None None
>>> T.__doc__ >>> T.__doc__
...@@ -18,41 +18,45 @@ __doc__ = """ ...@@ -18,41 +18,45 @@ __doc__ = """
Compare with standard Python: Compare with standard Python:
>>> def f(): >>> def f():
... 'This is a function docstring.' ... u'This is a function docstring.'
>>> f.__doc__ >>> f.__doc__
'This is a function docstring.' u'This is a function docstring.'
>>> class C: >>> class C:
... 'This is a class docstring.' ... u'This is a class docstring.'
>>> class CS(C): >>> class CS(C):
... 'This is a subclass docstring.' ... u'This is a subclass docstring.'
>>> class CSS(CS): >>> class CSS(CS):
... pass ... pass
>>> C.__doc__ >>> C.__doc__
'This is a class docstring.' u'This is a class docstring.'
>>> CS.__doc__ >>> CS.__doc__
'This is a subclass docstring.' u'This is a subclass docstring.'
>>> CSS.__doc__ >>> CSS.__doc__
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u" u'", u" '")
def f(): def f():
"This is a function docstring." u"This is a function docstring."
class C: class C:
"This is a class docstring." u"This is a class docstring."
class CS(C): class CS(C):
"This is a subclass docstring." u"This is a subclass docstring."
class CSS(CS): class CSS(CS):
pass pass
cdef class T: cdef class T:
"This is an extension type docstring." u"This is an extension type docstring."
cdef class TS(T): cdef class TS(T):
"This is an extension subtype docstring." u"This is an extension subtype docstring."
cdef class TSS(TS): cdef class TSS(TS):
pass pass
__doc__ = """ __doc__ = u"""
>>> c = eggs() >>> c = eggs()
>>> print "eggs returned:", c >>> c
eggs returned: (17+42j) (17+42j)
>>> spam(c) >>> spam(c)
Real: 17.0 Real: 17.0
Imag: 42.0 Imag: 42.0
...@@ -17,8 +17,8 @@ cdef extern from "complexobject.h": ...@@ -17,8 +17,8 @@ cdef extern from "complexobject.h":
cdef Py_complex cval cdef Py_complex cval
def spam(complex c): def spam(complex c):
print "Real:", c.cval.real print u"Real:", c.cval.real
print "Imag:", c.cval.imag print u"Imag:", c.cval.imag
def eggs(): def eggs():
return complex(17, 42) return complex(17, 42)
__doc__ = """ __doc__ = u"""
>>> s = Swallow("Brian", 42) >>> s = Swallow("Brian", 42)
Name: Brian Name: Brian
Airspeed: 42 Airspeed: 42
...@@ -33,7 +33,7 @@ __doc__ = """ ...@@ -33,7 +33,7 @@ __doc__ = """
cdef class Swallow: cdef class Swallow:
def __init__(self, name, airspeed, *args, **kwds): def __init__(self, name, airspeed, *args, **kwds):
print "Name:", name print u"Name:", name
print "Airspeed:", airspeed print u"Airspeed:", airspeed
print "Extra args:", args print u"Extra args:", args
print "Extra keywords:", kwds print u"Extra keywords:", kwds
__doc__ = """ __doc__ = u"""
>>> go() >>> go()
Spam! Spam!
Spam! Spam!
...@@ -9,5 +9,5 @@ __doc__ = """ ...@@ -9,5 +9,5 @@ __doc__ = """
def go(): def go():
for i in range(5): for i in range(5):
print "Spam!" print u"Spam!"
__doc__ = """ __doc__ = u"""
>>> try: >>> try:
... s = Spam() ... s = Spam()
... except StandardError, e: ... except KeyError, e:
... print "Exception:", e ... print("Exception: %s" % e)
... else: ... else:
... print "Did not raise the expected exception" ... print("Did not raise the expected exception")
Exception: This is not a spanish inquisition Exception: u'This is not a spanish inquisition'
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u"Error, e", u"Error as e")
__doc__ = __doc__.replace(u" u'", u" '")
cdef extern from "Python.h": cdef extern from "Python.h":
ctypedef class types.ListType [object PyListObject]: ctypedef class __builtin__.list [object PyListObject]:
pass pass
cdef class Spam(ListType): cdef class Spam(list):
def __init__(self): def __init__(self):
raise StandardError("This is not a spanish inquisition") raise KeyError(u"This is not a spanish inquisition")
__doc__ = """ __doc__ = u"""
try: >>> try:
foo() ... foo()
except Exception, e: ... except Exception, e:
print "%s: %s" % (e.__class__.__name__, e) ... print("%s: %s" % (e.__class__.__name__, e))
ValueError:
>>> try:
... bar()
... except Exception, e:
... print("%s: %s" % (e.__class__.__name__, e))
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u"Exception, e", u"Exception as e")
def bar(): def bar():
try: try:
raise TypeError raise TypeError
......
__doc__ = """ __doc__ = u"""
print r_jeff_epler_1.blowup([2, 3, 5]) >>> blowup([2, 3, 5])
1
""" """
def blowup(p): def blowup(p):
......
__doc__ = """ __doc__ = u"""
>>> test() >>> test()
This parrot is resting. This parrot is resting.
Lovely plumage! Lovely plumage!
...@@ -8,7 +8,7 @@ __doc__ = """ ...@@ -8,7 +8,7 @@ __doc__ = """
cdef class Parrot: cdef class Parrot:
cdef void describe(self): cdef void describe(self):
print "This parrot is resting." print u"This parrot is resting."
def describe_python(self): def describe_python(self):
self.describe() self.describe()
...@@ -16,7 +16,7 @@ cdef class Parrot: ...@@ -16,7 +16,7 @@ cdef class Parrot:
cdef class Norwegian(Parrot): cdef class Norwegian(Parrot):
cdef void describe(self): cdef void describe(self):
print "Lovely plumage!" print u"Lovely plumage!"
def test(): def test():
cdef Parrot p1, p2 cdef Parrot p1, p2
......
__doc__ = """ __doc__ = u"""
g = r_lepage_3.Grail() >>> g = Grail()
g("spam", 42, ["tomato", "sandwich"]) >>> g("spam", 42, ["tomato", "sandwich"])
Grail called with: spam 42 ['tomato', 'sandwich']
""" """
cdef class Grail: cdef class Grail:
def __call__(self, x, y, z): def __call__(self, x, y, z):
print "Grail called with:", x, y, z print u"Grail called with:", x, y, z
__doc__ = """ __doc__ = u"""
>>> import re >>> import re
>>> t >>> t
('2',) (u'2',)
>>> t == re.search('(\\d+)', '-2.80 98\\n').groups() >>> t == re.search('(\\d+)', '-2.80 98\\n').groups()
True True
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u"(u'", u"('")
# this is a string constant test, not a test for 're' # this is a string constant test, not a test for 're'
import re import re
t = re.search('(\d+)', '-2.80 98\n').groups() t = re.search(u'(\d+)', u'-2.80 98\n').groups()
__doc__ = """ __doc__ = u"""
>>> b = Bicycle() >>> b = Bicycle()
>>> b.fall_off() >>> b.fall_off()
Falling off extremely hard Falling off extremely hard
...@@ -8,5 +8,5 @@ __doc__ = """ ...@@ -8,5 +8,5 @@ __doc__ = """
class Bicycle: class Bicycle:
def fall_off(self, how_hard = "extremely"): def fall_off(self, how_hard = u"extremely"):
print "Falling off", how_hard, "hard" print u"Falling off", how_hard, u"hard"
__doc__ = """ __doc__ = u"""
>>> boolExpressionsFail() >>> boolExpressionsFail()
'Not 2b' u'Not 2b'
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u" u'", u" '")
def boolExpressionsFail(): def boolExpressionsFail():
dict = {1: 1} dict = {1: 1}
if not dict.has_key("2b"): if not "2b" in dict:
return "Not 2b" return u"Not 2b"
else: else:
return "2b?" return u"2b?"
__doc__ = """ __doc__ = u"""
>>> print primes(20) >>> primes(20)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
""" """
......
__doc__ = """ __doc__ = u"""
>>> frighten() >>> frighten()
NOBODY expects the Spanish Inquisition! NOBODY expects the Spanish Inquisition!
""" """
def frighten(): def frighten():
print "NOBODY", "expects", "the Spanish Inquisition!" print u"NOBODY", u"expects", u"the Spanish Inquisition!"
__doc__ = """ __doc__ = u"""
>>> order() >>> order()
42 tons of spam! 42 tons of spam!
""" """
...@@ -9,7 +9,7 @@ class Spam: ...@@ -9,7 +9,7 @@ class Spam:
self.weight = w self.weight = w
def serve(self): def serve(self):
print self.weight, "tons of spam!" print self.weight, u"tons of spam!"
def order(): def order():
s = Spam(42) s = Spam(42)
......
__doc__ = """ __doc__ = u"""
>>> c = CoconutCarrier() >>> c = CoconutCarrier()
>>> c.swallow(name = "Brian") >>> c.swallow(name = "Brian")
This swallow is called Brian This swallow is called Brian
...@@ -12,8 +12,8 @@ class CoconutCarrier: ...@@ -12,8 +12,8 @@ class CoconutCarrier:
def swallow(self, name = None, airspeed = None, coconuts = None): def swallow(self, name = None, airspeed = None, coconuts = None):
if name is not None: if name is not None:
print "This swallow is called", name print u"This swallow is called", name
if airspeed is not None: if airspeed is not None:
print "This swallow is flying at", airspeed, "furlongs per fortnight" print u"This swallow is flying at", airspeed, u"furlongs per fortnight"
if coconuts is not None: if coconuts is not None:
print "This swallow is carrying", coconuts, "coconuts" print u"This swallow is carrying", coconuts, u"coconuts"
__doc__ = """ __doc__ = u"""
>>> x = spam() >>> x = spam()
>>> print repr(x) >>> print(repr(x))
'Ftang\\x00Ftang!' b'Ftang\\x00Ftang!'
""" """
import sys
if sys.version_info[0] < 3:
__doc__ = __doc__.replace(u" b'", u" '")
cdef extern from "string.h": cdef extern from "string.h":
void memcpy(char *d, char *s, int n) void memcpy(char *d, char *s, int n)
......
__doc__ = """ __doc__ = u"""
>>> s = Spam() >>> s = Spam()
>>> print s.get_tons() >>> s.get_tons()
17 17
>>> s.set_tons(42) >>> s.set_tons(42)
>>> print s.get_tons() >>> s.get_tons()
42 42
>>> s = None >>> s = None
42 tons of spam is history. 42 tons of spam is history.
...@@ -17,7 +17,7 @@ cdef class Spam: ...@@ -17,7 +17,7 @@ cdef class Spam:
self.tons = 17 self.tons = 17
def __dealloc__(self): def __dealloc__(self):
print self.tons, "tons of spam is history." print self.tons, u"tons of spam is history."
def get_tons(self): def get_tons(self):
return self.tons return self.tons
......
__doc__ = """ __doc__ = u"""
>>> eggs() >>> eggs()
Args: 1 2 3 Args: 1 2 3
Args: buckle my shoe Args: buckle my shoe
""" """
def spam(a, b, c): def spam(a, b, c):
print "Args:", a, b, c print u"Args:", a, b, c
def eggs(): def eggs():
spam(*(1,2,3)) spam(*(1,2,3))
spam(*["buckle","my","shoe"]) spam(*[u"buckle",u"my",u"shoe"])
__doc__ = """ __doc__ = u"""
>>> swallow("Brian", 42) >>> swallow("Brian", 42)
Name: Brian Name: Brian
Airspeed: 42 Airspeed: 42
...@@ -31,8 +31,8 @@ __doc__ = """ ...@@ -31,8 +31,8 @@ __doc__ = """
""" """
def swallow(name, airspeed, *args, **kwds): def swallow(name, airspeed, *args, **kwds):
print "Name:", name print u"Name:", name
print "Airspeed:", airspeed print u"Airspeed:", airspeed
print "Extra args:", args print u"Extra args:", args
print "Extra keywords:", kwds print u"Extra keywords:", kwds
__doc__ = """ __doc__ = u"""
>>> spam() >>> spam()
Args: () Args: ()
>>> spam(42) >>> spam(42)
...@@ -8,5 +8,5 @@ __doc__ = """ ...@@ -8,5 +8,5 @@ __doc__ = """
""" """
def spam(*args): def spam(*args):
print "Args:", args print u"Args:", args
__doc__ = """ __doc__ = u"""
>>> s = Spam() >>> s = Spam() #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (0 given) TypeError: function takes exactly 3 arguments (0 given)
""" """
import sys, re
if sys.version_info >= (2,6):
__doc__ = re.sub(u"Error: .*", u"Error: ...", __doc__)
cdef class Spam: cdef class Spam:
def __init__(self, a, b, int c): def __init__(self, a, b, int c):
......
__doc__ = """ __doc__ = """# disabled in Py3
>>> test(0) >>> test(0)
0L 0L
>>> test(1) >>> test(1)
......
__doc__ = """ __doc__ = u"""
>>> f() >>> f()
42 42
""" """
......
__doc__ = """ __doc__ = u"""
>>> f('test') >>> f('test')
>>> test_g() >>> test_g()
>>> test_h(5) >>> test_h(5)
......
__doc__ = """ __doc__ = u"""
>>> b = B() >>> b = B()
>>> b.t >>> b.t
{1: ((1, 2, 3),), 2: (1, 2, 3)} {1: ((1, 2, 3),), 2: (1, 2, 3)}
......
__doc__ = """ __doc__ = u"""
>>> z(1,9.2,'test') >>> z(1,9.2, b'test')
>>> failtype() >>> failtype()
Traceback (most recent call last): Traceback (most recent call last):
TypeError: an integer is required TypeError: an integer is required
>>> fail0(1,2) >>> fail0(1,2) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 2 arguments (0 given) TypeError: function takes exactly 2 arguments (0 given)
>>> fail1(1,2) >>> fail1(1,2) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 2 arguments (1 given) TypeError: function takes exactly 2 arguments (1 given)
""" """
import sys, re
if sys.version_info >= (2,6):
__doc__ = re.sub(u"Error: .*exactly.*", u"Error: ...", __doc__)
import sys
if sys.version_info[0] < 3:
__doc__ = __doc__.replace(u" b'", u" '")
def f(x, y): def f(x, y):
x = y x = y
......
__doc__ = """ __doc__ = u"""
>>> f() >>> f()
""" """
......
__doc__ = """ __doc__ = u"""
>>> l = [1,2,3,4] >>> l = [1,2,3,4]
>>> f(1, l, 2, 3) >>> f(1, l, 2, 3)
......
__doc__ = """ __doc__ = u"""
>>> class Test(object): >>> class Test(object):
... def __setitem__(self, key, value): ... def __setitem__(self, key, value):
... print key, value ... print((key, value))
... def __getitem__(self, key): ... def __getitem__(self, key):
... print key ... print(key)
... return self ... return self
>>> ellipsis(Test()) >>> ellipsis(Test())
...@@ -23,7 +23,7 @@ __doc__ = """ ...@@ -23,7 +23,7 @@ __doc__ = """
slice(1, 2, 3) slice(1, 2, 3)
>>> set(Test(), -11) >>> set(Test(), -11)
slice(1, 2, 3) -11 (slice(1, 2, 3), -11)
""" """
def ellipsis(o): def ellipsis(o):
......
__doc__ = """ __doc__ = u"""
>>> f() >>> f()
12.5 12.5
......
__doc__ = """ __doc__ = u"""
>>> spam(1,2,3) >>> spam(1,2,3)
(1, 2, 3) (1, 2, 3)
>>> spam(1,2) >>> spam(1,2) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (2 given) TypeError: function takes exactly 3 arguments (2 given)
>>> spam(1,2,3,4) >>> spam(1,2,3,4)
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (4 given) TypeError: function takes exactly 3 arguments (4 given)
>>> spam(1,2,3, a=1) >>> spam(1,2,3, a=1) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: 'a' is an invalid keyword argument for this function TypeError: 'a' is an invalid keyword argument for this function
...@@ -17,10 +17,10 @@ __doc__ = """ ...@@ -17,10 +17,10 @@ __doc__ = """
(1, 2, 3, (4,)) (1, 2, 3, (4,))
>>> grail(1,2,3,4,5,6,7,8,9) >>> grail(1,2,3,4,5,6,7,8,9)
(1, 2, 3, (4, 5, 6, 7, 8, 9)) (1, 2, 3, (4, 5, 6, 7, 8, 9))
>>> grail(1,2) >>> grail(1,2) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (2 given) TypeError: function takes exactly 3 arguments (2 given)
>>> grail(1,2,3, a=1) >>> grail(1,2,3, a=1) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: 'a' is an invalid keyword argument for this function TypeError: 'a' is an invalid keyword argument for this function
...@@ -31,7 +31,7 @@ __doc__ = """ ...@@ -31,7 +31,7 @@ __doc__ = """
TypeError: function takes at most 3 positional arguments (4 given) TypeError: function takes at most 3 positional arguments (4 given)
>>> swallow(1,2,3, a=1, b=2) >>> swallow(1,2,3, a=1, b=2)
(1, 2, 3, (('a', 1), ('b', 2))) (1, 2, 3, (('a', 1), ('b', 2)))
>>> swallow(1,2,3, x=1) >>> swallow(1,2,3, x=1) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: keyword parameter 'x' was given by position and by name TypeError: keyword parameter 'x' was given by position and by name
...@@ -43,7 +43,7 @@ __doc__ = """ ...@@ -43,7 +43,7 @@ __doc__ = """
(1, 2, 3, (), (('a', 1),)) (1, 2, 3, (), (('a', 1),))
>>> creosote(1,2,3,4, a=1, b=2) >>> creosote(1,2,3,4, a=1, b=2)
(1, 2, 3, (4,), (('a', 1), ('b', 2))) (1, 2, 3, (4,), (('a', 1), ('b', 2)))
>>> creosote(1,2,3,4, x=1) >>> creosote(1,2,3,4, x=1) #doctest: +ELLIPSIS
Traceback (most recent call last): Traceback (most recent call last):
TypeError: keyword parameter 'x' was given by position and by name TypeError: keyword parameter 'x' was given by position and by name
...@@ -84,8 +84,16 @@ __doc__ = """ ...@@ -84,8 +84,16 @@ __doc__ = """
(1, ('a', 1), ('b', 2)) (1, ('a', 1), ('b', 2))
""" """
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)
cdef sorteditems(d): cdef sorteditems(d):
l = d.items() l = list(d.items())
l.sort() l.sort()
return tuple(l) return tuple(l)
......
__doc__ = u"""
>>> class1.plus1(1)
2
>>> class2.plus1(1)
2
>>> class3.plus1(1)
2
"""
def f_plus(a):
return a + 1
class class1:
plus1 = f_plus
class class2(object):
plus1 = f_plus
cdef class class3:
plus1 = f_plus
__doc__ = """ __doc__ = u"""
>>> c = C() >>> c = C()
>>> print c.x >>> c.x
foo b'foo'
""" """
import sys
if sys.version_info[0] < 3:
__doc__ = __doc__.replace(u" b'", u" '")
class C: class C:
x = "foo" x = "foo"
__doc__ = """ __doc__ = u"""
>>> s('test') >>> s('test', **encoding)
'test' b'test'
>>> z >>> z
'test' b'test'
>>> c('testing') >>> c('testing')
'testing' b'testing'
>>> sub('testing a subtype') >>> sub('testing a subtype')
'testing a subtype' b'testing a subtype'
>>> subs('testing a subtype') >>> subs('testing a subtype', **encoding)
'testing a subtype' b'testing a subtype'
# >>> csub('testing a subtype') # >>> csub('testing a subtype')
# 'testing a subtype' # 'testing a subtype'
...@@ -16,20 +16,27 @@ __doc__ = """ ...@@ -16,20 +16,27 @@ __doc__ = """
# 'testing a subtype' # 'testing a subtype'
""" """
import sys
if sys.version_info[0] >= 3:
encoding = {u'encoding' : u'ASCII'}
else:
encoding = {}
__doc__ = __doc__.replace(u" b'", u" '")
s = str s = str
z = str('test') z = str('test')
def c(string): def c(string):
return str(string) return str(string, **encoding)
class subs(str): class subs(str):
pass pass
def sub(string): def sub(string):
return subs(string) return subs(string, **encoding)
#cdef class subs(str): #cdef class subs(str):
# pass # pass
#def csub(string): #def csub(string):
# return csubs(string) # return csubs(string, **encoding)
__doc__ = ur"""
>>> s1
b'abc\x11'
>>> s1 == b'abc\x11'
True
>>> len(s1)
4
>>> s2
b'abc\\x11'
>>> s2 == br'abc\x11'
True
>>> len(s2)
7
>>> s3
b'abc\\x11'
>>> s3 == bR'abc\x11'
True
>>> len(s3)
7
>>> s4
b'abc\x11'
>>> s4 == b'abc\x11'
True
>>> len(s4)
4
>>> s5
b'abc\x11'
>>> s5 == B'abc\x11'
True
>>> len(s5)
4
>>> s6
b'abc\\x11'
>>> s6 == br'abc\x11'
True
>>> len(s6)
7
>>> s7
b'abc\\x11'
>>> s7 == Br'abc\x11'
True
>>> len(s7)
7
>>> s8
b'abc\\x11'
>>> s8 == bR'abc\x11'
True
>>> len(s8)
7
>>> s9
b'abc\\x11'
>>> s9 == BR'abc\x11'
True
>>> len(s9)
7
>>> u1
u'abc\x11'
>>> u1 == u'abc\x11'
True
>>> len(u1)
4
>>> u2
u'abc\x11'
>>> u2 == U'abc\x11'
True
>>> len(u2)
4
>>> u3
u'abc\\x11'
>>> u3 == ur'abc\x11'
True
>>> len(u3)
7
>>> u4
u'abc\\x11'
>>> u4 == Ur'abc\x11'
True
>>> len(u4)
7
>>> u5
u'abc\\x11'
>>> u5 == uR'abc\x11'
True
>>> len(u5)
7
>>> u6
u'abc\\x11'
>>> u6 == UR'abc\x11'
True
>>> len(u6)
7
"""
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u" u'", u" '").replace(u" U'", u" '").replace(u" ur'", u" r'").replace(u" uR'", u" R'").replace(u" Ur'", u" r'").replace(u" UR'", u" R'")
else:
__doc__ = __doc__.replace(u" b'", u" '").replace(u" B'", u" '").replace(u" br'", u" r'").replace(u" bR'", u" R'").replace(u" Br'", u" r'").replace(u" BR'", u" R'")
s1 = "abc\x11"
s2 = r"abc\x11"
s3 = R"abc\x11"
s4 = b"abc\x11"
s5 = B"abc\x11"
s6 = br"abc\x11"
s7 = Br"abc\x11"
s8 = bR"abc\x11"
s9 = BR"abc\x11"
u1 = u"abc\x11"
u2 = U"abc\x11"
u3 = ur"abc\x11"
u4 = Ur"abc\x11"
u5 = uR"abc\x11"
u6 = UR"abc\x11"
__doc__ = """ __doc__ = u"""
>>> f() >>> f()
(-1, -1) (-1, -1)
>>> p() >>> p()
......
__doc__ = u"""
>>> result() == (99, 17*42, 17*42)
True
"""
cdef int i, j, k cdef int i, j, k
i = 17; j = 42; k = i * j i = 17; j = 42; k = i * j
if j > k: i = 88 if j > k: i = 88
else: i = 99; j = k else: i = 99; j = k
def result():
return (i,j,k)
__doc__ = """ __doc__ = u"""
>>> f(1,2,3,4,5) >>> f(1,2,3,4,5)
() ()
>>> g(1,2,3,4,5) >>> g(1,2,3,4,5)
......
__doc__ = """ __doc__ = u"""
>>> test1( (1,2,3) ) >>> test1( (1,2,3) )
1 1
>>> test3( (1,2,3) ) >>> test3( (1,2,3) )
......
__doc__ = """ __doc__ = u"""
>>> u('test') >>> u('test')
u'test' u'test'
>>> z >>> z
...@@ -16,8 +16,12 @@ __doc__ = """ ...@@ -16,8 +16,12 @@ __doc__ = """
# u'testing a C subtype' # u'testing a C subtype'
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u" u'", u" '")
u = unicode u = unicode
z = unicode('test') z = unicode(u'test')
def c(string): def c(string):
return unicode(string) return unicode(string)
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
__doc__ = r""" __doc__ = r"""
>>> sa >>> sa
'abc' b'abc'
>>> ua >>> ua
u'abc' u'abc'
>>> b >>> b
...@@ -19,7 +19,7 @@ __doc__ = r""" ...@@ -19,7 +19,7 @@ __doc__ = r"""
u'S\xf8k ik\xfc\xd6\xe4abc' u'S\xf8k ik\xfc\xd6\xe4abc'
>>> null >>> null
u'\x00' u'\x00'
""" + """ """.decode(u"ASCII") + """
>>> len(sa) >>> len(sa)
3 3
>>> len(ua) >>> len(ua)
...@@ -38,9 +38,7 @@ __doc__ = r""" ...@@ -38,9 +38,7 @@ __doc__ = r"""
12 12
>>> len(null) >>> len(null)
1 1
""" + u""" """.decode(u"ASCII") + u"""
>>> sa == 'abc'
True
>>> ua == u'abc' >>> ua == u'abc'
True True
>>> b == u'123' >>> b == u'123'
...@@ -63,6 +61,12 @@ __doc__ = r""" ...@@ -63,6 +61,12 @@ __doc__ = r"""
True True
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u" u'", u" '")
else:
__doc__ = __doc__.replace(u" b'", u" '")
sa = 'abc' sa = 'abc'
ua = u'abc' ua = u'abc'
...@@ -72,5 +76,5 @@ d = u'üÖä' ...@@ -72,5 +76,5 @@ d = u'üÖä'
e = u'\x03\x67\xf8\uf8d2Søk ik' e = u'\x03\x67\xf8\uf8d2Søk ik'
f = u'\xf8' f = u'\xf8'
add = u'Søk ik' + u'üÖä' + 'abc' add = u'Søk ik' + u'üÖä' + u'abc'
null = u'\x00' null = u'\x00'
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
__doc__ = r""" __doc__ = r"""
>>> sa >>> sa
'abc' b'abc'
>>> ua >>> ua
u'abc' u'abc'
>>> b >>> b
...@@ -25,7 +25,7 @@ __doc__ = r""" ...@@ -25,7 +25,7 @@ __doc__ = r"""
u'S\xf8k ik\xfc\xd6\xe4abc' u'S\xf8k ik\xfc\xd6\xe4abc'
>>> null >>> null
u'\x00' u'\x00'
""" + """ """.decode(u"ASCII") + """
>>> len(sa) >>> len(sa)
3 3
>>> len(ua) >>> len(ua)
...@@ -44,9 +44,7 @@ __doc__ = r""" ...@@ -44,9 +44,7 @@ __doc__ = r"""
12 12
>>> len(null) >>> len(null)
1 1
""" + u""" """.decode(u"ASCII") + u"""
>>> sa == 'abc'
True
>>> ua == u'abc' >>> ua == u'abc'
True True
>>> b == u'123' >>> b == u'123'
...@@ -69,6 +67,12 @@ __doc__ = r""" ...@@ -69,6 +67,12 @@ __doc__ = r"""
True True
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u" u'", u" '")
else:
__doc__ = __doc__.replace(u" b'", u" '")
sa = 'abc' sa = 'abc'
ua = u'abc' ua = u'abc'
...@@ -78,5 +82,5 @@ d = u'üÖä' ...@@ -78,5 +82,5 @@ d = u'üÖä'
e = u'\x03\x67\xf8\uf8d2Søk ik' e = u'\x03\x67\xf8\uf8d2Søk ik'
f = u'\xf8' f = u'\xf8'
add = u'Søk ik' + u'üÖä' + 'abc' add = u'Søk ik' + u'üÖä' + u'abc'
null = u'\x00' null = u'\x00'
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
__doc__ = r""" __doc__ = r"""
>>> sa >>> sa
'abc' b'abc'
>>> ua >>> ua
u'abc' u'abc'
>>> b >>> b
...@@ -19,7 +19,7 @@ __doc__ = r""" ...@@ -19,7 +19,7 @@ __doc__ = r"""
u'S\xf8k ik\xfc\xd6\xe4abc' u'S\xf8k ik\xfc\xd6\xe4abc'
>>> null >>> null
u'\x00' u'\x00'
""" + """ """.decode(u"ASCII") + """
>>> len(sa) >>> len(sa)
3 3
>>> len(ua) >>> len(ua)
...@@ -38,9 +38,7 @@ __doc__ = r""" ...@@ -38,9 +38,7 @@ __doc__ = r"""
12 12
>>> len(null) >>> len(null)
1 1
""" + u""" """.decode(u"ASCII") + u"""
>>> sa == 'abc'
True
>>> ua == u'abc' >>> ua == u'abc'
True True
>>> b == u'123' >>> b == u'123'
...@@ -63,6 +61,12 @@ __doc__ = r""" ...@@ -63,6 +61,12 @@ __doc__ = r"""
True True
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u" u'", u" '")
else:
__doc__ = __doc__.replace(u" b'", u" '")
sa = 'abc' sa = 'abc'
ua = u'abc' ua = u'abc'
...@@ -72,5 +76,5 @@ d = u' ...@@ -72,5 +76,5 @@ d = u'
e = u'\x03\x67\xf8\uf8d2Sk ik' e = u'\x03\x67\xf8\uf8d2Sk ik'
f = u'\xf8' f = u'\xf8'
add = u'Sk ik' + u'' + 'abc' add = u'Sk ik' + u'' + u'abc'
null = u'\x00' null = u'\x00'
__doc__ = """ __doc__ = u"""
>>> f(1, 2, 3) >>> f(1, 2, 3)
(-3, -4, 1) (-3, -4, 1)
""" """
......
__doc__ = """ __doc__ = u"""
>>> f(1, (2,), (3,4,5), (6,(7,(8,9))), 0) >>> f(1, (2,), (3,4,5), (6,(7,(8,9))), 0)
(8, 9, (8, 9), (6, (7, (8, 9))), 0) (8, 9, (8, 9), (6, (7, (8, 9))), 0)
""" """
......
__doc__ = """ __doc__ = u"""
>>> unpack_normal([1,2]) >>> unpack_normal([1,2])
(1, 2) (1, 2)
>>> unpack_normal([1,2,3]) # doctest: +ELLIPSIS >>> unpack_normal([1,2,3]) # doctest: +ELLIPSIS
......
__doc__ = """ __doc__ = u"""
>>> swallow() >>> swallow()
""" """
......
__doc__ = u"""
>>> test() == 55 + 66
True
"""
def test(): def test():
cdef int a,b cdef int a,b
foo=(55,66) foo=(55,66)
a,b=foo a,b=foo
return a + b
cdef object f(object x): __doc__ = u"""
>>> f(1)
(1, 17)
>>> g()
1
"""
def f(x):
cdef int y cdef int y
#z = 42 z = 42
with nogil: with nogil:
pass#y = 17 y = 17
#z = 88 z = x
return z,y
cdef object g(): def g():
with nogil: with nogil:
h() h()
return 1
cdef int h() except -1: cdef int h() except -1:
pass pass
__doc__ = """ __doc__ = u"""
>>> x >>> x
5L 5L
""" """
import sys
if sys.version_info[0] >= 3:
__doc__ = __doc__.replace(u"5L", u"5")
cdef unsigned int ui cdef unsigned int ui
ui = 5 ui = 5
x = ui x = ui
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