Commit a2236526 authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

Merge (++, see details)

Also fixed a bug that the merge revealed.
Also added CythonTransform.current_directives.
parents d2f4df7a e05e7c05
......@@ -11,3 +11,5 @@ build/
*.orig
*.rej
*.dep
tags
import re
from Cython.Compiler.Visitor import CythonTransform
from Cython.Compiler.Nodes import DefNode, CFuncDefNode
from Cython.Compiler.Errors import CompileError
from Cython.Compiler.StringEncoding import EncodedString
from Cython.Compiler import Options
class EmbedSignature(CythonTransform):
SPECIAL_METHOD_RE = re.compile(r'__\w+__')
def __init__(self, context):
super(EmbedSignature, self).__init__(context)
self.denv = None # XXX
self.is_in_class = False
self.class_name = None
def _fmt_basic_c_type_modifiers(self, ctype):
longness = ctype.longness
modifiers = ''
if longness < 0:
modifiers = 'short '
elif longness > 0:
modifiers = 'long ' * longness
signed = ctype.signed
if signed == 0:
modifiers = 'unsigned ' + modifiers
elif signed == 2:
modifiers = 'signed ' + modifiers
return modifiers[:-1] # strip final space
def _fmt_arg_type(self, arg):
try:
base_type = arg.base_type
arg_type = base_type.name
except AttributeError:
return ''
if base_type.is_basic_c_type:
modifiers = self._fmt_basic_c_type_modifiers(base_type)
if modifiers:
arg_type = '%s %s' % (modifiers, arg_type)
return arg_type
def _fmt_arg_name(self, arg):
try:
return arg.declarator.name
except AttributeError:
return arg.declarator.base.name
def _fmt_arg_defv(self, arg):
if not arg.default:
return None
try:
denv = self.denv # XXX
ctval = arg.default.compile_time_value(self.denv)
return '%s' % ctval
except Exception:
try:
return arg.default.name # XXX
except AttributeError:
return '<???>'
def _fmt_arg(self, arg):
arg_type = self._fmt_arg_type(arg)
arg_name = self._fmt_arg_name(arg)
arg_defv = self._fmt_arg_defv(arg)
doc = arg_name
if arg_type:
doc = ('%s ' % arg_type) + doc
if arg_defv:
doc = doc + ('=%s' % arg_defv)
return doc
def _fmt_arglist(self, args,
npargs=0, pargs=None,
nkargs=0, kargs=None):
arglist = []
for arg in args:
arg_doc = self._fmt_arg(arg)
arglist.append(arg_doc)
if pargs:
arglist.insert(npargs, '*%s' % pargs.name)
elif nkargs:
arglist.insert(npargs, '*')
if kargs:
arglist.append('**%s' % kargs.name)
return arglist
def _fmt_ret_type(self, ret):
ret_type = ret.name
if ret_type is None:
return ''
modifiers = self._fmt_basic_c_type_modifiers(ret)
if modifiers:
ret_type = '%s %s' % (modifiers, ret_type)
return ret_type
def _fmt_signature(self, cls_name, func_name, args,
npargs=0, pargs=None,
nkargs=0, kargs=None,
return_type=None):
arglist = self._fmt_arglist(args,
npargs, pargs,
nkargs, kargs)
arglist_doc = ', '.join(arglist)
func_doc = '%s(%s)' % (func_name, arglist_doc)
if cls_name:
func_doc = '%s.%s' % (cls_name, func_doc)
if return_type:
ret_doc = self._fmt_ret_type(return_type)
if ret_doc:
func_doc = '%s -> %s' % (func_doc, ret_doc)
return func_doc
def _embed_signature(self, signature, node_doc):
if node_doc:
return signature + '\n' + node_doc
else:
return signature
def __call__(self, node):
if not Options.docstrings:
return node
else:
return super(EmbedSignature, self).__call__(node)
def visit_ClassDefNode(self, node):
oldincls = self.is_in_class
oldname = self.class_name
self.is_in_class = True
try:
# PyClassDefNode
self.class_name = node.name
except AttributeError:
# CClassDefNode
self.class_name = node.class_name
self.visitchildren(node)
self.is_in_class = oldincls
self.class_name = oldname
return node
def visit_FuncDefNode(self, node):
if not self.current_directives['embedsignature']:
return node
signature = None
if type(node) is DefNode: # def FOO(...):
special_method = (self.is_in_class and \
self.SPECIAL_METHOD_RE.match(node.name))
if not special_method:
nkargs = getattr(node, 'num_kwonly_args', 0)
npargs = len(node.args) - nkargs
signature = self._fmt_signature(
self.class_name, node.name, node.args,
npargs, node.star_arg,
nkargs, node.starstar_arg,
return_type=None)
elif type(node) is CFuncDefNode:
if node.overridable: # cpdef FOO(...):
signature = self._fmt_signature(
self.class_name, node.declarator.base.name,
node.declarator.args,
return_type=node.base_type)
else: # should not fall here ...
assert False
if signature:
new_doc = self._embed_signature(signature, node.doc)
node.doc = EncodedString(new_doc) # XXX
return node
This diff is collapsed.
......@@ -104,14 +104,15 @@ builtin_types_table = [
builtin_structs_table = [
('Py_buffer', 'Py_buffer',
[("buf", PyrexTypes.c_void_ptr_type),
("obj", PyrexTypes.py_object_type),
("len", PyrexTypes.c_py_ssize_t_type),
("itemsize", PyrexTypes.c_py_ssize_t_type),
("readonly", PyrexTypes.c_bint_type),
("format", PyrexTypes.c_char_ptr_type),
("ndim", PyrexTypes.c_int_type),
("format", PyrexTypes.c_char_ptr_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),
])
]
......
......@@ -36,7 +36,7 @@ Options:
-D, --no-docstrings Remove docstrings.
-a, --annotate Produce a colorized HTML version of the source.
--convert-range Convert for loops using range() function to for...from loops.
--line-directives Produce #line directives pointing to the .pyx source
--cplus Output a c++ rather than c file.
-X, --directive <name>=<value>[,<name=value,...] Overrides a compiler directive
"""
......@@ -114,6 +114,8 @@ def parse_command_line(args):
Options.annotate = True
elif option == "--convert-range":
Options.convert_range = True
elif option == "--line-directives":
options.emit_linenums = True
elif option in ("-X", "--directive"):
try:
options.pragma_overrides = Options.parse_option_list(pop_arg())
......
......@@ -167,13 +167,14 @@ class GlobalState(object):
directives = {}
def __init__(self, rootwriter):
def __init__(self, rootwriter, emit_linenums=False):
self.filename_table = {}
self.filename_list = []
self.input_file_contents = {}
self.used_utility_code = set()
self.declared_cnames = {}
self.pystring_table_needed = False
self.emit_linenums = emit_linenums
def initwriters(self, rootwriter):
self.utilprotowriter = rootwriter.new_writer()
......@@ -384,6 +385,8 @@ class GlobalState(object):
writer.insert(self.utilprotowriter)
def put_utility_code_defs(self, writer):
if self.emit_linenums:
writer.write('\n#line 1 "cython_utility"\n')
writer.insert(self.utildefwriter)
......@@ -421,19 +424,21 @@ class CCodeWriter(object):
# generation (labels and temps state etc.)
# globalstate GlobalState contains state global for a C file (input file info,
# utility code, declared constants etc.)
# emit_linenums boolean whether or not to write #line pragmas
def __init__(self, create_from=None, buffer=None, copy_formatting=False):
def __init__(self, create_from=None, buffer=None, copy_formatting=False, emit_linenums=None):
if buffer is None: buffer = StringIOTree()
self.buffer = buffer
self.marker = None
self.last_marker_line = 0
self.source_desc = ""
self.funcstate = None
self.level = 0
self.bol = 1
if create_from is None:
# Root CCodeWriter
self.globalstate = GlobalState(self)
self.globalstate = GlobalState(self, emit_linenums=emit_linenums)
self.globalstate.initwriters(self)
# ^^^ need seperate step because this will reference self.globalstate
else:
......@@ -443,6 +448,10 @@ class CCodeWriter(object):
if copy_formatting:
self.level = create_from.level
self.bol = create_from.bol
if emit_linenums is None:
self.emit_linenums = self.globalstate.emit_linenums
else:
self.emit_linenums = emit_linenums
def create_new(self, create_from, buffer, copy_formatting):
# polymorphic constructor -- very slightly more versatile
......@@ -510,6 +519,8 @@ class CCodeWriter(object):
def putln(self, code = ""):
if self.marker and self.bol:
self.emit_marker()
if self.emit_linenums and self.last_marker_line != 0:
self.write('\n#line %s "%s"\n' % (self.last_marker_line, self.source_desc))
if code:
self.put(code)
self.write("\n");
......@@ -586,7 +597,8 @@ class CCodeWriter(object):
marker = u'"%s":%d\n%s\n' % (
source_desc.get_escaped_description(), line, u'\n'.join(lines))
self.marker = (line, marker)
if self.emit_linenums:
self.source_desc = source_desc.get_escaped_description()
def put_label(self, lbl):
if lbl in self.funcstate.labels_used:
......
......@@ -1423,7 +1423,7 @@ class IndexNode(ExprNode):
elif not skip_child_analysis:
self.index.analyse_types(env)
if self.base.type.is_pyobject:
if self.index.type.is_int:
if self.index.type.is_int and not self.index.type.is_longlong:
self.original_index_type = self.index.type
self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
if getting:
......@@ -1886,6 +1886,9 @@ class SimpleCallNode(CallNode):
arg_code = actual_arg.result_as(formal_arg.type)
arg_list_code.append(arg_code)
if func_type.is_overridable:
arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
if func_type.optional_arg_count:
if expected_nargs == actual_nargs:
optional_args = 'NULL'
......@@ -1897,9 +1900,9 @@ class SimpleCallNode(CallNode):
arg_list_code.append(actual_arg.result_code)
result = "%s(%s)" % (self.function.result_code,
join(arg_list_code, ", "))
if self.wrapper_call or \
self.function.entry.is_unbound_cmethod and self.function.entry.type.is_overridable:
result = "(%s = 1, %s)" % (Naming.skip_dispatch_cname, result)
# if self.wrapper_call or \
# self.function.entry.is_unbound_cmethod and self.function.entry.type.is_overridable:
# result = "(%s = 1, %s)" % (Naming.skip_dispatch_cname, result)
return result
def generate_result_code(self, code):
......@@ -2641,7 +2644,7 @@ class ListComprehensionAppendNode(ExprNode):
self.is_temp = 1
def generate_result_code(self, code):
code.putln("%s = PyList_Append(%s, %s); %s" %
code.putln("%s = PyList_Append(%s, (PyObject*)%s); %s" %
(self.result_code,
self.target.result_code,
self.expr.result_code,
......
......@@ -80,6 +80,7 @@ class Context:
from ParseTreeTransforms import AnalyseDeclarationsTransform, AnalyseExpressionsTransform
from ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform
from ParseTreeTransforms import InterpretCompilerDirectives
from AutoDocTransforms import EmbedSignature
from Optimize import FlattenInListTransform, SwitchTransform, OptimizeRefcounting
from Buffer import IntroduceBufferAuxiliaryVars
from ModuleNode import check_c_classes
......@@ -96,6 +97,7 @@ class Context:
PostParse(self),
_specific_post_parse,
InterpretCompilerDirectives(self, self.pragma_overrides),
EmbedSignature(self),
FlattenInListTransform(),
WithTransform(self),
DecoratorTransform(self),
......@@ -727,7 +729,8 @@ default_options = dict(
timestamps = None,
verbose = 0,
quiet = 0,
pragma_overrides = {}
pragma_overrides = {},
emit_linenums = False,
)
if sys.platform == "mac":
from Cython.Mac.MacSystem import c_compile, c_link, CCompilerError
......
......@@ -3,7 +3,6 @@
#
import os, time
from cStringIO import StringIO
from PyrexTypes import CPtrType
import Future
......@@ -44,6 +43,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
# directives Top-level compiler directives
child_attrs = ["body"]
directives = None
def analyse_declarations(self, env):
if Options.embed_pos_in_docstring:
......@@ -242,7 +242,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if Options.annotate or options.annotate:
code = Annotate.AnnotationCCodeWriter()
else:
code = Code.CCodeWriter()
code = Code.CCodeWriter(emit_linenums=options.emit_linenums)
h_code = code.insertion_point()
self.generate_module_preamble(env, modules, h_code)
......@@ -432,14 +432,15 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("")
code.putln(" typedef struct {")
code.putln(" void *buf;")
code.putln(" PyObject *obj;")
code.putln(" Py_ssize_t len;")
code.putln(" Py_ssize_t itemsize;")
code.putln(" int readonly;")
code.putln(" const char *format;")
code.putln(" int ndim;")
code.putln(" char *format;")
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("")
......@@ -463,6 +464,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln(" #define Py_TPFLAGS_HAVE_INDEX 0")
code.putln("#endif")
code.putln("#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)")
code.putln(" #define Py_TPFLAGS_HAVE_NEWBUFFER 0")
code.putln("#endif")
code.putln("#if PY_MAJOR_VERSION >= 3")
code.putln(" #define PyBaseString_Type PyUnicode_Type")
code.putln(" #define PyString_Type PyBytes_Type")
......@@ -761,10 +766,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
dll_linkage = dll_linkage)
if entry.visibility == 'private':
storage_class = "static "
elif entry.visibility == 'extern':
storage_class = "%s " % Naming.extern_c_macro
else:
storage_class = ""
storage_class = "%s " % Naming.extern_c_macro
code.putln("%s%s; /*proto*/" % (
storage_class,
header))
......@@ -872,7 +875,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
else:
code.put_init_var_to_py_none(entry, "p->%s")
entry = scope.lookup_here("__new__")
if entry:
if entry and entry.is_special:
if entry.trivial_signature:
cinit_args = "o, %s, NULL" % Naming.empty_tuple
else:
......@@ -1958,11 +1961,11 @@ builtin_module_name_utility_code = [
import_module_utility_code = [
"""
static PyObject *__Pyx_ImportModule(char *name); /*proto*/
static PyObject *__Pyx_ImportModule(const char *name); /*proto*/
""","""
#ifndef __PYX_HAVE_RT_ImportModule
#define __PYX_HAVE_RT_ImportModule
static PyObject *__Pyx_ImportModule(char *name) {
static PyObject *__Pyx_ImportModule(const char *name) {
PyObject *py_name = 0;
PyObject *py_module = 0;
......@@ -1987,29 +1990,32 @@ bad:
type_import_utility_code = [
"""
static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size); /*proto*/
static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, long size); /*proto*/
""","""
#ifndef __PYX_HAVE_RT_ImportType
#define __PYX_HAVE_RT_ImportType
static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
long size)
{
PyObject *py_module = 0;
PyObject *result = 0;
PyObject *py_name = 0;
py_module = __Pyx_ImportModule(module_name);
if (!py_module)
goto bad;
#if PY_MAJOR_VERSION < 3
py_name = PyString_FromString(module_name);
py_name = PyString_FromString(class_name);
#else
py_name = PyUnicode_FromString(module_name);
py_name = PyUnicode_FromString(class_name);
#endif
if (!py_name)
goto bad;
py_module = __Pyx_ImportModule(module_name);
if (!py_module)
goto bad;
result = PyObject_GetAttrString(py_module, class_name);
result = PyObject_GetAttr(py_module, py_name);
Py_DECREF(py_name);
py_name = 0;
Py_DECREF(py_module);
py_module = 0;
if (!result)
goto bad;
if (!PyType_Check(result)) {
......@@ -2026,7 +2032,7 @@ static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
}
return (PyTypeObject *)result;
bad:
Py_XDECREF(py_name);
Py_XDECREF(py_module);
Py_XDECREF(result);
return 0;
}
......
......@@ -44,7 +44,7 @@ vtabstruct_prefix = pyrex_prefix + "vtabstruct_"
opt_arg_prefix = pyrex_prefix + "opt_args_"
args_cname = pyrex_prefix + "args"
kwdlist_cname = pyrex_prefix + "argnames"
pykwdlist_cname = pyrex_prefix + "pyargnames"
obj_base_cname = pyrex_prefix + "base"
builtins_cname = pyrex_prefix + "b"
preimport_cname = pyrex_prefix + "i"
......@@ -76,7 +76,6 @@ print_function_kwargs = pyrex_prefix + "print_kwargs"
cleanup_cname = pyrex_prefix + "module_cleanup"
pymoduledef_cname = pyrex_prefix + "moduledef"
optional_args_cname = pyrex_prefix + "optional_args"
no_opt_args = pyrex_prefix + "no_opt_args"
import_star = pyrex_prefix + "import_star"
import_star_set = pyrex_prefix + "import_star_set"
cur_scope_cname = pyrex_prefix + "cur_scope"
......@@ -95,6 +94,10 @@ exc_lineno_name = pyrex_prefix + "exc_lineno"
exc_vars = (exc_type_name, exc_value_name, exc_tb_name)
exc_save_vars = (pyrex_prefix + 'save_exc_type',
pyrex_prefix + 'save_exc_value',
pyrex_prefix + 'save_exc_tb')
api_name = pyrex_prefix + "capi__"
h_guard_prefix = "__PYX_HAVE__"
......
This diff is collapsed.
......@@ -56,9 +56,8 @@ class SwitchTransform(Visitor.VisitorTransform):
def visit_IfStatNode(self, node):
self.visitchildren(node)
if len(node.if_clauses) < 3:
return node
common_var = None
case_count = 0
cases = []
for if_clause in node.if_clauses:
var, conditions = self.extract_conditions(if_clause.condition)
......@@ -70,9 +69,12 @@ class SwitchTransform(Visitor.VisitorTransform):
return node
else:
common_var = var
case_count += len(conditions)
cases.append(Nodes.SwitchCaseNode(pos = if_clause.pos,
conditions = conditions,
body = if_clause.body))
if case_count < 2:
return node
common_var = unwrap_node(common_var)
return Nodes.SwitchStatNode(pos = node.pos,
......
......@@ -57,12 +57,14 @@ c_line_in_traceback = 1
# Declare pragmas
option_types = {
'boundscheck' : bool,
'nonecheck' : bool
'nonecheck' : bool,
'embedsignature' : bool
}
option_defaults = {
'boundscheck' : True,
'nonecheck' : False
'nonecheck' : False,
'embedsignature' : False,
}
def parse_option_value(name, value):
......
......@@ -80,7 +80,7 @@ class NormalizeTree(CythonTransform):
class PostParseError(CompileError): pass
# error strings checked by unit tests, so define them
ERR_CDEF_INCLASS = 'Cannot assign default value to cdef class attributes'
ERR_CDEF_INCLASS = 'Cannot assign default value to fields in cdef classes, structs or unions'
ERR_BUF_LOCALONLY = 'Buffer types only allowed as function local variables'
ERR_BUF_DEFAULTS = 'Invalid buffer defaults specification (see docs)'
ERR_INVALID_SPECIALATTR_TYPE = 'Special attributes must not have a type declared'
......@@ -130,31 +130,33 @@ class PostParse(CythonTransform):
def visit_ModuleNode(self, node):
self.scope_type = 'module'
self.scope_node = node
self.visitchildren(node)
return node
def visit_ClassDefNode(self, node):
prev = self.scope_type
self.scope_type = 'class'
self.classnode = node
def visit_scope(self, node, scope_type):
prev = self.scope_type, self.scope_node
self.scope_type = scope_type
self.scope_node = node
self.visitchildren(node)
self.scope_type = prev
del self.classnode
self.scope_type, self.scope_node = prev
return node
def visit_ClassDefNode(self, node):
return self.visit_scope(node, 'class')
def visit_FuncDefNode(self, node):
prev = self.scope_type
self.scope_type = 'function'
self.visitchildren(node)
self.scope_type = prev
return node
return self.visit_scope(node, 'function')
def visit_CStructOrUnionDefNode(self, node):
return self.visit_scope(node, 'struct')
# cdef variables
def handle_bufferdefaults(self, decl):
if not isinstance(decl.default, DictNode):
raise PostParseError(decl.pos, ERR_BUF_DEFAULTS)
self.classnode.buffer_defaults_node = decl.default
self.classnode.buffer_defaults_pos = decl.pos
self.scope_node.buffer_defaults_node = decl.default
self.scope_node.buffer_defaults_pos = decl.pos
def visit_CVarDefNode(self, node):
# This assumes only plain names and pointers are assignable on
......@@ -171,8 +173,8 @@ class PostParse(CythonTransform):
declbase = declbase.base
if isinstance(declbase, CNameDeclaratorNode):
if declbase.default is not None:
if self.scope_type == 'class':
if isinstance(self.classnode, CClassDefNode):
if self.scope_type in ('class', 'struct'):
if isinstance(self.scope_node, CClassDefNode):
handler = self.specialattribute_handlers.get(decl.name)
if handler:
if decl is not declbase:
......@@ -346,7 +348,7 @@ class InterpretCompilerDirectives(CythonTransform):
assert isinstance(body, StatListNode), body
retbody = self.visit_Node(body)
directive = CompilerDirectivesNode(pos=retbody.pos, body=retbody,
directives=options)
directives=newoptions)
self.options = oldoptions
return directive
......
......@@ -229,6 +229,8 @@ def p_typecast(s):
pos = s.position()
s.next()
base_type = p_c_base_type(s)
if base_type.name is None:
s.error("Unknown type")
declarator = p_c_declarator(s, empty = 1)
if s.sy == '?':
s.next()
......@@ -297,7 +299,14 @@ def p_call(s, function):
keyword_args = []
star_arg = None
starstar_arg = None
while s.sy not in ('*', '**', ')'):
while s.sy not in ('**', ')'):
if s.sy == '*':
if star_arg:
s.error("only one star-arg parameter allowed",
pos = s.position())
s.next()
star_arg = p_simple_expr(s)
else:
arg = p_simple_expr(s)
if s.sy == '=':
s.next()
......@@ -313,16 +322,14 @@ def p_call(s, function):
if keyword_args:
s.error("Non-keyword arg following keyword arg",
pos = arg.pos)
if star_arg:
s.error("Non-keyword arg following star-arg",
pos = arg.pos)
positional_args.append(arg)
if s.sy != ',':
break
s.next()
if s.sy == '*':
s.next()
star_arg = p_simple_expr(s)
if s.sy == ',':
s.next()
if s.sy == '**':
s.next()
starstar_arg = p_simple_expr(s)
......@@ -1738,7 +1745,7 @@ def p_c_declarator(s, ctx = Ctx(), empty = 0, is_type = 0, cmethod_flag = 0,
if s.sy == '(':
s.next()
if s.sy == ')' or looking_at_type(s):
base = Nodes.CNameDeclaratorNode(pos, name = "", cname = None)
base = Nodes.CNameDeclaratorNode(pos, name = EncodedString(u""), cname = None)
result = p_c_func_declarator(s, pos, ctx, base, cmethod_flag)
else:
result = p_c_declarator(s, ctx, empty = empty, is_type = is_type,
......@@ -1808,7 +1815,7 @@ def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag,
else:
rhs = None
if s.sy == 'IDENT':
name = s.systring
name = EncodedString(s.systring)
if is_type:
s.add_type_name(name)
if empty:
......@@ -2171,7 +2178,7 @@ def p_def_statement(s, decorators=None):
# s.sy == 'def'
pos = s.position()
s.next()
name = p_ident(s)
name = EncodedString( p_ident(s) )
#args = []
s.expect('(');
args = p_c_arg_list(s, in_pyfunc = 1, nonempty_declarators = 1)
......
......@@ -29,6 +29,7 @@ class PyrexType(BaseType):
# is_extension_type boolean Is a Python extension type
# is_numeric boolean Is a C numeric type
# is_int boolean Is a C integer type
# is_longlong boolean Is a long long or unsigned long long.
# is_float boolean Is a C floating point type
# is_void boolean Is the C void type
# is_array boolean Is a C array type
......@@ -79,6 +80,7 @@ class PyrexType(BaseType):
is_builtin_type = 0
is_numeric = 0
is_int = 0
is_longlong = 0
is_float = 0
is_void = 0
is_array = 0
......@@ -553,12 +555,14 @@ class CULongType(CUIntType):
class CLongLongType(CUIntType):
is_longlong = 1
to_py_function = "PyLong_FromLongLong"
from_py_function = "__pyx_PyInt_AsLongLong"
class CULongLongType(CUIntType):
is_longlong = 1
to_py_function = "PyLong_FromUnsignedLongLong"
from_py_function = "__pyx_PyInt_AsUnsignedLongLong"
......@@ -728,7 +732,7 @@ class CFuncType(CType):
return 1
if not other_type.is_cfunction:
return 0
if not self.is_overridable and other_type.is_overridable:
if self.is_overridable != other_type.is_overridable:
return 0
nargs = len(self.args)
if nargs != len(other_type.args):
......@@ -842,6 +846,8 @@ class CFuncType(CType):
for arg in self.args[:len(self.args)-self.optional_arg_count]:
arg_decl_list.append(
arg.type.declaration_code("", for_display, pyrex = pyrex))
if self.is_overridable:
arg_decl_list.append("int %s" % Naming.skip_dispatch_cname)
if self.optional_arg_count:
arg_decl_list.append(self.op_arg_struct.declaration_code(Naming.optional_args_cname))
if self.has_varargs:
......@@ -1175,11 +1181,16 @@ def widest_numeric_type(type1, type2):
# Given two numeric types, return the narrowest type
# encompassing both of them.
if type1.is_enum and type2.is_enum:
widest_type = c_int_type
elif type2.rank > type1.rank:
widest_type = type2
return c_int_type
elif type1 is type2:
return type1
elif (type1.signed and type2.signed) or (not type1.signed and not type2.signed):
if type2.rank > type1.rank:
return type2
else:
return type1
else:
widest_type = type1
return sign_and_rank_to_type[min(type1.signed, type2.signed), max(type1.rank, type2.rank)]
return widest_type
def simple_c_type(signed, longness, name):
......
......@@ -138,6 +138,7 @@ class Entry:
utility_code = None
is_overridable = 0
buffer_aux = None
prev_entry = None
def __init__(self, name, cname, type, pos = None, init = None):
self.name = name
......@@ -280,7 +281,7 @@ class Scope:
if name and dict.has_key(name):
if visibility == 'extern':
warning(pos, "'%s' redeclared " % name, 0)
else:
elif visibility != 'ignore':
error(pos, "'%s' redeclared " % name)
entry = Entry(name, cname, type, pos = pos)
entry.in_cinclude = self.in_cinclude
......@@ -1414,22 +1415,8 @@ class CClassScope(ClassScope):
if type.same_c_signature_as(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil:
pass
elif type.compatible_signature_with(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil:
if type.optional_arg_count and not type.original_sig.optional_arg_count:
# Need to put a wrapper taking no optional arguments
# into the method table.
wrapper_func_cname = self.mangle(Naming.func_prefix, name) + Naming.no_opt_args
wrapper_func_name = name + Naming.no_opt_args
if entry.type.optional_arg_count:
old_entry = self.lookup_here(wrapper_func_name)
old_entry.func_cname = wrapper_func_cname
else:
entry.func_cname = wrapper_func_cname
entry.name = wrapper_func_name
entry = self.add_cfunction(name, type, pos, cname or name, visibility)
entry = self.add_cfunction(name, type, pos, cname or name, visibility='ignore')
defining = 1
entry.type = type
# if type.narrower_c_signature_than(entry.type, as_cmethod = 1):
# entry.type = type
else:
error(pos, "Signature not compatible with previous declaration")
error(entry.pos, "Previous declaration is here")
......@@ -1445,8 +1432,10 @@ class CClassScope(ClassScope):
def add_cfunction(self, name, type, pos, cname, visibility):
# Add a cfunction entry without giving it a func_cname.
prev_entry = self.lookup_here(name)
entry = ClassScope.add_cfunction(self, name, type, pos, cname, visibility)
entry.is_cmethod = 1
entry.prev_entry = prev_entry
return entry
def declare_property(self, name, doc, pos):
......
......@@ -127,13 +127,15 @@ class SlotDescriptor:
# flag Py_TPFLAGS_XXX value indicating presence of slot
# py3k Indicates presence of slot in Python 3
# py2 Indicates presence of slot in Python 2
# ifdef Full #ifdef string that slot is wrapped in. Using this causes py3k, py2 and flags to be ignored.)
def __init__(self, slot_name, dynamic = 0, flag = None, py3k = True, py2 = True):
def __init__(self, slot_name, dynamic = 0, flag = None, py3k = True, py2 = True, ifdef = None):
self.slot_name = slot_name
self.is_initialised_dynamically = dynamic
self.flag = flag
self.py3k = py3k
self.py2 = py2
self.ifdef = ifdef
def generate(self, scope, code):
if self.is_initialised_dynamically:
......@@ -143,6 +145,9 @@ class SlotDescriptor:
flag = self.flag
py3k = self.py3k
py2 = self.py2
if self.ifdef:
code.putln("#if %s" % self.ifdef)
else:
if not py3k:
code.putln("#if PY_MAJOR_VERSION < 3")
elif not py2:
......@@ -150,9 +155,7 @@ class SlotDescriptor:
if flag:
code.putln("#if (PY_MAJOR_VERSION >= 3) || (Py_TPFLAGS_DEFAULT & %s)" % flag)
code.putln("%s, /*%s*/" % (value, self.slot_name))
if flag:
code.putln("#endif")
if not py3k or not py2:
if flag or (not py3k or not py2) or self.ifdef:
code.putln("#endif")
# Some C implementations have trouble statically
......@@ -199,8 +202,8 @@ class MethodSlot(SlotDescriptor):
# method_name string The __xxx__ name of the method
# default string or None Default value of the slot
def __init__(self, signature, slot_name, method_name, default = None, flag = None, py3k=True, py2=True):
SlotDescriptor.__init__(self, slot_name, flag = flag, py3k = py3k, py2=py2)
def __init__(self, signature, slot_name, method_name, default = None, flag = None, py3k=True, py2=True, ifdef=None):
SlotDescriptor.__init__(self, slot_name, flag = flag, py3k = py3k, py2=py2, ifdef=ifdef)
self.signature = signature
self.slot_name = slot_name
self.method_name = method_name
......@@ -296,7 +299,7 @@ class TypeFlagsSlot(SlotDescriptor):
# Descriptor for the type flags slot.
def slot_code(self, scope):
value = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE"
value = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_NEWBUFFER"
if scope.needs_gc():
value += "|Py_TPFLAGS_HAVE_GC"
return value
......@@ -609,8 +612,8 @@ PyBufferProcs = (
MethodSlot(getsegcountproc, "bf_getsegcount", "__getsegcount__", py3k = False),
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"),
MethodSlot(getbufferproc, "bf_getbuffer", "__getbuffer__", ifdef = "PY_VERSION_HEX >= 0x02060000"),
MethodSlot(releasebufferproc, "bf_releasebuffer", "__releasebuffer__", ifdef = "PY_VERSION_HEX >= 0x02060000")
)
#------------------------------------------------------------------------------------------
......
......@@ -164,11 +164,26 @@ class CythonTransform(VisitorTransform):
super(CythonTransform, self).__init__()
self.context = context
def __call__(self, node):
import ModuleNode
if isinstance(node, ModuleNode.ModuleNode):
self.current_directives = node.directives
return super(CythonTransform, self).__call__(node)
def visit_CompilerDirectivesNode(self, node):
old = self.current_directives
self.current_directives = node.directives
self.visitchildren(node)
self.current_directives = old
return node
def visit_Node(self, node):
self.visitchildren(node)
return node
# Utils
def ensure_statlist(node):
if not isinstance(node, Nodes.StatListNode):
......
cimport python_buffer as pybuf
cdef extern from "Python.h":
ctypedef int Py_intptr_t
......@@ -19,7 +21,11 @@ cdef extern from "numpy/arrayobject.h":
NPY_NTYPES,
NPY_NOTYPE,
NPY_CHAR,
NPY_USERDEF
NPY_USERDEF,
NPY_C_CONTIGUOUS,
NPY_F_CONTIGUOUS
ctypedef class numpy.ndarray [object PyArrayObject]:
cdef __cythonbufferdefaults__ = {"mode": "strided"}
......@@ -29,20 +35,29 @@ cdef extern from "numpy/arrayobject.h":
int ndim "nd"
npy_intp *shape "dimensions"
npy_intp *strides
int flags
# Note: This syntax (function definition in pxd files) is an
# experimental exception made for __getbuffer__ and __releasebuffer__
# -- the details of this may change.
def __getbuffer__(ndarray self, Py_buffer* info, int flags):
# This implementation of getbuffer is geared towards Cython
# requirements, and does not yet fullfill the PEP (specifically,
# Cython always requests and we always provide strided access,
# so the flags are not even checked).
# requirements, and does not yet fullfill the PEP.
# In particular strided access is always provided regardless
# of flags
if sizeof(npy_intp) != sizeof(Py_ssize_t):
raise RuntimeError("Py_intptr_t and Py_ssize_t differs in size, numpy.pxd does not support this")
if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
raise ValueError("ndarray is not C contiguous")
if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
raise ValueError("ndarray is not Fortran contiguous")
info.buf = PyArray_DATA(self)
# info.obj = None # this is automatic
info.ndim = PyArray_NDIM(self)
info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
info.shape = <Py_ssize_t*>PyArray_DIMS(self)
......@@ -81,6 +96,7 @@ cdef extern from "numpy/arrayobject.h":
cdef npy_intp PyArray_STRIDES(ndarray arr)
cdef npy_intp PyArray_DIMS(ndarray arr)
cdef Py_ssize_t PyArray_ITEMSIZE(ndarray arr)
cdef int PyArray_CHKFLAGS(ndarray arr, int flags)
ctypedef signed int npy_byte
ctypedef signed int npy_short
......
#####################################################################
#
# These are the "SageX" pxi files for (most of) the Python/C API.
#
# SageX = SAGE Pyrex, which is a fork of Pyrex for use in SAGE.
# These are the Cython pxd files for (most of) the Python/C API.
#
# REFERENCE COUNTING:
#
# JUST TO SCARE YOU:
# If you are going to use any of the Python/C API in your SageX
# If you are going to use any of the Python/C API in your Cython
# program, you might be responsible for doing reference counting.
# Read http://docs.python.org/api/refcounts.html which is so
# important I've copied it below.
......@@ -15,10 +13,10 @@
# For all the declaration below, whenver the Py_ function returns
# a *new reference* to a PyObject*, the return type is "object".
# When the function returns a borrowed reference, the return
# type is PyObject*. When SageX sees "object" as a return type
# type is PyObject*. When Cython sees "object" as a return type
# it doesn't increment the reference count. When it sees PyObject*
# in order to use the result you must explicitly cast to <object>,
# and when you do that SageX increments the reference count wether
# and when you do that Cython increments the reference count wether
# you want it to or not, forcing you to an explicit DECREF (or leak memory).
# To avoid this we make the above convention. Note, you can
# always locally override this convention by putting something like
......@@ -26,10 +24,10 @@
# cdef extern from "Python.h":
# PyObject* PyNumber_Add(PyObject *o1, PyObject *o2)
#
# in your file after any .pxi includes. SageX will use the latest
# in your file after any .pxi includes. Cython will use the latest
# declaration.
#
# SageX takes care of this automatically for anything of type object.
# Cython takes care of this automatically for anything of type object.
## More precisely, I think the correct convention for
## using the Python/C API from Pyrex is as follows.
##
......@@ -119,7 +117,7 @@
#
#################################################################
from python_version cimport *
from python_ref cimport *
from python_exc cimport *
from python_module cimport *
......@@ -138,6 +136,7 @@ from python_long cimport *
from python_float cimport *
from python_complex cimport *
from python_string cimport *
from python_unicode cimport *
from python_dict cimport *
from python_instance cimport *
from python_function cimport *
......
This diff is collapsed.
# Python version constants
#
# It's better to evaluate these at runtime (i.e. C compile time) using
#
# if PY_MAJOR_VERSION >= 3:
# do_stuff_in_Py3_0_and_later()
# if PY_VERSION_HEX >= 0x02050000:
# do_stuff_in_Py2_5_and_later()
#
# than using the IF/DEF statements, which are evaluated at Cython
# compile time. This will keep your C code portable.
cdef extern from *:
# the complete version, e.g. 0x010502B2 == 1.5.2b2
int PY_VERSION_HEX
# the individual sections as plain numbers
int PY_MAJOR_VERSION
int PY_MINOR_VERSION
int PY_MICRO_VERSION
int PY_RELEASE_LEVEL
int PY_RELEASE_SERIAL
# Note: PY_RELEASE_LEVEL is one of
# 0xA (alpha)
# 0xB (beta)
# 0xC (release candidate)
# 0xF (final)
char[] PY_VERSION
char[] PY_PATCHLEVEL_REVISION
#! /usr/bin/env python
# --------------------------------------------------------------------
import re
from epydoc import docstringparser as dsp
CYTHON_SIGNATURE_RE = re.compile(
# Class name (for builtin methods)
r'^\s*((?P<class>\w+)\.)?' +
# The function name
r'(?P<func>\w+)' +
# The parameters
r'\(((?P<self>(?:self|cls|mcs)),?)?(?P<params>.*)\)' +
# The return value (optional)
r'(\s*(->)\s*(?P<return>\w+(?:\s*\w+)))?' +
# The end marker
r'\s*(?:\n|$)')
parse_signature = dsp.parse_function_signature
def parse_function_signature(func_doc, doc_source,
docformat, parse_errors):
PYTHON_SIGNATURE_RE = dsp._SIGNATURE_RE
assert PYTHON_SIGNATURE_RE is not CYTHON_SIGNATURE_RE
try:
dsp._SIGNATURE_RE = CYTHON_SIGNATURE_RE
found = parse_signature(func_doc, doc_source,
docformat, parse_errors)
dsp._SIGNATURE_RE = PYTHON_SIGNATURE_RE
if not found:
found = parse_signature(func_doc, doc_source,
docformat, parse_errors)
return found
finally:
dsp._SIGNATURE_RE = PYTHON_SIGNATURE_RE
dsp.parse_function_signature = parse_function_signature
# --------------------------------------------------------------------
from epydoc.cli import cli
cli()
# --------------------------------------------------------------------
This diff is collapsed.
......@@ -10,11 +10,11 @@ cdef extern from "longintrepr.h":
cdef struct _longobject:
int ob_refcnt
PyTypeObject *ob_type
int ob_size
# int ob_size # not in Py3k
unsigned int *ob_digit
def test(temp = long(0)):
cdef _longobject *l
l = <_longobject *> temp
print sizeof(l.ob_size)
#print sizeof(l.ob_size) # not in Py3k
print sizeof(l.ob_digit[0])
def f(*args, **kwargs):
pass
args = (1,2,3)
kwargs = {u"test" : "toast"}
def test():
f(*args, 1, 2, 3)
f(**kwargs, 1, 2, c=3)
f(*args, **kwargs, *args)
f(1, 2, c=3, *args, **kwargs, *args)
f(1, 2, c=3, *args, d=5, **kwargs, **kwargs)
f(1, 2, c=3, *args, d=5, **kwargs, x=6)
f(1=2)
# too bad we don't get more errors here ...
_ERRORS = u"""
8:13: Non-keyword arg following star-arg
"""
cdef class Test:
cdef __cinit__(self):
pass
cdef __len__(self):
pass
_ERRORS = u"""
3:9: Special methods must be declared with 'def', not 'cdef'
6:9: Special methods must be declared with 'def', not 'cdef'
"""
cdef class A:
cdef int value = 3
cdef extern from *:
cdef struct B:
int value = 3
_ERRORS = u"""
2:13: Cannot assign default value to cdef class attributes
2:13: Cannot assign default value to fields in cdef classes, structs or unions
6:12: Cannot assign default value to fields in cdef classes, structs or unions
"""
try:
raise KeyError
except KeyError:
pass
except:
pass
except:
pass
except AttributeError:
pass
_ERRORS = u"""
8:0: default 'except:' must be last
10:0: default 'except:' must be last
"""
......@@ -13,5 +13,5 @@ cdef class ExtClass:
_attribute = 5 # FIXME: this is not currently handled!!!
_ERRORS = u"""
8:13: Cannot assign default value to cdef class attributes
8:13: Cannot assign default value to fields in cdef classes, structs or unions
"""
def f():
a = <foao>x
_ERRORS = """
2:13: Unknown type
"""
\ No newline at end of file
......@@ -329,6 +329,35 @@ def explicitly_release_buffer():
x = None
print "After release"
#
# Format strings
#
@testcase
def alignment_string(object[int] buf):
"""
>>> alignment_string(IntMockBuffer(None, [1,2], format="@i"))
2
>>> alignment_string(IntMockBuffer(None, [1,2], format="@i@@"))
2
>>> alignment_string(IntMockBuffer(None, [1,2], format=">i"))
Traceback (most recent call last):
...
ValueError: Buffer acquisition error: Only native byte order, size and alignment supported.
>>> alignment_string(IntMockBuffer(None, [1,2], format="<i"))
Traceback (most recent call last):
...
ValueError: Buffer acquisition error: Only native byte order, size and alignment supported.
>>> alignment_string(IntMockBuffer(None, [1,2], format="=i"))
Traceback (most recent call last):
...
ValueError: Buffer acquisition error: Only native byte order, size and alignment supported.
>>> alignment_string(IntMockBuffer(None, [1,2], format="!i"))
Traceback (most recent call last):
...
ValueError: Buffer acquisition error: Only native byte order, size and alignment supported.
"""
print buf[1]
#
# Getting items and index bounds checking
#
......@@ -524,6 +553,54 @@ def strided(object[int, ndim=1, mode='strided'] buf):
"""
return buf[2]
@testcase
def c_contig(object[int, ndim=1, mode='c'] buf):
"""
>>> A = IntMockBuffer(None, range(4))
>>> c_contig(A)
2
>>> [str(x) for x in A.recieved_flags]
['FORMAT', 'ND', 'STRIDES', 'C_CONTIGUOUS']
"""
return buf[2]
@testcase
def c_contig_2d(object[int, ndim=2, mode='c'] buf):
"""
Multi-dim has seperate implementation
>>> A = IntMockBuffer(None, range(12), shape=(3,4))
>>> c_contig_2d(A)
7
>>> [str(x) for x in A.recieved_flags]
['FORMAT', 'ND', 'STRIDES', 'C_CONTIGUOUS']
"""
return buf[1, 3]
@testcase
def f_contig(object[int, ndim=1, mode='fortran'] buf):
"""
>>> A = IntMockBuffer(None, range(4))
>>> f_contig(A)
2
>>> [str(x) for x in A.recieved_flags]
['FORMAT', 'ND', 'STRIDES', 'F_CONTIGUOUS']
"""
return buf[2]
@testcase
def f_contig_2d(object[int, ndim=2, mode='fortran'] buf):
"""
Must set up strides manually to ensure Fortran ordering.
>>> A = IntMockBuffer(None, range(12), shape=(4,3), strides=(1, 4))
>>> f_contig_2d(A)
7
>>> [str(x) for x in A.recieved_flags]
['FORMAT', 'ND', 'STRIDES', 'F_CONTIGUOUS']
"""
return buf[3, 1]
#
# Test compiler options for bounds checking. We create an array with a
# safe "boundary" (memory
......@@ -848,6 +925,8 @@ available_flags = (
('INDIRECT', python_buffer.PyBUF_INDIRECT),
('ND', python_buffer.PyBUF_ND),
('STRIDES', python_buffer.PyBUF_STRIDES),
('C_CONTIGUOUS', python_buffer.PyBUF_C_CONTIGUOUS),
('F_CONTIGUOUS', python_buffer.PyBUF_F_CONTIGUOUS),
('WRITABLE', python_buffer.PyBUF_WRITABLE)
)
......@@ -884,7 +963,6 @@ cdef class MockBuffer:
strides.reverse()
strides = [x * self.itemsize for x in strides]
suboffsets = [-1] * len(shape)
datashape = [len(data)]
p = data
while True:
......@@ -950,10 +1028,6 @@ cdef class MockBuffer:
if self.fail:
raise ValueError("Failing on purpose")
if buffer is NULL:
print u"locking!"
return
self.recieved_flags = []
cdef int value
for name, value in available_flags:
......@@ -961,6 +1035,7 @@ cdef class MockBuffer:
self.recieved_flags.append(name)
buffer.buf = <void*>(<char*>self.buffer + (<int>self.offset * self.itemsize))
buffer.obj = self
buffer.len = self.len
buffer.readonly = 0
buffer.format = <char*>self.format
......@@ -1000,7 +1075,7 @@ cdef class IntMockBuffer(MockBuffer):
(<int*>buf)[0] = <int>value
return 0
cdef get_itemsize(self): return sizeof(int)
cdef get_default_format(self): return b"=i"
cdef get_default_format(self): return b"@i"
cdef class ShortMockBuffer(MockBuffer):
cdef int write(self, char* buf, object value) except -1:
......@@ -1014,7 +1089,7 @@ cdef class UnsignedShortMockBuffer(MockBuffer):
(<unsigned short*>buf)[0] = <unsigned short>value
return 0
cdef get_itemsize(self): return sizeof(unsigned short)
cdef get_default_format(self): return b"=1H" # Try with repeat count
cdef get_default_format(self): return b"@1H" # Try with repeat count
cdef class FloatMockBuffer(MockBuffer):
cdef int write(self, char* buf, object value) except -1:
......@@ -1040,7 +1115,7 @@ cdef class ObjectMockBuffer(MockBuffer):
return 0
cdef get_itemsize(self): return sizeof(void*)
cdef get_default_format(self): return b"=O"
cdef get_default_format(self): return b"@O"
cdef class IntStridedMockBuffer(IntMockBuffer):
......@@ -1052,10 +1127,10 @@ cdef class ErrorBuffer:
def __init__(self, label):
self.label = label
def __getbuffer__(MockBuffer self, Py_buffer* buffer, int flags):
def __getbuffer__(ErrorBuffer self, Py_buffer* buffer, int flags):
raise Exception("acquiring %s" % self.label)
def __releasebuffer__(MockBuffer self, Py_buffer* buffer):
def __releasebuffer__(ErrorBuffer self, Py_buffer* buffer):
raise Exception("releasing %s" % self.label)
#
......
......@@ -8,18 +8,16 @@ if sys.version_info[0] >= 3:
__doc__ += u"""
>>> ms = memoryview(s)
>>> ms.tobytes()
bytearray(b'abcdefg')
b'abcdefg'
>>> m1 = memoryview(b1)
>>> m1.tobytes()
locking!
bytearray(b'abcdefg')
b'abcdefg'
>>> m2 = memoryview(b2)
>>> m2.tobytes()
locking!
unlocking!
bytearray(b'abcdefg')
releasing!
b'abcdefg'
>>> del m1
>>> del m2
......@@ -30,10 +28,8 @@ 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.obj = self
buffer.len = len(s)
buffer.readonly = 0
buffer.format = "B"
......@@ -46,7 +42,4 @@ cdef class TestBuffer:
cdef class TestBufferRelease(TestBuffer):
def __releasebuffer__(self, Py_buffer* buffer):
if buffer is NULL:
print u"unlocking!"
else:
print u"releasing!"
__doc__ = u"""
>>> test_pos_args(h)
1 2 3 * 0 0
1 2 9 * 2 0
1 2 7 * 2 0
9 8 7 * 0 0
7 8 9 * 0 0
>>> test_kw_args(h)
1 2 3 * 0 0
1 2 9 * 2 1
1 2 7 * 2 1
1 2 9 * 2 2
1 2 9 * 2 2
1 2 9 * 2 3
>>> test_kw_args(e)
2 1
5 1
5 1
5 2
5 2
5 3
>>> test_kw(e)
0 1
0 2
0 2
0 1
>>> test_kw(g)
1
2
2
1
>>> test_pos_args(f)
3
5
5
3
3
>>> test_noargs(e)
0 0
>>> test_noargs(f)
0
>>> test_noargs(g)
0
# and some errors:
>>> test_noargs(h)
Traceback (most recent call last):
TypeError: h() takes at least 3 positional arguments (0 given)
>>> h(1,2, d=5)
Traceback (most recent call last):
TypeError: h() takes at least 3 positional arguments (2 given)
>>> f(1,2, d=5)
Traceback (most recent call last):
TypeError: f() got an unexpected keyword argument 'd'
>>> f(1, d=5)
Traceback (most recent call last):
TypeError: f() got an unexpected keyword argument 'd'
>>> f(d=5)
Traceback (most recent call last):
TypeError: f() got an unexpected keyword argument 'd'
>>> g(1,2, d=5)
Traceback (most recent call last):
TypeError: g() takes exactly 0 positional arguments (2 given)
>>> g(1,2)
Traceback (most recent call last):
TypeError: g() takes exactly 0 positional arguments (2 given)
>>> g(1)
Traceback (most recent call last):
TypeError: g() takes exactly 0 positional arguments (1 given)
>>> test_int_kwargs(e)
Traceback (most recent call last):
TypeError: e() keywords must be strings
>>> test_int_kwargs(f)
Traceback (most recent call last):
TypeError: f() keywords must be strings
>>> test_int_kwargs(g)
Traceback (most recent call last):
TypeError: g() keywords must be strings
>>> test_int_kwargs(h)
Traceback (most recent call last):
TypeError: h() keywords must be strings
"""
def e(*args, **kwargs):
print len(args), len(kwargs)
def f(*args):
print len(args)
def g(**kwargs):
print len(kwargs)
def h(a, b, c, *args, **kwargs):
print a, b, c, u'*', len(args), len(kwargs)
args = (9,8,7)
import sys
if sys.version_info[0] >= 3:
kwargs = {u"test" : u"toast"}
else:
kwargs = {"test" : u"toast"}
def test_kw_args(f):
f(1,2, c=3)
f(1,2, d=3, *args)
f(1,2, d=3, *(7,8,9))
f(1,2, d=3, *args, **kwargs)
f(1,2, d=3, *args, e=5)
f(1,2, d=3, *args, e=5, **kwargs)
def test_pos_args(f):
f(1,2,3)
f(1,2, *args)
f(1,2, *(7,8,9))
f(*args)
f(*(7,8,9))
def test_kw(f):
f(c=3)
f(d=3, e=5)
f(d=3, **kwargs)
f(**kwargs)
def test_noargs(f):
f()
def test_int_kwargs(f):
f(a=1,b=2,c=3, **{10:20,30:40})
......@@ -5,23 +5,23 @@ __doc__ = u"""
>>> b(1,2,3)
>>> b(1,2,3,4)
Traceback (most recent call last):
TypeError: function takes exactly 4 arguments (5 given)
TypeError: b() takes exactly 4 positional arguments (5 given)
>>> c(1,2)
>>> c(1,2,3)
>>> c(1,2,3,4)
Traceback (most recent call last):
TypeError: function takes at most 4 arguments (5 given)
TypeError: c() takes at most 4 positional arguments (5 given)
>>> d(1,2)
>>> d(1,2, c=1)
>>> d(1,2,3)
Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given)
TypeError: d() takes exactly 3 positional arguments (4 given)
>>> d(1,2, d=1)
Traceback (most recent call last):
TypeError: 'd' is an invalid keyword argument for this function
TypeError: d() got an unexpected keyword argument 'd'
>>> e(1,2)
>>> e(1,2, c=1)
......@@ -30,34 +30,34 @@ __doc__ = u"""
>>> e(1,2,3)
>>> e(1,2,3,4)
Traceback (most recent call last):
TypeError: function takes at most 4 positional arguments (5 given)
TypeError: e() takes at most 4 positional arguments (5 given)
>>> f(1,2, c=1)
>>> f(1,2, c=1, d=2)
>>> f(1,2,3)
Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given)
TypeError: f() takes exactly 3 positional arguments (4 given)
>>> f(1,2)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
TypeError: f() needs keyword-only argument c
>>> f(1,2, c=1, e=2)
Traceback (most recent call last):
TypeError: 'e' is an invalid keyword argument for this function
TypeError: f() got an unexpected keyword argument 'e'
>>> g(1,2, c=1, f=2)
>>> 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,3) #doctest: +ELLIPSIS
>>> g(1,2,3)
Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given)
TypeError: g() takes exactly 3 positional arguments (4 given)
>>> g(1,2)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
TypeError: g() needs keyword-only argument c
>>> g(1,2, c=1)
Traceback (most recent call last):
TypeError: required keyword argument 'f' is missing
TypeError: g() needs keyword-only argument f
>>> h(1,2, c=1, f=2)
>>> h(1,2, c=1, f=2, e=3)
......@@ -66,10 +66,10 @@ __doc__ = u"""
>>> h(1,2,3)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
TypeError: h() needs keyword-only argument c
>>> h(1,2, d=1)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
TypeError: h() needs keyword-only argument c
>>> k(1,2, c=1, f=2)
>>> k(1,2, c=1, f=2, e=3)
......@@ -78,20 +78,12 @@ __doc__ = u"""
>>> k(1,2,3)
Traceback (most recent call last):
TypeError: required keyword argument 'f' is missing
TypeError: k() needs keyword-only argument f
>>> k(1,2, d=1)
Traceback (most recent call last):
TypeError: required keyword argument 'f' is missing
TypeError: k() needs keyword-only argument f
"""
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:
def b(self, a, b, c):
pass
......
#cython: embedsignature=True
# note the r, we use \n below
__doc__ = ur"""
>>> print (Ext.a.__doc__)
Ext.a(self)
>>> print (Ext.b.__doc__)
Ext.b(self, a, b, c)
>>> print (Ext.c.__doc__)
Ext.c(self, a, b, c=1)
>>> print (Ext.d.__doc__)
Ext.d(self, a, b, *, c=88)
>>> print (Ext.e.__doc__)
Ext.e(self, a, b, c=88, **kwds)
>>> print (Ext.f.__doc__)
Ext.f(self, a, b, *, c, d=42)
>>> print (Ext.g.__doc__)
Ext.g(self, a, b, *, c, d=42, e=17, f, **kwds)
>>> print (Ext.h.__doc__)
Ext.h(self, a, b, *args, c, d=42, e=17, f, **kwds)
>>> print (Ext.k.__doc__)
Ext.k(self, a, b, c=1, *args, d=42, e=17, f, **kwds)
>>> print (Ext.get_int.__doc__)
Ext.get_int(self) -> int
>>> print (Ext.get_float.__doc__)
Ext.get_float(self) -> float
>>> print (Ext.clone.__doc__)
Ext.clone(self) -> Ext
>>> print (foo.__doc__)
foo()
>>> with_doc_1.__doc__
'with_doc_1(a, b, c)\nExisting string'
>>> with_doc_2.__doc__
'with_doc_2(a, b, c)\n\n Existing string\n '
>>> types.__doc__
'types(Ext a, int b, unsigned short int c, float d, e)'
>>> print (f_c.__doc__)
f_c(char c) -> char
>>> print (f_uc.__doc__)
f_uc(unsigned char c) -> unsigned char
>>> print (f_sc.__doc__)
f_sc(signed char c) -> signed char
>>> print (f_s.__doc__)
f_s(short int s) -> short int
>>> print (f_us.__doc__)
f_us(unsigned short int s) -> unsigned short int
>>> print (f_ss.__doc__)
f_ss(signed short int s) -> signed short int
>>> print (f_i.__doc__)
f_i(int i) -> int
>>> print (f_ui.__doc__)
f_ui(unsigned int i) -> unsigned int
>>> print (f_si.__doc__)
f_si(signed int i) -> signed int
>>> print (f_l.__doc__)
f_l(long int l) -> long int
>>> print (f_ul.__doc__)
f_ul(unsigned long int l) -> unsigned long int
>>> print (f_sl.__doc__)
f_sl(signed long int l) -> signed long int
>>> print (f_L.__doc__)
f_L(long long int L) -> long long int
>>> print (f_uL.__doc__)
f_uL(unsigned long long int L) -> unsigned long long int
>>> print (f_sL.__doc__)
f_sL(signed long long int L) -> signed long long int
>>> print (f_f.__doc__)
f_f(float f) -> float
>>> print (f_d.__doc__)
f_d(double d) -> double
>>> print (f_D.__doc__)
f_D(long double D) -> long double
"""
cdef class Ext:
def a(self):
pass
def b(self, a, b, c):
pass
def c(self, a, b, c=1):
pass
def d(self, a, b, *, c = 88):
pass
def e(self, a, b, c = 88, **kwds):
pass
def f(self, a, b, *, c, d = 42):
pass
def g(self, a, b, *, c, d = 42, e = 17, f, **kwds):
pass
def h(self, a, b, *args, c, d = 42, e = 17, f, **kwds):
pass
def k(self, a, b, c=1, *args, d = 42, e = 17, f, **kwds):
pass
cpdef int get_int(self):
return 0
cpdef float get_float(self):
return 0.0
cpdef Ext clone(self):
return Ext()
def foo():
pass
def types(Ext a, int b, unsigned short c, float d, e):
pass
def with_doc_1(a, b, c):
"""Existing string"""
pass
def with_doc_2(a, b, c):
"""
Existing string
"""
pass
cpdef char f_c(char c):
return c
cpdef unsigned char f_uc(unsigned char c):
return c
cpdef signed char f_sc(signed char c):
return c
cpdef short f_s(short s):
return s
cpdef unsigned short f_us(unsigned short s):
return s
cpdef signed short f_ss(signed short s):
return s
cpdef int f_i(int i):
return i
cpdef unsigned int f_ui(unsigned int i):
return i
cpdef signed int f_si(signed int i):
return i
cpdef long f_l(long l):
return l
cpdef unsigned long f_ul(unsigned long l):
return l
cpdef signed long f_sl(signed long l):
return l
cpdef long long f_L(long long L):
return L
cpdef unsigned long long f_uL(unsigned long long L):
return L
cpdef signed long long f_sL(signed long long L):
return L
cpdef float f_f(float f):
return f
cpdef double f_d(double d):
return d
cpdef long double f_D(long double D):
return D
......@@ -5,23 +5,23 @@ __doc__ = u"""
>>> b(1,2,3)
>>> b(1,2,3,4)
Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (4 given)
TypeError: b() takes exactly 3 positional arguments (4 given)
>>> c(1,2)
>>> c(1,2,3)
>>> c(1,2,3,4)
Traceback (most recent call last):
TypeError: function takes at most 3 arguments (4 given)
TypeError: c() takes at most 3 positional arguments (4 given)
>>> d(1,2)
>>> d(1,2, c=1)
>>> d(1,2,3)
Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given)
TypeError: d() takes exactly 2 positional arguments (3 given)
>>> d(1,2, d=1)
Traceback (most recent call last):
TypeError: 'd' is an invalid keyword argument for this function
TypeError: d() got an unexpected keyword argument 'd'
>>> e(1,2)
>>> e(1,2, c=1)
......@@ -30,20 +30,20 @@ __doc__ = u"""
>>> e(1,2,3)
>>> e(1,2,3,4)
Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given)
TypeError: e() takes at most 3 positional arguments (4 given)
>>> f(1,2, c=1)
>>> f(1,2, c=1, d=2)
>>> f(1,2,3)
Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given)
TypeError: f() takes exactly 2 positional arguments (3 given)
>>> f(1,2)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
TypeError: f() needs keyword-only argument c
>>> f(1,2, c=1, e=2)
Traceback (most recent call last):
TypeError: 'e' is an invalid keyword argument for this function
TypeError: f() got an unexpected keyword argument 'e'
>>> g(1,2, c=1, f=2)
>>> g(1,2, c=1, e=0, f=2, d=11)
......@@ -51,13 +51,13 @@ __doc__ = u"""
>>> g(1,2,3)
Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given)
TypeError: g() takes exactly 2 positional arguments (3 given)
>>> g(1,2)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
TypeError: g() needs keyword-only argument c
>>> g(1,2, c=1)
Traceback (most recent call last):
TypeError: required keyword argument 'f' is missing
TypeError: g() needs keyword-only argument f
>>> h(1,2, c=1, f=2)
>>> h(1,2, c=1, f=2, e=3)
......@@ -66,10 +66,10 @@ __doc__ = u"""
>>> h(1,2,3)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
TypeError: h() needs keyword-only argument c
>>> h(1,2, d=1)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
TypeError: h() needs keyword-only argument c
>>> k(1,2, c=1, f=2)
>>> k(1,2, c=1, f=2, e=3)
......@@ -78,16 +78,12 @@ __doc__ = u"""
>>> k(1,2,3)
Traceback (most recent call last):
TypeError: required keyword argument 'f' is missing
TypeError: k() needs keyword-only argument f
>>> k(1,2, d=1)
Traceback (most recent call last):
TypeError: required keyword argument 'f' is missing
TypeError: k() needs keyword-only argument f
"""
import sys, re
if sys.version_info >= (2,6):
__doc__ = re.sub(u"Error: (.*)exactly(.*)", u"Error: \\1at most\\2", __doc__)
cdef class Ext:
def b(self, a, b, c):
pass
......
......@@ -5,15 +5,15 @@ __doc__ = u"""
>>> spam(1,2,3)
(1, 2, 3)
>>> spam(1,2) #doctest: +ELLIPSIS
>>> spam(1,2)
Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (2 given)
TypeError: spam() takes exactly 3 positional arguments (2 given)
>>> spam(1,2,3,4)
Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (4 given)
TypeError: spam() takes exactly 3 positional arguments (4 given)
>>> spam(1,2,3, a=1) #doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: 'a' is an invalid keyword argument for this function
TypeError: spam() got an unexpected keyword argument 'a'
>>> grail(1,2,3)
(1, 2, 3, ())
......@@ -21,23 +21,23 @@ __doc__ = u"""
(1, 2, 3, (4,))
>>> grail(1,2,3,4,5,6,7,8,9)
(1, 2, 3, (4, 5, 6, 7, 8, 9))
>>> grail(1,2) #doctest: +ELLIPSIS
>>> grail(1,2)
Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (2 given)
TypeError: grail() takes at least 3 positional arguments (2 given)
>>> grail(1,2,3, a=1) #doctest: +ELLIPSIS
Traceback (most recent call last):
TypeError: 'a' is an invalid keyword argument for this function
TypeError: grail() got an unexpected keyword argument 'a'
>>> swallow(1,2,3)
(1, 2, 3, ())
>>> swallow(1,2,3,4)
Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given)
TypeError: swallow() takes exactly 3 positional arguments (4 given)
>>> swallow(1,2,3, a=1, b=2)
(1, 2, 3, (('a', 1), ('b', 2)))
>>> swallow(1,2,3, x=1) #doctest: +ELLIPSIS
>>> swallow(1,2,3, x=1)
Traceback (most recent call last):
TypeError: keyword parameter 'x' was given by position and by name
TypeError: swallow() got multiple values for keyword argument 'x'
>>> creosote(1,2,3)
(1, 2, 3, (), ())
......@@ -47,9 +47,9 @@ __doc__ = u"""
(1, 2, 3, (), (('a', 1),))
>>> creosote(1,2,3,4, a=1, b=2)
(1, 2, 3, (4,), (('a', 1), ('b', 2)))
>>> creosote(1,2,3,4, x=1) #doctest: +ELLIPSIS
>>> creosote(1,2,3,4, x=1)
Traceback (most recent call last):
TypeError: keyword parameter 'x' was given by position and by name
TypeError: creosote() got multiple values for keyword argument 'x'
>>> onlyt(1)
(1,)
......@@ -57,10 +57,10 @@ __doc__ = u"""
(1, 2)
>>> onlyt(a=1)
Traceback (most recent call last):
TypeError: 'a' is an invalid keyword argument for this function
TypeError: onlyt() got an unexpected keyword argument 'a'
>>> onlyt(1, a=2)
Traceback (most recent call last):
TypeError: 'a' is an invalid keyword argument for this function
TypeError: onlyt() got an unexpected keyword argument 'a'
>>> onlyk(a=1)
(('a', 1),)
......@@ -68,13 +68,13 @@ __doc__ = u"""
(('a', 1), ('b', 2))
>>> onlyk(1)
Traceback (most recent call last):
TypeError: function takes at most 0 positional arguments (1 given)
TypeError: onlyk() takes exactly 0 positional arguments (1 given)
>>> onlyk(1, 2)
Traceback (most recent call last):
TypeError: function takes at most 0 positional arguments (2 given)
TypeError: onlyk() takes exactly 0 positional arguments (2 given)
>>> onlyk(1, a=1, b=2)
Traceback (most recent call last):
TypeError: function takes at most 0 positional arguments (1 given)
TypeError: onlyk() takes exactly 0 positional arguments (1 given)
>>> tk(a=1)
(('a', 1),)
......@@ -88,10 +88,6 @@ __doc__ = u"""
(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)
......
__doc__ = u"""
>>> import sys
>>> if not IS_PY3: sys.exc_clear()
>>> def test_py():
... try:
... raise AttributeError
... except AttributeError:
... print(sys.exc_info()[0] == AttributeError or sys.exc_info()[0])
... print((IS_PY3 and sys.exc_info()[0] is None) or
... (not IS_PY3 and sys.exc_info()[0] == AttributeError) or
... sys.exc_info()[0])
>>> print(sys.exc_info()[0]) # 0
None
>>> test_py()
True
True
>>> print(sys.exc_info()[0]) # test_py()
None
>>> test_c()
True
True
>>> print(sys.exc_info()[0]) # test_c()
None
"""
import sys
IS_PY3 = sys.version_info[0] >= 3
def test_c():
try:
raise AttributeError
except AttributeError:
print(sys.exc_info()[0] == AttributeError or sys.exc_info()[0])
print(sys.exc_info()[0] is None or sys.exc_info()[0])
__doc__ = u"""
>>> import sys
>>> if not IS_PY3: sys.exc_clear()
>>> def test_py(outer_exc):
... try:
... raise AttributeError
... except AttributeError:
... print(sys.exc_info()[0] is AttributeError or sys.exc_info()[0])
... try: raise KeyError
... except: print(sys.exc_info()[0] is KeyError or sys.exc_info()[0])
... print((IS_PY3 and sys.exc_info()[0] is AttributeError) or
... (not IS_PY3 and sys.exc_info()[0] is KeyError) or
... sys.exc_info()[0])
... print((IS_PY3 and sys.exc_info()[0] is outer_exc) or
... (not IS_PY3 and sys.exc_info()[0] is KeyError) or
... sys.exc_info()[0])
>>> print(sys.exc_info()[0]) # 0
None
>>> test_py(None)
True
True
True
True
>>> print(sys.exc_info()[0]) # test_py()
None
>>> test_c(None)
True
True
True
True
>>> print(sys.exc_info()[0]) # test_c()
None
>>> def test_py2():
... try:
... raise Exception
... except Exception:
... test_py(Exception)
... print(sys.exc_info()[0] is Exception or sys.exc_info()[0])
... print((IS_PY3 and sys.exc_info()[0] is None) or
... (not IS_PY3 and sys.exc_info()[0] is Exception) or
... sys.exc_info()[0])
>>> test_py2()
True
True
True
True
True
True
>>> print(sys.exc_info()[0]) # test_py2()
None
>>> test_c2()
True
True
True
True
True
True
>>> print(sys.exc_info()[0]) # test_c2()
None
"""
import sys
IS_PY3 = sys.version_info[0] >= 3
def test_c(outer_exc):
try:
raise AttributeError
except AttributeError:
print(sys.exc_info()[0] is AttributeError or sys.exc_info()[0])
try: raise KeyError
except: print(sys.exc_info()[0] is KeyError or sys.exc_info()[0])
print(sys.exc_info()[0] is AttributeError or sys.exc_info()[0])
print(sys.exc_info()[0] is outer_exc or sys.exc_info()[0])
def test_c2():
try:
raise Exception
except Exception:
test_c(Exception)
print(sys.exc_info()[0] is Exception or sys.exc_info()[0])
print(sys.exc_info()[0] is None or sys.exc_info()[0])
__doc__ = u"""
>>> import sys
>>> if not IS_PY3: sys.exc_clear()
>>> def test_py():
... try:
... raise AttributeError
... except AttributeError:
... test_c(error=AttributeError)
... print(sys.exc_info()[0] is AttributeError or sys.exc_info()[0])
... print((IS_PY3 and sys.exc_info()[0] is TestException) or
... (not IS_PY3 and sys.exc_info()[0] is AttributeError) or
... sys.exc_info()[0])
>>> print(sys.exc_info()[0]) # 0
None
>>> test_py()
True
True
True
True
>>> print(sys.exc_info()[0]) # test_py()
None
>>> test_c(test_py)
True
True
True
True
True
True
>>> print(sys.exc_info()[0]) # test_c()
None
"""
import sys
IS_PY3 = sys.version_info[0] >= 3
class TestException(Exception):
pass
def test_c(func=None, error=None):
try:
raise TestException
except TestException:
if func:
func()
print(sys.exc_info()[0] is TestException or sys.exc_info()[0])
print(sys.exc_info()[0] is error or sys.exc_info()[0])
__doc__ = u"""
>>> import sys
>>> if not IS_PY3: sys.exc_clear()
>>> print(sys.exc_info()[0]) # 0
None
>>> exc = test_c()
>>> type(exc) is TestException
True
>>> print(sys.exc_info()[0]) # test_c()
None
"""
import sys
IS_PY3 = sys.version_info[0] >= 3
class TestException(Exception):
pass
def test_c():
try:
raise TestException
except TestException, e:
return e
......@@ -2,23 +2,23 @@ __doc__ = u"""
>>> b(1,2,3)
>>> b(1,2,3,4)
Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (4 given)
TypeError: b() takes exactly 3 positional arguments (4 given)
>>> c(1,2)
>>> c(1,2,3)
>>> c(1,2,3,4)
Traceback (most recent call last):
TypeError: function takes at most 3 arguments (4 given)
TypeError: c() takes at most 3 positional arguments (4 given)
>>> d(1,2)
>>> d(1,2, c=1)
>>> d(1,2,3)
Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given)
TypeError: d() takes exactly 2 positional arguments (3 given)
>>> d(1,2, d=1)
Traceback (most recent call last):
TypeError: 'd' is an invalid keyword argument for this function
TypeError: d() got an unexpected keyword argument 'd'
>>> e(1,2)
>>> e(1,2, c=1)
......@@ -27,20 +27,20 @@ __doc__ = u"""
>>> e(1,2,3)
>>> e(1,2,3,4)
Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given)
TypeError: e() takes at most 3 positional arguments (4 given)
>>> f(1,2, c=1)
>>> f(1,2, c=1, d=2)
>>> f(1,2,3)
Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given)
TypeError: f() takes exactly 2 positional arguments (3 given)
>>> f(1,2)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
TypeError: f() needs keyword-only argument c
>>> f(1,2, c=1, e=2)
Traceback (most recent call last):
TypeError: 'e' is an invalid keyword argument for this function
TypeError: f() got an unexpected keyword argument 'e'
>>> g(1,2, c=1, f=2)
>>> g(1,2, c=1, e=0, f=2, d=11)
......@@ -48,13 +48,13 @@ __doc__ = u"""
>>> g(1,2,3)
Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given)
TypeError: g() takes exactly 2 positional arguments (3 given)
>>> g(1,2)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
TypeError: g() needs keyword-only argument c
>>> g(1,2, c=1)
Traceback (most recent call last):
TypeError: required keyword argument 'f' is missing
TypeError: g() needs keyword-only argument f
>>> h(1,2, c=1, f=2)
>>> h(1,2, c=1, f=2, e=3)
......@@ -63,10 +63,10 @@ __doc__ = u"""
>>> h(1,2,3)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
TypeError: h() needs keyword-only argument c
>>> h(1,2, d=1)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
TypeError: h() needs keyword-only argument c
>>> k(1,2, c=1, f=2)
>>> k(1,2, c=1, f=2, e=3)
......@@ -75,15 +75,21 @@ __doc__ = u"""
>>> k(1,2,3)
Traceback (most recent call last):
TypeError: required keyword argument 'f' is missing
TypeError: k() needs keyword-only argument f
>>> k(1,2, d=1)
Traceback (most recent call last):
TypeError: required keyword argument 'f' is missing
"""
TypeError: k() needs keyword-only argument f
import sys, re
if sys.version_info >= (2,6):
__doc__ = re.sub(u"Error: (.*)exactly(.*)", u"Error: \\1at most\\2", __doc__)
>>> l(a=1, b=2)
>>> l(a=1, b=2, c=1)
>>> l(1,2,3)
Traceback (most recent call last):
TypeError: l() takes exactly 0 positional arguments (3 given)
>>> l(1,2, d=1)
Traceback (most recent call last):
TypeError: l() takes exactly 0 positional arguments (2 given)
"""
def b(a, b, c):
pass
......@@ -108,3 +114,6 @@ def h(a, b, *args, c, d = 42, e = 17, f, **kwds):
def k(a, b, c=1, *args, d = 42, e = 17, f, **kwds):
pass
def l(*, a, b, c = 88):
pass
__doc__ = u"""
>>> call0ab(b)
Traceback (most recent call last):
TypeError: b() takes exactly 3 positional arguments (2 given)
>>> call0abc(b)
1 2 3
>>> call3(b)
1 2 3
>>> call4(b)
Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (4 given)
TypeError: b() takes exactly 3 positional arguments (4 given)
>>> call0ab(c)
1 2 1
>>> call0abc(c)
1 2 3
>>> call2(c)
1 2 1
>>> call3(c)
1 2 3
>>> call4(c)
Traceback (most recent call last):
TypeError: function takes at most 3 arguments (4 given)
TypeError: c() takes at most 3 positional arguments (4 given)
>>> call0abc(d)
1 2 3
>>> call0ab(d)
1 2 88
>>> call2(d)
1 2 88
>>> call2c(d)
1 2 1
>>> call3(d)
Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given)
TypeError: d() takes exactly 2 positional arguments (3 given)
>>> call2d(d)
Traceback (most recent call last):
TypeError: 'd' is an invalid keyword argument for this function
TypeError: d() got an unexpected keyword argument 'd'
>>> call0abc(e)
1 2 3 []
>>> call2(e)
1 2 88 []
>>> call2c(e)
1 2 1 []
>>> call2d(e)
1 2 88 [('d', 1)]
>>> call2cde(e)
1 2 1 [('d', 2), ('e', 3)]
>>> call3(e)
1 2 3 []
>>> call4(e)
Traceback (most recent call last):
TypeError: function takes at most 3 positional arguments (4 given)
TypeError: e() takes at most 3 positional arguments (4 given)
>>> call0abc(f)
1 2 3 42
>>> call2c(f)
1 2 1 42
>>> call2cd(f)
1 2 1 2
>>> call3(f)
Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given)
TypeError: f() takes exactly 2 positional arguments (3 given)
>>> call2(f)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
TypeError: f() needs keyword-only argument c
>>> call2ce(f)
Traceback (most recent call last):
TypeError: 'e' is an invalid keyword argument for this function
TypeError: f() got an unexpected keyword argument 'e'
>>> call2cf(g)
1 2 1 42 17 2 []
>>> call2cefd(g)
1 2 1 11 0 2 []
>>> call2cfex(g)
1 2 1 42 0 2 [('x', 25)]
>>> call3(g)
Traceback (most recent call last):
TypeError: function takes at most 2 positional arguments (3 given)
TypeError: g() takes exactly 2 positional arguments (3 given)
>>> call2(g)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
TypeError: g() needs keyword-only argument c
>>> call2c(g)
Traceback (most recent call last):
TypeError: required keyword argument 'f' is missing
TypeError: g() needs keyword-only argument f
>>> call2cf(h)
1 2 1 42 17 2 () []
>>> call2cfe(h)
1 2 1 42 3 2 () []
>>> call6cf(h)
1 2 1 42 17 2 (3, 4, 5, 6) []
>>> call6cfexy(h)
1 2 1 42 3 2 (3, 4, 5, 6) [('x', 25), ('y', 11)]
>>> call3(h)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
TypeError: h() needs keyword-only argument c
>>> call3d(h)
Traceback (most recent call last):
TypeError: required keyword argument 'c' is missing
TypeError: h() needs keyword-only argument c
>>> call2cf(k)
1 2 1 42 17 2 () []
>>> call2cfe(k)
1 2 1 42 3 2 () []
>>> call6df(k)
1 2 3 1 17 2 (4, 5, 6) []
>>> call6dfexy(k)
1 2 3 1 3 2 (4, 5, 6) [('x', 25), ('y', 11)]
>>> call3(k)
Traceback (most recent call last):
TypeError: required keyword argument 'f' is missing
TypeError: k() needs keyword-only argument f
>>> call2d(k)
Traceback (most recent call last):
TypeError: required keyword argument 'f' is missing
"""
TypeError: k() needs keyword-only argument f
import sys, re
if sys.version_info >= (2,6):
__doc__ = re.sub(u"Error: (.*)exactly(.*)", u"Error: \\1at most\\2", __doc__)
>>> call0abc(m)
1 2 3
>>> call2c(m)
1 2 1
>>> call3(m)
Traceback (most recent call last):
TypeError: m() takes at most 2 positional arguments (3 given)
>>> call2(m)
Traceback (most recent call last):
TypeError: m() needs keyword-only argument c
>>> call2cd(m)
Traceback (most recent call last):
TypeError: m() got an unexpected keyword argument 'd'
"""
# the calls:
def call0ab(f):
f(a=1,b=2)
def call0abc(f):
f(a=1,b=2,c=3)
def call2(f):
f(1,2)
......@@ -132,6 +189,10 @@ def call2cefd(f):
def call2cfex(f):
f(1,2, c=1, f=2, e=0, x=25)
def call6argscfexy(f):
args = (1,2,3,4,5,6)
f(*args, c=1, f=2, e=3, x=25, y=11)
def call6cfexy(f):
f(1,2,3,4,5,6, c=1, f=2, e=3, x=25, y=11)
......@@ -141,25 +202,36 @@ def call6dfexy(f):
# the called functions:
def b(a, b, c):
pass
print a,b,c
def c(a, b, c=1):
pass
print a,b,c
def d(a, b, *, c = 88):
pass
print a,b,c
def e(a, b, c = 88, **kwds):
pass
kwlist = list(kwds.items())
kwlist.sort()
print a,b,c, kwlist
def f(a, b, *, c, d = 42):
pass
print a,b,c,d
def g(a, b, *, c, d = 42, e = 17, f, **kwds):
pass
kwlist = list(kwds.items())
kwlist.sort()
print a,b,c,d,e,f, kwlist
def h(a, b, *args, c, d = 42, e = 17, f, **kwds):
pass
kwlist = list(kwds.items())
kwlist.sort()
print a,b,c,d,e,f, args, kwlist
def k(a, b, c=1, *args, d = 42, e = 17, f, **kwds):
pass
kwlist = list(kwds.items())
kwlist.sort()
print a,b,c,d,e,f, args, kwlist
def m(a, b=1, *, c):
print a,b,c
u"""
>>> smoketest()
[0, 4, 8]
>>> typed()
[A, A, A]
"""
def smoketest():
print [x*2 for x in range(5) if x % 2 == 0]
cdef class A:
def __repr__(self): return "A"
def typed():
cdef A obj
print [obj for obj in [A(), A(), A()]]
\ No newline at end of file
__doc__ = """
>>> D = set_longlong(2**40, 2**50, 2, "yelp")
>>> D[2**40]
'yelp'
>>> D[2**50]
'yelp'
>>> D[2]
'yelp'
"""
ctypedef long long foo
def set_longlong(long long ob, foo x, long y, val):
tank = {}
tank[ob] = val
tank[x] = val
tank[y] = val
return tank
__doc__ = u"""
>>> a
2
"""
a = 0
try:
raise KeyError
except AttributeError:
a = 1
except KeyError:
a = 2
except:
a = 3
This diff is collapsed.
This diff is collapsed.
__doc__ = u"""
>>> s = Spam() #doctest: +ELLIPSIS
>>> s = Spam()
Traceback (most recent call last):
TypeError: function takes exactly 3 arguments (0 given)
TypeError: __init__() takes exactly 3 positional arguments (0 given)
"""
import sys, re
if sys.version_info >= (2,6):
__doc__ = re.sub(u"Error: .*", u"Error: ...", __doc__)
cdef class Spam:
def __init__(self, a, b, int c):
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment