Commit ebbac140 authored by Robert Bradshaw's avatar Robert Bradshaw

merge changes for 0.9.6.7 release

parents 15833ae4 286b89f3
...@@ -88,7 +88,10 @@ class CCodeWriter: ...@@ -88,7 +88,10 @@ class CCodeWriter:
F = open(file).readlines() F = open(file).readlines()
self.input_file_contents[file] = F self.input_file_contents[file] = F
return F return F
def get_py_version_hex(self, pyversion):
return "0x%02X%02X%02X%02X" % (tuple(pyversion) + (0,0,0,0))[:4]
def mark_pos(self, pos): def mark_pos(self, pos):
file, line, col = pos file, line, col = pos
contents = self.file_contents(file) contents = self.file_contents(file)
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
# to be rebuilt next time pyrexc is run. # to be rebuilt next time pyrexc is run.
# #
string_prefixes = "cCrR" string_prefixes = "cCrRuU"
def make_lexicon(): def make_lexicon():
from Cython.Plex import \ from Cython.Plex import \
......
...@@ -1074,12 +1074,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1074,12 +1074,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
Naming.stringtab_cname) Naming.stringtab_cname)
for entry in entries: for entry in entries:
code.putln( code.putln(
"{&%s, %s, sizeof(%s)}," % ( "{&%s, %s, sizeof(%s), %d}," % (
entry.pystring_cname, entry.pystring_cname,
entry.cname, entry.cname,
entry.cname)) entry.cname,
isinstance(entry.init, unicode)
))
code.putln( code.putln(
"{0, 0, 0}") "{0, 0, 0, 0}")
code.putln( code.putln(
"};") "};")
......
...@@ -888,13 +888,15 @@ class DefNode(FuncDefNode): ...@@ -888,13 +888,15 @@ class DefNode(FuncDefNode):
if self.entry.signature is TypeSlots.pyfunction_signature: if self.entry.signature is TypeSlots.pyfunction_signature:
if len(self.args) == 0: if len(self.args) == 0:
self.entry.signature = TypeSlots.pyfunction_noargs self.entry.signature = TypeSlots.pyfunction_noargs
elif len(self.args) == 1 and self.args[0].default is None: elif len(self.args) == 1:
self.entry.signature = TypeSlots.pyfunction_onearg if self.args[0].default is None and not self.args[0].kw_only:
self.entry.signature = TypeSlots.pyfunction_onearg
elif self.entry.signature is TypeSlots.pymethod_signature: elif self.entry.signature is TypeSlots.pymethod_signature:
if len(self.args) == 1: if len(self.args) == 1:
self.entry.signature = TypeSlots.unaryfunc self.entry.signature = TypeSlots.unaryfunc
elif len(self.args) == 2 and self.args[1].default is None: elif len(self.args) == 2:
self.entry.signature = TypeSlots.ibinaryfunc if self.args[1].default is None and not self.args[1].kw_only:
self.entry.signature = TypeSlots.ibinaryfunc
sig = self.entry.signature sig = self.entry.signature
nfixed = sig.num_fixed_args() nfixed = sig.num_fixed_args()
for i in range(nfixed): for i in range(nfixed):
...@@ -2784,7 +2786,7 @@ utility_function_predeclarations = \ ...@@ -2784,7 +2786,7 @@ utility_function_predeclarations = \
typedef struct {const char *s; const void **p;} __Pyx_CApiTabEntry; /*proto*/ typedef struct {const char *s; const void **p;} __Pyx_CApiTabEntry; /*proto*/
typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/ typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
typedef struct {PyObject **p; char *s; long n;} __Pyx_StringTabEntry; /*proto*/ typedef struct {PyObject **p; char *s; long n; int is_unicode;} __Pyx_StringTabEntry; /*proto*/
#define __pyx_PyIndex_AsSsize_t(b) PyInt_AsSsize_t(PyNumber_Index(b)) #define __pyx_PyIndex_AsSsize_t(b) PyInt_AsSsize_t(PyNumber_Index(b))
...@@ -3297,7 +3299,11 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/ ...@@ -3297,7 +3299,11 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
""",""" ""","""
static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
while (t->p) { while (t->p) {
*t->p = PyString_FromStringAndSize(t->s, t->n - 1); if (t->is_unicode) {
*t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
} else {
*t->p = PyString_FromStringAndSize(t->s, t->n - 1);
}
if (!*t->p) if (!*t->p)
return -1; return -1;
++t; ++t;
......
...@@ -493,7 +493,7 @@ def p_opt_string_literal(s): ...@@ -493,7 +493,7 @@ def p_opt_string_literal(s):
def p_string_literal(s): def p_string_literal(s):
# A single string or char literal. # A single string or char literal.
# Returns (kind, value) where kind in ('', 'c', 'r') # Returns (kind, value) where kind in ('', 'c', 'r', 'u')
if s.sy == 'STRING': if s.sy == 'STRING':
value = unquote(s.systring) value = unquote(s.systring)
s.next() s.next()
...@@ -502,7 +502,7 @@ def p_string_literal(s): ...@@ -502,7 +502,7 @@ def p_string_literal(s):
pos = s.position() pos = s.position()
#is_raw = s.systring[:1].lower() == "r" #is_raw = s.systring[:1].lower() == "r"
kind = s.systring[:1].lower() kind = s.systring[:1].lower()
if kind not in "cr": if kind not in "cru":
kind = '' kind = ''
chars = [] chars = []
while 1: while 1:
...@@ -513,6 +513,8 @@ def p_string_literal(s): ...@@ -513,6 +513,8 @@ def p_string_literal(s):
systr = s.systring systr = s.systring
if len(systr) == 1 and systr in "'\"\n": if len(systr) == 1 and systr in "'\"\n":
chars.append('\\') chars.append('\\')
if kind == 'u' and not isinstance(systr, unicode):
systr = systr.decode("UTF-8")
chars.append(systr) chars.append(systr)
elif sy == 'ESCAPE': elif sy == 'ESCAPE':
systr = s.systring systr = s.systring
...@@ -533,6 +535,8 @@ def p_string_literal(s): ...@@ -533,6 +535,8 @@ def p_string_literal(s):
chars.append('\\x0' + systr[2:]) chars.append('\\x0' + systr[2:])
elif c == '\n': elif c == '\n':
pass pass
elif c == 'u':
chars.append(systr)
else: else:
chars.append(r'\\' + systr[1:]) chars.append(r'\\' + systr[1:])
elif sy == 'NEWLINE': elif sy == 'NEWLINE':
...@@ -546,7 +550,10 @@ def p_string_literal(s): ...@@ -546,7 +550,10 @@ def p_string_literal(s):
"Unexpected token %r:%r in string literal" % "Unexpected token %r:%r in string literal" %
(sy, s.systring)) (sy, s.systring))
s.next() s.next()
value = join(chars, '') if kind == 'u':
value = u''.join(chars)
else:
value = ''.join(chars)
#print "p_string_literal: value =", repr(value) ### #print "p_string_literal: value =", repr(value) ###
return kind, value return kind, value
...@@ -1763,20 +1770,15 @@ def p_def_statement(s): ...@@ -1763,20 +1770,15 @@ def p_def_statement(s):
starstar_arg = None starstar_arg = None
if s.sy == '*': if s.sy == '*':
s.next() s.next()
if s.sy == 'IDENT':
star_arg = p_py_arg_decl(s)
if s.sy == ',': if s.sy == ',':
s.next() s.next()
if s.sy == 'IDENT': if s.sy == 'IDENT':
args.extend(p_c_arg_list(s, in_pyfunc = 1, kw_only = 1)) args.extend(p_c_arg_list(s, in_pyfunc = 1, kw_only = 1))
else: if s.sy == '**':
star_arg = p_py_arg_decl(s)
if s.sy == ',':
s.next() s.next()
if s.sy == '**': starstar_arg = p_py_arg_decl(s)
s.next()
starstar_arg = p_py_arg_decl(s)
elif s.sy == 'IDENT':
args.extend(p_c_arg_list(s, in_pyfunc = 1,
kw_only = 1))
elif s.sy == '**': elif s.sy == '**':
s.next() s.next()
starstar_arg = p_py_arg_decl(s) starstar_arg = p_py_arg_decl(s)
......
...@@ -717,6 +717,8 @@ class CStringType: ...@@ -717,6 +717,8 @@ class CStringType:
exception_value = "NULL" exception_value = "NULL"
def literal_code(self, value): def literal_code(self, value):
if isinstance(value, unicode):
value = value.encode("UTF-8")
return '"%s"' % value return '"%s"' % value
......
...@@ -515,12 +515,14 @@ class BuiltinScope(Scope): ...@@ -515,12 +515,14 @@ class BuiltinScope(Scope):
# TODO: perhapse these should all be declared in some universal .pxi file? # TODO: perhapse these should all be declared in some universal .pxi file?
builtin_functions = { builtin_functions = {
"hasattr": ["PyObject_HasAttrString", c_bint_type, (py_object_type, c_char_ptr_type)], "hasattr": ["PyObject_HasAttr", c_bint_type, (py_object_type, py_object_type)],
"setattr": ["PyObject_SetAttr", c_int_type, (py_object_type, py_object_type, py_object_type), -1],
"cmp": ["PyObject_Compare", c_int_type, (py_object_type, py_object_type), None, True], "cmp": ["PyObject_Compare", c_int_type, (py_object_type, py_object_type), None, True],
"repr": ["PyObject_Repr", py_object_type, (py_object_type, ), 0], "repr": ["PyObject_Repr", py_object_type, (py_object_type, ), 0],
# "str": ["PyObject_Str", py_object_type, (py_object_type, ), 0], # "str": ["PyObject_Str", py_object_type, (py_object_type, ), 0],
"unicode": ["PyObject_Unicode", py_object_type, (py_object_type, ), 0], "unicode": ["PyObject_Unicode", py_object_type, (py_object_type, ), 0],
"isinstance": ["PyObject_IsInstance", c_bint_type, (py_object_type, py_object_type), -1], "isinstance": ["PyObject_IsInstance", c_bint_type, (py_object_type, py_object_type), -1],
"issubclass": ["PyObject_IsSubclass", c_bint_type, (py_object_type, py_object_type), -1],
"hash": ["PyObject_Hash", c_long_type, (py_object_type, ), -1, True], "hash": ["PyObject_Hash", c_long_type, (py_object_type, ), -1, True],
"type": ["PyObject_Type", py_object_type, (py_object_type, ), 0], "type": ["PyObject_Type", py_object_type, (py_object_type, ), 0],
"len": ["PyObject_Size", c_py_ssize_t_type, (py_object_type, ), -1], "len": ["PyObject_Size", c_py_ssize_t_type, (py_object_type, ), -1],
......
...@@ -105,22 +105,23 @@ class SlotDescriptor: ...@@ -105,22 +105,23 @@ class SlotDescriptor:
# slot_name string Member name of the slot in the type object # slot_name string Member name of the slot in the type object
# is_initialised_dynamically Is initialised by code in the module init function # is_initialised_dynamically Is initialised by code in the module init function
def __init__(self, slot_name, min_version=None, dynamic = 0): def __init__(self, slot_name, dynamic = 0, min_python_version = None):
self.slot_name = slot_name self.slot_name = slot_name
self.is_initialised_dynamically = dynamic self.is_initialised_dynamically = dynamic
self.min_version = min_version self.min_python_version = min_python_version
def generate(self, scope, code): def generate(self, scope, code):
if self.is_initialised_dynamically: if self.is_initialised_dynamically:
value = 0 value = 0
else: else:
value = self.slot_code(scope) value = self.slot_code(scope)
if self.min_version: if self.min_python_version is not None:
code.putln("#if PY_VERSION_HEX >= 0x%X" % Naming.py_version_hex(*self.min_version)) code.putln("#if PY_VERSION_HEX >= " +
code.get_py_version_hex(self.min_python_version))
code.putln("%s, /*%s*/" % (value, self.slot_name)) code.putln("%s, /*%s*/" % (value, self.slot_name))
if self.min_version: if self.min_python_version is not None:
code.putln("#endif") code.putln("#endif")
# Some C implementations have trouble statically # Some C implementations have trouble statically
# initialising a global with a pointer to an extern # initialising a global with a pointer to an extern
# function, so we initialise some of the type slots # function, so we initialise some of the type slots
...@@ -181,8 +182,10 @@ class MethodSlot(SlotDescriptor): ...@@ -181,8 +182,10 @@ class MethodSlot(SlotDescriptor):
# method_name string The __xxx__ name of the method # method_name string The __xxx__ name of the method
# default string or None Default value of the slot # default string or None Default value of the slot
def __init__(self, signature, slot_name, method_name, min_version=None, default = None): def __init__(self, signature, slot_name, method_name,
SlotDescriptor.__init__(self, slot_name, min_version) default = None, min_python_version = None):
SlotDescriptor.__init__(self, slot_name,
min_python_version = min_python_version)
self.signature = signature self.signature = signature
self.slot_name = slot_name self.slot_name = slot_name
self.method_name = method_name self.method_name = method_name
...@@ -499,7 +502,7 @@ PyNumberMethods = ( ...@@ -499,7 +502,7 @@ PyNumberMethods = (
MethodSlot(ibinaryfunc, "nb_inplace_true_divide", "__itruediv__"), MethodSlot(ibinaryfunc, "nb_inplace_true_divide", "__itruediv__"),
# Added in release 2.5 # Added in release 2.5
MethodSlot(unaryfunc, "nb_index", "__index__", min_version=(2,5)), MethodSlot(unaryfunc, "nb_index", "__index__", min_python_version=(2,5)),
) )
PySequenceMethods = ( PySequenceMethods = (
......
...@@ -37,8 +37,16 @@ class build_ext (distutils.command.build_ext.build_ext): ...@@ -37,8 +37,16 @@ class build_ext (distutils.command.build_ext.build_ext):
if not self.extensions: if not self.extensions:
return return
#suffix = self.swig_cpp and '.cpp' or '.c'
suffix = '.c'
cplus = 0
include_dirs = []
if extension is not None: if extension is not None:
module_name = extension.name module_name = extension.name
include_dirs = extension.include_dirs or []
if extension.language == "c++":
cplus = 1
suffix = ".cpp"
else: else:
module_name = None module_name = None
...@@ -46,22 +54,21 @@ class build_ext (distutils.command.build_ext.build_ext): ...@@ -46,22 +54,21 @@ class build_ext (distutils.command.build_ext.build_ext):
pyx_sources = [source for source in sources if source.endswith('.pyx')] pyx_sources = [source for source in sources if source.endswith('.pyx')]
other_sources = [source for source in sources if not source.endswith('.pyx')] other_sources = [source for source in sources if not source.endswith('.pyx')]
#suffix = self.swig_cpp and '.cpp' or '.c'
suffix = '.c'
for pyx in pyx_sources: for pyx in pyx_sources:
# should I raise an exception if it doesn't exist? # should I raise an exception if it doesn't exist?
if os.path.exists(pyx): if os.path.exists(pyx):
source = pyx source = pyx
target = replace_suffix(source, suffix) target = replace_suffix(source, suffix)
if newer(source, target) or self.force: if newer(source, target) or self.force:
self.cython_compile(source, module_name) self.cython_compile(source, module_name, include_dirs, cplus)
return [replace_suffix(src, suffix) for src in pyx_sources] + other_sources return [replace_suffix(src, suffix) for src in pyx_sources] + other_sources
def cython_compile(self, source, module_name): def cython_compile(self, source, module_name, include_dirs, cplus):
options = CompilationOptions(default_options, options = CompilationOptions(
include_path = self.include_dirs) default_options,
include_path = include_dirs + self.include_dirs,
cplus=cplus)
result = compile(source, options, full_module_name=module_name) result = compile(source, options, full_module_name=module_name)
if result.num_errors <> 0: if result.num_errors <> 0:
sys.exit(1) sys.exit(1)
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