Commit ebbac140 authored by Robert Bradshaw's avatar Robert Bradshaw

merge changes for 0.9.6.7 release

parents 15833ae4 286b89f3
......@@ -89,6 +89,9 @@ class CCodeWriter:
self.input_file_contents[file] = 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):
file, line, col = pos
contents = self.file_contents(file)
......
......@@ -5,7 +5,7 @@
# to be rebuilt next time pyrexc is run.
#
string_prefixes = "cCrR"
string_prefixes = "cCrRuU"
def make_lexicon():
from Cython.Plex import \
......
......@@ -1074,12 +1074,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
Naming.stringtab_cname)
for entry in entries:
code.putln(
"{&%s, %s, sizeof(%s)}," % (
"{&%s, %s, sizeof(%s), %d}," % (
entry.pystring_cname,
entry.cname,
entry.cname))
entry.cname,
isinstance(entry.init, unicode)
))
code.putln(
"{0, 0, 0}")
"{0, 0, 0, 0}")
code.putln(
"};")
......
......@@ -888,12 +888,14 @@ class DefNode(FuncDefNode):
if self.entry.signature is TypeSlots.pyfunction_signature:
if len(self.args) == 0:
self.entry.signature = TypeSlots.pyfunction_noargs
elif len(self.args) == 1 and self.args[0].default is None:
elif len(self.args) == 1:
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:
if len(self.args) == 1:
self.entry.signature = TypeSlots.unaryfunc
elif len(self.args) == 2 and self.args[1].default is None:
elif len(self.args) == 2:
if self.args[1].default is None and not self.args[1].kw_only:
self.entry.signature = TypeSlots.ibinaryfunc
sig = self.entry.signature
nfixed = sig.num_fixed_args()
......@@ -2784,7 +2786,7 @@ utility_function_predeclarations = \
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; 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))
......@@ -3297,7 +3299,11 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
""","""
static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
while (t->p) {
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)
return -1;
++t;
......
......@@ -493,7 +493,7 @@ def p_opt_string_literal(s):
def p_string_literal(s):
# 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':
value = unquote(s.systring)
s.next()
......@@ -502,7 +502,7 @@ def p_string_literal(s):
pos = s.position()
#is_raw = s.systring[:1].lower() == "r"
kind = s.systring[:1].lower()
if kind not in "cr":
if kind not in "cru":
kind = ''
chars = []
while 1:
......@@ -513,6 +513,8 @@ def p_string_literal(s):
systr = s.systring
if len(systr) == 1 and systr in "'\"\n":
chars.append('\\')
if kind == 'u' and not isinstance(systr, unicode):
systr = systr.decode("UTF-8")
chars.append(systr)
elif sy == 'ESCAPE':
systr = s.systring
......@@ -533,6 +535,8 @@ def p_string_literal(s):
chars.append('\\x0' + systr[2:])
elif c == '\n':
pass
elif c == 'u':
chars.append(systr)
else:
chars.append(r'\\' + systr[1:])
elif sy == 'NEWLINE':
......@@ -546,7 +550,10 @@ def p_string_literal(s):
"Unexpected token %r:%r in string literal" %
(sy, s.systring))
s.next()
value = join(chars, '')
if kind == 'u':
value = u''.join(chars)
else:
value = ''.join(chars)
#print "p_string_literal: value =", repr(value) ###
return kind, value
......@@ -1762,21 +1769,16 @@ def p_def_statement(s):
star_arg = None
starstar_arg = None
if s.sy == '*':
s.next()
if s.sy == ',':
s.next()
if s.sy == 'IDENT':
args.extend(p_c_arg_list(s, in_pyfunc = 1, kw_only = 1))
else:
star_arg = p_py_arg_decl(s)
if s.sy == ',':
s.next()
if s.sy == 'IDENT':
args.extend(p_c_arg_list(s, in_pyfunc = 1, kw_only = 1))
if s.sy == '**':
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 == '**':
s.next()
starstar_arg = p_py_arg_decl(s)
......
......@@ -717,6 +717,8 @@ class CStringType:
exception_value = "NULL"
def literal_code(self, value):
if isinstance(value, unicode):
value = value.encode("UTF-8")
return '"%s"' % value
......
......@@ -515,12 +515,14 @@ class BuiltinScope(Scope):
# TODO: perhapse these should all be declared in some universal .pxi file?
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],
"repr": ["PyObject_Repr", 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],
"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],
"type": ["PyObject_Type", py_object_type, (py_object_type, ), 0],
"len": ["PyObject_Size", c_py_ssize_t_type, (py_object_type, ), -1],
......
......@@ -105,20 +105,21 @@ class SlotDescriptor:
# slot_name string Member name of the slot in the type object
# 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.is_initialised_dynamically = dynamic
self.min_version = min_version
self.min_python_version = min_python_version
def generate(self, scope, code):
if self.is_initialised_dynamically:
value = 0
else:
value = self.slot_code(scope)
if self.min_version:
code.putln("#if PY_VERSION_HEX >= 0x%X" % Naming.py_version_hex(*self.min_version))
if self.min_python_version is not None:
code.putln("#if PY_VERSION_HEX >= " +
code.get_py_version_hex(self.min_python_version))
code.putln("%s, /*%s*/" % (value, self.slot_name))
if self.min_version:
if self.min_python_version is not None:
code.putln("#endif")
# Some C implementations have trouble statically
......@@ -181,8 +182,10 @@ 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, min_version=None, default = None):
SlotDescriptor.__init__(self, slot_name, min_version)
def __init__(self, signature, slot_name, method_name,
default = None, min_python_version = None):
SlotDescriptor.__init__(self, slot_name,
min_python_version = min_python_version)
self.signature = signature
self.slot_name = slot_name
self.method_name = method_name
......@@ -499,7 +502,7 @@ PyNumberMethods = (
MethodSlot(ibinaryfunc, "nb_inplace_true_divide", "__itruediv__"),
# 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 = (
......
......@@ -37,8 +37,16 @@ class build_ext (distutils.command.build_ext.build_ext):
if not self.extensions:
return
#suffix = self.swig_cpp and '.cpp' or '.c'
suffix = '.c'
cplus = 0
include_dirs = []
if extension is not None:
module_name = extension.name
include_dirs = extension.include_dirs or []
if extension.language == "c++":
cplus = 1
suffix = ".cpp"
else:
module_name = None
......@@ -46,22 +54,21 @@ class build_ext (distutils.command.build_ext.build_ext):
pyx_sources = [source for source in sources if 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:
# should I raise an exception if it doesn't exist?
if os.path.exists(pyx):
source = pyx
target = replace_suffix(source, suffix)
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
def cython_compile(self, source, module_name):
options = CompilationOptions(default_options,
include_path = self.include_dirs)
def cython_compile(self, source, module_name, include_dirs, cplus):
options = CompilationOptions(
default_options,
include_path = include_dirs + self.include_dirs,
cplus=cplus)
result = compile(source, options, full_module_name=module_name)
if result.num_errors <> 0:
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