Cython Changelog
================
+0.28.6 (2018-11-01)
+===================
+
+Bugs fixed
+----------
+
+* Extensions compiled with MinGW-64 under Windows could misinterpret integer
+ objects larger than 15 bit and return incorrect results.
+ (Github issue #2670)
+
+* Multiplied string literals lost their factor when they are part of another
+ constant expression (e.g. 'x' * 10 + 'y' => 'xy').
+
+
0.28.5 (2018-08-03)
===================
h_code.put_generated_by()
api_guard = Naming.api_guard_prefix + self.api_name(env)
h_code.put_h_guard(api_guard)
+ # Work around https://bugs.python.org/issue4709
+ h_code.putln('#ifdef __MINGW64__')
+ h_code.putln('#define MS_WIN64')
+ h_code.putln('#endif')
+
h_code.putln('#include "Python.h"')
if result.h_file:
h_code.putln('#include "%s"' % os.path.basename(result.h_file))
string_node.bytes_value.encoding)
else:
assert False, "unknown string node type: %s" % type(string_node)
- string_node.value = build_string(
+ string_node.constant_result = string_node.value = build_string(
string_node.value * multiplier,
string_node.value.encoding)
return string_node
import operator
path_tokenizer = re.compile(
- "("
- "'[^']*'|\"[^\"]*\"|"
- "//?|"
- "\(\)|"
- "==?|"
- "[/.*\[\]\(\)@])|"
- "([^/\[\]\(\)@=\s]+)|"
- "\s+"
+ r"("
+ r"'[^']*'|\"[^\"]*\"|"
+ r"//?|"
+ r"\(\)|"
+ r"==?|"
+ r"[/.*\[\]()@])|"
+ r"([^/\[\]()@=\s]+)|"
+ r"\s+"
).findall
def iterchildren(node, attr_name):
# cython.* namespace for pure mode.
from __future__ import absolute_import
-__version__ = "0.28.5"
+__version__ = "0.28.6"
try:
from __builtin__ import basestring
#undef SHIFT
#undef BASE
#undef MASK
+ /* Compile-time sanity check that these are indeed equal. Github issue #2670. */
+ #ifdef SIZEOF_VOID_P
+ enum { __pyx_check_sizeof_voidp = 1/(SIZEOF_VOID_P == sizeof(void*)) };
+ #endif
#endif
#ifndef __has_attribute
PYTHON_VERSION: "2.7"
PYTHON_ARCH: "64"
+ - PYTHON: "C:\\Python37"
+ PYTHON_VERSION: "3.7"
+ PYTHON_ARCH: "32"
+
+ - PYTHON: "C:\\Python37-x64"
+ PYTHON_VERSION: "3.7"
+ PYTHON_ARCH: "64"
+
- PYTHON: "C:\\Python36"
PYTHON_VERSION: "3.6"
PYTHON_ARCH: "32"
class ErrorWriter(object):
- match_error = re.compile('(warning:)?(?:.*:)?\s*([-0-9]+)\s*:\s*([-0-9]+)\s*:\s*(.*)').match
+ match_error = re.compile(r'(warning:)?(?:.*:)?\s*([-0-9]+)\s*:\s*([-0-9]+)\s*:\s*(.*)').match
def __init__(self):
self.output = []
yield i
return generator
-def with_outer_raising(*args):
- """
- >>> x = with_outer_raising(1, 2, 3)
- >>> list(x())
- [1, 2, 3]
- """
- def generator():
- for i in args:
- yield i
- raise StopIteration
- return generator
def test_close():
"""
--- /dev/null
+# mode: run
+# tag: generators, pure3.5
+
+from __future__ import generator_stop
+
+# "generator_stop" was only added in Py3.5.
+
+
+def with_outer_raising(*args):
+ """
+ >>> x = with_outer_raising(1, 2, 3)
+ >>> try:
+ ... list(x())
+ ... except RuntimeError:
+ ... print("OK!")
+ ... else:
+ ... print("NOT RAISED!")
+ OK!
+ """
+ def generator():
+ for i in args:
+ yield i
+ raise StopIteration
+ return generator
@cython.ccall
@cython.returns(cython.double)
def c_call(x):
+ return x
+
+
+def call_ccall(x):
"""
Test that a declared return type is honoured when compiled.
>>> (is_compiled and 1) or result
1
"""
- return x
-
-
-def call_ccall(x):
ret = c_call(x)
return ret, cython.typeof(ret)
@cython.inline
@cython.returns(cython.double)
def cdef_inline(x):
+ return x + 1
+
+
+def call_cdef_inline(x):
"""
>>> result, return_type = call_cdef_inline(1)
- >>> (not is_compiled and 'float') or type(return_type).__name__
+ >>> (not is_compiled and 'float') or type(result).__name__
'float'
>>> (not is_compiled and 'double') or return_type
'double'
>>> result == 2.0 or result
True
"""
- return x + 1
-
-
-def call_cdef_inline(x):
ret = cdef_inline(x)
return ret, cython.typeof(ret)
@cython.returns(cython.long)
@cython.exceptval(-1)
def cdef_except(x):
+ if x == 0:
+ raise ValueError
+ return x+1
+
+
+def call_cdef_except(x):
"""
>>> call_cdef_except(41)
42
Traceback (most recent call last):
ValueError
"""
- if x == 0:
- raise ValueError
- return x+1
-
-
-def call_cdef_except(x):
return cdef_except(x)
@cython.ccall
def c_call(x) -> cython.double:
+ return x
+
+
+def call_ccall(x):
"""
Test that a declared return type is honoured when compiled.
>>> (is_compiled and 1) or result
1
"""
- return x
-
-
-def call_ccall(x):
ret = c_call(x)
return ret, cython.typeof(ret)
@cython.cfunc
@cython.inline
def cdef_inline(x) -> cython.double:
+ return x + 1
+
+
+def call_cdef_inline(x):
"""
>>> result, return_type = call_cdef_inline(1)
- >>> (not is_compiled and 'float') or type(return_type).__name__
+ >>> (not is_compiled and 'float') or type(result).__name__
'float'
>>> (not is_compiled and 'double') or return_type
'double'
>>> result == 2.0 or result
True
"""
- return x + 1
-
-
-def call_cdef_inline(x):
ret = cdef_inline(x)
return ret, cython.typeof(ret)
True
>>> wide_literal == u'\\U00101234' # unescaped by Python
True
+ >>> ustring_in_constant_tuple == ('a', u'abc', u'\\N{SNOWMAN}', u'x' * 3, u'\\N{SNOWMAN}' * 4 + u'O') or ustring_in_constant_tuple # unescaped by Python
+ True
"""
if sys.version_info >= (2,6,5):
null = u'\x00'
wide_literal = u'\U00101234'
+
+ustring_in_constant_tuple = ('a', u'abc', u'\N{SNOWMAN}', u'x' * 3, u'\N{SNOWMAN}' * 4 + u'O')