Commit 39d60c71 authored by Stefan Behnel's avatar Stefan Behnel

merged in latest cython-devel (with minor merge fixes)

parents cad41704 137545fd
......@@ -132,6 +132,7 @@ class CodeWriter(TreeVisitor):
def visit_IntNode(self, node):
self.put(node.value)
# FIXME: represent string nodes correctly
def visit_StringNode(self, node):
value = node.value
if value.encoding is not None:
......
from Cython.Compiler.Visitor import VisitorTransform, ScopeTrackingTransform, TreeVisitor
from Nodes import StatListNode, SingleAssignmentNode, CFuncDefNode
from ExprNodes import (DictNode, DictItemNode, NameNode, UnicodeNode, NoneNode,
ExprNode, AttributeNode, ModuleRefNode, DocstringRefNode)
from ExprNodes import DictNode, DictItemNode, NameNode, UnicodeNode, NoneNode, \
ExprNode, AttributeNode, ModuleRefNode, DocstringRefNode
from PyrexTypes import py_object_type
from Builtin import dict_type
from StringEncoding import EncodedString
......@@ -10,6 +10,8 @@ import Naming
class AutoTestDictTransform(ScopeTrackingTransform):
# Handles autotestdict directive
blacklist = ['__cinit__', '__dealloc__', '__richcmp__', '__nonzero__']
def visit_ModuleNode(self, node):
self.scope_type = 'module'
self.scope_node = node
......@@ -62,6 +64,12 @@ class AutoTestDictTransform(ScopeTrackingTransform):
parent = ModuleRefNode(pos)
name = node.entry.name
elif self.scope_type in ('pyclass', 'cclass'):
if isinstance(node, CFuncDefNode):
name = node.py_func.name
else:
name = node.name
if self.scope_type == 'cclass' and name in self.blacklist:
return node
mod = ModuleRefNode(pos)
if self.scope_type == 'pyclass':
clsname = self.scope_node.name
......
......@@ -3,9 +3,7 @@ from Cython.Compiler.Nodes import DefNode, CFuncDefNode
from Cython.Compiler.Errors import CompileError
from Cython.Compiler.StringEncoding import EncodedString
from Cython.Compiler import Options
from Cython.Compiler import PyrexTypes
from Cython.Compiler import PyrexTypes, ExprNodes
class EmbedSignature(CythonTransform):
......@@ -16,15 +14,26 @@ class EmbedSignature(CythonTransform):
self.class_node = None
def _fmt_arg_defv(self, arg):
if not arg.default:
default_val = arg.default
if not default_val:
return None
try:
denv = self.denv # XXX
ctval = arg.default.compile_time_value(self.denv)
return '%r' % ctval
ctval = default_val.compile_time_value(self.denv)
repr_val = '%r' % ctval
if isinstance(default_val, ExprNodes.UnicodeNode):
if repr_val[:1] != 'u':
return u'u%s' % repr_val
elif isinstance(default_val, ExprNodes.BytesNode):
if repr_val[:1] != 'b':
return u'b%s' % repr_val
elif isinstance(default_val, ExprNodes.StringNode):
if repr_val[:1] in ('u', 'b'):
repr_val[1:]
return repr_val
except Exception:
try:
return arg.default.name # XXX
return default_val.name # XXX
except AttributeError:
return '<???>'
......
......@@ -392,13 +392,15 @@ def init_builtins():
init_builtin_funcs()
init_builtin_types()
init_builtin_structs()
global list_type, tuple_type, dict_type, set_type, bytes_type, unicode_type, type_type
global list_type, tuple_type, dict_type, set_type, type_type
global bytes_type, str_type, unicode_type
type_type = builtin_scope.lookup('type').type
list_type = builtin_scope.lookup('list').type
tuple_type = builtin_scope.lookup('tuple').type
dict_type = builtin_scope.lookup('dict').type
set_type = builtin_scope.lookup('set').type
bytes_type = builtin_scope.lookup('bytes').type
str_type = builtin_scope.lookup('str').type
unicode_type = builtin_scope.lookup('unicode').type
init_builtins()
......@@ -39,12 +39,12 @@ Options:
--line-directives Produce #line directives pointing to the .pyx source
--cplus Output a c++ rather than c file.
--embed Embed the Python interpreter in a main() method.
--directive <name>=<value>[,<name=value,...] Overrides a compiler directive
-X, --directive <name>=<value>[,<name=value,...] Overrides a compiler directive
"""
#The following experimental options are supported only on MacOSX:
# -C, --compile Compile generated .c file to .o file
# -X, --link Link .o file to produce extension module (implies -C)
# --link Link .o file to produce extension module (implies -C)
# -+, --cplus Use C++ compiler for compiling and linking
# Additional .o files to link may be supplied when using -X."""
......@@ -81,11 +81,7 @@ def parse_command_line(args):
options.use_listing_file = 1
elif option in ("-C", "--compile"):
options.c_only = 0
elif option in ("-X", "--link"):
if option == "-X":
print >>sys.stderr, "Deprecation warning: The -X command line switch will be changed to a"
print >>sys.stderr, "shorthand for --directive in Cython 0.12. Please use --link instead."
print >>sys.stderr
elif option in ("--link"):
options.c_only = 0
options.obj_only = 0
elif option in ("-+", "--cplus"):
......@@ -126,7 +122,7 @@ def parse_command_line(args):
options.emit_linenums = True
elif option in ("-X", "--directive"):
try:
options.compiler_directives = Options.parse_option_list(pop_arg())
options.compiler_directives = Options.parse_directive_list(pop_arg())
except ValueError, e:
sys.stderr.write("Error in compiler directive: %s\n" % e.message)
sys.exit(1)
......
......@@ -289,7 +289,8 @@ class PyObjectConst(object):
possible_unicode_identifier = re.compile(ur"(?![0-9])\w+$", re.U).match
possible_bytes_identifier = re.compile(r"(?![0-9])\w+$".encode('ASCII')).match
nice_identifier = re.compile('^[a-zA-Z0-0_]+$').match
nice_identifier = re.compile('^[a-zA-Z0-9_]+$').match
find_alphanums = re.compile('([a-zA-Z0-9]+)').findall
class StringConst(object):
"""Global info about a C string constant held by GlobalState.
......@@ -304,19 +305,31 @@ class StringConst(object):
self.escaped_value = StringEncoding.escape_byte_string(byte_string)
self.py_strings = None
def get_py_string_const(self, encoding, identifier=None):
def get_py_string_const(self, encoding, identifier=None, is_str=False):
py_strings = self.py_strings
text = self.text
if encoding is not None:
encoding = encoding.upper()
key = (bool(identifier), encoding)
is_str = bool(identifier or is_str)
is_unicode = encoding is None and not is_str
if encoding is None:
# unicode string
encoding_key = None
else:
# bytes or str
encoding = encoding.lower()
if encoding in ('utf8', 'utf-8', 'ascii', 'usascii', 'us-ascii'):
encoding = None
encoding_key = None
else:
encoding_key = ''.join(find_alphanums(encoding))
key = (is_str, is_unicode, encoding_key)
if py_strings is not None and key in py_strings:
py_string = py_strings[key]
else:
if py_strings is None:
self.py_strings = {}
is_unicode = encoding is None
if identifier:
intern = True
elif identifier is None:
......@@ -330,14 +343,13 @@ class StringConst(object):
prefix = Naming.interned_str_prefix
else:
prefix = Naming.py_const_prefix
pystring_cname = "%s%s%s_%s" % (
pystring_cname = "%s%s_%s" % (
prefix,
is_unicode and 'u' or 'b',
identifier and 'i' or '',
(is_str and 's') or (is_unicode and 'u') or 'b',
self.cname[len(Naming.const_prefix):])
py_string = PyStringConst(
pystring_cname, is_unicode, bool(identifier), intern)
pystring_cname, encoding, is_unicode, is_str, intern)
self.py_strings[key] = py_string
return py_string
......@@ -346,14 +358,16 @@ class PyStringConst(object):
"""Global info about a Python string constant held by GlobalState.
"""
# cname string
# unicode boolean
# encoding string
# intern boolean
# identifier boolean
# is_unicode boolean
# is_str boolean
def __init__(self, cname, is_unicode, identifier=False, intern=False):
def __init__(self, cname, encoding, is_unicode, is_str=False, intern=False):
self.cname = cname
self.identifier = identifier
self.unicode = is_unicode
self.encoding = encoding
self.is_str = is_str
self.is_unicode = is_unicode
self.intern = intern
def __lt__(self, other):
......@@ -393,7 +407,6 @@ class GlobalState(object):
code_layout = [
'h_code',
'complex_numbers_utility_code',
'utility_code_proto_before_types',
'type_declarations',
'utility_code_proto',
......@@ -511,6 +524,11 @@ class GlobalState(object):
w.putln("}")
w.exit_cfunc_scope()
if Options.generate_cleanup_code:
w = self.parts['cleanup_globals']
w.putln("}")
w.exit_cfunc_scope()
if Options.generate_cleanup_code:
w = self.parts['cleanup_module']
w.putln("}")
......@@ -545,12 +563,15 @@ class GlobalState(object):
c = self.new_string_const(text, byte_string)
return c
def get_py_string_const(self, text, identifier=None):
def get_py_string_const(self, text, identifier=None, is_str=False):
# return a Python string constant, creating a new one if necessary
c_string = self.get_string_const(text)
py_string = c_string.get_py_string_const(text.encoding, identifier)
py_string = c_string.get_py_string_const(text.encoding, identifier, is_str)
return py_string
def get_interned_identifier(self, text):
return self.get_py_string_const(text, identifier=True)
def new_string_const(self, text, byte_string):
cname = self.new_string_const_cname(byte_string)
c = StringConst(cname, text, byte_string)
......@@ -577,7 +598,7 @@ class GlobalState(object):
return self.new_const_cname()
if len(value) < 20 and nice_identifier(value):
return "%s%s" % (Naming.const_prefix, value)
return "%s_%s" % (Naming.const_prefix, value)
else:
return self.new_const_cname()
......@@ -596,7 +617,7 @@ class GlobalState(object):
def add_cached_builtin_decl(self, entry):
if Options.cache_builtins:
if self.should_declare(entry.cname, entry):
interned_cname = self.get_py_string_const(entry.name, True).cname
interned_cname = self.get_interned_identifier(entry.name).cname
self.put_pyobject_decl(entry)
w = self.parts['cached_builtins']
w.putln('%s = __Pyx_GetName(%s, %s); if (!%s) %s' % (
......@@ -644,18 +665,26 @@ class GlobalState(object):
w.putln("static __Pyx_StringTabEntry %s[] = {" %
Naming.stringtab_cname)
for c_cname, _, py_string in py_strings:
if not py_string.is_str or not py_string.encoding or \
py_string.encoding in ('ASCII', 'USASCII', 'US-ASCII',
'UTF8', 'UTF-8'):
encoding = '0'
else:
encoding = '"%s"' % py_string.encoding.lower()
decls_writer.putln(
"static PyObject *%s;" % py_string.cname)
w.putln(
"{&%s, %s, sizeof(%s), %d, %d, %d}," % (
"{&%s, %s, sizeof(%s), %s, %d, %d, %d}," % (
py_string.cname,
c_cname,
c_cname,
py_string.unicode,
py_string.intern,
py_string.identifier
encoding,
py_string.is_unicode,
py_string.is_str,
py_string.intern
))
w.putln("{0, 0, 0, 0, 0, 0}")
w.putln("{0, 0, 0, 0, 0, 0, 0}")
w.putln("};")
init_globals = self.parts['init_globals']
......@@ -718,8 +747,9 @@ class GlobalState(object):
u'*/', u'*[inserted by cython to avoid comment closer]/'
).replace(
u'/*', u'/[inserted by cython to avoid comment start]*'
).encode('ASCII', 'replace').decode('ASCII')
for line in source_desc.get_lines()]
)
for line in source_desc.get_lines(encoding='ASCII',
error_handling='ignore')]
if len(F) == 0: F.append(u'')
self.input_file_contents[source_desc] = F
return F
......@@ -889,8 +919,8 @@ class CCodeWriter(object):
def get_string_const(self, text):
return self.globalstate.get_string_const(text).cname
def get_py_string_const(self, text, identifier=None):
return self.globalstate.get_py_string_const(text, identifier).cname
def get_py_string_const(self, text, identifier=None, is_str=False):
return self.globalstate.get_py_string_const(text, identifier, is_str).cname
def get_argument_default_const(self, type):
return self.globalstate.get_py_const(type).cname
......@@ -899,7 +929,7 @@ class CCodeWriter(object):
return self.get_py_string_const(text)
def intern_identifier(self, text):
return self.get_py_string_const(text, True)
return self.get_py_string_const(text, identifier=True)
# code generation
......@@ -1244,10 +1274,10 @@ class CCodeWriter(object):
return self.globalstate.lookup_filename(filename)
def put_setup_refcount_context(self, name):
self.putln('__Pyx_SetupRefcountContext("%s");' % name)
self.putln('__Pyx_RefNannySetupContext("%s");' % name)
def put_finish_refcount_context(self):
self.putln("__Pyx_FinishRefcountContext();")
self.putln("__Pyx_RefNannyFinishContext();")
def put_trace_call(self, name, pos):
self.putln('__Pyx_TraceCall("%s", %s[%s], %s);' % (name, Naming.filetable_cname, self.lookup_filename(pos[0]), pos[1]));
......
This diff is collapsed.
......@@ -87,6 +87,7 @@ class Context(object):
from ParseTreeTransforms import AnalyseDeclarationsTransform, AnalyseExpressionsTransform
from ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform
from ParseTreeTransforms import InterpretCompilerDirectives, TransformBuiltinMethods
from TypeInference import MarkAssignments
from ParseTreeTransforms import AlignFunctionDefinitions, GilCheck
from AnalysedTreeTransforms import AutoTestDictTransform
from AutoDocTransforms import EmbedSignature
......@@ -131,6 +132,7 @@ class Context(object):
CreateClosureClasses(self),
AutoTestDictTransform(self),
EmbedSignature(self),
MarkAssignments(self),
TransformBuiltinMethods(self),
IntroduceBufferAuxiliaryVars(self),
_check_c_declarations,
......
This diff is collapsed.
This diff is collapsed.
......@@ -20,6 +20,11 @@ try:
except NameError:
from functools import reduce
try:
set
except NameError:
from sets import Set as set
def unwrap_node(node):
while isinstance(node, UtilNodes.ResultRefNode):
node = node.expression
......@@ -224,7 +229,7 @@ class IterationTransform(Visitor.VisitorTransform):
bound2 = args[1].coerce_to_integer(self.current_scope)
step = step.coerce_to_integer(self.current_scope)
if not isinstance(bound2, ExprNodes.ConstNode):
if not bound2.is_literal:
# stop bound must be immutable => keep it in a temp var
bound2_is_temp = True
bound2 = UtilNodes.LetRefNode(bound2)
......@@ -416,12 +421,12 @@ class SwitchTransform(Visitor.VisitorTransform):
and cond.operator == '=='
and not cond.is_python_comparison()):
if is_common_value(cond.operand1, cond.operand1):
if isinstance(cond.operand2, ExprNodes.ConstNode):
if cond.operand2.is_literal:
return cond.operand1, [cond.operand2]
elif hasattr(cond.operand2, 'entry') and cond.operand2.entry and cond.operand2.entry.is_const:
return cond.operand1, [cond.operand2]
if is_common_value(cond.operand2, cond.operand2):
if isinstance(cond.operand1, ExprNodes.ConstNode):
if cond.operand1.is_literal:
return cond.operand2, [cond.operand1]
elif hasattr(cond.operand1, 'entry') and cond.operand1.entry and cond.operand1.entry.is_const:
return cond.operand2, [cond.operand1]
......@@ -517,6 +522,46 @@ class FlattenInListTransform(Visitor.VisitorTransform, SkipDeclarations):
visit_Node = Visitor.VisitorTransform.recurse_to_children
class DropRefcountingTransform(Visitor.VisitorTransform):
"""Drop ref-counting in safe places.
"""
visit_Node = Visitor.VisitorTransform.recurse_to_children
def visit_ParallelAssignmentNode(self, node):
left, right, temps = [], [], []
for stat in node.stats:
if isinstance(stat, Nodes.SingleAssignmentNode):
lhs = unwrap_node(stat.lhs)
if not isinstance(lhs, ExprNodes.NameNode):
return node
left.append(lhs)
rhs = unwrap_node(stat.rhs)
if isinstance(rhs, ExprNodes.CoerceToTempNode):
temps.append(rhs)
rhs = rhs.arg
if not isinstance(rhs, ExprNodes.NameNode):
return node
right.append(rhs)
else:
return node
for name_node in left + right:
if name_node.entry.is_builtin or name_node.entry.is_pyglobal:
return node
left_names = [n.name for n in left]
right_names = [n.name for n in right]
if set(left_names) != set(right_names):
return node
if len(set(left_names)) != len(right):
return node
for name_node in left + right + temps:
name_node.use_managed_ref = False
return node
class OptimizeBuiltinCalls(Visitor.VisitorTransform):
"""Optimize some common methods calls and instantiation patterns
for builtin types.
......@@ -853,10 +898,11 @@ class OptimizeBuiltinCalls(Visitor.VisitorTransform):
encoding_node = args[1]
if isinstance(encoding_node, ExprNodes.CoerceToPyTypeNode):
encoding_node = encoding_node.arg
if not isinstance(encoding_node, (ExprNodes.UnicodeNode, ExprNodes.StringNode)):
if not isinstance(encoding_node, (ExprNodes.UnicodeNode, ExprNodes.StringNode,
ExprNodes.BytesNode)):
return node
encoding = encoding_node.value
encoding_node = ExprNodes.StringNode(encoding_node.pos, value=encoding,
encoding_node = ExprNodes.BytesNode(encoding_node.pos, value=encoding,
type=PyrexTypes.c_char_ptr_type)
if len(args) == 3:
......@@ -864,13 +910,14 @@ class OptimizeBuiltinCalls(Visitor.VisitorTransform):
if isinstance(error_handling_node, ExprNodes.CoerceToPyTypeNode):
error_handling_node = error_handling_node.arg
if not isinstance(error_handling_node,
(ExprNodes.UnicodeNode, ExprNodes.StringNode)):
(ExprNodes.UnicodeNode, ExprNodes.StringNode,
ExprNodes.BytesNode)):
return node
error_handling = error_handling_node.value
if error_handling == 'strict':
error_handling_node = null_node
else:
error_handling_node = ExprNodes.StringNode(
error_handling_node = ExprNodes.BytesNode(
error_handling_node.pos, value=error_handling,
type=PyrexTypes.c_char_ptr_type)
else:
......@@ -887,7 +934,7 @@ class OptimizeBuiltinCalls(Visitor.VisitorTransform):
else:
value = BytesLiteral(value)
value.encoding = encoding
return ExprNodes.StringNode(
return ExprNodes.BytesNode(
string_node.pos, value=value, type=Builtin.bytes_type)
if error_handling == 'strict':
......@@ -1030,8 +1077,7 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations):
# the compiler, but we do not aggregate them into a
# constant node to prevent any loss of precision.
return node
if not isinstance(node.operand1, ExprNodes.ConstNode) or \
not isinstance(node.operand2, ExprNodes.ConstNode):
if not node.operand1.is_literal or not node.operand2.is_literal:
# We calculate other constants to make them available to
# the compiler, but we only aggregate constant nodes
# recursively, so non-const nodes are straight out.
......
......@@ -55,7 +55,7 @@ embed = False
# Declare compiler directives
option_defaults = {
directive_defaults = {
'boundscheck' : True,
'nonecheck' : False,
'embedsignature' : False,
......@@ -65,9 +65,10 @@ option_defaults = {
'cdivision_warnings': False,
'always_allow_keywords': False,
'wraparound' : True,
'c99_complex' : False, # Don't use macro wrappers for complex arith, not sure what to name this...
'ccomplex' : False, # use C99/C++ for complex types and arith
'callspec' : "",
'profile': False,
'infer_types': False,
'autotestdict': True,
# test support
......@@ -76,35 +77,35 @@ option_defaults = {
}
# Override types possibilities above, if needed
option_types = {}
directive_types = {}
for key, val in option_defaults.items():
if key not in option_types:
option_types[key] = type(val)
for key, val in directive_defaults.items():
if key not in directive_types:
directive_types[key] = type(val)
option_scopes = { # defaults to available everywhere
directive_scopes = { # defaults to available everywhere
# 'module', 'function', 'class', 'with statement'
'autotestdict' : ('module',),
'test_assert_path_exists' : ('function',),
'test_fail_if_path_exists' : ('function',),
}
def parse_option_value(name, value):
def parse_directive_value(name, value):
"""
Parses value as an option value for the given name and returns
the interpreted value. None is returned if the option does not exist.
>>> print parse_option_value('nonexisting', 'asdf asdfd')
>>> print parse_directive_value('nonexisting', 'asdf asdfd')
None
>>> parse_option_value('boundscheck', 'True')
>>> parse_directive_value('boundscheck', 'True')
True
>>> parse_option_value('boundscheck', 'true')
>>> parse_directive_value('boundscheck', 'true')
Traceback (most recent call last):
...
ValueError: boundscheck directive must be set to True or False
"""
type = option_types.get(name)
type = directive_types.get(name)
if not type: return None
if type is bool:
if value == "True": return True
......@@ -118,25 +119,25 @@ def parse_option_value(name, value):
else:
assert False
def parse_option_list(s):
def parse_directive_list(s):
"""
Parses a comma-seperated list of pragma options. Whitespace
is not considered.
>>> parse_option_list(' ')
>>> parse_directive_list(' ')
{}
>>> (parse_option_list('boundscheck=True') ==
>>> (parse_directive_list('boundscheck=True') ==
... {'boundscheck': True})
True
>>> parse_option_list(' asdf')
>>> parse_directive_list(' asdf')
Traceback (most recent call last):
...
ValueError: Expected "=" in option "asdf"
>>> parse_option_list('boundscheck=hey')
>>> parse_directive_list('boundscheck=hey')
Traceback (most recent call last):
...
ValueError: Must pass a boolean value for option "boundscheck"
>>> parse_option_list('unknown=True')
>>> parse_directive_list('unknown=True')
Traceback (most recent call last):
...
ValueError: Unknown option: "unknown"
......@@ -148,7 +149,7 @@ def parse_option_list(s):
if not '=' in item: raise ValueError('Expected "=" in option "%s"' % item)
name, value = item.strip().split('=')
try:
type = option_types[name]
type = directive_types[name]
except KeyError:
raise ValueError('Unknown option: "%s"' % name)
if type is bool:
......
This diff is collapsed.
......@@ -14,7 +14,7 @@ from Cython.Compiler.Scanning import PyrexScanner, FileSourceDescriptor
import Nodes
import ExprNodes
import StringEncoding
from StringEncoding import EncodedString, BytesLiteral, _str, _bytes
from StringEncoding import EncodedString, BytesLiteral, _unicode, _bytes
from ModuleNode import ModuleNode
from Errors import error, warning, InternalError
from Cython import Utils
......@@ -387,8 +387,7 @@ def p_call(s, function):
s.error("Expected an identifier before '='",
pos = arg.pos)
encoded_name = EncodedString(arg.name)
keyword = ExprNodes.IdentifierStringNode(arg.pos,
value = encoded_name)
keyword = ExprNodes.IdentifierStringNode(arg.pos, value = encoded_name)
arg = p_simple_expr(s)
keyword_args.append((keyword, arg))
else:
......@@ -579,6 +578,8 @@ def p_atom(s):
return ExprNodes.CharNode(pos, value = value)
elif kind == 'u':
return ExprNodes.UnicodeNode(pos, value = value)
elif kind == 'b':
return ExprNodes.BytesNode(pos, value = value)
else:
return ExprNodes.StringNode(pos, value = value)
elif sy == 'IDENT':
......@@ -610,8 +611,10 @@ def p_name(s, name):
return ExprNodes.IntNode(pos, value = rep, longness = "L")
elif isinstance(value, float):
return ExprNodes.FloatNode(pos, value = rep)
elif isinstance(value, (_str, _bytes)):
return ExprNodes.StringNode(pos, value = value)
elif isinstance(value, _unicode):
return ExprNodes.UnicodeNode(pos, value = value)
elif isinstance(value, _bytes):
return ExprNodes.BytesNode(pos, value = value)
else:
error(pos, "Invalid type for compile-time constant: %s"
% value.__class__.__name__)
......@@ -619,24 +622,20 @@ def p_name(s, name):
def p_cat_string_literal(s):
# A sequence of one or more adjacent string literals.
# Returns (kind, value) where kind in ('b', 'c', 'u')
# Returns (kind, value) where kind in ('b', 'c', 'u', '')
kind, value = p_string_literal(s)
if s.sy != 'BEGIN_STRING':
return kind, value
if kind != 'c':
strings = [value]
while s.sy == 'BEGIN_STRING':
pos = s.position()
next_kind, next_value = p_string_literal(s)
if next_kind == 'c':
error(s.position(),
"Cannot concatenate char literal with another string or char literal")
error(pos, "Cannot concatenate char literal with another string or char literal")
elif next_kind != kind:
# we have to switch to unicode now
if kind == 'b':
# concatenating a unicode string to byte strings
strings = [u''.join([s.decode(s.encoding) for s in strings])]
elif kind == 'u':
# concatenating a byte string to unicode strings
strings.append(next_value.decode(next_value.encoding))
kind = 'u'
error(pos, "Cannot mix string literals of different types, expected %s'', got %s''" %
(kind, next_kind))
else:
strings.append(next_value)
if kind == 'u':
......@@ -669,8 +668,6 @@ def p_string_literal(s):
if Future.unicode_literals in s.context.future_directives:
if kind == '':
kind = 'u'
elif kind == '':
kind = 'b'
if kind == 'u':
chars = StringEncoding.UnicodeLiteralBuilder()
else:
......@@ -935,7 +932,7 @@ def p_expression_or_assignment(s):
rhs = p_expr(s)
return Nodes.InPlaceAssignmentNode(lhs.pos, operator = operator, lhs = lhs, rhs = rhs)
expr = expr_list[0]
if isinstance(expr, ExprNodes.StringNode):
if isinstance(expr, (ExprNodes.UnicodeNode, ExprNodes.StringNode, ExprNodes.BytesNode)):
return Nodes.PassStatNode(expr.pos)
else:
return Nodes.ExprStatNode(expr.pos, expr = expr)
......@@ -966,7 +963,7 @@ def flatten_parallel_assignments(input, output):
# individual elements. This transformation is applied
# recursively, so that nested structures get matched as well.
rhs = input[-1]
if not rhs.is_sequence_constructor:
if not rhs.is_sequence_constructor or not sum([lhs.is_sequence_constructor for lhs in input[:-1]]):
output.append(input)
return
......@@ -1170,8 +1167,7 @@ def p_import_statement(s):
else:
if as_name and "." in dotted_name:
name_list = ExprNodes.ListNode(pos, args = [
ExprNodes.IdentifierStringNode(
pos, value = EncodedString("*"))])
ExprNodes.IdentifierStringNode(pos, value = EncodedString("*"))])
else:
name_list = None
stat = Nodes.SingleAssignmentNode(pos,
......@@ -1756,8 +1752,8 @@ def p_positional_and_keyword_args(s, end_sy_set, type_positions=(), type_keyword
parsed_type = True
else:
arg = p_simple_expr(s)
keyword_node = ExprNodes.IdentifierStringNode(arg.pos,
value = EncodedString(ident))
keyword_node = ExprNodes.IdentifierStringNode(
arg.pos, value = EncodedString(ident))
keyword_args.append((keyword_node, arg))
was_keyword = True
else:
......@@ -2628,7 +2624,7 @@ def p_compiler_directive_comments(s):
if m:
name = m.group(1)
try:
value = Options.parse_option_value(str(name), str(m.group(2).strip()))
value = Options.parse_directive_value(str(name), str(m.group(2).strip()))
if value is not None: # can be False!
result[name] = value
except ValueError, e:
......@@ -2639,7 +2635,7 @@ def p_compiler_directive_comments(s):
def p_module(s, pxd, full_module_name):
pos = s.position()
option_comments = p_compiler_directive_comments(s)
directive_comments = p_compiler_directive_comments(s)
s.parse_comments = False
doc = p_doc_string(s)
......@@ -2654,7 +2650,7 @@ def p_module(s, pxd, full_module_name):
repr(s.sy), repr(s.systring)))
return ModuleNode(pos, doc = doc, body = body,
full_module_name = full_module_name,
option_comments = option_comments)
directive_comments = directive_comments)
#----------------------------------------------
#
......
This diff is collapsed.
......@@ -9,6 +9,7 @@ import os
import platform
import stat
import sys
import codecs
from time import time
import cython
......@@ -279,8 +280,12 @@ class FileSourceDescriptor(SourceDescriptor):
self.filename = filename
self._cmp_name = filename
def get_lines(self):
return Utils.open_source_file(self.filename)
def get_lines(self, encoding=None, error_handling=None):
if not encoding:
return Utils.open_source_file(self.filename)
else:
return codecs.open(self.filename, "rU", encoding=encoding,
errors=error_handling)
def get_description(self):
return self.filename
......@@ -307,9 +312,13 @@ class StringSourceDescriptor(SourceDescriptor):
self.codelines = [x + "\n" for x in code.split("\n")]
self._cmp_name = name
def get_lines(self):
return self.codelines
def get_lines(self, encoding=None, error_handling=None):
if not encoding:
return self.codelines
else:
return [ line.encode(encoding, error_handling).decode(encoding)
for line in self.codelines ]
def get_description(self):
return self.name
......@@ -454,7 +463,6 @@ class PyrexScanner(Scanner):
sy = systring
else:
systring = EncodedString(systring)
systring.encoding = self.source_encoding
self.sy = sy
self.systring = systring
if False: # debug_scanner:
......
......@@ -6,14 +6,14 @@ import re
import sys
if sys.version_info[0] >= 3:
_str, _bytes = str, bytes
_unicode, _str, _bytes = str, str, bytes
IS_PYTHON3 = True
else:
_str, _bytes = unicode, str
_unicode, _str, _bytes = unicode, str, str
IS_PYTHON3 = False
empty_bytes = _bytes()
empty_str = _str()
empty_unicode = _unicode()
join_bytes = empty_bytes.join
......@@ -27,7 +27,7 @@ class UnicodeLiteralBuilder(object):
if isinstance(characters, _bytes):
# this came from a Py2 string literal in the parser code
characters = characters.decode("ASCII")
assert isinstance(characters, _str), str(type(characters))
assert isinstance(characters, _unicode), str(type(characters))
self.chars.append(characters)
def append_charval(self, char_number):
......@@ -45,7 +45,7 @@ class BytesLiteralBuilder(object):
self.target_encoding = target_encoding
def append(self, characters):
if isinstance(characters, _str):
if isinstance(characters, _unicode):
characters = characters.encode(self.target_encoding)
assert isinstance(characters, _bytes), str(type(characters))
self.chars.append(characters)
......@@ -63,7 +63,7 @@ class BytesLiteralBuilder(object):
# this *must* return a byte string!
return self.getstring()
class EncodedString(_str):
class EncodedString(_unicode):
# unicode string subclass to keep track of the original encoding.
# 'encoding' is None for unicode strings and the source encoding
# otherwise
......@@ -82,7 +82,7 @@ class EncodedString(_str):
is_unicode = property(is_unicode)
class BytesLiteral(_bytes):
# str subclass that is compatible with EncodedString
# bytes subclass that is compatible with EncodedString
encoding = None
def byteencode(self):
......
......@@ -8,7 +8,7 @@ from Errors import warning, error, InternalError
from StringEncoding import EncodedString
import Options, Naming
import PyrexTypes
from PyrexTypes import py_object_type
from PyrexTypes import py_object_type, unspecified_type
import TypeSlots
from TypeSlots import \
pyfunction_signature, pymethod_signature, \
......@@ -115,9 +115,10 @@ class Entry(object):
# api boolean Generate C API for C class or function
# utility_code string Utility code needed when this entry is used
#
# buffer_aux BufferAux or None Extra information needed for buffer variables
# buffer_aux BufferAux or None Extra information needed for buffer variables
# inline_func_in_pxd boolean Hacky special case for inline function in pxd file.
# Ideally this should not be necesarry.
# assignments [ExprNode] List of expressions that get assigned to this entry.
inline_func_in_pxd = False
borrowed = 0
......@@ -173,6 +174,10 @@ class Entry(object):
self.type = type
self.pos = pos
self.init = init
self.assignments = []
def __repr__(self):
return "Entry(name=%s, type=%s)" % (self.name, self.type)
def redeclared(self, pos):
error(pos, "'%s' does not match previous declaration" % self.name)
......@@ -344,7 +349,11 @@ class Scope(object):
cname = name
else:
cname = self.mangle(Naming.type_prefix, name)
type = PyrexTypes.CTypedefType(cname, base_type, (visibility == 'extern'))
try:
type = PyrexTypes.create_typedef_type(cname, base_type, (visibility == 'extern'))
except ValueError, e:
error(pos, e.message)
type = PyrexTypes.error_type
entry = self.declare_type(name, type, pos, cname, visibility)
type.qualified_name = entry.qualified_name
return entry
......@@ -365,6 +374,7 @@ class Scope(object):
entry = self.declare_type(name, type, pos, cname,
visibility = visibility, defining = scope is not None)
self.sue_entries.append(entry)
type.entry = entry
else:
if not (entry.is_type and entry.type.is_struct_or_union
and entry.type.kind == kind):
......@@ -513,7 +523,7 @@ class Scope(object):
if entry.as_module:
scope = entry.as_module
else:
error(pos, "'%s' is not a cimported module" % scope.qualified_name)
error(pos, "'%s' is not a cimported module" % '.'.join(path))
return None
return scope
......@@ -555,6 +565,10 @@ class Scope(object):
if name in self.entries:
return 1
return 0
def infer_types(self):
from TypeInference import get_type_inferer
get_type_inferer().infer_types(self)
class PreImportScope(Scope):
......@@ -827,6 +841,8 @@ class ModuleScope(Scope):
if not visibility in ('private', 'public', 'extern'):
error(pos, "Module-level variable cannot be declared %s" % visibility)
if not is_cdef:
if type is unspecified_type:
type = py_object_type
if not (type.is_pyobject and not type.is_extension_type):
raise InternalError(
"Non-cdef global variable is not a generic Python object")
......@@ -1056,6 +1072,10 @@ class ModuleScope(Scope):
var_entry.is_cglobal = 1
var_entry.is_readonly = 1
entry.as_variable = var_entry
def infer_types(self):
from TypeInference import PyObjectTypeInferer
PyObjectTypeInferer().infer_types(self)
class LocalScope(Scope):
......@@ -1087,7 +1107,7 @@ class LocalScope(Scope):
cname, visibility, is_cdef)
if type.is_pyobject and not Options.init_local_none:
entry.init = "0"
entry.init_to_none = type.is_pyobject and Options.init_local_none
entry.init_to_none = (type.is_pyobject or type.is_unspecified) and Options.init_local_none
entry.is_local = 1
self.var_entries.append(entry)
return entry
......@@ -1188,7 +1208,7 @@ class StructOrUnionScope(Scope):
def declare_cfunction(self, name, type, pos,
cname = None, visibility = 'private', defining = 0,
api = 0, in_pxd = 0, modifiers = ()):
self.declare_var(name, type, pos, cname, visibility)
return self.declare_var(name, type, pos, cname, visibility)
class ClassScope(Scope):
# Abstract base class for namespace of
......@@ -1235,6 +1255,8 @@ class PyClassScope(ClassScope):
def declare_var(self, name, type, pos,
cname = None, visibility = 'private', is_cdef = 0):
if type is unspecified_type:
type = py_object_type
# Add an entry for a class attribute.
entry = Scope.declare_var(self, name, type, pos,
cname, visibility, is_cdef)
......@@ -1321,6 +1343,8 @@ class CClassScope(ClassScope):
"Non-generic Python attribute cannot be exposed for writing from Python")
return entry
else:
if type is unspecified_type:
type = py_object_type
# Add an entry for a class attribute.
entry = Scope.declare_var(self, name, type, pos,
cname, visibility, is_cdef)
......@@ -1477,15 +1501,22 @@ static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
}
if (PyObject_TypeCheck(method, methoddescr_type)) { /* cdef classes */
PyMethodDescrObject *descr = (PyMethodDescrObject *)method;
return PyDescr_NewClassMethod(descr->d_type, descr->d_method);
#if PY_VERSION_HEX < 0x03020000
PyTypeObject *d_type = descr->d_type;
#else
PyTypeObject *d_type = descr->d_common.d_type;
#endif
return PyDescr_NewClassMethod(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));
}
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;
}
""")
import ExprNodes
from PyrexTypes import py_object_type, unspecified_type, spanning_type
from Visitor import CythonTransform
try:
set
except NameError:
# Python 2.3
from sets import Set as set
class TypedExprNode(ExprNodes.ExprNode):
# Used for declaring assignments of a specified type whithout a known entry.
def __init__(self, type):
self.type = type
object_expr = TypedExprNode(py_object_type)
class MarkAssignments(CythonTransform):
def mark_assignment(self, lhs, rhs):
if isinstance(lhs, ExprNodes.NameNode):
if lhs.entry is None:
# TODO: This shouldn't happen...
# It looks like comprehension loop targets are not declared soon enough.
return
lhs.entry.assignments.append(rhs)
elif isinstance(lhs, ExprNodes.SequenceNode):
for arg in lhs.args:
self.mark_assignment(arg, object_expr)
else:
# Could use this info to infer cdef class attributes...
pass
def visit_SingleAssignmentNode(self, node):
self.mark_assignment(node.lhs, node.rhs)
self.visitchildren(node)
return node
def visit_CascadedAssignmentNode(self, node):
for lhs in node.lhs_list:
self.mark_assignment(lhs, node.rhs)
self.visitchildren(node)
return node
def visit_InPlaceAssignmentNode(self, node):
self.mark_assignment(node.lhs, node.create_binop_node())
self.visitchildren(node)
return node
def visit_ForInStatNode(self, node):
# TODO: Remove redundancy with range optimization...
is_range = False
sequence = node.iterator.sequence
if isinstance(sequence, ExprNodes.SimpleCallNode):
function = sequence.function
if sequence.self is None and \
isinstance(function, ExprNodes.NameNode) and \
function.name in ('range', 'xrange'):
is_range = True
self.mark_assignment(node.target, sequence.args[0])
if len(sequence.args) > 1:
self.mark_assignment(node.target, sequence.args[1])
if len(sequence.args) > 2:
self.mark_assignment(node.target,
ExprNodes.binop_node(node.pos,
'+',
sequence.args[0],
sequence.args[2]))
if not is_range:
self.mark_assignment(node.target, object_expr)
self.visitchildren(node)
return node
def visit_ForFromStatNode(self, node):
self.mark_assignment(node.target, node.bound1)
if node.step is not None:
self.mark_assignment(node.target,
ExprNodes.binop_node(node.pos,
'+',
node.bound1,
node.step))
self.visitchildren(node)
return node
def visit_ExceptClauseNode(self, node):
if node.target is not None:
self.mark_assignment(node.target, object_expr)
self.visitchildren(node)
return node
def visit_FromCImportStatNode(self, node):
pass # Can't be assigned to...
def visit_FromImportStatNode(self, node):
for name, target in node.items:
if name != "*":
self.mark_assignment(target, object_expr)
self.visitchildren(node)
return node
class PyObjectTypeInferer:
"""
If it's not declared, it's a PyObject.
"""
def infer_types(self, scope):
"""
Given a dict of entries, map all unspecified types to a specified type.
"""
for name, entry in scope.entries.items():
if entry.type is unspecified_type:
entry.type = py_object_type
class SimpleAssignmentTypeInferer:
"""
Very basic type inference.
"""
# TODO: Implement a real type inference algorithm.
# (Something more powerful than just extending this one...)
def infer_types(self, scope):
dependancies_by_entry = {} # entry -> dependancies
entries_by_dependancy = {} # dependancy -> entries
ready_to_infer = []
for name, entry in scope.entries.items():
if entry.type is unspecified_type:
all = set()
for expr in entry.assignments:
all.update(expr.type_dependencies(scope))
if all:
dependancies_by_entry[entry] = all
for dep in all:
if dep not in entries_by_dependancy:
entries_by_dependancy[dep] = set([entry])
else:
entries_by_dependancy[dep].add(entry)
else:
ready_to_infer.append(entry)
def resolve_dependancy(dep):
if dep in entries_by_dependancy:
for entry in entries_by_dependancy[dep]:
entry_deps = dependancies_by_entry[entry]
entry_deps.remove(dep)
if not entry_deps and entry != dep:
del dependancies_by_entry[entry]
ready_to_infer.append(entry)
# Try to infer things in order...
while True:
while ready_to_infer:
entry = ready_to_infer.pop()
types = [expr.infer_type(scope) for expr in entry.assignments]
if types:
entry.type = reduce(spanning_type, types)
else:
# List comprehension?
# print "No assignments", entry.pos, entry
entry.type = py_object_type
resolve_dependancy(entry)
# Deal with simple circular dependancies...
for entry, deps in dependancies_by_entry.items():
if len(deps) == 1 and deps == set([entry]):
types = [expr.infer_type(scope) for expr in entry.assignments if expr.type_dependencies(scope) == ()]
if types:
entry.type = reduce(spanning_type, types)
types = [expr.infer_type(scope) for expr in entry.assignments]
entry.type = reduce(spanning_type, types) # might be wider...
resolve_dependancy(entry)
del dependancies_by_entry[entry]
if ready_to_infer:
break
if not ready_to_infer:
break
# We can't figure out the rest with this algorithm, let them be objects.
for entry in dependancies_by_entry:
entry.type = py_object_type
def get_type_inferer():
return SimpleAssignmentTypeInferer()
......@@ -10,6 +10,7 @@ from Nodes import Node
from ExprNodes import AtomicExprNode
class TempHandle(object):
# THIS IS DEPRECATED, USE LetRefNode instead
temp = None
needs_xdecref = False
def __init__(self, type):
......@@ -23,6 +24,7 @@ class TempHandle(object):
return CleanupTempRefNode(pos, handle=self, type=self.type)
class TempRefNode(AtomicExprNode):
# THIS IS DEPRECATED, USE LetRefNode instead
# handle TempHandle
def analyse_types(self, env):
......@@ -52,6 +54,7 @@ class TempRefNode(AtomicExprNode):
rhs.free_temps(code)
class CleanupTempRefNode(TempRefNode):
# THIS IS DEPRECATED, USE LetRefNode instead
# handle TempHandle
def generate_assignment_code(self, rhs, code):
......@@ -63,6 +66,8 @@ class CleanupTempRefNode(TempRefNode):
self.handle.needs_cleanup = False
class TempsBlockNode(Node):
# THIS IS DEPRECATED, USE LetNode instead
"""
Creates a block which allocates temporary variables.
This is used by transforms to output constructs that need
......
......@@ -17,7 +17,7 @@
DEF _buffer_format_string_len = 255
cimport python_buffer as pybuf
from python_object cimport PyObject
from python_ref cimport PyObject, Py_INCREF, Py_XDECREF
cimport stdlib
cimport stdio
......@@ -151,6 +151,7 @@ cdef extern from "numpy/arrayobject.h":
npy_intp *shape "dimensions"
npy_intp *strides
dtype descr
PyObject* base
# Note: This syntax (function definition in pxd files) is an
# experimental exception made for __getbuffer__ and __releasebuffer__
......@@ -292,12 +293,6 @@ cdef extern from "numpy/arrayobject.h":
ctypedef long double npy_float96
ctypedef long double npy_float128
ctypedef float complex npy_complex64
ctypedef double complex npy_complex128
ctypedef long double complex npy_complex120
ctypedef long double complex npy_complex192
ctypedef long double complex npy_complex256
ctypedef struct npy_cfloat:
double real
double imag
......@@ -310,6 +305,26 @@ cdef extern from "numpy/arrayobject.h":
double real
double imag
ctypedef struct npy_complex64:
double real
double imag
ctypedef struct npy_complex128:
double real
double imag
ctypedef struct npy_complex160:
double real
double imag
ctypedef struct npy_complex192:
double real
double imag
ctypedef struct npy_complex256:
double real
double imag
ctypedef struct PyArray_Dims:
npy_intp *ptr
int len
......@@ -469,6 +484,13 @@ cdef extern from "numpy/arrayobject.h":
object PyArray_Take(ndarray ap, object items, int axis)
object PyArray_Put(ndarray ap, object items, object values)
void PyArray_ITER_RESET(flatiter it) nogil
void PyArray_ITER_NEXT(flatiter it) nogil
void PyArray_ITER_GOTO(flatiter it, npy_intp* destination) nogil
void PyArray_ITER_GOTO1D(flatiter it, npy_intp ind) nogil
void* PyArray_ITER_DATA(flatiter it) nogil
bint PyArray_ITER_NOTDONE(flatiter it) nogil
void PyArray_MultiIter_RESET(broadcast multi) nogil
void PyArray_MultiIter_NEXT(broadcast multi) nogil
void PyArray_MultiIter_GOTO(broadcast multi, npy_intp dest) nogil
......@@ -895,6 +917,21 @@ cdef extern from "numpy/ufuncobject.h":
(PyUFuncGenericFunction *, void **, char *, int, int, int,
int, char *, char *, int, char *)
void import_ufunc()
void import_ufunc()
cdef inline void set_array_base(ndarray arr, object base):
cdef PyObject* baseptr
if base is None:
baseptr = NULL
else:
Py_INCREF(base) # important to do this before decref below!
baseptr = <PyObject*>base
Py_XDECREF(arr.base)
arr.base = baseptr
cdef inline object get_array_base(ndarray arr):
if arr.base is NULL:
return None
else:
return <object>arr.base
......@@ -125,6 +125,7 @@ from python_mem cimport *
from python_tuple cimport *
from python_list cimport *
from python_object cimport *
from python_cobject cimport *
from python_sequence cimport *
from python_mapping cimport *
from python_iterator cimport *
......
cdef extern from "Python.h":
ctypedef void PyObject
############################################################################
# 7.2.2 Boolean Objects
......
# Please see the Python header files (object.h) for docs
# Please see the Python header files (object.h/abstract.h) for docs
cdef extern from "Python.h":
ctypedef void PyObject
ctypedef struct bufferinfo:
void *buf
Py_ssize_t len
Py_ssize_t itemsize
int readonly
int ndim
char *format
Py_ssize_t *shape
Py_ssize_t *strides
Py_ssize_t *suboffsets
void *internal
ctypedef bufferinfo Py_buffer
cdef enum:
PyBUF_SIMPLE,
......@@ -39,23 +25,85 @@ cdef extern from "Python.h":
PyBUF_WRITE,
PyBUF_SHADOW
int PyObject_CheckBuffer(PyObject* obj)
int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
void PyObject_ReleaseBuffer(PyObject *obj, Py_buffer *view)
bint PyObject_CheckBuffer(object obj)
# Return 1 if obj supports the buffer interface otherwise 0.
int PyObject_GetBuffer(object obj, Py_buffer *view, int flags) except -1
# Export obj into a Py_buffer, view. These arguments must never be
# NULL. The flags argument is a bit field indicating what kind of
# buffer the caller is prepared to deal with and therefore what
# kind of buffer the exporter is allowed to return. The buffer
# interface allows for complicated memory sharing possibilities,
# but some caller may not be able to handle all the complexity but
# may want to see if the exporter will let them take a simpler
# view to its memory.
# Some exporters may not be able to share memory in every possible
# way and may need to raise errors to signal to some consumers
# that something is just not possible. These errors should be a
# BufferError unless there is another error that is actually
# causing the problem. The exporter can use flags information to
# simplify how much of the Py_buffer structure is filled in with
# non-default values and/or raise an error if the object can’t
# support a simpler view of its memory.
# 0 is returned on success and -1 on error.
void PyBuffer_Release(object obj, object view)
# Release the buffer view over obj. This should be called when the
# buffer is no longer being used as it may free memory from it.
void* PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices)
# ??
int PyBuffer_SizeFromFormat(char *) # actually const char
# Return the implied ~Py_buffer.itemsize from the struct-stype
# ~Py_buffer.format
int PyBuffer_ToContiguous(void *buf, Py_buffer *view, Py_ssize_t len, char fort)
# ??
int PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort)
int PyObject_CopyData(PyObject *dest, PyObject *src)
int PyBuffer_IsContiguous(Py_buffer *view, char fort)
# ??
int PyObject_CopyToObject(object obj, void *buf, Py_ssize_t len, char fortran) except -1
# Copy len bytes of data pointed to by the contiguous chunk of
# memory pointed to by buf into the buffer exported by obj. The
# buffer must of course be writable. Return 0 on success and
# return -1 and raise an error on failure. If the object does not
# have a writable buffer, then an error is raised. If fortran is
# 'F', then if the object is multi-dimensional, then the data will
# be copied into the array in Fortran-style (first dimension
# varies the fastest). If fortran is 'C', then the data will be
# copied into the array in C-style (last dimension varies the
# fastest). If fortran is 'A', then it does not matter and the
# copy will be made in whatever way is more efficient.
int PyObject_CopyData(object dest, object src)
# Copy the data from the src buffer to the buffer of destination
bint PyBuffer_IsContiguous(Py_buffer *view, char fort)
# Return 1 if the memory defined by the view is C-style (fortran
# is 'C') or Fortran-style (fortran is 'F') contiguous or either
# one (fortran is 'A'). Return 0 otherwise.
void PyBuffer_FillContiguousStrides(int ndims,
Py_ssize_t *shape,
Py_ssize_t *strides,
int itemsize,
char fort)
# Fill the strides array with byte-strides of a contiguous
# (Fortran-style if fort is 'F' or C-style otherwise) array of the
# given shape with the given number of bytes per element.
int PyBuffer_FillInfo(Py_buffer *view, void *buf,
Py_ssize_t len, int readonly,
int flags)
int flags) except -1
# Fill in a buffer-info structure, view, correctly for an exporter
# that can only share a contiguous chunk of memory of “unsigned
# bytes” of the given length. Return 0 on success and -1 (with
# raising an error) on error.
PyObject* PyObject_Format(PyObject* obj,
PyObject *format_spec)
object PyObject_Format(object obj, object format_spec)
# Takes an arbitrary object and returns the result of calling
# obj.__format__(format_spec).
from python_ref cimport PyObject
cdef extern from "Python.h":
###########################################################################
# Warning:
#
# The CObject API is deprecated as of Python 3.1. Please switch to
# the new Capsules API.
###########################################################################
int PyCObject_Check(object p)
# Return true if its argument is a PyCObject.
object PyCObject_FromVoidPtr(void* cobj, void (*destr)(void *))
# Return value: New reference.
#
# Create a PyCObject from the void * cobj. The destr function will
# be called when the object is reclaimed, unless it is NULL.
object PyCObject_FromVoidPtrAndDesc(void* cobj, void* desc, void (*destr)(void *, void *))
# Return value: New reference.
#
# Create a PyCObject from the void * cobj. The destr function will
# be called when the object is reclaimed. The desc argument can be
# used to pass extra callback data for the destructor function.
void* PyCObject_AsVoidPtr(object self)
# Return the object void * that the PyCObject self was created with.
void* PyCObject_GetDesc(object self)
# Return the description void * that the PyCObject self was created with.
int PyCObject_SetVoidPtr(object self, void* cobj)
# Set the void pointer inside self to cobj. The PyCObject must not
# have an associated destructor. Return true on success, false on
# failure.
cdef extern from "Python.h":
ctypedef void PyObject
ctypedef struct Py_complex
############################################################################
......
from python_ref cimport PyObject
cdef extern from "Python.h":
ctypedef void PyObject
############################################################################
# 7.4.1 Dictionary Objects
############################################################################
# PyDictObject
# This subtype of PyObject represents a Python dictionary object.
#
# This subtype of PyObject represents a Python dictionary object
# (i.e. the 'dict' type).
# PyTypeObject PyDict_Type
# This instance of PyTypeObject represents the Python dictionary type. This is exposed to Python programs as dict and types.DictType.
#
# This instance of PyTypeObject represents the Python dictionary
# type. This is exposed to Python programs as dict and
# types.DictType.
bint PyDict_Check(object p)
# Return true if p is a dict object or an instance of a subtype of
......@@ -29,7 +38,7 @@ cdef extern from "Python.h":
void PyDict_Clear(object p)
# Empty an existing dictionary of all key-value pairs.
int PyDict_Contains(object p, object key)
int PyDict_Contains(object p, object key) except -1
# Determine if dictionary p contains key. If an item in p is
# matches key, return 1, otherwise return 0. On error, return
# -1. This is equivalent to the Python expression "key in p".
......@@ -38,22 +47,22 @@ cdef extern from "Python.h":
# Return value: New reference.
# Return a new dictionary that contains the same key-value pairs as p.
int PyDict_SetItem(object p, object key, object val)
int PyDict_SetItem(object p, object key, object val) except -1
# Insert value into the dictionary p with a key of key. key must
# be hashable; if it isn't, TypeError will be raised. Return 0 on
# success or -1 on failure.
int PyDict_SetItemString(object p, char *key, object val)
int PyDict_SetItemString(object p, char *key, object val) except -1
# Insert value into the dictionary p using key as a key. key
# should be a char*. The key object is created using
# PyString_FromString(key). Return 0 on success or -1 on failure.
int PyDict_DelItem(object p, object key)
int PyDict_DelItem(object p, object key) except -1
# Remove the entry in dictionary p with key key. key must be
# hashable; if it isn't, TypeError is raised. Return 0 on success
# or -1 on failure.
int PyDict_DelItemString(object p, char *key)
int PyDict_DelItemString(object p, char *key) except -1
# Remove the entry in dictionary p which has a key specified by
# the string key. Return 0 on success or -1 on failure.
......@@ -87,7 +96,8 @@ cdef extern from "Python.h":
# Python Library Reference).
Py_ssize_t PyDict_Size(object p)
# Return the number of items in the dictionary. This is equivalent to "len(p)" on a dictionary.
# Return the number of items in the dictionary. This is equivalent
# to "len(p)" on a dictionary.
int PyDict_Next(object p, Py_ssize_t *ppos, PyObject* *pkey, PyObject* *pvalue)
# Iterate over all key-value pairs in the dictionary p. The int
......@@ -128,7 +138,7 @@ cdef extern from "Python.h":
# Py_DECREF(o);
# }
int PyDict_Merge(object a, object b, int override)
int PyDict_Merge(object a, object b, int override) except -1
# Iterate over mapping object b adding key-value pairs to
# dictionary a. b may be a dictionary, or any object supporting
# PyMapping_Keys() and PyObject_GetItem(). If override is true,
......@@ -137,11 +147,11 @@ cdef extern from "Python.h":
# matching key in a. Return 0 on success or -1 if an exception was
# raised.
int PyDict_Update(object a, object b)
int PyDict_Update(object a, object b) except -1
# This is the same as PyDict_Merge(a, b, 1) in C, or a.update(b)
# in Python. Return 0 on success or -1 if an exception was raised.
int PyDict_MergeFromSeq2(object a, object seq2, int override)
int PyDict_MergeFromSeq2(object a, object seq2, int override) except -1
# Update or merge into dictionary a, from the key-value pairs in
# seq2. seq2 must be an iterable object producing iterable objects
# of length 2, viewed as key-value pairs. In case of duplicate
......
from python_ref cimport PyObject
cdef extern from "Python.h":
ctypedef void PyObject
#####################################################################
# 3. Exception Handling
......
cdef extern from "Python.h":
ctypedef void PyObject
############################################################################
# 7.2.3
############################################################################
# PyFloatObject
# This subtype of PyObject represents a Python floating point object.
#
# This subtype of PyObject represents a Python floating point object.
# PyTypeObject PyFloat_Type
# This instance of PyTypeObject represents the Python floating point type. This is the same object as float and types.FloatType.
#
# This instance of PyTypeObject represents the Python floating
# point type. This is the same object as float and
# types.FloatType.
bint PyFloat_Check(object p)
# Return true if its argument is a PyFloatObject or a subtype of
......@@ -28,7 +32,8 @@ cdef extern from "Python.h":
# Create a PyFloatObject object from v, or NULL on failure.
double PyFloat_AsDouble(object pyfloat)
# Return a C double representation of the contents of pyfloat.
# Return a C double representation of the contents of pyfloat.
double PyFloat_AS_DOUBLE(object pyfloat)
# Return a C double representation of the contents of pyfloat, but without error checking.
# Return a C double representation of the contents of pyfloat, but
# without error checking.
from python_ref cimport PyObject
cdef extern from "Python.h":
ctypedef void PyObject
############################################################################
# 7.5.3 Function Objects
############################################################################
# There are a few functions specific to Python functions.
# PyFunctionObject
# The C structure used for functions.
#
# The C structure used for functions.
# PyTypeObject PyFunction_Type
#
# This is an instance of PyTypeObject and represents the Python
# function type. It is exposed to Python programmers as
# types.FunctionType.
......@@ -43,7 +49,7 @@ cdef extern from "Python.h":
# Return the argument default values of the function object
# op. This can be a tuple of arguments or NULL.
int PyFunction_SetDefaults(object op, object defaults)
int PyFunction_SetDefaults(object op, object defaults) except -1
# Set the argument default values for the function object
# op. defaults must be Py_None or a tuple.
# Raises SystemError and returns -1 on failure.
......@@ -53,7 +59,7 @@ cdef extern from "Python.h":
# Return the closure associated with the function object op. This
# can be NULL or a tuple of cell objects.
int PyFunction_SetClosure(object op, object closure)
int PyFunction_SetClosure(object op, object closure) except -1
# Set the closure associated with the function object op. closure
# must be Py_None or a tuple of cell objects.
# Raises SystemError and returns -1 on failure.
cdef extern from "Python.h":
ctypedef void PyObject
############################################################################
# 7.5.2 Instance Objects
############################################################################
# PyTypeObject PyInstance_Type
# Type object for class instances.
# int PyInstance_Check(PyObject *obj)
#
# Type object for class instances.
int PyInstance_Check(object obj)
# Return true if obj is an instance.
object PyInstance_New(PyObject* cls, object arg, object kw)
object PyInstance_New(object cls, object arg, object kw)
# Return value: New reference.
# Create a new instance of a specific class. The parameters arg
# and kw are used as the positional and keyword parameters to the
......
cdef extern from "Python.h":
ctypedef void PyObject
ctypedef unsigned long long PY_LONG_LONG
############################################################################
# Integer Objects
......@@ -48,7 +48,7 @@ cdef extern from "Python.h":
# Create a new integer object with a value of ival. If the value
# exceeds LONG_MAX, a long integer object is returned.
long PyInt_AsLong(object io)
long PyInt_AsLong(object io) except? -1
# Will first attempt to cast the object to a PyIntObject, if it is
# not already one, and then return its value. If there is an
# error, -1 is returned, and the caller should check
......@@ -64,7 +64,6 @@ cdef extern from "Python.h":
# value as unsigned long. This function does not check for
# overflow.
ctypedef unsigned long long PY_LONG_LONG
PY_LONG_LONG PyInt_AsUnsignedLongLongMask(object io)
# Will first attempt to cast the object to a PyIntObject or
# PyLongObject, if it is not already one, and then return its
......
......@@ -3,7 +3,7 @@ cdef extern from "Python.h":
############################################################################
# 6.5 Iterator Protocol
############################################################################
int PyIter_Check(object o)
bint PyIter_Check(object o)
# Return true if the object o supports the iterator protocol.
object PyIter_Next(object o)
......
from python_ref cimport PyObject
cdef extern from "Python.h":
ctypedef void PyObject
############################################################################
# Lists
############################################################################
object PyList_New(Py_ssize_t len)
# Return a new list of length len on success, or NULL on
# failure. Note: If length is greater than zero, the returned list
# object's items are set to NULL. Thus you cannot use abstract API
# Return a new list of length len on success, or NULL on failure.
#
# Note: If length is greater than zero, the returned list object's
# items are set to NULL. Thus you cannot use abstract API
# functions such as PySequence_SetItem() or expose the object to
# Python code before setting all items to a real object with
# PyList_SetItem().
bint PyList_Check(object p)
# Return true if p is a list object or an instance of a subtype of the list type.
# Return true if p is a list object or an instance of a subtype of
# the list type.
bint PyList_CheckExact(object p)
# Return true if p is a list object, but not an instance of a subtype of the list type.
# Return true if p is a list object, but not an instance of a
# subtype of the list type.
Py_ssize_t PyList_Size(object list)
# Return the length of the list object in list; this is equivalent to "len(list)" on a list object.
# Return the length of the list object in list; this is equivalent
# to "len(list)" on a list object.
Py_ssize_t PyList_GET_SIZE(object list)
# Macro form of PyList_Size() without error checking.
......@@ -35,7 +40,7 @@ cdef extern from "Python.h":
# Return value: Borrowed reference.
# Macro form of PyList_GetItem() without error checking.
int PyList_SetItem(object list, Py_ssize_t index, object item)
int PyList_SetItem(object list, Py_ssize_t index, object item) except -1
# Set the item at index index in list to item. Return 0 on success
# or -1 on failure. Note: This function ``steals'' a reference to
# item and discards a reference to an item already in the list at
......@@ -49,12 +54,12 @@ cdef extern from "Python.h":
# to any item that it being replaced; any reference in list at
# position i will be *leaked*.
int PyList_Insert(object list, Py_ssize_t index, object item)
int PyList_Insert(object list, Py_ssize_t index, object item) except -1
# Insert the item item into list list in front of index
# index. Return 0 if successful; return -1 and set an exception if
# unsuccessful. Analogous to list.insert(index, item).
int PyList_Append(object list, object item)
int PyList_Append(object list, object item) except -1
# Append the object item at the end of list list. Return 0 if
# successful; return -1 and set an exception if
# unsuccessful. Analogous to list.append(item).
......@@ -65,17 +70,17 @@ cdef extern from "Python.h":
# between low and high. Return NULL and set an exception if
# unsuccessful. Analogous to list[low:high].
int PyList_SetSlice(object list, Py_ssize_t low, Py_ssize_t high, object itemlist)
int PyList_SetSlice(object list, Py_ssize_t low, Py_ssize_t high, object itemlist) except -1
# Set the slice of list between low and high to the contents of
# itemlist. Analogous to list[low:high] = itemlist. The itemlist
# may be NULL, indicating the assignment of an empty list (slice
# deletion). Return 0 on success, -1 on failure.
int PyList_Sort(object list)
int PyList_Sort(object list) except -1
# Sort the items of list in place. Return 0 on success, -1 on
# failure. This is equivalent to "list.sort()".
int PyList_Reverse(object list)
int PyList_Reverse(object list) except -1
# Reverse the items of list in place. Return 0 on success, -1 on
# failure. This is the equivalent of "list.reverse()".
......
from python_unicode cimport Py_UNICODE
cdef extern from "Python.h":
ctypedef void PyObject
ctypedef long PY_LONG_LONG
ctypedef long long PY_LONG_LONG
ctypedef unsigned long long uPY_LONG_LONG
############################################################################
# 7.2.3 Long Integer Objects
############################################################################
# PyLongObject
# This subtype of PyObject represents a Python long integer object.
#
# This subtype of PyObject represents a Python long integer object.
# PyTypeObject PyLong_Type
#
# This instance of PyTypeObject represents the Python long integer
# type. This is the same object as long and types.LongType.
......@@ -29,8 +35,7 @@ cdef extern from "Python.h":
# Return value: New reference.
# Return a new PyLongObject object from a C long long, or NULL on failure.
object PyLong_FromUnsignedLongLong(PY_LONG_LONG v)
#PyObject* PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG v)
object PyLong_FromUnsignedLongLong(uPY_LONG_LONG v)
# Return value: New reference.
# Return a new PyLongObject object from a C unsigned long long, or NULL on failure.
......@@ -51,8 +56,7 @@ cdef extern from "Python.h":
# inclusive. Leading spaces are ignored. If there are no digits,
# ValueError will be raised.
# object PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)
object PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)
# Return value: New reference.
# Convert a sequence of Unicode digits to a Python long integer
# value. The first parameter, u, points to the first character of
......@@ -82,7 +86,7 @@ cdef extern from "Python.h":
# cannot be represented as a long long, an OverflowError will be
# raised.
PY_LONG_LONG PyLong_AsUnsignedLongLong(object pylong)
uPY_LONG_LONG PyLong_AsUnsignedLongLong(object pylong)
#unsigned PY_LONG_LONG PyLong_AsUnsignedLongLong(object pylong)
# Return a C unsigned long long from a Python long integer. If
# pylong cannot be represented as an unsigned long long, an
......@@ -93,13 +97,12 @@ cdef extern from "Python.h":
# Return a C unsigned long from a Python long integer, without
# checking for overflow.
PY_LONG_LONG PyLong_AsUnsignedLongLongMask(object io)
uPY_LONG_LONG PyLong_AsUnsignedLongLongMask(object io)
#unsigned PY_LONG_LONG PyLong_AsUnsignedLongLongMask(object io)
# Return a C unsigned long long from a Python long integer,
# without checking for overflow.
double PyLong_AsDouble(object pylong)
double PyLong_AsDouble(object pylong) except? -1.0
# Return a C double representation of the contents of pylong. If
# pylong cannot be approximately represented as a double, an
# OverflowError exception is raised and -1.0 will be returned.
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
cdef extern from "Python.h":
ctypedef void PyObject
ctypedef void PyTypeObject
# The C structure of the objects used to describe built-in types.
############################################################################
......@@ -38,7 +37,7 @@ cdef extern from "Python.h":
object PyType_GenericNew(object type, object args, object kwds)
# Return value: New reference.
bint PyType_Ready(object type)
bint PyType_Ready(object type) except -1
# Finalize a type object. This should be called on all type
# objects to finish their initialization. This function is
# responsible for adding inherited slots from a type's base
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
cdef extern from "complex_numbers_c89_T398.h": pass
include "complex_numbers_T305.pyx"
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment