Commit cb49864e authored by Robert Bradshaw's avatar Robert Bradshaw

merge

parents 310140c7 3db40527
...@@ -2,3 +2,4 @@ ...@@ -2,3 +2,4 @@
67ee5a34bfc662e4e3cf989c2c8bf78a412ae8f4 0.9.8rc1 67ee5a34bfc662e4e3cf989c2c8bf78a412ae8f4 0.9.8rc1
16a746d969e2654112fc0dc081690b891c496977 Version-0.9.8 16a746d969e2654112fc0dc081690b891c496977 Version-0.9.8
a09347d7b470290076b983aef98707921445a038 0.9.8.1 a09347d7b470290076b983aef98707921445a038 0.9.8.1
82084a7b654e2a133ab64ceb47e03d6e7a204990 0.9.9.2.beta
...@@ -39,9 +39,8 @@ class AnnotationCCodeWriter(CCodeWriter): ...@@ -39,9 +39,8 @@ class AnnotationCCodeWriter(CCodeWriter):
self.annotation_buffer.write(s) self.annotation_buffer.write(s)
def mark_pos(self, pos): def mark_pos(self, pos):
# if pos is not None: if pos is not None:
# CCodeWriter.mark_pos(self, pos) CCodeWriter.mark_pos(self, pos)
# return
if self.last_pos: if self.last_pos:
code = self.code.get(self.last_pos[1], "") code = self.code.get(self.last_pos[1], "")
self.code[self.last_pos[1]] = code + self.annotation_buffer.getvalue() self.code[self.last_pos[1]] = code + self.annotation_buffer.getvalue()
......
...@@ -1915,10 +1915,10 @@ class DefNode(FuncDefNode): ...@@ -1915,10 +1915,10 @@ class DefNode(FuncDefNode):
# --- optimised code when we receive keyword arguments # --- optimised code when we receive keyword arguments
if self.num_required_kw_args: if self.num_required_kw_args:
code.putln("if (likely(%s)) {" % Naming.kwds_cname) likely_hint = "likely"
else: else:
code.putln("if (unlikely(%s) && (PyDict_Size(%s) > 0)) {" % ( likely_hint = "unlikely"
Naming.kwds_cname, Naming.kwds_cname)) code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
self.generate_keyword_unpacking_code( self.generate_keyword_unpacking_code(
min_positional_args, max_positional_args, min_positional_args, max_positional_args,
has_fixed_positional_count, has_fixed_positional_count,
...@@ -1946,9 +1946,9 @@ class DefNode(FuncDefNode): ...@@ -1946,9 +1946,9 @@ class DefNode(FuncDefNode):
for i, arg in enumerate(kw_only_args): for i, arg in enumerate(kw_only_args):
if not arg.default: if not arg.default:
# required keyword-only argument missing # required keyword-only argument missing
code.put('__Pyx_RaiseKeywordRequired("%s", *%s[%d]); ' % ( code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
self.name.utf8encode(), Naming.pykwdlist_cname, self.name.utf8encode(),
len(positional_args) + i)) arg.name_entry.pystring_cname))
code.putln(code.error_goto(self.pos)) code.putln(code.error_goto(self.pos))
break break
...@@ -2054,16 +2054,24 @@ class DefNode(FuncDefNode): ...@@ -2054,16 +2054,24 @@ class DefNode(FuncDefNode):
code.put_goto(argtuple_error_label) code.put_goto(argtuple_error_label)
code.putln('}') code.putln('}')
# now fill up the arguments with values from the kw dict # now fill up the required arguments with values from the kw dict
code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname) last_required_arg = -1
for i, arg in enumerate(all_args): for i, arg in enumerate(all_args):
if not arg.default:
last_required_arg = i
if last_required_arg >= 0:
code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
for i, arg in enumerate(all_args[:last_required_arg+1]):
if i <= max_positional_args: if i <= max_positional_args:
if self.star_arg and i == max_positional_args: if self.star_arg and i == max_positional_args:
code.putln('default:') code.putln('default:')
else: else:
code.putln('case %2d:' % i) code.putln('case %2d:' % i)
code.putln('values[%d] = PyDict_GetItem(%s, *%s[%d]);' % ( if arg.default:
i, Naming.kwds_cname, Naming.pykwdlist_cname, i)) # handled in ParseOptionalKeywords() below
continue
code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
i, Naming.kwds_cname, arg.name_entry.pystring_cname))
if i < min_positional_args: if i < min_positional_args:
code.putln('if (likely(values[%d])) kw_args--;' % i); code.putln('if (likely(values[%d])) kw_args--;' % i);
if i == 0: if i == 0:
...@@ -2071,7 +2079,7 @@ class DefNode(FuncDefNode): ...@@ -2071,7 +2079,7 @@ class DefNode(FuncDefNode):
code.put('else ') code.put('else ')
code.put_goto(argtuple_error_label) code.put_goto(argtuple_error_label)
else: else:
# provide the correct number of values (args or # print the correct number of values (args or
# kwargs) that were passed into positional # kwargs) that were passed into positional
# arguments up to this point # arguments up to this point
code.putln('else {') code.putln('else {')
...@@ -2084,14 +2092,14 @@ class DefNode(FuncDefNode): ...@@ -2084,14 +2092,14 @@ class DefNode(FuncDefNode):
code.putln('if (values[%d]) kw_args--;' % i); code.putln('if (values[%d]) kw_args--;' % i);
if arg.kw_only and not arg.default: if arg.kw_only and not arg.default:
code.putln('else {') code.putln('else {')
code.put('__Pyx_RaiseKeywordRequired("%s", *%s[%d]); ' %( code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
self.name.utf8encode(), Naming.pykwdlist_cname, i)) self.name.utf8encode(), arg.name_entry.pystring_cname))
code.putln(code.error_goto(self.pos)) code.putln(code.error_goto(self.pos))
code.putln('}') code.putln('}')
code.putln('}') code.putln('}')
code.putln('if (unlikely(kw_args > 0)) {') code.putln('if (unlikely(kw_args > 0)) {')
# non-positional kw args left in the dict: **kwargs or error # non-positional kw args left in dict: default args, **kwargs or error
if self.star_arg: if self.star_arg:
code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % ( code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
Naming.args_cname, max_positional_args, Naming.args_cname, max_positional_args,
...@@ -2099,9 +2107,9 @@ class DefNode(FuncDefNode): ...@@ -2099,9 +2107,9 @@ class DefNode(FuncDefNode):
pos_arg_count = "used_pos_args" pos_arg_count = "used_pos_args"
else: else:
pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
code.globalstate.use_utility_code(split_keywords_utility_code) code.globalstate.use_utility_code(parse_keywords_utility_code)
code.put( code.put(
'if (unlikely(__Pyx_SplitKeywords(%s, %s, %s, %s, "%s") < 0)) ' % ( 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
Naming.kwds_cname, Naming.kwds_cname,
Naming.pykwdlist_cname, Naming.pykwdlist_cname,
self.starstar_arg and self.starstar_arg.entry.cname or '0', self.starstar_arg and self.starstar_arg.entry.cname or '0',
...@@ -4815,9 +4823,9 @@ invalid_keyword: ...@@ -4815,9 +4823,9 @@ invalid_keyword:
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
# #
# __Pyx_SplitKeywords copies the keyword arguments that are not named # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
# in argnames[] from the kwds dict into kwds2. If kwds2 is NULL, # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
# these keywords will raise an invalid keyword error. # keywords will raise an invalid keyword error.
# #
# Three kinds of errors are checked: 1) non-string keywords, 2) # Three kinds of errors are checked: 1) non-string keywords, 2)
# unexpected keywords and 3) overlap with positional arguments. # unexpected keywords and 3) overlap with positional arguments.
...@@ -4829,22 +4837,25 @@ invalid_keyword: ...@@ -4829,22 +4837,25 @@ invalid_keyword:
# This method does not check for required keyword arguments. # This method does not check for required keyword arguments.
# #
split_keywords_utility_code = UtilityCode( parse_keywords_utility_code = UtilityCode(
proto = """ proto = """
static int __Pyx_SplitKeywords(PyObject *kwds, PyObject **argnames[], \ static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
PyObject *kwds2, Py_ssize_t num_pos_args, const char* function_name); /*proto*/ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
const char* function_name); /*proto*/
""", """,
impl = """ impl = """
static int __Pyx_SplitKeywords( static int __Pyx_ParseOptionalKeywords(
PyObject *kwds, PyObject *kwds,
PyObject **argnames[], PyObject **argnames[],
PyObject *kwds2, PyObject *kwds2,
PyObject *values[],
Py_ssize_t num_pos_args, Py_ssize_t num_pos_args,
const char* function_name) const char* function_name)
{ {
PyObject *key = 0, *value = 0; PyObject *key = 0, *value = 0;
Py_ssize_t pos = 0; Py_ssize_t pos = 0;
PyObject*** name; PyObject*** name;
PyObject*** first_kw_arg = argnames + num_pos_args;
while (PyDict_Next(kwds, &pos, &key, &value)) { while (PyDict_Next(kwds, &pos, &key, &value)) {
#if PY_MAJOR_VERSION < 3 #if PY_MAJOR_VERSION < 3
...@@ -4856,8 +4867,11 @@ static int __Pyx_SplitKeywords( ...@@ -4856,8 +4867,11 @@ static int __Pyx_SplitKeywords(
} else { } else {
name = argnames; name = argnames;
while (*name && (**name != key)) name++; while (*name && (**name != key)) name++;
if (!*name) { if (*name) {
for (name = argnames; *name; name++) { if (name < first_kw_arg) goto arg_passed_twice;
values[name-argnames] = value;
} else {
for (name = first_kw_arg; *name; name++) {
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) && if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
PyUnicode_Compare(**name, key) == 0) break; PyUnicode_Compare(**name, key) == 0) break;
...@@ -4867,7 +4881,21 @@ static int __Pyx_SplitKeywords( ...@@ -4867,7 +4881,21 @@ static int __Pyx_SplitKeywords(
PyString_AS_STRING(key)) == 0) break; PyString_AS_STRING(key)) == 0) break;
#endif #endif
} }
if (!*name) { if (*name) {
values[name-argnames] = value;
} else {
/* unexpected keyword found */
for (name=argnames; name != first_kw_arg; name++) {
if (**name == key) goto arg_passed_twice;
#if PY_MAJOR_VERSION >= 3
if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
#else
if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
strcmp(PyString_AS_STRING(**name),
PyString_AS_STRING(key)) == 0) goto arg_passed_twice;
#endif
}
if (kwds2) { if (kwds2) {
if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
} else { } else {
...@@ -4875,8 +4903,6 @@ static int __Pyx_SplitKeywords( ...@@ -4875,8 +4903,6 @@ static int __Pyx_SplitKeywords(
} }
} }
} }
if (*name && ((name-argnames) < num_pos_args))
goto arg_passed_twice;
} }
} }
return 0; return 0;
......
version = '0.9.8.1.1' version = '0.9.8.2.beta'
ctypedef struct struct_type_not_boolean:
int i
float f
if struct_type_not_boolean:
print("INVALID CODE")
cdef struct struct_not_boolean:
int i
float f
if struct_not_boolean:
print("INVALID CODE")
ctypedef union union_type_not_boolean:
int i
float f
if union_type_not_boolean:
print("INVALID CODE")
cdef union union_not_boolean:
int i
float f
if union_not_boolean:
print("INVALID CODE")
_ERRORS = u"""
5:26: 'struct_type_not_boolean' is not a constant, variable or function identifier
5:26: Type 'struct_type_not_boolean' not acceptable as a boolean
12:21: 'struct_not_boolean' is not a constant, variable or function identifier
12:21: Type 'struct_not_boolean' not acceptable as a boolean
19:25: 'union_type_not_boolean' is not a constant, variable or function identifier
19:25: Type 'union_type_not_boolean' not acceptable as a boolean
26:20: 'union_not_boolean' is not a constant, variable or function identifier
26:20: Type 'union_not_boolean' not acceptable as a boolean
"""
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