Commit c0643507 authored by Vitja Makarov's avatar Vitja Makarov

Merge remote branch 'upstream/master'

Conflicts:
	Cython/Compiler/ExprNodes.py
	Cython/Compiler/Nodes.py
	Cython/Compiler/ParseTreeTransforms.py
	Cython/Compiler/Symtab.py
parents 748f27fe 84079e51
...@@ -38,3 +38,4 @@ ef9d2c680684d0df7d81f529cda29e9e1741f575 cython-0.10.1 ...@@ -38,3 +38,4 @@ ef9d2c680684d0df7d81f529cda29e9e1741f575 cython-0.10.1
7fa84cb6d3d75eb3d015aeeb60bf8b642171fe93 0.14.beta2 7fa84cb6d3d75eb3d015aeeb60bf8b642171fe93 0.14.beta2
8412b39fbc3eb709a543e2f1e95c0c8881ea9ed4 0.14.beta2 8412b39fbc3eb709a543e2f1e95c0c8881ea9ed4 0.14.beta2
a6b9f0a6d02d23fc3d3a9d0587867faa3afb2fcd 0.14.rc0 a6b9f0a6d02d23fc3d3a9d0587867faa3afb2fcd 0.14.rc0
15bf34c9387444e262acb1de594405444dd571a4 0.14
...@@ -220,7 +220,11 @@ def parse_dependencies(source_filename): ...@@ -220,7 +220,11 @@ def parse_dependencies(source_filename):
# Actual parsing is way to slow, so we use regular expressions. # Actual parsing is way to slow, so we use regular expressions.
# The only catch is that we must strip comments and string # The only catch is that we must strip comments and string
# literals ahead of time. # literals ahead of time.
source = Utils.open_source_file(source_filename, "rU").read() fh = Utils.open_source_file(source_filename, "rU")
try:
source = fh.read()
finally:
fh.close()
distutils_info = DistutilsInfo(source) distutils_info = DistutilsInfo(source)
source, literals = strip_string_literals(source) source, literals = strip_string_literals(source)
source = source.replace('\\\n', ' ') source = source.replace('\\\n', ' ')
......
...@@ -52,9 +52,12 @@ def unbound_symbols(code, context=None): ...@@ -52,9 +52,12 @@ def unbound_symbols(code, context=None):
symbol_collector = AllSymbols() symbol_collector = AllSymbols()
symbol_collector(tree) symbol_collector(tree)
unbound = [] unbound = []
import __builtin__ try:
import builtins
except ImportError:
import __builtin__ as builtins
for name in symbol_collector.names: for name in symbol_collector.names:
if not tree.scope.lookup(name) and not hasattr(__builtin__, name): if not tree.scope.lookup(name) and not hasattr(builtins, name):
unbound.append(name) unbound.append(name)
return unbound return unbound
...@@ -79,7 +82,7 @@ def safe_type(arg, context=None): ...@@ -79,7 +82,7 @@ def safe_type(arg, context=None):
return 'numpy.ndarray[numpy.%s_t, ndim=%s]' % (arg.dtype.name, arg.ndim) return 'numpy.ndarray[numpy.%s_t, ndim=%s]' % (arg.dtype.name, arg.ndim)
else: else:
for base_type in py_type.mro(): for base_type in py_type.mro():
if base_type.__module__ == '__builtin__': if base_type.__module__ in ('__builtin__', 'builtins'):
return 'object' return 'object'
module = context.find_module(base_type.__module__, need_pxd=False) module = context.find_module(base_type.__module__, need_pxd=False)
if module: if module:
...@@ -125,7 +128,7 @@ def cython_inline(code, ...@@ -125,7 +128,7 @@ def cython_inline(code,
arg_names.sort() arg_names.sort()
arg_sigs = tuple([(get_type(kwds[arg], ctx), arg) for arg in arg_names]) arg_sigs = tuple([(get_type(kwds[arg], ctx), arg) for arg in arg_names])
key = code, arg_sigs, sys.version_info, sys.executable, Cython.__version__ key = code, arg_sigs, sys.version_info, sys.executable, Cython.__version__
module_name = "_cython_inline_" + hashlib.md5(str(key)).hexdigest() module_name = "_cython_inline_" + hashlib.md5(str(key).encode('utf-8')).hexdigest()
try: try:
if not os.path.exists(lib_dir): if not os.path.exists(lib_dir):
os.makedirs(lib_dir) os.makedirs(lib_dir)
...@@ -160,7 +163,11 @@ def __invoke(%(params)s): ...@@ -160,7 +163,11 @@ def __invoke(%(params)s):
for key, value in literals.items(): for key, value in literals.items():
module_code = module_code.replace(key, value) module_code = module_code.replace(key, value)
pyx_file = os.path.join(lib_dir, module_name + '.pyx') pyx_file = os.path.join(lib_dir, module_name + '.pyx')
open(pyx_file, 'w').write(module_code) fh = open(pyx_file, 'w')
try:
fh.write(module_code)
finally:
fh.close()
extension = Extension( extension = Extension(
name = module_name, name = module_name,
sources = [pyx_file], sources = [pyx_file],
......
...@@ -125,6 +125,8 @@ def parse_command_line(args): ...@@ -125,6 +125,8 @@ def parse_command_line(args):
options.language_level = 3 options.language_level = 3
elif option == "--fast-fail": elif option == "--fast-fail":
Options.fast_fail = True Options.fast_fail = True
elif option == "--disable-function-redefinition":
Options.disable_function_redefinition = True
elif option in ("-X", "--directive"): elif option in ("-X", "--directive"):
try: try:
options.compiler_directives = Options.parse_directive_list( options.compiler_directives = Options.parse_directive_list(
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
import cython import cython
cython.declare(re=object, Naming=object, Options=object, StringEncoding=object, cython.declare(re=object, Naming=object, Options=object, StringEncoding=object,
Utils=object, SourceDescriptor=object, StringIOTree=object, Utils=object, SourceDescriptor=object, StringIOTree=object,
DebugFlags=object, none_or_sub=object) DebugFlags=object, none_or_sub=object, basestring=object)
import re import re
import Naming import Naming
...@@ -19,9 +19,9 @@ import DebugFlags ...@@ -19,9 +19,9 @@ import DebugFlags
from Cython.Utils import none_or_sub from Cython.Utils import none_or_sub
try: try:
basestring from __builtin__ import basestring
except NameError: except ImportError:
basestring = str from builtins import str as basestring
class UtilityCode(object): class UtilityCode(object):
# Stores utility code to add during code generation. # Stores utility code to add during code generation.
......
...@@ -3408,7 +3408,7 @@ class AttributeNode(ExprNode): ...@@ -3408,7 +3408,7 @@ class AttributeNode(ExprNode):
return module_scope.lookup_type(self.attribute) return module_scope.lookup_type(self.attribute)
if not isinstance(self.obj, (UnicodeNode, StringNode, BytesNode)): if not isinstance(self.obj, (UnicodeNode, StringNode, BytesNode)):
base_type = self.obj.analyse_as_type(env) base_type = self.obj.analyse_as_type(env)
if base_type and hasattr(base_type, 'scope'): if base_type and hasattr(base_type, 'scope') and base_type.scope is not None:
return base_type.scope.lookup_type(self.attribute) return base_type.scope.lookup_type(self.attribute)
return None return None
...@@ -8255,17 +8255,17 @@ typedef struct { ...@@ -8255,17 +8255,17 @@ typedef struct {
PyCFunctionObject func; PyCFunctionObject func;
} %(binding_cfunc)s_object; } %(binding_cfunc)s_object;
PyTypeObject %(binding_cfunc)s_type; static PyTypeObject %(binding_cfunc)s_type;
PyTypeObject *%(binding_cfunc)s = NULL; static PyTypeObject *%(binding_cfunc)s = NULL;
PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module); /* proto */ static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module); /* proto */
#define %(binding_cfunc)s_New(ml, self) %(binding_cfunc)s_NewEx(ml, self, NULL) #define %(binding_cfunc)s_New(ml, self) %(binding_cfunc)s_NewEx(ml, self, NULL)
int %(binding_cfunc)s_init(void); /* proto */ static int %(binding_cfunc)s_init(void); /* proto */
""" % Naming.__dict__, """ % Naming.__dict__,
impl=""" impl="""
PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) { static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
%(binding_cfunc)s_object *op = PyObject_GC_New(%(binding_cfunc)s_object, %(binding_cfunc)s); %(binding_cfunc)s_object *op = PyObject_GC_New(%(binding_cfunc)s_object, %(binding_cfunc)s);
if (op == NULL) if (op == NULL)
return NULL; return NULL;
...@@ -8291,7 +8291,7 @@ static PyObject *%(binding_cfunc)s_descr_get(PyObject *func, PyObject *obj, PyOb ...@@ -8291,7 +8291,7 @@ static PyObject *%(binding_cfunc)s_descr_get(PyObject *func, PyObject *obj, PyOb
return PyMethod_New(func, obj, type); return PyMethod_New(func, obj, type);
} }
int %(binding_cfunc)s_init(void) { static int %(binding_cfunc)s_init(void) {
%(binding_cfunc)s_type = PyCFunction_Type; %(binding_cfunc)s_type = PyCFunction_Type;
%(binding_cfunc)s_type.tp_name = __Pyx_NAMESTR("cython_binding_builtin_function_or_method"); %(binding_cfunc)s_type.tp_name = __Pyx_NAMESTR("cython_binding_builtin_function_or_method");
%(binding_cfunc)s_type.tp_dealloc = (destructor)%(binding_cfunc)s_dealloc; %(binding_cfunc)s_type.tp_dealloc = (destructor)%(binding_cfunc)s_dealloc;
......
...@@ -70,7 +70,6 @@ class Context(object): ...@@ -70,7 +70,6 @@ class Context(object):
# language_level int currently 2 or 3 for Python 2/3 # language_level int currently 2 or 3 for Python 2/3
def __init__(self, include_directories, compiler_directives, cpp=False, language_level=2): def __init__(self, include_directories, compiler_directives, cpp=False, language_level=2):
#self.modules = {"__builtin__" : BuiltinScope()}
import Builtin, CythonScope import Builtin, CythonScope
self.modules = {"__builtin__" : Builtin.builtin_scope} self.modules = {"__builtin__" : Builtin.builtin_scope}
self.modules["cython"] = CythonScope.create_cython_scope(self) self.modules["cython"] = CythonScope.create_cython_scope(self)
...@@ -95,6 +94,7 @@ class Context(object): ...@@ -95,6 +94,7 @@ class Context(object):
from Future import print_function, unicode_literals from Future import print_function, unicode_literals
self.future_directives.add(print_function) self.future_directives.add(print_function)
self.future_directives.add(unicode_literals) self.future_directives.add(unicode_literals)
self.modules['builtins'] = self.modules['__builtin__']
def create_pipeline(self, pxd, py=False): def create_pipeline(self, pxd, py=False):
from Visitor import PrintTree from Visitor import PrintTree
......
...@@ -264,7 +264,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -264,7 +264,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code = globalstate['before_global_var'] code = globalstate['before_global_var']
code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name) code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name)
code.putln("int %s%s = 0;" % (Naming.module_is_main, self.full_module_name.replace('.', '__'))) code.putln("static int %s%s = 0;" % (Naming.module_is_main, self.full_module_name.replace('.', '__')))
code.putln("") code.putln("")
code.putln("/* Implementation of %s */" % env.qualified_name) code.putln("/* Implementation of %s */" % env.qualified_name)
...@@ -569,12 +569,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -569,12 +569,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
#define PyBytes_Repr PyString_Repr #define PyBytes_Repr PyString_Repr
#define PyBytes_Concat PyString_Concat #define PyBytes_Concat PyString_Concat
#define PyBytes_ConcatAndDel PyString_ConcatAndDel #define PyBytes_ConcatAndDel PyString_ConcatAndDel
#endif
#if PY_VERSION_HEX < 0x02060000
#define PySet_Check(obj) PyObject_TypeCheck(obj, &PySet_Type) #define PySet_Check(obj) PyObject_TypeCheck(obj, &PySet_Type)
#define PyFrozenSet_Check(obj) PyObject_TypeCheck(obj, &PyFrozenSet_Type) #define PyFrozenSet_Check(obj) PyObject_TypeCheck(obj, &PyFrozenSet_Type)
#endif #endif
#ifndef PySet_CheckExact #ifndef PySet_CheckExact
# define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
#endif #endif
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
...@@ -858,7 +860,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -858,7 +860,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
Naming.extern_c_macro, Naming.extern_c_macro,
name)) name))
elif entry.visibility == 'public': elif entry.visibility == 'public':
#code.putln("DL_EXPORT(PyTypeObject) %s;" % name)
code.putln("%s DL_EXPORT(PyTypeObject) %s;" % ( code.putln("%s DL_EXPORT(PyTypeObject) %s;" % (
Naming.extern_c_macro, Naming.extern_c_macro,
name)) name))
...@@ -1591,8 +1592,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -1591,8 +1592,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if entry.visibility == 'public': if entry.visibility == 'public':
header = "DL_EXPORT(PyTypeObject) %s = {" header = "DL_EXPORT(PyTypeObject) %s = {"
else: else:
#header = "statichere PyTypeObject %s = {" header = "static PyTypeObject %s = {"
header = "PyTypeObject %s = {"
#code.putln(header % scope.parent_type.typeobj_cname) #code.putln(header % scope.parent_type.typeobj_cname)
code.putln(header % type.typeobj_cname) code.putln(header % type.typeobj_cname)
code.putln( code.putln(
......
...@@ -1110,8 +1110,9 @@ class EarlyReplaceBuiltinCalls(Visitor.EnvTransform): ...@@ -1110,8 +1110,9 @@ class EarlyReplaceBuiltinCalls(Visitor.EnvTransform):
def _function_is_builtin_name(self, function): def _function_is_builtin_name(self, function):
if not function.is_name: if not function.is_name:
return False return False
entry = self.current_env().lookup(function.name) env = self.current_env()
if entry and getattr(entry, 'scope', None) is not Builtin.builtin_scope: entry = env.lookup(function.name)
if entry is not env.builtin_scope().lookup_here(function.name):
return False return False
# if entry is None, it's at least an undeclared name, so likely builtin # if entry is None, it's at least an undeclared name, so likely builtin
return True return True
...@@ -1724,8 +1725,8 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform): ...@@ -1724,8 +1725,8 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
# into a C function call (defined in the builtin scope) # into a C function call (defined in the builtin scope)
if not function.entry: if not function.entry:
return node return node
is_builtin = function.entry.is_builtin \ is_builtin = function.entry.is_builtin or \
or getattr(function.entry, 'scope', None) is Builtin.builtin_scope function.entry is self.current_env().builtin_scope().lookup_here(function.name)
if not is_builtin: if not is_builtin:
return node return node
function_handler = self._find_handler( function_handler = self._find_handler(
......
...@@ -51,6 +51,10 @@ c_line_in_traceback = 1 ...@@ -51,6 +51,10 @@ c_line_in_traceback = 1
# executes the body of this module. # executes the body of this module.
embed = False embed = False
# Disables function redefinition, allowing all functions to be declared at
# module creation time. For legacy code only.
disable_function_redefinition = False
# Declare compiler directives # Declare compiler directives
directive_defaults = { directive_defaults = {
......
...@@ -1371,10 +1371,10 @@ impl=""" ...@@ -1371,10 +1371,10 @@ impl="""
} }
#if %(is_float)s #if %(is_float)s
static CYTHON_INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s z) { static CYTHON_INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s z) {
#if HAVE_HYPOT #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
return hypot%(m)s(z.real, z.imag);
#else
return sqrt%(m)s(z.real*z.real + z.imag*z.imag); return sqrt%(m)s(z.real*z.real + z.imag*z.imag);
#else
return hypot%(m)s(z.real, z.imag);
#endif #endif
} }
static CYTHON_INLINE %(type)s __Pyx_c_pow%(m)s(%(type)s a, %(type)s b) { static CYTHON_INLINE %(type)s __Pyx_c_pow%(m)s(%(type)s a, %(type)s b) {
......
...@@ -526,7 +526,7 @@ class Scope(object): ...@@ -526,7 +526,7 @@ class Scope(object):
def declare_pyfunction(self, name, pos, allow_redefine=False, visibility='extern'): def declare_pyfunction(self, name, pos, allow_redefine=False, visibility='extern'):
# Add an entry for a Python function. # Add an entry for a Python function.
entry = self.lookup_here(name) entry = self.lookup_here(name)
if not allow_redefine: if not allow_redefine or Options.disable_function_redefinition:
return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry) return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry)
if entry: if entry:
if entry.type.is_unspecified: if entry.type.is_unspecified:
...@@ -733,6 +733,13 @@ class BuiltinScope(Scope): ...@@ -733,6 +733,13 @@ class BuiltinScope(Scope):
cname, type = definition cname, type = definition
self.declare_var(name, type, None, cname) self.declare_var(name, type, None, cname)
def lookup(self, name, language_level=None):
# 'language_level' is passed by ModuleScope
if language_level == 3:
if name == 'str':
name = 'unicode'
return Scope.lookup(self, name)
def declare_builtin(self, name, pos): def declare_builtin(self, name, pos):
if not hasattr(builtins, name): if not hasattr(builtins, name):
if self.outer_scope is not None: if self.outer_scope is not None:
...@@ -882,6 +889,12 @@ class ModuleScope(Scope): ...@@ -882,6 +889,12 @@ class ModuleScope(Scope):
def global_scope(self): def global_scope(self):
return self return self
def lookup(self, name):
entry = self.lookup_here(name)
if entry is not None:
return entry
return self.outer_scope.lookup(name, language_level = self.context.language_level)
def declare_builtin(self, name, pos): def declare_builtin(self, name, pos):
if not hasattr(builtins, name) and name != 'xrange': if not hasattr(builtins, name) and name != 'xrange':
# 'xrange' is special cased in Code.py # 'xrange' is special cased in Code.py
...@@ -1121,6 +1134,19 @@ class ModuleScope(Scope): ...@@ -1121,6 +1134,19 @@ class ModuleScope(Scope):
type.vtabslot_cname = "%s.%s" % ( type.vtabslot_cname = "%s.%s" % (
Naming.obj_base_cname, type.base_type.vtabslot_cname) Naming.obj_base_cname, type.base_type.vtabslot_cname)
elif type.scope and type.scope.cfunc_entries: elif type.scope and type.scope.cfunc_entries:
# one special case here: when inheriting from builtin
# types, the methods may also be built-in, in which
# case they won't need a vtable
entry_count = len(type.scope.cfunc_entries)
base_type = type.base_type
while base_type:
# FIXME: this will break if we ever get non-inherited C methods
if not base_type.scope or entry_count > len(base_type.scope.cfunc_entries):
break
if base_type.is_builtin_type:
# builtin base type defines all methods => no vtable needed
return
base_type = base_type.base_type
#print "...allocating vtabslot_cname because there are C methods" ### #print "...allocating vtabslot_cname because there are C methods" ###
type.vtabslot_cname = Naming.vtabslot_cname type.vtabslot_cname = Naming.vtabslot_cname
if type.vtabslot_cname: if type.vtabslot_cname:
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import re import re
from StringIO import StringIO from StringIO import StringIO
from Scanning import PyrexScanner, StringSourceDescriptor from Scanning import PyrexScanner, StringSourceDescriptor
from Symtab import BuiltinScope, ModuleScope from Symtab import ModuleScope
import Symtab import Symtab
import PyrexTypes import PyrexTypes
from Visitor import VisitorTransform from Visitor import VisitorTransform
......
__version__ = "0.14.rc0" __version__ = "0.14+"
# Void cython.* directives (for case insensitive operating systems). # Void cython.* directives (for case insensitive operating systems).
from Cython.Shadow import * from Cython.Shadow import *
include MANIFEST.in README.txt INSTALL.txt ToDo.txt USAGE.txt include MANIFEST.in README.txt INSTALL.txt ToDo.txt USAGE.txt
include COPYING.txt LICENSE.txt PKG-INFO Makefile include COPYING.txt LICENSE.txt Makefile
include .hgrev include .hgrev
include setup.py include setup.py
include setupegg.py include setupegg.py
...@@ -15,16 +15,12 @@ include Demos/callback/* ...@@ -15,16 +15,12 @@ include Demos/callback/*
include Demos/embed/* include Demos/embed/*
include Demos/freeze/* include Demos/freeze/*
include Demos/libraries/* include Demos/libraries/*
include Demos/Setup.py
include Demos/Makefile* include Demos/Makefile*
recursive-include Tools * recursive-include Tools *
recursive-include tests *.pyx *.pxd *.pxi *.py *.h *.BROKEN bugs.txt recursive-include tests *.pyx *.pxd *.pxi *.py *.h *.BROKEN bugs.txt
recursive-include tests *_lib.cpp *.srctree recursive-include tests *_lib.cpp *.srctree
include runtests.py include runtests.py
include Cython/Mac/Makefile
include Cython/Mac/_Filemodule_patched.c
include Cython/Debugger/Tests/cfuncs.c include Cython/Debugger/Tests/cfuncs.c
include Cython/Debugger/Tests/codefile include Cython/Debugger/Tests/codefile
......
...@@ -8,6 +8,35 @@ cdef class MyInt(int): ...@@ -8,6 +8,35 @@ cdef class MyInt(int):
""" """
cdef readonly object attr cdef readonly object attr
cdef class MyInt2(int):
"""
>>> MyInt2(2) == 2
True
>>> MyInt2(2).attr is None
True
>>> MyInt2(2).test(3)
5
"""
cdef readonly object attr
def test(self, arg):
return self._test(arg)
cdef _test(self, arg):
return self + arg
cdef class MyInt3(MyInt2):
"""
>>> MyInt3(2) == 2
True
>>> MyInt3(2).attr is None
True
>>> MyInt3(2).test(3)
6
"""
cdef _test(self, arg):
return self + arg + 1
cdef class MyFloat(float): cdef class MyFloat(float):
""" """
>>> MyFloat(1.0)== 1.0 >>> MyFloat(1.0)== 1.0
...@@ -23,6 +52,8 @@ cdef class MyUnicode(unicode): ...@@ -23,6 +52,8 @@ cdef class MyUnicode(unicode):
""" """
>>> MyUnicode(ustring) == ustring >>> MyUnicode(ustring) == ustring
True True
>>> MyUnicode(ustring + ustring) == ustring
False
>>> MyUnicode(ustring).attr is None >>> MyUnicode(ustring).attr is None
True True
""" """
...@@ -37,6 +68,43 @@ cdef class MyList(list): ...@@ -37,6 +68,43 @@ cdef class MyList(list):
""" """
cdef readonly object attr cdef readonly object attr
cdef class MyListOverride(list):
"""
>>> MyListOverride([1,2,3]) == [1,2,3]
True
>>> l = MyListOverride([1,2,3])
>>> l.reverse()
>>> l
[1, 2, 3, 5]
>>> l._reverse()
>>> l
[1, 2, 3, 5, 5]
"""
# not doctested:
"""
>>> l = MyListOverride([1,2,3])
>>> l.append(8)
>>> l
[1, 2, 3, 0, 8]
>>> l._append(9)
>>> l
[1, 2, 3, 0, 8, 0, 9]
"""
def reverse(self):
self[:] = self + [5]
def _reverse(self):
self.reverse()
## FIXME: this doesn't currently work:
## cdef int append(self, value) except -1:
## self[:] = self + [0] + [value]
## return 0
## def _append(self, value):
## self.append(value)
cdef class MyDict(dict): cdef class MyDict(dict):
""" """
>>> MyDict({1:2, 3:4}) == {1:2, 3:4} >>> MyDict({1:2, 3:4}) == {1:2, 3:4}
......
__doc__ = u"""
>>> d = Defined()
>>> n = NotDefined()
Traceback (most recent call last):
NameError: name 'NotDefined' is not defined
"""
if True:
class Defined(object):
"""
>>> isinstance(Defined(), Defined)
True
"""
if False:
class NotDefined(object):
"""
>>> NotDefined() # fails when defined
"""
def test_class_cond(x):
"""
>>> Test, test = test_class_cond(True)
>>> test.A
1
>>> Test().A
1
>>> Test, test = test_class_cond(False)
>>> test.A
2
>>> Test().A
2
"""
if x:
class Test(object):
A = 1
else:
class Test(object):
A = 2
return Test, Test()
def test_func_cond(x):
"""
>>> func = test_func_cond(True)
>>> func()
1
>>> func = test_func_cond(False)
>>> func()
2
"""
if x:
def func():
return 1
else:
def func():
return 2
return func
...@@ -28,8 +28,8 @@ def test_pow(double complex z, double complex w, tol=None): ...@@ -28,8 +28,8 @@ def test_pow(double complex z, double complex w, tol=None):
Various implementations produce slightly different results... Various implementations produce slightly different results...
>>> a = complex(3, 1) >>> a = complex(3, 1)
>>> test_pow(a, 1) >>> test_pow(a, 1, 1e-15)
(3+1j) True
>>> test_pow(a, 2, 1e-15) >>> test_pow(a, 2, 1e-15)
True True
>>> test_pow(a, a, 1e-15) >>> test_pow(a, a, 1e-15)
...@@ -48,7 +48,7 @@ def test_int_pow(double complex z, int n, tol=None): ...@@ -48,7 +48,7 @@ def test_int_pow(double complex z, int n, tol=None):
[True, True, True, True, True, True, True, True, True] [True, True, True, True, True, True, True, True, True]
>>> [test_int_pow(complex(0, 2), k, 1e-15) for k in range(-4, 5)] >>> [test_int_pow(complex(0, 2), k, 1e-15) for k in range(-4, 5)]
[True, True, True, True, True, True, True, True, True] [True, True, True, True, True, True, True, True, True]
>>> [test_int_pow(complex(2, 0.5), k, 1e-15) for k in range(0, 10)] >>> [test_int_pow(complex(2, 0.5), k, 1e-14) for k in range(0, 10)]
[True, True, True, True, True, True, True, True, True, True] [True, True, True, True, True, True, True, True, True, True]
""" """
if tol is None: if tol is None:
......
...@@ -66,6 +66,19 @@ def unicode_literals(): ...@@ -66,6 +66,19 @@ def unicode_literals():
print(isinstance(ustring, unicode) or type(ustring)) print(isinstance(ustring, unicode) or type(ustring))
return ustring return ustring
def str_type_is_unicode():
"""
>>> str_type, s = str_type_is_unicode()
>>> isinstance(s, type(ustring)) or (s, str_type)
True
>>> isinstance(s, str_type) or (s, str_type)
True
>>> isinstance(ustring, str_type) or str_type
True
"""
cdef str s = 'abc'
return str, s
def list_comp(): def list_comp():
""" """
>>> list_comp() >>> list_comp()
......
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