Cython-0.23.4/0000755000175600017570000000000012606202455014207 5ustar jenkinsjenkins00000000000000Cython-0.23.4/PKG-INFO0000644000175600017570000000337012606202455015307 0ustar jenkinsjenkins00000000000000Metadata-Version: 1.1 Name: Cython Version: 0.23.4 Summary: The Cython compiler for writing C extensions for the Python language. Home-page: http://cython.org/ Author: Robert Bradshaw, Stefan Behnel, Dag Seljebotn, Greg Ewing, et al. Author-email: cython-devel@python.org License: UNKNOWN Description: The Cython language makes writing C extensions for the Python language as easy as Python itself. Cython is a source code translator based on Pyrex_, but supports more cutting edge functionality and optimizations. The Cython language is very close to the Python language (and most Python code is also valid Cython code), but Cython additionally supports calling C functions and declaring C types on variables and class attributes. This allows the compiler to generate very efficient C code from Cython code. This makes Cython the ideal language for writing glue code for external C libraries, and for fast C modules that speed up the execution of Python code. .. _Pyrex: http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/ Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: C Classifier: Programming Language :: Cython Classifier: Topic :: Software Development :: Code Generators Classifier: Topic :: Software Development :: Compilers Classifier: Topic :: Software Development :: Libraries :: Python Modules Cython-0.23.4/setupegg.py0000755000175600017570000000024412606202452016404 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python """Wrapper to run setup.py using setuptools.""" import setuptools with open('setup.py') as f: exec(compile(f.read(), 'setup.py', 'exec')) Cython-0.23.4/setup.py0000755000175600017570000002503612606202452015727 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python try: from setuptools import setup, Extension except ImportError: from distutils.core import setup, Extension import os import stat import subprocess import textwrap import sys import platform is_cpython = platform.python_implementation() == 'CPython' if sys.platform == "darwin": # Don't create resource files on OS X tar. os.environ['COPY_EXTENDED_ATTRIBUTES_DISABLE'] = 'true' os.environ['COPYFILE_DISABLE'] = 'true' setup_args = {} def add_command_class(name, cls): cmdclasses = setup_args.get('cmdclass', {}) cmdclasses[name] = cls setup_args['cmdclass'] = cmdclasses from distutils.command.sdist import sdist as sdist_orig class sdist(sdist_orig): def run(self): self.force_manifest = 1 if (sys.platform != "win32" and os.path.isdir('.git')): assert os.system("git rev-parse --verify HEAD > .gitrev") == 0 sdist_orig.run(self) add_command_class('sdist', sdist) if sys.version_info[:2] == (3, 2): import lib2to3.refactor from distutils.command.build_py \ import build_py_2to3 as build_py # need to convert sources to Py3 on installation with open('2to3-fixers.txt') as f: fixers = [line.strip() for line in f if line.strip()] build_py.fixer_names = fixers add_command_class("build_py", build_py) pxd_include_dirs = [ directory for directory, dirs, files in os.walk('Cython/Includes') if '__init__.pyx' in files or '__init__.pxd' in files or directory == 'Cython/Includes' or directory == 'Cython/Includes/Deprecated'] pxd_include_patterns = [ p+'/*.pxd' for p in pxd_include_dirs ] + [ p+'/*.pyx' for p in pxd_include_dirs ] setup_args['package_data'] = { 'Cython.Plex' : ['*.pxd'], 'Cython.Compiler' : ['*.pxd'], 'Cython.Runtime' : ['*.pyx', '*.pxd'], 'Cython.Utility' : ['*.pyx', '*.pxd', '*.c', '*.h', '*.cpp'], 'Cython' : [ p[7:] for p in pxd_include_patterns ], } # This dict is used for passing extra arguments that are setuptools # specific to setup setuptools_extra_args = {} # tells whether to include cygdb (the script and the Cython.Debugger package include_debugger = sys.version_info[:2] > (2, 5) if 'setuptools' in sys.modules: setuptools_extra_args['zip_safe'] = False setuptools_extra_args['entry_points'] = { 'console_scripts': [ 'cython = Cython.Compiler.Main:setuptools_main', 'cythonize = Cython.Build.Cythonize:main' ] } scripts = [] else: if os.name == "posix": scripts = ["bin/cython", 'bin/cythonize'] else: scripts = ["cython.py", "cythonize.py"] if include_debugger: if 'setuptools' in sys.modules: setuptools_extra_args['entry_points']['console_scripts'].append( 'cygdb = Cython.Debugger.Cygdb:main') else: if os.name == "posix": scripts.append('bin/cygdb') else: scripts.append('cygdb.py') def compile_cython_modules(profile=False, compile_more=False, cython_with_refnanny=False): source_root = os.path.abspath(os.path.dirname(__file__)) compiled_modules = [ "Cython.Plex.Scanners", "Cython.Plex.Actions", "Cython.Compiler.Lexicon", "Cython.Compiler.Scanning", "Cython.Compiler.Parsing", "Cython.Compiler.Visitor", "Cython.Compiler.FlowControl", "Cython.Compiler.Code", "Cython.Runtime.refnanny", # "Cython.Compiler.FusedNode", "Cython.Tempita._tempita", ] if compile_more: compiled_modules.extend([ "Cython.Build.Dependencies", "Cython.Compiler.ParseTreeTransforms", "Cython.Compiler.Nodes", "Cython.Compiler.ExprNodes", "Cython.Compiler.ModuleNode", "Cython.Compiler.Optimize", ]) from distutils.spawn import find_executable from distutils.sysconfig import get_python_inc pgen = find_executable( 'pgen', os.pathsep.join([os.environ['PATH'], os.path.join(get_python_inc(), '..', 'Parser')])) if not pgen: print ("Unable to find pgen, not compiling formal grammar.") else: parser_dir = os.path.join(os.path.dirname(__file__), 'Cython', 'Parser') grammar = os.path.join(parser_dir, 'Grammar') subprocess.check_call([ pgen, os.path.join(grammar), os.path.join(parser_dir, 'graminit.h'), os.path.join(parser_dir, 'graminit.c'), ]) cst_pyx = os.path.join(parser_dir, 'ConcreteSyntaxTree.pyx') if os.stat(grammar)[stat.ST_MTIME] > os.stat(cst_pyx)[stat.ST_MTIME]: mtime = os.stat(grammar)[stat.ST_MTIME] os.utime(cst_pyx, (mtime, mtime)) compiled_modules.extend([ "Cython.Parser.ConcreteSyntaxTree", ]) defines = [] if cython_with_refnanny: defines.append(('CYTHON_REFNANNY', '1')) extensions = [] for module in compiled_modules: source_file = os.path.join(source_root, *module.split('.')) if os.path.exists(source_file + ".py"): pyx_source_file = source_file + ".py" else: pyx_source_file = source_file + ".pyx" dep_files = [] if os.path.exists(source_file + '.pxd'): dep_files.append(source_file + '.pxd') if '.refnanny' in module: defines_for_module = [] else: defines_for_module = defines extensions.append(Extension( module, sources=[pyx_source_file], define_macros=defines_for_module, depends=dep_files)) # XXX hack around setuptools quirk for '*.pyx' sources extensions[-1].sources[0] = pyx_source_file from Cython.Distutils import build_ext if sys.version_info[:2] == (3, 2): # Python 3.2: can only run Cython *after* running 2to3 build_ext = _defer_cython_import_in_py32(build_ext, source_root, profile) elif profile: from Cython.Compiler.Options import directive_defaults directive_defaults['profile'] = True print("Enabled profiling for the Cython binary modules") # not using cythonize() here to let distutils decide whether building extensions was requested add_command_class("build_ext", build_ext) setup_args['ext_modules'] = extensions def _defer_cython_import_in_py32(build_ext_orig, source_root, profile=False): # Python 3.2: can only run Cython *after* running 2to3 # => re-import Cython inside of build_ext class build_ext(build_ext_orig): # we must keep the original modules alive to make sure # their code keeps working when we remove them from # sys.modules dead_modules = [] def build_extensions(self): # add path where 2to3 installed the transformed sources # and make sure Python (re-)imports them from there already_imported = [ module for module in sys.modules if module == 'Cython' or module.startswith('Cython.') ] keep_alive = self.dead_modules.append for module in already_imported: keep_alive(sys.modules[module]) del sys.modules[module] sys.path.insert(0, os.path.join(source_root, self.build_lib)) if profile: from Cython.Compiler.Options import directive_defaults directive_defaults['profile'] = True print("Enabled profiling for the Cython binary modules") build_ext_orig.build_extensions(self) return build_ext cython_profile = '--cython-profile' in sys.argv if cython_profile: sys.argv.remove('--cython-profile') try: sys.argv.remove("--cython-compile-all") cython_compile_more = True except ValueError: cython_compile_more = False try: sys.argv.remove("--cython-with-refnanny") cython_with_refnanny = True except ValueError: cython_with_refnanny = False try: sys.argv.remove("--no-cython-compile") compile_cython_itself = False except ValueError: compile_cython_itself = True if compile_cython_itself and (is_cpython or cython_compile_more): compile_cython_modules(cython_profile, cython_compile_more, cython_with_refnanny) setup_args.update(setuptools_extra_args) from Cython import __version__ as version packages = [ 'Cython', 'Cython.Build', 'Cython.Compiler', 'Cython.Runtime', 'Cython.Distutils', 'Cython.Plex', 'Cython.Tests', 'Cython.Build.Tests', 'Cython.Compiler.Tests', 'Cython.Utility', 'Cython.Tempita', 'pyximport', ] if include_debugger: packages.append('Cython.Debugger') packages.append('Cython.Debugger.Tests') # it's enough to do this for Py2.5+: setup_args['package_data']['Cython.Debugger.Tests'] = ['codefile', 'cfuncs.c'] setup( name='Cython', version=version, url='http://cython.org/', author='Robert Bradshaw, Stefan Behnel, Dag Seljebotn, Greg Ewing, et al.', author_email='cython-devel@python.org', description="The Cython compiler for writing C extensions for the Python language.", long_description=textwrap.dedent("""\ The Cython language makes writing C extensions for the Python language as easy as Python itself. Cython is a source code translator based on Pyrex_, but supports more cutting edge functionality and optimizations. The Cython language is very close to the Python language (and most Python code is also valid Cython code), but Cython additionally supports calling C functions and declaring C types on variables and class attributes. This allows the compiler to generate very efficient C code from Cython code. This makes Cython the ideal language for writing glue code for external C libraries, and for fast C modules that speed up the execution of Python code. .. _Pyrex: http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/ """), classifiers=[ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", "Programming Language :: C", "Programming Language :: Cython", "Topic :: Software Development :: Code Generators", "Topic :: Software Development :: Compilers", "Topic :: Software Development :: Libraries :: Python Modules" ], scripts=scripts, packages=packages, py_modules=["cython"], **setup_args ) Cython-0.23.4/runtests.py0000755000175600017570000023713212606202452016460 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python import os import sys import re import gc import locale import shutil import time import unittest import doctest import operator import subprocess import tempfile import traceback import warnings try: import platform IS_PYPY = platform.python_implementation() == 'PyPy' IS_CPYTHON = platform.python_implementation() == 'CPython' except (ImportError, AttributeError): IS_CPYTHON = True IS_PYPY = False from io import open as io_open try: from StringIO import StringIO except ImportError: from io import StringIO # doesn't accept 'str' in Py2 try: import cPickle as pickle except ImportError: import pickle try: import threading except ImportError: # No threads, no problems threading = None try: from collections import defaultdict except ImportError: class defaultdict(object): def __init__(self, default_factory=lambda : None): self._dict = {} self.default_factory = default_factory def __getitem__(self, key): if key not in self._dict: self._dict[key] = self.default_factory() return self._dict[key] def __setitem__(self, key, value): self._dict[key] = value def __contains__(self, key): return key in self._dict def __repr__(self): return repr(self._dict) def __nonzero__(self): return bool(self._dict) try: basestring except NameError: basestring = str WITH_CYTHON = True CY3_DIR = None from distutils.command.build_ext import build_ext as _build_ext from distutils import sysconfig def get_distutils_distro(_cache=[]): if _cache: return _cache[0] # late import to accomodate for setuptools override from distutils.dist import Distribution distutils_distro = Distribution() if sys.platform == 'win32': # TODO: Figure out why this hackery (see http://thread.gmane.org/gmane.comp.python.cython.devel/8280/). config_files = distutils_distro.find_config_files() try: config_files.remove('setup.cfg') except ValueError: pass distutils_distro.parse_config_files(config_files) cfgfiles = distutils_distro.find_config_files() try: cfgfiles.remove('setup.cfg') except ValueError: pass distutils_distro.parse_config_files(cfgfiles) _cache.append(distutils_distro) return distutils_distro EXT_DEP_MODULES = { 'tag:numpy': 'numpy', 'tag:asyncio': 'asyncio', 'tag:pstats': 'pstats', 'tag:posix': 'posix', 'tag:array': 'array', 'tag:coverage': 'Cython.Coverage', 'Coverage': 'Cython.Coverage', 'tag:ipython': 'IPython', 'tag:jedi': 'jedi', } def patch_inspect_isfunction(): import inspect orig_isfunction = inspect.isfunction def isfunction(obj): return orig_isfunction(obj) or type(obj).__name__ == 'cython_function_or_method' isfunction._orig_isfunction = orig_isfunction inspect.isfunction = isfunction def unpatch_inspect_isfunction(): import inspect try: orig_isfunction = inspect.isfunction._orig_isfunction except AttributeError: pass else: inspect.isfunction = orig_isfunction def def_to_cdef(source): ''' Converts the module-level def methods into cdef methods, i.e. @decorator def foo([args]): """ [tests] """ [body] becomes def foo([args]): """ [tests] """ return foo_c([args]) cdef foo_c([args]): [body] ''' output = [] skip = False def_node = re.compile(r'def (\w+)\(([^()*]*)\):').match lines = iter(source.split('\n')) for line in lines: if not line.strip(): output.append(line) continue if skip: if line[0] != ' ': skip = False else: continue if line[0] == '@': skip = True continue m = def_node(line) if m: name = m.group(1) args = m.group(2) if args: args_no_types = ", ".join(arg.split()[-1] for arg in args.split(',')) else: args_no_types = "" output.append("def %s(%s):" % (name, args_no_types)) line = next(lines) if '"""' in line: has_docstring = True output.append(line) for line in lines: output.append(line) if '"""' in line: break else: has_docstring = False output.append(" return %s_c(%s)" % (name, args_no_types)) output.append('') output.append("cdef %s_c(%s):" % (name, args)) if not has_docstring: output.append(line) else: output.append(line) return '\n'.join(output) def update_linetrace_extension(ext): ext.define_macros.append(('CYTHON_TRACE', 1)) return ext def update_numpy_extension(ext): import numpy from numpy.distutils.misc_util import get_info ext.include_dirs.append(numpy.get_include()) # We need the npymath library for numpy.math. # This is typically a static-only library. for attr, value in get_info('npymath').items(): getattr(ext, attr).extend(value) def update_openmp_extension(ext): ext.openmp = True language = ext.language if language == 'cpp': flags = OPENMP_CPP_COMPILER_FLAGS else: flags = OPENMP_C_COMPILER_FLAGS if flags: compile_flags, link_flags = flags ext.extra_compile_args.extend(compile_flags.split()) ext.extra_link_args.extend(link_flags.split()) return ext elif sys.platform == 'win32': return ext return EXCLUDE_EXT def get_openmp_compiler_flags(language): """ As of gcc 4.2, it supports OpenMP 2.5. Gcc 4.4 implements 3.0. We don't (currently) check for other compilers. returns a two-tuple of (CFLAGS, LDFLAGS) to build the OpenMP extension """ if language == 'cpp': cc = sysconfig.get_config_var('CXX') else: cc = sysconfig.get_config_var('CC') if not cc: if sys.platform == 'win32': return '/openmp', '' return None # For some reason, cc can be e.g. 'gcc -pthread' cc = cc.split()[0] # Force english output env = os.environ.copy() env['LC_MESSAGES'] = 'C' matcher = re.compile(r"gcc version (\d+\.\d+)").search try: p = subprocess.Popen([cc, "-v"], stderr=subprocess.PIPE, env=env) except EnvironmentError: # Be compatible with Python 3 warnings.warn("Unable to find the %s compiler: %s: %s" % (language, os.strerror(sys.exc_info()[1].errno), cc)) return None _, output = p.communicate() output = output.decode(locale.getpreferredencoding() or 'ASCII', 'replace') gcc_version = matcher(output) if not gcc_version: return None # not gcc - FIXME: do something about other compilers # gcc defines "__int128_t", assume that at least all 64 bit architectures have it global COMPILER_HAS_INT128 COMPILER_HAS_INT128 = getattr(sys, 'maxsize', getattr(sys, 'maxint', 0)) > 2**60 compiler_version = gcc_version.group(1) if compiler_version and compiler_version.split('.') >= ['4', '2']: return '-fopenmp', '-fopenmp' try: locale.setlocale(locale.LC_ALL, '') except locale.Error: pass COMPILER = None COMPILER_HAS_INT128 = False OPENMP_C_COMPILER_FLAGS = get_openmp_compiler_flags('c') OPENMP_CPP_COMPILER_FLAGS = get_openmp_compiler_flags('cpp') # Return this from the EXT_EXTRAS matcher callback to exclude the extension EXCLUDE_EXT = object() EXT_EXTRAS = { 'tag:numpy' : update_numpy_extension, 'tag:openmp': update_openmp_extension, 'tag:trace' : update_linetrace_extension, } def _is_py3_before_32(excluded, version): return version[0] >= 3 and version < (3,2) # TODO: use tags VER_DEP_MODULES = { # tests are excluded if 'CurrentPythonVersion OP VersionTuple', i.e. # (2,4) : (operator.lt, ...) excludes ... when PyVer < 2.4.x (2,7) : (operator.lt, lambda x: x in ['run.withstat_py27', # multi context with statement 'run.yield_inside_lambda', 'run.test_dictviews', 'run.pyclass_special_methods', 'run.set_literals', ]), # The next line should start (3,); but this is a dictionary, so # we can only have one (3,) key. Since 2.7 is supposed to be the # last 2.x release, things would have to change drastically for this # to be unsafe... (2,999): (operator.lt, lambda x: x in ['run.special_methods_T561_py3', 'run.test_raisefrom', ]), (3,): (operator.ge, lambda x: x in ['run.non_future_division', 'compile.extsetslice', 'compile.extdelslice', 'run.special_methods_T561_py2' ]), (3,1): (_is_py3_before_32, lambda x: x in ['run.pyclass_special_methods', ]), (3,3) : (operator.lt, lambda x: x in ['build.package_compilation', 'run.yield_from_py33', ]), (3,4): (operator.lt, lambda x: x in ['run.py34_signature', ]), (3,5): (operator.lt, lambda x: x in ['run.py35_pep492_interop', ]), } INCLUDE_DIRS = [ d for d in os.getenv('INCLUDE', '').split(os.pathsep) if d ] CFLAGS = os.getenv('CFLAGS', '').split() CCACHE = os.getenv('CYTHON_RUNTESTS_CCACHE', '').split() TEST_SUPPORT_DIR = 'testsupport' BACKENDS = ['c', 'cpp'] UTF8_BOM_BYTES = r'\xef\xbb\xbf'.encode('ISO-8859-1').decode('unicode_escape') def memoize(f): uncomputed = object() f._cache = {} def func(*args): res = f._cache.get(args, uncomputed) if res is uncomputed: res = f._cache[args] = f(*args) return res return func @memoize def parse_tags(filepath): tags = defaultdict(list) parse_tag = re.compile(r'#\s*(\w+)\s*:(.*)$').match f = io_open(filepath, encoding='ISO-8859-1', errors='ignore') try: for line in f: # ignore BOM-like bytes and whitespace line = line.lstrip(UTF8_BOM_BYTES).strip() if not line: if tags: break # assume all tags are in one block else: continue if line[0] != '#': break parsed = parse_tag(line) if parsed: tag, values = parsed.groups() if tag in ('coding', 'encoding'): continue if tag == 'tags': tag = 'tag' print("WARNING: test tags use the 'tag' directive, not 'tags' (%s)" % filepath) if tag not in ('mode', 'tag', 'ticket', 'cython', 'distutils', 'preparse'): print("WARNING: unknown test directive '%s' found (%s)" % (tag, filepath)) values = values.split(',') tags[tag].extend(filter(None, [value.strip() for value in values])) elif tags: break # assume all tags are in one block finally: f.close() return tags list_unchanging_dir = memoize(lambda x: os.listdir(x)) @memoize def _list_pyregr_data_files(test_directory): is_data_file = re.compile('(?:[.](txt|pem|db|html)|^bad.*[.]py)$').search return ['__init__.py'] + [ filename for filename in list_unchanging_dir(test_directory) if is_data_file(filename)] def import_ext(module_name, file_path=None): if file_path: import imp return imp.load_dynamic(module_name, file_path) else: try: from importlib import invalidate_caches except ImportError: pass else: invalidate_caches() return __import__(module_name, globals(), locals(), ['*']) class build_ext(_build_ext): def build_extension(self, ext): try: try: # Py2.7+ & Py3.2+ compiler_obj = self.compiler_obj except AttributeError: compiler_obj = self.compiler if ext.language == 'c++': compiler_obj.compiler_so.remove('-Wstrict-prototypes') if CCACHE: compiler_obj.compiler_so = CCACHE + compiler_obj.compiler_so if getattr(ext, 'openmp', None) and compiler_obj.compiler_type == 'msvc': ext.extra_compile_args.append('/openmp') except Exception: pass _build_ext.build_extension(self, ext) class ErrorWriter(object): match_error = re.compile('(warning:)?(?:.*:)?\s*([-0-9]+)\s*:\s*([-0-9]+)\s*:\s*(.*)').match def __init__(self): self.output = [] self.write = self.output.append def _collect(self, collect_errors, collect_warnings): s = ''.join(self.output) result = [] for line in s.split('\n'): match = self.match_error(line) if match: is_warning, line, column, message = match.groups() if (is_warning and collect_warnings) or \ (not is_warning and collect_errors): result.append( (int(line), int(column), message.strip()) ) result.sort() return [ "%d:%d: %s" % values for values in result ] def geterrors(self): return self._collect(True, False) def getwarnings(self): return self._collect(False, True) def getall(self): return self._collect(True, True) class TestBuilder(object): def __init__(self, rootdir, workdir, selectors, exclude_selectors, annotate, cleanup_workdir, cleanup_sharedlibs, cleanup_failures, with_pyregr, cython_only, languages, test_bugs, fork, language_level, common_utility_dir): self.rootdir = rootdir self.workdir = workdir self.selectors = selectors self.exclude_selectors = exclude_selectors self.annotate = annotate self.cleanup_workdir = cleanup_workdir self.cleanup_sharedlibs = cleanup_sharedlibs self.cleanup_failures = cleanup_failures self.with_pyregr = with_pyregr self.cython_only = cython_only self.languages = languages self.test_bugs = test_bugs self.fork = fork self.language_level = language_level self.common_utility_dir = common_utility_dir def build_suite(self): suite = unittest.TestSuite() filenames = os.listdir(self.rootdir) filenames.sort() for filename in filenames: path = os.path.join(self.rootdir, filename) if os.path.isdir(path) and filename != TEST_SUPPORT_DIR: if filename == 'pyregr' and not self.with_pyregr: continue if filename == 'broken' and not self.test_bugs: continue suite.addTest( self.handle_directory(path, filename)) if sys.platform not in ['win32']: # Non-Windows makefile. if [1 for selector in self.selectors if selector("embedded")] \ and not [1 for selector in self.exclude_selectors if selector("embedded")]: suite.addTest(unittest.makeSuite(EmbedTest)) return suite def handle_directory(self, path, context): workdir = os.path.join(self.workdir, context) if not os.path.exists(workdir): os.makedirs(workdir) suite = unittest.TestSuite() filenames = list_unchanging_dir(path) filenames.sort() for filename in filenames: filepath = os.path.join(path, filename) module, ext = os.path.splitext(filename) if ext not in ('.py', '.pyx', '.srctree'): continue if filename.startswith('.'): continue # certain emacs backup files if context == 'pyregr': tags = defaultdict(list) else: tags = parse_tags(filepath) fqmodule = "%s.%s" % (context, module) if not [ 1 for match in self.selectors if match(fqmodule, tags) ]: continue if self.exclude_selectors: if [1 for match in self.exclude_selectors if match(fqmodule, tags)]: continue mode = 'run' # default if tags['mode']: mode = tags['mode'][0] elif context == 'pyregr': mode = 'pyregr' if ext == '.srctree': if 'cpp' not in tags['tag'] or 'cpp' in self.languages: suite.addTest(EndToEndTest(filepath, workdir, self.cleanup_workdir)) continue # Choose the test suite. if mode == 'pyregr': if not filename.startswith('test_'): continue test_class = CythonPyregrTestCase elif mode == 'run': if module.startswith("test_"): test_class = CythonUnitTestCase else: test_class = CythonRunTestCase else: test_class = CythonCompileTestCase for test in self.build_tests(test_class, path, workdir, module, mode == 'error', tags): suite.addTest(test) if mode == 'run' and ext == '.py' and not self.cython_only: # additionally test file in real Python suite.addTest(PureDoctestTestCase(module, os.path.join(path, filename))) return suite def build_tests(self, test_class, path, workdir, module, expect_errors, tags): if 'werror' in tags['tag']: warning_errors = True else: warning_errors = False if expect_errors: if 'cpp' in tags['tag'] and 'cpp' in self.languages: languages = ['cpp'] else: languages = self.languages[:1] else: languages = self.languages if 'cpp' in tags['tag'] and 'c' in languages: languages = list(languages) languages.remove('c') elif 'no-cpp' in tags['tag'] and 'cpp' in self.languages: languages = list(languages) languages.remove('cpp') preparse_list = tags.get('preparse', ['id']) tests = [ self.build_test(test_class, path, workdir, module, tags, language, expect_errors, warning_errors, preparse) for language in languages for preparse in preparse_list ] return tests def build_test(self, test_class, path, workdir, module, tags, language, expect_errors, warning_errors, preparse): language_workdir = os.path.join(workdir, language) if not os.path.exists(language_workdir): os.makedirs(language_workdir) workdir = os.path.join(language_workdir, module) if preparse != 'id': workdir += '_%s' % str(preparse) return test_class(path, workdir, module, tags, language=language, preparse=preparse, expect_errors=expect_errors, annotate=self.annotate, cleanup_workdir=self.cleanup_workdir, cleanup_sharedlibs=self.cleanup_sharedlibs, cleanup_failures=self.cleanup_failures, cython_only=self.cython_only, fork=self.fork, language_level=self.language_level, warning_errors=warning_errors, common_utility_dir=self.common_utility_dir) class CythonCompileTestCase(unittest.TestCase): def __init__(self, test_directory, workdir, module, tags, language='c', preparse='id', expect_errors=False, annotate=False, cleanup_workdir=True, cleanup_sharedlibs=True, cleanup_failures=True, cython_only=False, fork=True, language_level=2, warning_errors=False, common_utility_dir=None): self.test_directory = test_directory self.tags = tags self.workdir = workdir self.module = module self.language = language self.preparse = preparse self.name = module if self.preparse == "id" else "%s_%s" % (module, preparse) self.expect_errors = expect_errors self.annotate = annotate self.cleanup_workdir = cleanup_workdir self.cleanup_sharedlibs = cleanup_sharedlibs self.cleanup_failures = cleanup_failures self.cython_only = cython_only self.fork = fork self.language_level = language_level self.warning_errors = warning_errors self.common_utility_dir = common_utility_dir unittest.TestCase.__init__(self) def shortDescription(self): return "compiling (%s) %s" % (self.language, self.name) def setUp(self): from Cython.Compiler import Options self._saved_options = [ (name, getattr(Options, name)) for name in ('warning_errors', 'clear_to_none', 'error_on_unknown_names', 'error_on_uninitialized') ] self._saved_default_directives = list(Options.directive_defaults.items()) Options.warning_errors = self.warning_errors if sys.version_info >= (3, 4): Options.directive_defaults['autotestdict'] = False if not os.path.exists(self.workdir): os.makedirs(self.workdir) if self.workdir not in sys.path: sys.path.insert(0, self.workdir) def tearDown(self): from Cython.Compiler import Options for name, value in self._saved_options: setattr(Options, name, value) Options.directive_defaults = dict(self._saved_default_directives) unpatch_inspect_isfunction() try: sys.path.remove(self.workdir) except ValueError: pass try: del sys.modules[self.module] except KeyError: pass cleanup = self.cleanup_failures or self.success cleanup_c_files = WITH_CYTHON and self.cleanup_workdir and cleanup cleanup_lib_files = self.cleanup_sharedlibs and cleanup if os.path.exists(self.workdir): if cleanup_c_files and cleanup_lib_files: shutil.rmtree(self.workdir, ignore_errors=True) else: for rmfile in os.listdir(self.workdir): if not cleanup_c_files: if (rmfile[-2:] in (".c", ".h") or rmfile[-4:] == ".cpp" or rmfile.endswith(".html") and rmfile.startswith(self.module)): continue if not cleanup_lib_files and (rmfile.endswith(".so") or rmfile.endswith(".dll")): continue try: rmfile = os.path.join(self.workdir, rmfile) if os.path.isdir(rmfile): shutil.rmtree(rmfile, ignore_errors=True) else: os.remove(rmfile) except IOError: pass def runTest(self): self.success = False self.runCompileTest() self.success = True def runCompileTest(self): return self.compile( self.test_directory, self.module, self.workdir, self.test_directory, self.expect_errors, self.annotate) def find_module_source_file(self, source_file): if not os.path.exists(source_file): source_file = source_file[:-1] return source_file def build_target_filename(self, module_name): target = '%s.%s' % (module_name, self.language) return target def related_files(self, test_directory, module_name): is_related = re.compile('%s_.*[.].*' % module_name).match return [filename for filename in list_unchanging_dir(test_directory) if is_related(filename)] def copy_files(self, test_directory, target_directory, file_list): if self.preparse and self.preparse != 'id': preparse_func = globals()[self.preparse] def copy(src, dest): open(dest, 'w').write(preparse_func(open(src).read())) else: # use symlink on Unix, copy on Windows try: copy = os.symlink except AttributeError: copy = shutil.copy join = os.path.join for filename in file_list: file_path = join(test_directory, filename) if os.path.exists(file_path): copy(file_path, join(target_directory, filename)) def source_files(self, workdir, module_name, file_list): return ([self.build_target_filename(module_name)] + [filename for filename in file_list if not os.path.isfile(os.path.join(workdir, filename))]) def split_source_and_output(self, test_directory, module, workdir): source_file = self.find_module_source_file(os.path.join(test_directory, module) + '.pyx') source_and_output = io_open(source_file, 'rU', encoding='ISO-8859-1') try: out = io_open(os.path.join(workdir, module + os.path.splitext(source_file)[1]), 'w', encoding='ISO-8859-1') for line in source_and_output: if line.startswith("_ERRORS"): out.close() out = ErrorWriter() else: out.write(line) finally: source_and_output.close() try: geterrors = out.geterrors except AttributeError: out.close() return [] else: return geterrors() def run_cython(self, test_directory, module, targetdir, incdir, annotate, extra_compile_options=None): include_dirs = INCLUDE_DIRS + [os.path.join(test_directory, '..', TEST_SUPPORT_DIR)] if incdir: include_dirs.append(incdir) source = self.find_module_source_file( os.path.join(test_directory, module + '.pyx')) if self.preparse == 'id': source = self.find_module_source_file( os.path.join(test_directory, module + '.pyx')) else: self.copy_files(test_directory, targetdir, [module + '.pyx']) source = os.path.join(targetdir, module + '.pyx') target = os.path.join(targetdir, self.build_target_filename(module)) if extra_compile_options is None: extra_compile_options = {} if 'allow_unknown_names' in self.tags['tag']: from Cython.Compiler import Options Options.error_on_unknown_names = False try: CompilationOptions except NameError: from Cython.Compiler.Main import CompilationOptions from Cython.Compiler.Main import compile as cython_compile from Cython.Compiler.Main import default_options common_utility_include_dir = self.common_utility_dir options = CompilationOptions( default_options, include_path = include_dirs, output_file = target, annotate = annotate, use_listing_file = False, cplus = self.language == 'cpp', language_level = self.language_level, generate_pxi = False, evaluate_tree_assertions = True, common_utility_include_dir = common_utility_include_dir, **extra_compile_options ) cython_compile(source, options=options, full_module_name=module) def run_distutils(self, test_directory, module, workdir, incdir, extra_extension_args=None): cwd = os.getcwd() os.chdir(workdir) try: build_extension = build_ext(get_distutils_distro()) build_extension.include_dirs = INCLUDE_DIRS[:] if incdir: build_extension.include_dirs.append(incdir) build_extension.finalize_options() if COMPILER: build_extension.compiler = COMPILER ext_compile_flags = CFLAGS[:] compiler = COMPILER or sysconfig.get_config_var('CC') if self.language == 'c' and compiler == 'gcc': ext_compile_flags.extend(['-std=c89', '-pedantic']) if build_extension.compiler == 'mingw32': ext_compile_flags.append('-Wno-format') if extra_extension_args is None: extra_extension_args = {} related_files = self.related_files(test_directory, module) self.copy_files(test_directory, workdir, related_files) from distutils.core import Extension extension = Extension( module, sources=self.source_files(workdir, module, related_files), extra_compile_args=ext_compile_flags, **extra_extension_args ) if self.language == 'cpp': # Set the language now as the fixer might need it extension.language = 'c++' if 'distutils' in self.tags: from Cython.Build.Dependencies import DistutilsInfo pyx_path = os.path.join(self.test_directory, self.module + ".pyx") DistutilsInfo(open(pyx_path)).apply(extension) for matcher, fixer in list(EXT_EXTRAS.items()): if isinstance(matcher, str): # lazy init del EXT_EXTRAS[matcher] matcher = string_selector(matcher) EXT_EXTRAS[matcher] = fixer if matcher(module, self.tags): newext = fixer(extension) if newext is EXCLUDE_EXT: return extension = newext or extension if self.language == 'cpp': extension.language = 'c++' build_extension.extensions = [extension] build_extension.build_temp = workdir build_extension.build_lib = workdir build_extension.run() finally: os.chdir(cwd) try: get_ext_fullpath = build_extension.get_ext_fullpath except AttributeError: def get_ext_fullpath(ext_name, self=build_extension): # copied from distutils.command.build_ext (missing in Py2.[45]) fullname = self.get_ext_fullname(ext_name) modpath = fullname.split('.') filename = self.get_ext_filename(modpath[-1]) if not self.inplace: filename = os.path.join(*modpath[:-1]+[filename]) return os.path.join(self.build_lib, filename) package = '.'.join(modpath[0:-1]) build_py = self.get_finalized_command('build_py') package_dir = os.path.abspath(build_py.get_package_dir(package)) return os.path.join(package_dir, filename) return get_ext_fullpath(module) def compile(self, test_directory, module, workdir, incdir, expect_errors, annotate): expected_errors = errors = () if expect_errors: expected_errors = self.split_source_and_output( test_directory, module, workdir) test_directory = workdir if WITH_CYTHON: old_stderr = sys.stderr try: sys.stderr = ErrorWriter() self.run_cython(test_directory, module, workdir, incdir, annotate) errors = sys.stderr.geterrors() finally: sys.stderr = old_stderr tostderr = sys.__stderr__.write if 'cerror' in self.tags['tag']: if errors: tostderr("\n=== Expected C compile error ===\n") tostderr("\n=== Got Cython errors: ===\n") tostderr('\n'.join(errors)) tostderr('\n\n') raise RuntimeError('should have generated extension code') elif errors or expected_errors: try: for expected, error in zip(expected_errors, errors): self.assertEquals(expected, error) if len(errors) < len(expected_errors): expected_error = expected_errors[len(errors)] self.assertEquals(expected_error, None) elif len(errors) > len(expected_errors): unexpected_error = errors[len(expected_errors)] self.assertEquals(None, unexpected_error) except AssertionError: tostderr("\n=== Expected errors: ===\n") tostderr('\n'.join(expected_errors)) tostderr("\n\n=== Got errors: ===\n") tostderr('\n'.join(errors)) tostderr('\n\n') raise return None so_path = None if not self.cython_only: from Cython.Utils import captured_fd, print_bytes show_output = True get_stderr = get_stdout = None try: with captured_fd(1) as get_stdout: with captured_fd(2) as get_stderr: so_path = self.run_distutils(test_directory, module, workdir, incdir) except Exception: if 'cerror' in self.tags['tag'] and get_stderr and get_stderr(): show_output = False # expected C compiler failure else: raise else: if 'cerror' in self.tags['tag']: raise RuntimeError('should have failed C compile') finally: if show_output: stdout = get_stdout and get_stdout().strip() if stdout: tostderr("\n=== C/C++ compiler output: ===\n") print_bytes(stdout, end=None, file=sys.__stderr__) stderr = get_stderr and get_stderr().strip() if stderr: tostderr("\n=== C/C++ compiler error output: ===\n") print_bytes(stderr, end=None, file=sys.__stderr__) if stdout or stderr: tostderr("\n==============================\n") return so_path class CythonRunTestCase(CythonCompileTestCase): def setUp(self): CythonCompileTestCase.setUp(self) from Cython.Compiler import Options Options.clear_to_none = False def shortDescription(self): if self.cython_only: return CythonCompileTestCase.shortDescription(self) else: return "compiling (%s) and running %s" % (self.language, self.name) def run(self, result=None): if result is None: result = self.defaultTestResult() result.startTest(self) try: self.setUp() try: self.success = False ext_so_path = self.runCompileTest() failures, errors = len(result.failures), len(result.errors) if not self.cython_only and ext_so_path is not None: self.run_tests(result, ext_so_path) if failures == len(result.failures) and errors == len(result.errors): # No new errors... self.success = True finally: check_thread_termination() except Exception: result.addError(self, sys.exc_info()) result.stopTest(self) try: self.tearDown() except Exception: pass def run_tests(self, result, ext_so_path): self.run_doctests(self.module, result, ext_so_path) def run_doctests(self, module_or_name, result, ext_so_path): def run_test(result): if isinstance(module_or_name, basestring): module = import_ext(module_or_name, ext_so_path) else: module = module_or_name tests = doctest.DocTestSuite(module) tests.run(result) run_forked_test(result, run_test, self.shortDescription(), self.fork) def run_forked_test(result, run_func, test_name, fork=True): if not fork or sys.version_info[0] >= 3 or not hasattr(os, 'fork'): run_func(result) sys.stdout.flush() sys.stderr.flush() gc.collect() return # fork to make sure we do not keep the tested module loaded result_handle, result_file = tempfile.mkstemp() os.close(result_handle) child_id = os.fork() if not child_id: result_code = 0 output = None try: try: tests = partial_result = None try: partial_result = PartialTestResult(result) run_func(partial_result) sys.stdout.flush() sys.stderr.flush() gc.collect() except Exception: result_code = 1 if partial_result is not None: if tests is None: # importing failed, try to fake a test class tests = _FakeClass( failureException=sys.exc_info()[1], _shortDescription=test_name, module_name=None) partial_result.addError(tests, sys.exc_info()) output = open(result_file, 'wb') pickle.dump(partial_result.data(), output) except: traceback.print_exc() finally: try: sys.stderr.flush() except: pass try: sys.stdout.flush() except: pass try: if output is not None: output.close() except: pass os._exit(result_code) try: cid, result_code = os.waitpid(child_id, 0) module_name = test_name.split()[-1] # os.waitpid returns the child's result code in the # upper byte of result_code, and the signal it was # killed by in the lower byte if result_code & 255: raise Exception("Tests in module '%s' were unexpectedly killed by signal %d"% (module_name, result_code & 255)) result_code >>= 8 if result_code in (0,1): input = open(result_file, 'rb') try: PartialTestResult.join_results(result, pickle.load(input)) finally: input.close() if result_code: raise Exception("Tests in module '%s' exited with status %d" % (module_name, result_code)) finally: try: os.unlink(result_file) except: pass class PureDoctestTestCase(unittest.TestCase): def __init__(self, module_name, module_path): self.module_name = module_name self.module_path = module_path unittest.TestCase.__init__(self, 'run') def shortDescription(self): return "running pure doctests in %s" % self.module_name def run(self, result=None): if result is None: result = self.defaultTestResult() loaded_module_name = 'pure_doctest__' + self.module_name result.startTest(self) try: self.setUp() import imp m = imp.load_source(loaded_module_name, self.module_path) try: doctest.DocTestSuite(m).run(result) finally: del m if loaded_module_name in sys.modules: del sys.modules[loaded_module_name] check_thread_termination() except Exception: result.addError(self, sys.exc_info()) result.stopTest(self) try: self.tearDown() except Exception: pass is_private_field = re.compile('^_[^_]').match class _FakeClass(object): def __init__(self, **kwargs): self._shortDescription = kwargs.get('module_name') self.__dict__.update(kwargs) def shortDescription(self): return self._shortDescription try: # Py2.7+ and Py3.2+ from unittest.runner import _TextTestResult except ImportError: from unittest import _TextTestResult class PartialTestResult(_TextTestResult): def __init__(self, base_result): _TextTestResult.__init__( self, self._StringIO(), True, base_result.dots + base_result.showAll*2) def strip_error_results(self, results): for test_case, error in results: for attr_name in filter(is_private_field, dir(test_case)): if attr_name == '_dt_test': test_case._dt_test = _FakeClass( name=test_case._dt_test.name) elif attr_name != '_shortDescription': setattr(test_case, attr_name, None) def data(self): self.strip_error_results(self.failures) self.strip_error_results(self.errors) return (self.failures, self.errors, self.testsRun, self.stream.getvalue()) def join_results(result, data): """Static method for merging the result back into the main result object. """ failures, errors, tests_run, output = data if output: result.stream.write(output) result.errors.extend(errors) result.failures.extend(failures) result.testsRun += tests_run join_results = staticmethod(join_results) class _StringIO(StringIO): def writeln(self, line): self.write("%s\n" % line) class CythonUnitTestCase(CythonRunTestCase): def shortDescription(self): return "compiling (%s) tests in %s" % (self.language, self.name) def run_tests(self, result, ext_so_path): module = import_ext(self.module, ext_so_path) unittest.defaultTestLoader.loadTestsFromModule(module).run(result) class CythonPyregrTestCase(CythonRunTestCase): def setUp(self): CythonRunTestCase.setUp(self) from Cython.Compiler import Options Options.error_on_unknown_names = False Options.error_on_uninitialized = False Options.directive_defaults.update(dict( binding=True, always_allow_keywords=True, set_initial_path="SOURCEFILE")) patch_inspect_isfunction() def related_files(self, test_directory, module_name): return _list_pyregr_data_files(test_directory) def _run_unittest(self, result, *classes): """Run tests from unittest.TestCase-derived classes.""" valid_types = (unittest.TestSuite, unittest.TestCase) suite = unittest.TestSuite() for cls in classes: if isinstance(cls, str): if cls in sys.modules: suite.addTest(unittest.findTestCases(sys.modules[cls])) else: raise ValueError("str arguments must be keys in sys.modules") elif isinstance(cls, valid_types): suite.addTest(cls) else: suite.addTest(unittest.makeSuite(cls)) suite.run(result) def _run_doctest(self, result, module): self.run_doctests(module, result, None) def run_tests(self, result, ext_so_path): try: from test import support except ImportError: # Python2.x from test import test_support as support def run_test(result): def run_unittest(*classes): return self._run_unittest(result, *classes) def run_doctest(module, verbosity=None): return self._run_doctest(result, module) backup = (support.run_unittest, support.run_doctest) support.run_unittest = run_unittest support.run_doctest = run_doctest try: try: sys.stdout.flush() # helps in case of crashes module = import_ext(self.module, ext_so_path) sys.stdout.flush() # helps in case of crashes if hasattr(module, 'test_main'): # help 'doctest.DocFileTest' find the module path through frame inspection fake_caller_module_globals = { 'module': module, '__name__': module.__name__, } call_tests = eval( 'lambda: module.test_main()', fake_caller_module_globals, fake_caller_module_globals) call_tests() sys.stdout.flush() # helps in case of crashes except (unittest.SkipTest, support.ResourceDenied): result.addSkip(self, 'ok') finally: support.run_unittest, support.run_doctest = backup run_forked_test(result, run_test, self.shortDescription(), self.fork) include_debugger = IS_CPYTHON and sys.version_info[:2] > (2, 5) def collect_unittests(path, module_prefix, suite, selectors, exclude_selectors): def file_matches(filename): return filename.startswith("Test") and filename.endswith(".py") def package_matches(dirname): return dirname == "Tests" loader = unittest.TestLoader() if include_debugger: skipped_dirs = [] else: skipped_dirs = ['Cython' + os.path.sep + 'Debugger' + os.path.sep] for dirpath, dirnames, filenames in os.walk(path): if dirpath != path and "__init__.py" not in filenames: skipped_dirs.append(dirpath + os.path.sep) continue skip = False for dir in skipped_dirs: if dirpath.startswith(dir): skip = True if skip: continue parentname = os.path.split(dirpath)[-1] if package_matches(parentname): for f in filenames: if file_matches(f): filepath = os.path.join(dirpath, f)[:-len(".py")] modulename = module_prefix + filepath[len(path)+1:].replace(os.path.sep, '.') if not any(1 for match in selectors if match(modulename)): continue if any(1 for match in exclude_selectors if match(modulename)): continue module = __import__(modulename) for x in modulename.split('.')[1:]: module = getattr(module, x) suite.addTests([loader.loadTestsFromModule(module)]) def collect_doctests(path, module_prefix, suite, selectors, exclude_selectors): def package_matches(dirname): if dirname == 'Debugger' and not include_debugger: return False return dirname not in ("Mac", "Distutils", "Plex", "Tempita") def file_matches(filename): filename, ext = os.path.splitext(filename) blacklist = ['libcython', 'libpython', 'test_libcython_in_gdb', 'TestLibCython'] return (ext == '.py' and not '~' in filename and not '#' in filename and not filename.startswith('.') and not filename in blacklist) import doctest for dirpath, dirnames, filenames in os.walk(path): for dir in list(dirnames): if not package_matches(dir): dirnames.remove(dir) for f in filenames: if file_matches(f): if not f.endswith('.py'): continue filepath = os.path.join(dirpath, f) if os.path.getsize(filepath) == 0: continue filepath = filepath[:-len(".py")] modulename = module_prefix + filepath[len(path)+1:].replace(os.path.sep, '.') if not [ 1 for match in selectors if match(modulename) ]: continue if [ 1 for match in exclude_selectors if match(modulename) ]: continue if 'in_gdb' in modulename: # These should only be imported from gdb. continue module = __import__(modulename) for x in modulename.split('.')[1:]: module = getattr(module, x) if hasattr(module, "__doc__") or hasattr(module, "__test__"): try: suite.addTest(doctest.DocTestSuite(module)) except ValueError: # no tests pass class EndToEndTest(unittest.TestCase): """ This is a test of build/*.srctree files, where srctree defines a full directory structure and its header gives a list of commands to run. """ cython_root = os.path.dirname(os.path.abspath(__file__)) def __init__(self, treefile, workdir, cleanup_workdir=True): self.name = os.path.splitext(os.path.basename(treefile))[0] self.treefile = treefile self.workdir = os.path.join(workdir, self.name) self.cleanup_workdir = cleanup_workdir cython_syspath = [self.cython_root] for path in sys.path: if path.startswith(self.cython_root) and path not in cython_syspath: # Py3 installation and refnanny build prepend their # fixed paths to sys.path => prefer that over the # generic one (cython_root itself goes last) cython_syspath.append(path) self.cython_syspath = os.pathsep.join(cython_syspath[::-1]) unittest.TestCase.__init__(self) def shortDescription(self): return "End-to-end %s" % self.name def setUp(self): from Cython.TestUtils import unpack_source_tree _, self.commands = unpack_source_tree(self.treefile, self.workdir) self.old_dir = os.getcwd() os.chdir(self.workdir) if self.workdir not in sys.path: sys.path.insert(0, self.workdir) def tearDown(self): if self.cleanup_workdir: for trial in range(5): try: shutil.rmtree(self.workdir) except OSError: time.sleep(0.1) else: break os.chdir(self.old_dir) def _try_decode(self, content): try: return content.decode() except UnicodeDecodeError: return content.decode('iso-8859-1') def runTest(self): self.success = False commands = (self.commands .replace("CYTHON", "PYTHON %s" % os.path.join(self.cython_root, 'cython.py')) .replace("PYTHON", sys.executable)) old_path = os.environ.get('PYTHONPATH') os.environ['PYTHONPATH'] = self.cython_syspath + os.pathsep + (old_path or '') try: for command in filter(None, commands.splitlines()): p = subprocess.Popen(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) out, err = p.communicate() res = p.returncode if res != 0: print(command) print(self._try_decode(out)) print(self._try_decode(err)) self.assertEqual(0, res, "non-zero exit status") finally: if old_path: os.environ['PYTHONPATH'] = old_path else: del os.environ['PYTHONPATH'] self.success = True # TODO: Support cython_freeze needed here as well. # TODO: Windows support. class EmbedTest(unittest.TestCase): working_dir = "Demos/embed" def setUp(self): self.old_dir = os.getcwd() os.chdir(self.working_dir) os.system( "make PYTHON='%s' clean > /dev/null" % sys.executable) def tearDown(self): try: os.system( "make PYTHON='%s' clean > /dev/null" % sys.executable) except: pass os.chdir(self.old_dir) def test_embed(self): from distutils import sysconfig libname = sysconfig.get_config_var('LIBRARY') libdir = sysconfig.get_config_var('LIBDIR') if not os.path.isdir(libdir) or libname not in os.listdir(libdir): libdir = os.path.join(os.path.dirname(sys.executable), '..', 'lib') if not os.path.isdir(libdir) or libname not in os.listdir(libdir): libdir = os.path.join(libdir, 'python%d.%d' % sys.version_info[:2], 'config') if not os.path.isdir(libdir) or libname not in os.listdir(libdir): # report the error for the original directory libdir = sysconfig.get_config_var('LIBDIR') cython = 'cython.py' if sys.version_info[0] >=3 and CY3_DIR: cython = os.path.join(CY3_DIR, cython) cython = os.path.abspath(os.path.join('..', '..', cython)) self.assert_(os.system( "make PYTHON='%s' CYTHON='%s' LIBDIR1='%s' test > make.output" % (sys.executable, cython, libdir)) == 0) try: os.remove('make.output') except OSError: pass class MissingDependencyExcluder: def __init__(self, deps): # deps: { matcher func : module name } self.exclude_matchers = [] for matcher, mod in deps.items(): try: __import__(mod) except ImportError: self.exclude_matchers.append(string_selector(matcher)) self.tests_missing_deps = [] def __call__(self, testname, tags=None): for matcher in self.exclude_matchers: if matcher(testname, tags): self.tests_missing_deps.append(testname) return True return False class VersionDependencyExcluder: def __init__(self, deps): # deps: { version : matcher func } from sys import version_info self.exclude_matchers = [] for ver, (compare, matcher) in deps.items(): if compare(version_info, ver): self.exclude_matchers.append(matcher) self.tests_missing_deps = [] def __call__(self, testname, tags=None): for matcher in self.exclude_matchers: if matcher(testname): self.tests_missing_deps.append(testname) return True return False class FileListExcluder: def __init__(self, list_file, verbose=False): self.verbose = verbose self.excludes = {} self._list_file = os.path.relpath(list_file) with open(list_file) as f: for line in f: line = line.strip() if line and line[0] != '#': self.excludes[line.split()[0]] = True def __call__(self, testname, tags=None): exclude = (testname in self.excludes or testname.split('.')[-1] in self.excludes) if exclude and self.verbose: print("Excluding %s because it's listed in %s" % (testname, self._list_file)) return exclude class TagsSelector: def __init__(self, tag, value): self.tag = tag self.value = value def __call__(self, testname, tags=None): if tags is None: return False else: return self.value in tags[self.tag] class RegExSelector: def __init__(self, pattern_string): try: self.pattern = re.compile(pattern_string, re.I|re.U) except re.error: print('Invalid pattern: %r' % pattern_string) raise def __call__(self, testname, tags=None): return self.pattern.search(testname) def string_selector(s): ix = s.find(':') if ix == -1: return RegExSelector(s) else: return TagsSelector(s[:ix], s[ix+1:]) class ShardExcludeSelector: # This is an exclude selector so it can override the (include) selectors. # It may not provide uniform distribution (in time or count), but is a # determanistic partition of the tests which is important. def __init__(self, shard_num, shard_count): self.shard_num = shard_num self.shard_count = shard_count def __call__(self, testname, tags=None): return abs(hash(testname)) % self.shard_count != self.shard_num def refactor_for_py3(distdir, cy3_dir): # need to convert Cython sources first import lib2to3.refactor from distutils.util import copydir_run_2to3 with open('2to3-fixers.txt') as f: fixers = [line.strip() for line in f if line.strip()] if not os.path.exists(cy3_dir): os.makedirs(cy3_dir) import distutils.log as dlog dlog.set_threshold(dlog.INFO) copydir_run_2to3(distdir, cy3_dir, fixer_names=fixers, template = ''' global-exclude * graft Cython recursive-exclude Cython * recursive-include Cython *.py *.pyx *.pxd recursive-include Cython/Debugger/Tests * recursive-include Cython/Utility * recursive-exclude pyximport test include Tools/*.py include pyximport/*.py include runtests.py include cython.py include cythonize.py ''') sys.path.insert(0, cy3_dir) class PendingThreadsError(RuntimeError): pass threads_seen = [] def check_thread_termination(ignore_seen=True): if threading is None: # no threading enabled in CPython return current = threading.currentThread() blocking_threads = [] for t in threading.enumerate(): if not t.isAlive() or t == current: continue t.join(timeout=2) if t.isAlive(): if not ignore_seen: blocking_threads.append(t) continue for seen in threads_seen: if t is seen: break else: threads_seen.append(t) blocking_threads.append(t) if not blocking_threads: return sys.stderr.write("warning: left-over threads found after running test:\n") for t in blocking_threads: sys.stderr.write('...%s\n' % repr(t)) raise PendingThreadsError("left-over threads found after running test") def subprocess_output(cmd): try: p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) return p.communicate()[0].decode('UTF-8') except OSError: return '' def get_version(): from Cython.Compiler.Version import version as cython_version full_version = cython_version top = os.path.dirname(os.path.abspath(__file__)) if os.path.exists(os.path.join(top, '.git')): old_dir = os.getcwd() try: os.chdir(top) head_commit = subprocess_output(['git', 'rev-parse', 'HEAD']).strip() version_commit = subprocess_output(['git', 'rev-parse', cython_version]).strip() diff = subprocess_output(['git', 'diff', '--stat']).strip() if head_commit != version_commit: full_version += " " + head_commit if diff: full_version += ' + uncommitted changes' finally: os.chdir(old_dir) return full_version _orig_stdout, _orig_stderr = sys.stdout, sys.stderr def flush_and_terminate(status): try: _orig_stdout.flush() _orig_stderr.flush() finally: os._exit(status) def main(): global DISTDIR, WITH_CYTHON DISTDIR = os.path.join(os.getcwd(), os.path.dirname(sys.argv[0])) from optparse import OptionParser parser = OptionParser() parser.add_option("--no-cleanup", dest="cleanup_workdir", action="store_false", default=True, help="do not delete the generated C files (allows passing --no-cython on next run)") parser.add_option("--no-cleanup-sharedlibs", dest="cleanup_sharedlibs", action="store_false", default=True, help="do not delete the generated shared libary files (allows manual module experimentation)") parser.add_option("--no-cleanup-failures", dest="cleanup_failures", action="store_false", default=True, help="enable --no-cleanup and --no-cleanup-sharedlibs for failed tests only") parser.add_option("--no-cython", dest="with_cython", action="store_false", default=True, help="do not run the Cython compiler, only the C compiler") parser.add_option("--compiler", dest="compiler", default=None, help="C compiler type") backend_list = ','.join(BACKENDS) parser.add_option("--backends", dest="backends", default=backend_list, help="select backends to test (default: %s)" % backend_list) parser.add_option("--no-c", dest="use_c", action="store_false", default=True, help="do not test C compilation backend") parser.add_option("--no-cpp", dest="use_cpp", action="store_false", default=True, help="do not test C++ compilation backend") parser.add_option("--no-unit", dest="unittests", action="store_false", default=True, help="do not run the unit tests") parser.add_option("--no-doctest", dest="doctests", action="store_false", default=True, help="do not run the doctests") parser.add_option("--no-file", dest="filetests", action="store_false", default=True, help="do not run the file based tests") parser.add_option("--no-pyregr", dest="pyregr", action="store_false", default=True, help="do not run the regression tests of CPython in tests/pyregr/") parser.add_option("--cython-only", dest="cython_only", action="store_true", default=False, help="only compile pyx to c, do not run C compiler or run the tests") parser.add_option("--no-refnanny", dest="with_refnanny", action="store_false", default=True, help="do not regression test reference counting") parser.add_option("--no-fork", dest="fork", action="store_false", default=True, help="do not fork to run tests") parser.add_option("--sys-pyregr", dest="system_pyregr", action="store_true", default=False, help="run the regression tests of the CPython installation") parser.add_option("-x", "--exclude", dest="exclude", action="append", metavar="PATTERN", help="exclude tests matching the PATTERN") parser.add_option("-j", "--shard_count", dest="shard_count", metavar="N", type=int, default=1, help="shard this run into several parallel runs") parser.add_option("--shard_num", dest="shard_num", metavar="K", type=int, default=-1, help="test only this single shard") parser.add_option("-C", "--coverage", dest="coverage", action="store_true", default=False, help="collect source coverage data for the Compiler") parser.add_option("--coverage-xml", dest="coverage_xml", action="store_true", default=False, help="collect source coverage data for the Compiler in XML format") parser.add_option("--coverage-html", dest="coverage_html", action="store_true", default=False, help="collect source coverage data for the Compiler in HTML format") parser.add_option("-A", "--annotate", dest="annotate_source", action="store_true", default=True, help="generate annotated HTML versions of the test source files") parser.add_option("--no-annotate", dest="annotate_source", action="store_false", help="do not generate annotated HTML versions of the test source files") parser.add_option("-v", "--verbose", dest="verbosity", action="count", default=0, help="display test progress, pass twice to print test names") parser.add_option("-T", "--ticket", dest="tickets", action="append", help="a bug ticket number to run the respective test in 'tests/*'") parser.add_option("-3", dest="language_level", action="store_const", const=3, default=2, help="set language level to Python 3 (useful for running the CPython regression tests)'") parser.add_option("--xml-output", dest="xml_output_dir", metavar="DIR", help="write test results in XML to directory DIR") parser.add_option("--exit-ok", dest="exit_ok", default=False, action="store_true", help="exit without error code even on test failures") parser.add_option("--root-dir", dest="root_dir", default=os.path.join(DISTDIR, 'tests'), help="working directory") parser.add_option("--work-dir", dest="work_dir", default=os.path.join(os.getcwd(), 'BUILD'), help="working directory") parser.add_option("--cython-dir", dest="cython_dir", default=os.getcwd(), help="Cython installation directory (default: use local source version)") parser.add_option("--debug", dest="for_debugging", default=False, action="store_true", help="configure for easier use with a debugger (e.g. gdb)") parser.add_option("--pyximport-py", dest="pyximport_py", default=False, action="store_true", help="use pyximport to automatically compile imported .pyx and .py files") parser.add_option("--watermark", dest="watermark", default=None, help="deterministic generated by string") parser.add_option("--use_common_utility_dir", default=False, action="store_true") parser.add_option("--use_formal_grammar", default=False, action="store_true") options, cmd_args = parser.parse_args() WORKDIR = os.path.abspath(options.work_dir) if options.with_cython and sys.version_info[0] >= 3: sys.path.insert(0, options.cython_dir) if sys.version_info[:2] == (3, 2): try: # try if Cython is installed in a Py3 version import Cython.Compiler.Main except Exception: # back out anything the import process loaded, then # 2to3 the Cython sources to make them re-importable cy_modules = [ name for name in sys.modules if name == 'Cython' or name.startswith('Cython.') ] for name in cy_modules: del sys.modules[name] # hasn't been refactored yet - do it now global CY3_DIR CY3_DIR = cy3_dir = os.path.join(WORKDIR, 'Cy3') refactor_for_py3(DISTDIR, cy3_dir) if options.watermark: import Cython.Compiler.Version Cython.Compiler.Version.watermark = options.watermark WITH_CYTHON = options.with_cython coverage = None if options.coverage or options.coverage_xml or options.coverage_html: if options.shard_count <= 1 and options.shard_num < 0: if not WITH_CYTHON: options.coverage = options.coverage_xml = options.coverage_html = False else: print("Enabling coverage analysis") from coverage import coverage as _coverage coverage = _coverage(branch=True, omit=['Test*']) coverage.erase() coverage.start() if options.xml_output_dir: shutil.rmtree(options.xml_output_dir, ignore_errors=True) if WITH_CYTHON: global CompilationOptions, pyrex_default_options, cython_compile from Cython.Compiler.Main import \ CompilationOptions, \ default_options as pyrex_default_options, \ compile as cython_compile from Cython.Compiler import Errors Errors.LEVEL = 0 # show all warnings from Cython.Compiler import Options Options.generate_cleanup_code = 3 # complete cleanup code from Cython.Compiler import DebugFlags DebugFlags.debug_temp_code_comments = 1 pyrex_default_options['formal_grammar'] = options.use_formal_grammar if options.shard_count > 1 and options.shard_num == -1: import multiprocessing pool = multiprocessing.Pool(options.shard_count) tasks = [(options, cmd_args, shard_num) for shard_num in range(options.shard_count)] errors = [] for shard_num, return_code in pool.imap_unordered(runtests_callback, tasks): if return_code != 0: errors.append(shard_num) print("FAILED (%s/%s)" % (shard_num, options.shard_count)) print("ALL DONE (%s/%s)" % (shard_num, options.shard_count)) pool.close() pool.join() if errors: print("Errors for shards %s" % ", ".join([str(e) for e in errors])) return_code = 1 else: return_code = 0 else: _, return_code = runtests(options, cmd_args, coverage) print("ALL DONE") try: check_thread_termination(ignore_seen=False) except PendingThreadsError: # normal program exit won't kill the threads, do it the hard way here flush_and_terminate(return_code) else: sys.exit(return_code) def runtests_callback(args): options, cmd_args, shard_num = args options.shard_num = shard_num return runtests(options, cmd_args) def runtests(options, cmd_args, coverage=None): WITH_CYTHON = options.with_cython ROOTDIR = os.path.abspath(options.root_dir) WORKDIR = os.path.abspath(options.work_dir) xml_output_dir = options.xml_output_dir if options.shard_num > -1: WORKDIR = os.path.join(WORKDIR, str(options.shard_num)) if xml_output_dir: xml_output_dir = os.path.join(xml_output_dir, 'shard-%03d' % options.shard_num) # RUN ALL TESTS! UNITTEST_MODULE = "Cython" UNITTEST_ROOT = os.path.join(os.path.dirname(__file__), UNITTEST_MODULE) if WITH_CYTHON: if os.path.exists(WORKDIR): for path in os.listdir(WORKDIR): if path in ("support", "Cy3"): continue shutil.rmtree(os.path.join(WORKDIR, path), ignore_errors=True) if not os.path.exists(WORKDIR): os.makedirs(WORKDIR) if options.shard_num <= 0: sys.stderr.write("Python %s\n" % sys.version) sys.stderr.write("\n") if WITH_CYTHON: sys.stderr.write("Running tests against Cython %s\n" % get_version()) else: sys.stderr.write("Running tests without Cython.\n") if options.for_debugging: options.cleanup_workdir = False options.cleanup_sharedlibs = False options.fork = False if WITH_CYTHON and include_debugger: from Cython.Compiler.Main import default_options as compiler_default_options compiler_default_options['gdb_debug'] = True compiler_default_options['output_dir'] = os.getcwd() if options.with_refnanny: from pyximport.pyxbuild import pyx_to_dll libpath = pyx_to_dll(os.path.join("Cython", "Runtime", "refnanny.pyx"), build_in_temp=True, pyxbuild_dir=os.path.join(WORKDIR, "support")) sys.path.insert(0, os.path.split(libpath)[0]) CFLAGS.append("-DCYTHON_REFNANNY=1") if xml_output_dir and options.fork: # doesn't currently work together sys.stderr.write("Disabling forked testing to support XML test output\n") options.fork = False if WITH_CYTHON and options.language_level == 3: sys.stderr.write("Using Cython language level 3.\n") test_bugs = False if options.tickets: for ticket_number in options.tickets: test_bugs = True cmd_args.append('ticket:%s' % ticket_number) if not test_bugs: for selector in cmd_args: if selector.startswith('bugs'): test_bugs = True selectors = [ string_selector(r) for r in cmd_args ] verbose_excludes = selectors or options.verbosity >= 2 if not selectors: selectors = [ lambda x, tags=None: True ] # Check which external modules are not present and exclude tests # which depends on them (by prefix) missing_dep_excluder = MissingDependencyExcluder(EXT_DEP_MODULES) version_dep_excluder = VersionDependencyExcluder(VER_DEP_MODULES) exclude_selectors = [missing_dep_excluder, version_dep_excluder] # want to print msg at exit try: import IPython.core.release if list(IPython.core.release._ver) < [1, 0, 0]: raise ImportError except (ImportError, AttributeError, TypeError): exclude_selectors.append(RegExSelector('IPython')) try: import jedi if not ([0, 9] <= list(map(int, re.findall('[0-9]+', jedi.__version__ or '0')))): raise ImportError except (ImportError, AttributeError, TypeError): exclude_selectors.append(RegExSelector('Jedi')) if options.exclude: exclude_selectors += [ string_selector(r) for r in options.exclude ] if not COMPILER_HAS_INT128 or not IS_CPYTHON: exclude_selectors += [RegExSelector('int128')] if options.shard_num > -1: exclude_selectors.append(ShardExcludeSelector(options.shard_num, options.shard_count)) if not test_bugs: exclude_selectors += [ FileListExcluder(os.path.join(ROOTDIR, bugs_file_name), verbose=verbose_excludes) for bugs_file_name in ['bugs.txt'] + (['pypy_bugs.txt'] if IS_PYPY else []) ] if sys.platform in ['win32', 'cygwin'] and sys.version_info < (2,6): exclude_selectors += [ lambda x: x == "run.specialfloat" ] global COMPILER if options.compiler: COMPILER = options.compiler selected_backends = [ name.strip() for name in options.backends.split(',') if name.strip() ] backends = [] for backend in selected_backends: if backend == 'c' and not options.use_c: continue elif backend == 'cpp' and not options.use_cpp: continue elif backend not in BACKENDS: sys.stderr.write("Unknown backend requested: '%s' not one of [%s]\n" % ( backend, ','.join(BACKENDS))) sys.exit(1) backends.append(backend) if options.shard_num <= 0: sys.stderr.write("Backends: %s\n" % ','.join(backends)) languages = backends if options.use_common_utility_dir: common_utility_dir = os.path.join(WORKDIR, 'utility_code') if not os.path.exists(common_utility_dir): os.makedirs(common_utility_dir) else: common_utility_dir = None sys.stderr.write("\n") test_suite = unittest.TestSuite() if options.unittests: collect_unittests(UNITTEST_ROOT, UNITTEST_MODULE + ".", test_suite, selectors, exclude_selectors) if options.doctests: collect_doctests(UNITTEST_ROOT, UNITTEST_MODULE + ".", test_suite, selectors, exclude_selectors) if options.filetests and languages: filetests = TestBuilder(ROOTDIR, WORKDIR, selectors, exclude_selectors, options.annotate_source, options.cleanup_workdir, options.cleanup_sharedlibs, options.cleanup_failures, options.pyregr, options.cython_only, languages, test_bugs, options.fork, options.language_level, common_utility_dir) test_suite.addTest(filetests.build_suite()) if options.system_pyregr and languages: sys_pyregr_dir = os.path.join(sys.prefix, 'lib', 'python'+sys.version[:3], 'test') if os.path.isdir(sys_pyregr_dir): filetests = TestBuilder(ROOTDIR, WORKDIR, selectors, exclude_selectors, options.annotate_source, options.cleanup_workdir, options.cleanup_sharedlibs, options.cleanup_failures, True, options.cython_only, languages, test_bugs, options.fork, sys.version_info[0], common_utility_dir) sys.stderr.write("Including CPython regression tests in %s\n" % sys_pyregr_dir) test_suite.addTest(filetests.handle_directory(sys_pyregr_dir, 'pyregr')) if xml_output_dir: from Cython.Tests.xmlrunner import XMLTestRunner if not os.path.exists(xml_output_dir): try: os.makedirs(xml_output_dir) except OSError: pass # concurrency issue? test_runner = XMLTestRunner(output=xml_output_dir, verbose=options.verbosity > 0) else: test_runner = unittest.TextTestRunner(verbosity=options.verbosity) if options.pyximport_py: from pyximport import pyximport pyximport.install(pyimport=True, build_dir=os.path.join(WORKDIR, '_pyximport'), load_py_module_on_import_failure=True, inplace=True) result = test_runner.run(test_suite) if common_utility_dir and options.shard_num < 0 and options.cleanup_workdir: shutil.rmtree(common_utility_dir) if coverage is not None: coverage.stop() ignored_modules = set( 'Cython.Compiler.' + name for name in ('Version', 'DebugFlags', 'CmdLine')) | set( 'Cython.' + name for name in ('Debugging',)) ignored_packages = ['Cython.Runtime', 'Cython.Tempita'] modules = [ module for name, module in sys.modules.items() if module is not None and name.startswith('Cython.') and '.Tests' not in name and name not in ignored_modules and not any(name.startswith(package) for package in ignored_packages) ] if options.coverage: coverage.report(modules, show_missing=0) if options.coverage_xml: coverage.xml_report(modules, outfile="coverage-report.xml") if options.coverage_html: coverage.html_report(modules, directory="coverage-report-html") if missing_dep_excluder.tests_missing_deps: sys.stderr.write("Following tests excluded because of missing dependencies on your system:\n") for test in missing_dep_excluder.tests_missing_deps: sys.stderr.write(" %s\n" % test) if options.with_refnanny: import refnanny sys.stderr.write("\n".join([repr(x) for x in refnanny.reflog])) if options.exit_ok: return options.shard_num, 0 else: return options.shard_num, not result.wasSuccessful() if __name__ == '__main__': try: main() except Exception: traceback.print_exc() try: check_thread_termination(ignore_seen=False) except PendingThreadsError: # normal program exit won't kill the threads, do it the hard way here flush_and_terminate(1) Cython-0.23.4/pylintrc0000644000175600017570000001721212606202452015776 0ustar jenkinsjenkins00000000000000[MASTER] # Specify a configuration file. #rcfile= # Python code to execute, usually for sys.path manipulation such as # pygtk.require(). #init-hook= # Profiled execution. profile=no # Add files or directories to the blacklist. They should be base names, not # paths. ignore=.git,.gitmarker # Pickle collected data for later comparisons. persistent=yes # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. load-plugins= [MESSAGES CONTROL] # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option # multiple time. #enable= # Disable the message, report, category or checker with the given id(s). You # can either give multiple identifier separated by comma (,) or put this option # multiple time (only on the command line, not in the configuration file where # it should appear only once). ## R0201: Method could be a function ## R0904: Too many public methods ## W0201: Attribute defined outside __init__() ## W0141: Used builtin function 'map' disable=E1101,C0111,R0201,R0904,W0201,W0141 [REPORTS] # Set the output format. Available formats are text, parseable, colorized, msvs # (visual studio) and html. You can also give a reporter class, eg # mypackage.mymodule.MyReporterClass. output-format=parseable # Include message's id in output include-ids=yes # Include symbolic ids of messages in output symbols=no # Put messages in a separate file for each module / package specified on the # command line instead of printing them on stdout. Reports (if any) will be # written in a file name "pylint_global.[txt|html]". files-output=no # Tells whether to display a full report or only the messages reports=no # Python expression which should return a note less than 10 (10 is the highest # note). You have access to the variables errors warning, statement which # respectively contain the number of errors / warnings messages and the total # number of statements analyzed. This is used by the global evaluation report # (RP0004). evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) # Add a comment according to your evaluation note. This is used by the global # evaluation report (RP0004). comment=no [MISCELLANEOUS] # List of note tags to take in consideration, separated by a comma. notes=FIXME,XXX,TODO [BASIC] # Required attributes for module, separated by a comma required-attributes= # List of builtins function names that should not be used, separated by a comma bad-functions=map,filter,apply,input # Regular expression which should only match correct module names module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ # Regular expression which should only match correct module level names const-rgx=(([a-zA-Z_][a-zA-Z0-9_]*)|(__.*__))$ # Regular expression which should only match correct class names class-rgx=[A-Z_][a-zA-Z0-9]+$ # Regular expression which should only match correct function names function-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct method names method-rgx=[a-z_][a-z0-9_]{2,30}|visit_[A-Za-z]+$ # Regular expression which should only match correct instance attribute names attr-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct argument names argument-rgx=[a-z_][a-z0-9_]{0,30}$ # Regular expression which should only match correct variable names variable-rgx=[a-z_][a-z0-9_]{0,30}$ # Regular expression which should only match correct list comprehension / # generator expression variable names inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ # Good variable names which should always be accepted, separated by a comma good-names=i,j,k,ex,Run,_ # Bad variable names which should always be refused, separated by a comma bad-names=foo,bar,baz,toto,tutu,tata # Regular expression which should only match functions or classes name which do # not require a docstring no-docstring-rgx=__.*__ [FORMAT] # Maximum number of characters on a single line. max-line-length=120 # Maximum number of lines in a module max-module-lines=15000 # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 # tab). indent-string=' ' [SIMILARITIES] # Minimum lines number of a similarity. min-similarity-lines=4 # Ignore comments when computing similarities. ignore-comments=yes # Ignore docstrings when computing similarities. ignore-docstrings=yes # Ignore imports when computing similarities. ignore-imports=no [TYPECHECK] # Tells whether missing members accessed in mixin class should be ignored. A # mixin class is detected if its name ends with "mixin" (case insensitive). ignore-mixin-members=yes # List of classes names for which member attributes should not be checked # (useful for classes with attributes dynamically set). ignored-classes= # When zope mode is activated, add a predefined set of Zope acquired attributes # to generated-members. zope=no # List of members which are set dynamically and missed by pylint inference # system, and so shouldn't trigger E0201 when accessed. Python regular # expressions are accepted. generated-members=REQUEST,acl_users,aq_parent [VARIABLES] # Tells whether we should check for unused import in __init__ files. init-import=no # A regular expression matching the beginning of the name of dummy variables # (i.e. not used). dummy-variables-rgx=_|dummy # List of additional names supposed to be defined in builtins. Remember that # you should avoid to define new builtins when possible. additional-builtins= [IMPORTS] # Deprecated modules which should not be used, separated by a comma deprecated-modules=regsub,string,TERMIOS,Bastion,rexec # Create a graph of every (i.e. internal and external) dependencies in the # given file (report RP0402 must not be disabled) import-graph= # Create a graph of external dependencies in the given file (report RP0402 must # not be disabled) ext-import-graph= # Create a graph of internal dependencies in the given file (report RP0402 must # not be disabled) int-import-graph= [DESIGN] # Maximum number of arguments for function / method max-args=12 # Argument names that match this expression will be ignored. Default to name # with leading underscore ignored-argument-names=_.* # Maximum number of locals for function / method body max-locals=15 # Maximum number of return / yield for function / method body max-returns=6 # Maximum number of branch for function / method body max-branchs=12 # Maximum number of statements in function / method body max-statements=50 # Maximum number of parents for a class (see R0901). max-parents=7 # Maximum number of attributes for a class (see R0902). max-attributes=7 # Minimum number of public methods for a class (see R0903). min-public-methods=2 # Maximum number of public methods for a class (see R0904). max-public-methods=20 [CLASSES] # List of interface methods to ignore, separated by a comma. This is used for # instance to not check methods defines in Zope's Interface base class. ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by # List of method names used to declare (i.e. assign) instance attributes. defining-attr-methods=__init__,__new__,setUp # List of valid names for the first argument in a class method. valid-classmethod-first-arg=cls # List of valid names for the first argument in a metaclass class method. valid-metaclass-classmethod-first-arg=mcs [EXCEPTIONS] # Exceptions that will emit a warning when being caught. Defaults to # "Exception" overgeneral-exceptions=Exception Cython-0.23.4/cythonize.py0000755000175600017570000000022212606202452016571 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # # Cython -- enhanced main program # if __name__ == '__main__': from Cython.Build.Cythonize import main main() Cython-0.23.4/cython.py0000755000175600017570000000101012606202452016055 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # # Cython -- Main Program, generic # if __name__ == '__main__': import os import sys # Make sure we import the right Cython cythonpath, _ = os.path.split(os.path.realpath(__file__)) sys.path.insert(0, cythonpath) from Cython.Compiler.Main import main main(command_line = 1) else: # Void cython.* directives. from Cython.Shadow import * ## and bring in the __version__ from Cython import __version__ from Cython import load_ipython_extension Cython-0.23.4/cygdb.py0000755000175600017570000000017312606202452015652 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python import sys from Cython.Debugger import Cygdb as cygdb if __name__ == '__main__': cygdb.main() Cython-0.23.4/USAGE.txt0000644000175600017570000000513012606202452015610 0ustar jenkinsjenkins00000000000000Cython - Usage Instructions ========================== Building Cython extensions using distutils ----------------------------------------- Cython comes with an experimental distutils extension for compiling Cython modules, contributed by Graham Fawcett of the University of Windsor (fawcett@uwindsor.ca). The Demos directory contains a setup.py file demonstrating its use. To compile the demos: (1) cd Demos (2) python setup.py build_ext --inplace or python setup.py build --build-lib=. (You may get a screed of warnings from the C compiler, but you can ignore these -- as long as there are no actual errors, things are probably okay.) Try out the extensions with: python run_primes.py python run_spam.py python run_numeric_demo.py Building Cython extensions by hand --------------------------------- You can also invoke the Cython compiler on its own to translate a .pyx file to a .c file. On Unix, cython filename.pyx On other platforms, python cython.py filename.pyx It's then up to you to compile and link the .c file using whatever procedure is appropriate for your platform. The file Makefile.nodistutils in the Demos directory shows how to do this for one particular Unix system. Command line options -------------------- The cython command supports the following options: Short Long Argument Description ----------------------------------------------------------------------------- -v --version Display version number of cython compiler -l --create-listing Write error messages to a .lis file -I --include-dir Search for include files in named directory (may be repeated) -o --output-file Specify name of generated C file (only one source file allowed if this is used) -p, --embed-positions If specified, the positions in Cython files of each function definition is embedded in its docstring. -z, --pre-import If specified, assume undeclared names in this module. Emulates the behavior of putting "from import *" at the top of the file. Anything else is taken as the name of a Cython source file and compiled to a C source file. Multiple Cython source files can be specified (unless -o is used), in which case each source file is treated as the source of a distinct extension module and compiled separately to produce its own C file. Cython-0.23.4/ToDo.txt0000644000175600017570000001616312606202452015621 0ustar jenkinsjenkins00000000000000See http://trac.cython.org/cython_trac and http://wiki.cython.org/enhancements -- The Original Pyrex Todo List -- DONE - Pointer-to-function types. DONE - Nested declarators. DONE - Varargs C func defs and calls. DONE - * and ** args in Python func defs. DONE - Default argument values. DONE - Tracebacks. DONE - Disallow creating char * from Python temporary anywhere (not just on assignment). DONE - Module and function and class doc strings. DONE - Predeclare C functions. DONE - Constant expressions. DONE - Forward C struct declarations. DONE - Prefix & operator. DONE - Get rid of auto string->char coercion and add a c'X' syntax for char literals. DONE - Cascaded assignments (a = b = c). DONE - 'include' statement for including other Pyrex files. DONE - Add command line option for specifying name of generated C file. DONE - Add 'else' clause to try-except. DONE - Allow extension types to be declared "public" so they can be accessed from another Pyrex module or a C file. DONE - Don't try to generate objstruct definition for external extension type declared without suite (treat as though declared with empty suite). DONE - Implement two-argument form of 'assert' statement. Const types. Tuple/list construction: Evaluate & store items one at a time? Varargs argument traversal. Use PyDict_SetItemString to build keyword arg dicts? (Or wait until names are interned.) Intern names. print >>file abs() and anything similar. Semicolon-separated statement lists. Optional semicolons after C declarations. Multiple C declarations on one line? Optimise return without value outside of try-finally. exec statement. from ... import statement. Use iterator protocol for unpacking. Save & restore exception being handled on function entry/exit. In-place operators (+=, etc). Constant declarations. Syntax? DONE - Some way for C functions to signal Python errors? Check for lack of return with value in non-void C functions? Allow 'pass' in struct/union/enum definition. Make C structs callable as constructors. DONE - Provide way of specifying C names. DONE - Public cdefs. When calling user __dealloc__ func, save & restore exception. DONE - Forward declaration of extension types. Complex number parsetuple format? DONE - long long type DONE - long double type? Windows __fooblarg function declaration things. Generate type, var and func declarations in the same order that they appear in the source file. Provide a way of declaring a C function as returning a borrowed Python reference. Provide a way of specifying whether a Python object obtained by casting a pointer should be treated as a new reference or not. Optimize integer for-loops. Make sizeof() take types as well as variables. Allow "unsigned" to be used alone as a type name. Allow duplicate declarations, at least in extern-from. Do something about installing proper version of pyrexc script according to platform in setup.py. DONE - Add "-o filename" command line option to unix/dos versions. Recognise #line directives? Catch floating point exceptions? Check that forward-declared non-external extension types are defined. Generate type test when casting from one Python type to another. Generate a Pyrex include file for public declarations as well as a C one. Syntax for defining indefinite-sized int & float types. Allow ranges of exception values. Support "complex double" and "complex float"? Allow module-level Python variables to be declared extern. Consider: >cdef extern from "foo.h": > int dosomething() except -1 raise MyException Properties for Python types. DONE - Properties for extension types. Find a way to make classmethod and staticmethod work better. DONE - Document workarounds for classmethod and staticmethod. Statically initialised C arrays & structs. Reduce generation of unused vars and unreachable code? Support for acquiring and releasing GIL. Make docstrings of extension type special methods work. Treat result of getting C attribute of extension type as non-ephemeral. Make None a reserved identifier. Teach it about builtin functions that correspond to Python/C API calls. Teach it about common builtin types. Option for generating a main() function? DONE - Allow an extension type to inherit from another type. Do something about external C functions declared as returning const * types? Use PyString_FromStringAndSize for string literals? DONE - C functions as methods of extension types. What to do about __name__ etc. attributes of a module (they are currently assumed to be built-in names). Use PyDict_GetItem etc. on module & builtins dicts for speed. Intern all string literals used as Python strings? [Koshy ] Make extension types weak-referenceable. [Matthias Baas ] Make 'pass' work in the body of an extern-from struct or union. Disallow a filename which results in an illegal identifier when used as a module name. Use ctypedef names. Provide an easy way of exposing a set of enum values as Python names. [John J Lee ] Prevent user from returning a value from special methods that return an error indicator only. Use PyObject_TypeCheck instead of PyObject_IsInstance? Allow * in cimport? [John J Lee ] FAQ: Q. Pyrex says my extension type object has no attribute 'rhubarb', but I know it does. A. Have you declared the type at the point where you're using it? Eliminate lvalue casts! (Illegal in C++, also disallowed by some C compilers) [Matthias Baas ] Make Python class construction work more like it does in Python. Give the right module name to Python classes. Command line switch for full pathnames in backtraces? Use PyString_FromStringAndSize on string literals containing nulls. Peephole optimisation? [Vladislav Bulatov ] Avoid PyArg_ParseTuple call when a function takes no positional args. Omit incref/decref of arguments that are not assigned to? Can a faster way of instantiating extension types be found? Disallow declaring a special method of an extension type with 'cdef' instead of 'def'. Use PySequence_GetItem instead of PyObject_GetItem when index is an integer. If a __getitem__ method is declared with an int index, use the sq_item slot instead of the mp_subscript slot. Provide some way of controlling the argument list passed to an extension type's base __new__ method? [Alain Pointdexter ] Rename __new__ in extension types to __alloc__. Implement a true __new__ for extension types. Way to provide constructors for extension types that are not available to Python and can accept C types directly? Support generators by turning them into extension types? List comprehensions. Variable declarations inside inner code blocks? Initial values when declaring variables? Do something about __stdcall. Support class methods in extension types using METH_CLASS flag. Disallow defaulting types to 'object' in C declarations? C globals with static initialisers. Find a way of providing C-only initialisers for extension types. Metaclasses for extension types? Make extension types use Py_TPFLAGS_HEAPTYPE so their __module__ will get set dynamically? Cython-0.23.4/README.txt0000644000175600017570000000425112606202452015704 0ustar jenkinsjenkins00000000000000Welcome to Cython! ================= Cython (http://cython.org) is a language that makes writing C extensions for the Python language as easy as Python itself. Cython is based on the well-known Pyrex, but supports more cutting edge functionality and optimizations. The Cython language is very close to the Python language, but Cython additionally supports calling C functions and declaring C types on variables and class attributes. This allows the compiler to generate very efficient C code from Cython code. This makes Cython the ideal language for wrapping external C libraries, and for fast C modules that speed up the execution of Python code. LICENSE: The original Pyrex program was licensed "free of restrictions" (see below). Cython itself is licensed under the permissive Apache License See LICENSE.txt. -------------------------- Note that Cython used to ship the full version control repository in its source distribution, but no longer does so due to space constraints. To get the full source history, make sure you have git installed, then step into the base directory of the Cython source distribution and type make repo Alternatively, check out the latest developer repository from https://github.com/cython/cython The following is from Pyrex: ------------------------------------------------------ This is a development version of Pyrex, a language for writing Python extension modules. For more info, see: Doc/About.html for a description of the language INSTALL.txt for installation instructions USAGE.txt for usage instructions Demos for usage examples Comments, suggestions, bug reports, etc. are welcome! Copyright stuff: Pyrex is free of restrictions. You may use, redistribute, modify and distribute modified versions. The latest version of Pyrex can be found here: http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/ Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg@cosc.canterbury.ac.nz +--------------------------------------+ Cython-0.23.4/Makefile0000644000175600017570000000144112606202452015644 0ustar jenkinsjenkins00000000000000PYTHON?=python REPO = git://github.com/cython/cython.git all: local local: ${PYTHON} setup.py build_ext --inplace TMPDIR = .repo_tmp .git: .gitrev rm -rf $(TMPDIR) git clone -n $(REPO) $(TMPDIR) cd $(TMPDIR) && git reset -q "$(shell cat .gitrev)" mv $(TMPDIR)/.git . rm -rf $(TMPDIR) git ls-files -d | xargs git checkout -- repo: .git clean: @echo Cleaning Source @rm -fr build @rm -f *.py[co] */*.py[co] */*/*.py[co] */*/*/*.py[co] @rm -f *.so */*.so */*/*.so @rm -f *.pyd */*.pyd */*/*.pyd @rm -f *~ */*~ */*/*~ @rm -f core */core @rm -f Cython/Compiler/*.c @rm -f Cython/Plex/*.c @rm -f Cython/Tempita/*.c @rm -f Cython/Runtime/refnanny.c @(cd Demos; $(MAKE) clean) testclean: rm -fr BUILD test: testclean ${PYTHON} runtests.py -vv s5: $(MAKE) -C Doc/s5 slides Cython-0.23.4/MANIFEST.in0000644000175600017570000000176112606202452015747 0ustar jenkinsjenkins00000000000000include MANIFEST.in README.txt INSTALL.txt ToDo.txt USAGE.txt CHANGES.rst include COPYING.txt LICENSE.txt 2to3-fixers.txt Makefile include .gitrev include pylintrc include setup.py include setupegg.py include bin/* include cython.py cythonize.py cygdb.py recursive-include Cython *.pyx *.pxd include Cython/Parser/Grammar Cython/Parser/__init__.py include Doc/* include Demos/*.pyx include Demos/*.py include Demos/callback/* include Demos/benchmarks/* include Demos/embed/* include Demos/freeze/* include Demos/libraries/* include Demos/Makefile* recursive-include Cython/Debugger/Tests *.pyx *.pxd *.c *.h recursive-include Cython/Utility *.pyx *.pxd *.c *.h *.cpp recursive-include Tools * recursive-include tests *.pyx *.pxd *.pxi *.py *.h *.BROKEN bugs.txt recursive-include tests *_lib.cpp *.srctree recursive-include docs * include runtests.py include Cython/Debugger/Tests/cfuncs.c include Cython/Debugger/Tests/codefile recursive-include pyximport *.py include pyximport/PKG-INFO pyximport/README Cython-0.23.4/LICENSE.txt0000644000175600017570000002367512606202452016044 0ustar jenkinsjenkins00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS Cython-0.23.4/INSTALL.txt0000644000175600017570000000103612606202452016053 0ustar jenkinsjenkins00000000000000Cython - Installation Instructions ================================== You have two installation options: (1) Run the setup.py script in this directory as follows: python setup.py install This will install the Cython package into your Python system. OR (2) If you prefer not to modify your Python installation, arrange for the directory containing this file (INSTALL.txt) to be in your PYTHONPATH. On unix, also put the bin directory on your PATH. See README.txt for pointers to other documentation. Cython-0.23.4/COPYING.txt0000644000175600017570000000136412606202452016061 0ustar jenkinsjenkins00000000000000The original Pyrex code as of 2006-04 is licensed under the following license: "Copyright stuff: Pyrex is free of restrictions. You may use, redistribute, modify and distribute modified versions." ------------------ Cython, which derives from Pyrex, is licensed under the Apache 2.0 Software License. More precisely, all modifications and new code made to go from Pyrex to Cython are so licensed. See LICENSE.txt for more details. ------------------ The output of a Cython compilation is NOT considered a derivative work of Cython. Specifically, though the compilation process may embed snippets of varying lengths into the final output, these snippets, as embedded in the output, do not encumber the resulting output with any license restrictions. Cython-0.23.4/CHANGES.rst0000644000175600017570000015613612606202452016022 0ustar jenkinsjenkins00000000000000================ Cython Changelog ================ 0.23.4 (2015-10-10) =================== Bugs fixed ---------- * Memory leak when calling Python functions in PyPy. * Compilation problem with MSVC in C99-ish mode. * Warning about unused values in a helper macro. 0.23.3 (2015-09-29) =================== Bugs fixed ---------- * Invalid C code for some builtin methods. This fixes ticket 856 again. * Incorrect C code in helper functions for PyLong conversion and string decoding. This fixes ticket 863, ticket 864 and ticket 865. Original patch by Nikolaus Rath. * Large folded or inserted integer constants could use too small C integer types and thus trigger a value wrap-around. Other changes ------------- * The coroutine and generator types of Cython now also register directly with the ``Coroutine`` and ``Generator`` ABCs in the ``backports_abc`` module if it can be imported. This fixes ticket 870. 0.23.2 (2015-09-11) =================== Bugs fixed ---------- * Compiler crash when analysing some optimised expressions. * Coverage plugin was adapted to coverage.py 4.0 beta 2. * C++ destructor calls could fail when '&' operator is overwritten. * Incorrect C literal generation for large integers in compile-time evaluated DEF expressions and constant folded expressions. * Byte string constants could end up as Unicode strings when originating from compile-time evaluated DEF expressions. * Invalid C code when caching known builtin methods. This fixes ticket 860. * ``ino_t`` in ``posix.types`` was not declared as ``unsigned``. * Declarations in ``libcpp/memory.pxd`` were missing ``operator!()``. Patch by Leo Razoumov. * Static cdef methods can now be declared in .pxd files. 0.23.1 (2015-08-22) =================== Bugs fixed ---------- * Invalid C code for generators. This fixes ticket 858. * Invalid C code for some builtin methods. This fixes ticket 856. * Invalid C code for unused local buffer variables. This fixes ticket 154. * Test failures on 32bit systems. This fixes ticket 857. * Code that uses "from xyz import *" and global C struct/union/array variables could fail to compile due to missing helper functions. This fixes ticket 851. * Misnamed PEP 492 coroutine property ``cr_yieldfrom`` renamed to ``cr_await`` to match CPython. * Missing deallocation code for C++ object attributes in certain extension class hierarchies. * Crash when async coroutine was not awaited. * Compiler crash on ``yield`` in signature annotations and default argument values. Both are forbidden now. * Compiler crash on certain constructs in ``finally`` clauses. * Cython failed to build when CPython's pgen is installed. 0.23 (2015-08-08) ================= Features added -------------- * PEP 492 (async/await) was implemented. See https://www.python.org/dev/peps/pep-0492/ * PEP 448 (Additional Unpacking Generalizations) was implemented. See https://www.python.org/dev/peps/pep-0448/ * Support for coverage.py 4.0+ can be enabled by adding the plugin "Cython.Coverage" to the ".coveragerc" config file. * Annotated HTML source pages can integrate (XML) coverage reports. * Tracing is supported in ``nogil`` functions/sections and module init code. * When generators are used in a Cython module and the module imports the modules "inspect" and/or "asyncio", Cython enables interoperability by patching these modules during the import to recognise Cython's internal generator and coroutine types. This can be disabled by C compiling the module with "-D CYTHON_PATCH_ASYNCIO=0" or "-D CYTHON_PATCH_INSPECT=0" * When generators or coroutines are used in a Cython module, their types are registered with the ``Generator`` and ``Coroutine`` ABCs in the ``collections`` or ``collections.abc`` stdlib module at import time to enable interoperability with code that needs to detect and process Python generators/coroutines. These ABCs were added in CPython 3.5 and are available for older Python versions through the ``backports_abc`` module on PyPI. See https://bugs.python.org/issue24018 * Adding/subtracting/dividing/modulus and equality comparisons with constant Python floats and small integers are faster. * Binary and/or/xor/rshift operations with small constant Python integers are faster. * When called on generator expressions, the builtins ``all()``, ``any()``, ``dict()``, ``list()``, ``set()``, ``sorted()`` and ``unicode.join()`` avoid the generator iteration overhead by inlining a part of their functionality into the for-loop. * Keyword argument dicts are no longer copied on function entry when they are not being used or only passed through to other function calls (e.g. in wrapper functions). * The ``PyTypeObject`` declaration in ``cpython.object`` was extended. * The builtin ``type`` type is now declared as PyTypeObject in source, allowing for extern functions taking type parameters to have the correct C signatures. Note that this might break code that uses ``type`` just for passing around Python types in typed variables. Removing the type declaration provides a backwards compatible fix. * ``wraparound()`` and ``boundscheck()`` are available as no-ops in pure Python mode. * Const iterators were added to the provided C++ STL declarations. * Smart pointers were added to the provided C++ STL declarations. Patch by Daniel Filonik. * ``NULL`` is allowed as default argument when embedding signatures. This fixes ticket 843. * When compiling with ``--embed``, the internal module name is changed to ``__main__`` to allow arbitrary program names, including those that would be invalid for modules. Note that this prevents reuse of the generated C code as an importable module. * External C++ classes that overload the assignment operator can be used. Patch by Ian Henriksen. * Support operator bool() for C++ classes so they can be used in if statements. Bugs fixed ---------- * Calling "yield from" from Python on a Cython generator that returned a value triggered a crash in CPython. This is now being worked around. See https://bugs.python.org/issue23996 * Language level 3 did not enable true division (a.k.a. float division) for integer operands. * Functions with fused argument types that included a generic 'object' fallback could end up using that fallback also for other explicitly listed object types. * Relative cimports could accidentally fall back to trying an absolute cimport on failure. * The result of calling a C struct constructor no longer requires an intermediate assignment when coercing to a Python dict. * C++ exception declarations with mapping functions could fail to compile when pre-declared in .pxd files. * ``cpdef void`` methods are now permitted. * ``abs(cint)`` could fail to compile in MSVC and used sub-optimal code in C++. Patch by David Vierra, original patch by Michael Enßlin. * Buffer index calculations using index variables with small C integer types could overflow for large buffer sizes. Original patch by David Vierra. * C unions use a saner way to coerce from and to Python dicts. * When compiling a module ``foo.pyx``, the directories in ``sys.path`` are no longer searched when looking for ``foo.pxd``. Patch by Jeroen Demeyer. * Memory leaks in the embedding main function were fixed. Original patch by Michael Enßlin. * Some complex Python expressions could fail to compile inside of finally clauses. * Unprefixed 'str' literals were not supported as C varargs arguments. * Fixed type errors in conversion enum types to/from Python. Note that this imposes stricter correctness requirements on enum declarations. Other changes ------------- * Changed mangling scheme in header files generated by ``cdef api`` declarations. * Installation under CPython 3.3+ no longer requires a pass of the 2to3 tool. This also makes it possible to run Cython in Python 3.3+ from a source checkout without installing it first. Patch by Petr Viktorin. * ``jedi-typer.py`` (in ``Tools/``) was extended and renamed to ``jedityper.py`` (to make it importable) and now works with and requires Jedi 0.9. Patch by Tzer-jen Wei. 0.22.1 (2015-06-20) =================== Bugs fixed ---------- * Crash when returning values on generator termination. * In some cases, exceptions raised during internal isinstance() checks were not propagated. * Runtime reported file paths of source files (e.g for profiling and tracing) are now relative to the build root directory instead of the main source file. * Tracing exception handling code could enter the trace function with an active exception set. * The internal generator function type was not shared across modules. * Comparisons of (inferred) ctuples failed to compile. * Closures inside of cdef functions returning ``void`` failed to compile. * Using ``const`` C++ references in intermediate parts of longer expressions could fail to compile. * C++ exception declarations with mapping functions could fail to compile when pre-declared in .pxd files. * C++ compilation could fail with an ambiguity error in recent MacOS-X Xcode versions. * C compilation could fail in pypy3. * Fixed a memory leak in the compiler when compiling multiple modules. * When compiling multiple modules, external library dependencies could leak into later compiler runs. Fix by Jeroen Demeyer. This fixes ticket 845. 0.22 (2015-02-11) ================= Features added -------------- * C functions can coerce to Python functions, which allows passing them around as callable objects. * C arrays can be assigned by value and auto-coerce from Python iterables and to Python lists (and tuples). * Extern C functions can now be declared as cpdef to export them to the module's Python namespace. Extern C functions in pxd files export their values to their own module, iff it exists. * Anonymous C tuple types can be declared as (ctype1, ctype2, ...). * PEP 479: turn accidental StopIteration exceptions that exit generators into a RuntimeError, activated with future import "generator_stop". See https://www.python.org/dev/peps/pep-0479/ * Looping over ``reversed(range())`` is optimised in the same way as ``range()``. Patch by Favian Contreras. Bugs fixed ---------- * Mismatching 'except' declarations on signatures in .pxd and .pyx files failed to produce a compile error. * Failure to find any files for the path pattern(s) passed into ``cythonize()`` is now an error to more easily detect accidental typos. * The ``logaddexp`` family of functions in ``numpy.math`` now has correct declarations. * In Py2.6/7 and Py3.2, simple Cython memory views could accidentally be interpreted as non-contiguous by CPython, which could trigger a CPython bug when copying data from them, thus leading to data corruption. See CPython issues 12834 and 23349. Other changes ------------- * Preliminary support for defining the Cython language with a formal grammar. To try parsing your files against this grammar, use the --formal_grammar directive. Experimental. * ``_`` is no longer considered a cacheable builtin as it could interfere with gettext. * Cythonize-computed metadata now cached in the generated C files. * Several corrections and extensions in numpy, cpython, and libcpp pxd files. 0.21.2 (2014-12-27) =================== Bugs fixed ---------- * Crash when assigning a C value to both a Python and C target at the same time. * Automatic coercion from C++ strings to ``str`` generated incomplete code that failed to compile. * Declaring a constructor in a C++ child class erroneously required a default constructor declaration in the super class. * ``resize_smart()`` in ``cpython.array`` was broken. * Functions in ``libcpp.cast`` are now declared as ``nogil``. * Some missing C-API declarations were added. * Py3 main code in embedding program code was lacking casts. * Exception related to distutils "Distribution" class type in pyximport under latest CPython 2.7 and 3.4 releases when setuptools is being imported later. 0.21.1 (2014-10-18) =================== Features added -------------- * New ``cythonize`` option ``-a`` to generate the annotated HTML source view. * Missing C-API declarations in ``cpython.unicode`` were added. * Passing ``language='c++'`` into cythonize() globally enables C++ mode for all modules that were not passed as Extension objects (i.e. only source files and file patterns). * ``Py_hash_t`` is a known type (used in CPython for hash values). * ``PySlice_*()`` C-API functions are available from the ``cpython.slice`` module. * Allow arrays of C++ classes. Bugs fixed ---------- * Reference leak for non-simple Python expressions in boolean and/or expressions. * To fix a name collision and to reflect availability on host platforms, standard C declarations [ clock(), time(), struct tm and tm* functions ] were moved from posix/time.pxd to a new libc/time.pxd. Patch by Charles Blake. * Rerunning unmodified modules in IPython's cython support failed. Patch by Matthias Bussonier. * Casting C++ ``std::string`` to Python byte strings failed when auto-decoding was enabled. * Fatal exceptions in global module init code could lead to crashes if the already created module was used later on (e.g. through a stale reference in sys.modules or elsewhere). * ``cythonize.py`` script was not installed on MS-Windows. Other changes ------------- * Compilation no longer fails hard when unknown compilation options are passed. Instead, it raises a warning and ignores them (as it did silently before 0.21). This will be changed back to an error in a future release. 0.21 (2014-09-10) ================= Features added -------------- * C (cdef) functions allow inner Python functions. * Enums can now be declared as cpdef to export their values to the module's Python namespace. Cpdef enums in pxd files export their values to their own module, iff it exists. * Allow @staticmethod decorator to declare static cdef methods. This is especially useful for declaring "constructors" for cdef classes that can take non-Python arguments. * Taking a ``char*`` from a temporary Python string object is safer in more cases and can be done inside of non-trivial expressions, including arguments of a function call. A compile time error is raised only when such a pointer is assigned to a variable and would thus exceed the lifetime of the string itself. * Generators have new properties ``__name__`` and ``__qualname__`` that provide the plain/qualified name of the generator function (following CPython 3.5). See http://bugs.python.org/issue21205 * The ``inline`` function modifier is available as a decorator ``@cython.inline`` in pure mode. * When cygdb is run in a virtualenv, it enables the same virtualenv inside of the debugger. Patch by Marc Abramowitz. * PEP 465: dedicated infix operator for matrix multiplication (A @ B). * HTML output of annotated code uses Pygments for code highlighting and generally received a major overhaul by Matthias Bussonier. * IPython magic support is now available directly from Cython with the command "%load_ext cython". Cython code can directly be executed in a cell when marked with "%%cython". Code analysis is available with "%%cython -a". Patch by Martín Gaitán. * Simple support for declaring Python object types in Python signature annotations. Currently requires setting the compiler directive ``annotation_typing=True``. * New directive ``use_switch`` (defaults to True) to optionally disable the optimization of chained if statement to C switch statements. * Defines dynamic_cast et al. in ``libcpp.cast`` and C++ heap data structure operations in ``libcpp.algorithm``. * Shipped header declarations in ``posix.*`` were extended to cover more of the POSIX API. Patches by Lars Buitinck and Mark Peek. Optimizations ------------- * Simple calls to C implemented Python functions/methods are faster. This also speeds up many operations on builtins that Cython cannot otherwise optimise. * The "and"/"or" operators try to avoid unnecessary coercions of their arguments. They now evaluate the truth value of each argument independently and only coerce the final result of the whole expression to the target type (e.g. the type on the left side of an assignment). This also avoids reference counting overhead for Python values during evaluation and generally improves the code flow in the generated C code. * The Python expression "2 ** N" is optimised into bit shifting. See http://bugs.python.org/issue21420 * Cascaded assignments (a = b = ...) try to minimise the number of type coercions. * Calls to ``slice()`` are translated to a straight C-API call. Bugs fixed ---------- * Crash when assigning memory views from ternary conditional expressions. * Nested C++ templates could lead to unseparated ">>" characters being generated into the C++ declarations, which older C++ compilers could not parse. * Sending SIGINT (Ctrl-C) during parallel cythonize() builds could hang the child processes. * No longer ignore local setup.cfg files for distutils in pyximport. Patch by Martin Teichmann. * Taking a ``char*`` from an indexed Python string generated unsafe reference counting code. * Set literals now create all of their items before trying to add them to the set, following the behaviour in CPython. This makes a difference in the rare case that the item creation has side effects and some items are not hashable (or if hashing them has side effects, too). * Cython no longer generates the cross product of C functions for code that uses memory views of fused types in function signatures (e.g. ``cdef func(floating[:] a, floating[:] b)``). This is considered the expected behaviour by most users and was previously inconsistent with other structured types like C arrays. Code that really wants all type combinations can create the same fused memoryview type under different names and use those in the signature to make it clear which types are independent. * Names that were unknown at compile time were looked up as builtins at runtime but not as global module names. Trying both lookups helps with globals() manipulation. * Fixed stl container conversion for typedef element types. * ``obj.pop(x)`` truncated large C integer values of x to ``Py_ssize_t``. * ``__init__.pyc`` is recognised as marking a package directory (in addition to .py, .pyx and .pxd). * Syntax highlighting in ``cython-mode.el`` for Emacs no longer incorrectly highlights keywords found as part of longer names. * Correctly handle ``from cython.submodule cimport name``. * Fix infinite recursion when using super with cpdef methods. * No-args ``dir()`` was not guaranteed to return a sorted list. Other changes ------------- * The header line in the generated C files no longer contains the timestamp but only the Cython version that wrote it. This was changed to make builds more reproducible. * Removed support for CPython 2.4, 2.5 and 3.1. * The licensing implications on the generated code were clarified to avoid legal constraints for users. 0.20.2 (2014-06-16) =================== Features added -------------- * Some optimisations for set/frozenset instantiation. * Support for C++ unordered_set and unordered_map. Bugs fixed ---------- * Access to attributes of optimised builtin methods (e.g. ``[].append.__name__``) could fail to compile. * Memory leak when extension subtypes add a memory view as attribute to those of the parent type without having Python object attributes or a user provided dealloc method. * Compiler crash on readonly properties in "binding" mode. * Auto-encoding with ``c_string_encoding=ascii`` failed in Py3.3. * Crash when subtyping freelist enabled Cython extension types with Python classes that use ``__slots__``. * Freelist usage is restricted to CPython to avoid problems with other Python implementations. * Memory leak in memory views when copying overlapping, contiguous slices. * Format checking when requesting non-contiguous buffers from ``cython.array`` objects was accidentally omitted in Py3. * C++ destructor calls in extension types could fail to compile in clang. * Buffer format validation failed for sequences of strings in structs. * Docstrings on extension type attributes in .pxd files were rejected. 0.20.1 (2014-02-11) =================== Bugs fixed ---------- * Build error under recent MacOS-X versions where ``isspace()`` could not be resolved by clang. * List/Tuple literals multiplied by more than one factor were only multiplied by the last factor instead of all. * Lookups of special methods (specifically for context managers) could fail in Python <= 2.6/3.1. * Local variables were erroneously appended to the signature introspection of Cython implemented functions with keyword-only arguments under Python 3. * In-place assignments to variables with inferred Python builtin/extension types could fail with type errors if the result value type was incompatible with the type of the previous value. * The C code generation order of cdef classes, closures, helper code, etc. was not deterministic, thus leading to high code churn. * Type inference could fail to deduce C enum types. * Type inference could deduce unsafe or inefficient types from integer assignments within a mix of inferred Python variables and integer variables. 0.20 (2014-01-18) ================= Features added -------------- * Support for CPython 3.4. * Support for calling C++ template functions. * ``yield`` is supported in ``finally`` clauses. * The C code generated for finally blocks is duplicated for each exit case to allow for better optimisations by the C compiler. * Cython tries to undo the Python optimisationism of assigning a bound method to a local variable when it can generate better code for the direct call. * Constant Python float values are cached. * String equality comparisons can use faster type specific code in more cases than before. * String/Unicode formatting using the '%' operator uses a faster C-API call. * ``bytearray`` has become a known type and supports coercion from and to C strings. Indexing, slicing and decoding is optimised. Note that this may have an impact on existing code due to type inference. * Using ``cdef basestring stringvar`` and function arguments typed as ``basestring`` is now meaningful and allows assigning exactly ``str`` and ``unicode`` objects, but no subtypes of these types. * Support for the ``__debug__`` builtin. * Assertions in Cython compiled modules are disabled if the running Python interpreter was started with the "-O" option. * Some types that Cython provides internally, such as functions and generators, are now shared across modules if more than one Cython implemented module is imported. * The type inference algorithm works more fine granular by taking the results of the control flow analysis into account. * A new script in ``bin/cythonize`` provides a command line frontend to the cythonize() compilation function (including distutils build). * The new extension type decorator ``@cython.no_gc_clear`` prevents objects from being cleared during cyclic garbage collection, thus making sure that object attributes are kept alive until deallocation. * During cyclic garbage collection, attributes of extension types that cannot create reference cycles due to their type (e.g. strings) are no longer considered for traversal or clearing. This can reduce the processing overhead when searching for or cleaning up reference cycles. * Package compilation (i.e. ``__init__.py`` files) now works, starting with Python 3.3. * The cython-mode.el script for Emacs was updated. Patch by Ivan Andrus. * An option common_utility_include_dir was added to cythonize() to save oft-used utility code once in a separate directory rather than as part of each generated file. * ``unraisable_tracebacks`` directive added to control printing of tracebacks of unraisable exceptions. Bugs fixed ---------- * Abstract Python classes that subtyped a Cython extension type failed to raise an exception on instantiation, and thus ended up being instantiated. * ``set.add(a_tuple)`` and ``set.discard(a_tuple)`` failed with a TypeError in Py2.4. * The PEP 3155 ``__qualname__`` was incorrect for nested classes and inner classes/functions declared as ``global``. * Several corner cases in the try-finally statement were fixed. * The metaclass of a Python class was not inherited from its parent class(es). It is now extracted from the list of base classes if not provided explicitly using the Py3 ``metaclass`` keyword argument. In Py2 compilation mode, a ``__metaclass__`` entry in the class dict will still take precedence if not using Py3 metaclass syntax, but only *after* creating the class dict (which may have been done by a metaclass of a base class, see PEP 3115). It is generally recommended to use the explicit Py3 syntax to define metaclasses for Python types at compile time. * The automatic C switch statement generation behaves more safely for heterogeneous value types (e.g. mixing enum and char), allowing for a slightly wider application and reducing corner cases. It now always generates a 'default' clause to avoid C compiler warnings about unmatched enum values. * Fixed a bug where class hierarchies declared out-of-order could result in broken generated code. * Fixed a bug which prevented overriding const methods of C++ classes. * Fixed a crash when converting Python objects to C++ strings fails. Other changes ------------- * In Py3 compilation mode, Python2-style metaclasses declared by a ``__metaclass__`` class dict entry are ignored. * In Py3.4+, the Cython generator type uses ``tp_finalize()`` for safer cleanup instead of ``tp_del()``. 0.19.2 (2013-10-13) =================== Features added -------------- Bugs fixed ---------- * Some standard declarations were fixed or updated, including the previously incorrect declaration of ``PyBuffer_FillInfo()`` and some missing bits in ``libc.math``. * Heap allocated subtypes of ``type`` used the wrong base type struct at the C level. * Calling the unbound method dict.keys/value/items() in dict subtypes could call the bound object method instead of the unbound supertype method. * "yield" wasn't supported in "return" value expressions. * Using the "bint" type in memory views lead to unexpected results. It is now an error. * Assignments to global/closure variables could catch them in an illegal state while deallocating the old value. Other changes ------------- 0.19.1 (2013-05-11) =================== Features added -------------- * Completely empty C-API structs for extension type slots (protocols like number/mapping/sequence) are no longer generated into the C code. * Docstrings that directly follow a public/readonly attribute declaration in a cdef class will be used as docstring of the auto-generated property. This fixes ticket 206. * The automatic signature documentation tries to preserve more semantics of default arguments and argument types. Specifically, ``bint`` arguments now appear as type ``bool``. * A warning is emitted when negative literal indices are found inside of a code section that disables ``wraparound`` handling. This helps with fixing invalid code that might fail in the face of future compiler optimisations. * Constant folding for boolean expressions (and/or) was improved. * Added a build_dir option to cythonize() which allows one to place the generated .c files outside the source tree. Bugs fixed ---------- * ``isinstance(X, type)`` failed to get optimised into a call to ``PyType_Check()``, as done for other builtin types. * A spurious "from datetime cimport *" was removed from the "cpython" declaration package. This means that the "datetime" declarations (added in 0.19) are no longer available directly from the "cpython" namespace, but only from "cpython.datetime". This is the correct way of doing it because the declarations refer to a standard library module, not the core CPython C-API itself. * The C code for extension types is now generated in topological order instead of source code order to avoid C compiler errors about missing declarations for subtypes that are defined before their parent. * The ``memoryview`` type name no longer shows up in the module dict of modules that use memory views. This fixes trac ticket 775. * Regression in 0.19 that rejected valid C expressions from being used in C array size declarations. * In C++ mode, the C99-only keyword ``restrict`` could accidentally be seen by the GNU C++ compiler. It is now specially handled for both GCC and MSVC. * Testing large (> int) C integer values for their truth value could fail due to integer wrap-around. Other changes ------------- 0.19 (2013-04-19) ================= Features added -------------- * New directives ``c_string_type`` and ``c_string_encoding`` to more easily and automatically convert between C strings and the different Python string types. * The extension type flag ``Py_TPFLAGS_HAVE_VERSION_TAG`` is enabled by default on extension types and can be disabled using the ``type_version_tag`` compiler directive. * EXPERIMENTAL support for simple Cython code level line tracing. Enabled by the "linetrace" compiler directive. * Cython implemented functions make their argument and return type annotations available through the ``__annotations__`` attribute (PEP 3107). * Access to non-cdef module globals and Python object attributes is faster. * ``Py_UNICODE*`` coerces from and to Python unicode strings. This is helpful when talking to Windows APIs, which use compatible wchar_t arrays for strings. Note that the ``Py_UNICODE`` type is otherwise deprecated as of CPython 3.3. * ``isinstance(obj, basestring)`` is optimised. In Python 3 it only tests for instances of ``str`` (i.e. Py2 ``unicode``). * The ``basestring`` builtin is mapped to ``str`` (i.e. Py2 ``unicode``) when compiling the generated C code under Python 3. * Closures use freelists, which can speed up their creation quite substantially. This is also visible for short running generator expressions, for example. * A new class decorator ``@cython.freelist(N)`` creates a static freelist of N instances for an extension type, thus avoiding the costly allocation step if possible. This can speed up object instantiation by 20-30% in suitable scenarios. Note that freelists are currently only supported for base types, not for types that inherit from others. * Fast extension type instantiation using the ``Type.__new__(Type)`` idiom has gained support for passing arguments. It is also a bit faster for types defined inside of the module. * The Python2-only dict methods ``.iter*()`` and ``.view*()`` (requires Python 2.7) are automatically mapped to the equivalent keys/values/items methods in Python 3 for typed dictionaries. * Slicing unicode strings, lists and tuples is faster. * list.append() is faster on average. * ``raise Exception() from None`` suppresses the exception context in Py3.3. * Py3 compatible ``exec(tuple)`` syntax is supported in Py2 code. * Keyword arguments are supported for cdef functions. * External C++ classes can be declared nogil. Patch by John Stumpo. This fixes trac ticket 805. Bugs fixed ---------- * 2-value slicing of unknown objects passes the correct slice when the ``getitem`` protocol is used instead of the ``getslice`` protocol (especially in Python 3), i.e. ``None`` values for missing bounds instead of ``[0,maxsize]``. It is also a bit faster in some cases, e.g. for constant bounds. This fixes trac ticket 636. * Cascaded assignments of None values to extension type variables failed with a ``TypeError`` at runtime. * The ``__defaults__`` attribute was not writable for Cython implemented functions. * Default values of keyword-only arguments showed up in ``__defaults__`` instead of ``__kwdefaults__`` (which was not implemented). Both are available for Cython implemented functions now, as specified in Python 3.x. * ``yield`` works inside of ``with gil`` sections. It previously lead to a crash. This fixes trac ticket 803. * Static methods without explicitly named positional arguments (e.g. having only ``*args``) crashed when being called. This fixes trac ticket 804. * ``dir()`` without arguments previously returned an unsorted list, which now gets sorted as expected. * ``dict.items()``, ``dict.keys()`` and ``dict.values()`` no longer return lists in Python 3. * Exiting from an ``except-as`` clause now deletes the exception in Python 3 mode. * The declarations of ``frexp()`` and ``ldexp()`` in ``math.pxd`` were incorrect. Other changes ------------- 0.18 (2013-01-28) ================= Features added -------------- * Named Unicode escapes ("\N{...}") are supported. * Python functions/classes provide the special attribute "__qualname__" as defined by PEP 3155. * Added a directive ``overflowcheck`` which raises an OverflowException when arithmetic with C ints overflow. This has a modest performance penalty, but is much faster than using Python ints. * Calls to nested Python functions are resolved at compile time. * Type inference works across nested functions. * ``py_bytes_string.decode(...)`` is optimised. * C ``const`` declarations are supported in the language. Bugs fixed ---------- * Automatic C++ exception mapping didn't work in nogil functions (only in "with nogil" blocks). Other changes ------------- 0.17.4 (2013-01-03) =================== Bugs fixed ---------- * Garbage collection triggered during deallocation of container classes could lead to a double-deallocation. 0.17.3 (2012-12-14) =================== Features added -------------- Bugs fixed ---------- * During final interpreter cleanup (with types cleanup enabled at compile time), extension types that inherit from base types over more than one level that were cimported from other modules could lead to a crash. * Weak-reference support in extension types (with a ``cdef __weakref__`` attribute) generated incorrect deallocation code. * In CPython 3.3, converting a Unicode character to the Py_UNICODE type could fail to raise an overflow for non-BMP characters that do not fit into a wchar_t on the current platform. * Negative C integer constants lost their longness suffix in the generated C code. Other changes ------------- 0.17.2 (2012-11-20) =================== Features added -------------- * ``cythonize()`` gained a best effort compile mode that can be used to simply ignore .py files that fail to compile. Bugs fixed ---------- * Replacing an object reference with the value of one of its cdef attributes could generate incorrect C code that accessed the object after deleting its last reference. * C-to-Python type coercions during cascaded comparisons could generate invalid C code, specifically when using the 'in' operator. * "obj[1,]" passed a single integer into the item getter instead of a tuple. * Cyclic imports at module init time did not work in Py3. * The names of C++ destructors for template classes were built incorrectly. * In pure mode, type casts in Cython syntax and the C ampersand operator are now rejected. Use the pure mode replacements instead. * In pure mode, C type names and the sizeof() function are no longer recognised as such and can be used as normal Python names. * The extended C level support for the CPython array type was declared too late to be used by user defined classes. * C++ class nesting was broken. * Better checking for required nullary constructors for stack-allocated C++ instances. * Remove module docstring in no-docstring mode. * Fix specialization for varargs function signatures. * Fix several compiler crashes. Other changes ------------- * An experimental distutils script for compiling the CPython standard library was added as Tools/cystdlib.py. 0.17.1 (2012-09-26) =================== Features added -------------- Bugs fixed ---------- * A reference leak was fixed in the new dict iteration code when the loop target was not a plain variable but an unpacked tuple. * Memory views did not handle the special case of a NULL buffer strides value, as allowed by PEP3118. Other changes ------------- 0.17 (2012-09-01) ================= Features added -------------- * Alpha quality support for compiling and running Cython generated extension modules in PyPy (through cpyext). Note that this requires at least PyPy 1.9 and in many cases also adaptations in user code, especially to avoid borrowed references when no owned reference is being held directly in C space (a reference in a Python list or dict is not enough, for example). See the documentation on porting Cython code to PyPy. * "yield from" is supported (PEP 380) and a couple of minor problems with generators were fixed. * C++ STL container classes automatically coerce from and to the equivalent Python container types on typed assignments and casts. Note that the data in the containers is copied during this conversion. * C++ iterators can now be iterated over using "for x in cpp_container" whenever cpp_container has begin() and end() methods returning objects satisfying the iterator pattern (that is, it can be incremented, dereferenced, and compared (for non-equality)). * cdef classes can now have C++ class members (provided a zero-argument constructor exists) * A new cpython.array standard cimport file allows to efficiently talk to the stdlib array.array data type in Python 2. Since CPython does not export an official C-API for this module, it receives special casing by the compiler in order to avoid setup overhead on user side. In Python 3, both buffers and memory views on the array type already worked out of the box with earlier versions of Cython due to the native support for the buffer interface in the Py3 array module. * Fast dict iteration is now enabled optimistically also for untyped variables when the common iteration methods are used. * The unicode string processing code was adapted for the upcoming CPython 3.3 (PEP 393, new Unicode buffer layout). * Buffer arguments and memory view arguments in Python functions can be declared "not None" to raise a TypeError on None input. * c(p)def functions in pure mode can specify their return type with "@cython.returns()". * Automatic dispatch for fused functions with memoryview arguments * Support newaxis indexing for memoryviews * Support decorators for fused functions Bugs fixed ---------- * Old-style Py2 imports did not work reliably in Python 3.x and were broken in Python 3.3. Regardless of this fix, it's generally best to be explicit about relative and global imports in Cython code because old-style imports have a higher overhead. To this end, "from __future__ import absolute_import" is supported in Python/Cython 2.x code now (previous versions of Cython already used it when compiling Python 3 code). * Stricter constraints on the "inline" and "final" modifiers. If your code does not compile due to this change, chances are these modifiers were previously being ignored by the compiler and can be removed without any performance regression. * Exceptions are always instantiated while raising them (as in Python), instead of risking to instantiate them in potentially unsafe situations when they need to be handled or otherwise processed. * locals() properly ignores names that do not have Python compatible types (including automatically inferred types). * Some garbage collection issues of memory views were fixed. * numpy.pxd compiles in Python 3 mode. * Several C compiler warnings were fixed. * Several bugs related to memoryviews and fused types were fixed. * Several bug-fixes and improvements related to cythonize(), including ccache-style caching. Other changes ------------- * libc.string provides a convenience declaration for const uchar in addition to const char. * User declared char* types are now recognised as such and auto-coerce to and from Python bytes strings. * callable() and next() compile to more efficient C code. * list.append() is faster on average. * Modules generated by @cython.inline() are written into the directory pointed to by the environment variable CYTHON_CACHE_DIR if set. 0.16 (2012-04-21) ================= Features added -------------- * Enhancements to Cython's function type (support for weak references, default arguments, code objects, dynamic attributes, classmethods, staticmethods, and more) * Fused Types - Template-like support for functions and methods CEP 522 (docs) * Typed views on memory - Support for efficient direct and indirect buffers (indexing, slicing, transposing, ...) CEP 517 (docs) * super() without arguments * Final cdef methods (which translate into direct calls on known instances) Bugs fixed ---------- * fix alignment handling for record types in buffer support Other changes ------------- * support default arguments for closures * search sys.path for pxd files * support C++ template casting * faster traceback building and faster generator termination * support inplace operators on indexed buffers * allow nested prange sections 0.15.1 (2011-09-19) =================== Features added -------------- Bugs fixed ---------- Other changes ------------- 0.15 (2011-08-05) ================= Features added -------------- * Generators (yield) - Cython has full support for generators, generator expressions and PEP 342 coroutines. * The nonlocal keyword is supported. * Re-acquiring the gil: with gil - works as expected within a nogil context. * OpenMP support: prange. * Control flow analysis prunes dead code and emits warnings and errors about uninitialised variables. * Debugger command cy set to assign values of expressions to Cython variables and cy exec counterpart $cy_eval(). * Exception chaining PEP 3134. * Relative imports PEP 328. * Improved pure syntax including cython.cclass, cython.cfunc, and cython.ccall. * The with statement has its own dedicated and faster C implementation. * Support for del. * Boundschecking directives implemented for builtin Python sequence types. * Several updates and additions to the shipped standard library .pxd files. * Forward declaration of types is no longer required for circular references. Bugs fixed ---------- Other changes ------------- * Uninitialized variables are no longer initialized to None and accessing them has the same semantics as standard Python. * globals() now returns a read-only dict of the Cython module's globals, rather than the globals of the first non-Cython module in the stack * Many C++ exceptions are now special cased to give closer Python counterparts. This means that except+ functions that formerly raised generic RuntimeErrors may raise something else such as ArithmeticError. * The inlined generator expressions (introduced in Cython 0.13) were disabled in favour of full generator expression support. This breaks code that previously used them inside of cdef functions (usage in def functions continues to work) and induces a performance regression for cases that continue to work but that were previously inlined. We hope to reinstate this feature in the near future. 0.14.1 (2011-02-04) =================== Features added -------------- * The gdb debugging support was extended to include all major Cython features, including closures. * raise MemoryError() is now safe to use as Cython replaces it with the correct C-API call. Bugs fixed ---------- Other changes ------------- * Decorators on special methods of cdef classes now raise a compile time error rather than being ignored. * In Python 3 language level mode (-3 option), the 'str' type is now mapped to 'unicode', so that cdef str s declares a Unicode string even when running in Python 2. 0.14 (2010-12-14) ================= Features added -------------- * Python classes can now be nested and receive a proper closure at definition time. * Redefinition is supported for Python functions, even within the same scope. * Lambda expressions are supported in class bodies and at the module level. * Metaclasses are supported for Python classes, both in Python 2 and Python 3 syntax. The Python 3 syntax (using a keyword argument in the type declaration) is preferred and optimised at compile time. * "final" extension classes prevent inheritance in Python space. This feature is available through the new "cython.final" decorator. In the future, these classes may receive further optimisations. * "internal" extension classes do not show up in the module dictionary. This feature is available through the new "cython.internal" decorator. * Extension type inheritance from builtin types, such as "cdef class MyUnicode(unicode)", now works without further external type redeclarations (which are also strongly discouraged now and continue to issue a warning). * GDB support. http://docs.cython.org/src/userguide/debugging.html * A new build system with support for inline distutils directives, correct dependency tracking, and parallel compilation. http://wiki.cython.org/enhancements/distutils_preprocessing * Support for dynamic compilation at runtime via the new cython.inline function and cython.compile decorator. http://wiki.cython.org/enhancements/inline * "nogil" blocks are supported when compiling pure Python code by writing "with cython.nogil". * Iterating over arbitrary pointer types is now supported, as is an optimized version of the in operator, e.g. x in ptr[a:b]. Bugs fixed ---------- * In parallel assignments, the right side was evaluated in reverse order in 0.13. This could result in errors if it had side effects (e.g. function calls). * In some cases, methods of builtin types would raise a SystemError instead of an AttributeError when called on None. Other changes ------------- * Constant tuples are now cached over the lifetime of an extension module, just like CPython does. Constant argument tuples of Python function calls are also cached. * Closures have tightened to include exactly the names used in the inner functions and classes. Previously, they held the complete locals of the defining function. * The builtin "next()" function in Python 2.6 and later is now implemented internally and therefore available in all Python versions. This makes it the preferred and portable way of manually advancing an iterator. * In addition to the previously supported inlined generator expressions in 0.13, "sorted(genexpr)" can now be used as well. Typing issues were fixed in "sum(genexpr)" that could lead to invalid C code being generated. Other known issues with inlined generator expressions were also fixed that make upgrading to 0.14 a strong recommendation for code that uses them. Note that general generators and generator expressions continue to be not supported. * Inplace arithmetic operators now respect the cdivision directive and are supported for complex types. * Typing a variable as type "complex" previously gave it the Python object type. It now uses the appropriate C/C++ double complex type. A side-effect is that assignments and typed function parameters now accept anything that Python can coerce to a complex, including integers and floats, and not only complex instances. * Large integer literals pass through the compiler in a safer way. To prevent truncation in C code, non 32-bit literals are turned into Python objects if not used in a C context. This context can either be given by a clear C literal suffix such as "UL" or "LL" (or "L" in Python 3 code), or it can be an assignment to a typed variable or a typed function argument, in which case it is up to the user to take care of a sufficiently large value space of the target. * Python functions are declared in the order they appear in the file, rather than all being created at module creation time. This is consistent with Python and needed to support, for example, conditional or repeated declarations of functions. In the face of circular imports this may cause code to break, so a new --disable-function-redefinition flag was added to revert to the old behavior. This flag will be removed in a future release, so should only be used as a stopgap until old code can be fixed. 0.13 (2010-08-25) ================= Features added -------------- * Closures are fully supported for Python functions. Cython supports inner functions and lambda expressions. Generators and generator expressions are not supported in this release. * Proper C++ support. Cython knows about C++ classes, templates and overloaded function signatures, so that Cython code can interact with them in a straight forward way. * Type inference is enabled by default for safe C types (e.g. double, bint, C++ classes) and known extension types. This reduces the need for explicit type declarations and can improve the performance of untyped code in some cases. There is also a verbose compile mode for testing the impact on user code. * Cython's for-in-loop can iterate over C arrays and sliced pointers. The type of the loop variable will be inferred automatically in this case. * The Py_UNICODE integer type for Unicode code points is fully supported, including for-loops and 'in' tests on unicode strings. It coerces from and to single character unicode strings. Note that untyped for-loop variables will automatically be inferred as Py_UNICODE when iterating over a unicode string. In most cases, this will be much more efficient than yielding sliced string objects, but can also have a negative performance impact when the variable is used in a Python context multiple times, so that it needs to coerce to a unicode string object more than once. If this happens, typing the loop variable as unicode or object will help. * The built-in functions any(), all(), sum(), list(), set() and dict() are inlined as plain for loops when called on generator expressions. Note that generator expressions are not generally supported apart from this feature. Also, tuple(genexpr) is not currently supported - use tuple([listcomp]) instead. * More shipped standard library declarations. The python_* and stdlib/stdio .pxd files have been deprecated in favor of clib.* and cpython[.*] and may get removed in a future release. * Pure Python mode no longer disallows non-Python keywords like 'cdef', 'include' or 'cimport'. It also no longer recognises syntax extensions like the for-from loop. * Parsing has improved for Python 3 syntax in Python code, although not all features are correctly supported. The missing Python 3 features are being worked on for the next release. * from __future__ import print_function is supported in Python 2.6 and later. Note that there is currently no emulation for earlier Python versions, so code that uses print() with this future import will require at least Python 2.6. * New compiler directive language_level (valid values: 2 or 3) with corresponding command line options -2 and -3 requests source code compatibility with Python 2.x or Python 3.x respectively. Language level 3 currently enforces unicode literals for unprefixed string literals, enables the print function (requires Python 2.6 or later) and keeps loop variables in list comprehensions from leaking. * Loop variables in set/dict comprehensions no longer leak into the surrounding scope (following Python 2.7). List comprehensions are unchanged in language level 2. * print >> stream Bugs fixed ---------- Other changes ------------- * The availability of type inference by default means that Cython will also infer the type of pointers on assignments. Previously, code like this:: cdef char* s = ... untyped_variable = s would convert the char* to a Python bytes string and assign that. This is no longer the case and no coercion will happen in the example above. The correct way of doing this is through an explicit cast or by typing the target variable, i.e. :: cdef char* s = ... untyped_variable1 = s untyped_variable2 = s cdef object py_object = s cdef bytes bytes_string = s * bool is no longer a valid type name by default. The problem is that it's not clear whether bool should refer to the Python type or the C++ type, and expecting one and finding the other has already led to several hard-to-find bugs. Both types are available for importing: you can use from cpython cimport bool for the Python bool type, and from libcpp cimport bool for the C++ type. bool is still a valid object by default, so one can still write bool(x). * ``__getsegcount__`` is now correctly typed to take a ``Py_size_t*`` rather than an ``int*``. 0.12.1 (2010-02-02) =================== Features added -------------- * Type inference improvements. * There have been several bug fixes and improvements to the type inferencer. * Notably, there is now a "safe" mode enabled by setting the infer_types directive to None. (The None here refers to the "default" mode, which will be the default in 0.13.) This safe mode limits inference to Python object types and C doubles, which should speed up execution without affecting any semantics such as integer overflow behavior like infer_types=True might. There is also an infer_types.verbose option which allows one to see what types are inferred. * The boundscheck directive works for lists and tuples as well as buffers. * len(s) and s.decode("encoding") are efficiently supported for char* s. * Cython's INLINE macro has been renamed to CYTHON_INLINE to reduce conflict and has better support for the MSVC compiler on Windows. It is no longer clobbered if externally defined. * Revision history is now omitted from the source package, resulting in a 85% size reduction. Running make repo will download the history and turn the directory into a complete Mercurial working repository. * Cython modules don't need to be recompiled when the size of an external type grows. (A warning, rather than an error, is produced.) This should be helpful for binary distributions relying on NumPy. Bugs fixed ---------- * Several other bugs and minor improvements have been made. This release should be fully backwards compatible with 0.12. Other changes ------------- 0.12 (2009-11-23) ================= Features added -------------- * Type inference with the infer_types directive * Seamless C++ complex support * Fast extension type instantiation using the normal Python meme obj = MyType.__new__(MyType) * Improved support for Py3.1 * Cython now runs under Python 3.x using the 2to3 tool * unittest support for doctests in Cython modules * Optimised handling of C strings (char*): for c in cstring[2:50] and cstring.decode() * Looping over c pointers: for i in intptr[:50]. * pyximport improvements * cython_freeze improvements Bugs fixed ---------- * Many bug fixes Other changes ------------- * Many other optimisation, e.g. enumerate() loops, parallel swap assignments (a,b = b,a), and unicode.encode() * More complete numpy.pxd 0.11.2 (2009-05-20) =================== Features added -------------- * There's now native complex floating point support! C99 complex will be used if complex.h is included, otherwise explicit complex arithmetic working on all C compilers is used. [Robert Bradshaw] :: cdef double complex a = 1 + 0.3j cdef np.ndarray[np.complex128_t, ndim=2] arr = \ np.zeros(10, np.complex128) * Cython can now generate a main()-method for embedding of the Python interpreter into an executable (see #289) [Robert Bradshaw] * @wraparound directive (another way to disable arr[idx] for negative idx) [Dag Sverre Seljebotn] * Correct support for NumPy record dtypes with different alignments, and "cdef packed struct" support [Dag Sverre Seljebotn] * @callspec directive, allowing custom calling convention macros [Lisandro Dalcin] Bugs fixed ---------- Other changes ------------- * Bug fixes and smaller improvements. For the full list, see [1]. Cython-0.23.4/2to3-fixers.txt0000644000175600017570000000003212606202452017025 0ustar jenkinsjenkins00000000000000lib2to3.fixes.fix_unicode Cython-0.23.4/.gitrev0000644000175600017570000000005112606202454015503 0ustar jenkinsjenkins00000000000000dc00a176d896f0df892aad8b305d946d3ed632a0 Cython-0.23.4/tests/0000755000175600017570000000000012606202455015351 5ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/pypy_bugs.txt0000644000175600017570000000173012606202452020131 0ustar jenkinsjenkins00000000000000# This file contains tests corresponding to unresolved bugs # either in PyPy, PyPy's cpyext, or Cython under PyPy, # which will be skipped in the normal testing run. broken_exception bufaccess exarkun memoryview memslice sequential_parallel setjmp yield_from_pep380 memoryview_inplace_division # GIL issues # https://bitbucket.org/pypy/pypy/issue/2025/cpyext-finish-implementation-of run.exceptions_nogil run.nogil run.with_gil run.parallel # gc issue? memoryview_in_subclasses external_ref_reassignment run.exttype_dealloc # https://bitbucket.org/pypy/pypy/issue/2023/cpyext-pydict_keys-values-items-does-not builtin_subtype_methods_cy3 # bugs in cpyext run.special_methods_T561 run.special_methods_T561_py2 # tests for things that don't exist in cpyext compile.pylong run.datetime_pxd run.datetime_cimport run.datetime_members run.extern_builtins_T258 run.unicode_ascii_auto_encoding run.unicode_default_auto_encoding run.str_ascii_auto_encoding run.str_default_auto_encoding Cython-0.23.4/tests/bugs.txt0000644000175600017570000000273412606202452017055 0ustar jenkinsjenkins00000000000000# This file contains tests corresponding to unresolved bugs, # which will be skipped in the normal testing run. class_attribute_init_values_T18 unsignedbehaviour_T184 missing_baseclass_in_predecl_T262 cfunc_call_tuple_args_T408 cpp_structs genexpr_iterable_lookup_T600 generator_expressions_in_class for_from_pyvar_loop_T601 temp_sideeffects_T654 # not really a bug, Cython warns about it inherited_final_method tryfinallychaining # also see FIXME in "yield_from_pep380" test cimport_alias_subclass # CPython regression tests that don't current work: pyregr.test_signal pyregr.test_capi pyregr.test_socket pyregr.test_sys pyregr.test_pep3131 pyregr.test_multiprocessing pyregr.test_tempfile pyregr.test_ioctl # CPython regression tests with threading issues pyregr.test_threadsignals pyregr.test_threading pyregr.test_threaded_import pyregr.test_logging # CPython regression tests that don't make sense pyregr.test_gdb pyregr.test_support pyregr.test_peepholer # the atexit test runs the registered atexit functions => module cleanup => crash pyregr.test_atexit # a settrace test bypasses a with statement and currently crashes pyregr.test_sys_settrace # tests for exception on infinite recursion - may crash with stack overflow when calling C function pyregr.test_exceptions # CPython regression tests that take too long pyregr.test_subprocess pyregr.test_zipfile64 pyregr.test_tuple pyregr.test_urllib2net pyregr.test_urllibnet # Inlined generators inlined_generator_expressions Cython-0.23.4/tests/wrappers/0000755000175600017570000000000012606202455017214 5ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/wrappers/cppwrap_lib.pxd0000644000175600017570000000061012606202452022225 0ustar jenkinsjenkins00000000000000cdef extern from "cppwrap_lib.cpp": pass cdef extern from "cppwrap_lib.h": void voidfunc() double doublefunc(double a, double b, double c) cdef cppclass DoubleKeeper: DoubleKeeper(double factor) void set_number(double f) double get_number() double transmogrify(double value) double transmogrify_from_cpp (DoubleKeeper *obj, double value) Cython-0.23.4/tests/wrappers/cppwrap_lib.h0000644000175600017570000000066112606202452021667 0ustar jenkinsjenkins00000000000000#ifndef CPPWRAP_LIB_H #define CPPWRAP_LIB_H void voidfunc(void); double doublefunc (double a, double b, double c); class DoubleKeeper { double number; public: DoubleKeeper (double number); virtual ~DoubleKeeper (); void set_number (double num); double get_number () const; virtual double transmogrify (double value) const; }; double transmogrify_from_cpp (DoubleKeeper const *obj, double value); #endif Cython-0.23.4/tests/wrappers/cppwrap_lib.cpp0000644000175600017570000000106012606202452022214 0ustar jenkinsjenkins00000000000000 #include "cppwrap_lib.h" void voidfunc (void) { } double doublefunc (double a, double b, double c) { return a + b + c; } DoubleKeeper::DoubleKeeper (double factor) : number (factor) { } DoubleKeeper::~DoubleKeeper () { } double DoubleKeeper::get_number () const { return number; } void DoubleKeeper::set_number (double f) { number = f; } double DoubleKeeper::transmogrify (double value) const { return value*number; } double transmogrify_from_cpp (DoubleKeeper const *obj, double value) { return obj->transmogrify (value); } Cython-0.23.4/tests/wrappers/cppwrap.pyx0000644000175600017570000000225312606202452021431 0ustar jenkinsjenkins00000000000000# tag: cpp cimport cppwrap_lib cdef class DoubleKeeper: """ >>> d = DoubleKeeper(1.0) >>> d.get_number() == 1.0 True >>> d.get_number() == 2.0 False >>> d.set_number(2.0) >>> d.get_number() == 2.0 True >>> d.transmogrify(3.0) == 6.0 True """ cdef cppwrap_lib.DoubleKeeper* keeper def __cinit__(self, double number): self.keeper = new cppwrap_lib.DoubleKeeper(number) def __dealloc__(self): del self.keeper def set_number(self, double number): self.keeper.set_number(number) def get_number(self): return self.keeper.get_number() def transmogrify(self, double value): return self.keeper.transmogrify(value) def voidfunc(): """ >>> voidfunc() """ cppwrap_lib.voidfunc() def doublefunc(double x, double y, double z): """ >>> doublefunc(1.0, 2.0, 3.0) == 1.0 + 2.0 + 3.0 True """ return cppwrap_lib.doublefunc(x, y, z) def transmogrify_from_cpp(DoubleKeeper obj not None, double value): """ >>> d = DoubleKeeper(2.0) >>> d.transmogrify(3.0) == 6.0 True """ return cppwrap_lib.transmogrify_from_cpp(obj.keeper, value) Cython-0.23.4/tests/wrappers/cpp_references_helper.h0000644000175600017570000000013412606202452023702 0ustar jenkinsjenkins00000000000000 int ref_var_value = 10; int& ref_var = ref_var_value; int& ref_func(int& x) { return x; } Cython-0.23.4/tests/wrappers/cpp_references.pyx0000644000175600017570000000177012606202452022743 0ustar jenkinsjenkins00000000000000# tag: cpp cimport cython cdef extern from "cpp_references_helper.h": cdef int& ref_func(int&) cdef int ref_var_value cdef int& ref_var def test_ref_func(int x): """ >>> test_ref_func(2) 2 >>> test_ref_func(3) 3 """ return ref_func(x) def test_ref_func_address(int x): """ >>> test_ref_func_address(5) 5 >>> test_ref_func_address(7) 7 """ cdef int* i_ptr = &ref_func(x) return i_ptr[0] def test_ref_var(int x): """ >>> test_ref_func(11) 11 >>> test_ref_func(13) 13 """ ref_var = x return ref_var_value def test_ref_assign(int x): """ >>> test_ref_assign(17) 17.0 >>> test_ref_assign(19) 19.0 """ cdef double d = ref_func(x) return d @cython.infer_types(True) def test_ref_inference(int x): """ >>> test_ref_inference(23) 23 >>> test_ref_inference(29) 29 """ z = ref_func(x) assert cython.typeof(z) == "int", cython.typeof(z) return z Cython-0.23.4/tests/wrappers/cpp_overload_wrapper_lib.pxd0000644000175600017570000000072312606202452024773 0ustar jenkinsjenkins00000000000000cdef extern from "cpp_overload_wrapper_lib.cpp": pass cdef extern from "cpp_overload_wrapper_lib.h": void voidfunc() double doublefunc(double a, double b, double c) cdef cppclass DoubleKeeper: DoubleKeeper() DoubleKeeper(double factor) void set_number() void set_number(double f) double get_number() double transmogrify(double value) double transmogrify_from_cpp (DoubleKeeper *obj, double value) Cython-0.23.4/tests/wrappers/cpp_overload_wrapper_lib.h0000644000175600017570000000077412606202452024435 0ustar jenkinsjenkins00000000000000#ifndef CPP_OVERLOAD_WRAPPER_LIB_H #define CPP_OVERLOAD_WRAPPER_LIB_H void voidfunc(void); double doublefunc (double a, double b, double c); class DoubleKeeper { double number; public: DoubleKeeper (); DoubleKeeper (double number); virtual ~DoubleKeeper (); void set_number (double num); void set_number (void); double get_number () const; virtual double transmogrify (double value) const; }; double transmogrify_from_cpp (DoubleKeeper const *obj, double value); #endif Cython-0.23.4/tests/wrappers/cpp_overload_wrapper_lib.cpp0000644000175600017570000000125412606202452024762 0ustar jenkinsjenkins00000000000000 #include "cpp_overload_wrapper_lib.h" void voidfunc (void) { } double doublefunc (double a, double b, double c) { return a + b + c; } DoubleKeeper::DoubleKeeper () : number (1.0) { } DoubleKeeper::DoubleKeeper (double factor) : number (factor) { } DoubleKeeper::~DoubleKeeper () { } double DoubleKeeper::get_number () const { return number; } void DoubleKeeper::set_number (double f) { number = f; } void DoubleKeeper::set_number () { number = 1.0; } double DoubleKeeper::transmogrify (double value) const { return value*number; } double transmogrify_from_cpp (DoubleKeeper const *obj, double value) { return obj->transmogrify (value); } Cython-0.23.4/tests/wrappers/cpp_overload_wrapper.pyx0000644000175600017570000000273612606202452024200 0ustar jenkinsjenkins00000000000000# tag: cpp cimport cpp_overload_wrapper_lib as cppwrap_lib cdef class DoubleKeeper: """ >>> d = DoubleKeeper() >>> d.get_number() 1.0 >>> d.set_number(5.5) >>> d.get_number() 5.5 >>> d.set_number(0) >>> d.get_number() 0.0 """ cdef cppwrap_lib.DoubleKeeper* keeper def __cinit__(self, number=None): if number is None: self.keeper = new cppwrap_lib.DoubleKeeper() else: self.keeper = new cppwrap_lib.DoubleKeeper(number) def __dealloc__(self): del self.keeper def set_number(self, number=None): if number is None: self.keeper.set_number() else: self.keeper.set_number(number) def get_number(self): return self.keeper.get_number() def transmogrify(self, double value): """ >>> d = DoubleKeeper(5.5) >>> d.transmogrify(1.0) 5.5 >>> d.transmogrify(2.0) 11.0 """ return self.keeper.transmogrify(value) def voidfunc(): """ >>> voidfunc() """ cppwrap_lib.voidfunc() def doublefunc(double x, double y, double z): """ >>> doublefunc(1.0, 2.0, 3.0) == 1.0 + 2.0 + 3.0 True """ return cppwrap_lib.doublefunc(x, y, z) def transmogrify_from_cpp(DoubleKeeper obj not None, double value): """ >>> d = DoubleKeeper(2.0) >>> d.transmogrify(3.0) == 6.0 True """ return cppwrap_lib.transmogrify_from_cpp(obj.keeper, value) Cython-0.23.4/tests/testsupport/0000755000175600017570000000000012606202455017765 5ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/testsupport/cythonarrayutil.pxi0000644000175600017570000000134312606202452023746 0ustar jenkinsjenkins00000000000000from libc.stdlib cimport malloc, free cimport cython from cython.view cimport array cdef void callback(void *data): print "callback called" free(data) def create_array(shape, mode, use_callback=False): cdef array result = array(shape, itemsize=sizeof(int), format='i', mode=mode) cdef int *data = result.data cdef int i, j, cidx, fidx for i in range(shape[0]): for j in range(shape[1]): cidx = i * shape[1] + j fidx = i + j * shape[0] if mode == 'fortran': data[fidx] = cidx else: data[cidx] = cidx if use_callback: result.callback_free_data = callback return result Cython-0.23.4/tests/run/0000755000175600017570000000000012606202455016155 5ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/run/yield_inside_lambda.py0000644000175600017570000000041212606202452022462 0ustar jenkinsjenkins00000000000000# mode: run # tag: generators, lambda def test_inside_lambda(): """ >>> obj = test_inside_lambda()() >>> next(obj) 1 >>> next(obj) 2 >>> try: next(obj) ... except StopIteration: pass """ return lambda:((yield 1), (yield 2)) Cython-0.23.4/tests/run/yield_from_py33.pyx0000644000175600017570000000065512606202452021731 0ustar jenkinsjenkins00000000000000# mode: run # tag: generator def yield_from_gen(values): """ >>> def yf(x): yield from x >>> list(yf(yield_from_gen([1, 2, 3, 4]))) [1, 2, 3, 4] """ for value in values: yield value def yield_from_gen_return(values): """ >>> def yf(x): yield from x >>> list(yf(yield_from_gen_return([1, 2, 3, 4]))) [1, 2, 3, 4] """ for value in values: yield value return 5 Cython-0.23.4/tests/run/yield_from_pep380.pyx0000644000175600017570000006170512606202452022155 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- """ Test suite for PEP 380 implementation adapted from original tests written by Greg Ewing see """ import sys def _lines(trace): for line in trace: print(line) def test_delegation_of_initial_next_to_subgenerator(): """ >>> _lines(test_delegation_of_initial_next_to_subgenerator()) Starting g1 Starting g2 Yielded 42 Finishing g2 Finishing g1 """ trace = [] def g1(): trace.append("Starting g1") yield from g2() trace.append("Finishing g1") def g2(): trace.append("Starting g2") yield 42 trace.append("Finishing g2") for x in g1(): trace.append("Yielded %s" % (x,)) return trace def test_raising_exception_in_initial_next_call(): """ >>> _lines(test_raising_exception_in_initial_next_call()) Starting g1 Starting g2 Finishing g2 Finishing g1 """ trace = [] def g1(): try: trace.append("Starting g1") yield from g2() finally: trace.append("Finishing g1") def g2(): try: trace.append("Starting g2") raise ValueError("spanish inquisition occurred") finally: trace.append("Finishing g2") try: for x in g1(): trace.append("Yielded %s" % (x,)) except ValueError as e: pass else: trace.append("subgenerator failed to raise ValueError") return trace def test_delegation_of_next_call_to_subgenerator(): """ >>> _lines(test_delegation_of_next_call_to_subgenerator()) Starting g1 Yielded g1 ham Starting g2 Yielded g2 spam Yielded g2 more spam Finishing g2 Yielded g1 eggs Finishing g1 """ trace = [] def g1(): trace.append("Starting g1") yield "g1 ham" yield from g2() yield "g1 eggs" trace.append("Finishing g1") def g2(): trace.append("Starting g2") yield "g2 spam" yield "g2 more spam" trace.append("Finishing g2") for x in g1(): trace.append("Yielded %s" % (x,)) return trace def test_raising_exception_in_delegated_next_call(): """ >>> _lines(test_raising_exception_in_delegated_next_call()) Starting g1 Yielded g1 ham Starting g2 Yielded g2 spam Finishing g2 Finishing g1 """ trace = [] def g1(): try: trace.append("Starting g1") yield "g1 ham" yield from g2() yield "g1 eggs" finally: trace.append("Finishing g1") def g2(): try: trace.append("Starting g2") yield "g2 spam" raise ValueError("hovercraft is full of eels") yield "g2 more spam" finally: trace.append("Finishing g2") try: for x in g1(): trace.append("Yielded %s" % (x,)) except ValueError: pass else: trace.append("subgenerator failed to raise ValueError") return trace def test_delegation_of_send(): """ >>> _lines(test_delegation_of_send()) Starting g1 g1 received 1 Starting g2 Yielded g2 spam g2 received 2 Yielded g2 more spam g2 received 3 Finishing g2 Yielded g1 eggs g1 received 4 Finishing g1 """ trace = [] def g1(): trace.append("Starting g1") x = yield "g1 ham" trace.append("g1 received %s" % (x,)) yield from g2() x = yield "g1 eggs" trace.append("g1 received %s" % (x,)) trace.append("Finishing g1") def g2(): trace.append("Starting g2") x = yield "g2 spam" trace.append("g2 received %s" % (x,)) x = yield "g2 more spam" trace.append("g2 received %s" % (x,)) trace.append("Finishing g2") g = g1() y = next(g) x = 1 try: while 1: y = g.send(x) trace.append("Yielded %s" % (y,)) x += 1 except StopIteration: pass return trace def test_handling_exception_while_delegating_send(): """ >>> _lines(test_handling_exception_while_delegating_send()) Starting g1 g1 received 1 Starting g2 Yielded g2 spam g2 received 2 """ trace = [] def g1(): trace.append("Starting g1") x = yield "g1 ham" trace.append("g1 received %s" % (x,)) yield from g2() x = yield "g1 eggs" trace.append("g1 received %s" % (x,)) trace.append("Finishing g1") def g2(): trace.append("Starting g2") x = yield "g2 spam" trace.append("g2 received %s" % (x,)) raise ValueError("hovercraft is full of eels") x = yield "g2 more spam" trace.append("g2 received %s" % (x,)) trace.append("Finishing g2") def run(): g = g1() y = next(g) x = 1 try: while 1: y = g.send(x) trace.append("Yielded %s" % (y,)) x += 1 except StopIteration: trace.append("StopIteration") try: run() except ValueError: pass # ok else: trace.append("no ValueError") return trace def test_delegating_close(): """ >>> _lines(test_delegating_close()) Starting g1 Yielded g1 ham Starting g2 Yielded g2 spam Finishing g2 Finishing g1 """ trace = [] def g1(): try: trace.append("Starting g1") yield "g1 ham" yield from g2() yield "g1 eggs" finally: trace.append("Finishing g1") def g2(): try: trace.append("Starting g2") yield "g2 spam" yield "g2 more spam" finally: trace.append("Finishing g2") g = g1() for i in range(2): x = next(g) trace.append("Yielded %s" % (x,)) g.close() return trace def test_handing_exception_while_delegating_close(): """ >>> _lines(test_handing_exception_while_delegating_close()) Starting g1 Yielded g1 ham Starting g2 Yielded g2 spam Finishing g2 Finishing g1 nybbles have exploded with delight """ trace = [] def g1(): try: trace.append("Starting g1") yield "g1 ham" yield from g2() yield "g1 eggs" finally: trace.append("Finishing g1") def g2(): try: trace.append("Starting g2") yield "g2 spam" yield "g2 more spam" finally: trace.append("Finishing g2") raise ValueError("nybbles have exploded with delight") try: g = g1() for i in range(2): x = next(g) trace.append("Yielded %s" % (x,)) g.close() except ValueError as e: trace.append(e.args[0]) # FIXME: __context__ is currently not set #if sys.version_info[0] >= 3: # assert isinstance(e.__context__, GeneratorExit), 'exception context is %r' % e.__context__ else: trace.append("subgenerator failed to raise ValueError") return trace def test_delegating_throw(): """ >>> _lines(test_delegating_throw()) Starting g1 Yielded g1 ham Starting g2 Yielded g2 spam Finishing g2 Finishing g1 """ trace = [] def g1(): try: trace.append("Starting g1") yield "g1 ham" yield from g2() yield "g1 eggs" finally: trace.append("Finishing g1") def g2(): try: trace.append("Starting g2") yield "g2 spam" yield "g2 more spam" finally: trace.append("Finishing g2") try: g = g1() for i in range(2): x = next(g) trace.append("Yielded %s" % (x,)) e = ValueError("tomato ejected") g.throw(e) except ValueError: pass else: trace.append("subgenerator failed to raise ValueError") return trace def __test_value_attribute_of_StopIteration_exception(): """ StopIteration: value = None StopIteration: spam value = spam StopIteration: spam value = eggs """ trace = [] def pex(e): trace.append("%s: %s" % (e.__class__.__name__, e)) trace.append("value = %s" % (e.value,)) e = StopIteration() pex(e) e = StopIteration("spam") pex(e) e.value = "eggs" pex(e) return trace def test_exception_value_crash(): """ >>> test_exception_value_crash() ['g2'] """ # There used to be a refcount error in CPython when the return value # stored in the StopIteration has a refcount of 1. def g1(): yield from g2() def g2(): yield "g2" return [42] return list(g1()) def test_return_none(): """ >>> test_return_none() ['g2'] """ # There used to be a refcount error in CPython when the return value # stored in the StopIteration has a refcount of 1. def g1(): yield from g2() def g2(): yield "g2" return None return list(g1()) def test_finally_return_none(raise_exc=None): """ >>> gen = test_finally_return_none() >>> next(gen) 'g2' >>> next(gen) Traceback (most recent call last): StopIteration >>> gen = test_finally_return_none() >>> next(gen) 'g2' >>> try: gen.throw(ValueError()) ... except StopIteration: pass ... else: print("FAILED") """ # There used to be a refcount error in CPython when the return value # stored in the StopIteration has a refcount of 1. def g1(): yield from g2() def g2(): try: yield "g2" finally: return None return g1() def test_generator_return_value(): """ >>> _lines(test_generator_return_value()) Starting g1 Yielded g1 ham Starting g2 Yielded g2 spam Yielded g2 more spam Finishing g2 g2 returned None Starting g2 Yielded g2 spam Yielded g2 more spam Finishing g2 g2 returned 42 Yielded g1 eggs Finishing g1 """ trace = [] def g1(): trace.append("Starting g1") yield "g1 ham" ret = yield from g2() trace.append("g2 returned %s" % (ret,)) ret = yield from g2(42) trace.append("g2 returned %s" % (ret,)) yield "g1 eggs" trace.append("Finishing g1") def g2(v = None): trace.append("Starting g2") yield "g2 spam" yield "g2 more spam" trace.append("Finishing g2") if v: return v for x in g1(): trace.append("Yielded %s" % (x,)) return trace def test_delegation_of_next_to_non_generator(): """ >>> _lines(test_delegation_of_next_to_non_generator()) Yielded 0 Yielded 1 Yielded 2 """ trace = [] def g(): yield from range(3) for x in g(): trace.append("Yielded %s" % (x,)) return trace def test_conversion_of_sendNone_to_next(): """ >>> _lines(test_conversion_of_sendNone_to_next()) Yielded: 0 Yielded: 1 Yielded: 2 """ trace = [] def g(): yield from range(3) gi = g() for x in range(3): y = gi.send(None) trace.append("Yielded: %s" % (y,)) return trace def test_delegation_of_close_to_non_generator(): """ >>> _lines(test_delegation_of_close_to_non_generator()) starting g finishing g """ trace = [] def g(): try: trace.append("starting g") yield from range(3) trace.append("g should not be here") finally: trace.append("finishing g") gi = g() next(gi) gi.close() return trace def test_delegating_throw_to_non_generator(): """ >>> _lines(test_delegating_throw_to_non_generator()) Starting g Yielded 0 Yielded 1 Yielded 2 Yielded 3 Yielded 4 Finishing g """ trace = [] def g(): try: trace.append("Starting g") yield from range(10) finally: trace.append("Finishing g") try: gi = g() for i in range(5): x = next(gi) trace.append("Yielded %s" % (x,)) e = ValueError("tomato ejected") gi.throw(e) except ValueError: pass else: trace.append("subgenerator failed to raise ValueError") return trace def test_attempting_to_send_to_non_generator(): """ >>> _lines(test_attempting_to_send_to_non_generator()) starting g finishing g """ trace = [] def g(): try: trace.append("starting g") yield from range(3) trace.append("g should not be here") finally: trace.append("finishing g") try: gi = g() next(gi) for x in range(3): y = gi.send(42) trace.append("Should not have yielded: %s" % y) except AttributeError: pass else: trace.append("was able to send into non-generator") return trace def test_broken_getattr_handling(): """ >>> test_broken_getattr_handling() [] """ class Broken: def __iter__(self): return self def __next__(self): return 1 next = __next__ def __getattr__(self, attr): 1/0 def g(): yield from Broken() not_raised = [] try: gi = g() assert next(gi) == 1 gi.send(1) except ZeroDivisionError: pass else: not_raised.append(1) try: gi = g() assert next(gi) == 1 gi.throw(AttributeError) except ZeroDivisionError: pass else: not_raised.append(2) """ # this currently only calls PyErr_WriteUnraisable() and doesn't raise ... try: gi = g() assert next(gi) == 1 gi.close() except ZeroDivisionError: pass else: not_raised.append(3) """ gi = g() assert next(gi) == 1 gi.close() return not_raised def test_exception_in_initial_next_call(): """ >>> _lines(test_exception_in_initial_next_call()) g1 about to yield from g2 """ trace = [] def g1(): trace.append("g1 about to yield from g2") yield from g2() trace.append("g1 should not be here") def g2(): yield 1/0 def run(): gi = g1() next(gi) try: run() except ZeroDivisionError: pass else: trace.append("ZeroDivisionError not raised") return trace def test_attempted_yield_from_loop(): """ >>> _lines(test_attempted_yield_from_loop()) g1: starting Yielded: y1 g1: about to yield from g2 g2: starting Yielded: y2 g2: about to yield from g1 """ trace = [] def g1(): trace.append("g1: starting") yield "y1" trace.append("g1: about to yield from g2") yield from g2() trace.append("g1 should not be here") def g2(): trace.append("g2: starting") yield "y2" trace.append("g2: about to yield from g1") yield from gi trace.append("g2 should not be here") try: gi = g1() for y in gi: trace.append("Yielded: %s" % (y,)) except ValueError: pass # "generator already executing" else: trace.append("subgenerator didn't raise ValueError") return trace def test_attempted_reentry(): """ >>> _lines(test_attempted_reentry()) g1: starting Yielded: y1 g1: about to yield from g2 g2: starting Yielded: y2 g2: about to yield from g1 g2: caught ValueError Yielded: y3 g1: after delegating to g2 Yielded: y4 """ trace = [] def g1(): trace.append("g1: starting") yield "y1" trace.append("g1: about to yield from g2") yield from g2() trace.append("g1: after delegating to g2") yield "y4" def g2(): trace.append("g2: starting") yield "y2" trace.append("g2: about to yield from g1") try: yield from gi except ValueError: trace.append("g2: caught ValueError") else: trace.append("g1 did not raise ValueError on reentry") yield "y3" gi = g1() for y in gi: trace.append("Yielded: %s" % (y,)) return trace def test_returning_value_from_delegated_throw(): """ >>> _lines(test_returning_value_from_delegated_throw()) Starting g1 Yielded g1 ham Starting g2 Yielded g2 spam Caught LunchError in g2 Yielded g2 yet more spam Yielded g1 eggs Finishing g1 """ trace = [] def g1(): try: trace.append("Starting g1") yield "g1 ham" yield from g2() yield "g1 eggs" finally: trace.append("Finishing g1") def g2(): try: trace.append("Starting g2") yield "g2 spam" yield "g2 more spam" except LunchError: trace.append("Caught LunchError in g2") yield "g2 lunch saved" yield "g2 yet more spam" class LunchError(Exception): pass g = g1() for i in range(2): x = next(g) trace.append("Yielded %s" % (x,)) e = LunchError("tomato ejected") g.throw(e) for x in g: trace.append("Yielded %s" % (x,)) return trace def test_next_and_return_with_value(): """ >>> _lines(test_next_and_return_with_value()) g starting f resuming g g returning None f caught StopIteration g starting f resuming g g returning 42 f caught StopIteration """ trace = [] def f(r): gi = g(r) next(gi) try: trace.append("f resuming g") next(gi) trace.append("f SHOULD NOT BE HERE") except StopIteration: trace.append("f caught StopIteration") def g(r): trace.append("g starting") yield trace.append("g returning %s" % (r,)) return r f(None) f(42) return trace def test_send_and_return_with_value(): """ >>> _lines(test_send_and_return_with_value()) g starting f sending spam to g g received spam g returning None f caught StopIteration g starting f sending spam to g g received spam g returning 42 f caught StopIteration """ trace = [] def f(r): gi = g(r) next(gi) try: trace.append("f sending spam to g") gi.send("spam") trace.append("f SHOULD NOT BE HERE") except StopIteration: trace.append("f caught StopIteration") def g(r): trace.append("g starting") x = yield trace.append("g received %s" % (x,)) trace.append("g returning %s" % (r,)) return r f(None) f(42) return trace def test_catching_exception_from_subgen_and_returning(): """ Test catching an exception thrown into a subgenerator and returning a value >>> _lines(test_catching_exception_from_subgen_and_returning()) 1 inner caught ValueError inner returned 2 to outer 2 """ trace = [] def inner(): try: yield 1 except ValueError: trace.append("inner caught ValueError") return 2 def outer(): v = yield from inner() trace.append("inner returned %r to outer" % v) yield v g = outer() trace.append(next(g)) trace.append(g.throw(ValueError)) return trace def test_throwing_GeneratorExit_into_subgen_that_returns(): """ Test throwing GeneratorExit into a subgenerator that catches it and returns normally. >>> _lines(test_throwing_GeneratorExit_into_subgen_that_returns()) Enter g Enter f """ trace = [] def f(): try: trace.append("Enter f") yield trace.append("Exit f") except GeneratorExit: return def g(): trace.append("Enter g") yield from f() trace.append("Exit g") try: gi = g() next(gi) gi.throw(GeneratorExit) except GeneratorExit: pass else: trace.append("subgenerator failed to raise GeneratorExit") return trace def test_throwing_GeneratorExit_into_subgenerator_that_yields(): """ Test throwing GeneratorExit into a subgenerator that catches it and yields. >>> _lines(test_throwing_GeneratorExit_into_subgenerator_that_yields()) Enter g Enter f """ trace = [] def f(): try: trace.append("Enter f") yield trace.append("Exit f") except GeneratorExit: yield def g(): trace.append("Enter g") yield from f() trace.append("Exit g") try: gi = g() next(gi) gi.throw(GeneratorExit) except RuntimeError: pass # "generator ignored GeneratorExit" else: trace.append("subgenerator failed to raise GeneratorExit") return trace def test_throwing_GeneratorExit_into_subgen_that_raises(): """ Test throwing GeneratorExit into a subgenerator that catches it and raises a different exception. >>> _lines(test_throwing_GeneratorExit_into_subgen_that_raises()) Enter g Enter f """ trace = [] def f(): try: trace.append("Enter f") yield trace.append("Exit f") except GeneratorExit: raise ValueError("Vorpal bunny encountered") def g(): trace.append("Enter g") yield from f() trace.append("Exit g") try: gi = g() next(gi) gi.throw(GeneratorExit) except ValueError: pass # "Vorpal bunny encountered" else: trace.append("subgenerator failed to raise ValueError") return trace def test_yield_from_empty(): """ >>> test_yield_from_empty() """ def g(): yield from () try: next(g()) except StopIteration: pass else: return "FAILED" # test re-entry guards def _reentering_gen(): def one(): yield 0 yield from two() yield 3 def two(): yield 1 try: yield from g1 except ValueError: pass yield 2 g1 = one() return g1 def test_delegating_generators_claim_to_be_running_next(): """ >>> test_delegating_generators_claim_to_be_running_next() [0, 1, 2, 3] """ return list(_reentering_gen()) def test_delegating_generators_claim_to_be_running_send(): """ >>> test_delegating_generators_claim_to_be_running_send() [0, 1, 2, 3] """ g1 = _reentering_gen() res = [next(g1)] try: while True: res.append(g1.send(42)) except StopIteration: pass return res def test_delegating_generators_claim_to_be_running_throw(): """ >>> test_delegating_generators_claim_to_be_running_throw() [0, 1, 2, 3] """ class MyErr(Exception): pass def one(): try: yield 0 except MyErr: pass yield from two() try: yield 3 except MyErr: pass def two(): try: yield 1 except MyErr: pass try: yield from g1 except ValueError: pass try: yield 2 except MyErr: pass g1 = one() res = [next(g1)] try: while True: res.append(g1.throw(MyErr)) except StopIteration: pass return res def test_delegating_generators_claim_to_be_running_close(): """ >>> test_delegating_generators_claim_to_be_running_close() 42 """ class MyIt(object): def __iter__(self): return self def __next__(self): return 42 next = __next__ def close(self): assert g1.gi_running try: next(g1) except ValueError: pass # guard worked else: assert False, "re-entry guard failed to bark" def one(): yield from MyIt() g1 = one() ret = next(g1) g1.close() return ret def yield_in_return(x): """ >>> x = yield_in_return(range(3)) >>> for _ in range(10): ... try: ... print(next(x)) ... except StopIteration: ... if sys.version_info >= (3,3): ... print(sys.exc_info()[1].value is None) ... else: ... print(True) ... break 0 1 2 True """ return (yield from x) def gi_yieldfrom(it): """ >>> it = iter([1, 2, 3]) >>> g = gi_yieldfrom(it) >>> g.gi_yieldfrom is None or "ERROR: %r" % g.gi_yieldfrom True >>> next(g) 1 >>> g.gi_yieldfrom is it or "ERROR: %r" % g.gi_yieldfrom True """ x = yield from it return x Cython-0.23.4/tests/run/wundram1.pyx0000644000175600017570000000011012606202452020442 0ustar jenkinsjenkins00000000000000""" >>> x == 5 or repr(x) True """ cdef unsigned int ui ui = 5 x = ui Cython-0.23.4/tests/run/withstat_py27.py0000644000175600017570000001101112606202452021246 0ustar jenkinsjenkins00000000000000import sys def typename(t): name = type(t).__name__ if sys.version_info < (2,5): if name == 'classobj' and issubclass(t, MyException): name = 'type' elif name == 'instance' and isinstance(t, MyException): name = 'MyException' return "" % name class MyException(Exception): pass class ContextManager(object): def __init__(self, value, exit_ret = None): self.value = value self.exit_ret = exit_ret def __exit__(self, a, b, tb): print("exit %s %s %s" % (typename(a), typename(b), typename(tb))) return self.exit_ret def __enter__(self): print("enter") return self.value def multimanager(): """ >>> multimanager() enter enter enter enter enter enter 2 value 1 2 3 4 5 nested exit exit exit exit exit exit """ with ContextManager(1), ContextManager(2) as x, ContextManager('value') as y,\ ContextManager(3), ContextManager((1, 2, (3, (4, 5)))) as (a, b, (c, (d, e))): with ContextManager('nested') as nested: print(x) print(y) print('%s %s %s %s %s' % (a, b, c, d, e)) print(nested) class GetManager(object): def get(self, *args): return ContextManager(*args) def manager_from_expression(): """ >>> manager_from_expression() enter 1 exit enter 2 exit """ with GetManager().get(1) as x: print(x) g = GetManager() with g.get(2) as x: print(x) # Tests borrowed from pyregr test_with.py, # modified to follow the constraints of Cython. import unittest class Dummy(object): def __init__(self, value=None, gobble=False): if value is None: value = self self.value = value self.gobble = gobble self.enter_called = False self.exit_called = False def __enter__(self): self.enter_called = True return self.value def __exit__(self, *exc_info): self.exit_called = True self.exc_info = exc_info if self.gobble: return True class InitRaises(object): def __init__(self): raise RuntimeError() class EnterRaises(object): def __enter__(self): raise RuntimeError() def __exit__(self, *exc_info): pass class ExitRaises(object): def __enter__(self): pass def __exit__(self, *exc_info): raise RuntimeError() class NestedWith(unittest.TestCase): """ >>> NestedWith().runTest() """ def runTest(self): self.testNoExceptions() self.testExceptionInExprList() self.testExceptionInEnter() self.testExceptionInExit() self.testEnterReturnsTuple() def testNoExceptions(self): with Dummy() as a, Dummy() as b: self.assertTrue(a.enter_called) self.assertTrue(b.enter_called) self.assertTrue(a.exit_called) self.assertTrue(b.exit_called) def testExceptionInExprList(self): try: with Dummy() as a, InitRaises(): pass except: pass self.assertTrue(a.enter_called) self.assertTrue(a.exit_called) def testExceptionInEnter(self): try: with Dummy() as a, EnterRaises(): self.fail('body of bad with executed') except RuntimeError: pass else: self.fail('RuntimeError not reraised') self.assertTrue(a.enter_called) self.assertTrue(a.exit_called) def testExceptionInExit(self): body_executed = False with Dummy(gobble=True) as a, ExitRaises(): body_executed = True self.assertTrue(a.enter_called) self.assertTrue(a.exit_called) self.assertTrue(body_executed) self.assertNotEqual(a.exc_info[0], None) def testEnterReturnsTuple(self): with Dummy(value=(1,2)) as (a1, a2), \ Dummy(value=(10, 20)) as (b1, b2): self.assertEqual(1, a1) self.assertEqual(2, a2) self.assertEqual(10, b1) self.assertEqual(20, b2) Cython-0.23.4/tests/run/withstat_py.py0000644000175600017570000001027112606202452021104 0ustar jenkinsjenkins00000000000000import sys def typename(t): name = type(t).__name__ if sys.version_info < (2,5): if name == 'classobj' and issubclass(t, MyException): name = 'type' elif name == 'instance' and isinstance(t, MyException): name = 'MyException' return "" % name class MyException(Exception): pass class ContextManager(object): def __init__(self, value, exit_ret = None): self.value = value self.exit_ret = exit_ret def __exit__(self, a, b, tb): print("exit %s %s %s" % (typename(a), typename(b), typename(tb))) return self.exit_ret def __enter__(self): print("enter") return self.value def no_as(): """ >>> no_as() enter hello exit """ with ContextManager("value"): print("hello") def basic(): """ >>> basic() enter value exit """ with ContextManager("value") as x: print(x) def with_pass(): """ >>> with_pass() enter exit """ with ContextManager("value") as x: pass def with_return(): """ >>> print(with_return()) enter exit value """ with ContextManager("value") as x: return x def with_break(): """ >>> print(with_break()) enter exit a """ for c in list("abc"): with ContextManager("value") as x: break print("FAILED") return c def with_continue(): """ >>> print(with_continue()) enter exit enter exit enter exit c """ for c in list("abc"): with ContextManager("value") as x: continue print("FAILED") return c def with_exception(exit_ret): """ >>> with_exception(None) enter value exit outer except >>> with_exception(True) enter value exit """ try: with ContextManager("value", exit_ret=exit_ret) as value: print(value) raise MyException() except: print("outer except") def with_real_lock(): """ >>> with_real_lock() about to acquire lock holding lock lock no longer held """ from threading import Lock lock = Lock() print("about to acquire lock") with lock: print("holding lock") print("lock no longer held") def functions_in_with(): """ >>> f = functions_in_with() enter exit outer except >>> f(1)[0] 1 >>> print(f(1)[1]) value """ try: with ContextManager("value") as value: def f(x): return x, value make = lambda x:x() raise make(MyException) except: print("outer except") return f def multitarget(): """ >>> multitarget() enter 1 2 3 4 5 exit """ with ContextManager((1, 2, (3, (4, 5)))) as (a, b, (c, (d, e))): print('%s %s %s %s %s' % (a, b, c, d, e)) def tupletarget(): """ >>> tupletarget() enter (1, 2, (3, (4, 5))) exit """ with ContextManager((1, 2, (3, (4, 5)))) as t: print(t) class GetManager(object): def get(self, *args): return ContextManager(*args) def manager_from_expression(): """ >>> manager_from_expression() enter 1 exit enter 2 exit """ with GetManager().get(1) as x: print(x) g = GetManager() with g.get(2) as x: print(x) Cython-0.23.4/tests/run/withstat.pyx0000644000175600017570000001336612606202452020574 0ustar jenkinsjenkins00000000000000from __future__ import with_statement import sys def typename(t): name = type(t).__name__ if sys.version_info < (2,5): if name == 'classobj' and issubclass(t, MyException): name = 'type' elif name == 'instance' and isinstance(t, MyException): name = 'MyException' return u"" % name class MyException(Exception): pass class ContextManager(object): def __init__(self, value, exit_ret = None): self.value = value self.exit_ret = exit_ret def __exit__(self, a, b, tb): print u"exit", typename(a), typename(b), typename(tb) return self.exit_ret def __enter__(self): print u"enter" return self.value def no_as(): """ >>> no_as() enter hello exit """ with ContextManager(u"value"): print u"hello" def basic(): """ >>> basic() enter value exit """ with ContextManager(u"value") as x: print x def with_pass(): """ >>> with_pass() enter exit """ with ContextManager(u"value") as x: pass def with_exception(exit_ret): """ >>> with_exception(None) enter value exit outer except >>> with_exception(True) enter value exit """ try: with ContextManager(u"value", exit_ret=exit_ret) as value: print value raise MyException() except: print u"outer except" def multitarget(): """ >>> multitarget() enter 1 2 3 4 5 exit """ with ContextManager((1, 2, (3, (4, 5)))) as (a, b, (c, (d, e))): print a, b, c, d, e def tupletarget(): """ >>> tupletarget() enter (1, 2, (3, (4, 5))) exit """ with ContextManager((1, 2, (3, (4, 5)))) as t: print t def typed(): """ >>> typed() enter 10 exit """ cdef unsigned char i c = ContextManager(255) with c as i: i += 11 print i def multimanager(): """ >>> multimanager() enter enter enter enter enter enter 2 value 1 2 3 4 5 nested exit exit exit exit exit exit """ with ContextManager(1), ContextManager(2) as x, ContextManager(u'value') as y,\ ContextManager(3), ContextManager((1, 2, (3, (4, 5)))) as (a, b, (c, (d, e))): with ContextManager(u'nested') as nested: print x print y print a, b, c, d, e print nested # Tests borrowed from pyregr test_with.py, # modified to follow the constraints of Cython. import unittest class Dummy(object): def __init__(self, value=None, gobble=False): if value is None: value = self self.value = value self.gobble = gobble self.enter_called = False self.exit_called = False def __enter__(self): self.enter_called = True return self.value def __exit__(self, *exc_info): self.exit_called = True self.exc_info = exc_info if self.gobble: return True class InitRaises(object): def __init__(self): raise RuntimeError() class EnterRaises(object): def __enter__(self): raise RuntimeError() def __exit__(self, *exc_info): pass class ExitRaises(object): def __enter__(self): pass def __exit__(self, *exc_info): raise RuntimeError() class NestedWith(unittest.TestCase): """ >>> NestedWith().runTest() """ def runTest(self): self.testNoExceptions() self.testExceptionInExprList() self.testExceptionInEnter() self.testExceptionInExit() self.testEnterReturnsTuple() def testNoExceptions(self): with Dummy() as a, Dummy() as b: self.assertTrue(a.enter_called) self.assertTrue(b.enter_called) self.assertTrue(a.exit_called) self.assertTrue(b.exit_called) def testExceptionInExprList(self): try: with Dummy() as a, InitRaises(): pass except: pass self.assertTrue(a.enter_called) self.assertTrue(a.exit_called) def testExceptionInEnter(self): try: with Dummy() as a, EnterRaises(): self.fail('body of bad with executed') except RuntimeError: pass else: self.fail('RuntimeError not reraised') self.assertTrue(a.enter_called) self.assertTrue(a.exit_called) def testExceptionInExit(self): body_executed = False with Dummy(gobble=True) as a, ExitRaises(): body_executed = True self.assertTrue(a.enter_called) self.assertTrue(a.exit_called) self.assertTrue(body_executed) self.assertNotEqual(a.exc_info[0], None) def testEnterReturnsTuple(self): with Dummy(value=(1,2)) as (a1, a2), \ Dummy(value=(10, 20)) as (b1, b2): self.assertEqual(1, a1) self.assertEqual(2, a2) self.assertEqual(10, b1) self.assertEqual(20, b2) Cython-0.23.4/tests/run/withnogil.pyx0000644000175600017570000000040212606202452020714 0ustar jenkinsjenkins00000000000000def f(x): """ >>> f(1) (1, 17) """ cdef int y z = 42 with nogil: y = 17 z = x return z,y def g(): """ >>> g() 1 """ with nogil: h() return 1 cdef int h() nogil except -1: pass Cython-0.23.4/tests/run/with_statement_module_level_T536.pyx0000644000175600017570000000134512606202452025233 0ustar jenkinsjenkins00000000000000# ticket: 536 __doc__ = """ >>> inner_result ['ENTER'] >>> result # doctest: +ELLIPSIS ['ENTER', ...EXIT (<...ValueError...>,...ValueError..., >> inner_result_no_exc ['ENTER'] >>> result_no_exc ['ENTER', 'EXIT (None, None, None)'] """ class ContextManager(object): def __init__(self, result): self.result = result def __enter__(self): self.result.append("ENTER") def __exit__(self, *values): self.result.append("EXIT %r" % (values,)) return True result_no_exc = [] with ContextManager(result_no_exc) as c: inner_result_no_exc = result_no_exc[:] result = [] with ContextManager(result) as c: inner_result = result[:] raise ValueError('TEST') Cython-0.23.4/tests/run/with_gil.pyx0000644000175600017570000002447012606202452020531 0ustar jenkinsjenkins00000000000000""" Test the 'with gil:' statement. """ cimport cython from cpython.ref cimport PyObject import sys def redirect_stderr(func, *args, **kwargs): """ Helper function that redirects stderr to stdout for doctest. """ stderr, sys.stderr = sys.stderr, sys.stdout func(*args, **kwargs) sys.stderr = stderr cdef void puts(char *string) with gil: """ We need this for doctest, used from nogil sections. """ print string.decode('ascii') class ExceptionWithMsg(Exception): """ In python2.4 Exception is formatted as when swallowed. """ def __repr__(self): return "ExceptionWithMsg(%r)" % self.args # Start with some normal Python functions def test_simple(): """ >>> test_simple() ['spam', 'ham'] """ with nogil: with gil: print ['spam', 'ham'] def test_nested_gil_blocks(): """ >>> test_nested_gil_blocks() entered outer nogil section entered outer gil section entered inner nogil section entered inner gil section leaving inner gil section leaving inner nogil section leaving outer gil section leaving outer nogil section """ with nogil: puts("entered outer nogil section") with gil: print 'entered outer gil section' with nogil: puts("entered inner nogil section") with gil: print 'entered inner gil section' print 'leaving inner gil section' puts("leaving inner nogil section") print "leaving outer gil section" puts("leaving outer nogil section") def test_propagate_exception(): """ >>> test_propagate_exception() Traceback (most recent call last): ... Exception: This exception propagates! """ # Note, doctest doesn't support both output and exceptions with nogil: with gil: raise Exception("This exception propagates!") def test_catch_exception(): """ >>> test_catch_exception() This is executed Exception value This is also executed """ try: with nogil: with gil: print "This is executed" raise Exception("Exception value") print "This is not executed" puts("This is also not executed") except Exception, e: print e print "This is also executed" def test_try_finally_and_outer_except(): """ >>> test_try_finally_and_outer_except() First finally clause Second finally clause Caught: Some Exception End of function """ try: with nogil: with gil: try: with nogil: with gil: try: raise Exception("Some Exception") finally: puts("First finally clause") finally: puts("Second finally clause") puts("This is not executed") except Exception, e: print "Caught:", e print "End of function" def test_restore_exception(): """ >>> test_restore_exception() Traceback (most recent call last): ... Exception: Override the raised exception """ with nogil: with gil: try: with nogil: with gil: raise Exception("Override this please") finally: raise Exception("Override the raised exception") ### DISABLED: this cannot work with flow control analysis ## ## def test_declared_variables(): ## """ ## >>> test_declared_variables() ## None ## None ## ['s', 'p', 'a', 'm'] ## ['s', 'p', 'a', 'm'] ## """ ## cdef object somevar ## ## print somevar ## ## with nogil: ## with gil: ## print somevar ## somevar = list("spam") ## print somevar ## ## print somevar ### DISABLED: this cannot work with flow control analysis ## ## def test_undeclared_variables(): ## """ ## >>> test_undeclared_variables() ## None ## None ## ['s', 'p', 'a', 'm'] ## ['s', 'p', 'a', 'm'] ## """ ## print somevar ## with nogil: ## with gil: ## print somevar ## somevar = list("spam") ## print somevar ## ## print somevar def test_loops_and_boxing(): """ >>> test_loops_and_boxing() spamham h a m done looping """ cdef char c, *string = "spamham" with nogil: with gil: print string.decode('ascii') for c in string[4:]: print "%c" % c else: print "done looping" cdef class SomeExtClass(object): cdef int some_attribute @cython.infer_types(True) def test_infer_types(): """ >>> test_infer_types() 10 """ with nogil: with gil: obj = SomeExtClass() obj.some_attribute = 10 print obj.some_attribute def test_closure(): """ >>> test_closure() Traceback (most recent call last): ... Exception: {'twinkle': 'little star'} """ a = dict(twinkle='little star') def inner_function(): with nogil: with gil: raise Exception(a) with nogil: with gil: inner_function() raise Exception("This should not be raised!") cpdef test_cpdef(): """ >>> test_cpdef() Seems to work! Or does it? """ with nogil: with gil: print "Seems to work!" puts("Or does it?") # Now test some cdef functions with different return types cdef void void_nogil_ignore_exception() nogil: with gil: raise ExceptionWithMsg("This is swallowed") puts("unreachable") with gil: print "unreachable" cdef void void_nogil_nested_gil() nogil: with gil: with nogil: with gil: print 'Inner gil section' puts("nogil section") raise ExceptionWithMsg("Swallow this") puts("Don't print this") def test_nogil_void_funcs_with_gil(): """ >>> redirect_stderr(test_nogil_void_funcs_with_gil) # doctest: +ELLIPSIS Exception... ignored... Inner gil section nogil section Exception... ignored... """ void_nogil_ignore_exception() void_nogil_nested_gil() def test_nogil_void_funcs_with_nogil(): """ >>> redirect_stderr(test_nogil_void_funcs_with_nogil) # doctest: +ELLIPSIS Exception... ignored... Inner gil section nogil section Exception... ignored... """ with nogil: void_nogil_ignore_exception() void_nogil_nested_gil() cdef PyObject *nogil_propagate_exception() nogil except NULL: with nogil: with gil: raise Exception("This exception propagates!") return 1 def test_nogil_propagate_exception(): """ >>> test_nogil_propagate_exception() Traceback (most recent call last): ... Exception: This exception propagates! """ nogil_propagate_exception() cdef with_gil_raise() with gil: raise Exception("This exception propagates!") def test_release_gil_call_gil_func(): """ >>> test_release_gil_call_gil_func() Traceback (most recent call last): ... Exception: This exception propagates! """ with nogil: with gil: with_gil_raise() # Test try/finally in nogil blocks def test_try_finally_in_nogil(): """ >>> test_try_finally_in_nogil() Traceback (most recent call last): ... Exception: Override exception! """ with nogil: try: with gil: raise Exception("This will be overridden") finally: with gil: raise Exception("Override exception!") with gil: raise Exception("This code should not be executed!") def test_nogil_try_finally_no_exception(): """ >>> test_nogil_try_finally_no_exception() first nogil try nogil try gil second nogil try nogil finally ------ First with gil block Second with gil block finally block """ with nogil: try: puts("first nogil try") with gil: print "nogil try gil" puts("second nogil try") finally: puts("nogil finally") print '------' with nogil: try: with gil: print "First with gil block" with gil: print "Second with gil block" finally: puts("finally block") def test_nogil_try_finally_propagate_exception(): """ >>> test_nogil_try_finally_propagate_exception() Execute finally clause Propagate this! """ try: with nogil: try: with gil: raise Exception("Propagate this!") with gil: raise Exception("Don't reach this section!") finally: puts("Execute finally clause") except Exception, e: print e def test_nogil_try_finally_return_in_with_gil(x): """ >>> test_nogil_try_finally_return_in_with_gil(10) print me 10 """ with nogil: try: with gil: raise Exception("Swallow me!") finally: with gil: print "print me" return x print "I am not executed" cdef void nogil_try_finally_return() nogil: try: with gil: raise Exception("I am swallowed in nogil code... right?") finally: with gil: print "print me first" return with gil: print "I am not executed" def test_nogil_try_finally_return(): """ >>> test_nogil_try_finally_return() print me first """ with nogil: nogil_try_finally_return() cdef int error_func() except -1 with gil: raise Exception("propagate this") def test_nogil_try_finally_error_label(): """ >>> test_nogil_try_finally_error_label() print me first propagate this """ try: with nogil: try: error_func() finally: with gil: print "print me first" except Exception, e: print e.args[0] Cython-0.23.4/tests/run/weakfail.pyx0000644000175600017570000000072312606202452020501 0ustar jenkinsjenkins00000000000000import gc import weakref foo_dict = weakref.WeakValueDictionary() cdef class Foo: cdef object __weakref__ def test_weakref(key): """ Test af9cfeb5f94d9cd4f2989fc8e111c33208494ba4 fix. Originally running it using debug build of python lead to:: visit_decref: Assertion `gc->gc.gc_refs != 0' failed >>> _ = gc.collect() >>> _ = test_weakref(48) >>> _ = gc.collect() """ obj = Foo() foo_dict[key] = obj return obj Cython-0.23.4/tests/run/watts1.pyx0000644000175600017570000000021512606202452020135 0ustar jenkinsjenkins00000000000000def test(): """ >>> test() == 55 + 66 True """ cdef int a,b cdef object foo = (55,66) a,b = foo return a + b Cython-0.23.4/tests/run/voidstarcast.pyx0000644000175600017570000000066012606202452021424 0ustar jenkinsjenkins00000000000000cdef class C: cdef int i def foo(self): self.i = 42 def get_i(self): return self.i def cast_cast_cast(arg): """ >>> x = C() >>> x.foo() >>> cast_cast_cast(x) == x True >>> x.get_i() 42 """ cdef object x cdef void *p = arg cdef int i x = p p = x x = (p).foo i = (p).i (p).i = i return p Cython-0.23.4/tests/run/varargdecl.pyx0000644000175600017570000000020312606202452021021 0ustar jenkinsjenkins00000000000000cdef grail(char *blarg, ...): pass def test(): """ >>> test() """ grail(b"test") grail(b"test", b"toast") Cython-0.23.4/tests/run/varargcall.pyx0000644000175600017570000000027312606202452021034 0ustar jenkinsjenkins00000000000000cdef grail(const char *blarg, ...): pass def swallow(): """ >>> swallow() """ grail("spam") grail("spam", 42) grail("spam", b"abc") grail("spam", "abc") Cython-0.23.4/tests/run/unused_args.pyx0000644000175600017570000000153312606202452021235 0ustar jenkinsjenkins00000000000000cdef c_unused_simple(a, b, c): """ >>> c_unused_simple(1, 2, 3) 3 """ return a + b cdef c_unused_optional(a, b, c=1, d=2): """ >>> c_unused_optional(1, 2) 4 >>> c_unused_optional(1, 2, 3, 4) 6 """ return b + d cpdef cp_unused_simple(a, b, c): """ >>> cp_unused_simple(1, 2, 3) 3 """ return a + b cpdef cp_unused_optional(a, b, c=1, d=2): """ >>> cp_unused_optional(1, 2) 4 >>> cp_unused_optional(1, 2, 3, 4) 6 """ return b + d cdef class Unused: """ >>> o = Unused() """ cpdef cp_unused_simple(self, a, b, c): return c cpdef cp_unused_optional(self, a, b, c=1, d=2): return b + d def def_unused(a, b, c): """ >>> def_unused(1, 2, 3) """ def def_unused_metho(o): """ >>> def_unused_metho(0) """ Cython-0.23.4/tests/run/unused.pyx0000644000175600017570000000131712606202452020221 0ustar jenkinsjenkins00000000000000cdef c_unused_simple(a, b, c): """ >>> c_unused_simple(1, 2, 3) 3 """ return a + b cdef c_unused_optional(a, b, c=1, d=2): """ >>> c_unused_optional(1, 2) 4 >>> c_unused_optional(1, 2, 3, 4) 6 """ return b + d cpdef cp_unused_simple(a, b, c): """ >>> cp_unused_simple(1, 2, 3) 3 """ return a + b cpdef cp_unused_optional(a, b, c=1, d=2): """ >>> cp_unused_optional(1, 2) 4 >>> cp_unused_optional(1, 2, 3, 4) 6 """ return b + d cdef class Unused: """ >>> o = Unused() """ cpdef cp_unused_simple(self, a, b, c): return c cpdef cp_unused_optional(self, a, b, c=1, d=2): return b + d Cython-0.23.4/tests/run/unsignedbehaviour_T184.pyx0000644000175600017570000000102012606202452023146 0ustar jenkinsjenkins00000000000000# ticket: 184 """ >>> c_call() (-10, 10) >>> py_call() (-10, 10) >>> loop() 19 >>> rangelist() [-3, -2, -1, 0, 1, 2] """ cdef c_g(int a, int b): return (a, b) def py_g(a, b): return (a, b) def c_call(): cdef unsigned int i = 10 return c_g(-i, i) def py_call(): cdef unsigned int i = 10 return py_g(-i, i) def loop(): cdef unsigned int i = 10 times = 0 for x in range(-i,i): times += 1 return times def rangelist(): cdef unsigned int i = 3 return list(range(-i, i)) Cython-0.23.4/tests/run/unsigned_char_ptr_bytes_conversion_T359.pyx0000644000175600017570000000124612606202452026614 0ustar jenkinsjenkins00000000000000# ticket: 359 cdef unsigned char* some_c_unstring = 'test toast taste' def test_uchar_conversion(): """ >>> py_string1, py_string2, py_string3 = test_uchar_conversion() >>> print(py_string1.decode('iso8859-1')) test toast taste >>> print(py_string2.decode('iso8859-1')) test toast taste >>> print(py_string3.decode('iso8859-1')) test toast taste """ cdef object py_string1 = some_c_unstring cdef unsigned char* c_unstring_from_py = py_string1 cdef object py_string2 = c_unstring_from_py cdef char* c_string_from_py = py_string2 cdef object py_string3 = c_string_from_py return py_string1, py_string2, py_string3 Cython-0.23.4/tests/run/unsigned.pyx0000644000175600017570000000173312606202452020534 0ustar jenkinsjenkins00000000000000cdef int i = 1 cdef long l = 2 cdef unsigned int ui = 4 cdef unsigned long ul = 8 def test_add(): """ >>> test_add() 3 9 6 12 """ print i + l print i + ul print ui + l print ui + ul def test_add_sshort_ulong(signed short a, unsigned long b): """ >>> test_add_sshort_ulong(1, 1) == 2 True >>> test_add_sshort_ulong(-1, 1) == 0 True >>> test_add_sshort_ulong(-2, 1) == -1 False """ return a + b def test_add_ushort_slonglong(unsigned short a, signed long long b): """ >>> test_add_ushort_slonglong(1, 1) == 2 True >>> test_add_ushort_slonglong(1, -1) == 0 True >>> test_add_ushort_slonglong(1, -2) == -1 True """ return a + b def test_add_slong_ulong(signed long a, unsigned long b): """ >>> test_add_slong_ulong(1, 1) == 2 True >>> test_add_slong_ulong(-1, 1) == 0 True >>> test_add_slong_ulong(-2, 1) == -1 False """ return a + b Cython-0.23.4/tests/run/unreachable.pyx0000644000175600017570000000024212606202452021163 0ustar jenkinsjenkins00000000000000# mode: run # tag: generators unreachable def with_yield_removed(): """ >>> o = with_yield_removed() >>> list(o) [] """ return yield Cython-0.23.4/tests/run/unpacklistcomp.pyx0000644000175600017570000000123612606202452021752 0ustar jenkinsjenkins00000000000000def unpack_normal(l): """ >>> unpack_normal([1,2]) (1, 2) >>> unpack_normal([1,2,3]) # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: ... """ a,b = l return a,b def unpack_comp(l): """ >>> unpack_comp([1,2]) (1, 2) >>> unpack_comp([1,2,3]) # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: ... """ a,b = [ n for n in l ] return a,b def unpack_expr(l): """ >>> unpack_expr([1,2]) (1, 4) >>> unpack_expr([1,2,3]) # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: ... """ a,b = [ n*n for n in l ] return a,b Cython-0.23.4/tests/run/unpack_fused.pyx0000644000175600017570000000541212606202452021365 0ustar jenkinsjenkins00000000000000 ctypedef fused sequence: list tuple object def unpack_one(sequence it): """ >>> items = [1] >>> unpack_one(items) 1 >>> unpack_one(iter(items)) 1 >>> unpack_one(list(items)) 1 >>> unpack_one(tuple(items)) 1 """ a, = it return a def unpack_two(sequence it): """ >>> items = [1,2] >>> unpack_two(items) (1, 2) >>> unpack_two(iter(items)) (1, 2) >>> unpack_two(list(items)) (1, 2) >>> unpack_two(tuple(items)) (1, 2) """ a,b = it return a,b def unpack_two_int(sequence it): """ >>> items = [1,2] >>> unpack_two_int(items) (1, 2) >>> unpack_two_int(iter(items)) (1, 2) >>> unpack_two_int(list(items)) (1, 2) >>> unpack_two_int(tuple(items)) (1, 2) >>> items = [1, object()] >>> unpack_two_int(items) Traceback (most recent call last): TypeError: an integer is required >>> unpack_two_int(iter(items)) Traceback (most recent call last): TypeError: an integer is required >>> unpack_two_int(list(items)) Traceback (most recent call last): TypeError: an integer is required >>> unpack_two_int(tuple(items)) Traceback (most recent call last): TypeError: an integer is required """ cdef int b a,b = it return a,b def unpack_many(sequence it): """ >>> items = range(1,13) >>> unpack_many(items) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) >>> unpack_many(iter(items)) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) >>> unpack_many(list(items)) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) >>> unpack_many(tuple(items)) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) """ a,b,c,d,e,f,g,h,i,j,k,l = it return a,b,c,d,e,f,g,h,i,j,k,l def unpack_many_int(sequence it): """ >>> items = range(1,13) >>> unpack_many_int(items) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) >>> unpack_many_int(iter(items)) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) >>> unpack_many_int(list(items)) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) >>> unpack_many_int(tuple(items)) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) >>> items = range(1,10) >>> unpack_many_int(items) Traceback (most recent call last): ValueError: need more than 9 values to unpack >>> unpack_many_int(iter(items)) Traceback (most recent call last): ValueError: need more than 9 values to unpack >>> unpack_many_int(list(items)) Traceback (most recent call last): ValueError: need more than 9 values to unpack >>> unpack_many_int(tuple(items)) Traceback (most recent call last): ValueError: need more than 9 values to unpack """ cdef int b cdef long f cdef Py_ssize_t h a,b,c,d,e,f,g,h,i,j,k,l = it return a,b,c,d,e,f,g,h,i,j,k,l Cython-0.23.4/tests/run/unpack.pyx0000644000175600017570000002237212606202452020203 0ustar jenkinsjenkins00000000000000# mode: run # tag: sequence_unpacking import cython def _it(N): for i in range(N): yield i cdef class ItCount(object): cdef object values cdef readonly count def __init__(self, values): self.values = iter(values) self.count = 0 def __iter__(self): return self def __next__(self): self.count += 1 return next(self.values) def kunterbunt(obj1, obj2, obj3, obj4, obj5): """ >>> kunterbunt(1, (2,), (3,4,5), (6,(7,(8,9))), 0) (8, 9, (8, 9), (6, (7, (8, 9))), 0) """ obj1, = obj2 obj1, obj2 = obj2 + obj2 obj1, obj2, obj3 = obj3 obj1, (obj2, obj3) = obj4 [obj1, obj2] = obj3 return obj1, obj2, obj3, obj4, obj5 def unpack_tuple(tuple it): """ >>> unpack_tuple((1,2,3)) (1, 2, 3) >>> a,b,c = None # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> unpack_tuple(None) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... """ a,b,c = it return a,b,c def unpack_list(list it): """ >>> unpack_list([1,2,3]) (1, 2, 3) >>> a,b,c = None # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> unpack_list(None) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... """ a,b,c = it return a,b,c def unpack_to_itself(it): """ >>> it = _it(2) >>> it, it = it >>> it 1 >>> unpack_to_itself([1,2]) 2 >>> unpack_to_itself((1,2)) 2 >>> unpack_to_itself(_it(2)) 1 >>> unpack_to_itself((1,2,3)) Traceback (most recent call last): ValueError: too many values to unpack (expected 2) >>> unpack_to_itself(_it(3)) Traceback (most recent call last): ValueError: too many values to unpack (expected 2) """ it, it = it return it def unpack_partial(it): """ >>> it = _it(2) >>> a = b = c = 0 >>> try: a,b,c = it ... except ValueError: pass ... else: print("DID NOT FAIL!") >>> a, b, c (0, 0, 0) >>> unpack_partial([1,2]) (0, 0, 0) >>> unpack_partial((1,2)) (0, 0, 0) >>> unpack_partial(_it(2)) (0, 0, 0) >>> it = ItCount([1,2]) >>> a = b = c = 0 >>> try: a,b,c = it ... except ValueError: pass ... else: print("DID NOT FAIL!") >>> a, b, c (0, 0, 0) >>> it.count 3 >>> it = ItCount([1,2]) >>> unpack_partial(it) (0, 0, 0) >>> it.count 3 """ a = b = c = 0 try: a, b, c = it except ValueError: pass return a, b, c def unpack_fail_assignment(it): """ >>> it = ItCount([1, 2, 3]) >>> a = b = c = 0 >>> try: a, b[0], c = it ... except TypeError: pass >>> a,b,c (1, 0, 0) >>> it.count 4 >>> it = ItCount([1, 2, 3]) >>> unpack_fail_assignment(it) (1, 0, 0) >>> it.count 4 """ cdef object a,b,c a = b = c = 0 try: a, b[0], c = it except TypeError: pass return a, b, c def unpack_partial_typed(it): """ >>> unpack_partial_typed([1, 2, 'abc']) (0, 0, 0) >>> unpack_partial_typed((1, 'abc', 3)) (0, 0, 0) >>> unpack_partial_typed(set([1, 'abc', 3])) (0, 0, 0) >>> it = ItCount([1, 'abc', 3]) >>> unpack_partial_typed(it) (0, 0, 0) >>> it.count 4 """ cdef int a,b,c a = b = c = 0 try: a, b, c = it except TypeError: pass return a, b, c def unpack_typed(it): """ >>> unpack_typed((1, 2.0, [1])) (1, 2.0, [1]) >>> unpack_typed([1, 2.0, [1]]) (1, 2.0, [1]) >>> it = ItCount([1, 2.0, [1]]) >>> unpack_typed(it) (1, 2.0, [1]) >>> it.count 4 >>> try: unpack_typed((1, None, [1])) ... except TypeError: pass >>> try: unpack_typed([1, None, [1]]) ... except TypeError: pass >>> it = ItCount([1, None, [1]]) >>> try: unpack_typed(it) ... except TypeError: pass >>> it.count 4 >>> unpack_typed((1, 2.0, (1,))) Traceback (most recent call last): TypeError: Expected list, got tuple >>> it = ItCount([1, 2.0, (1,)]) >>> unpack_typed(it) Traceback (most recent call last): TypeError: Expected list, got tuple >>> it.count 4 """ cdef int a cdef float b cdef list c a,b,c = it return a,b,c def failure_too_many(it): """ >>> try: a,b,c = [1,2,3,4] ... except ValueError: pass >>> failure_too_many([1,2,3,4]) Traceback (most recent call last): ValueError: too many values to unpack (expected 3) >>> try: a,b,c = [1,2,3,4] ... except ValueError: pass >>> failure_too_many((1,2,3,4)) Traceback (most recent call last): ValueError: too many values to unpack (expected 3) >>> a,b,c = set([1,2,3,4]) # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: too many values to unpack... >>> failure_too_many(set([1,2,3,4])) Traceback (most recent call last): ValueError: too many values to unpack (expected 3) >>> a,b,c = _it(4) # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: too many values to unpack... >>> failure_too_many(_it(4)) Traceback (most recent call last): ValueError: too many values to unpack (expected 3) """ a,b,c = it return a,b,c def failure_too_few(it): """ >>> try: a,b,c = [1,2] ... except ValueError: pass >>> failure_too_few([1,2]) Traceback (most recent call last): ValueError: need more than 2 values to unpack >>> try: a,b,c = (1,2) ... except ValueError: pass >>> failure_too_few((1,2)) Traceback (most recent call last): ValueError: need more than 2 values to unpack >>> try: a,b,c = set([1,2]) ... except ValueError: pass ... else: print("DID NOT FAIL!") >>> failure_too_few(set([1,2])) Traceback (most recent call last): ValueError: need more than 2 values to unpack >>> try: a,b,c = _it(2) ... except ValueError: pass ... else: print("DID NOT FAIL!") >>> failure_too_few(_it(2)) Traceback (most recent call last): ValueError: need more than 2 values to unpack """ a,b,c = it return a,b,c def _it_failure(N): for i in range(N): yield i raise ValueError("huhu") def failure_while_unpacking(it): """ >>> a,b,c = _it_failure(0) Traceback (most recent call last): ValueError: huhu >>> failure_while_unpacking(_it_failure(0)) Traceback (most recent call last): ValueError: huhu >>> a,b,c = _it_failure(1) Traceback (most recent call last): ValueError: huhu >>> failure_while_unpacking(_it_failure(1)) Traceback (most recent call last): ValueError: huhu >>> a,b,c = _it_failure(2) Traceback (most recent call last): ValueError: huhu >>> failure_while_unpacking(_it_failure(2)) Traceback (most recent call last): ValueError: huhu >>> a,b,c = _it_failure(3) Traceback (most recent call last): ValueError: huhu >>> failure_while_unpacking(_it_failure(3)) Traceback (most recent call last): ValueError: huhu >>> a,b,c = _it_failure(4) # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: too many values to unpack... >>> failure_while_unpacking(_it_failure(4)) Traceback (most recent call last): ValueError: too many values to unpack (expected 3) """ a,b,c = it return a,b,c def unpack_many(it): """ >>> items = range(1,13) >>> unpack_many(items) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) >>> unpack_many(iter(items)) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) >>> unpack_many(list(items)) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) >>> unpack_many(tuple(items)) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) """ a,b,c,d,e,f,g,h,i,j,k,l = it return a,b,c,d,e,f,g,h,i,j,k,l def unpack_many_tuple(tuple it): """ >>> items = range(1,13) >>> unpack_many_tuple(tuple(items)) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) """ a,b,c,d,e,f,g,h,i,j,k,l = it return a,b,c,d,e,f,g,h,i,j,k,l def unpack_many_list(list it): """ >>> items = range(1,13) >>> unpack_many_list(list(items)) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) """ a,b,c,d,e,f,g,h,i,j,k,l = it return a,b,c,d,e,f,g,h,i,j,k,l def unpack_many_int(it): """ >>> items = range(1,13) >>> unpack_many_int(items) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) >>> unpack_many_int(iter(items)) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) >>> unpack_many_int(list(items)) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) >>> unpack_many_int(tuple(items)) (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) """ cdef int b cdef long f cdef Py_ssize_t h a,b,c,d,e,f,g,h,i,j,k,l = it return a,b,c,d,e,f,g,h,i,j,k,l @cython.test_fail_if_path_exists('//PyTypeTestNode') def unpack_literal_none_to_builtin_type(): """ >>> unpack_literal_none_to_builtin_type() (None, None, None, None) """ cdef list a,b,c,d a, b = c, d = None, None return a,b,c,d cdef class ExtType: pass @cython.test_fail_if_path_exists('//PyTypeTestNode') def unpack_literal_none_to_exttype(): """ >>> unpack_literal_none_to_exttype() (None, None, None, None) """ cdef ExtType a,b,c,d a, b = c, d = None, None return a,b,c,d Cython-0.23.4/tests/run/unop_extras.pyx0000644000175600017570000000115112606202452021261 0ustar jenkinsjenkins00000000000000cimport cython.operator from cython.operator cimport dereference from cython.operator cimport dereference as deref def test_deref(int x): """ >>> test_deref(3) (3, 3, 3) >>> test_deref(5) (5, 5, 5) """ cdef int* x_ptr = &x return cython.operator.dereference(x_ptr), dereference(x_ptr), deref(x_ptr) def increment_decrement(int x): """ >>> increment_decrement(10) 11 11 12 11 11 10 10 """ print cython.operator.preincrement(x), cython.operator.postincrement(x), x print cython.operator.predecrement(x), cython.operator.postdecrement(x), x return x Cython-0.23.4/tests/run/unop.pyx0000644000175600017570000000060412606202452017675 0ustar jenkinsjenkins00000000000000def f(obj1, obj2, obj3): """ >>> f(1, 2, 3) (-3, -4, 1) """ cdef int bool1, bool2 cdef int int1, int2 cdef char *str1 int2 = obj3 str1 = NULL bool2 = 0 bool1 = not bool2 obj1 = not obj2 bool1 = not str1 int1 = +int2 obj1 = +obj2 int1 = -int2 obj1 = -obj2 int1 = ~int2 obj1 = ~obj2 return obj1, int1, bool1 Cython-0.23.4/tests/run/uninitialized.py0000644000175600017570000000713012606202452021375 0ustar jenkinsjenkins00000000000000# mode: run # tag: control-flow, uninitialized def conditional(cond): """ >>> conditional(True) [] >>> conditional(False) Traceback (most recent call last): ... UnboundLocalError: local variable 'a' referenced before assignment """ if cond: a = [] return a def inside_loop(iter): """ >>> inside_loop([1,2,3]) 3 >>> inside_loop([]) Traceback (most recent call last): ... UnboundLocalError: local variable 'i' referenced before assignment """ for i in iter: pass return i def try_except(cond): """ >>> try_except(True) [] >>> try_except(False) Traceback (most recent call last): ... UnboundLocalError: local variable 'a' referenced before assignment """ try: if cond: a = [] raise ValueError except ValueError: return a def try_finally(cond): """ >>> try_finally(True) [] >>> try_finally(False) Traceback (most recent call last): ... UnboundLocalError: local variable 'a' referenced before assignment """ try: if cond: a = [] raise ValueError finally: return a def deleted(cond): """ >>> deleted(False) {} >>> deleted(True) Traceback (most recent call last): ... UnboundLocalError: local variable 'a' referenced before assignment """ a = {} if cond: del a return a def test_nested(cond): """ >>> test_nested(True) >>> test_nested(False) Traceback (most recent call last): ... UnboundLocalError: local variable 'a' referenced before assignment """ if cond: def a(): pass return a() def test_outer(cond): """ >>> test_outer(True) {} >>> test_outer(False) Traceback (most recent call last): ... UnboundLocalError: local variable 'a' referenced before assignment """ if cond: a = {} def inner(): return a return a def test_inner(cond): """ >>> test_inner(True) {} >>> test_inner(False) Traceback (most recent call last): ... NameError: free variable 'a' referenced before assignment in enclosing scope """ if cond: a = {} def inner(): return a return inner() def test_class(cond): """ >>> test_class(True) 1 >>> test_class(False) Traceback (most recent call last): ... UnboundLocalError: local variable 'A' referenced before assignment """ if cond: class A: x = 1 return A.x def test_try_except_regression(c): """ >>> test_try_except_regression(True) (123,) >>> test_try_except_regression(False) Traceback (most recent call last): ... UnboundLocalError: local variable 'a' referenced before assignment """ if c: a = (123,) try: return a except: return a def test_try_finally_regression(c): """ >>> test_try_finally_regression(True) (123,) >>> test_try_finally_regression(False) Traceback (most recent call last): ... UnboundLocalError: local variable 'a' referenced before assignment """ if c: a = (123,) try: return a finally: return a def test_expression_calculation_order_bug(a): """ >>> test_expression_calculation_order_bug(False) [] >>> test_expression_calculation_order_bug(True) Traceback (most recent call last): ... UnboundLocalError: local variable 'b' referenced before assignment """ if not a: b = [] return (a or b) and (b or a) Cython-0.23.4/tests/run/unicodemethods.pyx0000644000175600017570000004273112606202452021735 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- cimport cython import sys PY_VERSION = sys.version_info text = u'ab jd sdflk as sa sadas asdas fsdf ' sep = u' ' format1 = u'abc%sdef' format2 = u'abc%sdef%sghi' unicode_sa = u'sa' multiline_text = u'''\ ab jd sdflk as sa sadas asdas fsdf ''' def print_all(l): for s in l: print(s) # unicode.split(s, [sep, [maxsplit]]) @cython.test_assert_path_exists( "//PythonCapiCallNode") def split(unicode s): """ >>> print_all( text.split() ) ab jd sdflk as sa sadas asdas fsdf >>> print_all( split(text) ) ab jd sdflk as sa sadas asdas fsdf """ return s.split() @cython.test_assert_path_exists( "//PythonCapiCallNode") def split_sep(unicode s, sep): """ >>> print_all( text.split(sep) ) ab jd sdflk as sa sadas asdas fsdf >>> print_all( split_sep(text, sep) ) ab jd sdflk as sa sadas asdas fsdf """ return s.split(sep) @cython.test_fail_if_path_exists( "//CoerceToPyTypeNode", "//CastNode", "//TypecastNode") @cython.test_assert_path_exists( "//CoerceFromPyTypeNode", "//PythonCapiCallNode") def split_sep_max(unicode s, sep, max): """ >>> print_all( text.split(sep, 1) ) ab jd sdflk as sa sadas asdas fsdf >>> print_all( split_sep_max(text, sep, 1) ) ab jd sdflk as sa sadas asdas fsdf """ return s.split(sep, max) @cython.test_fail_if_path_exists( "//CoerceToPyTypeNode", "//CoerceFromPyTypeNode", "//CastNode", "//TypecastNode") @cython.test_assert_path_exists( "//PythonCapiCallNode") def split_sep_max_int(unicode s, sep): """ >>> print_all( text.split(sep, 1) ) ab jd sdflk as sa sadas asdas fsdf >>> print_all( split_sep_max_int(text, sep) ) ab jd sdflk as sa sadas asdas fsdf """ return s.split(sep, 1) # unicode.splitlines(s, [keepends]) @cython.test_assert_path_exists( "//PythonCapiCallNode") def splitlines(unicode s): """ >>> len(multiline_text.splitlines()) 3 >>> print_all( multiline_text.splitlines() ) ab jd sdflk as sa sadas asdas fsdf >>> len(splitlines(multiline_text)) 3 >>> print_all( splitlines(multiline_text) ) ab jd sdflk as sa sadas asdas fsdf """ return s.splitlines() @cython.test_assert_path_exists( "//PythonCapiCallNode") def splitlines_keep(unicode s, keep): """ >>> len(multiline_text.splitlines(True)) 3 >>> print_all( multiline_text.splitlines(True) ) ab jd sdflk as sa sadas asdas fsdf >>> len(splitlines_keep(multiline_text, True)) 3 >>> print_all( splitlines_keep(multiline_text, True) ) ab jd sdflk as sa sadas asdas fsdf """ return s.splitlines(keep) @cython.test_fail_if_path_exists( "//CoerceToPyTypeNode", "//CoerceFromPyTypeNode", "//CastNode", "//TypecastNode") @cython.test_assert_path_exists( "//PythonCapiCallNode") def splitlines_keep_bint(unicode s): """ >>> len(multiline_text.splitlines(True)) 3 >>> print_all( multiline_text.splitlines(True) ) ab jd sdflk as sa sadas asdas fsdf >>> print_all( multiline_text.splitlines(False) ) ab jd sdflk as sa sadas asdas fsdf >>> len(splitlines_keep_bint(multiline_text)) 7 >>> print_all( splitlines_keep_bint(multiline_text) ) ab jd sdflk as sa sadas asdas fsdf -- ab jd sdflk as sa sadas asdas fsdf """ return s.splitlines(True) + ['--'] + s.splitlines(False) # unicode.join(s, iterable) pipe_sep = u'|' @cython.test_fail_if_path_exists( "//CoerceToPyTypeNode", "//CoerceFromPyTypeNode", "//CastNode", "//TypecastNode", "//SimpleCallNode//AttributeNode[@is_py_attr = true]") @cython.test_assert_path_exists( "//PythonCapiCallNode", ) def join(unicode sep, l): """ >>> l = text.split() >>> len(l) 8 >>> print( pipe_sep.join(l) ) ab|jd|sdflk|as|sa|sadas|asdas|fsdf >>> print( join(pipe_sep, l) ) ab|jd|sdflk|as|sa|sadas|asdas|fsdf """ return sep.join(l) @cython.test_fail_if_path_exists( "//CoerceToPyTypeNode", "//CoerceFromPyTypeNode", "//CastNode", "//TypecastNode", "//NoneCheckNode", "//SimpleCallNode//AttributeNode[@is_py_attr = true]") @cython.test_assert_path_exists( "//PythonCapiCallNode", ) def join_sep(l): """ >>> l = text.split() >>> len(l) 8 >>> print( '|'.join(l) ) ab|jd|sdflk|as|sa|sadas|asdas|fsdf >>> print( join_sep(l) ) ab|jd|sdflk|as|sa|sadas|asdas|fsdf """ result = u'|'.join(l) assert cython.typeof(result) == 'unicode object', cython.typeof(result) return result @cython.test_fail_if_path_exists( "//CoerceToPyTypeNode", "//CoerceFromPyTypeNode", "//CastNode", "//TypecastNode", "//NoneCheckNode", "//SimpleCallNode//AttributeNode[@is_py_attr = true]" ) @cython.test_assert_path_exists( "//PythonCapiCallNode", "//InlinedGeneratorExpressionNode" ) def join_sep_genexpr(l): """ >>> l = text.split() >>> len(l) 8 >>> print( '<<%s>>' % '|'.join(s + ' ' for s in l) ) <> >>> print( '<<%s>>' % join_sep_genexpr(l) ) <> """ result = u'|'.join(s + u' ' for s in l) assert cython.typeof(result) == 'unicode object', cython.typeof(result) return result @cython.test_fail_if_path_exists( "//CoerceToPyTypeNode", "//CoerceFromPyTypeNode", "//CastNode", "//TypecastNode", ) @cython.test_assert_path_exists( "//PythonCapiCallNode", "//InlinedGeneratorExpressionNode" ) def join_sep_genexpr_dictiter(dict d): """ >>> l = text.split() >>> d = dict(zip(range(len(l)), l)) >>> print('|'.join( sorted(' '.join('%s:%s' % (k, v) for k, v in d.items()).split()) )) 0:ab|1:jd|2:sdflk|3:as|4:sa|5:sadas|6:asdas|7:fsdf >>> print('|'.join( sorted(join_sep_genexpr_dictiter(d).split())) ) 0:ab|1:jd|2:sdflk|3:as|4:sa|5:sadas|6:asdas|7:fsdf """ result = u' '.join('%s:%s' % (k, v) for k, v in d.iteritems()) assert cython.typeof(result) == 'unicode object', cython.typeof(result) return result @cython.test_assert_path_exists( "//PythonCapiCallNode", ) def join_unbound(unicode sep, l): """ >>> l = text.split() >>> len(l) 8 >>> print( pipe_sep.join(l) ) ab|jd|sdflk|as|sa|sadas|asdas|fsdf >>> print( join_unbound(pipe_sep, l) ) ab|jd|sdflk|as|sa|sadas|asdas|fsdf """ join = unicode.join return join(sep, l) # unicode.startswith(s, prefix, [start, [end]]) @cython.test_fail_if_path_exists( "//CoerceToPyTypeNode", "//CoerceFromPyTypeNode", "//CastNode", "//TypecastNode") @cython.test_assert_path_exists( "//PythonCapiCallNode") def startswith(unicode s, sub): """ >>> text.startswith('ab ') True >>> startswith(text, 'ab ') 'MATCH' >>> text.startswith('ab X') False >>> startswith(text, 'ab X') 'NO MATCH' >>> PY_VERSION < (2,5) or text.startswith(('ab', 'ab ')) True >>> startswith(text, ('ab', 'ab ')) 'MATCH' >>> PY_VERSION < (2,5) or not text.startswith((' ab', 'ab X')) True >>> startswith(text, (' ab', 'ab X')) 'NO MATCH' """ if s.startswith(sub): return 'MATCH' else: return 'NO MATCH' @cython.test_fail_if_path_exists( "//CoerceToPyTypeNode", "//CastNode", "//TypecastNode") @cython.test_assert_path_exists( "//CoerceFromPyTypeNode", "//PythonCapiCallNode") def startswith_start_end(unicode s, sub, start, end): """ >>> text.startswith('b ', 1, 5) True >>> startswith_start_end(text, 'b ', 1, 5) 'MATCH' >>> text.startswith('ab ', -1000, 5000) True >>> startswith_start_end(text, 'ab ', -1000, 5000) 'MATCH' >>> text.startswith('b X', 1, 5) False >>> startswith_start_end(text, 'b X', 1, 5) 'NO MATCH' """ if s.startswith(sub, start, end): return 'MATCH' else: return 'NO MATCH' # unicode.endswith(s, prefix, [start, [end]]) @cython.test_fail_if_path_exists( "//CoerceToPyTypeNode", "//CoerceFromPyTypeNode", "//CastNode", "//TypecastNode") @cython.test_assert_path_exists( "//PythonCapiCallNode") def endswith(unicode s, sub): """ >>> text.endswith('fsdf ') True >>> endswith(text, 'fsdf ') 'MATCH' >>> text.endswith('fsdf X') False >>> endswith(text, 'fsdf X') 'NO MATCH' >>> PY_VERSION < (2,5) or text.endswith(('fsdf', 'fsdf ')) True >>> endswith(text, ('fsdf', 'fsdf ')) 'MATCH' >>> PY_VERSION < (2,5) or not text.endswith(('fsdf', 'fsdf X')) True >>> endswith(text, ('fsdf', 'fsdf X')) 'NO MATCH' """ if s.endswith(sub): return 'MATCH' else: return 'NO MATCH' @cython.test_fail_if_path_exists( "//CoerceToPyTypeNode", "//CastNode", "//TypecastNode") @cython.test_assert_path_exists( "//CoerceFromPyTypeNode", "//PythonCapiCallNode") def endswith_start_end(unicode s, sub, start, end): """ >>> text.endswith('fsdf', 10, len(text)-1) True >>> endswith_start_end(text, 'fsdf', 10, len(text)-1) 'MATCH' >>> text.endswith('fsdf ', 10, len(text)-1) False >>> endswith_start_end(text, 'fsdf ', 10, len(text)-1) 'NO MATCH' >>> text.endswith('fsdf ', -1000, 5000) True >>> endswith_start_end(text, 'fsdf ', -1000, 5000) 'MATCH' >>> PY_VERSION < (2,5) or text.endswith(('fsd', 'fsdf'), 10, len(text)-1) True >>> endswith_start_end(text, ('fsd', 'fsdf'), 10, len(text)-1) 'MATCH' >>> PY_VERSION < (2,5) or not text.endswith(('fsdf ', 'fsdf X'), 10, len(text)-1) True >>> endswith_start_end(text, ('fsdf ', 'fsdf X'), 10, len(text)-1) 'NO MATCH' """ if s.endswith(sub, start, end): return 'MATCH' else: return 'NO MATCH' # unicode.__contains__(s, sub) @cython.test_fail_if_path_exists( "//CoerceFromPyTypeNode", "//AttributeNode") @cython.test_assert_path_exists( "//CoerceToPyTypeNode", "//PrimaryCmpNode") def in_test(unicode s, substring): """ >>> in_test(text, 'sa') True >>> in_test(text, 'XYZ') False >>> in_test(None, 'sa') Traceback (most recent call last): TypeError: 'NoneType' object is not iterable """ return substring in s # unicode.__concat__(s, suffix) def concat_any(unicode s, suffix): """ >>> concat(text, 'sa') == text + 'sa' or concat(text, 'sa') True >>> concat(None, 'sa') # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> concat(text, None) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> class RAdd(object): ... def __radd__(self, other): ... return 123 >>> concat(None, 'sa') # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... """ assert cython.typeof(s + suffix) == 'Python object', cython.typeof(s + suffix) return s + suffix def concat(unicode s, str suffix): """ >>> concat(text, 'sa') == text + 'sa' or concat(text, 'sa') True >>> concat(None, 'sa') # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> concat(text, None) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> class RAdd(object): ... def __radd__(self, other): ... return 123 >>> concat(None, 'sa') # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... """ assert cython.typeof(s + object()) == 'Python object', cython.typeof(s + object()) assert cython.typeof(s + suffix) == 'unicode object', cython.typeof(s + suffix) return s + suffix def concat_literal_str(str suffix): """ >>> concat_literal_str('sa') == 'abcsa' or concat_literal_str('sa') True >>> concat_literal_str(None) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...NoneType... """ assert cython.typeof(u'abc' + object()) == 'Python object', cython.typeof(u'abc' + object()) assert cython.typeof(u'abc' + suffix) == 'unicode object', cython.typeof(u'abc' + suffix) return u'abc' + suffix def concat_literal_unicode(unicode suffix): """ >>> concat_literal_unicode(unicode_sa) == 'abcsa' or concat_literal_unicode(unicode_sa) True >>> concat_literal_unicode(None) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...NoneType... """ assert cython.typeof(u'abc' + suffix) == 'unicode object', cython.typeof(u'abc' + suffix) return u'abc' + suffix # unicode.__mod__(format, values) def mod_format(unicode s, values): """ >>> mod_format(format1, 'sa') == 'abcsadef' or mod_format(format1, 'sa') True >>> mod_format(format2, ('XYZ', 'ABC')) == 'abcXYZdefABCghi' or mod_format(format2, ('XYZ', 'ABC')) True >>> mod_format(None, 'sa') # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: unsupported operand type(s) for %: 'NoneType' and 'str' >>> class RMod(object): ... def __rmod__(self, other): ... return 123 >>> mod_format(None, RMod()) 123 """ assert cython.typeof(s % values) == 'Python object', cython.typeof(s % values) return s % values def mod_format_literal(values): """ >>> mod_format_literal('sa') == 'abcsadef' or mod_format(format1, 'sa') True >>> mod_format_literal(('sa',)) == 'abcsadef' or mod_format(format1, ('sa',)) True >>> mod_format_literal(['sa']) == "abc['sa']def" or mod_format(format1, ['sa']) True """ assert cython.typeof(u'abc%sdef' % values) == 'unicode object', cython.typeof(u'abc%sdef' % values) return u'abc%sdef' % values def mod_format_tuple(*values): """ >>> mod_format_tuple('sa') == 'abcsadef' or mod_format(format1, 'sa') True >>> mod_format_tuple() Traceback (most recent call last): TypeError: not enough arguments for format string """ assert cython.typeof(u'abc%sdef' % values) == 'unicode object', cython.typeof(u'abc%sdef' % values) return u'abc%sdef' % values # unicode.find(s, sub, [start, [end]]) @cython.test_fail_if_path_exists( "//CoerceFromPyTypeNode", "//CastNode", "//TypecastNode") @cython.test_assert_path_exists( "//CoerceToPyTypeNode", "//PythonCapiCallNode") def find(unicode s, substring): """ >>> text.find('sa') 16 >>> find(text, 'sa') 16 """ cdef Py_ssize_t pos = s.find(substring) return pos @cython.test_fail_if_path_exists( "//CastNode", "//TypecastNode") @cython.test_assert_path_exists( "//CoerceToPyTypeNode", "//PythonCapiCallNode") def find_start_end(unicode s, substring, start, end): """ >>> text.find('sa', 17, 25) 20 >>> find_start_end(text, 'sa', 17, 25) 20 """ cdef Py_ssize_t pos = s.find(substring, start, end) return pos # unicode.rfind(s, sub, [start, [end]]) @cython.test_fail_if_path_exists( "//CoerceFromPyTypeNode", "//CastNode", "//TypecastNode") @cython.test_assert_path_exists( "//CoerceToPyTypeNode", "//PythonCapiCallNode") def rfind(unicode s, substring): """ >>> text.rfind('sa') 20 >>> rfind(text, 'sa') 20 """ cdef Py_ssize_t pos = s.rfind(substring) return pos @cython.test_fail_if_path_exists( "//CastNode", "//TypecastNode") @cython.test_assert_path_exists( "//CoerceToPyTypeNode", "//PythonCapiCallNode") def rfind_start_end(unicode s, substring, start, end): """ >>> text.rfind('sa', 14, 19) 16 >>> rfind_start_end(text, 'sa', 14, 19) 16 """ cdef Py_ssize_t pos = s.rfind(substring, start, end) return pos # unicode.count(s, sub, [start, [end]]) @cython.test_fail_if_path_exists( "//CoerceFromPyTypeNode", "//CastNode", "//TypecastNode") @cython.test_assert_path_exists( "//CoerceToPyTypeNode", "//PythonCapiCallNode") def count(unicode s, substring): """ >>> text.count('sa') 2 >>> count(text, 'sa') 2 """ cdef Py_ssize_t pos = s.count(substring) return pos @cython.test_fail_if_path_exists( "//CastNode", "//TypecastNode") @cython.test_assert_path_exists( "//CoerceToPyTypeNode", "//PythonCapiCallNode") def count_start_end(unicode s, substring, start, end): """ >>> text.count('sa', 14, 21) 1 >>> text.count('sa', 14, 22) 2 >>> count_start_end(text, 'sa', 14, 21) 1 >>> count_start_end(text, 'sa', 14, 22) 2 """ cdef Py_ssize_t pos = s.count(substring, start, end) return pos # unicode.replace(s, sub, repl, [maxcount]) @cython.test_fail_if_path_exists( "//CoerceFromPyTypeNode", "//CastNode", "//TypecastNode") @cython.test_assert_path_exists( "//PythonCapiCallNode") def replace(unicode s, substring, repl): """ >>> print( text.replace('sa', 'SA') ) ab jd sdflk as SA SAdas asdas fsdf >>> print( replace(text, 'sa', 'SA') ) ab jd sdflk as SA SAdas asdas fsdf """ return s.replace(substring, repl) @cython.test_fail_if_path_exists( "//CastNode", "//TypecastNode") @cython.test_assert_path_exists( "//CoerceFromPyTypeNode", "//PythonCapiCallNode") def replace_maxcount(unicode s, substring, repl, maxcount): """ >>> print( text.replace('sa', 'SA', 1) ) ab jd sdflk as SA sadas asdas fsdf >>> print( replace_maxcount(text, 'sa', 'SA', 1) ) ab jd sdflk as SA sadas asdas fsdf """ return s.replace(substring, repl, maxcount) Cython-0.23.4/tests/run/unicodeliteralslatin1.pyx0000644000175600017570000000270112606202452023213 0ustar jenkinsjenkins00000000000000# -*- coding: latin-1 -*- __doc__ = br""" >>> sa 'abc' >>> ua u'abc' >>> b u'123' >>> c u'S\xf8k ik' >>> d u'\xfc\xd6\xe4' >>> e u'\x03g\xf8\uf8d2S\xf8k ik' >>> f u'\xf8' >>> add u'S\xf8k ik\xfc\xd6\xe4abc' >>> null u'\x00' """.decode("ASCII") + b""" >>> len(sa) 3 >>> len(ua) 3 >>> len(b) 3 >>> len(c) 6 >>> len(d) 3 >>> len(e) 10 >>> len(f) 1 >>> len(add) 12 >>> len(null) 1 """.decode("ASCII") + u""" >>> ua == u'abc' True >>> b == u'123' True >>> c == u'Søk ik' True >>> d == u'üÖä' True >>> e == u'\x03\x67\xf8\uf8d2Søk ik' # unescaped by Cython True >>> e == u'\\x03\\x67\\xf8\\uf8d2Søk ik' # unescaped by Python True >>> f == u'\xf8' # unescaped by Cython True >>> f == u'\\xf8' # unescaped by Python True >>> k == u'ä' == u'\\N{LATIN SMALL LETTER A WITH DIAERESIS}' True >>> add == u'Søk ik' + u'üÖä' + 'abc' True >>> null == u'\\x00' # unescaped by Python (required by doctest) True """ import sys if sys.version_info[0] >= 3: __doc__ = __doc__.replace(u" u'", u" '") else: __doc__ = __doc__.replace(u" b'", u" '") sa = 'abc' ua = u'abc' b = u'123' c = u'Søk ik' d = u'üÖä' e = u'\x03\x67\xf8\uf8d2Søk ik' f = u'\xf8' k = u'\N{LATIN SMALL LETTER A WITH DIAERESIS}' add = u'Søk ik' + u'üÖä' + u'abc' null = u'\x00' Cython-0.23.4/tests/run/unicodeliteralsdefault.pyx0000644000175600017570000000276412606202452023460 0ustar jenkinsjenkins00000000000000## keep two lines free to make sure PEP 263 does not apply ## ## # This file is written in UTF-8, but it has no encoding declaration, # so it just defaults to UTF-8 (PEP 3120). __doc__ = br""" >>> sa 'abc' >>> ua u'abc' >>> b u'123' >>> c u'S\xf8k ik' >>> d u'\xfc\xd6\xe4' >>> e u'\x03g\xf8\uf8d2S\xf8k ik' >>> f u'\xf8' >>> add u'S\xf8k ik\xfc\xd6\xe4abc' >>> null u'\x00' """.decode("ASCII") + b""" >>> len(sa) 3 >>> len(ua) 3 >>> len(b) 3 >>> len(c) 6 >>> len(d) 3 >>> len(e) 10 >>> len(f) 1 >>> len(add) 12 >>> len(null) 1 """.decode("ASCII") + u""" >>> ua == u'abc' True >>> b == u'123' True >>> c == u'Søk ik' True >>> d == u'üÖä' True >>> e == u'\x03\x67\xf8\uf8d2Søk ik' # unescaped by Cython True >>> e == u'\\x03\\x67\\xf8\\uf8d2Søk ik' # unescaped by Python True >>> f == u'\xf8' # unescaped by Cython True >>> f == u'\\xf8' # unescaped by Python True >>> add == u'Søk ik' + u'üÖä' + 'abc' True >>> null == u'\\x00' # unescaped by Python (required by doctest) True """ import sys if sys.version_info[0] >= 3: __doc__ = __doc__.replace(u" u'", u" '") else: __doc__ = __doc__.replace(u" b'", u" '") sa = 'abc' ua = u'abc' b = u'123' c = u'Søk ik' d = u'üÖä' e = u'\x03\x67\xf8\uf8d2Søk ik' f = u'\xf8' add = u'Søk ik' + u'üÖä' + u'abc' null = u'\x00' Cython-0.23.4/tests/run/unicodeliterals.pyx0000644000175600017570000000451512606202452022107 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- import sys __doc__ = br""" >>> sa 'abc' >>> ua u'abc' >>> b u'123' >>> c u'S\xf8k ik' >>> d u'\xfc\xd6\xe4' >>> e u'\x03g\xf8\uf8d2S\xf8k ik' >>> f u'\xf8' >>> g u'\udc00' >>> h u'\ud800' >>> add u'S\xf8k ik\xfc\xd6\xe4abc' >>> null u'\x00' """.decode("ASCII") + b""" >>> len(sa) 3 >>> len(ua) 3 >>> len(b) 3 >>> len(c) 6 >>> len(d) 3 >>> len(e) 10 >>> len(f) 1 >>> len(g) 1 >>> len(h) 1 >>> len(add) 12 >>> len(null) 1 >>> sys.maxunicode >= 65535 True >>> sys.maxunicode == 65535 and 1 or len(wide_literal) # test for wide build 1 >>> sys.maxunicode > 65535 and 2 or len(wide_literal) # test for narrow build 2 """.decode("ASCII") + u""" >>> ua == u'abc' True >>> b == u'123' True >>> c == u'Søk ik' True >>> d == u'üÖä' True >>> e == u'\x03\x67\xf8\uf8d2Søk ik' # unescaped by Cython True >>> e == u'\\x03\\x67\\xf8\\uf8d2Søk ik' # unescaped by Python True >>> f == u'\xf8' # unescaped by Cython True >>> f == u'\\xf8' # unescaped by Python True >>> g == u'\\udc00' # unescaped by Python (required by doctest) True >>> h == u'\\ud800' # unescaped by Python (required by doctest) True >>> k == u'\\N{SNOWMAN}' == u'\\u2603' True >>> add == u'Søk ik' + u'üÖä' + 'abc' True >>> null == u'\\x00' # unescaped by Python (required by doctest) True >>> wide_literal == u'\\U00101234' # unescaped by Python True """ if sys.version_info >= (2,6,5): # this doesn't work well in older Python versions __doc__ += u"""\ >>> expected = u'\U00101234' # unescaped by Cython >>> if wide_literal == expected: print(True) ... else: print(repr(wide_literal), repr(expected), sys.maxunicode) True """ if sys.version_info[0] >= 3: __doc__ = __doc__.replace(u" u'", u" '") else: __doc__ = __doc__.replace(u" b'", u" '") sa = 'abc' ua = u'abc' b = u'123' c = u'Søk ik' d = u'üÖä' e = u'\x03\x67\xf8\uf8d2Søk ik' f = u'\xf8' g = u'\udc00' # lone trail surrogate h = u'\ud800' # lone lead surrogate k = u'\N{SNOWMAN}' add = u'Søk ik' + u'üÖä' + u'abc' null = u'\x00' wide_literal = u'\U00101234' Cython-0.23.4/tests/run/unicodefunction.pyx0000644000175600017570000000126412606202452022113 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> u('test') u'test' >>> z u'test' >>> c('testing') u'testing' >>> subu('testing a Python subtype') u'testing a Python subtype' >>> sub('testing a Python subtype') u'testing a Python subtype' # >>> csubu('testing a C subtype') # u'testing a C subtype' # >>> csub('testing a C subtype') # u'testing a C subtype' """ import sys if sys.version_info[0] >= 3: __doc__ = __doc__.replace(u" u'", u" '") u = unicode z = unicode(u'test') def c(string): return unicode(string) class subu(unicode): pass def sub(string): return subu(string) #cdef class csubu(unicode): # pass #def csub(string): # return csubu(string) Cython-0.23.4/tests/run/unicodeencode.pyx0000644000175600017570000000512712606202452021525 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- __doc__ = u""" >>> len(u) 15 """ cimport cython _bytes = bytes cdef unicode text = u'abcäöüöéèâÃÀABC' u = text def default(): """ >>> default() == 'abcdefg'.encode() True """ return u'abcdefg'.encode() def encode_non_constant(encoding): """ >>> isinstance(encode_non_constant('utf8'), _bytes) True >>> encode_non_constant('utf8') == u.encode('UTF-8') True """ return text.encode(encoding) @cython.test_assert_path_exists('//PythonCapiFunctionNode[@cname = "PyUnicode_AsUTF8String"]') def utf8(): """ >>> isinstance(utf8(), _bytes) True >>> utf8() == u.encode('UTF-8') True """ return text.encode(u'UTF-8') @cython.test_assert_path_exists('//PythonCapiFunctionNode[@cname = "PyUnicode_AsUTF8String"]') def utf8_strict(): """ >>> isinstance(utf8_strict(), _bytes) True >>> utf8_strict() == u.encode('UTF-8', 'strict') True """ return text.encode(u'UTF-8', u'strict') @cython.test_assert_path_exists('//PythonCapiFunctionNode[@cname = "PyUnicode_AsUTF8String"]') def utf8_str_strict(): """ >>> isinstance(utf8_str_strict(), _bytes) True >>> utf8_str_strict() == u.encode('UTF-8', 'strict') True """ return text.encode('UTF-8', 'strict') @cython.test_assert_path_exists('//PythonCapiFunctionNode[@cname = "PyUnicode_AsUTF8String"]') def utf8_bytes_strict(): """ >>> isinstance(utf8_bytes_strict(), _bytes) True >>> utf8_bytes_strict() == u.encode('UTF-8', 'strict') True """ return text.encode(b'UTF-8', b'strict') @cython.test_assert_path_exists('//PythonCapiFunctionNode[@cname = "PyUnicode_AsEncodedString"]') def ascii_replace(): """ >>> isinstance(ascii_replace(), _bytes) True >>> ascii_replace() == u.encode('ASCII', 'replace') True """ return text.encode(u'ASCII', u'replace') def cp850_strict(): """ >>> isinstance(cp850_strict(), _bytes) True >>> cp850_strict() == u.encode('cp850', 'strict') True """ return text.encode(u'cp850', u'strict') @cython.test_assert_path_exists('//PythonCapiFunctionNode[@cname = "PyUnicode_AsLatin1String"]') def latin1(): """ >>> isinstance(latin1(), _bytes) True >>> latin1() == u.encode('latin-1') True """ return text.encode(u'latin-1') @cython.test_fail_if_path_exists('//PythonCapiFunctionNode', '//SimpleCallNode') def latin1_constant(): """ >>> isinstance(latin1_constant(), _bytes) True >>> latin1_constant() == latin1() True """ return u'abcäöüöéèâÃÀABC'.encode('latin1') Cython-0.23.4/tests/run/unicode_slicing.pyx0000644000175600017570000001130312606202452022050 0ustar jenkinsjenkins00000000000000# coding: utf-8 __doc__ = u""" >>> slice_start_end(u'abcdef', 2, 3) c >>> slice_start(u'abcdef', 2, 3) cdef >>> slice_end(u'abcdef', 2, 3) ab >>> slice_all(u'abcdef', 2, 3) abcdef >>> slice_start_none(u'abcdef', 2, 3) cdef >>> slice_none_end(u'abcdef', 2, 3) ab >>> slice_none_none(u'abcdef', 2, 3) abcdef >>> slice_start_end(u'abcdef', 2, 10) cdef >>> slice_start(u'abcdef', 2, 10) cdef >>> slice_end(u'abcdef', 2, 10) ab >>> slice_all(u'abcdef', 2, 10) abcdef >>> slice_start_end(u'abcdef', 0, 5) abcde >>> slice_start(u'abcdef', 0, 5) abcdef >>> slice_end(u'abcdef', 0, 5) >>> slice_all(u'abcdef', 0, 5) abcdef >>> slice_start_none(u'abcdef', 0, 5) abcdef >>> slice_none_end(u'abcdef', 0, 5) >>> slice_none_none(u'abcdef', 0, 5) abcdef >>> slice_start_end(u'abcdef', -6, -1) abcde >>> slice_start(u'abcdef', -6, -1) abcdef >>> slice_end(u'abcdef', -6, -1) >>> slice_all(u'abcdef', -6, -1) abcdef >>> slice_start_none(u'abcdef', -6, -1) abcdef >>> slice_none_end(u'abcdef', -6, -1) >>> slice_none_none(u'abcdef', -6, -1) abcdef >>> slice_start_end(u'abcdef', -6, -7) >>> slice_start(u'abcdef', -6, -7) abcdef >>> slice_end(u'abcdef', -6, -7) >>> slice_all(u'abcdef', -6, -7) abcdef >>> slice_start_none(u'abcdef', -6, -7) abcdef >>> slice_none_end(u'abcdef', -6, -7) >>> slice_none_none(u'abcdef', -6, -7) abcdef >>> slice_start_end(u'abcdef', -7, -7) >>> slice_start(u'abcdef', -7, -7) abcdef >>> slice_end(u'abcdef', -7, -7) >>> slice_all(u'abcdef', -7, -7) abcdef >>> slice_start_none(u'abcdef', -7, -7) abcdef >>> slice_none_end(u'abcdef', -7, -7) >>> slice_none_none(u'abcdef', -7, -7) abcdef >>> slice_start_end(u'aÐbБcСdДeЕfФ', 2, 8) bБcСdД >>> slice_start(u'aÐbБcСdДeЕfФ', 2, 8) bБcСdДeЕfФ >>> slice_end(u'aÐbБcСdДeЕfФ', 2, 8) aÐ >>> slice_all(u'aÐbБcСdДeЕfФ', 2, 8) aÐbБcСdДeЕfФ >>> slice_start_none(u'aÐbБcСdДeЕfФ', 2, 8) bБcСdДeЕfФ >>> slice_none_end(u'aÐbБcСdДeЕfФ', 2, 8) aÐ >>> slice_none_none(u'aÐbБcСdДeЕfФ', 2, 8) aÐbБcСdДeЕfФ >>> slice_start_end(u'ÐБСДЕФ', 2, 4) СД >>> slice_start(u'ÐБСДЕФ', 2, 4) СДЕФ >>> slice_end(u'ÐБСДЕФ', 2, 4) ÐБ >>> slice_all(u'ÐБСДЕФ', 2, 4) ÐБСДЕФ >>> slice_start_none(u'ÐБСДЕФ', 2, 4) СДЕФ >>> slice_none_end(u'ÐБСДЕФ', 2, 4) ÐБ >>> slice_none_none(u'ÐБСДЕФ', 2, 4) ÐБСДЕФ >>> slice_start_end(u'ÐБСДЕФ', -4, -2) СД >>> slice_start(u'ÐБСДЕФ', -4, -2) СДЕФ >>> slice_end(u'ÐБСДЕФ', -4, -2) ÐБ >>> slice_all(u'ÐБСДЕФ', -4, -2) ÐБСДЕФ >>> slice_start_none(u'ÐБСДЕФ', -4, -2) СДЕФ >>> slice_none_end(u'ÐБСДЕФ', -4, -2) ÐБ >>> slice_none_none(u'ÐБСДЕФ', -4, -2) ÐБСДЕФ >>> slice_start_end(None, 2, 4) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable >>> slice_start(None, 2, 4) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable >>> slice_end(None, 2, 4) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable >>> slice_all(None, 2, 4) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable >>> slice_start_none(None, 2, 4) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable >>> slice_none_end(None, 2, 4) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable >>> slice_none_none(None, 2, 4) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable """ import sys if sys.version_info[0] >= 3: __doc__ = __doc__.replace(u"(u'", u"('").replace(u" u'", u" '") def slice_start_end(unicode s, int i, int j): print(s[i:j]) def slice_start(unicode s, int i, int j): print(s[i:]) def slice_end(unicode s, int i, int j): print(s[:i]) def slice_all(unicode s, int i, int j): print(s[:]) def slice_start_none(unicode s, int i, int j): print(s[i:None]) def slice_none_end(unicode s, int i, int j): print(s[None:i]) def slice_none_none(unicode s, int i, int j): print(s[None:None]) Cython-0.23.4/tests/run/unicode_kwargs.pyx0000644000175600017570000000332512606202452021723 0ustar jenkinsjenkins00000000000000# -*- coding: utf8 -*- try: import platform IS_PYPY = platform.python_implementation() == 'PyPy' except (ImportError, AttributeError): IS_PYPY = False ustring_a = u'a' ustring_ascii = u'abc' ustring_nonascii = u'àöé\u0888' def accept_kwargs(a, b, c=1, **kwargs): """ >>> accept_kwargs(1, 2, 3) (1, 2, 3, {}) >>> accept_kwargs(1, 2, 3, d=5) (1, 2, 3, {'d': 5}) >>> accept_kwargs(1, 2, 3, **{ustring_a: 5}) Traceback (most recent call last): TypeError: accept_kwargs() got multiple values for keyword argument 'a' >>> if not IS_PYPY: a, b, c, kwargs = accept_kwargs(1, 2, 3, **{ustring_ascii: 5}) >>> IS_PYPY and (1,2,3,1) or (a,b,c,len(kwargs)) (1, 2, 3, 1) >>> IS_PYPY and 5 or kwargs[ustring_ascii] 5 >>> if not IS_PYPY: a, b, c, kwargs = accept_kwargs(1, 2, 3, **{ustring_nonascii: 5}) >>> IS_PYPY and (1,2,3,1) or (a,b,c,len(kwargs)) (1, 2, 3, 1) >>> IS_PYPY and 5 or kwargs[ustring_nonascii] 5 >>> if not IS_PYPY: a, b, c, kwargs = accept_kwargs(1, 2, 3, **{ustring_nonascii: 5, ustring_ascii: 6}) >>> IS_PYPY and (1,2,3,2) or (a,b,c,len(kwargs)) (1, 2, 3, 2) >>> IS_PYPY and 5 or kwargs[ustring_nonascii] 5 >>> IS_PYPY and 6 or kwargs[ustring_ascii] 6 """ return a, b, c, kwargs def unexpected_kwarg(a, b, c=1): """ >>> unexpected_kwarg(1, b=2) (1, 2, 1) >>> unexpected_kwarg(1, 2, **{ustring_ascii: 5}) Traceback (most recent call last): TypeError: unexpected_kwarg() got an unexpected keyword argument 'abc' >>> unexpected_kwarg(1, 2, 3, d=5) Traceback (most recent call last): TypeError: unexpected_kwarg() got an unexpected keyword argument 'd' """ return a, b, c Cython-0.23.4/tests/run/unicode_indexing.pyx0000644000175600017570000001753512606202452022242 0ustar jenkinsjenkins00000000000000 cimport cython cdef unicode _ustring = u'azerty123456' ustring = _ustring @cython.test_assert_path_exists("//CoerceToPyTypeNode", "//IndexNode") @cython.test_fail_if_path_exists("//IndexNode//CoerceToPyTypeNode") def index(unicode ustring, Py_ssize_t i): """ >>> index(ustring, 0) == 'a' True >>> index(ustring, 2) == 'e' True >>> index(ustring, -1) == '6' True >>> index(ustring, -len(ustring)) == 'a' True >>> index(ustring, len(ustring)) Traceback (most recent call last): IndexError: string index out of range """ return ustring[i] @cython.test_assert_path_exists("//IndexNode") @cython.test_fail_if_path_exists("//CoerceToPyTypeNode") def index_pyindex(unicode ustring, i): """ >>> index(ustring, 0) == 'a' True >>> index(ustring, 2) == 'e' True >>> index(ustring, -1) == '6' True >>> index(ustring, -len(ustring)) == 'a' True >>> index(ustring, len(ustring)) Traceback (most recent call last): IndexError: string index out of range """ return ustring[i] @cython.test_assert_path_exists("//CoerceToPyTypeNode", "//IndexNode") @cython.test_fail_if_path_exists("//IndexNode//CoerceToPyTypeNode") def index_literal(Py_ssize_t i): """ >>> index_literal(0) == 'a' True >>> index_literal(2) == 'e' True >>> index_literal(-1) == '6' True >>> index_literal(-len('azerty123456')) == 'a' True >>> index_literal(len(ustring)) Traceback (most recent call last): IndexError: string index out of range """ return u'azerty123456'[i] @cython.test_assert_path_exists("//IndexNode") @cython.test_fail_if_path_exists("//IndexNode//CoerceToPyTypeNode") def index_literal_pyunicode_cast(int i): """ >>> index_literal_pyunicode_cast(0) == '1' True >>> index_literal_pyunicode_cast(-5) == '1' True >>> index_literal_pyunicode_cast(2) == '3' True >>> index_literal_pyunicode_cast(4) == '5' True >>> index_literal_pyunicode_coerce(6) Traceback (most recent call last): IndexError: string index out of range """ return (u"12345"[i]) @cython.test_assert_path_exists("//IndexNode", "//SingleAssignmentNode") @cython.test_fail_if_path_exists("//SingleAssignmentNode//CoerceToPyTypeNode") def index_literal_pyunicode_coerce(int i): """ >>> index_literal_pyunicode_coerce(0) == '1' True >>> index_literal_pyunicode_coerce(-5) == '1' True >>> index_literal_pyunicode_coerce(2) == '3' True >>> index_literal_pyunicode_coerce(4) == '5' True >>> index_literal_pyunicode_coerce(6) Traceback (most recent call last): IndexError: string index out of range """ cdef Py_UNICODE result = u"12345"[i] return result @cython.test_assert_path_exists("//SingleAssignmentNode") @cython.test_fail_if_path_exists("//SingleAssignmentNode//CoerceFromPyTypeNode") @cython.boundscheck(False) def index_literal_pyunicode_coerce_no_check(int i): """ >>> index_literal_pyunicode_coerce_no_check(0) == '1' True >>> index_literal_pyunicode_coerce_no_check(-5) == '1' True >>> index_literal_pyunicode_coerce_no_check(2) == '3' True >>> index_literal_pyunicode_coerce_no_check(4) == '5' True """ cdef Py_UNICODE result = u"12345"[i] return result @cython.test_assert_path_exists("//CoerceToPyTypeNode", "//IndexNode") @cython.test_fail_if_path_exists("//IndexNode//CoerceToPyTypeNode") @cython.boundscheck(False) def index_no_boundscheck(unicode ustring, Py_ssize_t i): """ >>> index_no_boundscheck(ustring, 0) == 'a' True >>> index_no_boundscheck(ustring, 2) == 'e' True >>> index_no_boundscheck(ustring, -1) == '6' True >>> index_no_boundscheck(ustring, len(ustring)-1) == '6' True >>> index_no_boundscheck(ustring, -len(ustring)) == 'a' True """ return ustring[i] @cython.test_assert_path_exists("//CoerceToPyTypeNode", "//IndexNode") @cython.test_fail_if_path_exists("//IndexNode//CoerceToPyTypeNode") @cython.boundscheck(False) def unsigned_index_no_boundscheck(unicode ustring, unsigned int i): """ >>> unsigned_index_no_boundscheck(ustring, 0) == 'a' True >>> unsigned_index_no_boundscheck(ustring, 2) == 'e' True >>> unsigned_index_no_boundscheck(ustring, len(ustring)-1) == '6' True """ return ustring[i] @cython.test_assert_path_exists("//CoerceToPyTypeNode", "//IndexNode", "//PrimaryCmpNode") @cython.test_fail_if_path_exists("//IndexNode//CoerceToPyTypeNode") def index_compare(unicode ustring, Py_ssize_t i): """ >>> index_compare(ustring, 0) True >>> index_compare(ustring, 1) False >>> index_compare(ustring, -1) False >>> index_compare(ustring, -len(ustring)) True >>> index_compare(ustring, len(ustring)) Traceback (most recent call last): IndexError: string index out of range """ return ustring[i] == u'a' @cython.test_assert_path_exists("//CoerceToPyTypeNode", "//IndexNode", "//PrimaryCmpNode") @cython.test_fail_if_path_exists("//IndexNode//CoerceToPyTypeNode") def index_compare_string(unicode ustring, Py_ssize_t i, unicode other): """ >>> index_compare_string(ustring, 0, ustring[0]) True >>> index_compare_string(ustring, 0, ustring[:4]) False >>> index_compare_string(ustring, 1, ustring[0]) False >>> index_compare_string(ustring, 1, ustring[1]) True >>> index_compare_string(ustring, -1, ustring[0]) False >>> index_compare_string(ustring, -1, ustring[-1]) True >>> index_compare_string(ustring, -len(ustring), ustring[-len(ustring)]) True >>> index_compare_string(ustring, len(ustring), ustring) Traceback (most recent call last): IndexError: string index out of range """ return ustring[i] == other @cython.test_assert_path_exists("//CoerceToPyTypeNode", "//IndexNode", "//MulNode", "//MulNode/CoerceToPyTypeNode") @cython.test_fail_if_path_exists("//IndexNode//CoerceToPyTypeNode") def index_multiply(unicode ustring, Py_ssize_t i, int mul): """ >>> ustring[0] * 5 == 'aaaaa' True >>> index_multiply(ustring, 0, 5) == 'aaaaa' True """ return ustring[i] * mul @cython.test_assert_path_exists("//CoerceToPyTypeNode", "//IndexNode", "//AddNode", "//AddNode/CoerceToPyTypeNode") @cython.test_fail_if_path_exists("//IndexNode//CoerceToPyTypeNode") def index_add(unicode ustring, Py_ssize_t i, Py_ssize_t j): """ >>> ustring[0] + ustring[-1] == 'a6' True >>> index_add(ustring, 0, -1) == 'a6' True """ return ustring[i] + ustring[j] @cython.test_assert_path_exists("//CoerceToPyTypeNode", "//IndexNode", "//CoerceToPyTypeNode//IndexNode") @cython.test_fail_if_path_exists("//IndexNode//CoerceToPyTypeNode") def index_concat_loop(unicode ustring): """ >>> index_concat_loop(ustring) == ustring True """ cdef int i cdef unicode s = u'' for i in range(len(ustring)): s += ustring[i] return s @cython.test_assert_path_exists("//CoerceToPyTypeNode", "//IndexNode", "//CoerceToPyTypeNode//IndexNode") @cython.test_fail_if_path_exists("//IndexNode//CoerceToPyTypeNode") def index_join_loop(unicode ustring): """ >>> index_join_loop(ustring) == ustring True """ cdef int i return u''.join([ ustring[i] for i in range(len(ustring)) ]) Cython-0.23.4/tests/run/unicode_default_auto_encoding.pyx0000644000175600017570000000047312606202452024750 0ustar jenkinsjenkins00000000000000# cython: c_string_type = unicode # cython: c_string_encoding = default import sys if sys.version_info[0] >= 3: __doc__ = r""" >>> as_objects("ab\xff") == "ab\xff" True >>> slice_as_objects("ab\xffd", 1, 4) == "b\xff" True """ include "unicode_ascii_auto_encoding.pyx" Cython-0.23.4/tests/run/unicode_ascii_auto_encoding.pyx0000644000175600017570000000317412606202452024415 0ustar jenkinsjenkins00000000000000#cython: c_string_type = unicode #cython: c_string_encoding = ascii auto_string_type = unicode from libc.string cimport strcmp def _as_string(x): try: return x.decode('latin1') except AttributeError: return x def as_objects(char* ascii_data): """ >>> x = as_objects('abc') >>> isinstance(x, auto_string_type) or type(x) True >>> _as_string(x) == 'abc' or repr(x) True """ assert isinstance(ascii_data, auto_string_type) assert isinstance(ascii_data, bytes) assert isinstance(ascii_data, str) assert isinstance(ascii_data, unicode) return ascii_data def from_object(): """ >>> from_object() """ cdef bytes b = b"abc" cdef str s = "abc" cdef unicode u = u"abc" assert strcmp(b, "abc") == 0 assert strcmp(s, "abc") == 0 assert strcmp(u, "abc") == 0 def slice_as_objects(char* ascii_data, int start, int end): """ >>> x = slice_as_objects('grok', 1, 3) >>> isinstance(x, auto_string_type) or type(x) True >>> _as_string(x) == 'ro' or repr(x) True """ assert isinstance(ascii_data[start:end], auto_string_type) assert isinstance(ascii_data[start:end], bytes) assert isinstance(ascii_data[start:end], str) assert isinstance(ascii_data[start:end], unicode) assert isinstance(ascii_data[start:], auto_string_type) assert isinstance(ascii_data[start:], bytes) assert isinstance(ascii_data[start:], str) assert isinstance(ascii_data[start:], unicode) return ascii_data[start:end] Cython-0.23.4/tests/run/unbound_special_methods.pyx0000644000175600017570000000332612606202452023615 0ustar jenkinsjenkins00000000000000# mode: run # tag: special_method cimport cython text = u'ab jd sdflk as sa sadas asdas fsdf ' @cython.test_fail_if_path_exists( "//CoerceFromPyTypeNode") @cython.test_assert_path_exists( "//CoerceToPyTypeNode", "//AttributeNode", "//AttributeNode[@entry.cname = 'PyUnicode_Contains']") def unicode_contains(unicode s, substring): """ >>> unicode_contains(text, 'fl') True >>> unicode_contains(text, 'XYZ') False >>> unicode_contains(None, 'XYZ') Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute '__contains__' """ return s.__contains__(substring) @cython.test_fail_if_path_exists( "//CoerceFromPyTypeNode") @cython.test_assert_path_exists( # "//CoerceToPyTypeNode", "//NameNode[@entry.cname = 'PyUnicode_Contains']") def unicode_contains_unbound(unicode s, substring): """ >>> unicode_contains_unbound(text, 'fl') True >>> unicode_contains_unbound(text, 'XYZ') False >>> unicode_contains_unbound(None, 'XYZ') # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: descriptor '__contains__' requires a '...' object but received a 'NoneType' """ return unicode.__contains__(s, substring) cdef class UnicodeSubclass(unicode): """ >>> u = UnicodeSubclass(text) >>> 'fl' in u False >>> 'XYZ' in u True >>> u.method('fl') False >>> u.method('XYZ') True >>> u.operator('fl') False >>> u.operator('XYZ') True """ def __contains__(self, substring): return substring not in (self + u'x') def method(self, other): return self.__contains__(other) def operator(self, other): return other in self Cython-0.23.4/tests/run/unbound_builtin_methods.pyx0000644000175600017570000000134212606202452023637 0ustar jenkinsjenkins00000000000000 def list_insert(list l): """ >>> list_insert([1,2,3]) [1, 4, 2, 3] """ list.insert(l, 1, 4) return l def list_insert_literal(): """ >>> list_insert_literal() (None, [1, 4, 2, 3]) """ l = [1,2,3] r = list.insert(l, 1, 4) return r, l def list_insert_assigned(): """ >>> list_insert_assigned() (None, [1, 4, 2, 3]) """ insert = list.insert l = [1,2,3] r = insert(l, 1, 4) return r, l def list_pop(): """ >>> list_pop() (2, [1, 3]) """ l = [1,2,3] r = list.pop(l, 1) return r, l def list_pop_assigned(): """ >>> list_pop_assigned() [1, 3] """ pop = list.pop l = [1,2,3] pop(l, 1) return l Cython-0.23.4/tests/run/typetest_T417.pyx0000644000175600017570000000462312606202452021321 0ustar jenkinsjenkins00000000000000# ticket: 417 #cython: autotestdict=True cdef class Foo: cdef int i def __cinit__(self): self.i = 1 cdef class SubFoo(Foo): pass cdef class Bar: pass def foo1(arg): """ >>> foo1(Foo()) >>> foo1(SubFoo()) >>> foo1(None) >>> foo1(123) >>> foo1(Bar()) """ cdef Foo val = arg def foo2(arg): """ >>> foo2(Foo()) >>> foo2(SubFoo()) >>> foo2(None) >>> foo2(123) Traceback (most recent call last): ... TypeError: Cannot convert int to typetest_T417.Foo >>> foo2(Bar()) Traceback (most recent call last): ... TypeError: Cannot convert typetest_T417.Bar to typetest_T417.Foo """ cdef Foo val = arg def foo3(arg): """ >>> foo3(Foo()) >>> foo3(SubFoo()) >>> foo3(None) Traceback (most recent call last): ... TypeError: Cannot convert NoneType to typetest_T417.Foo >>> foo3(123) Traceback (most recent call last): ... TypeError: Cannot convert int to typetest_T417.Foo >>> foo2(Bar()) Traceback (most recent call last): ... TypeError: Cannot convert typetest_T417.Bar to typetest_T417.Foo """ cdef val = arg def attribute_access(arg): """ >>> attribute_access(Foo()) >>> attribute_access(SubFoo()) >>> attribute_access(None) Traceback (most recent call last): ... TypeError: Cannot convert NoneType to typetest_T417.Foo >>> attribute_access(123) Traceback (most recent call last): ... TypeError: Cannot convert int to typetest_T417.Foo >>> attribute_access(Bar()) Traceback (most recent call last): ... TypeError: Cannot convert typetest_T417.Bar to typetest_T417.Foo """ cdef val = (arg).i cdef int count = 0 cdef object getFoo(): global count count += 1 return Foo() def test_getFoo(): """ >>> test_getFoo() 1 """ cdef int old_count = count cdef Foo x = getFoo() return count - old_count def test_getFooCast(): """ >>> test_getFooCast() 1 """ cdef int old_count = count cdef Foo x = getFoo() return count - old_count def test_builtin_typecheck_cast(maybe_list): """ >>> test_builtin_typecheck_cast([]) [] >>> test_builtin_typecheck_cast({}) Traceback (most recent call last): ... TypeError: Expected list, got dict """ return maybe_list Cython-0.23.4/tests/run/types.h0000644000175600017570000000021612606202452017466 0ustar jenkinsjenkins00000000000000/* This header is present to test effects of misdeclaring types Cython-side. */ typedef long actually_long_t; typedef short actually_short_t; Cython-0.23.4/tests/run/typeofexttype.pyx0000644000175600017570000000020112606202452021636 0ustar jenkinsjenkins00000000000000# mode: run # tag: exttype cdef class Spam: pass def test(): """ >>> test() """ cdef type t t = Spam Cython-0.23.4/tests/run/typeof.pyx0000644000175600017570000000204412606202452020222 0ustar jenkinsjenkins00000000000000from cython cimport typeof cdef class A: pass cdef class B(A): pass cdef struct X: double a double complex b def simple(): """ >>> simple() int long long long int * int ** A B X Python object """ cdef int i = 0 cdef long l = 0 cdef long long ll = 0 cdef int* iptr = &i cdef int** iptrptr = &iptr cdef A a = None cdef B b = None cdef X x = X(a=1, b=2) print typeof(i) print typeof(l) print typeof(ll) print typeof(iptr) print typeof(iptrptr) print typeof(a) print typeof(b) print typeof(x) print typeof(None) used = i, l, ll, iptr, iptrptr, a, b, x def expression(): """ >>> expression() double double complex int unsigned int """ cdef X x = X(a=1, b=2) cdef X *xptr = &x cdef short s = 0 cdef int i = 0 cdef unsigned int ui = 0 print typeof(x.a) print typeof(xptr.b) print typeof(s + i) print typeof(i + ui) used = x, xptr, s, i, ui Cython-0.23.4/tests/run/typedfieldbug_T303.pyx0000644000175600017570000000221112606202452022250 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 303 __doc__ = """ >>> try: readonly() ... except (TypeError, AttributeError): pass """ cdef extern from "external_defs.h": ctypedef float DoubleTypedef ctypedef float LongDoubleTypedef cdef public DoubleTypedef global_tdef cdef public double global_double cdef class MyClass: cdef readonly: double actual_double DoubleTypedef float_isreally_double LongDoubleTypedef float_isreally_longdouble def __init__(self): self.actual_double = 42.0 self.float_isreally_double = 42.0 self.float_isreally_longdouble = 42.0 def global_vars(x): """ >>> global_vars(12.0) 12.0 12.0 """ global global_tdef, global_double global_tdef = x global_double = x print global_tdef, global_double def f(): """ >>> f() 42.0 42.0 """ cdef object c = MyClass() print c.actual_double print c.float_isreally_double def longdouble_access(): """ >>> longdouble_access() 42.0 """ cdef object c = MyClass() print c.float_isreally_longdouble def readonly(): cdef object c = MyClass() c.actual_double = 3 Cython-0.23.4/tests/run/typeddefaultargT373.pyx0000644000175600017570000000044312606202452022462 0ustar jenkinsjenkins00000000000000# ticket: 373 import math cdef class MyClass: """ >>> x=MyClass() 4 """ def __cinit__(self, int arg=2*2): print arg cdef class MyOtherClass: """ >>> x=MyOtherClass() 8 """ def __cinit__(self, int arg=4*int(math.sqrt(4))): print arg Cython-0.23.4/tests/run/typed_slice.pyx0000644000175600017570000000777412606202452021237 0ustar jenkinsjenkins00000000000000# mode: run # tag: list, tuple, slice def slice_list(list l, int start, int stop): """ >>> slice_list([1,2,3,4], 1, 3) [2, 3] >>> slice_list([1,2,3,4], 1, 7) [2, 3, 4] >>> slice_list([], 1, 3) [] >>> slice_list([1], 1, 3) [] >>> slice_list([1,2,3,4], -3, -1) [2, 3] >>> slice_list([1,2,3,4], -10, -1) [1, 2, 3] >>> slice_list([], -3, -1) [] >>> slice_list([1], -3, -1) [] """ return l[start:stop] def slice_list_start(list l, int start): """ >>> slice_list_start([1,2,3,4], 1) [2, 3, 4] >>> slice_list_start([], 1) [] >>> slice_list_start([1], 1) [] >>> slice_list_start([1], 2) [] >>> slice_list_start([1,2,3,4], -3) [2, 3, 4] >>> slice_list_start([1,2,3,4], -10) [1, 2, 3, 4] >>> slice_list_start([], -3) [] >>> slice_list_start([1], -3) [1] """ return l[start:] def slice_list_stop(list l, int stop): """ >>> slice_list_stop([1,2,3,4], 3) [1, 2, 3] >>> slice_list_stop([1,2,3,4], 7) [1, 2, 3, 4] >>> slice_list_stop([], 3) [] >>> slice_list_stop([1], 3) [1] >>> slice_list_stop([1,2,3,4], -3) [1] >>> slice_list_stop([1,2,3,4], -10) [] >>> slice_list_stop([], -1) [] >>> slice_list_stop([1], -1) [] >>> slice_list_stop([1, 2], -3) [] """ return l[:stop] def slice_list_copy(list l): """ >>> slice_list_copy([]) [] >>> slice_list_copy([1,2,3]) [1, 2, 3] """ return l[:] def slice_tuple_copy(tuple l): """ >>> slice_tuple_copy(()) () >>> slice_tuple_copy((1,2,3)) (1, 2, 3) """ return l[:] def slice_tuple(tuple t, int start, int stop): """ >>> slice_tuple((1,2,3,4), 1, 3) (2, 3) >>> slice_tuple((1,2,3,4), 1, 7) (2, 3, 4) >>> slice_tuple((), 1, 3) () >>> slice_tuple((1,), 1, 3) () >>> slice_tuple((1,2,3,4), -3, -1) (2, 3) >>> slice_tuple((1,2,3,4), -10, -1) (1, 2, 3) >>> slice_tuple((), -3, -1) () >>> slice_tuple((1,), -3, -1) () """ return t[start:stop] def slice_tuple_start(tuple t, int start): """ >>> slice_tuple_start((1,2,3,4), 1) (2, 3, 4) >>> slice_tuple_start((), 1) () >>> slice_tuple_start((1,), 1) () >>> slice_tuple_start((1,2,3,4), -3) (2, 3, 4) >>> slice_tuple_start((1,2,3,4), -10) (1, 2, 3, 4) >>> slice_tuple_start((), -3) () >>> slice_tuple_start((1,), -3) (1,) """ return t[start:] def slice_tuple_stop(tuple t, int stop): """ >>> slice_tuple_stop((1,2,3,4), 3) (1, 2, 3) >>> slice_tuple_stop((1,2,3,4), 7) (1, 2, 3, 4) >>> slice_tuple_stop((), 3) () >>> slice_tuple_stop((1,), 3) (1,) >>> slice_tuple_stop((1,2,3,4), -1) (1, 2, 3) >>> slice_tuple_stop((), -1) () """ return t[:stop] def slice_list_assign_list(list l): """ >>> l = [1,2,3,4] >>> l2 = l[:] >>> slice_list_assign_list(l2) [1, 1, 2, 3, 4, 4] """ l[1:3] = [1,2,3,4] return l def slice_list_assign_tuple(list l): """ >>> l = [1,2,3,4] >>> l2 = l[:] >>> slice_list_assign_tuple(l2) [1, 1, 2, 3, 4, 4] """ l[1:3] = (1,2,3,4) return l def slice_list_assign(list l, value): """ >>> l = [1,2,3,4] >>> l2 = l[:] >>> slice_list_assign(l2, (1,2,3,4)) [1, 1, 2, 3, 4, 4] >>> l2 = l[:] >>> slice_list_assign(l2, dict(zip(l,l))) [1, 1, 2, 3, 4, 4] """ l[1:3] = value return l def slice_charp(py_string_arg): """ >>> print("%s" % slice_charp('abcdefg')) bc """ cdef bytes py_string = py_string_arg.encode(u'ASCII') cdef char* s = py_string return s[1:3].decode(u'ASCII') def slice_charp_repeat(py_string_arg): """ >>> print("%s" % slice_charp_repeat('abcdefg')) cd """ cdef bytes py_string = py_string_arg.encode(u'ASCII') cdef char* s = py_string cdef bytes slice_val = s[1:6] s = slice_val return s[1:3].decode(u'ASCII') Cython-0.23.4/tests/run/type_slots_nonzero_bool.pyx0000644000175600017570000000114612606202452023710 0ustar jenkinsjenkins00000000000000__doc__ = """ >>> not not BoolA(0) False >>> not not BoolA(1) True >>> not not BoolB(0) False >>> not not BoolB(1) True >>> not not BoolX(0) False >>> not not BoolX(1) True >>> not not BoolY(0) False >>> not not BoolY(1) True """ cdef class BoolA: cdef bint value def __cinit__(self, bint value): self.value = value def __nonzero__(self): return self.value cdef class BoolB: cdef bint value def __cinit__(self, bint value): self.value = value def __bool__(self): return self.value cdef class BoolX(BoolA): pass cdef class BoolY(BoolB): pass Cython-0.23.4/tests/run/type_slots_int_long_T287.pyx0000644000175600017570000000147512606202452023545 0ustar jenkinsjenkins00000000000000# ticket: 287 __doc__ = u""" >>> print( "%d" % Int() ) 2 >>> print( "%d" % Long() ) 3 >>> print( "%d" % IntLongA() ) 2 >>> print( "%d" % IntLongB() ) 2 """ def getint(int i): """ >>> getint( Int() ) 2 >>> getint( Long() ) 3 >>> getint( IntLongA() ) 2 >>> getint( IntLongB() ) 2 """ return i def getlong(long long i): """ >>> getlong( Int() ) 2 >>> getlong( Long() ) 3 >>> getlong( IntLongA() ) 2 >>> getlong( IntLongB() ) 2 """ return i cdef class Int: def __int__(self): return 2 cdef class Long: def __long__(self): return 3 cdef class IntLongA: def __int__(self): return 2 def __long__(self): return 3 cdef class IntLongB: def __int__(self): return 2 __long__ = __int__ Cython-0.23.4/tests/run/type_inference_new.pyx0000644000175600017570000000554312606202452022573 0ustar jenkinsjenkins00000000000000cimport cython from cython cimport typeof, infer_types def test_swap(): """ >>> test_swap() """ a = 0 b = 1 tmp = a a = b b = tmp assert typeof(a) == "long", typeof(a) assert typeof(b) == "long", typeof(b) assert typeof(tmp) == "long", typeof(tmp) def test_object_assmt(): """ >>> test_object_assmt() """ a = 1 b = a a = "str" assert typeof(a) == "Python object", typeof(a) assert typeof(b) == "long", typeof(b) class RAdd(object): other = None def __radd__(self, other): self._other = other return self def __repr__(self): return '%s(%s)' % (type(self).__name__, self._other) def test_inplace_assignment(): """ >>> test_inplace_assignment() RAdd([1, 2, 3]) """ l = [1, 2, 3] # inferred type of l is list, but assignment result is object l += RAdd() return l def test_reassignment(): """ >>> test_reassignment() (1, 2, 3) """ l = [1, 2, 3] l = (1, 2, 3) return l def test_long_vs_double(cond): """ >>> test_long_vs_double(0) """ assert typeof(a) == "double", typeof(a) assert typeof(b) == "double", typeof(b) assert typeof(c) == "double", typeof(c) assert typeof(d) == "double", typeof(d) if cond: a = 1 b = 2 c = (a + b) / 2 else: a = 1.0 b = 2.0 d = (a + b) / 2 def test_double_vs_pyobject(): """ >>> test_double_vs_pyobject() """ assert typeof(a) == "Python object", typeof(a) assert typeof(b) == "Python object", typeof(b) assert typeof(d) == "double", typeof(d) a = [] b = [] a = 1.0 b = 2.0 d = (a + b) / 2 def test_python_objects(cond): """ >>> test_python_objects(0) """ if cond == 1: a = [1, 2, 3] o_list = a elif cond == 2: a = set([1, 2, 3]) o_set = a else: a = {1:1, 2:2, 3:3} o_dict = a assert typeof(a) == "Python object", typeof(a) assert typeof(o_list) == "list object", typeof(o_list) assert typeof(o_dict) == "dict object", typeof(o_dict) assert typeof(o_set) == "set object", typeof(o_set) # CF loops def test_cf_loop(): """ >>> test_cf_loop() """ cdef int i a = 0.0 for i in range(3): a += 1 assert typeof(a) == "double", typeof(a) def test_cf_loop_intermediate(): """ >>> test_cf_loop() """ cdef int i a = 0 for i in range(3): b = a a = b + 1 assert typeof(a) == "long", typeof(a) assert typeof(b) == "long", typeof(b) # Integer overflow def test_integer_overflow(): """ >>> test_integer_overflow() """ a = 1 b = 2 c = a + b assert typeof(a) == "Python object", typeof(a) assert typeof(b) == "Python object", typeof(b) assert typeof(c) == "Python object", typeof(c) Cython-0.23.4/tests/run/type_inference_T768_cpp.pyx0000644000175600017570000000057512606202452023314 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp # ticket: 768 from cython cimport typeof cdef extern from "shapes.h" namespace "shapes": cdef cppclass Shape: float area() cdef cppclass Circle(Shape): int radius Circle(int) def type_inference_del_cpp(): """ >>> type_inference_del_cpp() 'Circle *' """ x = new Circle(10) del x return typeof(x) Cython-0.23.4/tests/run/type_inference_T768.pyx0000644000175600017570000000052012606202452022440 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 768 from cython cimport typeof def type_inference_del_int(): """ >>> type_inference_del_int() 'Python object' """ x = 1 del x return typeof(x) def type_inference_del_dict(): """ >>> type_inference_del_dict() 'dict object' """ x = {} del x return typeof(x) Cython-0.23.4/tests/run/type_inference.pyx0000644000175600017570000004127112606202452021720 0ustar jenkinsjenkins00000000000000# cython: infer_types = True cimport cython from cython cimport typeof, infer_types from cpython cimport bool ################################################## # type inference tests in 'full' mode cdef class MyType: pass def simple(): """ >>> simple() """ i = 3 assert typeof(i) == "long", typeof(i) x = 1.41 assert typeof(x) == "double", typeof(x) xptr = &x assert typeof(xptr) == "double *", typeof(xptr) xptrptr = &xptr assert typeof(xptrptr) == "double **", typeof(xptrptr) b = b"abc" assert typeof(b) == "bytes object", typeof(b) s = "abc" assert typeof(s) == "str object", typeof(s) u = u"xyz" assert typeof(u) == "unicode object", typeof(u) L = [1,2,3] assert typeof(L) == "list object", typeof(L) t = (4,5,6,()) assert typeof(t) == "tuple object", typeof(t) t2 = (4, 5.0, 6) assert typeof(t2) == "(long, double, long)", typeof(t) def builtin_types(): """ >>> builtin_types() """ b = bytes() assert typeof(b) == "bytes object", typeof(b) u = unicode() assert typeof(u) == "unicode object", typeof(u) L = list() assert typeof(L) == "list object", typeof(L) t = tuple() assert typeof(t) == "tuple object", typeof(t) d = dict() assert typeof(d) == "dict object", typeof(d) B = bool() assert typeof(B) == "bool", typeof(B) def slicing(): """ >>> slicing() """ b = b"abc" assert typeof(b) == "bytes object", typeof(b) b1 = b[1:2] assert typeof(b1) == "bytes object", typeof(b1) b2 = b[1:2:2] assert typeof(b2) == "bytes object", typeof(b2) u = u"xyz" assert typeof(u) == "unicode object", typeof(u) u1 = u[1:2] assert typeof(u1) == "unicode object", typeof(u1) u2 = u[1:2:2] assert typeof(u2) == "unicode object", typeof(u2) s = "xyz" assert typeof(s) == "str object", typeof(s) s1 = s[1:2] assert typeof(s1) == "str object", typeof(s1) s2 = s[1:2:2] assert typeof(s2) == "str object", typeof(s2) L = [1,2,3] assert typeof(L) == "list object", typeof(L) L1 = L[1:2] assert typeof(L1) == "list object", typeof(L1) L2 = L[1:2:2] assert typeof(L2) == "list object", typeof(L2) t = (4,5,6,()) assert typeof(t) == "tuple object", typeof(t) t1 = t[1:2] assert typeof(t1) == "tuple object", typeof(t1) t2 = t[1:2:2] assert typeof(t2) == "tuple object", typeof(t2) def indexing(): """ >>> indexing() """ b = b"abc" assert typeof(b) == "bytes object", typeof(b) b1 = b[1] assert typeof(b1) == "Python object", typeof(b1) # Py2: bytes, Py3: int u = u"xyz" assert typeof(u) == "unicode object", typeof(u) u1 = u[1] assert typeof(u1) == "Py_UCS4", typeof(u1) s = "xyz" assert typeof(s) == "str object", typeof(s) s1 = s[1] assert typeof(s1) == "str object", typeof(s1) L = [1,2,3] assert typeof(L) == "list object", typeof(L) L1 = L[1] assert typeof(L1) == "Python object", typeof(L1) t = (4,5,()) assert typeof(t) == "tuple object", typeof(t) t1 = t[1] assert typeof(t1) == "long", typeof(t1) t2 = ('abc', 'def', 'ghi') assert typeof(t2) == "tuple object", typeof(t2) t2_1 = t2[1] assert typeof(t2_1) == "str object", typeof(t2_1) t2_2 = t2[t[0]-3] assert typeof(t2_2) == "str object", typeof(t2_2) t5 = (b'abc', 'def', u'ghi') t5_0 = t5[0] assert typeof(t5_0) == "bytes object", typeof(t5_0) t5_1 = t5[1] assert typeof(t5_1) == "str object", typeof(t5_1) t5_2 = t5[2] assert typeof(t5_2) == "unicode object", typeof(t5_2) t5_3 = t5[t[0]-3] assert typeof(t5_3) == "Python object", typeof(t5_3) def multiple_assignments(): """ >>> multiple_assignments() """ a = 3 a = 4 a = 5 assert typeof(a) == "long" b = a b = 3.1 b = 3.14159 assert typeof(b) == "double" c = a c = b c = [1,2,3] assert typeof(c) == "Python object" def arithmetic(): """ >>> arithmetic() """ a = 1 + 2 assert typeof(a) == "long", typeof(a) b = 1 + 1.5 assert typeof(b) == "double", typeof(b) c = 1 + 2 assert typeof(c) == "Python object", typeof(c) d = 1 * 1.5 ** 2 assert typeof(d) == "double", typeof(d) cdef class some_class: pass def unary_operators(): """ >>> unary_operators() """ cdef int x = 1 assert typeof(~x) == "int", typeof(~x) cdef some_class obj assert typeof(~obj) == "Python object", typeof(~obj) a = int(1) assert typeof(a) == "Python object", typeof(a) b = not int(3) assert typeof(b) == "bint", typeof(b) c = +int(3) assert typeof(c) == "Python object", typeof(c) d = -int(5) assert typeof(d) == "Python object", typeof(d) def builtin_type_operations(): """ >>> builtin_type_operations() """ b1 = b'a' * 10 b1 = 10 * b'a' b1 = 10 * b'a' * 10 assert typeof(b1) == "bytes object", typeof(b1) b2 = b'a' + b'b' assert typeof(b2) == "bytes object", typeof(b2) u1 = u'a' * 10 u1 = 10 * u'a' assert typeof(u1) == "unicode object", typeof(u1) u2 = u'a' + u'b' assert typeof(u2) == "unicode object", typeof(u2) u3 = u'a%s' % u'b' u3 = u'a%s' % 10 assert typeof(u3) == "unicode object", typeof(u3) s1 = "abc %s" % "x" s1 = "abc %s" % 10 assert typeof(s1) == "str object", typeof(s1) s2 = "abc %s" + "x" assert typeof(s2) == "str object", typeof(s2) s3 = "abc %s" * 10 s3 = "abc %s" * 10 * 10 s3 = 10 * "abc %s" * 10 assert typeof(s3) == "str object", typeof(s3) L1 = [] + [] assert typeof(L1) == "list object", typeof(L1) L2 = [] * 2 assert typeof(L2) == "list object", typeof(L2) T1 = () + () assert typeof(T1) == "tuple object", typeof(T1) T2 = () * 2 assert typeof(T2) == "tuple object", typeof(T2) def builtin_type_methods(): """ >>> builtin_type_methods() """ l = [] assert typeof(l) == 'list object', typeof(l) append = l.append assert typeof(append) == 'Python object', typeof(append) append(1) assert l == [1], str(l) cdef int cfunc(int x): return x+1 def c_functions(): """ >>> c_functions() """ f = cfunc assert typeof(f) == 'int (*)(int)', typeof(f) assert 2 == f(1) def builtin_functions(): """ >>> _abs, _getattr = builtin_functions() Python object Python object >>> _abs(-1) 1 >>> class o(object): pass >>> o.x = 1 >>> _getattr(o, 'x') 1 """ _abs = abs print(typeof(_abs)) _getattr = getattr print(typeof(_getattr)) return _abs, _getattr def cascade(): """ >>> cascade() """ a = 1.0 b = a + 2 c = b + 3 d = c + 4 assert typeof(d) == "double" e = a + b + c + d assert typeof(e) == "double" def cascaded_assignment(): a = b = c = d = 1.0 assert typeof(a) == "double" assert typeof(b) == "double" assert typeof(c) == "double" assert typeof(d) == "double" e = a + b + c + d assert typeof(e) == "double" def increment(): """ >>> increment() """ a = 5 a += 1 assert typeof(a) == "long" def loop(): """ >>> loop() """ for a in range(10): pass assert typeof(a) == "long" b = 1.0 for b in range(5): pass assert typeof(b) == "double" for c from 0 <= c < 10 by .5: pass assert typeof(c) == "double" for d in range(0, 10L, 2): pass assert typeof(a) == "long" def loop_over_charptr(): """ >>> print( loop_over_charptr() ) char """ cdef char* char_ptr_string = 'abcdefg' for c in char_ptr_string: pass return typeof(c) def loop_over_bytes_literal(): """ >>> print( loop_over_bytes_literal() ) Python object """ for c in b'abcdefg': pass return typeof(c) def loop_over_bytes(): """ >>> print( loop_over_bytes() ) Python object """ cdef bytes bytes_string = b'abcdefg' # bytes in Py2, int in Py3 for c in bytes_string: pass return typeof(c) def loop_over_str(): """ >>> print( loop_over_str() ) str object """ cdef str string = 'abcdefg' # str (bytes) in Py2, str (unicode) in Py3 for c in string: pass return typeof(c) def loop_over_unicode(): """ >>> print( loop_over_unicode() ) Py_UCS4 """ cdef unicode ustring = u'abcdefg' # Py_UCS4 can represent any Unicode character for uchar in ustring: pass return typeof(uchar) def loop_over_unicode_literal(): """ >>> print( loop_over_unicode_literal() ) Py_UCS4 """ # Py_UCS4 can represent any Unicode character for uchar in u'abcdefg': pass return typeof(uchar) def loop_over_int_array(): """ >>> print( loop_over_int_array() ) int """ cdef int[10] int_array for i in int_array: pass return typeof(i) cdef struct MyStruct: int a def loop_over_struct_ptr(): """ >>> print( loop_over_struct_ptr() ) MyStruct """ cdef MyStruct[10] a_list cdef MyStruct *a_ptr = a_list for i in a_list[:10]: pass return typeof(i) cdef unicode retu(): return u"12345" cdef bytes retb(): return b"12345" def conditional(x): """ >>> conditional(True) (True, 'Python object') >>> conditional(False) (False, 'Python object') """ if x: a = retu() else: a = retb() return type(a) is unicode, typeof(a) ################################################## # type inference tests that work in 'safe' mode @infer_types(None) def double_inference(): """ >>> values, types = double_inference() >>> values == (1.0, 1.0*2, 1.0*2.0+2.0*2.0, 1.0*2.0) True >>> types ('double', 'double', 'double', 'Python object') """ d_a = 1.0 d_b = d_a * float(2) d_c = d_a * float(some_float_value()) + d_b * float(some_float_value()) o_d = d_a * some_float_value() return (d_a,d_b,d_c,o_d), (typeof(d_a), typeof(d_b), typeof(d_c), typeof(o_d)) cdef object some_float_value(): return 2.0 @infer_types(None) @cython.test_fail_if_path_exists('//DefNode//NameNode[@type.is_pyobject = True]') @cython.test_assert_path_exists('//DefNode//NameNode[@type.is_pyobject]', '//DefNode//NameNode[@type.is_pyobject = False]') def double_loop(): """ >>> double_loop() == 1.0 * 10 True """ cdef int i d = 1.0 for i in range(9): d += 1.0 return d @infer_types(None) def safe_only(): """ >>> safe_only() """ a = 1.0 assert typeof(a) == "double", typeof(c) b = 1; assert typeof(b) == "long", typeof(b) c = MyType() assert typeof(c) == "MyType", typeof(c) for i in range(10): pass assert typeof(i) == "long", typeof(i) d = 1 res = ~d assert typeof(d) == "long", typeof(d) # we special-case inference to type str, see # trac #553 s = "abc" assert typeof(s) == "Python object", typeof(s) cdef str t = "def" assert typeof(t) == "str object", typeof(t) # potentially overflowing arithmetic e = 1 e += 1 assert typeof(e) == "Python object", typeof(e) f = 1 res = f * 10 assert typeof(f) == "Python object", typeof(f) g = 1 res = 10*(~g) assert typeof(g) == "Python object", typeof(g) for j in range(10): res = -j assert typeof(j) == "Python object", typeof(j) @infer_types(None) def safe_c_functions(): """ >>> safe_c_functions() """ f = cfunc assert typeof(f) == 'int (*)(int)', typeof(f) assert 2 == f(1) @infer_types(None) def ptr_types(): """ >>> ptr_types() """ cdef int a a_ptr = &a assert typeof(a_ptr) == "int *", typeof(a_ptr) a_ptr_ptr = &a_ptr assert typeof(a_ptr_ptr) == "int **", typeof(a_ptr_ptr) cdef int[1] b b_ref = b assert typeof(b_ref) == "int *", typeof(b_ref) ptr = &a ptr = b assert typeof(ptr) == "int *", typeof(ptr) def const_types(const double x, double y, double& z): """ >>> const_types(1, 1, 1) """ a = x a = y a = z assert typeof(a) == "double", typeof(a) @infer_types(None) def args_tuple_keywords(*args, **kwargs): """ >>> args_tuple_keywords(1,2,3, a=1, b=2) """ assert typeof(args) == "tuple object", typeof(args) assert typeof(kwargs) == "dict object", typeof(kwargs) @infer_types(None) def args_tuple_keywords_reassign_same(*args, **kwargs): """ >>> args_tuple_keywords_reassign_same(1,2,3, a=1, b=2) """ assert typeof(args) == "tuple object", typeof(args) assert typeof(kwargs) == "dict object", typeof(kwargs) args = () kwargs = {} @infer_types(None) def args_tuple_keywords_reassign_pyobjects(*args, **kwargs): """ >>> args_tuple_keywords_reassign_pyobjects(1,2,3, a=1, b=2) """ assert typeof(args) == "Python object", typeof(args) assert typeof(kwargs) == "Python object", typeof(kwargs) args = [] kwargs = "test" # / A -> AA -> AAA # Base0 -> Base - # \ B -> BB # C -> CC cdef class Base0: pass cdef class Base(Base0): pass cdef class A(Base): pass cdef class AA(A): pass cdef class AAA(AA): pass cdef class B(Base): pass cdef class BB(B): pass cdef class C: pass cdef class CC(C): pass @infer_types(None) def common_extension_type_base(): """ >>> common_extension_type_base() """ x = A() x = AA() assert typeof(x) == "A", typeof(x) y = A() y = B() assert typeof(y) == "Base", typeof(y) z = AAA() z = BB() assert typeof(z) == "Base", typeof(z) w = A() w = CC() assert typeof(w) == "Python object", typeof(w) cdef class AcceptsKeywords: def __init__(self, *args, **kwds): pass @infer_types(None) def constructor_call(): """ >>> constructor_call() """ x = AcceptsKeywords(a=1, b=2) assert typeof(x) == "AcceptsKeywords", typeof(x) @infer_types(None) def large_literals(): """ >>> large_literals() """ # It's only safe to infer small integer literals. a = 10 b = 100000000000000000000000000000000 assert typeof(a) == "long", typeof(a) assert typeof(b) == "Python object", typeof(b) c, d = 10, 100000000000000000000000000000000 assert typeof(c) == "long", typeof(c) assert typeof(d) == "Python object", typeof(d) class EmptyContextManager(object): def __enter__(self): return None def __exit__(self, *args): return 0 def with_statement(): """ >>> with_statement() Python object Python object """ x = 1.0 with EmptyContextManager() as x: print(typeof(x)) print(typeof(x)) return x @cython.final cdef class TypedContextManager(object): cpdef double __enter__(self): return 2.0 def __exit__(self, *args): return 0 def with_statement_typed(): """ >>> with_statement_typed() double double 2.0 """ x = 1.0 with TypedContextManager() as x: print(typeof(x)) print(typeof(x)) return x def with_statement_untyped(): """ >>> with_statement_untyped() Python object Python object 2.0 """ x = 1.0 cdef object t = TypedContextManager() with t as x: print(typeof(x)) print(typeof(x)) return x def self_lookup(a): b = a b = b.foo(keyword=None) print typeof(b) # Regression test for trac #638. def bar(foo): qux = foo quux = foo[qux.baz] cdef enum MyEnum: enum_x = 1 enum_y = 2 ctypedef long my_long def test_int_typedef_inference(): """ >>> test_int_typedef_inference() """ cdef long x = 1 cdef my_long y = 2 cdef long long z = 3 assert typeof(x + y) == typeof(y + x) == 'my_long', typeof(x + y) assert typeof(y + z) == typeof(z + y) == 'long long', typeof(y + z) from libc.stdint cimport int32_t, int64_t def int64_long_sum(): cdef long x = 1 cdef int32_t x32 = 2 cdef int64_t x64 = 3 cdef unsigned long ux = 4 assert typeof(x + x32) == typeof(x32 + x) == 'long', typeof(x + x32) assert typeof(x + x64) == typeof(x64 + x) == 'int64_t', typeof(x + x64) # The correct answer here is either unsigned long or int64_t, depending on # whether sizeof(long) == 64 or not. Incorrect signedness is probably # preferable to incorrect width. assert typeof(ux + x64) == typeof(x64 + ux) == 'int64_t', typeof(ux + x64) cdef class InferInProperties: """ >>> InferInProperties().x ('double', 'unicode object', 'MyEnum', 'MyEnum') """ cdef MyEnum attr def __cinit__(self): self.attr = enum_x property x: def __get__(self): a = 1.0 b = u'abc' c = self.attr d = enum_y c = d return typeof(a), typeof(b), typeof(c), typeof(d) Cython-0.23.4/tests/run/tupleunpack_T712.pyx0000644000175600017570000000037512606202452021771 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 712 def single_from_string(): """ >>> print(single_from_string()) a """ (a,) = 'a' return a def single_from_set(): """ >>> print(single_from_set()) a """ (a,) = set(["a"]) return a Cython-0.23.4/tests/run/tupleunpack_T298.pyx0000644000175600017570000000043012606202452021772 0ustar jenkinsjenkins00000000000000# ticket: 298 """ >>> func() 0 0 0 0 1 1 1 1 2 2 2 2 >>> func2() """ def g(): return ((3, 2), 1, 0) def func2(): (a, b), c, d = g() def func(): for (a, b),c ,d in zip(zip(range(3), range(3)), range(3), range(3)): print a, b print c print d Cython-0.23.4/tests/run/tuplereassign.pyx0000644000175600017570000000066412606202452021607 0ustar jenkinsjenkins00000000000000def test1(t): """ >>> test1( (1,2,3) ) 1 """ t,a,b = t return t def test3(t): """ >>> test3( (1,2,3) ) 3 """ a,b,t = t return t def test(t): """ >>> test( (1,2,3) ) 3 """ t,t,t = t return t def testnonsense(): """ >>> testnonsense() # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... """ t,t,t = 1*2 return t Cython-0.23.4/tests/run/tupleassign.pyx0000644000175600017570000000603612606202452021257 0ustar jenkinsjenkins00000000000000t = (1,2,3) l = [1,2,3] def assign3(t): """ >>> assign3(l) (1, 2, 3) >>> assign3(t) (1, 2, 3) >>> assign3((1,)) Traceback (most recent call last): ValueError: need more than 1 value to unpack >>> assign3((1,2)) Traceback (most recent call last): ValueError: need more than 2 values to unpack >>> assign3((1,2,3,4)) Traceback (most recent call last): ValueError: too many values to unpack (expected 3) """ a,b,c = t return (a,b,c) def assign3_typed(tuple t): """ >>> assign3_typed(t) (1, 2, 3) >>> assign3_typed(l) Traceback (most recent call last): TypeError: Argument 't' has incorrect type (expected tuple, got list) >>> a,b,c = (1,) # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: ... >>> assign3_typed((1,)) Traceback (most recent call last): ValueError: need more than 1 value to unpack >>> a,b,c = (1,2) # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: ... >>> assign3_typed((1,2)) Traceback (most recent call last): ValueError: need more than 2 values to unpack >>> a,b,c = (1,2,3,4) # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: ... >>> assign3_typed((1,2,3,4)) Traceback (most recent call last): ValueError: too many values to unpack (expected 3) >>> a,b = 99,98 >>> a,b = t # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: ... >>> a,b (99, 98) """ a,b,c = t return (a,b,c) def assign3_int(t): """ >>> assign3_int(l) (1, 2, 3) """ cdef int a,b,c a,b,c = t return (a,b,c) def assign3_mixed1(t): """ >>> assign3_mixed1(l) (1, 2, 3) """ cdef int a a,b,c = t return (a,b,c) def assign3_mixed2(t): """ >>> assign3_mixed2(l) (1, 2, 3) """ cdef int b a,b,c = t return (a,b,c) def assign3_mixed3(t): """ >>> assign3_mixed3(l) (1, 2, 3) """ cdef int c a,b,c = t return (a,b,c) def assign3_mixed4(t): cdef int b,c a,b,c = t return (a,b,c) def test_overwrite(t): """ >>> test_overwrite(l) (99, 98) >>> test_overwrite(t) (99, 98) """ a,b = 99,98 try: a,b = t except ValueError: pass return (a,b) def test_overwrite_int(t): """ >>> test_overwrite_int(l) (99, 98) >>> test_overwrite_int(t) (99, 98) """ cdef int a,b a,b = 99,98 try: a,b = t except ValueError: pass return (a,b) def test_overwrite_mixed(t): """ >>> test_overwrite_mixed(l) (99, 98) >>> test_overwrite_mixed(t) (99, 98) """ cdef int b a,b = 99,98 try: a,b = t except ValueError: pass return (a,b) def test_overwrite_mixed2(t): """ >>> test_overwrite_mixed2(l) (99, 98) >>> test_overwrite_mixed2(t) (99, 98) """ cdef int a a,b = 99,98 try: a,b = t except ValueError: pass return (a,b) Cython-0.23.4/tests/run/tuple_unpack_string.pyx0000644000175600017570000000340212606202452022773 0ustar jenkinsjenkins00000000000000# mode: run # tag: string, unicode, sequence unpacking, starexpr def unpack_single_str(): """ >>> print(unpack_single_str()) a """ a, = 'a' return a def unpack_str(): """ >>> a,b = unpack_str() >>> print(a) a >>> print(b) b """ a,b = 'ab' return a,b def star_unpack_str(): """ >>> a,b,c = star_unpack_str() >>> print(a) a >>> type(b) is list True >>> print(''.join(b)) bbb >>> print(c) c """ a,*b,c = 'abbbc' return a,b,c def unpack_single_unicode(): """ >>> print(unpack_single_unicode()) a """ a, = u'a' return a def unpack_unicode(): """ >>> a,b = unpack_unicode() >>> print(a) a >>> print(b) b """ a,b = u'ab' return a,b def star_unpack_unicode(): """ >>> a,b,c = star_unpack_unicode() >>> print(a) a >>> type(b) is list True >>> print(''.join(b)) bbb >>> print(c) c """ a,*b,c = u'abbbc' return a,b,c # the following is not supported due to Py2/Py3 bytes differences ## def unpack_single_bytes(): ## """ ## >>> print(unpack_single_bytes().decode('ASCII')) ## a ## """ ## a, = b'a' ## return a ## def unpack_bytes(): ## """ ## >>> a,b = unpack_bytes() ## >>> print(a.decode('ASCII')) ## a ## >>> print(b.decode('ASCII')) ## b ## """ ## a,b = b'ab' ## return a,b ## def star_unpack_bytes(): ## """ ## >>> a,b,c = star_unpack_bytes() ## >>> print(a.decode('ASCII')) ## a ## >>> type(b) is list ## True ## >>> print(''.join([ch.decode('ASCII') for ch in b])) ## bbb ## >>> print(c.decode('ASCII')) ## c ## """ ## a,*b,c = b'abbbc' ## return a,b,c Cython-0.23.4/tests/run/tuple_constants.pyx0000644000175600017570000000603012606202452022140 0ustar jenkinsjenkins00000000000000 cimport cython module_level_tuple = (1,2,3) def return_module_level_tuple(): """ >>> return_module_level_tuple() (1, 2, 3) """ return module_level_tuple @cython.test_assert_path_exists("//TupleNode", "//TupleNode[@is_literal = true]") @cython.test_fail_if_path_exists("//TupleNode[@is_literal = false]") def return_empty_tuple(): """ >>> return_empty_tuple() () """ return () @cython.test_assert_path_exists("//TupleNode", "//TupleNode[@is_literal = true]") @cython.test_fail_if_path_exists("//TupleNode[@is_literal = false]") def return_constant_tuple1(): """ >>> return_constant_tuple1() (1,) """ return (1,) @cython.test_assert_path_exists("//TupleNode", "//TupleNode[@is_literal = true]") @cython.test_fail_if_path_exists("//TupleNode[@is_literal = false]") def return_folded_tuple(): """ >>> return_folded_tuple() (1, 2, 3) """ return (1, 1+1, 1+1+1) @cython.test_assert_path_exists("//TupleNode", "//TupleNode[@is_literal = true]") @cython.test_fail_if_path_exists("//TupleNode[@is_literal = false]") def return_nested_tuple(): """ >>> return_nested_tuple() (1, (2, 3), (3, (4, 5))) """ return (1, (2, 3), (3, (4, 5))) @cython.test_assert_path_exists("//TupleNode", "//TupleNode[@is_literal = true]") @cython.test_fail_if_path_exists("//TupleNode[@is_literal = false]") def constant_tuple1(): """ >>> constant_tuple1() (1,) """ tuple1 = (1,) return tuple1 @cython.test_assert_path_exists("//TupleNode", "//TupleNode[@is_literal = true]") @cython.test_fail_if_path_exists("//TupleNode[@is_literal = false]") def return_constant_tuple2(): """ >>> return_constant_tuple2() (1, 2) """ return (1,2) @cython.test_assert_path_exists("//TupleNode", "//TupleNode[@is_literal = true]") @cython.test_fail_if_path_exists("//TupleNode[@is_literal = false]") def return_constant_tuple_strings(): """ >>> return_constant_tuple_strings() ('tuple_1', 'bc', 'tuple_2') """ return ('tuple_1', 'bc', 'tuple_2') @cython.test_assert_path_exists("//TupleNode", "//TupleNode[@is_literal = true]") @cython.test_fail_if_path_exists("//TupleNode[@is_literal = false]") def return_constant_tuples_string_types(): """ >>> a,b,c = return_constant_tuples_string_types() >>> a is b False >>> a is c False >>> b is c False """ return ('a', 'bc'), (u'a', u'bc'), (b'a', b'bc') @cython.test_assert_path_exists("//ReturnStatNode//TupleNode", "//ReturnStatNode//TupleNode[@is_literal = false]") @cython.test_fail_if_path_exists("//ReturnStatNode//TupleNode[@is_literal = true]") def return_nonconstant_tuple(): """ >>> return_nonconstant_tuple() ('a', 1, 'd') """ a = eval("1") return ('a', a, 'd') Cython-0.23.4/tests/run/tuple.pyx0000644000175600017570000000501312606202452020044 0ustar jenkinsjenkins00000000000000 cimport cython def f(obj1, obj2, obj3, obj4, obj5): """ >>> f(1,2,3,4,5) () """ obj1 = () return obj1 def g(obj1, obj2, obj3, obj4, obj5): """ >>> g(1,2,3,4,5) (2,) """ obj1 = () obj1 = (obj2,) return obj1 def h(obj1, obj2, obj3, obj4, obj5): """ >>> h(1,2,3,4,5) (2, 3) """ obj1 = () obj1 = (obj2,) obj1 = obj2, obj3 return obj1 def j(obj1, obj2, obj3, obj4, obj5): """ >>> j(1,2,3,4,5) (2, 3, 4) """ obj1 = () obj1 = (obj2,) obj1 = obj2, obj3 obj1 = (obj2, obj3, obj4) return obj1 def k(obj1, obj2, obj3, obj4, obj5): """ >>> k(1,2,3,4,5) (2, 3, 4) """ obj1 = () obj1 = (obj2,) obj1 = obj2, obj3 obj1 = (obj2, obj3, obj4) obj1 = (obj2, obj3, obj4,) return obj1 def l(obj1, obj2, obj3, obj4, obj5): """ >>> l(1,2,3,4,5) (17, 42, 88) """ obj1 = () obj1 = (obj2,) obj1 = obj2, obj3 obj1 = (obj2, obj3, obj4) obj1 = (obj2, obj3, obj4,) obj1 = 17, 42, 88 return obj1 def tuple_none(): """ >>> tuple_none() # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...itera... """ return tuple(None) def tuple_none_list(): """ >>> tuple_none_list() # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...iterable... """ cdef list none = None return tuple(none) @cython.test_fail_if_path_exists( '//SimpleCallNode', '//PythonCapiCallNode' ) def tuple_of_tuple_literal(): """ >>> tuple_of_tuple_literal() (1, 2, 3) """ return tuple(tuple(tuple((1,2,3)))) @cython.test_fail_if_path_exists( '//SimpleCallNode', '//PythonCapiCallNode' ) def tuple_of_args_tuple(*args): """ >>> tuple_of_args_tuple(1,2,3) (1, 2, 3) """ return tuple(tuple(tuple(args))) @cython.test_fail_if_path_exists('//SimpleCallNode//SimpleCallNode') def tuple_of_object(ob): """ >>> tuple(type(1)) Traceback (most recent call last): TypeError: 'type' object is not iterable >>> sorted(tuple(set([1, 2, 3]))) [1, 2, 3] """ return tuple(ob) @cython.test_fail_if_path_exists( '//SimpleCallNode', '//PythonCapiCallNode//PythonCapiCallNode' ) def tuple_of_tuple_or_none(tuple x): """ >>> tuple_of_tuple_or_none((1,2,3)) (1, 2, 3) >>> tuple_of_tuple_or_none(None) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...itera... """ return tuple(tuple(tuple(x))) Cython-0.23.4/tests/run/tryfinallychaining.pyx0000644000175600017570000000205612606202452022615 0ustar jenkinsjenkins00000000000000# mode: run # tag: exceptions, tryfinally import sys IS_PY3 = sys.version_info[0] >= 3 def test_finally_c(): """ >>> def test_finally_py(): ... try: ... raise AttributeError() ... finally: ... raise KeyError() >>> try: ... test_finally_py() ... except KeyError: ... print(sys.exc_info()[0] is KeyError or sys.exc_info()[0]) ... if IS_PY3: ... print(isinstance(sys.exc_info()[1].__context__, AttributeError) ... or sys.exc_info()[1].__context__) ... else: ... print(True) True True >>> try: ... test_finally_c() ... except KeyError: ... print(sys.exc_info()[0] is KeyError or sys.exc_info()[0]) ... if IS_PY3: ... print(isinstance(sys.exc_info()[1].__context__, AttributeError) ... or sys.exc_info()[1].__context__) ... else: ... print(True) True True """ try: raise AttributeError() finally: raise KeyError() Cython-0.23.4/tests/run/tryfinally.pyx0000644000175600017570000003105712606202452021117 0ustar jenkinsjenkins00000000000000# mode: run # tag: tryfinally import string import sys IS_PY3 = sys.version_info[0] >= 3 cimport cython try: next except NameError: def next(it): return it.next() def finally_except(): """ >>> try: ... raise ValueError ... finally: ... raise TypeError Traceback (most recent call last): TypeError >>> finally_except() Traceback (most recent call last): TypeError """ try: raise ValueError finally: raise TypeError def finally_pass(): """ >>> finally_pass() Traceback (most recent call last): ValueError """ try: raise ValueError() finally: pass def except_finally_reraise(): """ >>> def py_check(): ... try: raise ValueError ... except ValueError: ... for i in range(2): ... try: raise TypeError ... finally: ... break ... assert sys.exc_info()[0] == ValueError, str(sys.exc_info()) ... raise ... >>> py_check() Traceback (most recent call last): ValueError >>> except_finally_reraise() Traceback (most recent call last): ValueError """ try: raise ValueError except ValueError: for i in range(2): try: raise TypeError finally: break assert sys.exc_info()[0] == ValueError, str(sys.exc_info()) raise def except_finally_reraise_new(): """ >>> def py_check(): ... try: raise ValueError ... except ValueError: ... try: raise TypeError ... finally: ... raise >>> try: py_check() ... except ValueError: assert not IS_PY3 ... except TypeError: assert IS_PY3 ... else: assert False >>> try: except_finally_reraise_new() ... except TypeError: pass # currently only Py3 semantics implemented ... else: assert False """ try: raise ValueError except ValueError: try: raise TypeError finally: raise def finally_exception_check_return(): """ >>> if not IS_PY3: ... sys.exc_clear() >>> def py_check(): ... try: raise ValueError() ... finally: ... if IS_PY3: ... assert sys.exc_info()[0] == ValueError, str(sys.exc_info()) ... else: ... assert sys.exc_info() == (None, None, None), str(sys.exc_info()) ... return 1 >>> py_check() 1 >>> finally_exception_check_return() 1 """ try: raise ValueError() finally: if IS_PY3: assert sys.exc_info()[0] == ValueError, str(sys.exc_info()) else: assert sys.exc_info() == (None, None, None), str(sys.exc_info()) return 1 cdef void swallow(): try: raise TypeError() except: return def finally_exception_check_swallow(): """ >>> if not IS_PY3: ... sys.exc_clear() >>> def swallow(): ... try: raise TypeError() ... except: return >>> def py_check(): ... try: raise ValueError() ... finally: ... if IS_PY3: ... assert sys.exc_info()[0] == ValueError, str(sys.exc_info()) ... else: ... assert sys.exc_info() == (None, None, None), str(sys.exc_info()) ... swallow() ... if IS_PY3: ... assert sys.exc_info()[0] == ValueError, str(sys.exc_info()) ... else: ... assert sys.exc_info() == (None, None, None), str(sys.exc_info()) >>> py_check() Traceback (most recent call last): ValueError >>> if not IS_PY3: ... sys.exc_clear() >>> finally_exception_check_swallow() Traceback (most recent call last): ValueError """ try: raise ValueError() finally: if IS_PY3: assert sys.exc_info()[0] == ValueError, str(sys.exc_info()) else: assert sys.exc_info() == (None, None, None), str(sys.exc_info()) swallow() if IS_PY3: assert sys.exc_info()[0] == ValueError, str(sys.exc_info()) else: assert sys.exc_info() == (None, None, None), str(sys.exc_info()) def finally_exception_break_check(): """ >>> if not IS_PY3: ... sys.exc_clear() >>> def py_check(): ... i = None ... for i in range(2): ... try: raise ValueError() ... finally: ... if IS_PY3: ... assert sys.exc_info()[0] == ValueError, str(sys.exc_info()) ... else: ... assert sys.exc_info() == (None, None, None), str(sys.exc_info()) ... break ... assert sys.exc_info() == (None, None, None), str(sys.exc_info()) ... return i >>> py_check() 0 >>> finally_exception_break_check() 0 """ i = None for i in range(2): try: raise ValueError() finally: if IS_PY3: assert sys.exc_info()[0] == ValueError, str(sys.exc_info()) else: assert sys.exc_info() == (None, None, None), str(sys.exc_info()) break assert sys.exc_info() == (None, None, None), str(sys.exc_info()) return i def finally_exception_break_check_with_swallowed_raise(): """ >>> if not IS_PY3: ... sys.exc_clear() >>> def swallow(): ... try: raise TypeError() ... except: return >>> def py_check(): ... i = None ... for i in range(2): ... try: raise ValueError() ... finally: ... if IS_PY3: ... assert sys.exc_info()[0] == ValueError, str(sys.exc_info()) ... else: ... assert sys.exc_info() == (None, None, None), str(sys.exc_info()) ... swallow() ... if IS_PY3: ... assert sys.exc_info()[0] == ValueError, str(sys.exc_info()) ... else: ... assert sys.exc_info() == (None, None, None), str(sys.exc_info()) ... break ... assert sys.exc_info() == (None, None, None), str(sys.exc_info()) ... return i >>> py_check() 0 >>> finally_exception_break_check_with_swallowed_raise() 0 """ i = None for i in range(2): try: raise ValueError() finally: if IS_PY3: assert sys.exc_info()[0] == ValueError, str(sys.exc_info()) else: assert sys.exc_info() == (None, None, None), str(sys.exc_info()) swallow() if IS_PY3: assert sys.exc_info()[0] == ValueError, str(sys.exc_info()) else: assert sys.exc_info() == (None, None, None), str(sys.exc_info()) break assert sys.exc_info() == (None, None, None), str(sys.exc_info()) return i def try_return_cy(): """ >>> def try_return_py(): ... try: ... return 1 ... finally: ... return 2 >>> try_return_py() 2 >>> try_return_cy() 2 """ try: return 1 finally: return 2 cdef int try_return_c(): try: return 1 finally: return 2 def call_try_return_c(): """ >>> call_try_return_c() 2 """ return try_return_c() cdef int try_return_with_exception(): try: raise TypeError finally: return 1 def call_try_return_with_exception(): """ >>> call_try_return_with_exception() 1 """ return try_return_with_exception() def try_return_temp(a): b = a+2 try: c = a+b return c finally: print b-a def try_continue(a): """ >>> i=1 >>> for i in range(3): ... try: ... continue ... finally: ... i+=1 >>> i 3 >>> try_continue(3) 3 """ i=1 for i in range(a): try: continue finally: i+=1 return i def try_return_none_1(): """ >>> try_return_none_1() """ try: return finally: return cdef extern from *: ctypedef struct PyObject void Py_INCREF(object) cdef PyObject* _none(): ret = None Py_INCREF(ret) return ret def try_return_none_2(): """ >>> try_return_none_2() """ try: return _none() finally: return _none() def try_break(): """ >>> try_break() """ for a in "abcd": try: if a == 'c': break except: break def empty_try(): """ >>> empty_try() 1 """ try: pass finally: return 1 def empty_try_in_except_raise(raise_in_finally): """ >>> empty_try_in_except_raise(False) Traceback (most recent call last): ValueError: HUHU >>> empty_try_in_except_raise(True) Traceback (most recent call last): TypeError: OLA """ try: raise ValueError("HUHU") except ValueError: try: pass finally: if raise_in_finally: raise TypeError('OLA') raise def try_all_cases(x): """ >>> try_all_cases(None) 2 >>> try_all_cases('break') 4 >>> try_all_cases('raise') Traceback (most recent call last): ValueError >>> try_all_cases('return') 3 >>> try_all_cases('tryraise') Traceback (most recent call last): TypeError >>> try_all_cases('trybreak') 4 """ for i in range(3): try: if i == 0: pass elif i == 1: continue elif x == 'trybreak': break elif x == 'tryraise': raise TypeError() else: return 2 finally: if x == 'raise': raise ValueError() elif x == 'break': break elif x == 'return': return 3 return 4 def finally_yield(x): """ >>> g = finally_yield(None) >>> next(g) # 1 1 >>> next(g) # 2 1 >>> next(g) # 3 Traceback (most recent call last): StopIteration >>> g = finally_yield('raise') >>> next(g) # raise 1 1 >>> next(g) # raise 2 1 >>> next(g) # raise 3 Traceback (most recent call last): TypeError >>> g = finally_yield('break') >>> next(g) # break 1 1 >>> next(g) # break 2 1 >>> next(g) # break 3 Traceback (most recent call last): StopIteration """ for i in range(3): try: if i == 0: continue elif x == 'raise': raise TypeError() elif x == 'break': break else: return finally: yield 1 def complex_finally_clause(x, obj): """ >>> class T(object): ... def method(self, value): ... print(value) >>> complex_finally_clause('finish', T()) module.py module.py module.py 99 >>> complex_finally_clause('tryreturn', T()) module.py module.py module.py 2 >>> complex_finally_clause('trybreak', T()) module.py module.py module.py 99 >>> complex_finally_clause('tryraise', T()) Traceback (most recent call last): TypeError """ name = 'module' l = [] cdef object lobj = l for i in range(3): l[:] = [1, 2, 3] try: if i == 0: pass elif i == 1: continue elif x == 'trybreak': break elif x == 'tryraise': raise TypeError() elif x == 'tryreturn': return 2 else: pass finally: obj.method(name + '.py') from contextlib import contextmanager with contextmanager(lambda: (yield 1))() as y: assert y == 1 a = 1 with nogil: if i > 0: with gil: assert obj.method a = 2 # FIXME: prevent deep-copying inner functions #def closure(l): # assert l == lobj #closure() assert name[0] in string.ascii_letters string.Template("-- huhu $name --").substitute(**{'name': '(%s)' % name}) if a: a = 3 del l[0], lobj[0] assert all(i == 3 for i in l), l return 99 Cython-0.23.4/tests/run/tryexcept.pyx0000644000175600017570000002303412606202452020745 0ustar jenkinsjenkins00000000000000def single_except(a, x): """ >>> single_except(ValueError, None) 2 >>> single_except(ValueError, ValueError('test')) 3 >>> single_except(ValueError, TypeError('test')) Traceback (most recent call last): TypeError: test """ cdef int i try: i = 1 if x: raise x i = 2 except a: i = 3 return i def single_except_builtin(a, x): """ >>> single_except_builtin(ValueError, None) 2 >>> single_except_builtin(ValueError, ValueError('test')) 3 >>> single_except_builtin(ValueError, TypeError('test')) Traceback (most recent call last): TypeError: test """ cdef int i try: i = 1 if x: raise x i = 2 except ValueError: i = 3 return i def single_except_expression(a, x): """ >>> single_except_expression([[ValueError]], None) 2 >>> single_except_expression([[ValueError]], ValueError('test')) 3 >>> single_except_expression([[ValueError]], TypeError('test')) Traceback (most recent call last): TypeError: test """ cdef int i try: i = 1 if x: raise x i = 2 except a[0][0]: i = 3 return i def double_except_no_raise(a,b): """ >>> double_except_no_raise(TypeError, ValueError) 1 """ d = a or b # mark used cdef int i try: i = 1 except a: i = 2 except b: i = 3 return i def double_except_raise(x, a, b): """ >>> double_except_raise(None, TypeError, ValueError) 1 >>> double_except_raise(TypeError('test'), TypeError, ValueError) 2 >>> double_except_raise(ValueError('test'), TypeError, ValueError) 3 >>> double_except_raise(None, TypeError, ValueError) 1 """ cdef int i try: i = 1 if x: raise x except a: i = 2 except b: i = 3 return i def target_except_no_raise(a): """ >>> target_except_no_raise(TypeError) 1 """ d = a # mark used cdef int i try: i = 1 except a, b: i = 2 return i def target_except_raise(x, a): """ >>> target_except_raise(None, TypeError) 1 >>> target_except_raise(TypeError('test'), TypeError) 2 >>> target_except_raise(ValueError('test'), TypeError) Traceback (most recent call last): ValueError: test >>> target_except_raise(None, TypeError) 1 """ cdef int i try: i = 1 if x: raise x except a, b: i = 2 assert isinstance(b, a) return i def tuple_except_builtin(x): """ >>> tuple_except_builtin(None) 1 >>> tuple_except_builtin(TypeError('test')) 2 >>> tuple_except_builtin(ValueError('test')) 2 >>> tuple_except_builtin(IndexError('5')) Traceback (most recent call last): IndexError: 5 >>> tuple_except_builtin(None) 1 """ cdef int i try: i = 1 if x: raise x except (TypeError, ValueError): i = 2 return i def normal_and_bare_except_no_raise(a): """ >>> normal_and_bare_except_no_raise(TypeError) 1 """ d = a # mark used cdef int i try: i = 1 except a: i = 2 except: i = 3 return i def normal_and_bare_except_raise(x, a): """ >>> normal_and_bare_except_raise(None, TypeError) 1 >>> normal_and_bare_except_raise(TypeError('test'), TypeError) 2 >>> normal_and_bare_except_raise(ValueError('test'), TypeError) 3 >>> normal_and_bare_except_raise(None, TypeError) 1 """ cdef int i try: i = 1 if x: raise x except a: i = 2 except: i = 3 return i def tuple_except_index_target_no_raise(a, b, c): """ >>> l = [None, None] >>> tuple_except_index_target_no_raise(TypeError, ValueError, l) 1 >>> l [None, None] """ d = a or b or c # mark used cdef int i try: i = 1 except (a, b), c[1]: i = 2 return i def tuple_except_index_target_raise(x, a, b, c): """ >>> l = [None, None] >>> tuple_except_index_target_raise(None, TypeError, ValueError, l) 1 >>> l [None, None] >>> tuple_except_index_target_raise(TypeError('test'), TypeError, ValueError, l) 2 >>> l[0] is None, isinstance(l[1], TypeError) (True, True) >>> tuple_except_index_target_raise(ValueError('test'), TypeError, ValueError, l) 2 >>> l[0] is None, isinstance(l[1], ValueError) (True, True) >>> tuple_except_index_target_raise(IndexError('5'), TypeError, ValueError, l) Traceback (most recent call last): IndexError: 5 >>> tuple_except_index_target_raise(None, TypeError, ValueError, l) 1 >>> l[0] is None, isinstance(l[1], ValueError) (True, True) """ cdef int i try: i = 1 if x: raise x except (a, b), c[1]: i = 2 assert isinstance(c[1], (a,b)) return i def loop_bare_except_no_raise(a, b, int c): """ >>> loop_bare_except_no_raise(TypeError, range(2), 2) (1, 3528) """ cdef int i = 1 for a in b: try: c = c * 42 except: i = 17 return i,c def loop_bare_except_raise(a, b, int c): """ >>> loop_bare_except_raise(TypeError, range(2), 2) (1, 3528) >>> loop_bare_except_raise(TypeError, range(3), 2) (17, 148176) >>> loop_bare_except_raise(TypeError, range(4), 2) (17, 6223392) """ cdef int i = 1 for a in b: try: c = c * 42 if a == 2: raise TypeError('test') except: i = 17 return i,c def bare_except_reraise_no_raise(l): """ >>> l = [None] >>> bare_except_reraise_no_raise(l) 1 >>> l [None] """ d = l # mark used cdef int i try: i = 1 except: l[0] = 2 raise return i def bare_except_reraise_raise(x, l): """ >>> l = [None] >>> bare_except_reraise_raise(None, l) 1 >>> l [None] >>> bare_except_reraise_raise(TypeError('test'), l) Traceback (most recent call last): TypeError: test >>> l [2] >>> l = [None] >>> bare_except_reraise_raise(None, l) 1 >>> l [None] """ cdef int i try: i = 1 if x: raise x except: l[0] = 2 raise return i def except_as_no_raise(a): """ >>> except_as_no_raise(TypeError) 1 """ d = a # mark used try: i = 1 except a as b: i = 2 return i def except_as_raise(x, a): """ >>> except_as_raise(None, TypeError) 1 >>> except_as_raise(TypeError('test'), TypeError) 2 >>> except_as_raise(ValueError('test'), TypeError) Traceback (most recent call last): ValueError: test >>> except_as_raise(None, TypeError) 1 """ try: i = 1 if x: raise x except a as b: i = 2 assert isinstance(b, a) return i def except_as_no_raise_does_not_touch_target(a): """ >>> i,b = except_as_no_raise_does_not_touch_target(TypeError) >>> i 1 >>> b 1 """ d = a # mark used b = 1 try: i = 1 except a as b: i = 2 return i, b def except_as_raise_does_not_delete_target(x, a): """ >>> except_as_raise_does_not_delete_target(None, TypeError) 1 >>> except_as_raise_does_not_delete_target(TypeError('test'), TypeError) 2 >>> except_as_raise_does_not_delete_target(ValueError('test'), TypeError) Traceback (most recent call last): ValueError: test >>> except_as_raise_does_not_delete_target(None, TypeError) 1 """ b = 1 try: i = 1 if x: raise x except a as b: i = 2 assert isinstance(b, a) # exception variable leaks with Py2 except-as semantics if x: assert isinstance(b, a) else: assert b == 1 return i def except_as_raise_with_empty_except(x, a): """ >>> except_as_raise_with_empty_except(None, TypeError) >>> except_as_raise_with_empty_except(TypeError('test'), TypeError) >>> except_as_raise_with_empty_except(ValueError('test'), TypeError) Traceback (most recent call last): ValueError: test >>> except_as_raise_with_empty_except(None, TypeError) """ try: if x: raise x b = 1 except a as b: pass if x: assert isinstance(b, a) else: assert b == 1 def complete_except_as_no_raise(a, b): """ >>> complete_except_as_no_raise(TypeError, ValueError) 5 """ d = a or b # mark used try: i = 1 except (a, b) as c: i = 2 except (b, a) as c: i = 3 except: i = 4 else: i = 5 return i def complete_except_as_raise(x, a, b): """ >>> complete_except_as_raise(None, TypeError, ValueError) 5 >>> complete_except_as_raise(TypeError('test'), TypeError, ValueError) 2 >>> complete_except_as_raise(ValueError('test'), TypeError, ValueError) 2 >>> complete_except_as_raise(IndexError('5'), TypeError, ValueError) 4 >>> complete_except_as_raise(None, TypeError, ValueError) 5 """ try: i = 1 if x: raise x except (a, b) as c: i = 2 assert isinstance(c, (a, b)) except (b, a) as c: i = 3 assert isinstance(c, (a, b)) except: i = 4 else: i = 5 return i Cython-0.23.4/tests/run/trybreak.pyx0000644000175600017570000000122212606202452020534 0ustar jenkinsjenkins00000000000000# Indirectly makes sure the cleanup happens correctly on breaking. def try_except_break(): """ >>> print(try_except_break()) a """ for x in list("abc"): try: x() except: break return x def try_break_except(): """ >>> print(try_break_except()) a """ for x in list("abc"): try: break except: pass return x def try_no_break_except_return(): """ >>> print(try_no_break_except_return()) a """ for x in list("abc"): try: x() break except: return x return x Cython-0.23.4/tests/run/tp_new_cimport.srctree0000644000175600017570000000343712606202452022603 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import tp_new_tests; tp_new_tests.test_all()" PYTHON -c "import tp_new_tests; tp_new_tests.test_sub()" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize("**/*.pyx"), ) ######## tp_new_tests.py ######## def test_all(): test_a() test_b() test_a_in_b() test_sub() def test_a(): import a assert isinstance(a.tpnew_ExtTypeA(), a.ExtTypeA) assert a.tpnew_ExtTypeA().attrA == 123 def test_b(): import b assert isinstance(b.tpnew_ExtTypeB(), b.ExtTypeB) assert b.tpnew_ExtTypeB().attrB == 234 def test_a_in_b(): import a,b assert isinstance(b.tpnew_ExtTypeA(), a.ExtTypeA) assert b.tpnew_ExtTypeA().attrA == 123 def test_sub(): import b assert isinstance(b.tpnew_SubExtTypeA(), b.SubExtTypeA) assert b.tpnew_SubExtTypeA().attrAB == 345 assert b.tpnew_SubExtTypeA().attrA == 123 ######## a.pxd ######## cdef api class ExtTypeA[type ExtTypeA_Type, object ExtTypeAObject]: cdef readonly attrA ######## a.pyx ######## cdef class ExtTypeA: def __cinit__(self): self.attrA = 123 def tpnew_ExtTypeA(): return ExtTypeA.__new__(ExtTypeA) ######## b.pxd ######## from a cimport ExtTypeA cdef class ExtTypeB: cdef readonly attrB cdef class SubExtTypeA(ExtTypeA): cdef readonly attrAB ######## b.pyx ######## from a cimport ExtTypeA cdef class ExtTypeB: def __cinit__(self): self.attrB = 234 cdef class SubExtTypeA(ExtTypeA): def __cinit__(self): self.attrAB = 345 def tpnew_ExtTypeA(): return ExtTypeA.__new__(ExtTypeA) def tpnew_ExtTypeB(): return ExtTypeB.__new__(ExtTypeB) def tpnew_SubExtTypeA(): return SubExtTypeA.__new__(SubExtTypeA) Cython-0.23.4/tests/run/tp_new_T454.pyx0000644000175600017570000000061412606202452020731 0ustar jenkinsjenkins00000000000000# ticket: 454 cimport cython cdef class TypeWithFactory: @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode/AttributeNode') @classmethod def new(cls): return cls.__new__(cls) def make_new_factory(): """ >>> isinstance(make_new_factory(), TypeWithFactory) True """ return TypeWithFactory.new() Cython-0.23.4/tests/run/tp_new.pyx0000644000175600017570000001311212606202452020206 0ustar jenkinsjenkins00000000000000# ticket: 808 cimport cython cdef class MyType: cdef public args, kwargs def __cinit__(self, *args, **kwargs): self.args, self.kwargs = args, kwargs print "CINIT" def __init__(self, *args, **kwargs): print "INIT" cdef class MySubType(MyType): def __cinit__(self, *args, **kwargs): self.args, self.kwargs = args, kwargs print "CINIT(SUB)" def __init__(self, *args, **kwargs): print "INIT" class MyClass(object): def __cinit__(self, *args, **kwargs): self.args, self.kwargs = args, kwargs print "CINIT" def __init__(self, *args, **kwargs): print "INIT" class MyTypeSubClass(MyType): def __cinit__(self, *args, **kwargs): # not called: Python class! print "CINIT(PYSUB)" def __init__(self, *args, **kwargs): print "INIT" # See ticket T808, vtab must be set even if there is no __cinit__. cdef class Base(object): pass cdef class Derived(Base): cpdef int f(self): return 42 def test_derived_vtab(): """ >>> test_derived_vtab() 42 """ cdef Derived d = Derived.__new__(Derived) return d.f() # only these can be safely optimised: @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists( '//SimpleCallNode/AttributeNode', '//PyMethodCallNode', ) def make_new(): """ >>> isinstance(make_new(), MyType) CINIT True """ m = MyType.__new__(MyType) return m @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists( '//SimpleCallNode/AttributeNode', '//PyMethodCallNode', ) def make_new_typed_target(): """ >>> isinstance(make_new_typed_target(), MyType) CINIT True """ cdef MyType m m = MyType.__new__(MyType) return m @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists( '//SimpleCallNode/AttributeNode', '//PyMethodCallNode', ) def make_new_with_args(): """ >>> isinstance(make_new_with_args(), MyType) CINIT (1, 2, 3) {} True """ m = MyType.__new__(MyType, 1, 2 ,3) print m.args print m.kwargs return m @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists( '//SimpleCallNode/AttributeNode', '//PyMethodCallNode', ) def make_new_with_args_kwargs(): """ >>> isinstance(make_new_with_args_kwargs(), MyType) CINIT (1, 2, 3) {'a': 4} True """ m = MyType.__new__(MyType, 1, 2 ,3, a=4) print m.args print m.kwargs return m @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists( '//SimpleCallNode/AttributeNode', '//PyMethodCallNode', ) def make_new_builtin(): """ >>> isinstance(make_new_builtin(), tuple) True """ m = dict.__new__(dict) m = list.__new__(list) m = tuple.__new__(tuple) return m @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists( '//SimpleCallNode/AttributeNode', '//PyMethodCallNode', ) def make_new_none(type t=None): """ >>> make_new_none() # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... is not a type object (NoneType) """ m = t.__new__(t) return m @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists( '//SimpleCallNode/AttributeNode', '//PyMethodCallNode', ) def make_new_kwargs(type t=None): """ >>> m = make_new_kwargs(MyType) CINIT >>> isinstance(m, MyType) True >>> m.args (1, 2, 3) >>> m.kwargs {'a': 5} """ m = t.__new__(t, 1, 2, 3, a=5) return m # these cannot: @cython.test_assert_path_exists('//PyMethodCallNode/AttributeNode') @cython.test_fail_if_path_exists('//PythonCapiCallNode') def make_new_pyclass(): """ >>> isinstance(make_new_pyclass(), MyTypeSubClass) CINIT True """ m = MyClass.__new__(MyClass) m = MyTypeSubClass.__new__(MyTypeSubClass) return m @cython.test_assert_path_exists('//PyMethodCallNode/AttributeNode') @cython.test_fail_if_path_exists('//PythonCapiCallNode') def make_new_args(type t1=None, type t2=None): """ >>> isinstance(make_new_args(), MyType) CINIT True >>> isinstance(make_new_args(MyType), MyType) CINIT True >>> isinstance(make_new_args(MyType, MyType), MyType) CINIT True >>> isinstance(make_new_args(MyType, MySubType), MySubType) Traceback (most recent call last): TypeError: tp_new.MyType.__new__(tp_new.MySubType) is not safe, use tp_new.MySubType.__new__() >>> isinstance(make_new_args(MySubType, MyType), MyType) Traceback (most recent call last): TypeError: tp_new.MySubType.__new__(tp_new.MyType): tp_new.MyType is not a subtype of tp_new.MySubType """ if t1 is None: t1 = MyType if t2 is None: t2 = MyType m = t1.__new__(t2) return m @cython.test_assert_path_exists('//PyMethodCallNode/AttributeNode') @cython.test_fail_if_path_exists('//PythonCapiCallNode') def make_new_none_typed(tuple t=None): """ >>> make_new_none_typed() # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... is not a type object (NoneType) """ m = t.__new__(t) return m @cython.test_assert_path_exists('//PyMethodCallNode/AttributeNode') @cython.test_fail_if_path_exists('//PythonCapiCallNode') def make_new_untyped(t): """ >>> make_new_untyped(None) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... is not a type object (NoneType) """ m = t.__new__(t) return m Cython-0.23.4/tests/run/ticket_124.pyx0000644000175600017570000000017612606202452020571 0ustar jenkinsjenkins00000000000000def spam(dict d): """ >>> spam(dict(test=2)) False """ for elm in d: return False return True Cython-0.23.4/tests/run/ticket_123.pyx0000644000175600017570000000052012606202452020561 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> ret = repeat_iter() >>> for s in ret: ... print(s) a a b b c c """ def repeat_iter(): cdef dict e cdef unicode s ret = [] e = {u"A": u"a", u"B": u"b", u"C": u"c"} for s in e.itervalues(): ret.append(s) for s in e.itervalues(): ret.append(s) ret.sort() return ret Cython-0.23.4/tests/run/testinclude.pxi0000644000175600017570000000003712606202452021217 0ustar jenkinsjenkins00000000000000# this will be included D = 2 Cython-0.23.4/tests/run/test_raisefrom.pyx0000644000175600017570000000365212606202452021750 0ustar jenkinsjenkins00000000000000 import sys import unittest # adapted from pyregr class TestCause(unittest.TestCase): def test_invalid_cause(self): try: raise IndexError from 5 except TypeError as e: self.assertTrue("exception cause" in str(e)) else: self.fail("No exception raised") def test_raise_from_none_sets_no_cause(self): try: raise IndexError from None except IndexError as e: self.assertFalse(e.__cause__) if sys.version_info[:2] >= (3,3): self.assertTrue(e.__suppress_context__) else: self.fail("No exception raised") def test_raise_from_none_covers_context(self): try: try: raise IndexError("INDEX") except IndexError as e: raise ValueError("VALUE") from None else: self.fail("No exception raised") except ValueError as e: self.assertFalse(e.__cause__) self.assertTrue(e.__context__) if sys.version_info[:2] >= (3,3): self.assertTrue(e.__suppress_context__) def test_class_cause(self): try: raise IndexError from KeyError except IndexError as e: self.assertTrue(isinstance(e.__cause__, KeyError)) else: self.fail("No exception raised") def test_instance_cause(self): cause = KeyError() try: raise IndexError from cause except IndexError as e: self.assertTrue(e.__cause__ is cause) else: self.fail("No exception raised") def test_erroneous_cause(self): class MyException(Exception): def __init__(self): raise RuntimeError() try: raise IndexError from MyException except RuntimeError: pass else: self.fail("No exception raised") Cython-0.23.4/tests/run/test_dictviews.pyx0000644000175600017570000001473712606202452021770 0ustar jenkinsjenkins00000000000000import unittest class DictSetTest(unittest.TestCase): def test_constructors_not_callable(self): kt = type({}.viewkeys()) self.assertRaises(TypeError, kt, {}) self.assertRaises(TypeError, kt) it = type({}.viewitems()) self.assertRaises(TypeError, it, {}) self.assertRaises(TypeError, it) vt = type({}.viewvalues()) self.assertRaises(TypeError, vt, {}) self.assertRaises(TypeError, vt) def test_dict_keys(self): d = {1: 10, "a": "ABC"} keys = d.viewkeys() self.assertEqual(len(keys), 2) self.assertEqual(set(keys), set([1, "a"])) self.assertEqual(keys, set([1, "a"])) self.assertNotEqual(keys, set([1, "a", "b"])) self.assertNotEqual(keys, set([1, "b"])) self.assertNotEqual(keys, set([1])) self.assertNotEqual(keys, 42) self.assertIn(1, keys) self.assertIn("a", keys) self.assertNotIn(10, keys) self.assertNotIn("Z", keys) self.assertEqual(d.viewkeys(), d.viewkeys()) e = {1: 11, "a": "def"} self.assertEqual(d.viewkeys(), e.viewkeys()) del e["a"] self.assertNotEqual(d.viewkeys(), e.viewkeys()) def test_dict_items(self): d = {1: 10, "a": "ABC"} items = d.viewitems() self.assertEqual(len(items), 2) self.assertEqual(set(items), set([(1, 10), ("a", "ABC")])) self.assertEqual(items, set([(1, 10), ("a", "ABC")])) self.assertNotEqual(items, set([(1, 10), ("a", "ABC"), "junk"])) self.assertNotEqual(items, set([(1, 10), ("a", "def")])) self.assertNotEqual(items, set([(1, 10)])) self.assertNotEqual(items, 42) self.assertIn((1, 10), items) self.assertIn(("a", "ABC"), items) self.assertNotIn((1, 11), items) self.assertNotIn(1, items) self.assertNotIn((), items) self.assertNotIn((1,), items) self.assertNotIn((1, 2, 3), items) self.assertEqual(d.viewitems(), d.viewitems()) e = dict(d.copy()) self.assertEqual(d.viewitems(), e.viewitems()) e["a"] = "def" self.assertNotEqual(d.viewitems(), e.viewitems()) def test_dict_mixed_keys_items(self): d = {(1, 1): 11, (2, 2): 22} e = {1: 1, 2: 2} self.assertEqual(d.viewkeys(), e.viewitems()) self.assertNotEqual(d.viewitems(), e.viewkeys()) def test_dict_values(self): d = {1: 10, "a": "ABC"} values = d.viewvalues() self.assertEqual(set(values), set([10, "ABC"])) self.assertEqual(len(values), 2) def test_dict_repr(self): d = {1: 10, "a": "ABC"} self.assertTrue(isinstance(repr(d), str)) r = repr(d.viewitems()) self.assertTrue(isinstance(r, str)) self.assertTrue(r == "dict_items([('a', 'ABC'), (1, 10)])" or r == "dict_items([(1, 10), ('a', 'ABC')])") r = repr(d.viewkeys()) self.assertTrue(isinstance(r, str)) self.assertTrue(r == "dict_keys(['a', 1])" or r == "dict_keys([1, 'a'])") r = repr(d.viewvalues()) self.assertTrue(isinstance(r, str)) self.assertTrue(r == "dict_values(['ABC', 10])" or r == "dict_values([10, 'ABC'])") def test_keys_set_operations(self): d1 = {'a': 1, 'b': 2} d2 = {'b': 3, 'c': 2} d3 = {'d': 4, 'e': 5} self.assertEqual(d1.viewkeys() & d1.viewkeys(), {'a', 'b'}) self.assertEqual(d1.viewkeys() & d2.viewkeys(), {'b'}) self.assertEqual(d1.viewkeys() & d3.viewkeys(), set()) self.assertEqual(d1.viewkeys() & set(d1.viewkeys()), {'a', 'b'}) self.assertEqual(d1.viewkeys() & set(d2.viewkeys()), {'b'}) self.assertEqual(d1.viewkeys() & set(d3.viewkeys()), set()) self.assertEqual(d1.viewkeys() | d1.viewkeys(), {'a', 'b'}) self.assertEqual(d1.viewkeys() | d2.viewkeys(), {'a', 'b', 'c'}) self.assertEqual(d1.viewkeys() | d3.viewkeys(), {'a', 'b', 'd', 'e'}) self.assertEqual(d1.viewkeys() | set(d1.viewkeys()), {'a', 'b'}) self.assertEqual(d1.viewkeys() | set(d2.viewkeys()), {'a', 'b', 'c'}) self.assertEqual(d1.viewkeys() | set(d3.viewkeys()), {'a', 'b', 'd', 'e'}) self.assertEqual(d1.viewkeys() ^ d1.viewkeys(), set()) self.assertEqual(d1.viewkeys() ^ d2.viewkeys(), {'a', 'c'}) self.assertEqual(d1.viewkeys() ^ d3.viewkeys(), {'a', 'b', 'd', 'e'}) self.assertEqual(d1.viewkeys() ^ set(d1.viewkeys()), set()) self.assertEqual(d1.viewkeys() ^ set(d2.viewkeys()), {'a', 'c'}) self.assertEqual(d1.viewkeys() ^ set(d3.viewkeys()), {'a', 'b', 'd', 'e'}) def test_items_set_operations(self): d1 = {'a': 1, 'b': 2} d2 = {'a': 2, 'b': 2} d3 = {'d': 4, 'e': 5} self.assertEqual( d1.viewitems() & d1.viewitems(), {('a', 1), ('b', 2)}) self.assertEqual(d1.viewitems() & d2.viewitems(), {('b', 2)}) self.assertEqual(d1.viewitems() & d3.viewitems(), set()) self.assertEqual(d1.viewitems() & set(d1.viewitems()), {('a', 1), ('b', 2)}) self.assertEqual(d1.viewitems() & set(d2.viewitems()), {('b', 2)}) self.assertEqual(d1.viewitems() & set(d3.viewitems()), set()) self.assertEqual(d1.viewitems() | d1.viewitems(), {('a', 1), ('b', 2)}) self.assertEqual(d1.viewitems() | d2.viewitems(), {('a', 1), ('a', 2), ('b', 2)}) self.assertEqual(d1.viewitems() | d3.viewitems(), {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) self.assertEqual(d1.viewitems() | set(d1.viewitems()), {('a', 1), ('b', 2)}) self.assertEqual(d1.viewitems() | set(d2.viewitems()), {('a', 1), ('a', 2), ('b', 2)}) self.assertEqual(d1.viewitems() | set(d3.viewitems()), {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) self.assertEqual(d1.viewitems() ^ d1.viewitems(), set()) self.assertEqual(d1.viewitems() ^ d2.viewitems(), {('a', 1), ('a', 2)}) self.assertEqual(d1.viewitems() ^ d3.viewitems(), {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) def test_main(): try: from test import test_support as support except ImportError: from test import support support.run_unittest(DictSetTest) if __name__ == "__main__": test_main() Cython-0.23.4/tests/run/test_coroutines_pep492.pyx0000644000175600017570000012425212606202452023256 0ustar jenkinsjenkins00000000000000# cython: language_level=3, binding=True # mode: run # tag: pep492, asyncfor, await import re import gc import sys #import types import os.path #import inspect import unittest import warnings import contextlib from Cython.Compiler import Errors try: from types import coroutine as types_coroutine except ImportError: # duck typed types.coroutine() decorator copied from types.py in Py3.5 class types_coroutine(object): def __init__(self, gen): self._gen = gen class _GeneratorWrapper(object): def __init__(self, gen): self.__wrapped__ = gen self.send = gen.send self.throw = gen.throw self.close = gen.close self.__name__ = getattr(gen, '__name__', None) self.__qualname__ = getattr(gen, '__qualname__', None) @property def gi_code(self): return self.__wrapped__.gi_code @property def gi_frame(self): return self.__wrapped__.gi_frame @property def gi_running(self): return self.__wrapped__.gi_running cr_code = gi_code cr_frame = gi_frame cr_running = gi_running def __next__(self): return next(self.__wrapped__) def __iter__(self): return self.__wrapped__ __await__ = __iter__ def __call__(self, *args, **kwargs): return self._GeneratorWrapper(self._gen(*args, **kwargs)) # compiled exec() def exec(code_string, l, g): from Cython.Shadow import inline try: from StringIO import StringIO except ImportError: from io import StringIO old_stderr = sys.stderr try: sys.stderr = StringIO() ns = inline(code_string, locals=l, globals=g, lib_dir=os.path.dirname(__file__)) finally: sys.stderr = old_stderr g.update(ns) class AsyncYieldFrom(object): def __init__(self, obj): self.obj = obj def __await__(self): yield from self.obj class AsyncYield(object): def __init__(self, value): self.value = value def __await__(self): yield self.value def run_async(coro): #assert coro.__class__ is types.GeneratorType assert coro.__class__.__name__ in ('coroutine', '_GeneratorWrapper'), coro.__class__.__name__ buffer = [] result = None while True: try: buffer.append(coro.send(None)) except StopIteration as ex: result = ex.args[0] if ex.args else None break return buffer, result def run_async__await__(coro): assert coro.__class__.__name__ in ('coroutine', '_GeneratorWrapper'), coro.__class__.__name__ aw = coro.__await__() buffer = [] result = None i = 0 while True: try: if i % 2: buffer.append(next(aw)) else: buffer.append(aw.send(None)) i += 1 except StopIteration as ex: result = ex.args[0] if ex.args else None break return buffer, result @contextlib.contextmanager def silence_coro_gc(): with warnings.catch_warnings(): warnings.simplefilter("ignore") yield gc.collect() class AsyncBadSyntaxTest(unittest.TestCase): @contextlib.contextmanager def assertRaisesRegex(self, exc_type, regex): # the error messages usually don't match, so we just ignore them try: yield except exc_type: self.assertTrue(True) else: self.assertTrue(False) def test_badsyntax_9(self): ns = {} for comp in {'(await a for a in b)', '[await a for a in b]', '{await a for a in b}', '{await a: a for a in b}'}: with self.assertRaisesRegex(Errors.CompileError, 'await.*in comprehen'): exec('async def f():\n\t{0}'.format(comp), ns, ns) def test_badsyntax_10(self): # Tests for issue 24619 samples = [ """async def foo(): def bar(): pass await = 1 """, """async def foo(): def bar(): pass await = 1 """, """async def foo(): def bar(): pass if 1: await = 1 """, """def foo(): async def bar(): pass if 1: await a """, """def foo(): async def bar(): pass await a """, """def foo(): def baz(): pass async def bar(): pass await a """, """def foo(): def baz(): pass # 456 async def bar(): pass # 123 await a """, """async def foo(): def baz(): pass # 456 async def bar(): pass # 123 await = 2 """, """def foo(): def baz(): pass async def bar(): pass await a """, """async def foo(): def baz(): pass async def bar(): pass await = 2 """, """async def foo(): def async(): pass """, """async def foo(): def await(): pass """, """async def foo(): def bar(): await """, """async def foo(): return lambda async: await """, """async def foo(): return lambda a: await """, """await a()""", """async def foo(a=await b): pass """, """async def foo(a:await b): pass """, """def baz(): async def foo(a=await b): pass """, """async def foo(async): pass """, """async def foo(): def bar(): def baz(): async = 1 """, """async def foo(): def bar(): def baz(): pass async = 1 """, """def foo(): async def bar(): async def baz(): pass def baz(): 42 async = 1 """, """async def foo(): def bar(): def baz(): pass\nawait foo() """, """def foo(): def bar(): async def baz(): pass\nawait foo() """, """async def foo(await): pass """, """def foo(): async def bar(): pass await a """, """def foo(): async def bar(): pass\nawait a """] for code in samples: # assertRaises() differs in Py2.6, so use our own assertRaisesRegex() instead with self.subTest(code=code), self.assertRaisesRegex(Errors.CompileError, '.'): exec(code, {}, {}) if not hasattr(unittest.TestCase, 'subTest'): @contextlib.contextmanager def subTest(self, code, **kwargs): try: yield except Exception: print(code) raise def test_goodsyntax_1(self): # Tests for issue 24619 def foo(await): async def foo(): pass async def foo(): pass return await + 1 self.assertEqual(foo(10), 11) def foo(await): async def foo(): pass async def foo(): pass return await + 2 self.assertEqual(foo(20), 22) def foo(await): async def foo(): pass async def foo(): pass return await + 2 self.assertEqual(foo(20), 22) def foo(await): """spam""" async def foo(): \ pass # 123 async def foo(): pass # 456 return await + 2 self.assertEqual(foo(20), 22) def foo(await): def foo(): pass def foo(): pass async def bar(): return await_ await_ = await try: bar().send(None) except StopIteration as ex: return ex.args[0] self.assertEqual(foo(42), 42) async def f(z): async def g(): pass await z await = 1 #self.assertTrue(inspect.iscoroutinefunction(f)) class TokenizerRegrTest(unittest.TestCase): def test_oneline_defs(self): buf = [] for i in range(500): buf.append('def i{i}(): return {i}'.format(i=i)) buf = '\n'.join(buf) # Test that 500 consequent, one-line defs is OK ns = {} exec(buf, ns, ns) self.assertEqual(ns['i499'](), 499) # Test that 500 consequent, one-line defs *and* # one 'async def' following them is OK buf += '\nasync def foo():\n return' ns = {} exec(buf, ns, ns) self.assertEqual(ns['i499'](), 499) self.assertEqual(type(ns['foo']()).__name__, 'coroutine') #self.assertTrue(inspect.iscoroutinefunction(ns['foo'])) class CoroutineTest(unittest.TestCase): @classmethod def setUpClass(cls): # never mark warnings as "already seen" to prevent them from being suppressed from warnings import simplefilter simplefilter("always") @contextlib.contextmanager def assertRaises(self, exc_type): try: yield except exc_type: self.assertTrue(True) else: self.assertTrue(False) @contextlib.contextmanager def assertRaisesRegex(self, exc_type, regex): # the error messages usually don't match, so we just ignore them try: yield except exc_type: self.assertTrue(True) else: self.assertTrue(False) @contextlib.contextmanager def assertWarnsRegex(self, exc_type, regex): from warnings import catch_warnings with catch_warnings(record=True) as log: yield first_match = None for warning in log: w = warning.message if not isinstance(w, exc_type): continue if first_match is None: first_match = w if re.search(regex, str(w)): self.assertTrue(True) return if first_match is None: self.assertTrue(False, "no warning was raised of type '%s'" % exc_type.__name__) else: self.assertTrue(False, "'%s' did not match '%s'" % (first_match, regex)) if not hasattr(unittest.TestCase, 'assertRegex'): def assertRegex(self, value, regex): self.assertTrue(re.search(regex, str(value)), "'%s' did not match '%s'" % (value, regex)) if not hasattr(unittest.TestCase, 'assertIn'): def assertIn(self, member, container, msg=None): self.assertTrue(member in container, msg) if not hasattr(unittest.TestCase, 'assertIsNone'): def assertIsNone(self, value, msg=None): self.assertTrue(value is None, msg) if not hasattr(unittest.TestCase, 'assertIsNotNone'): def assertIsNotNone(self, value, msg=None): self.assertTrue(value is not None, msg) def test_gen_1(self): def gen(): yield self.assertFalse(hasattr(gen, '__await__')) def test_func_1(self): async def foo(): return 10 f = foo() self.assertEqual(f.__class__.__name__, 'coroutine') #self.assertIsInstance(f, types.CoroutineType) #self.assertTrue(bool(foo.__code__.co_flags & 0x80)) #self.assertTrue(bool(foo.__code__.co_flags & 0x20)) #self.assertTrue(bool(f.cr_code.co_flags & 0x80)) #self.assertTrue(bool(f.cr_code.co_flags & 0x20)) self.assertEqual(run_async(f), ([], 10)) self.assertEqual(run_async__await__(foo()), ([], 10)) def bar(): pass self.assertFalse(bool(bar.__code__.co_flags & 0x80)) # TODO def __test_func_2(self): async def foo(): raise StopIteration with self.assertRaisesRegex( RuntimeError, "coroutine raised StopIteration"): run_async(foo()) def test_func_3(self): async def foo(): raise StopIteration with silence_coro_gc(): self.assertRegex(repr(foo()), '^$') def test_func_4(self): async def foo(): raise StopIteration check = lambda: self.assertRaisesRegex( TypeError, "'coroutine' object is not iterable") with check(): list(foo()) with check(): tuple(foo()) with check(): sum(foo()) with check(): iter(foo()) with check(): next(foo()) with silence_coro_gc(), check(): for i in foo(): pass with silence_coro_gc(), check(): [i for i in foo()] def test_func_5(self): @types_coroutine def bar(): yield 1 async def foo(): await bar() check = lambda: self.assertRaisesRegex( TypeError, "'coroutine' object is not iterable") with check(): for el in foo(): pass # the following should pass without an error for el in bar(): self.assertEqual(el, 1) self.assertEqual([el for el in bar()], [1]) self.assertEqual(tuple(bar()), (1,)) self.assertEqual(next(iter(bar())), 1) def test_func_6(self): @types_coroutine def bar(): yield 1 yield 2 async def foo(): await bar() f = foo() self.assertEqual(f.send(None), 1) self.assertEqual(f.send(None), 2) with self.assertRaises(StopIteration): f.send(None) # TODO (or not? see test_func_8() below) def __test_func_7(self): async def bar(): return 10 def foo(): yield from bar() with silence_coro_gc(), self.assertRaisesRegex( TypeError, "cannot 'yield from' a coroutine object in a non-coroutine generator"): list(foo()) def test_func_8(self): @types_coroutine def bar(): return (yield from foo()) async def foo(): return 'spam' self.assertEqual(run_async(bar()), ([], 'spam') ) def test_func_9(self): async def foo(): pass with self.assertWarnsRegex( RuntimeWarning, "coroutine '.*test_func_9.*foo' was never awaited"): foo() gc.collect() def test_func_10(self): N = 0 @types_coroutine def gen(): nonlocal N try: a = yield yield (a ** 2) except ZeroDivisionError: N += 100 raise finally: N += 1 async def foo(): await gen() coro = foo() aw = coro.__await__() self.assertTrue(aw is iter(aw)) next(aw) self.assertEqual(aw.send(10), 100) with self.assertRaises(TypeError): type(aw).send(None, None) self.assertEqual(N, 0) aw.close() self.assertEqual(N, 1) with self.assertRaises(TypeError): # removed from CPython test suite? type(aw).close(None) coro = foo() aw = coro.__await__() next(aw) with self.assertRaises(ZeroDivisionError): aw.throw(ZeroDivisionError, None, None) self.assertEqual(N, 102) with self.assertRaises(TypeError): # removed from CPython test suite? type(aw).throw(None, None, None, None) def test_func_11(self): async def func(): pass coro = func() # Test that PyCoro_Type and _PyCoroWrapper_Type types were properly # initialized self.assertIn('__await__', dir(coro)) self.assertIn('__iter__', dir(coro.__await__())) self.assertIn('coroutine_wrapper', repr(coro.__await__())) coro.close() # avoid RuntimeWarning def test_func_12(self): async def g(): i = me.send(None) await None me = g() with self.assertRaisesRegex(ValueError, "coroutine already executing"): me.send(None) def test_func_13(self): async def g(): pass with self.assertRaisesRegex( TypeError, "can't send non-None value to a just-started coroutine"): g().send('spam') def test_func_14(self): @types_coroutine def gen(): yield async def coro(): try: await gen() except GeneratorExit: await gen() c = coro() c.send(None) with self.assertRaisesRegex(RuntimeError, "coroutine ignored GeneratorExit"): c.close() def test_cr_await(self): @types_coroutine def a(): #self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_RUNNING) self.assertIsNone(coro_b.cr_await) yield #self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_RUNNING) # FIXME: no idea why the following works in CPython: #self.assertIsNone(coro_b.cr_await) async def c(): await a() async def b(): self.assertIsNone(coro_b.cr_await) await c() self.assertIsNone(coro_b.cr_await) coro_b = b() #self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_CREATED) self.assertIsNone(coro_b.cr_await) coro_b.send(None) #self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_SUSPENDED) #self.assertEqual(coro_b.cr_await.cr_await.gi_code.co_name, 'a') self.assertIsNotNone(coro_b.cr_await.cr_await) self.assertEqual(coro_b.cr_await.cr_await.__name__, 'a') with self.assertRaises(StopIteration): coro_b.send(None) # complete coroutine #self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_CLOSED) self.assertIsNone(coro_b.cr_await) def test_corotype_1(self): async def f(): pass ct = type(f()) self.assertIn('into coroutine', ct.send.__doc__) self.assertIn('inside coroutine', ct.close.__doc__) self.assertIn('in coroutine', ct.throw.__doc__) self.assertIn('of the coroutine', ct.__dict__['__name__'].__doc__) self.assertIn('of the coroutine', ct.__dict__['__qualname__'].__doc__) self.assertEqual(ct.__name__, 'coroutine') async def f(): pass c = f() self.assertIn('coroutine object', repr(c)) c.close() def test_await_1(self): async def foo(): await 1 with self.assertRaisesRegex(TypeError, "object int can.t.*await"): run_async(foo()) def test_await_2(self): async def foo(): await [] with self.assertRaisesRegex(TypeError, "object list can.t.*await"): run_async(foo()) def test_await_3(self): async def foo(): await AsyncYieldFrom([1, 2, 3]) self.assertEqual(run_async(foo()), ([1, 2, 3], None)) self.assertEqual(run_async__await__(foo()), ([1, 2, 3], None)) def test_await_4(self): async def bar(): return 42 async def foo(): return await bar() self.assertEqual(run_async(foo()), ([], 42)) def test_await_5(self): class Awaitable(object): def __await__(self): return async def foo(): return (await Awaitable()) with self.assertRaisesRegex( TypeError, "__await__.*returned non-iterator of type"): run_async(foo()) def test_await_6(self): class Awaitable(object): def __await__(self): return iter([52]) async def foo(): return (await Awaitable()) self.assertEqual(run_async(foo()), ([52], None)) def test_await_7(self): class Awaitable(object): def __await__(self): yield 42 return 100 async def foo(): return (await Awaitable()) self.assertEqual(run_async(foo()), ([42], 100)) def test_await_8(self): class Awaitable(object): pass async def foo(): return (await Awaitable()) with self.assertRaisesRegex( TypeError, "object Awaitable can't be used in 'await' expression"): run_async(foo()) def test_await_9(self): def wrap(): return bar async def bar(): return 42 async def foo(): b = bar() db = {'b': lambda: wrap} class DB(object): b = staticmethod(wrap) return (await bar() + await wrap()() + await db['b']()()() + await bar() * 1000 + await DB.b()()) async def foo2(): return -await bar() self.assertEqual(run_async(foo()), ([], 42168)) self.assertEqual(run_async(foo2()), ([], -42)) def test_await_10(self): async def baz(): return 42 async def bar(): return baz() async def foo(): return await (await bar()) self.assertEqual(run_async(foo()), ([], 42)) def test_await_11(self): def ident(val): return val async def bar(): return 'spam' async def foo(): return ident(val=await bar()) async def foo2(): return await bar(), 'ham' self.assertEqual(run_async(foo2()), ([], ('spam', 'ham'))) def test_await_12(self): async def coro(): return 'spam' class Awaitable(object): def __await__(self): return coro() async def foo(): return await Awaitable() with self.assertRaisesRegex( TypeError, "__await__\(\) returned a coroutine"): run_async(foo()) def test_await_13(self): class Awaitable(object): def __await__(self): return self async def foo(): return await Awaitable() with self.assertRaisesRegex( TypeError, "__await__.*returned non-iterator of type"): run_async(foo()) def test_await_14(self): class Wrapper(object): # Forces the interpreter to use CoroutineType.__await__ def __init__(self, coro): self.coro = coro def __await__(self): return self.coro.__await__() class FutureLike(object): def __await__(self): return (yield) class Marker(Exception): pass async def coro1(): try: return await FutureLike() except ZeroDivisionError: raise Marker async def coro2(): return await Wrapper(coro1()) c = coro2() c.send(None) with self.assertRaisesRegex(StopIteration, 'spam'): c.send('spam') c = coro2() c.send(None) with self.assertRaises(Marker): c.throw(ZeroDivisionError) def test_await_iterator(self): async def foo(): return 123 coro = foo() it = coro.__await__() self.assertEqual(type(it).__name__, 'coroutine_wrapper') with self.assertRaisesRegex(TypeError, "cannot instantiate 'coroutine_wrapper' type"): type(it)() # cannot instantiate with self.assertRaisesRegex(StopIteration, "123"): next(it) def test_with_1(self): class Manager(object): def __init__(self, name): self.name = name async def __aenter__(self): await AsyncYieldFrom(['enter-1-' + self.name, 'enter-2-' + self.name]) return self async def __aexit__(self, *args): await AsyncYieldFrom(['exit-1-' + self.name, 'exit-2-' + self.name]) if self.name == 'B': return True async def foo(): async with Manager("A") as a, Manager("B") as b: await AsyncYieldFrom([('managers', a.name, b.name)]) 1/0 f = foo() result, _ = run_async(f) self.assertEqual( result, ['enter-1-A', 'enter-2-A', 'enter-1-B', 'enter-2-B', ('managers', 'A', 'B'), 'exit-1-B', 'exit-2-B', 'exit-1-A', 'exit-2-A'] ) async def foo(): async with Manager("A") as a, Manager("C") as c: await AsyncYieldFrom([('managers', a.name, c.name)]) 1/0 with self.assertRaises(ZeroDivisionError): run_async(foo()) def test_with_2(self): class CM(object): def __aenter__(self): pass async def foo(): async with CM(): pass with self.assertRaisesRegex(AttributeError, '__aexit__'): run_async(foo()) def test_with_3(self): class CM(object): def __aexit__(self): pass async def foo(): async with CM(): pass with self.assertRaisesRegex(AttributeError, '__aenter__'): run_async(foo()) def test_with_4(self): class CM(object): def __enter__(self): pass def __exit__(self): pass async def foo(): async with CM(): pass with self.assertRaisesRegex(AttributeError, '__aexit__'): run_async(foo()) def test_with_5(self): # While this test doesn't make a lot of sense, # it's a regression test for an early bug with opcodes # generation class CM(object): async def __aenter__(self): return self async def __aexit__(self, *exc): pass async def func(): async with CM(): assert (1, ) == 1 with self.assertRaises(AssertionError): run_async(func()) def test_with_6(self): class CM(object): def __aenter__(self): return 123 def __aexit__(self, *e): return 456 async def foo(): async with CM(): pass with self.assertRaisesRegex( TypeError, "object int can't be used in 'await' expression"): # it's important that __aexit__ wasn't called run_async(foo()) def test_with_7(self): class CM(object): async def __aenter__(self): return self def __aexit__(self, *e): return 444 async def foo(): async with CM(): 1/0 try: run_async(foo()) except TypeError as exc: self.assertRegex( exc.args[0], "object int can't be used in 'await' expression") if sys.version_info[0] >= 3: self.assertTrue(exc.__context__ is not None) self.assertTrue(isinstance(exc.__context__, ZeroDivisionError)) else: self.fail('invalid asynchronous context manager did not fail') def test_with_8(self): CNT = 0 class CM(object): async def __aenter__(self): return self def __aexit__(self, *e): return 456 async def foo(): nonlocal CNT async with CM(): CNT += 1 with self.assertRaisesRegex( TypeError, "object int can't be used in 'await' expression"): run_async(foo()) self.assertEqual(CNT, 1) def test_with_9(self): CNT = 0 class CM(object): async def __aenter__(self): return self async def __aexit__(self, *e): 1/0 async def foo(): nonlocal CNT async with CM(): CNT += 1 with self.assertRaises(ZeroDivisionError): run_async(foo()) self.assertEqual(CNT, 1) def test_with_10(self): CNT = 0 class CM(object): async def __aenter__(self): return self async def __aexit__(self, *e): 1/0 async def foo(): nonlocal CNT async with CM(): async with CM(): raise RuntimeError try: run_async(foo()) except ZeroDivisionError as exc: pass # FIXME! #if sys.version_info[0] >= 3: # self.assertTrue(exc.__context__ is not None) # self.assertTrue(isinstance(exc.__context__, ZeroDivisionError)) # self.assertTrue(isinstance(exc.__context__.__context__, RuntimeError)) else: self.fail('exception from __aexit__ did not propagate') def test_with_11(self): CNT = 0 class CM(object): async def __aenter__(self): raise NotImplementedError async def __aexit__(self, *e): 1/0 async def foo(): nonlocal CNT async with CM(): raise RuntimeError try: run_async(foo()) except NotImplementedError as exc: if sys.version_info[0] >= 3: self.assertTrue(exc.__context__ is None) else: self.fail('exception from __aenter__ did not propagate') def test_with_12(self): CNT = 0 class CM(object): async def __aenter__(self): return self async def __aexit__(self, *e): return True async def foo(): nonlocal CNT async with CM() as cm: self.assertIs(cm.__class__, CM) raise RuntimeError run_async(foo()) def test_with_13(self): CNT = 0 class CM(object): async def __aenter__(self): 1/0 async def __aexit__(self, *e): return True async def foo(): nonlocal CNT CNT += 1 async with CM(): CNT += 1000 CNT += 10000 with self.assertRaises(ZeroDivisionError): run_async(foo()) self.assertEqual(CNT, 1) def test_for_1(self): aiter_calls = 0 class AsyncIter(object): def __init__(self): self.i = 0 async def __aiter__(self): nonlocal aiter_calls aiter_calls += 1 return self async def __anext__(self): self.i += 1 if not (self.i % 10): await AsyncYield(self.i * 10) if self.i > 100: raise StopAsyncIteration return self.i, self.i buffer = [] async def test1(): async for i1, i2 in AsyncIter(): buffer.append(i1 + i2) yielded, _ = run_async(test1()) # Make sure that __aiter__ was called only once self.assertEqual(aiter_calls, 1) self.assertEqual(yielded, [i * 100 for i in range(1, 11)]) self.assertEqual(buffer, [i*2 for i in range(1, 101)]) buffer = [] async def test2(): nonlocal buffer async for i in AsyncIter(): buffer.append(i[0]) if i[0] == 20: break else: buffer.append('what?') buffer.append('end') yielded, _ = run_async(test2()) # Make sure that __aiter__ was called only once self.assertEqual(aiter_calls, 2) self.assertEqual(yielded, [100, 200]) self.assertEqual(buffer, [i for i in range(1, 21)] + ['end']) buffer = [] async def test3(): nonlocal buffer async for i in AsyncIter(): if i[0] > 20: continue buffer.append(i[0]) else: buffer.append('what?') buffer.append('end') yielded, _ = run_async(test3()) # Make sure that __aiter__ was called only once self.assertEqual(aiter_calls, 3) self.assertEqual(yielded, [i * 100 for i in range(1, 11)]) self.assertEqual(buffer, [i for i in range(1, 21)] + ['what?', 'end']) def test_for_2(self): tup = (1, 2, 3) refs_before = sys.getrefcount(tup) async def foo(): async for i in tup: print('never going to happen') with self.assertRaisesRegex( TypeError, "async for' requires an object.*__aiter__.*tuple"): run_async(foo()) self.assertEqual(sys.getrefcount(tup), refs_before) def test_for_3(self): class I(object): def __aiter__(self): return self aiter = I() refs_before = sys.getrefcount(aiter) async def foo(): async for i in aiter: print('never going to happen') with self.assertRaisesRegex( TypeError, "async for' received an invalid object.*__aiter.*\: I"): run_async(foo()) self.assertEqual(sys.getrefcount(aiter), refs_before) def test_for_4(self): class I(object): async def __aiter__(self): return self def __anext__(self): return () aiter = I() refs_before = sys.getrefcount(aiter) async def foo(): async for i in aiter: print('never going to happen') with self.assertRaisesRegex( TypeError, "async for' received an invalid object.*__anext__.*tuple"): run_async(foo()) self.assertEqual(sys.getrefcount(aiter), refs_before) def test_for_5(self): class I(object): async def __aiter__(self): return self def __anext__(self): return 123 async def foo(): async for i in I(): print('never going to happen') with self.assertRaisesRegex( TypeError, "async for' received an invalid object.*__anext.*int"): run_async(foo()) def test_for_6(self): I = 0 class Manager(object): async def __aenter__(self): nonlocal I I += 10000 async def __aexit__(self, *args): nonlocal I I += 100000 class Iterable(object): def __init__(self): self.i = 0 async def __aiter__(self): return self async def __anext__(self): if self.i > 10: raise StopAsyncIteration self.i += 1 return self.i ############## manager = Manager() iterable = Iterable() mrefs_before = sys.getrefcount(manager) irefs_before = sys.getrefcount(iterable) async def main(): nonlocal I async with manager: async for i in iterable: I += 1 I += 1000 run_async(main()) self.assertEqual(I, 111011) self.assertEqual(sys.getrefcount(manager), mrefs_before) self.assertEqual(sys.getrefcount(iterable), irefs_before) ############## async def main(): nonlocal I async with Manager(): async for i in Iterable(): I += 1 I += 1000 async with Manager(): async for i in Iterable(): I += 1 I += 1000 run_async(main()) self.assertEqual(I, 333033) ############## async def main(): nonlocal I async with Manager(): I += 100 async for i in Iterable(): I += 1 else: I += 10000000 I += 1000 async with Manager(): I += 100 async for i in Iterable(): I += 1 else: I += 10000000 I += 1000 run_async(main()) self.assertEqual(I, 20555255) def test_for_7(self): CNT = 0 class AI(object): async def __aiter__(self): 1/0 async def foo(): nonlocal CNT async for i in AI(): CNT += 1 CNT += 10 with self.assertRaises(ZeroDivisionError): run_async(foo()) self.assertEqual(CNT, 0) class CoroAsyncIOCompatTest(unittest.TestCase): def test_asyncio_1(self): import asyncio class MyException(Exception): pass buffer = [] class CM(object): async def __aenter__(self): buffer.append(1) await asyncio.sleep(0.01) buffer.append(2) return self async def __aexit__(self, exc_type, exc_val, exc_tb): await asyncio.sleep(0.01) buffer.append(exc_type.__name__) async def f(): async with CM() as c: await asyncio.sleep(0.01) raise MyException buffer.append('unreachable') loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) try: loop.run_until_complete(f()) except MyException: pass finally: loop.close() asyncio.set_event_loop(None) self.assertEqual(buffer, [1, 2, 'MyException']) class SysSetCoroWrapperTest(unittest.TestCase): def test_set_wrapper_1(self): async def foo(): return 'spam' wrapped = None def wrap(gen): nonlocal wrapped wrapped = gen return gen self.assertIsNone(sys.get_coroutine_wrapper()) sys.set_coroutine_wrapper(wrap) self.assertIs(sys.get_coroutine_wrapper(), wrap) try: f = foo() self.assertTrue(wrapped) self.assertEqual(run_async(f), ([], 'spam')) finally: sys.set_coroutine_wrapper(None) self.assertIsNone(sys.get_coroutine_wrapper()) wrapped = None with silence_coro_gc(): foo() self.assertFalse(wrapped) def test_set_wrapper_2(self): self.assertIsNone(sys.get_coroutine_wrapper()) with self.assertRaisesRegex(TypeError, "callable expected, got int"): sys.set_coroutine_wrapper(1) self.assertIsNone(sys.get_coroutine_wrapper()) def test_set_wrapper_3(self): async def foo(): return 'spam' def wrapper(coro): async def wrap(coro): return await coro return wrap(coro) sys.set_coroutine_wrapper(wrapper) try: with silence_coro_gc(), self.assertRaisesRegex( RuntimeError, "coroutine wrapper.*\.wrapper at 0x.*attempted to " "recursively wrap .* wrap .*"): foo() finally: sys.set_coroutine_wrapper(None) def test_set_wrapper_4(self): @types_coroutine def foo(): return 'spam' wrapped = None def wrap(gen): nonlocal wrapped wrapped = gen return gen sys.set_coroutine_wrapper(wrap) try: foo() self.assertIs( wrapped, None, "generator-based coroutine was wrapped via " "sys.set_coroutine_wrapper") finally: sys.set_coroutine_wrapper(None) class CAPITest(unittest.TestCase): def test_tp_await_1(self): from _testcapi import awaitType as at async def foo(): future = at(iter([1])) return (await future) self.assertEqual(foo().send(None), 1) def test_tp_await_2(self): # Test tp_await to __await__ mapping from _testcapi import awaitType as at future = at(iter([1])) self.assertEqual(next(future.__await__()), 1) def test_tp_await_3(self): from _testcapi import awaitType as at async def foo(): future = at(1) return (await future) with self.assertRaisesRegex( TypeError, "__await__.*returned non-iterator of type 'int'"): self.assertEqual(foo().send(None), 1) # disable some tests that only apply to CPython # TODO? if True or sys.version_info < (3, 5): SysSetCoroWrapperTest = None CAPITest = None if sys.version_info < (3, 5): # (3, 4, 4) CoroAsyncIOCompatTest = None else: try: import asyncio except ImportError: CoroAsyncIOCompatTest = None if __name__=="__main__": unittest.main() Cython-0.23.4/tests/run/temps_corner1.pyx0000644000175600017570000000042612606202452021477 0ustar jenkinsjenkins00000000000000cdef class A: def numerator(self): return self cdef int bitsize(A a): return 1 coeffs = [A()] class B: """ >>> B().coeffs_bitsize() [2] """ def coeffs_bitsize(self): r = [bitsize(c.numerator())+1 for c in coeffs] return r Cython-0.23.4/tests/run/temp_sideeffects_T654.pyx0000644000175600017570000000134512606202452022752 0ustar jenkinsjenkins00000000000000# ticket: 654 # function call arguments # not really a bug, Cython warns about it now -- C argument evaluation order is undefined arg_order = [] cdef int f(): arg_order.append(1) return 1 def g(): arg_order.append(2) return 2 cdef call2(int x, object o): return x, o def test_c_call(): """ >>> arg_order [] >>> test_c_call() (1, 2) >>> arg_order [1, 2] """ return call2(f(), g()) # module globals cdef object X = 1 cdef redefine_global(): global X x,X = X,2 return x cdef call3(object x1, int o, object x2): return (x1, o, x2) def test_global_redefine(): """ >>> test_global_redefine() (1, 1, 2) """ return call3(X, redefine_global(), X) Cython-0.23.4/tests/run/temp_alloc_T409.pyx0000644000175600017570000000037412606202452021557 0ustar jenkinsjenkins00000000000000# ticket: 409 # Extracted from sage/plot/plot3d/index_face_set.pyx:502 # Turns out to be a bug in implementation of PEP 3132 (Extended Iterable Unpacking) def foo(): """ >>> foo() ([0, 0], [0, 0]) """ a = b = [0,0] return a, b Cython-0.23.4/tests/run/tandemstats.pyx0000644000175600017570000000026212606202452021243 0ustar jenkinsjenkins00000000000000cdef int i, j, k i = 17; j = 42; k = i * j if j > k: i = 88 else: i = 99; j = k def result(): """ >>> result() == (99, 17*42, 17*42) True """ return (i,j,k) Cython-0.23.4/tests/run/switch_transform.pyx0000644000175600017570000000037112606202452022311 0ustar jenkinsjenkins00000000000000# cython: optimize.use_switch=False cdef extern from *: enum: ONE "1" ONE_AGAIN "1+0" def is_not_one(int i): """ >>> is_not_one(1) False >>> is_not_one(2) True """ return i != ONE and i != ONE_AGAIN Cython-0.23.4/tests/run/switch.pyx0000644000175600017570000001570612606202452020226 0ustar jenkinsjenkins00000000000000# mode: run cimport cython @cython.test_fail_if_path_exists('//SwitchStatNode') @cython.test_assert_path_exists('//IfStatNode') def switch_simple_py(x): """ >>> switch_simple_py(1) 1 >>> switch_simple_py(2) 2 >>> switch_simple_py(3) 3 >>> switch_simple_py(4) 8 >>> switch_simple_py(5) 0 """ if x == 1: return 1 elif 2 == x: return 2 elif x in [3]: return 3 elif x in (4,): return 8 else: return 0 return -1 @cython.test_fail_if_path_exists('//SwitchStatNode') @cython.test_assert_path_exists('//IfStatNode') def switch_py(x): """ >>> switch_py(1) 1 >>> switch_py(2) 2 >>> switch_py(3) 3 >>> switch_py(4) 4 >>> switch_py(5) 4 >>> switch_py(6) 0 >>> switch_py(8) 4 >>> switch_py(10) 10 >>> switch_py(12) 12 >>> switch_py(13) 0 """ if x == 1: return 1 elif 2 == x: return 2 elif x in [3]: return 3 elif x in [4,5,7,8]: return 4 elif x in (10,11): return 10 elif x in (12,): return 12 else: return 0 return -1 @cython.test_assert_path_exists('//SwitchStatNode') @cython.test_fail_if_path_exists('//IfStatNode') def switch_simple_c(int x): """ >>> switch_simple_c(1) 1 >>> switch_simple_c(2) 2 >>> switch_simple_c(3) 3 >>> switch_simple_c(4) 8 >>> switch_simple_c(5) 0 """ if x == 1: return 1 elif 2 == x: return 2 elif x in [3]: return 3 elif x in (4,): return 8 else: return 0 return -1 @cython.test_assert_path_exists('//SwitchStatNode') @cython.test_fail_if_path_exists('//IfStatNode') def switch_c(int x): """ >>> switch_c(1) 1 >>> switch_c(2) 2 >>> switch_c(3) 3 >>> switch_c(4) 4 >>> switch_c(5) 4 >>> switch_c(6) 0 >>> switch_c(8) 4 >>> switch_c(10) 10 >>> switch_c(12) 12 >>> switch_c(13) 0 """ if x == 1: return 1 elif 2 == x: return 2 elif x in [3]: return 3 elif x in [4,5,7,8]: return 4 elif x in (10,11): return 10 elif x in (12,): return 12 else: return 0 return -1 @cython.test_assert_path_exists('//SwitchStatNode') @cython.test_fail_if_path_exists('//IfStatNode') def switch_or(int x): """ >>> switch_or(0) 0 >>> switch_or(1) 1 >>> switch_or(2) 1 >>> switch_or(3) 1 >>> switch_or(4) 0 """ if x == 1 or x == 2 or x == 3: return 1 else: return 0 return -1 @cython.test_assert_path_exists('//SwitchStatNode') @cython.test_fail_if_path_exists('//IfStatNode') def switch_in(int X): """ >>> switch_in(0) 0 >>> switch_in(1) 1 >>> switch_in(2) 0 >>> switch_in(7) 1 >>> switch_in(8) 0 """ if X in (1,3,5,7): return 1 return 0 @cython.test_assert_path_exists('//SwitchStatNode') @cython.test_fail_if_path_exists('//IfStatNode') def switch_short(int x): """ >>> switch_short(0) 0 >>> switch_short(1) 1 >>> switch_short(2) 2 >>> switch_short(3) 0 """ if x == 1: return 1 elif 2 == x: return 2 else: return 0 return -1 @cython.test_fail_if_path_exists('//SwitchStatNode') @cython.test_assert_path_exists('//IfStatNode') def switch_off(int x): """ >>> switch_off(0) 0 >>> switch_off(1) 1 >>> switch_off(2) 0 """ if x == 1: return 1 else: return 0 return -1 @cython.test_assert_path_exists('//SwitchStatNode') @cython.test_fail_if_path_exists('//IfStatNode') def switch_pass(int x): """ >>> switch_pass(1) 1 """ if x == 1: pass elif x == 2: pass else: pass return x DEF t = (1,2,3,4,5,6) @cython.test_assert_path_exists('//SwitchStatNode') @cython.test_fail_if_path_exists('//IfStatNode') def compile_time_tuple_constant(int x): """ >>> compile_time_tuple_constant(1) True >>> compile_time_tuple_constant(0) False >>> compile_time_tuple_constant(7) False """ if x in t: return True else: return False cdef enum X: a = 1 b c d e = 10 f = 100 @cython.test_assert_path_exists('//SwitchStatNode') @cython.test_fail_if_path_exists('//IfStatNode') def enum_switch(X x): """ >>> enum_switch(1) 0 >>> enum_switch(10) 1 >>> enum_switch(100) 2 """ if x in [a, b, c, d]: return 0 elif x == e: return 1 else: return 2 @cython.test_assert_path_exists('//IfStatNode') @cython.test_assert_path_exists('//IfStatNode//SwitchStatNode') def enum_duplicates(X x): """ >>> enum_duplicates(1) 0 >>> enum_duplicates(2) # b 0 >>> enum_duplicates(10) 1 >>> enum_duplicates(100) 3 """ if x in [a, b, c, d]: # switch is ok here! return 0 elif x == e: return 1 elif x == b: # duplicate => no switch here! return 2 else: return 3 @cython.test_assert_path_exists('//SwitchStatNode') @cython.test_fail_if_path_exists('//IfStatNode') def int_enum_switch_mix(int x): """ >>> int_enum_switch_mix(1) 0 >>> int_enum_switch_mix(10) 1 >>> int_enum_switch_mix(ord('X')) 2 >>> int_enum_switch_mix(99) 3 >>> int_enum_switch_mix(100) 4 """ if x in [a, b, c, d]: return 0 elif x == e: return 1 elif x == 'X': # ASCII(88) return 2 elif x == 99: return 3 else: return 4 @cython.test_fail_if_path_exists('//SwitchStatNode') @cython.test_assert_path_exists('//IfStatNode') def int_enum_duplicates_mix(int x): """ >>> int_enum_duplicates_mix(88) 0 >>> int_enum_duplicates_mix(ord('X')) 0 >>> int_enum_duplicates_mix(99) 2 >>> int_enum_duplicates_mix(100) 3 """ if x == 88: return 0 elif x == 'X': # ASCII(88) => redundant return 1 elif x == 99: return 2 else: return 3 @cython.test_assert_path_exists('//SwitchStatNode') @cython.test_fail_if_path_exists('//BoolBinopNode', '//PrimaryCmpNode') def int_in_bool_binop(int x): """ >>> int_in_bool_binop(0) False >>> int_in_bool_binop(1) True >>> int_in_bool_binop(2) True >>> int_in_bool_binop(3) False """ return x == 1 or x == 2 @cython.test_assert_path_exists('//SwitchStatNode') @cython.test_fail_if_path_exists('//BoolBinopNode', '//PrimaryCmpNode') def int_in_bool_binop_3(int x): """ >>> int_in_bool_binop_3(0) False >>> int_in_bool_binop_3(1) True >>> int_in_bool_binop_3(2) True >>> int_in_bool_binop_3(3) False >>> int_in_bool_binop_3(4) True >>> int_in_bool_binop_3(5) False """ return x == 1 or x == 2 or x == 4 Cython-0.23.4/tests/run/subop.pyx0000644000175600017570000000657212606202452020056 0ustar jenkinsjenkins00000000000000cimport cython def bigint(x): print(str(x).rstrip('L')) def mixed_test(): """ >>> mixed_test() (-1, -1) """ cdef int int1, int2, int3 obj1 = 1 obj2 = 2 obj3 = 3 int2 = 2 int3 = 3 int1 = int2 - int3 obj1 = obj2 - int3 return int1, obj1 def pointer_test(): """ >>> pointer_test() 0 """ cdef int int1, int2, int3 cdef char *ptr1, *ptr2, *ptr3 int2 = 2 int3 = 3 ptr2 = "test" ptr3 = ptr2 ptr1 = ptr2 - int3 int1 = ptr2 - ptr3 return int1 @cython.test_fail_if_path_exists('//SubNode') def sub_x_1(x): """ >>> sub_x_1(0) -1 >>> sub_x_1(1) 0 >>> sub_x_1(-1) -2 >>> bigint(2**50 - 1) 1125899906842623 >>> bigint(sub_x_1(2**50)) 1125899906842623 >>> sub_x_1(1.5) 0.5 >>> sub_x_1(-1.5) -2.5 >>> try: sub_x_1("abc") ... except TypeError: pass """ return x - 1 @cython.test_fail_if_path_exists('//SubNode') def sub_x_1f(x): """ >>> sub_x_1f(0) -1.0 >>> sub_x_1f(1) 0.0 >>> sub_x_1f(-1) -2.0 >>> 2**52 - 1.0 4503599627370495.0 >>> sub_x_1f(2**52) 4503599627370495.0 >>> sub_x_1f(2**60) == 2**60 - 1.0 or sub_x_1f(2**60) True >>> sub_x_1f(1.5) 0.5 >>> sub_x_1f(-1.5) -2.5 >>> try: sub_x_1f("abc") ... except TypeError: pass """ return x - 1.0 @cython.test_fail_if_path_exists('//SubNode') def sub_x_large(x): """ >>> sub_x_large(0) -1073741824 >>> sub_x_large(1) -1073741823 >>> sub_x_large(-1) -1073741825 >>> bigint(2**50 - 2**30) 1125898833100800 >>> bigint(sub_x_large(2**50)) 1125898833100800 >>> sub_x_large(2.0**30) 0.0 >>> sub_x_large(2.0**30 + 1) 1.0 >>> sub_x_large(2.0**30 - 1) -1.0 >>> 2.0 ** 31 - 2**30 1073741824.0 >>> sub_x_large(2.0**31) 1073741824.0 >>> try: sub_x_large("abc") ... except TypeError: pass """ return x - 2**30 @cython.test_fail_if_path_exists('//SubNode') def sub_1_x(x): """ >>> sub_1_x(0) 1 >>> sub_1_x(-1) 2 >>> sub_1_x(1) 0 >>> bigint(1 - 2**50) -1125899906842623 >>> bigint(sub_1_x(2**50)) -1125899906842623 >>> sub_1_x(1.5) -0.5 >>> sub_1_x(-1.5) 2.5 >>> try: sub_1_x("abc") ... except TypeError: pass """ return 1 - x @cython.test_fail_if_path_exists('//SubNode') def sub_1f_x(x): """ >>> sub_1f_x(0) 1.0 >>> sub_1f_x(-1) 2.0 >>> sub_1f_x(1) 0.0 >>> 1.0 - 2**52 -4503599627370495.0 >>> sub_1f_x(2**52) -4503599627370495.0 >>> sub_1f_x(2**60) == 1.0 - 2**60 or sub_1f_x(2**60) True >>> sub_1f_x(1.5) -0.5 >>> sub_1f_x(-1.5) 2.5 >>> try: sub_1f_x("abc") ... except TypeError: pass """ return 1.0 - x @cython.test_fail_if_path_exists('//SubNode') def sub_large_x(x): """ >>> sub_large_x(0) 1073741824 >>> sub_large_x(-1) 1073741825 >>> sub_large_x(1) 1073741823 >>> sub_large_x(2**30) 0 >>> bigint(2**30 - 2**31) -1073741824 >>> bigint(sub_large_x(2**31)) -1073741824 >>> sub_large_x(2.0**30) 0.0 >>> sub_large_x(2.0**31) -1073741824.0 >>> sub_large_x(2.0**30 + 1) -1.0 >>> sub_large_x(2.0**30 - 1) 1.0 >>> try: sub_large_x("abc") ... except TypeError: pass """ return 2**30 - x Cython-0.23.4/tests/run/subclasses.pyx0000644000175600017570000000230712606202452021065 0ustar jenkinsjenkins00000000000000cdef class Base0: pass cdef class Base(Base0): pass cdef class Foo(Base): cdef fooit(self): return 42 cdef class Bar(Foo): pass cdef class Bam(Bar): pass cdef class Zoo(Bam): pass def fooit(Foo foo): """ >>> zoo = Zoo() >>> for cl in (Zoo, Bam, Bar, Foo, Base, Base0): assert isinstance(zoo, cl) >>> fooit(zoo) 42 >>> bam = Bam() >>> for cl in (Bam, Bar, Foo, Base, Base0): assert isinstance(bam, cl) >>> fooit(bam) 42 >>> bar = Bar() >>> for cl in (Bar, Foo, Base, Base0): assert isinstance(bar, cl) >>> fooit(bar) 42 >>> foo = Foo() >>> for cl in (Foo, Base, Base0): assert isinstance(foo, cl) >>> fooit(foo) 42 >>> base = Base() >>> for cl in (Base, Base0): assert isinstance(base, cl) >>> fooit(base) Traceback (most recent call last): TypeError: Argument 'foo' has incorrect type (expected subclasses.Foo, got subclasses.Base) >>> base0 = Base0() >>> for cl in (Base0,): assert isinstance(base0, cl) >>> fooit(base0) Traceback (most recent call last): TypeError: Argument 'foo' has incorrect type (expected subclasses.Foo, got subclasses.Base0) """ return foo.fooit() Cython-0.23.4/tests/run/struct_conversion_extern_header.h0000644000175600017570000000010012606202452025000 0ustar jenkinsjenkins00000000000000struct my_date_t { int year; int month; int day; }; Cython-0.23.4/tests/run/struct_conversion_extern.pyx0000644000175600017570000000105312606202452024071 0ustar jenkinsjenkins00000000000000""" Note: this tests if the necessary utility code is included in the module env, despite potentially being already created before. """ cdef extern from "struct_conversion_extern_header.h": cdef struct my_date_t: int year int month int day def test_extern_struct(): """ >>> test_extern_struct() [('day', 24), ('month', 6), ('year', 2000)] """ cdef my_date_t day = my_date_t(year=2000, month=6, day=24) cdef object d = day assert type(d) is dict assert d == day return sorted(day.items()) Cython-0.23.4/tests/run/struct_conversion.pyx0000644000175600017570000001106512606202452022510 0ustar jenkinsjenkins00000000000000cdef struct Point: double x double y int color def test_constructor(x, y, int color): """ >>> sorted(test_constructor(1,2,255).items()) [('color', 255), ('x', 1.0), ('y', 2.0)] >>> try: test_constructor(1,None,255) ... except TypeError: pass """ cdef Point p = Point(x, y, color) return p def return_constructor(x, y, int color): """ >>> sorted(return_constructor(1,2,255).items()) [('color', 255), ('x', 1.0), ('y', 2.0)] >>> try: return_constructor(1, None, 255) ... except TypeError: pass """ return Point(x, y, color) def test_constructor_kwds(x, y, color): """ >>> sorted(test_constructor_kwds(1.25, 2.5, 128).items()) [('color', 128), ('x', 1.25), ('y', 2.5)] >>> test_constructor_kwds(1.25, 2.5, None) Traceback (most recent call last): ... TypeError: an integer is required """ cdef Point p = Point(x=x, y=y, color=color) return p def return_constructor_kwds(double x, y, color): """ >>> sorted(return_constructor_kwds(1.25, 2.5, 128).items()) [('color', 128), ('x', 1.25), ('y', 2.5)] >>> return_constructor_kwds(1.25, 2.5, None) Traceback (most recent call last): ... TypeError: an integer is required """ return Point(x=x, y=y, color=color) def test_dict_construction(x, y, color): """ >>> sorted(test_dict_construction(4, 5, 64).items()) [('color', 64), ('x', 4.0), ('y', 5.0)] >>> try: test_dict_construction("foo", 5, 64) ... except TypeError: pass """ cdef Point p = {'color': color, 'x': x, 'y': y} return p def test_list_construction(x, y, color): """ >>> sorted(test_list_construction(4, 5, 64).items()) [('color', 64), ('x', 4.0), ('y', 5.0)] >>> try: test_list_construction("foo", 5, 64) ... except TypeError: pass """ cdef Point p = [x, y, color] return p ''' # FIXME: make this work def test_tuple_construction(x, y, color): """ >>> sorted(test_tuple_construction(4, 5, 64).items()) [('color', 64), ('x', 4.0), ('y', 5.0)] >>> try: test_tuple_construction("foo", 5, 64) ... except TypeError: pass """ cdef Point p = (x, y, color) return p ''' cdef union int_or_float: int n double x def test_union_constructor(n,x): """ >>> test_union_constructor(1, None) 1 >>> test_union_constructor(None, 2.0) 2.0 """ cdef int_or_float u if n is None: u = int_or_float(x=x) return u.x else: u = int_or_float(n=n) return u.n cdef struct with_pointers: bint is_integral int_or_float data void* ptr def test_pointers(int n, double x): """ >>> test_pointers(100, 2.71828) 100 2.71828 True """ cdef with_pointers a = [True, {'n': n}, NULL] cdef with_pointers b = with_pointers(False, {'x': x}, NULL) print a.data.n print b.data.x print a.ptr == b.ptr == NULL cdef struct MyStruct: char c int i float f char *s bhello = b"hello" # must hold a C reference in PyPy def test_obj_to_struct(MyStruct mystruct): """ >>> test_obj_to_struct(dict(c=10, i=20, f=6.7, s=bhello)) c=10 i=20 f=6.70 s=hello >>> test_obj_to_struct(None) Traceback (most recent call last): ... TypeError: Expected a mapping, got NoneType >>> test_obj_to_struct(dict(s=b"world")) Traceback (most recent call last): ... ValueError: No value specified for struct attribute 'c' >>> test_obj_to_struct(dict(c=b"world")) Traceback (most recent call last): ... TypeError: an integer is required """ print 'c=%d i=%d f=%.2f s=%s' % (mystruct.c, mystruct.i, mystruct.f, mystruct.s.decode('ascii')) cdef struct NestedStruct: MyStruct mystruct double d def test_nested_obj_to_struct(NestedStruct nested): """ >>> test_nested_obj_to_struct(dict(mystruct=dict(c=10, i=20, f=6.7, s=bhello), d=4.5)) c=10 i=20 f=6.70 s=hello d=4.50 >>> test_nested_obj_to_struct(dict(d=7.6)) Traceback (most recent call last): ... ValueError: No value specified for struct attribute 'mystruct' >>> test_nested_obj_to_struct(dict(mystruct={}, d=7.6)) Traceback (most recent call last): ... ValueError: No value specified for struct attribute 'c' """ print 'c=%d i=%d f=%.2f s=%s d=%.2f' % (nested.mystruct.c, nested.mystruct.i, nested.mystruct.f, nested.mystruct.s.decode('UTF-8'), nested.d) Cython-0.23.4/tests/run/strmethods.pyx0000644000175600017570000000701612606202452021114 0ustar jenkinsjenkins00000000000000cimport cython @cython.test_assert_path_exists( "//PythonCapiCallNode") def str_startswith(str s, sub, start=None, stop=None): """ >>> str_startswith('a', 'a') True >>> str_startswith('ab', 'a') True >>> str_startswith('a', 'b') False >>> str_startswith('ab', 'b') False >>> str_startswith('a', ('a', 'b')) True >>> str_startswith('a', 'a', 1) False >>> str_startswith('a', 'a', 0, 0) False """ if start is None: return s.startswith(sub) elif stop is None: return s.startswith(sub, start) else: return s.startswith(sub, start, stop) @cython.test_assert_path_exists( "//PythonCapiCallNode") def str_endswith(str s, sub, start=None, stop=None): """ >>> str_endswith('a', 'a') True >>> str_endswith('ba', 'a') True >>> str_endswith('a', 'b') False >>> str_endswith('ba', 'b') False >>> str_endswith('a', ('a', 'b')) True >>> str_endswith('a', 'a', 1) False >>> str_endswith('a', 'a', 0, 0) False """ if start is None: return s.endswith(sub) elif stop is None: return s.endswith(sub, start) else: return s.endswith(sub, start, stop) @cython.test_assert_path_exists( "//SimpleCallNode", "//SimpleCallNode//NoneCheckNode", "//SimpleCallNode//AttributeNode[@is_py_attr = false]") def str_join(str s, args): """ >>> print(str_join('a', list('bbb'))) babab """ result = s.join(args) assert cython.typeof(result) == 'basestring object', cython.typeof(result) return result @cython.test_fail_if_path_exists( "//SimpleCallNode//NoneCheckNode", ) @cython.test_assert_path_exists( "//SimpleCallNode", "//SimpleCallNode//AttributeNode[@is_py_attr = false]") def literal_join(args): """ >>> print(literal_join(list('abcdefg'))) a|b|c|d|e|f|g """ result = '|'.join(args) assert cython.typeof(result) == 'basestring object', cython.typeof(result) return result # unicode.__mod__(format, values) format1 = 'abc%sdef' format2 = 'abc%sdef%sghi' def mod_format(str s, values): """ >>> mod_format(format1, 'sa') == 'abcsadef' or mod_format(format1, 'sa') True >>> mod_format(format2, ('XYZ', 'ABC')) == 'abcXYZdefABCghi' or mod_format(format2, ('XYZ', 'ABC')) True >>> mod_format(None, 'sa') Traceback (most recent call last): TypeError: unsupported operand type(s) for %: 'NoneType' and 'str' >>> class RMod(object): ... def __rmod__(self, other): ... return 123 >>> mod_format(None, RMod()) 123 """ assert cython.typeof(s % values) == 'basestring object', cython.typeof(s % values) return s % values def mod_format_literal(values): """ >>> mod_format_literal('sa') == 'abcsadef' or mod_format(format1, 'sa') True >>> mod_format_literal(('sa',)) == 'abcsadef' or mod_format(format1, ('sa',)) True >>> mod_format_literal(['sa']) == "abc['sa']def" or mod_format(format1, ['sa']) True """ assert cython.typeof('abc%sdef' % values) == 'basestring object', cython.typeof('abc%sdef' % values) return 'abc%sdef' % values def mod_format_tuple(*values): """ >>> mod_format_tuple('sa') == 'abcsadef' or mod_format(format1, 'sa') True >>> mod_format_tuple() Traceback (most recent call last): TypeError: not enough arguments for format string """ assert cython.typeof('abc%sdef' % values) == 'basestring object', cython.typeof('abc%sdef' % values) return 'abc%sdef' % values Cython-0.23.4/tests/run/strliterals.pyx0000644000175600017570000006361412606202452021276 0ustar jenkinsjenkins00000000000000__doc__ = ur""" >>> s1 'abc\x11' >>> s1 == 'abc\x11' True >>> len(s1) 4 >>> s2 'abc\\x11' >>> s2 == r'abc\x11' True >>> len(s2) 7 >>> s3 'abc\\x11' >>> s3 == R'abc\x11' True >>> len(s3) 7 >>> s4 b'abc\x11' >>> s4 == b'abc\x11' True >>> len(s4) 4 >>> s5 b'abc\x11' >>> s5 == B'abc\x11' True >>> len(s5) 4 >>> s6 b'abc\\x11' >>> s6 == br'abc\x11' True >>> len(s6) 7 >>> s7 b'abc\\x11' >>> s7 == Br'abc\x11' True >>> len(s7) 7 >>> s8 b'abc\\x11' >>> s8 == bR'abc\x11' True >>> len(s8) 7 >>> s9 b'abc\\x11' >>> s9 == BR'abc\x11' True >>> len(s9) 7 >>> u1 u'abc\x11' >>> u1 == u'abc\x11' True >>> len(u1) 4 >>> u2 u'abc\x11' >>> u2 == U'abc\x11' True >>> len(u2) 4 >>> u3 u'abc\\x11' >>> u3 == ur'abc\x11' True >>> len(u3) 7 >>> u4 u'abc\\x11' >>> u4 == Ur'abc\x11' True >>> len(u4) 7 >>> u5 u'abc\\x11' >>> u5 == uR'abc\x11' True >>> len(u5) 7 >>> u6 u'abc\\x11' >>> u6 == UR'abc\x11' True >>> len(u6) 7 >>> sresc '\\12\\\'\\"\\\\' >>> sresc == r'\12\'\"\\' True >>> len(sresc) 9 >>> bresc b'\\12\\\'\\"\\\\' >>> bresc == br'\12\'\"\\' True >>> len(bresc) 9 >>> uresc u'\\12\\\'\\"\\\\' >>> uresc == ur'\12\'\"\\' True >>> len(uresc) 9 >>> bytes_uescape b'\\u1234\\U12345678\\u\\u1\\u12\\uX' >>> bytes_uescape == b'\\u1234\\U12345678\\u\\u1\\u12\\uX' True >>> len(bytes_uescape) 28 >>> (sys.version_info[0] >= 3 and sys.maxunicode == 1114111 and len(str_uescape) == 4 or ... sys.version_info[0] >= 3 and sys.maxunicode == 65535 and len(str_uescape) == 5 or ... sys.version_info[0] < 3 and len(str_uescape) == 28 or ... len(str_uescape)) True >>> (sys.version_info[0] >= 3 and str_uescape[0] == 'c' or ... sys.version_info[0] < 3 and str_uescape[0] == '\\' or ... str_uescape[0]) True >>> print(str_uescape[-1]) B >>> (sys.version_info[0] >= 3 and ord(str_uescape[-2]) == 0x2603 or ... sys.version_info[0] < 3 and str_uescape[-12:-1] == b'\\N{SNOWMAN}' or ... sys.version_info[0] >= 3 and ord(str_uescape[-2]) or str_uescape[-12:-1]) True >>> same_cname [b'abc\xf0_2', b'abc\xf0', b'abc\xf1', b'abc\xf2', b'abc\xf3', b'abc_2', b'abc_3'] >>> newlines 'Aaa\n' >>> len(long_escapes) 3033 >>> len(even_lots_of_slashes) 3000 >>> len(odd_lots_of_slashes) 3001 >>> len(lots_of_tabs_and_newlines) 4321 """ import sys if sys.version_info[0] >= 3: __doc__ = __doc__.replace(u" u'", u" '").replace(u" U'", u" '").replace(u" ur'", u" r'").replace(u" uR'", u" R'").replace(u" Ur'", u" r'").replace(u" UR'", u" R'") else: __doc__ = __doc__.replace(u" b'", u" '").replace(u" B'", u" '").replace(u" br'", u" r'").replace(u" bR'", u" R'").replace(u" Br'", u" r'").replace(u" BR'", u" R'").replace(u"[b'", u"['") s1 = "abc\x11" s2 = r"abc\x11" s3 = R"abc\x11" s4 = b"abc\x11" s5 = B"abc\x11" s6 = br"abc\x11" s7 = Br"abc\x11" s8 = bR"abc\x11" s9 = BR"abc\x11" # and in reversed order: r+b s6_2 = rb"abc\x11" s7_2 = rB"abc\x11" s8_2 = Rb"abc\x11" s9_2 = RB"abc\x11" assert s6 == s6_2 assert s7 == s7_2 assert s8 == s8_2 assert s9 == s9_2 u1 = u"abc\x11" u2 = U"abc\x11" u3 = ur"abc\x11" u4 = Ur"abc\x11" u5 = uR"abc\x11" u6 = UR"abc\x11" sresc = r'\12\'\"\\' bresc = br'\12\'\"\\' uresc = ur'\12\'\"\\' bytes_uescape = b'\u1234\U12345678\u\u1\u12\uX' str_uescape = '\u0063\U00012345\N{SNOWMAN}\x42' same_cname = [b'abc\xf0_2', b'abc\xf0', b'abc\xf1', b'abc\xf2', b'abc\xf3', b'abc_2', b'abc_3'] newlines = "Aaa\n" # T640, long literals with escapes long_escapes = b"""\x31\x39\x37\x36\xe5\xb9\xb4\x39\xe6\x9c\x88\x39\xe6\x97\xa5\xef\xbc\x8c\xe5\x9c\xa8\xe6\xaf\x9b\xe6\xb3\xbd\xe4\xb8\x9c\xe9\x80\x9d\xe4\xb8\x96\xe4\xb9\x8b\xe5\x90\x8e\xef\xbc\x8c\xe4\xb8\xad\xe5\x9b\xbd\xe5\xbc\x80\xe5\xa7\x8b\xe7\x94\xb1\xe8\x87\xaa\xe7\x94\xb1\xe5\x8c\x96\xe7\x9f\xa5\xe8\xaf\x86\xe5\x88\x86\xe5\xad\x90\xe3\x80\x81\xe9\xa2\x86\xe5\xaf\xbc\xe9\x98\xb6\xe5\xb1\x82\xe7\x9a\x84\xe5\x85\xb7\xe6\x9c\x89\xe6\x94\xb9\xe9\x9d\xa9\xe6\x80\x9d\xe6\x83\xb3\xe7\x9a\x84\xe4\xba\xba\xe5\xa3\xab\xe5\x92\x8c\xe5\xb9\xbf\xe5\xa4\xa7\xe6\xb0\x91\xe9\x97\xb4\xe5\x85\xb1\xe5\x90\x8c\xe8\xbf\x9b\xe8\xa1\x8c\xe7\x9a\x84\xe2\x80\x9c\xe6\x80\x9d\xe6\x83\xb3\xe8\xa7\xa3\xe6\x94\xbe\xe2\x80\x9d\xe8\xbf\x90\xe5\x8a\xa8\xe3\x80\x82\x31\x39\x37\x38\xe5\xb9\xb4\xef\xbc\x8c\xe4\xb8\xad\xe5\x9b\xbd\xe5\x85\xb1\xe4\xba\xa7\xe5\x85\x9a\xe5\x8d\x81\xe4\xb8\x80\xe5\xb1\x8a\xe4\xb8\x89\xe4\xb8\xad\xe5\x85\xa8\xe4\xbc\x9a\xe6\x8f\x90\xe5\x87\xba\xe6\x94\xb9\xe9\x9d\xa9\xe5\xbc\x80\xe6\x94\xbe\xe7\x9a\x84\xe5\x9f\xba\xe6\x9c\xac\xe5\x9b\xbd\xe7\xad\x96\xef\xbc\x8c\xe4\xb8\xad\xe5\x9b\xbd\xe4\xba\xba\xe6\xb0\x91\xe5\xaf\xb9\xe5\x85\xb6\xe6\x9c\x89\xe8\x8e\xab\xe5\xa4\xa7\xe7\x9a\x84\xe6\x86\xa7\xe6\x86\xac\xef\xbc\x8c\xe5\xb8\x8c\xe6\x9c\x9b\xe6\x91\x86\xe8\x84\xb1\xe5\x8d\x81\xe5\xb9\xb4\xe6\x96\x87\xe9\x9d\xa9\xe7\x9a\x84\xe6\xb7\xb7\xe4\xb9\xb1\xe5\x8f\x8a\xe8\xbf\x87\xe5\x8e\xbb\xe7\x9a\x84\xe8\xb4\xab\xe7\xa9\xb7\xe3\x80\x82\x31\x39\x38\x35\xe5\xb9\xb4\xef\xbc\x8c\xe6\x94\xbf\xe5\xba\x9c\xe6\x89\xa9\xe5\xa4\xa7\xe4\xba\x86\xe4\xbc\x81\xe4\xb8\x9a\xe7\x9a\x84\xe8\x87\xaa\xe4\xb8\xbb\xe6\x9d\x83\xef\xbc\x8c\xe9\x81\xa3\xe8\xbf\x94\xe7\xa7\x81\xe8\x90\xa5\xe4\xbc\x81\xe4\xb8\x9a\xe4\xb8\xad\xe7\x9a\x84\xe5\x85\xac\xe6\x96\xb9\xe4\xbb\xa3\xe8\xa1\xa8\xef\xbc\x8c\xe5\xbc\x95\xe5\x85\xa5\xe5\xb8\x82\xe5\x9c\xba\xe7\xbb\x8f\xe6\xb5\x8e\xe4\xb8\xad\xe7\x9a\x84\xe8\xae\xb8\xe5\xa4\x9a\xe8\xa7\x82\xe5\xbf\xb5\xef\xbc\x8c\xe5\x8f\x91\xe5\xb1\x95\xe4\xb8\xba\xe7\xa4\xbe\xe4\xbc\x9a\xe4\xb8\xbb\xe4\xb9\x89\xe5\xb8\x82\xe5\x9c\xba\xe7\xbb\x8f\xe6\xb5\x8e\xef\xbc\x9b\xe4\xbd\x86\xe5\x90\x8c\xe6\x97\xb6\xe4\xba\xa6\xe5\x9c\xa8\xe5\x8e\x9f\xe6\x9c\x89\xe8\xae\xa1\xe5\x88\x92\xe7\xbb\x8f\xe6\xb5\x8e\xe7\x90\x86\xe8\xae\xba\xe9\x81\xad\xe5\x88\xb0\xe6\x8a\x9b\xe5\xbc\x83\xe7\x9a\x84\xe6\x83\x85\xe5\x86\xb5\xe4\xb8\x8b\xe5\xbc\x95\xe5\x8f\x91\xe4\xba\x86\xe5\x9b\xbd\xe5\x86\x85\xe6\xb0\x91\xe4\xbc\x97\xe7\x9a\x84\xe6\x80\x9d\xe6\x83\xb3\xe6\xb7\xb7\xe4\xb9\xb1\xe3\x80\x82\xe5\x8f\x8a\xe5\x90\x8e\xe5\x90\x84\xe5\x9c\xb0\xe5\x9b\xbd\xe8\x90\xa5\xe4\xbc\x81\xe4\xb8\x9a\xe5\x85\xb3\xe9\x97\xad\xef\xbc\x8c\xe5\x85\xa8\xe5\x9b\xbd\xe7\xba\xa6\xe6\x9c\x89\xe6\x95\xb0\xe7\x99\xbe\xe4\xb8\x87\xe5\xb7\xa5\xe4\xba\xba\xe5\xa4\xb1\xe4\xb8\x9a\xef\xbc\x8c\xe5\x9c\xa8\xe5\xbd\x93\xe6\x97\xb6\xe4\xb8\xad\xe5\x9b\xbd\xe6\x94\xbf\xe5\xba\x9c\xe5\x8f\x97\xe5\x88\xb0\xe4\xba\x86\xe6\x9e\x81\xe5\xa4\xa7\xe5\x86\xb2\xe5\x87\xbb\xe3\x80\x82\xe5\x90\x8c\xe6\x97\xb6\xe4\xba\xa6\xe5\xbc\x95\xe5\x8f\x91\xe8\xb4\xaa\xe6\xb1\xa1\xe8\x85\x90\xe8\xb4\xa5\xe7\x89\xa9\xe4\xbb\xb7\xe5\x8d\x87\xe6\xb6\xa8\xe7\xad\x89\xe9\x97\xae\xe9\xa2\x98\xef\xbc\x8c\xe5\x9c\xa8\xe6\xb0\x91\xe9\x97\xb4\xe9\x80\xa0\xe6\x88\x90\xe4\xb8\x80\xe5\xae\x9a\xe7\x9a\x84\xe4\xb8\x8d\xe6\xbb\xa1\xe3\x80\x82\x5b\x31\x5d\x5b\x32\x5d\x32\x30\xe4\xb8\x96\xe7\xba\xaa\x38\x30\xe5\xb9\xb4\xe4\xbb\xa3\xef\xbc\x8c\xe4\xb8\x96\xe7\x95\x8c\xe6\xad\xa3\xe5\xa4\x84\xe4\xba\x8e\xe5\x86\xb7\xe6\x88\x98\xe7\x9a\x84\xe6\x9c\x80\xe5\x90\x8e\xe9\x98\xb6\xe6\xae\xb5\xe3\x80\x82\x31\x39\x38\x35\xe5\xb9\xb4\xef\xbc\x8c\xe8\x8b\x8f\xe5\x85\xb1\xe4\xb8\xad\xe5\xa4\xae\xe6\x80\xbb\xe4\xb9\xa6\xe8\xae\xb0\xe6\x88\x88\xe5\xb0\x94\xe5\xb7\xb4\xe4\xb9\x94\xe5\xa4\xab\xe4\xb8\x8a\xe5\x8f\xb0\xef\xbc\x8c\xe6\x8e\xa8\xe8\xa1\x8c\xe4\xbb\xa5\xe4\xba\xba\xe9\x81\x93\xe4\xb8\xbb\xe4\xb9\x89\xe4\xb8\xba\xe6\xa0\xb8\xe5\xbf\x83\xe7\x9a\x84\xe2\x80\x9c\xe6\x96\xb0\xe6\x80\x9d\xe7\xbb\xb4\xe2\x80\x9d\xe8\xbf\x90\xe5\x8a\xa8\xef\xbc\x8c\xe5\x9c\xa8\xe7\xa4\xbe\xe4\xbc\x9a\xe4\xb8\xbb\xe4\xb9\x89\xe9\x98\xb5\xe8\x90\xa5\xe5\x86\x85\xe4\xba\xa7\xe7\x94\x9f\xe5\xb9\xbf\xe6\xb3\x9b\xe5\xbd\xb1\xe5\x93\x8d\xe3\x80\x82\xe8\xa2\xab\xe5\x8c\x97\xe4\xba\xac\xe6\x94\xbf\xe5\xba\x9c\xe7\xa7\xb0\xe2\x80\x9c\xe8\xb5\x84\xe4\xba\xa7\xe9\x98\xb6\xe7\xba\xa7\xe8\x87\xaa\xe7\x94\xb1\xe5\x8c\x96\xe2\x80\x9d\xe6\x80\x9d\xe6\x83\xb3\xe7\x9a\x84\xe8\xa5\xbf\xe6\x96\xb9\xe6\xb0\x91\xe4\xb8\xbb\xe6\x80\x9d\xe6\xbd\xae\xe4\xb9\x9f\xe5\x9c\xa8\xe4\xb8\xad\xe5\x9b\xbd\xe5\xbe\x97\xe5\x88\xb0\xe5\xb9\xbf\xe6\xb3\x9b\xe4\xbc\xa0\xe6\x92\xad\xe3\x80\x82\xe5\xbe\x88\xe5\xa4\x9a\xe4\xba\xba\xe8\xae\xa4\xe4\xb8\xba\xe9\x9a\x8f\xe7\x9d\x80\xe6\x94\xb9\xe9\x9d\xa9\xe5\xbc\x80\xe6\x94\xbe\xe4\xbb\xa5\xe5\x8f\x8a\xe5\xb8\x82\xe5\x9c\xba\xe7\xbb\x8f\xe6\xb5\x8e\xe7\x90\x86\xe5\xbf\xb5\xe7\x9a\x84\xe5\xbc\x95\xe5\x85\xa5\xef\xbc\x8c\xe5\xae\xa3\xe5\x91\x8a\xe4\xb8\xad\xe5\x9b\xbd\xe5\x85\xb1\xe4\xba\xa7\xe5\x85\x9a\xe8\x83\x8c\xe5\xbc\x83\xe4\xba\x86\xe9\xa9\xac\xe5\x88\x97\xe4\xb8\xbb\xe4\xb9\x89\xe7\x9a\x84\xe5\x9f\xba\xe6\x9c\xac\xe4\xbf\xa1\xe6\x9d\xa1\xef\xbc\x8c\xe4\xb8\xad\xe5\x9b\xbd\xe5\xb7\xb2\xe4\xb8\x8d\xe5\x86\x8d\xe6\x98\xaf\xe4\xb8\x80\xe4\xb8\xaa\xe7\xa4\xbe\xe4\xbc\x9a\xe4\xb8\xbb\xe4\xb9\x89\xe5\x9b\xbd\xe5\xae\xb6\xef\xbc\x8c\xe8\x80\x8c\xe6\x98\xaf\xe5\x85\xb7\xe6\x9c\x89\xe6\x9f\x90\xe7\xa7\x8d\xe8\xb5\x84\xe6\x9c\xac\xe4\xb8\xbb\xe4\xb9\x89\xe6\x80\xa7\xe8\xb4\xa8\xe7\x9a\x84\xe7\xa4\xbe\xe4\xbc\x9a\xe3\x80\x82\x31\x39\x38\x38\xe5\xb9\xb4\xef\xbc\x8c\xe5\x85\xac\xe5\xbc\x80\xe5\x91\xbc\xe5\x94\xa4\xe2\x80\x9c\xe8\x94\x9a\xe8\x93\x9d\xe8\x89\xb2\xe2\x80\x9d\xe8\xa5\xbf\xe6\x96\xb9\xe6\x96\x87\xe6\x98\x8e\xe7\x9a\x84\xe6\x94\xbf\xe8\xae\xba\xe7\x94\xb5\xe8\xa7\x86\xe7\x89\x87\xe3\x80\x8a\xe6\xb2\xb3\xe6\xae\x87\xe3\x80\x8b\xe5\x9c\xa8\xe4\xb8\xad\xe5\xa4\xae\xe7\x94\xb5\xe8\xa7\x86\xe5\x8f\xb0\xe5\x85\xac\xe5\xbc\x80\xe6\x92\xad\xe5\x87\xba\xef\xbc\x8c\xe5\x9c\xa8\xe5\x85\xa8\xe5\x9b\xbd\xe8\x8c\x83\xe5\x9b\xb4\xe5\x86\x85\xe5\xbc\x95\xe8\xb5\xb7\xe8\xbd\xb0\xe5\x8a\xa8\xef\xbc\x8c\xe6\x88\x90\xe4\xb8\xba\xe5\x85\xad\xe5\x9b\x9b\xe8\xbf\x90\xe5\x8a\xa8\xe7\x9a\x84\xe6\x80\x9d\xe6\x83\xb3\xe5\x89\x8d\xe5\xaf\xbc\xe3\x80\x82\xe9\x9a\x8f\xe7\x9d\x80\xe4\xb8\xad\xe5\x9b\xbd\xe7\x9a\x84\xe5\xbc\x80\xe6\x94\xbe\xef\xbc\x8c\xe4\xb8\xad\xe5\x9b\xbd\xe4\xba\xba\xe5\xbc\x80\xe5\xa7\x8b\xe6\x9b\xb4\xe5\xa4\x9a\xe5\x9c\xb0\xe6\x8e\xa5\xe8\xa7\xa6\xe8\xa5\xbf\xe6\x96\xb9\xe6\xb0\x91\xe4\xb8\xbb\xe4\xba\xba\xe6\x9d\x83\xe6\x80\x9d\xe6\x83\xb3\xef\xbc\x8c\xe5\xbe\x88\xe5\xa4\x9a\xe7\x9f\xa5\xe8\xaf\x86\xe5\x88\x86\xe5\xad\x90\xe5\xbc\x80\xe5\xa7\x8b\xe5\x85\xac\xe5\xbc\x80\xe6\x8f\x90\xe5\x80\xa1\xe4\xba\xba\xe6\x9d\x83\xe4\xb8\x8e\xe6\xb0\x91\xe4\xb8\xbb\xef\xbc\x8c\xe8\xae\xb8\xe5\xa4\x9a\xe5\xad\xa6\xe7\x94\x9f\xe6\x9b\xb4\xe6\x98\xaf\xe9\x80\x9a\xe8\xbf\x87\xe5\x90\x84\xe7\xa7\x8d\xe5\xbd\xa2\xe5\xbc\x8f\xe8\xa1\xa8\xe8\xbe\xbe\xe8\xbf\x99\xe6\x96\xb9\xe9\x9d\xa2\xe7\x9a\x84\xe8\xaf\x89\xe6\xb1\x82\xe3\x80\x82\xe4\xbb\x8e\xe4\xb8\x96\xe7\x95\x8c\xe8\x8c\x83\xe5\x9b\xb4\xe5\x86\x85\xe7\x9c\x8b\xef\xbc\x8c\xe5\x85\xad\xe5\x9b\x9b\xe8\xbf\x90\xe5\x8a\xa8\xe5\xb9\xb6\xe9\x9d\x9e\xe6\x98\xaf\xe4\xb8\x80\xe4\xb8\xaa\xe5\xad\xa4\xe7\xab\x8b\xe7\x9a\x84\xe4\xba\x8b\xe4\xbb\xb6\xef\xbc\x8c\xe8\x80\x8c\xe6\x98\xaf\xe5\xbd\x93\xe6\x97\xb6\xe6\x95\xb4\xe4\xb8\xaa\xe7\xa4\xbe\xe4\xbc\x9a\xe4\xb8\xbb\xe4\xb9\x89\xe9\x98\xb5\xe8\x90\xa5\xe5\x86\x85\xe6\xb0\x91\xe4\xb8\xbb\xe8\xbf\x90\xe5\x8a\xa8\xe7\x9a\x84\xe4\xb8\x80\xe4\xb8\xaa\xe9\x87\x8d\xe8\xa6\x81\xe7\x8e\xaf\xe8\x8a\x82\xe3\x80\x82\xe5\x9c\xa8\xe5\x85\xad\xe5\x9b\x9b\xe4\xba\x8b\xe4\xbb\xb6\xe5\x8f\x91\xe7\x94\x9f\xe7\x9a\x84\xe5\x90\x8c\xe4\xb8\x80\xe5\xa4\xa9\xef\xbc\x8c\xe6\xb3\xa2\xe5\x85\xb0\xe5\x9b\xa2\xe7\xbb\x93\xe5\xb7\xa5\xe4\xbc\x9a\xe5\x9c\xa8\xe5\xa4\xa7\xe9\x80\x89\xe4\xb8\xad\xe8\x8e\xb7\xe8\x83\x9c\xef\xbc\x8c\xe6\x8e\xa8\xe7\xbf\xbb\xe7\xa4\xbe\xe4\xbc\x9a\xe4\xb8\xbb\xe4\xb9\x89\xe5\x88\xb6\xe5\xba\xa6\xe3\x80\x82\xe9\x9a\x8f\xe5\x90\x8e\xe4\xb8\x8d\xe5\x88\xb0\xe4\xb8\x80\xe5\xb9\xb4\xef\xbc\x8c\xe4\xb8\x9c\xe6\xac\xa7\xe7\xa4\xbe\xe4\xbc\x9a\xe4\xb8\xbb\xe4\xb9\x89\xe5\x9b\xbd\xe5\xae\xb6\xe4\xb9\x9f\xe5\x85\x88\xe5\x90\x8e\xe5\x8f\x91\xe7\x94\x9f\xe5\x92\x8c\xe5\xb9\xb3\xe6\xbc\x94\xe5\x8f\x98\xef\xbc\x8c\xe4\xb8\xa4\xe5\xb9\xb4\xe5\x90\x8e\xe8\x8b\x8f\xe8\x81\x94\xe4\xba\xa6\xe5\xae\xa3\xe5\x91\x8a\xe8\xa7\xa3\xe4\xbd\x93\xef\xbc\x8c\xe7\xa4\xbe\xe4\xbc\x9a\xe4\xb8\xbb\xe4\xb9\x89\xe9\x98\xb5\xe8\x90\xa5\xe8\xa7\xa3\xe4\xbd\x93\xe3\x80\x82\xe8\xbf\x99\xe4\xba\x9b\xe5\xae\x9e\xe8\xa1\x8c\xe7\xa4\xbe\xe4\xbc\x9a\xe4\xb8\xbb\xe4\xb9\x89\xe5\x88\xb6\xe5\xba\xa6\xe7\x9a\x84\xe5\x9b\xbd\xe5\xae\xb6\xe5\x9c\xa8\xe4\xb8\x8d\xe5\x88\xb0\x35\xe5\xb9\xb4\xe7\x9a\x84\xe6\x97\xb6\xe9\x97\xb4\xe4\xb8\xad\xe5\x8f\x91\xe7\x94\x9f\xe4\xba\x86\xe6\x94\xbf\xe6\x9d\x83\xe8\xbd\xae\xe6\x9b\xbf\xef\xbc\x8c\xe5\xb9\xb6\xe6\x94\xb9\xe5\x8f\x98\xe4\xba\x86\xe5\x8e\x9f\xe6\x9c\x89\xe7\x9a\x84\xe6\x94\xbf\xe6\xb2\xbb\xe4\xbd\x93\xe5\x88\xb6\xe3\x80\x82\x31\x39\x38\x37\xe5\xb9\xb4\x31\xe6\x9c\x88\xef\xbc\x8c\xe5\x8e\x9f\xe6\x9c\xac\xe8\xa2\xab\xe9\x82\x93\xe5\xb0\x8f\xe5\xb9\xb3\xe9\x80\x89\xe5\xae\x9a\xe4\xb8\xba\xe6\x8e\xa5\xe7\x8f\xad\xe4\xba\xba\xe7\x9a\x84\xe8\x83\xa1\xe8\x80\x80\xe9\x82\xa6\xe8\xa2\xab\xe8\xbf\xab\xe4\xb8\x8b\xe5\x8f\xb0\xef\xbc\x8c\xe4\xbb\x96\xe8\xa2\xab\xe6\x8c\x87\xe8\xbf\x9d\xe5\x8f\x8d\xe4\xb8\xad\xe5\x9b\xbd\xe5\x85\xb1\xe4\xba\xa7\xe5\x85\x9a\xe7\x9a\x84\xe6\xb0\x91\xe4\xb8\xbb\xe9\x9b\x86\xe4\xb8\xad\xe5\x88\xb6\xef\xbc\x8c\xe7\xba\xb5\xe5\xae\xb9\xe8\xb5\x84\xe4\xba\xa7\xe9\x98\xb6\xe7\xba\xa7\xe8\x87\xaa\xe7\x94\xb1\xe5\x8c\x96\xef\xbc\x8c\xe6\xb2\xa1\xe6\x9c\x89\xe5\xaf\xb9\xe6\xb8\xb8\xe8\xa1\x8c\xe9\x87\x87\xe5\x8f\x96\xe6\x9c\x89\xe6\x95\x88\xe6\x8e\xaa\xe6\x96\xbd\xef\xbc\x8c\xe8\xa6\x81\xe5\xaf\xb9\x31\x39\x38\x36\xe5\xb9\xb4\xe5\xad\xa6\xe7\x94\x9f\xe8\xbf\x90\xe5\x8a\xa8\xe7\x9a\x84\xe5\xa4\xb1\xe6\x8e\xa7\xe8\xb4\x9f\xe8\xb4\xa3\xe3\x80\x82\xe5\x8f\x8a\xe5\x90\x8e\xe4\xb8\xad\xe5\x85\xb1\xe5\x85\x9a\xe5\x86\x85\xe5\x8f\x8d\xe6\x94\xb9\xe9\x9d\xa9\xe7\x9a\x84\xe2\x80\x9c\xe4\xbf\x9d\xe5\xae\x88\xe2\x80\x9d\xe5\x8a\xbf\xe5\x8a\x9b\xe6\x8e\x80\xe8\xb5\xb7\xe4\xb8\x80\xe8\x82\xa1\xe5\x8f\x8d\xe5\x8f\xb3\xe6\xb5\xaa\xe6\xbd\xae\xe3\x80\x82\x0a\x0a\xe6\xb3\x95\xe8\xbd\xae\xe5\x8a\x9f\xe5\x8f\x88\xe7\xa7\xb0\xe6\xb3\x95\xe8\xbd\xae\xe5\xa4\xa7\xe6\xb3\x95\xef\xbc\x8c\xe6\xb3\x95\xe8\xbd\xae\xe5\x8a\x9f\xe5\x8a\x9f\xe6\xb3\x95\xe6\x98\xaf\xe7\x94\xb1\xe4\xba\x94\xe5\xa5\x97\xe5\x8a\xa8\xe4\xbd\x9c\xe7\xbb\x84\xe6\x88\x90\xef\xbc\x8c\xe4\xbd\x86\xe4\xb8\x8d\xe5\x90\x8c\xe4\xba\x8e\xe4\xb8\x80\xe8\x88\xac\xe6\xb0\x94\xe5\x8a\x9f\xe7\x9a\x84\xe6\x98\xaf\xe7\x9d\x80\xe9\x87\x8d\xe5\xbf\x83\xe6\x80\xa7\xe7\x9a\x84\xe4\xbf\xae\xe7\x82\xbc\xef\xbc\x8c\xe5\x8d\xb3\xe2\x80\x9c\xe7\x9c\x9f\xe3\x80\x81\xe5\x96\x84\xe3\x80\x81\xe5\xbf\x8d\xe2\x80\x9d\xe7\x9a\x84\xe5\x8e\x9f\xe5\x88\x99\xe3\x80\x82\xe4\xb8\x80\xe4\xba\x9b\xe4\xba\xba\xe8\xae\xa4\xe4\xb8\xba\xe6\xb3\x95\xe8\xbd\xae\xe5\x8a\x9f\xe5\x80\x9f\xe7\x94\xa8\xe4\xba\x86\xe5\xbe\x88\xe5\xa4\x9a\xe4\xbd\x9b\xe6\x95\x99\xe8\xa7\x82\xe5\xbf\xb5\xef\xbc\x8c\xe5\xa6\x82\xe6\xb3\x95\xe8\xbd\xae\xe3\x80\x81\xe4\xb8\x9a\xe7\xad\x89\xef\xbc\x8c\xe5\x9b\xa0\xe8\x80\x8c\xe8\xa7\x86\xe4\xb9\x8b\xe4\xb8\xba\xe4\xb8\x80\xe7\xa7\x8d\xe5\xae\x97\xe6\x95\x99\xe3\x80\x82\xe4\xbd\x86\xe6\xb3\x95\xe8\xbd\xae\xe5\x8a\x9f\xe5\xad\xa6\xe5\x91\x98\xe8\xae\xa4\xe4\xb8\xba\xe2\x80\x9c\xe6\xb3\x95\xe8\xbd\xae\xe2\x80\x9d\xe5\x92\x8c\xe2\x80\x9c\xe4\xb8\x9a\xe2\x80\x9d\xe9\x83\xbd\xe4\xb8\x8d\xe6\x98\xaf\xe4\xbd\x9b\xe6\x95\x99\xe4\xb8\x93\xe7\x94\xa8\xe7\x9a\x84\xef\xbc\x8c\xe5\x85\xb6\xe4\xb8\xad\xe4\xb8\x9a\xe7\x9a\x84\xe6\xa6\x82\xe5\xbf\xb5\xe5\x9c\xa8\xe5\xa9\x86\xe7\xbd\x97\xe9\x97\xa8\xe6\x95\x99\xe6\x88\x96\xe6\x9b\xb4\xe6\x97\xa9\xe7\x9a\x84\xe4\xbf\xae\xe7\x82\xbc\xe6\x96\xb9\xe6\xb3\x95\xe5\x92\x8c\xe5\xae\x97\xe6\x95\x99\xe5\xb0\xb1\xe5\xb7\xb2\xe7\xbb\x8f\xe5\xad\x98\xe5\x9c\xa8\xe4\xba\x86\xe3\x80\x82\x0a\x0a\xe5\x8f\xb0\xe7\x8b\xac\xe5\x95\x8a\xe5\x8f\xb0\xe7\x8b\xac\xe4\xb8\x80\xe5\x8f\xb0\xe7\x8b\xac\xe7\xab\x8b\xe6\x9c\x8d\xe5\x8a\xa1\xe5\x99\xa8\x0a\x0a""" even_lots_of_slashes = r"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" odd_lots_of_slashes = r"0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" lots_of_tabs_and_newlines = r'0\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n\t\r\n' Cython-0.23.4/tests/run/string_comparison.pyx0000644000175600017570000003663212606202452022466 0ustar jenkinsjenkins00000000000000 cimport cython import sys IS_PY3 = sys.version_info[0] >= 3 bstring1 = b"abcdefg" bstring2 = b"1234567" string1 = "abcdefg" string2 = "1234567" ustring1 = u"abcdefg" ustring2 = u"1234567" # unicode @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def unicode_eq(unicode s1, unicode s2): """ >>> unicode_eq(ustring1, ustring1) True >>> unicode_eq(ustring1+ustring2, ustring1+ustring2) True >>> unicode_eq(ustring1, ustring2) False """ return s1 == s2 @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def unicode_neq(unicode s1, unicode s2): """ >>> unicode_neq(ustring1, ustring1) False >>> unicode_neq(ustring1+ustring2, ustring1+ustring2) False >>> unicode_neq(ustring1, ustring2) True """ return s1 != s2 @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def unicode_literal_eq(unicode s): """ >>> unicode_literal_eq(ustring1) True >>> unicode_literal_eq((ustring1+ustring2)[:len(ustring1)]) True >>> unicode_literal_eq(ustring2) False """ return s == u"abcdefg" @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def unicode_literal_neq(unicode s): """ >>> unicode_literal_neq(ustring1) False >>> unicode_literal_neq((ustring1+ustring2)[:len(ustring1)]) False >>> unicode_literal_neq(ustring2) True """ return s != u"abcdefg" @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", "//CascadedCmpNode" ) @cython.test_fail_if_path_exists( "//CascadedCmpNode[@is_pycmp = True]", "//PrimaryCmpNode[@is_pycmp = True]", ) def unicode_cascade(unicode s1, unicode s2): """ >>> unicode_cascade(ustring1, ustring1) True >>> unicode_cascade(ustring1, (ustring1+ustring2)[:len(ustring1)]) True >>> unicode_cascade(ustring1, ustring2) False """ return s1 == s2 == u"abcdefg" @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def unicode_cascade_untyped_end(unicode s1, unicode s2): """ >>> unicode_cascade_untyped_end(ustring1, ustring1) True >>> unicode_cascade_untyped_end(ustring1, (ustring1+ustring2)[:len(ustring1)]) True >>> unicode_cascade_untyped_end(ustring1, ustring2) False """ return s1 == s2 == u"abcdefg" == (ustring1) == ustring1 @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def unicode_cascade_untyped_end_bool(unicode s1, unicode s2): """ >>> unicode_cascade_untyped_end_bool(ustring1, ustring1) True >>> unicode_cascade_untyped_end_bool(ustring1, (ustring1+ustring2)[:len(ustring1)]) True >>> unicode_cascade_untyped_end_bool(ustring1, ustring2) False """ if s1 == s2 == u"abcdefg" == (ustring1) == ustring1: return True else: return False # str @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def str_eq(str s1, str s2): """ >>> str_eq(string1, string1) True >>> str_eq(string1+string2, string1+string2) True >>> str_eq(string1, string2) False """ return s1 == s2 @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def str_neq(str s1, str s2): """ >>> str_neq(string1, string1) False >>> str_neq(string1+string2, string1+string2) False >>> str_neq(string1, string2) True """ return s1 != s2 @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def str_literal_eq(str s): """ >>> str_literal_eq(string1) True >>> str_literal_eq((string1+string2)[:len(string1)]) True >>> str_literal_eq(string2) False """ return s == "abcdefg" @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def str_literal_neq(str s): """ >>> str_literal_neq(string1) False >>> str_literal_neq((string1+string2)[:len(string1)]) False >>> str_literal_neq(string2) True """ return s != "abcdefg" @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) @cython.test_fail_if_path_exists( "//CascadedCmpNode[@is_pycmp = True]", "//PrimaryCmpNode[@is_pycmp = True]", ) def str_cascade(str s1, str s2): """ >>> str_cascade(string1, string1) True >>> str_cascade(string1, (string1+string2)[:len(string1)]) True >>> str_cascade(string1, string2) False """ return s1 == s2 == "abcdefg" @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def str_cascade_untyped_end(str s1, str s2): """ >>> str_cascade_untyped_end(string1, string1) True >>> str_cascade_untyped_end(string1, (string1+string2)[:len(string1)]) True >>> str_cascade_untyped_end(string1, string2) False """ return s1 == s2 == "abcdefg" == (string1) == string1 # bytes @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def bytes_eq(bytes s1, bytes s2): """ >>> bytes_eq(bstring1, bstring1) True >>> bytes_eq(bstring1+bstring2, bstring1+bstring2) True >>> bytes_eq(bstring1, bstring2) False """ return s1 == s2 @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def bytes_neq(bytes s1, bytes s2): """ >>> bytes_neq(bstring1, bstring1) False >>> bytes_neq(bstring1+bstring2, bstring1+bstring2) False >>> bytes_neq(bstring1, bstring2) True """ return s1 != s2 @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def bytes_literal_eq(bytes s): """ >>> bytes_literal_eq(bstring1) True >>> bytes_literal_eq((bstring1+bstring2)[:len(bstring1)]) True >>> bytes_literal_eq(bstring2) False """ return s == b"abcdefg" @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def bytes_literal_neq(bytes s): """ >>> bytes_literal_neq(bstring1) False >>> bytes_literal_neq((bstring1+bstring2)[:len(bstring1)]) False >>> bytes_literal_neq(bstring2) True """ return s != b"abcdefg" @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) @cython.test_fail_if_path_exists( "//CascadedCmpNode[@is_pycmp = True]", "//PrimaryCmpNode[@is_pycmp = True]", ) def bytes_cascade(bytes s1, bytes s2): """ >>> bytes_cascade(bstring1, bstring1) True >>> bytes_cascade(bstring1, (bstring1+bstring2)[:len(bstring1)]) True >>> bytes_cascade(bstring1, bstring2) False """ return s1 == s2 == b"abcdefg" @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def bytes_cascade_untyped_end(bytes s1, bytes s2): """ >>> bytes_cascade_untyped_end(bstring1, bstring1) True >>> bytes_cascade_untyped_end(bstring1, (bstring1+bstring2)[:len(bstring1)]) True >>> bytes_cascade_untyped_end(bstring1, bstring2) False """ return s1 == s2 == b"abcdefg" == (bstring1) == bstring1 # basestring @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def basestring_eq(basestring s1, basestring s2): """ >>> basestring_eq(string1, string1) True >>> basestring_eq(string1, ustring1) True >>> basestring_eq(string1+string2, string1+string2) True >>> basestring_eq(string1+ustring2, ustring1+string2) True >>> basestring_eq(string1, string2) False >>> basestring_eq(string1, ustring2) False >>> basestring_eq(ustring1, string2) False """ return s1 == s2 @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def basestring_neq(basestring s1, basestring s2): """ >>> basestring_neq(string1, string1) False >>> basestring_neq(string1+string2, string1+string2) False >>> basestring_neq(string1+ustring2, ustring1+string2) False >>> basestring_neq(string1, string2) True >>> basestring_neq(string1, ustring2) True >>> basestring_neq(ustring1, string2) True """ return s1 != s2 @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def basestring_str_literal_eq(basestring s): """ >>> basestring_str_literal_eq(string1) True >>> basestring_str_literal_eq((string1+string2)[:len(string1)]) True >>> basestring_str_literal_eq(string2) False """ return s == "abcdefg" @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def basestring_unicode_literal_eq(basestring s): """ >>> basestring_unicode_literal_eq(string1) True >>> basestring_unicode_literal_eq((string1+string2)[:len(string1)]) True >>> basestring_unicode_literal_eq(string2) False """ return s == u"abcdefg" @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def basestring_str_literal_neq(basestring s): """ >>> basestring_str_literal_neq(string1) False >>> basestring_str_literal_neq((string1+string2)[:len(string1)]) False >>> basestring_str_literal_neq(string2) True """ return s != "abcdefg" @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def basestring_unicode_literal_neq(basestring s): """ >>> basestring_unicode_literal_neq(string1) False >>> basestring_unicode_literal_neq((string1+string2)[:len(string1)]) False >>> basestring_unicode_literal_neq(string2) True """ return s != u"abcdefg" @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", "//CascadedCmpNode[@is_pycmp = False]", ) @cython.test_fail_if_path_exists( "//CascadedCmpNode[@is_pycmp = True]", "//PrimaryCmpNode[@is_pycmp = True]", ) def basestring_cascade_str(basestring s1, basestring s2): """ >>> basestring_cascade_str(string1, string1) True >>> basestring_cascade_str(string1, (string1+string2)[:len(string1)]) True >>> basestring_cascade_str(string1, string2) False """ return s1 == s2 == "abcdefg" @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", "//CascadedCmpNode[@is_pycmp = False]", ) @cython.test_fail_if_path_exists( "//CascadedCmpNode[@is_pycmp = True]", "//PrimaryCmpNode[@is_pycmp = True]", ) def basestring_cascade_unicode(basestring s1, basestring s2): """ >>> basestring_cascade_unicode(string1, string1) True >>> basestring_cascade_unicode(ustring1, string1) True >>> basestring_cascade_unicode(string1, ustring1) True >>> basestring_cascade_unicode(string1, (string1+string2)[:len(string1)]) True >>> basestring_cascade_unicode(string1, string2) False >>> basestring_cascade_unicode(ustring1, string2) False >>> basestring_cascade_unicode(string1, ustring2) False """ return s1 == s2 == u"abcdefg" @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def basestring_cascade_untyped_end(basestring s1, basestring s2): """ >>> basestring_cascade_untyped_end(string1, string1) True >>> basestring_cascade_untyped_end(string1, (string1+string2)[:len(string1)]) True >>> basestring_cascade_untyped_end(string1, string2) False """ return s1 == s2 == "abcdefg" == (string1) == string1 # untyped/literal comparison @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def untyped_unicode_literal_eq_bool(s): """ >>> untyped_unicode_literal_eq_bool(string1) True >>> untyped_unicode_literal_eq_bool(ustring1) True >>> untyped_unicode_literal_eq_bool((string1+string2)[:len(string1)]) True >>> untyped_unicode_literal_eq_bool(string2) False >>> untyped_unicode_literal_eq_bool(ustring2) False """ return True if s == u"abcdefg" else False @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", ) def untyped_str_literal_eq_bool(s): """ >>> untyped_str_literal_eq_bool(string1) True >>> untyped_str_literal_eq_bool(ustring1) True >>> untyped_str_literal_eq_bool((string1+string2)[:len(string1)]) True >>> untyped_str_literal_eq_bool(string2) False >>> untyped_str_literal_eq_bool(ustring2) False """ return True if s == "abcdefg" else False @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = True]", "//CascadedCmpNode", "//CascadedCmpNode[@is_pycmp = False]", ) @cython.test_fail_if_path_exists( "//CascadedCmpNode[@is_pycmp = True]", "//PrimaryCmpNode[@is_pycmp = False]", ) def untyped_unicode_cascade(s1, unicode s2): """ >>> untyped_unicode_cascade(ustring1, ustring1) True >>> untyped_unicode_cascade(ustring1, (ustring1+ustring2)[:len(ustring1)]) True >>> untyped_unicode_cascade(ustring1, ustring2) False """ return s1 == s2 == u"abcdefg" @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = False]", "//CascadedCmpNode", "//CascadedCmpNode[@is_pycmp = False]", ) @cython.test_fail_if_path_exists( "//CascadedCmpNode[@is_pycmp = True]", "//PrimaryCmpNode[@is_pycmp = True]", ) def untyped_unicode_cascade_bool(s1, unicode s2): """ >>> untyped_unicode_cascade_bool(ustring1, ustring1) True >>> untyped_unicode_cascade_bool(ustring1, (ustring1+ustring2)[:len(ustring1)]) True >>> untyped_unicode_cascade_bool(ustring1, ustring2) False """ return True if s1 == s2 == u"abcdefg" else False @cython.test_assert_path_exists( "//PrimaryCmpNode", "//PrimaryCmpNode[@is_pycmp = True]", "//CascadedCmpNode", # "//CascadedCmpNode[@is_pycmp = False]", ) @cython.test_fail_if_path_exists( "//CascadedCmpNode[@is_pycmp = True]", "//PrimaryCmpNode[@is_pycmp = False]", ) def untyped_untyped_unicode_cascade_bool(s1, s2): """ >>> untyped_untyped_unicode_cascade_bool(ustring1, ustring1) True >>> untyped_untyped_unicode_cascade_bool(ustring1, (ustring1+ustring2)[:len(ustring1)]) True >>> untyped_untyped_unicode_cascade_bool(ustring1, ustring2) False >>> untyped_untyped_unicode_cascade_bool(string1, string2) False >>> untyped_untyped_unicode_cascade_bool(1, 2) False >>> untyped_untyped_unicode_cascade_bool(1, 1) False """ return True if s1 == s2 == u"abcdefg" else False # bytes/str comparison @cython.test_assert_path_exists( '//CondExprNode', '//CondExprNode//PrimaryCmpNode', '//CondExprNode//PrimaryCmpNode[@operator = "=="]', '//CondExprNode//PrimaryCmpNode[@operator = "!="]', ) def literal_compare_bytes_str(): """ >>> literal_compare_bytes_str() True """ # we must not constant fold the subexpressions as the result is Py2/3 sensitive return b'abc' != 'abc' if IS_PY3 else b'abc' == 'abc' Cython-0.23.4/tests/run/strfunction.pyx0000644000175600017570000000114412606202452021272 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> str('test') 'test' >>> z 'test' """ s = str z = str('test') def c(string): """ >>> c('testing') 'testing' """ return str(string) class subs(str): """ >>> subs('testing a subtype') 'testing a subtype' # >>> csub('testing a subtype') # 'testing a subtype' # >>> csubs('testing a subtype') # 'testing a subtype' """ pass def sub(string): """ >>> sub('testing a subtype') 'testing a subtype' """ return subs(string) #cdef class subs(str): # pass #def csub(string): # return csubs(string) Cython-0.23.4/tests/run/strescapes.pyx0000644000175600017570000000235612606202452021076 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> py_strings = [ ... b'\\x1234', ... b'\\x0A12\\x0C34', ... b'\\x0A57', ... b'\\x0A', ... b'\\'', ... b"\\'", ... b"\\"", ... b'\\"', ... b'abc\\x12def', ... u'\\u1234', ... u'\\U00001234', ... b'\\u1234', ... b'\\U00001234', ... b'\\n\\r\\t', ... b':>', ... b'??>', ... b'\\0\\0\\0', ... ] >>> for i, (py_string, (c_string, length)) in enumerate(zip(py_strings, c_strings)): ... assert py_string == c_string, "%d: %r != %r" % (i, py_string, c_string) ... assert len(py_string) == length, ( ... "%d: wrong length of %r, got %d, expected %d" % ( ... i, py_string, len(py_string), length)) ... assert len(c_string) == length, ( ... "%d: wrong length of %r, got %d, expected %d" % ( ... i, c_string, len(c_string), length)) """ import sys if sys.version_info[0] < 3: __doc__ = __doc__.replace(u" b'", u" '").replace(u' b"', u' "') else: __doc__ = __doc__.replace(u" u'", u" '").replace(u' u"', u' "') c_strings = [ (b'\x1234', 3), (b'\x0A12\x0C34', 6), (b'\x0A57', 3), (b'\x0A', 1), (b'\'', 1), (b"\'", 1), (b"\"", 1), (b'\"', 1), (b'abc\x12def', 7), (u'\u1234', 1), (u'\U00001234', 1), (b'\u1234', 6), (b'\U00001234', 10), (b'\n\r\t', 3), (b':>', 2), (b'??>', 3), (b'\0\0\0', 3), ] Cython-0.23.4/tests/run/strconstinclass.pyx0000644000175600017570000000012112606202452022142 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> c = C() >>> c.x 'foo' """ class C: x = "foo" Cython-0.23.4/tests/run/str_encoding_latin1.pyx0000644000175600017570000000133312606202452022642 0ustar jenkinsjenkins00000000000000# -*- coding: latin-1 -*- __doc__ = (u""" >>> a == 'abc' True >>> isinstance(a, str) True >>> isinstance(s, str) True >>> len(s) 6 >>> s == 'aäÄÖöo' True >>> isinstance(add(), str) True >>> len(add()) 9 >>> add() == 'abcaäÄÖöo' True >>> isinstance(add_literal(), str) True >>> len(add_literal()) 9 >>> add_literal() == 'abcaäÄÖöo' True >>> isinstance(typed(), str) True >>> len(typed()) 6 >>> typed() == 'üüääöö' True """ # recoding/escaping is required to properly pass the literals to doctest ).encode('unicode_escape').decode('ASCII').replace(u'\\n', u'\n') a = 'abc' s = 'aäÄÖöo' u = u'aäÄÖöo' cdef str S = 'üüääöö' def add(): return a+s def add_literal(): return 'abc' + 'aäÄÖöo' def typed(): return S Cython-0.23.4/tests/run/str_default_auto_encoding.pyx0000644000175600017570000000046312606202452024131 0ustar jenkinsjenkins00000000000000# cython: c_string_type = str # cython: c_string_encoding = default import sys if sys.version_info[0] >= 3: __doc__ = r""" >>> as_objects("ab\xff") == "ab\xff" True >>> slice_as_objects("ab\xffd", 1, 4) == "b\xff" True """ include "str_ascii_auto_encoding.pyx" Cython-0.23.4/tests/run/str_char_coercion_T412.pyx0000644000175600017570000000246612606202452023124 0ustar jenkinsjenkins00000000000000# ticket: 412 cdef int i = 'x' cdef char c = 'x' cdef char* s = 'x' def test_eq(): """ >>> test_eq() True True True True """ print i == 'x' print i == c'x' print c == 'x' print c == c'x' # print s == 'x' # error # print s == c'x' # error def test_cascaded_eq(): """ >>> test_cascaded_eq() True True True True True True True True """ print 'x' == i == 'x' print 'x' == i == c'x' print c'x' == i == 'x' print c'x' == i == c'x' print 'x' == c == 'x' print 'x' == c == c'x' print c'x' == c == 'x' print c'x' == c == c'x' def test_cascaded_ineq(): """ >>> test_cascaded_ineq() True True True True True True True True """ print 'a' <= i <= 'z' print 'a' <= i <= c'z' print c'a' <= i <= 'z' print c'a' <= i <= c'z' print 'a' <= c <= 'z' print 'a' <= c <= c'z' print c'a' <= c <= 'z' print c'a' <= c <= c'z' def test_long_ineq(): """ >>> test_long_ineq() True """ print 'a' < 'b' < 'c' < 'd' < c < 'y' < 'z' def test_long_ineq_py(): """ >>> test_long_ineq_py() True True """ print 'abcdef' < 'b' < 'c' < 'd' < 'y' < 'z' print 'a' < 'b' < 'cde' < 'd' < 'y' < 'z' Cython-0.23.4/tests/run/str_ascii_auto_encoding.pyx0000644000175600017570000000042112606202452023567 0ustar jenkinsjenkins00000000000000#cython: c_string_type = str #cython: c_string_encoding = ascii "End of first directives" include "unicode_ascii_auto_encoding.pyx" auto_string_type = str def check_auto_string_type(): """ >>> check_auto_string_type() """ assert auto_string_type is str Cython-0.23.4/tests/run/staticmethod.pyx0000644000175600017570000000472312606202452021412 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> class1.plus1(1) 2 >>> class2.plus1(1) 2 >>> class3.plus1(1) 2 >>> class4.plus1(1) 2 """ def f_plus(a): return a + 1 class class1: plus1 = f_plus class class2(object): plus1 = f_plus cdef class class3: plus1 = f_plus class class4: @staticmethod def plus1(a): return a + 1 def nested_class(): """ >>> cls = nested_class() >>> cls.plus1(1) 2 >>> obj = cls() >>> obj.plus1(1) 2 """ class class5(object): def __new__(cls): # implicit staticmethod return object.__new__(cls) @staticmethod def plus1(a): return a + 1 return class5 cdef class BaseClass(object): """ Test cdef static methods with super() and Python subclasses >>> obj = BaseClass() >>> obj.mystaticmethod(obj, 1) 1 >>> BaseClass.mystaticmethod(obj, 1) 1 >>> obj.mystaticmethod2(1, 2, 3) 1 2 3 >>> BaseClass.mystaticmethod2(1, 2, 3) 1 2 3 """ @staticmethod def mystaticmethod(self, arg1): print arg1 @staticmethod def mystaticmethod2(a, b, c): print a, b, c cdef class SubClass(BaseClass): """ >>> obj = SubClass() >>> obj.mystaticmethod(obj, 1) 1 2 >>> SubClass.mystaticmethod(obj, 1) 1 2 """ @staticmethod def mystaticmethod(self, arg1): print arg1 super().mystaticmethod(self, arg1 + 1) class SubSubClass(SubClass): """ >>> obj = SubSubClass() >>> obj.mystaticmethod(obj, 1) 1 2 3 >>> SubSubClass.mystaticmethod(obj, 1) 1 2 3 """ @staticmethod def mystaticmethod(self, arg1): print arg1 super().mystaticmethod(self, arg1 + 1) cdef class ArgsKwargs(object): @staticmethod def with_first_arg(arg1, *args, **kwargs): """ >>> ArgsKwargs().with_first_arg(1, 2, 3, a=4, b=5) (1, 'pos', 2, 3, ('a', 4), ('b', 5)) """ return (arg1, 'pos') + args + tuple(sorted(kwargs.items())) @staticmethod def only_args_kwargs(*args, **kwargs): """ >>> ArgsKwargs().only_args_kwargs() () >>> ArgsKwargs().only_args_kwargs(1, 2, a=3) (1, 2, ('a', 3)) """ return args + tuple(sorted(kwargs.items())) class StaticmethodSubclass(staticmethod): """ >>> s = StaticmethodSubclass(None) >>> s.is_subtype() True """ def is_subtype(self): return isinstance(self, staticmethod) Cython-0.23.4/tests/run/static_methods.pyx0000644000175600017570000000240312606202452021725 0ustar jenkinsjenkins00000000000000cdef class A: @staticmethod def static_def(int x): """ >>> A.static_def(2) ('def', 2) >>> A().static_def(2) ('def', 2) """ return 'def', x @staticmethod cdef static_cdef(int* x): return 'cdef', x[0] # @staticmethod # cpdef static_cpdef(int x): # """ # >>> A.static_def # >>> A.static_cpdef # # >>> A().static_def # >>> A().static_cpdef # # >>> A.static_cpdef(2) # ('cpdef', 2) # >>> A().static_cpdef(2) # ('cpdef', 2) # """ # return 'cpdef', x def call_static_def(int x): """ >>> call_static_def(2) ('def', 2) """ return A.static_def(x) def call_static_cdef(int x): """ >>> call_static_cdef(2) ('cdef', 2) """ cdef int *x_ptr = &x return A.static_cdef(x_ptr) # def call_static_cpdef(int x): # """ # >>> call_static_cpdef(2) # ('cpdef', 2) # """ # return A.static_cpdef(x) cdef class FromPxd: @staticmethod cdef static_cdef(int* x): return 'pxd_cdef', x[0] def call_static_pxd_cdef(int x): """ >>> call_static_pxd_cdef(2) ('pxd_cdef', 2) """ cdef int *x_ptr = &x return FromPxd.static_cdef(x_ptr) Cython-0.23.4/tests/run/static_methods.pxd0000644000175600017570000000010312606202452021673 0ustar jenkinsjenkins00000000000000cdef class FromPxd: @staticmethod cdef static_cdef(int* x) Cython-0.23.4/tests/run/starred_target_T664.pyx0000644000175600017570000000060012606202452022445 0ustar jenkinsjenkins00000000000000# ticket: 664 def assign(): """ >>> assign() (1, [2, 3, 4, 5]) """ a, *b = 1, 2, 3, 4, 5 return a, b def assign3(): """ >>> assign3() (1, [2, 3, 4, 5], 6) """ a, *b, c = 1, 2, 3, 4, 5, 6 return a, b, c def assign4(): """ >>> assign4() (1, [2, 3, 4], 5, 6) """ a, *b, c, d = 1, 2, 3, 4, 5, 6 return a, b, c, d Cython-0.23.4/tests/run/starimport_cimport.srctree0000644000175600017570000000147312606202452023511 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import star_cimport_test" ######## setup.py ######## from distutils.core import setup from Cython.Distutils import build_ext from Cython.Distutils.extension import Extension setup( ext_modules = [ Extension("star_cimport_ext", ["star_cimport_ext.pyx"]), Extension("star_cimport_test", ["star_cimport_test.pyx"]), ], cmdclass={'build_ext': build_ext}, ) ######## star_cimport_ext.pyx ######## cdef class test_pxd: pass ######## star_cimport_ext.pxd ######## cdef class test_pxd: pass ######## star_cimport.py ######## class test_py: pass ######## star_cimport_test.pyx ######## # Tests a Python star import followed by a cimport from star_cimport import * from star_cimport_ext cimport test_pxd cdef test_pxd t = test_pxd() Cython-0.23.4/tests/run/starargs.pyx0000644000175600017570000000577712606202452020562 0ustar jenkinsjenkins00000000000000cdef sorteditems(d): l = list(d.items()) l.sort() return tuple(l) def spam(x, y, z): """ >>> spam(1,2,3) (1, 2, 3) >>> spam(1,2) Traceback (most recent call last): TypeError: spam() takes exactly 3 positional arguments (2 given) >>> spam(1,2,3,4) Traceback (most recent call last): TypeError: spam() takes exactly 3 positional arguments (4 given) >>> spam(1,2,3, a=1) Traceback (most recent call last): TypeError: spam() got an unexpected keyword argument 'a' """ return (x, y, z) def grail(x, y, z, *a): """ >>> grail(1,2,3) (1, 2, 3, ()) >>> grail(1,2,3,4) (1, 2, 3, (4,)) >>> grail(1,2,3,4,5,6,7,8,9) (1, 2, 3, (4, 5, 6, 7, 8, 9)) >>> grail(1,2) Traceback (most recent call last): TypeError: grail() takes at least 3 positional arguments (2 given) >>> grail(1,2,3, a=1) Traceback (most recent call last): TypeError: grail() got an unexpected keyword argument 'a' """ return (x, y, z, a) def swallow(x, y, z, **k): """ >>> swallow(1,2,3) (1, 2, 3, ()) >>> swallow(1,2,3,4) Traceback (most recent call last): TypeError: swallow() takes exactly 3 positional arguments (4 given) >>> swallow(1,2,3, a=1, b=2) (1, 2, 3, (('a', 1), ('b', 2))) >>> swallow(1,2,3, x=1) Traceback (most recent call last): TypeError: swallow() got multiple values for keyword argument 'x' """ return (x, y, z, sorteditems(k)) def creosote(x, y, z, *a, **k): """ >>> creosote(1,2,3) (1, 2, 3, (), ()) >>> creosote(1,2,3,4) (1, 2, 3, (4,), ()) >>> creosote(1,2,3, a=1) (1, 2, 3, (), (('a', 1),)) >>> creosote(1,2,3,4, a=1, b=2) (1, 2, 3, (4,), (('a', 1), ('b', 2))) >>> creosote(1,2,3,4, x=1) Traceback (most recent call last): TypeError: creosote() got multiple values for keyword argument 'x' """ return (x, y, z, a, sorteditems(k)) def onlyt(*a): """ >>> onlyt(1) (1,) >>> onlyt(1,2) (1, 2) >>> onlyt(a=1) Traceback (most recent call last): TypeError: onlyt() got an unexpected keyword argument 'a' >>> onlyt(1, a=2) Traceback (most recent call last): TypeError: onlyt() got an unexpected keyword argument 'a' """ return a def onlyk(**k): """ >>> onlyk(a=1) (('a', 1),) >>> onlyk(a=1, b=2) (('a', 1), ('b', 2)) >>> onlyk(1) Traceback (most recent call last): TypeError: onlyk() takes exactly 0 positional arguments (1 given) >>> onlyk(1, 2) Traceback (most recent call last): TypeError: onlyk() takes exactly 0 positional arguments (2 given) >>> onlyk(1, a=1, b=2) Traceback (most recent call last): TypeError: onlyk() takes exactly 0 positional arguments (1 given) """ return sorteditems(k) def tk(*a, **k): """ >>> tk(a=1) (('a', 1),) >>> tk(a=1, b=2) (('a', 1), ('b', 2)) >>> tk(1) (1,) >>> tk(1, 2) (1, 2) >>> tk(1, a=1, b=2) (1, ('a', 1), ('b', 2)) """ return a + sorteditems(k) Cython-0.23.4/tests/run/ssize_t_T399.pyx0000644000175600017570000000234212606202452021125 0ustar jenkinsjenkins00000000000000# ticket: 399 __doc__ = u""" >>> test(-2) -2 >>> test(-1) -1 >>> test(0) 0 >>> test(1) 1 >>> test(2) 2 >>> test(SSIZE_T_MAX) == SSIZE_T_MAX True >>> test(SSIZE_T_MIN) == SSIZE_T_MIN True >>> test(SSIZE_T_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test(SSIZE_T_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test(1<<128) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test(-(1<<128)) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> a = A(1,2) >>> a.a == 1 True >>> a.b == 2 True >>> a.foo(5) 5 >>> a.foo(1 << 180) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef extern from *: ctypedef long ssize_t # XXX This should generate a warning !!! ssize_t PY_SSIZE_T_MAX ssize_t PY_SSIZE_T_MIN SSIZE_T_MAX = PY_SSIZE_T_MAX SSIZE_T_MIN = PY_SSIZE_T_MIN def test(ssize_t i): return i cdef class A: cdef public ssize_t a cdef readonly ssize_t b def __init__(self, ssize_t a, object b): self.a = a self.b = b cpdef ssize_t foo(self, ssize_t x): cdef object o = x return o Cython-0.23.4/tests/run/specialfloat.pyx0000644000175600017570000000542212606202452021365 0ustar jenkinsjenkins00000000000000DEF FLOAT = 12.5 DEF EMFLOAT = 5e-1 DEF EPFLOAT = 5e+1 DEF FLOAT_NAN = float('nan') DEF FLOAT_INFP = float('+inf') DEF FLOAT_INFN = float('-inf') cdef double cdef_float_nan = float('nan') cdef double cdef_float_infp = float('+inf') cdef double cdef_float_infn = float('-inf') float_nan = FLOAT_NAN float_infp = FLOAT_INFP float_infn = FLOAT_INFN def f(): """ >>> f() 12.5 """ cdef float f = FLOAT cdef object o = FLOAT assert f == o return f def emfloat(): """ >>> emfloat() 0.5 """ cdef float f = EMFLOAT assert f == 5e-1 cdef object o = EMFLOAT assert o == 5e-1 assert f == o return f def epfloat(): """ >>> epfloat() 50.0 """ cdef float f = EPFLOAT assert f == 5e+1 cdef object o = EPFLOAT assert o == 5e+1 assert f == o return f def nan1(): """ >>> nan1() nan """ cdef double f = FLOAT_NAN cdef object o = FLOAT_NAN assert str(f) == str(o) return f def nan2(): """ >>> nan2() nan """ cdef double f = float('nan') cdef object o = float('nan') assert str(f) == str(o) return f def nan3(): """ >>> nan3() nan >>> float_nan nan """ cdef float f = FLOAT_NAN cdef object o = FLOAT_NAN assert str(f) == str(o) return f def infp1(): """ >>> infp1() inf >>> infp1() == float('inf') True """ cdef double f = FLOAT_INFP cdef object o = FLOAT_INFP assert f == o return f def infp2(): """ >>> infp2() inf >>> infp2() == float('inf') True """ cdef double f = float('+inf') cdef object o = float('+inf') assert f == o return f def infp3(): """ >>> infp3() inf >>> infp3() == float('inf') True >>> float_infp inf >>> float_infp == float('inf') True """ cdef float f = FLOAT_INFP cdef object o = FLOAT_INFP assert f == o return f def infn1(): """ >>> infn1() -inf >>> infn1() == float('-inf') True """ cdef double f = FLOAT_INFN cdef object o = FLOAT_INFN assert f == o return f def infn2(): """ >>> infn2() -inf >>> infn2() == float('-inf') True """ cdef double f = float('-inf') cdef object o = float('-inf') assert f == o return f def infn3(): """ >>> infn3() -inf >>> infn3() == float('-inf') True >>> float_infn -inf >>> float_infn == float('-inf') True """ cdef float f = FLOAT_INFN cdef object o = FLOAT_INFN assert f == o return f def global_floats(): """ >>> global_floats()[1:] == (float('+inf'), float('-inf')) True >>> global_floats()[0] nan """ return (cdef_float_nan, cdef_float_infp, cdef_float_infn) Cython-0.23.4/tests/run/special_methods_T561_py3.pyx0000644000175600017570000000554212606202452023377 0ustar jenkinsjenkins00000000000000# ticket: 561 # tag: py3 # This file tests the behavior of special methods under Python 3 # after #561. (Only methods whose behavior differs between Python 2 and 3 # are tested here; see special_methods_T561.pyx for the rest of the tests.) __doc__ = u""" >>> vs0 = VerySpecial(0) VS __init__ 0 >>> # Python 3 does not use __cmp__, so any provided __cmp__ method is >>> # discarded under Python 3. >>> vs0_cmp = vs0.__cmp__ Traceback (most recent call last): ... AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__cmp__' >>> # Python 3 does not use __div__ or __idiv__, so these methods are >>> # discarded under Python 3. >>> vs0_div = vs0.__div__ Traceback (most recent call last): ... AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__div__' >>> vs0_rdiv = vs0.__rdiv__ Traceback (most recent call last): ... AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__rdiv__' >>> vs0_idiv = vs0.__idiv__ Traceback (most recent call last): ... AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__idiv__' >>> # Python 3 does not use __oct__ or __hex__, so these methods are >>> # discarded under Python 3. >>> vs0_oct = vs0.__oct__ Traceback (most recent call last): ... AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__oct__' >>> vs0_hex = vs0.__hex__ Traceback (most recent call last): ... AttributeError: 'special_methods_T561_py3.VerySpecial' object has no attribute '__hex__' >>> # Python 3 does not use __long__; if you define __long__ but not >>> # __int__, the __long__ definition will be used for __int__. >>> Ll = Long().__long__ Traceback (most recent call last): ... AttributeError: 'special_methods_T561_py3.Long' object has no attribute '__long__' >>> Li = Long().__int__ >>> Li() Long __long__ >>> # As of Python 3, defining __nonzero__ gives you a __bool__ method >>> # instead. >>> vs0_bool = vs0.__bool__ >>> vs0_bool() VS __nonzero__ 0 False """ cdef class VerySpecial: cdef readonly int value def __init__(self, v): self.value = v print "VS __init__ %d" % self.value def __nonzero__(self): print "VS __nonzero__ %d" % self.value def __oct__(self): print "VS __oct__ %d" % self.value def __hex__(self): print "VS __hex__ %d" % self.value def __cmp__(self, other): print "VS __cmp__ %d %d" % (self.value, other.value) def __div__(self, other): print "VS __div__ %d %d" % (self.value, other.value) def __idiv__(self, other): print "VS __idiv__ %d /= %d" % (self.value, other.value) cdef class Long: def __long__(self): print "Long __long__" Cython-0.23.4/tests/run/special_methods_T561_py2.pyx0000644000175600017570000001007712606202452023375 0ustar jenkinsjenkins00000000000000# ticket: 561 # tag: py2 # This file tests the behavior of special methods under Python 2 # after #561. (Only methods whose behavior differs between Python 2 and 3 # are tested here; see special_methods_T561.pyx for the rest of the tests.) __doc__ = u""" >>> vs0 = VerySpecial(0) VS __init__ 0 >>> vs1 = VerySpecial(1) VS __init__ 1 >>> # Python 3 does not use __cmp__. >>> vs0_cmp = vs0.__cmp__ >>> vs0_cmp(vs1) VS __cmp__ 0 1 0 >>> # Python 3 does not use __div__ or __idiv__. >>> vs0_div = vs0.__div__ >>> vs0_div(vs1) VS __div__ 0 1 >>> vs0_idiv = vs0.__idiv__ >>> vs0_idiv(vs1) VS __idiv__ 0 /= 1 >>> vs0_rdiv = vs0.__rdiv__ >>> vs0_rdiv(vs1) VS __div__ 1 0 >>> # Python 3 does not use __oct__ or __hex__. >>> vs0_oct = vs0.__oct__ >>> vs0_oct() VS __oct__ 0 >>> vs0_hex = vs0.__hex__ >>> vs0_hex() VS __hex__ 0 >>> # Python 3 does not use __nonzero__; if you define a __nonzero__ >>> # method, Cython for Python 3 would give you a __bool__ method >>> # instead. >>> vs0_nonzero = vs0.__nonzero__ >>> vs0_nonzero() VS __nonzero__ 0 False >>> # If you define __next__, you get both __next__ and next (this behavior >>> # is unchanged by T561, but only happens in Python 2) >>> vs0_next = vs0.__next__ >>> vs0_next() VS next/__next__ 0 >>> vs0_next2 = vs0.next >>> vs0_next2() VS next/__next__ 0 >>> # Cython supports getslice only for Python 2. >>> vs0_getslice = vs0.__getslice__ >>> vs0_getslice(13, 42) VS __getslice__ 0 13 42 >>> # Cython supports setslice and delslice only for Python 2. >>> # If you define either setslice or delslice, you get wrapper objects >>> # for both methods. (This behavior is unchanged by #561.) >>> ss_setslice = SetSlice().__setslice__ >>> ss_setslice(13, 42, 'foo') SetSlice setslice 13 42 'foo' >>> ss_delslice = SetSlice().__delslice__ >>> ss_delslice(13, 42) Traceback (most recent call last): ... NotImplementedError: 2-element slice deletion not supported by special_methods_T561_py2.SetSlice >>> ds_setslice = DelSlice().__setslice__ >>> ds_setslice(13, 42, 'foo') Traceback (most recent call last): ... NotImplementedError: 2-element slice assignment not supported by special_methods_T561_py2.DelSlice >>> ds_delslice = DelSlice().__delslice__ >>> ds_delslice(13, 42) DelSlice delslice 13 42 >>> sds_setslice = SetDelSlice().__setslice__ >>> sds_setslice(13, 42, 'foo') SetDelSlice setslice 13 42 'foo' >>> sds_delslice = SetDelSlice().__delslice__ >>> sds_delslice(13, 42) SetDelSlice delslice 13 42 >>> # Python 3 does not use __long__. >>> Ll = Long().__long__ >>> Ll() Long __long__ """ cdef class VerySpecial: cdef readonly int value def __init__(self, v): self.value = v print "VS __init__ %d" % self.value def __getslice__(self, a, b): print "VS __getslice__ %d %d %d" % (self.value, a, b) def __next__(self): print "VS next/__next__ %d" % self.value def __nonzero__(self): print "VS __nonzero__ %d" % self.value def __oct__(self): print "VS __oct__ %d" % self.value def __hex__(self): print "VS __hex__ %d" % self.value def __cmp__(self, other): print "VS __cmp__ %d %d" % (self.value, other.value) def __div__(self, other): print "VS __div__ %d %d" % (self.value, other.value) def __idiv__(self, other): print "VS __idiv__ %d /= %d" % (self.value, other.value) cdef class SetSlice: def __setslice__(self, a, b, value): print "SetSlice setslice %d %d %r" % (a, b, value) cdef class DelSlice: def __delslice__(self, a, b): print "DelSlice delslice %d %d" % (a, b) cdef class SetDelSlice: def __setslice__(self, a, b, value): print "SetDelSlice setslice %d %d %r" % (a, b, value) def __delslice__(self, a, b): print "SetDelSlice delslice %d %d" % (a, b) cdef class Long: def __long__(self): print "Long __long__" Cython-0.23.4/tests/run/special_methods_T561.pyx0000644000175600017570000006231612606202452022606 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 561 # ticket: 3 # The patch in #561 changes code generation for most special methods # to remove the Cython-generated wrapper and let PyType_Ready() # generate its own wrapper. (This wrapper would be used, for instance, # when using the special method as a bound method.) # To test this, we go through and verify that each affected special # method works as a bound method. # Special methods that are treated the same under Python 2 and 3 are # tested here; see also special_methods_T561_py2.pyx and # special_methods_T561_py3.pyx for tests of the differences between # Python 2 and 3. # Regarding ticket 3, we should additionally test that unbound method # calls to these special methods (e.g. ExtType.__init__()) do not use # a runtime lookup indirection. import sys __doc__ = u""" >>> # If you define either setitem or delitem, you get wrapper objects >>> # for both methods. (This behavior is unchanged by #561.) >>> si_setitem = SetItem().__setitem__ >>> si_setitem('foo', 'bar') SetItem setitem 'foo' 'bar' >>> si_delitem = SetItem().__delitem__ >>> si_delitem('foo') Traceback (most recent call last): ... NotImplementedError: Subscript deletion not supported by special_methods_T561.SetItem >>> di_setitem = DelItem().__setitem__ >>> di_setitem('foo', 'bar') Traceback (most recent call last): ... NotImplementedError: Subscript assignment not supported by special_methods_T561.DelItem >>> di_delitem = DelItem().__delitem__ >>> di_delitem('foo') DelItem delitem 'foo' >>> sdi_setitem = SetDelItem().__setitem__ >>> sdi_setitem('foo', 'bar') SetDelItem setitem 'foo' 'bar' >>> sdi_delitem = SetDelItem().__delitem__ >>> sdi_delitem('foo') SetDelItem delitem 'foo' >>> g01 = object.__getattribute__(GetAttr(), '__getattribute__') >>> g01('attr') GetAttr getattr 'attr' >>> g10 = object.__getattribute__(GetAttribute(), '__getattr__') Traceback (most recent call last): ... AttributeError: 'special_methods_T561.GetAttribute' object has no attribute '__getattr__' >>> g11 = object.__getattribute__(GetAttribute(), '__getattribute__') >>> g11('attr') GetAttribute getattribute 'attr' >>> # If you define either setattr or delattr, you get wrapper objects >>> # for both methods. (This behavior is unchanged by #561.) >>> sa_setattr = SetAttr().__setattr__ >>> sa_setattr('foo', 'bar') SetAttr setattr 'foo' 'bar' >>> sa_delattr = SetAttr().__delattr__ >>> sa_delattr('foo') Traceback (most recent call last): ... AttributeError: 'special_methods_T561.SetAttr' object has no attribute 'foo' >>> da_setattr = DelAttr().__setattr__ >>> da_setattr('foo', 'bar') Traceback (most recent call last): ... AttributeError: 'special_methods_T561.DelAttr' object has no attribute 'foo' >>> da_delattr = DelAttr().__delattr__ >>> da_delattr('foo') DelAttr delattr 'foo' >>> sda_setattr = SetDelAttr().__setattr__ >>> sda_setattr('foo', 'bar') SetDelAttr setattr 'foo' 'bar' >>> sda_delattr = SetDelAttr().__delattr__ >>> sda_delattr('foo') SetDelAttr delattr 'foo' >>> # If you define either set or delete, you get wrapper objects >>> # for both methods. (This behavior is unchanged by #561.) >>> s_set = Set().__set__ >>> s_set('instance', 'val') Set set 'instance' 'val' >>> s_delete = Set().__delete__ >>> s_delete('instance') Traceback (most recent call last): ... NotImplementedError: __delete__ >>> d_set = Delete().__set__ >>> d_set('instance', 'val') Traceback (most recent call last): ... NotImplementedError: __set__ >>> d_delete = Delete().__delete__ >>> d_delete('instance') Delete delete 'instance' >>> sd_set = SetDelete().__set__ >>> sd_set('instance', 'val') SetDelete set 'instance' 'val' >>> sd_delete = SetDelete().__delete__ >>> sd_delete('instance') SetDelete delete 'instance' >>> # If you define __long__, you get a wrapper object for __int__. >>> # (This behavior is unchanged by #561.) >>> Li = Long().__int__ >>> Li() Long __long__ """ if sys.version_info >= (2,5): __doc__ += u"""\ >>> vs0 = VerySpecial(0) VS __init__ 0 >>> vs0_index = vs0.__index__ >>> vs0_index() VS __index__ 0 """ cdef class VerySpecial: """ >>> vs0 = VerySpecial(0) VS __init__ 0 >>> vs1 = VerySpecial(1) VS __init__ 1 >>> vs0_add = vs0.__add__ >>> vs0_add(vs1) VS __add__ 0 1 >>> vs0_sub = vs0.__sub__ >>> vs0_sub(vs1) VS __sub__ 0 1 >>> vs0_mul = vs0.__mul__ >>> vs0_mul(vs1) VS __mul__ 0 1 >>> vs0_mod = vs0.__mod__ >>> vs0_mod(vs1) VS __mod__ 0 1 >>> vs0_divmod = vs0.__divmod__ >>> vs0_divmod(vs1) VS __divmod__ 0 1 >>> vs0_pow = vs0.__pow__ >>> vs0_pow(vs1) VS __pow__ pow(0, 1, None) >>> vs0_pow(vs1, 13) VS __pow__ pow(0, 1, 13) >>> vs0_neg = vs0.__neg__ >>> vs0_neg() VS __neg__ 0 >>> vs0_pos = vs0.__pos__ >>> vs0_pos() VS __pos__ 0 >>> vs0_abs = vs0.__abs__ >>> vs0_abs() VS __abs__ 0 >>> vs0_invert = vs0.__invert__ >>> vs0_invert() VS __invert__ 0 >>> vs0_lshift = vs0.__lshift__ >>> vs0_lshift(vs1) VS __lshift__ 0 << 1 >>> vs0_rshift = vs0.__rshift__ >>> vs0_rshift(vs1) VS __rshift__ 0 >> 1 >>> vs0_and = vs0.__and__ >>> vs0_and(vs1) VS __and__ 0 & 1 >>> vs0_xor = vs0.__xor__ >>> vs0_xor(vs1) VS __xor__ 0 ^ 1 >>> vs0_or = vs0.__or__ >>> vs0_or(vs1) VS __or__ 0 | 1 >>> vs0_int = vs0.__int__ >>> vs0_int() VS __int__ 0 >>> vs0_float = vs0.__float__ >>> vs0_float() VS __float__ 0 >>> vs0_iadd = vs0.__iadd__ >>> vs0_iadd(vs1) VS __iadd__ 0 += 1 >>> vs0_isub = vs0.__isub__ >>> vs0_isub(vs1) VS __isub__ 0 -= 1 >>> vs0_imul = vs0.__imul__ >>> vs0_imul(vs1) VS __imul__ 0 *= 1 >>> vs0_imod = vs0.__imod__ >>> vs0_imod(vs1) VS __imod__ 0 %= 1 >>> vs0_ipow = vs0.__ipow__ >>> vs0_ipow(vs1) VS __ipow__ 0 1 >>> vs0_ilshift = vs0.__ilshift__ >>> vs0_ilshift(vs1) VS __ilshift__ 0 <<= 1 >>> vs0_irshift = vs0.__irshift__ >>> vs0_irshift(vs1) VS __irshift__ 0 >>= 1 >>> vs0_iand = vs0.__iand__ >>> vs0_iand(vs1) VS __iand__ 0 &= 1 >>> vs0_ixor = vs0.__ixor__ >>> vs0_ixor(vs1) VS __ixor__ 0 ^= 1 >>> vs0_ior = vs0.__ior__ >>> vs0_ior(vs1) VS __ior__ 0 |= 1 >>> vs0_floordiv = vs0.__floordiv__ >>> vs0_floordiv(vs1) VS __floordiv__ 0 / 1 >>> vs0_truediv = vs0.__truediv__ >>> vs0_truediv(vs1) VS __truediv__ 0 / 1 >>> vs0_ifloordiv = vs0.__ifloordiv__ >>> vs0_ifloordiv(vs1) VS __ifloordiv__ 0 /= 1 >>> vs0_itruediv = vs0.__itruediv__ >>> vs0_itruediv(vs1) VS __itruediv__ 0 /= 1 # If you define an arithmetic method, you get wrapper objects for # the reversed version as well. (This behavior is unchanged by #561.) >>> vs0_radd = vs0.__radd__ >>> vs0_radd(vs1) VS __add__ 1 0 >>> vs0_rsub = vs0.__rsub__ >>> vs0_rsub(vs1) VS __sub__ 1 0 >>> vs0_rmul = vs0.__rmul__ >>> vs0_rmul(vs1) VS __mul__ 1 0 >>> vs0_rmod = vs0.__rmod__ >>> vs0_rmod(vs1) VS __mod__ 1 0 >>> vs0_rdivmod = vs0.__rdivmod__ >>> vs0_rdivmod(vs1) VS __divmod__ 1 0 >>> vs0_rpow = vs0.__rpow__ >>> vs0_rpow(vs1) VS __pow__ pow(1, 0, None) >>> vs0_rlshift = vs0.__rlshift__ >>> vs0_rlshift(vs1) VS __lshift__ 1 << 0 >>> vs0_rrshift = vs0.__rrshift__ >>> vs0_rrshift(vs1) VS __rshift__ 1 >> 0 >>> vs0_rand = vs0.__rand__ >>> vs0_rand(vs1) VS __and__ 1 & 0 >>> vs0_rxor = vs0.__rxor__ >>> vs0_rxor(vs1) VS __xor__ 1 ^ 0 >>> vs0_ror = vs0.__ror__ >>> vs0_ror(vs1) VS __or__ 1 | 0 >>> vs0_rfloordiv = vs0.__rfloordiv__ >>> vs0_rfloordiv(vs1) VS __floordiv__ 1 / 0 >>> vs0_rtruediv = vs0.__rtruediv__ >>> vs0_rtruediv(vs1) VS __truediv__ 1 / 0 >>> vs0_getitem = vs0.__getitem__ >>> vs0_getitem('foo') VS __getitem__ 0['foo'] >>> vs0_contains = vs0.__contains__ >>> vs0_contains(vs1) VS __contains__ 0 1 False >>> vs0_len = vs0.__len__ >>> vs0_len() VS __len__ 0 0 >>> vs0_repr = vs0.__repr__ >>> vs0_repr() VS __repr__ 0 >>> vs0_hash = vs0.__hash__ >>> vs0_hash() VS __hash__ 0 1000 >>> vs0_call = vs0.__call__ >>> vs0_call(vs1) VS __call__ 0(1) >>> vs0_str = vs0.__str__ >>> vs0_str() VS __str__ 0 # If you define __richcmp__, you get all of __lt__, __le__, # __eq__, __ne__, __gt__, __ge__ (this behavior is unchanged by #561). # (you don't get a __richcmp__ method, because it doesn't have a # Python signature) >>> vs0_lt = vs0.__lt__ >>> vs0_lt(vs1) VS richcmp 0 1 (kind=0) >>> vs0_le = vs0.__le__ >>> vs0_le(vs1) VS richcmp 0 1 (kind=1) >>> vs0_eq = vs0.__eq__ >>> vs0_eq(vs1) VS richcmp 0 1 (kind=2) >>> vs0_ne = vs0.__ne__ >>> vs0_ne(vs1) VS richcmp 0 1 (kind=3) >>> vs0_gt = vs0.__gt__ >>> vs0_gt(vs1) VS richcmp 0 1 (kind=4) >>> vs0_ge = vs0.__ge__ >>> vs0_ge(vs1) VS richcmp 0 1 (kind=5) >>> vs0_iter = vs0.__iter__ >>> vs0_iter() VS __iter__ 0 >>> vs0_next = vs0.__next__ >>> vs0_next() VS next/__next__ 0 >>> vs0_get = vs0.__get__ >>> vs0_get('instance', 'owner') VS __get__ 0 'instance' 'owner' >>> vs0_init = vs0.__init__ >>> vs0_init(0) VS __init__ 0 """ cdef readonly int value def __init__(self, v): self.value = v print "VS __init__ %d" % self.value def __add__(self, other): print "VS __add__ %d %d" % (self.value, other.value) def __sub__(self, other): print "VS __sub__ %d %d" % (self.value, other.value) def __mul__(self, other): print "VS __mul__ %d %d" % (self.value, other.value) def __div__(self, other): print "VS __div__ %d %d" % (self.value, other.value) def __mod__(self, other): print "VS __mod__ %d %d" % (self.value, other.value) def __divmod__(self, other): print "VS __divmod__ %d %d" % (self.value, other.value) def __pow__(self, other, mod): print "VS __pow__ pow(%d, %d, %r)" % (self.value, other.value, mod) def __lshift__(self, other): print "VS __lshift__ %d << %d" % (self.value, other.value) def __rshift__(self, other): print "VS __rshift__ %d >> %d" % (self.value, other.value) def __and__(self, other): print "VS __and__ %d & %d" % (self.value, other.value) def __xor__(self, other): print "VS __xor__ %d ^ %d" % (self.value, other.value) def __or__(self, other): print "VS __or__ %d | %d" % (self.value, other.value) def __floordiv__(self, other): print "VS __floordiv__ %d / %d" % (self.value, other.value) def __truediv__(self, other): print "VS __truediv__ %d / %d" % (self.value, other.value) def __neg__(self): print "VS __neg__ %d" % self.value def __pos__(self): print "VS __pos__ %d" % self.value def __abs__(self): print "VS __abs__ %d" % self.value def __nonzero__(self): print "VS __nonzero__ %d" % self.value def __invert__(self): print "VS __invert__ %d" % self.value def __int__(self): print "VS __int__ %d" % self.value def __long__(self): print "VS __long__ %d" % self.value def __float__(self): print "VS __float__ %d" % self.value def __oct__(self): print "VS __oct__ %d" % self.value def __hex__(self): print "VS __hex__ %d" % self.value def __iadd__(self, other): print "VS __iadd__ %d += %d" % (self.value, other.value) def __isub__(self, other): print "VS __isub__ %d -= %d" % (self.value, other.value) def __imul__(self, other): print "VS __imul__ %d *= %d" % (self.value, other.value) def __idiv__(self, other): print "VS __idiv__ %d /= %d" % (self.value, other.value) def __imod__(self, other): print "VS __imod__ %d %%= %d" % (self.value, other.value) def __ipow__(self, other): # We must declare mod as an argument, but we must not touch it # or we'll get a segfault. See #562 print "VS __ipow__ %d %d" % (self.value, other.value) def __ilshift__(self, other): print "VS __ilshift__ %d <<= %d" % (self.value, other.value) def __irshift__(self, other): print "VS __irshift__ %d >>= %d" % (self.value, other.value) def __iand__(self, other): print "VS __iand__ %d &= %d" % (self.value, other.value) def __ixor__(self, other): print "VS __ixor__ %d ^= %d" % (self.value, other.value) def __ior__(self, other): print "VS __ior__ %d |= %d" % (self.value, other.value) def __ifloordiv__(self, other): print "VS __ifloordiv__ %d /= %d" % (self.value, other.value) def __itruediv__(self, other): print "VS __itruediv__ %d /= %d" % (self.value, other.value) def __index__(self): print "VS __index__ %d" % self.value def __getitem__(self, index): print "VS __getitem__ %d[%r]" % (self.value, index) def __contains__(self, other): print "VS __contains__ %d %d" % (self.value, other.value) def __len__(self): print "VS __len__ %d" % (self.value) def __cmp__(self, other): print "VS __cmp__ %d %d" % (self.value, other.value) def __repr__(self): print "VS __repr__ %d" % self.value def __hash__(self): print "VS __hash__ %d" % self.value return self.value + 1000 def __call__(self, other): print "VS __call__ %d(%d)" % (self.value, other.value) def __str__(self): print "VS __str__ %d" % self.value def __richcmp__(self, other, kind): print "VS richcmp %d %d (kind=%r)" % (self.value, other.value, kind) def __iter__(self): print "VS __iter__ %d" % self.value def __next__(self): print "VS next/__next__ %d" % self.value def __get__(self, inst, own): print "VS __get__ %d %r %r" % (self.value, inst, own) cdef class SetItem: def __setitem__(self, index, value): print "SetItem setitem %r %r" % (index, value) cdef class DelItem: def __delitem__(self, index): print "DelItem delitem %r" % index cdef class SetDelItem: def __setitem__(self, index, value): print "SetDelItem setitem %r %r" % (index, value) def __delitem__(self, index): print "SetDelItem delitem %r" % index cdef class GetAttr: def __getattr__(self, attr): print "GetAttr getattr %r" % attr cdef class GetAttribute: def __getattribute__(self, attr): print "GetAttribute getattribute %r" % attr cdef class SetAttr: def __setattr__(self, attr, val): print "SetAttr setattr %r %r" % (attr, val) cdef class DelAttr: def __delattr__(self, attr): print "DelAttr delattr %r" % attr cdef class SetDelAttr: def __setattr__(self, attr, val): print "SetDelAttr setattr %r %r" % (attr, val) def __delattr__(self, attr): print "SetDelAttr delattr %r" % attr cdef class Set: def __set__(self, inst, val): print "Set set %r %r" % (inst, val) cdef class Delete: def __delete__(self, inst): print "Delete delete %r" % inst cdef class SetDelete: def __set__(self, inst, val): print "SetDelete set %r %r" % (inst, val) def __delete__(self, inst): print "SetDelete delete %r" % inst cdef class Long: def __long__(self): print "Long __long__" cdef class GetAttrGetItemRedirect: """ >>> o = GetAttrGetItemRedirect() >>> assert o.item == o['item'] >>> source, item_value = o.item >>> assert source == 'item', source >>> assert o['attr'] == o.attr >>> source, attr_value = o['attr'] >>> assert source == 'attr', source >>> assert item_value is attr_value, repr((item_value, attr_value)) """ cdef object obj def __cinit__(self): self.obj = object() def __getattr__(self, name): if name == 'item': return self[name] return ('attr', self.obj) def __getitem__(self, key): if key == 'attr': return getattr(self, key) return ('item', self.obj) # test unbound method usage in subtypes cdef class VerySpecialSubType(VerySpecial): """ >>> vs0 = VerySpecialSubType(0) VS __init__ 0 >>> vs1 = VerySpecialSubType(1) VS __init__ 1 >>> vs0_add = vs0.__add__ >>> vs0_add(vs1) VS __add__ 0 1 >>> vs0_sub = vs0.__sub__ >>> vs0_sub(vs1) VS __sub__ 0 1 >>> vs0_mul = vs0.__mul__ >>> vs0_mul(vs1) VS __mul__ 0 1 >>> vs0_mod = vs0.__mod__ >>> vs0_mod(vs1) VS __mod__ 0 1 >>> vs0_divmod = vs0.__divmod__ >>> vs0_divmod(vs1) VS __divmod__ 0 1 >>> vs0_pow = vs0.__pow__ >>> vs0_pow(vs1) VS __pow__ pow(0, 1, None) >>> vs0_pow(vs1, 13) VS __pow__ pow(0, 1, 13) >>> vs0_neg = vs0.__neg__ >>> vs0_neg() VS __neg__ 0 >>> vs0_pos = vs0.__pos__ >>> vs0_pos() VS __pos__ 0 >>> vs0_abs = vs0.__abs__ >>> vs0_abs() VS __abs__ 0 >>> vs0_invert = vs0.__invert__ >>> vs0_invert() VS __invert__ 0 >>> vs0_lshift = vs0.__lshift__ >>> vs0_lshift(vs1) VS __lshift__ 0 << 1 >>> vs0_rshift = vs0.__rshift__ >>> vs0_rshift(vs1) VS __rshift__ 0 >> 1 >>> vs0_and = vs0.__and__ >>> vs0_and(vs1) VS __and__ 0 & 1 >>> vs0_xor = vs0.__xor__ >>> vs0_xor(vs1) VS __xor__ 0 ^ 1 >>> vs0_or = vs0.__or__ >>> vs0_or(vs1) VS __or__ 0 | 1 >>> vs0_int = vs0.__int__ >>> vs0_int() VS __int__ 0 >>> vs0_float = vs0.__float__ >>> vs0_float() VS __float__ 0 >>> vs0_iadd = vs0.__iadd__ >>> vs0_iadd(vs1) VS __iadd__ 0 += 1 >>> vs0_isub = vs0.__isub__ >>> vs0_isub(vs1) VS __isub__ 0 -= 1 >>> vs0_imul = vs0.__imul__ >>> vs0_imul(vs1) VS __imul__ 0 *= 1 >>> vs0_imod = vs0.__imod__ >>> vs0_imod(vs1) VS __imod__ 0 %= 1 >>> vs0_ipow = vs0.__ipow__ >>> vs0_ipow(vs1) VS __ipow__ 0 1 >>> vs0_ilshift = vs0.__ilshift__ >>> vs0_ilshift(vs1) VS __ilshift__ 0 <<= 1 >>> vs0_irshift = vs0.__irshift__ >>> vs0_irshift(vs1) VS __irshift__ 0 >>= 1 >>> vs0_iand = vs0.__iand__ >>> vs0_iand(vs1) VS __iand__ 0 &= 1 >>> vs0_ixor = vs0.__ixor__ >>> vs0_ixor(vs1) VS __ixor__ 0 ^= 1 >>> vs0_ior = vs0.__ior__ >>> vs0_ior(vs1) VS __ior__ 0 |= 1 >>> vs0_floordiv = vs0.__floordiv__ >>> vs0_floordiv(vs1) VS __floordiv__ 0 / 1 >>> vs0_truediv = vs0.__truediv__ >>> vs0_truediv(vs1) VS __truediv__ 0 / 1 >>> vs0_ifloordiv = vs0.__ifloordiv__ >>> vs0_ifloordiv(vs1) VS __ifloordiv__ 0 /= 1 >>> vs0_itruediv = vs0.__itruediv__ >>> vs0_itruediv(vs1) VS __itruediv__ 0 /= 1 # If you define an arithmetic method, you get wrapper objects for # the reversed version as well. (This behavior is unchanged by #561.) >>> vs0_radd = vs0.__radd__ >>> vs0_radd(vs1) VS __add__ 1 0 >>> vs0_rsub = vs0.__rsub__ >>> vs0_rsub(vs1) VS __sub__ 1 0 >>> vs0_rmul = vs0.__rmul__ >>> vs0_rmul(vs1) VS __mul__ 1 0 >>> vs0_rmod = vs0.__rmod__ >>> vs0_rmod(vs1) VS __mod__ 1 0 >>> vs0_rdivmod = vs0.__rdivmod__ >>> vs0_rdivmod(vs1) VS __divmod__ 1 0 >>> vs0_rpow = vs0.__rpow__ >>> vs0_rpow(vs1) VS __pow__ pow(1, 0, None) >>> vs0_rlshift = vs0.__rlshift__ >>> vs0_rlshift(vs1) VS __lshift__ 1 << 0 >>> vs0_rrshift = vs0.__rrshift__ >>> vs0_rrshift(vs1) VS __rshift__ 1 >> 0 >>> vs0_rand = vs0.__rand__ >>> vs0_rand(vs1) VS __and__ 1 & 0 >>> vs0_rxor = vs0.__rxor__ >>> vs0_rxor(vs1) VS __xor__ 1 ^ 0 >>> vs0_ror = vs0.__ror__ >>> vs0_ror(vs1) VS __or__ 1 | 0 >>> vs0_rfloordiv = vs0.__rfloordiv__ >>> vs0_rfloordiv(vs1) VS __floordiv__ 1 / 0 >>> vs0_rtruediv = vs0.__rtruediv__ >>> vs0_rtruediv(vs1) VS __truediv__ 1 / 0 >>> vs0_getitem = vs0.__getitem__ >>> vs0_getitem('foo') VS __getitem__ 0['foo'] >>> vs0_contains = vs0.__contains__ >>> vs0_contains(vs1) VS __contains__ 0 1 False >>> vs0_len = vs0.__len__ >>> vs0_len() VS __len__ 0 0 >>> vs0_repr = vs0.__repr__ >>> vs0_repr() VS __repr__ 0 >>> vs0_hash = vs0.__hash__ >>> vs0_hash() VS __hash__ 0 1000 >>> vs0_call = vs0.__call__ >>> vs0_call(vs1) VS __call__ 0(1) >>> vs0_str = vs0.__str__ >>> vs0_str() VS __str__ 0 >>> vs0_lt = vs0.__lt__ >>> vs0_lt(vs1) VS richcmp 0 1 (kind=0) >>> vs0_le = vs0.__le__ >>> vs0_le(vs1) VS richcmp 0 1 (kind=1) >>> vs0_eq = vs0.__eq__ >>> vs0_eq(vs1) VS richcmp 0 1 (kind=2) >>> vs0_ne = vs0.__ne__ >>> vs0_ne(vs1) VS richcmp 0 1 (kind=3) >>> vs0_gt = vs0.__gt__ >>> vs0_gt(vs1) VS richcmp 0 1 (kind=4) >>> vs0_ge = vs0.__ge__ >>> vs0_ge(vs1) VS richcmp 0 1 (kind=5) >>> vs0_iter = vs0.__iter__ >>> vs0_iter() VS __iter__ 0 >>> vs0_next = vs0.__next__ >>> vs0_next() VS next/__next__ 0 >>> vs0_get = vs0.__get__ >>> vs0_get('instance', 'owner') VS __get__ 0 'instance' 'owner' >>> vs0_init = vs0.__init__ >>> vs0_init(0) VS __init__ 0 """ def __init__(self, v): VerySpecial.__init__(self, v) def __add__(self, other): return VerySpecial.__add__(self, other) def __sub__(self, other): return VerySpecial.__sub__(self, other) def __mul__(self, other): return VerySpecial.__mul__(self, other) def __div__(self, other): return VerySpecial.__div__(self, other) def __mod__(self, other): return VerySpecial.__mod__(self, other) def __divmod__(self, other): return VerySpecial.__divmod__(self, other) def __pow__(self, other, mod): return VerySpecial.__pow__(self, other, mod) def __lshift__(self, other): return VerySpecial.__lshift__(self, other) def __rshift__(self, other): return VerySpecial.__rshift__(self, other) def __and__(self, other): return VerySpecial.__and__(self, other) def __xor__(self, other): return VerySpecial.__xor__(self, other) def __or__(self, other): return VerySpecial.__or__(self, other) def __floordiv__(self, other): return VerySpecial.__floordiv__(self, other) def __truediv__(self, other): return VerySpecial.__truediv__(self, other) def __neg__(self): return VerySpecial.__neg__(self) def __pos__(self): return VerySpecial.__pos__(self) def __abs__(self): return VerySpecial.__abs__(self) def __nonzero__(self): return VerySpecial.__nonzero__(self) def __invert__(self): return VerySpecial.__invert__(self) def __int__(self): return VerySpecial.__int__(self) def __long__(self): return VerySpecial.__long__(self) def __float__(self): return VerySpecial.__float__(self) def __oct__(self): return VerySpecial.__oct__(self) def __hex__(self): return VerySpecial.__hex__(self) def __iadd__(self, other): return VerySpecial.__iadd__(self, other) def __isub__(self, other): return VerySpecial.__isub__(self, other) def __imul__(self, other): return VerySpecial.__imul__(self, other) def __idiv__(self, other): return VerySpecial.__idiv__(self, other) def __imod__(self, other): return VerySpecial.__imod__(self, other) def __ipow__(self, other): return VerySpecial.__ipow__(self, other) def __ilshift__(self, other): return VerySpecial.__ilshift__(self, other) def __irshift__(self, other): return VerySpecial.__irshift__(self, other) def __iand__(self, other): return VerySpecial.__iand__(self, other) def __ixor__(self, other): return VerySpecial.__ixor__(self, other) def __ior__(self, other): return VerySpecial.__ior__(self, other) def __ifloordiv__(self, other): return VerySpecial.__ifloordiv__(self, other) def __itruediv__(self, other): return VerySpecial.__itruediv__(self, other) def __index__(self): return VerySpecial.__index__(self) def __getitem__(self, index): return VerySpecial.__getitem__(self, index) def __contains__(self, other): return VerySpecial.__contains__(self, other) def __len__(self): return VerySpecial.__len__(self) def __cmp__(self, other): return VerySpecial.__cmp__(self, other) def __repr__(self): return VerySpecial.__repr__(self) def __hash__(self): return VerySpecial.__hash__(self) def __call__(self, arg): return VerySpecial.__call__(self, arg) def __str__(self): return VerySpecial.__str__(self) # there is no __richcmp__ at the Python level # def __richcmp__(self, other, kind): # return VerySpecial.__richcmp__(self, other, kind) def __iter__(self): return VerySpecial.__iter__(self) def __next__(self): return VerySpecial.__next__(self) def __get__(self, inst, own): return VerySpecial.__get__(self, inst, own) Cython-0.23.4/tests/run/special_method_docstrings.pyx0000644000175600017570000000210012606202452024124 0ustar jenkinsjenkins00000000000000cdef class A: """ >>> A.__init__.__doc__ 'A.__init__ docstring' >>> A.__len__.__doc__ 'A.__len__ docstring' >>> A.__add__.__doc__ 'A.__add__ docstring' >>> A.__getattr__.__doc__ 'A.__getattr__ docstring' """ def __init__(self): "A.__init__ docstring" def __len__(self): "A.__len__ docstring" def __add__(self, other): "A.__add__ docstring" def __getattr__(self, name): "A.__getattr__ docstring" cdef class B(A): """ >>> B.__init__.__doc__ 'A.__init__ docstring' >>> B.__len__.__doc__ 'B.__len__ docstring' >>> B.__add__.__doc__ 'A.__add__ docstring' >>> B.__getattr__.__doc__ 'A.__getattr__ docstring' """ def __len__(self): "B.__len__ docstring" class C(A): """ >>> C.__init__.__doc__ 'A.__init__ docstring' >>> C.__len__.__doc__ 'C.__len__ docstring' >>> C.__add__.__doc__ 'A.__add__ docstring' >>> C.__getattr__.__doc__ 'A.__getattr__ docstring' """ def __len__(self): "C.__len__ docstring" Cython-0.23.4/tests/run/slice_ptr.pyx0000644000175600017570000000436312606202452020706 0ustar jenkinsjenkins00000000000000from libc.stdlib cimport malloc, free from cpython.object cimport Py_EQ, Py_NE def double_ptr_slice(x, L, int a, int b): """ >>> L = list(range(10)) >>> double_ptr_slice(5, L, 0, 10) >>> double_ptr_slice(6, L, 0, 10) >>> double_ptr_slice(None, L, 0, 10) >>> double_ptr_slice(0, L, 3, 7) >>> double_ptr_slice(5, L, 3, 7) >>> double_ptr_slice(9, L, 3, 7) >>> double_ptr_slice(EqualsEvens(), L, 0, 10) >>> double_ptr_slice(EqualsEvens(), L, 1, 10) """ cdef double *L_c = NULL try: L_c = malloc(len(L) * sizeof(double)) for i, a in enumerate(L): L_c[i] = L[i] assert (x in L_c[:b]) == (x in L[:b]) assert (x not in L_c[:b]) == (x not in L[:b]) assert (x in L_c[a:b]) == (x in L[a:b]) assert (x not in L_c[a:b]) == (x not in L[a:b]) assert (x in L_c[a:b:2]) == (x in L[a:b:2]) assert (x not in L_c[a:b:2]) == (x not in L[a:b:2]) finally: free(L_c) def void_ptr_slice(py_x, L, int a, int b): """ >>> L = list(range(10)) >>> void_ptr_slice(5, L, 0, 10) >>> void_ptr_slice(6, L, 0, 10) >>> void_ptr_slice(None, L, 0, 10) >>> void_ptr_slice(0, L, 3, 7) >>> void_ptr_slice(5, L, 3, 7) >>> void_ptr_slice(9, L, 3, 7) """ # I'm using the fact that small Python ints are cached. cdef void **L_c = NULL cdef void *x = py_x try: L_c = malloc(len(L) * sizeof(void*)) for i, a in enumerate(L): L_c[i] = L[i] assert (x in L_c[:b]) == (py_x in L[:b]) assert (x not in L_c[:b]) == (py_x not in L[:b]) assert (x in L_c[a:b]) == (py_x in L[a:b]) assert (x not in L_c[a:b]) == (py_x not in L[a:b]) assert (x in L_c[a:b:2]) == (py_x in L[a:b:2]) assert (x not in L_c[a:b:2]) == (py_x not in L[a:b:2]) finally: free(L_c) cdef class EqualsEvens: """ >>> e = EqualsEvens() >>> e == 2 True >>> e == 5 False >>> [e == k for k in range(4)] [True, False, True, False] """ def __richcmp__(self, other, int op): if op == Py_EQ: return other % 2 == 0 elif op == Py_NE: return other % 2 == 1 else: return False Cython-0.23.4/tests/run/slice_charptr.pyx0000644000175600017570000000072212606202452021537 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> do_slice(b'abcdef', 2, 3) (b'c', b'cdef', b'ab', b'abcdef', b'cdef', b'ab', b'abcdef') >>> do_slice(b'abcdef', 0, 5) (b'abcde', b'abcdef', b'', b'abcdef', b'abcdef', b'', b'abcdef') """ import sys if sys.version_info[0] < 3: __doc__ = __doc__.replace(u"(b'", u"('").replace(u" b'", u" '") def do_slice(s, int i, int j): cdef char* ss = s return ss[i:j], ss[i:], ss[:i], ss[:], ss[i:None], ss[None:i], ss[None:None] Cython-0.23.4/tests/run/slice3.pyx0000644000175600017570000000210012606202452020067 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> class Test(object): ... def __setitem__(self, key, value): ... print((key, value)) ... def __getitem__(self, key): ... print(key) ... return self >>> ellipsis(Test()) Ellipsis >>> full(Test()) slice(None, None, None) >>> select(0, Test(), 10, 20, 30) slice(10, None, None) slice(None, 20, None) slice(None, None, 30) slice(10, 20, None) slice(10, None, 30) slice(None, 20, 30) slice(10, 20, 30) slice(1, 2, 3) >>> set(Test(), -11) (slice(1, 2, 3), -11) """ def ellipsis(o): obj1 = o[...] def full(o): obj1 = o[::] def set(o, v): cdef int int3, int4, int5 int3, int4, int5 = 1,2,3 o[int3:int4:int5] = v def select(obj1, obj2, obj3, obj4, obj5): cdef int int3, int4, int5 int3, int4, int5 = 1,2,3 obj1 = obj2[obj3::] obj1 = obj2[:obj4:] obj1 = obj2[::obj5] obj1 = obj2[obj3:obj4:] obj1 = obj2[obj3::obj5] obj1 = obj2[:obj4:obj5] obj1 = obj2[obj3:obj4:obj5] obj1 = obj2[int3:int4:int5] Cython-0.23.4/tests/run/slice2b.pyx0000644000175600017570000000040612606202452020237 0ustar jenkinsjenkins00000000000000cdef extern from *: ctypedef class __builtin__.list [ object PyListObject ]: pass def slice_of_typed_value(): """ >>> slice_of_typed_value() [1, 2, 3] """ cdef object a = [] cdef list L = [1, 2, 3] a[:] = L return a Cython-0.23.4/tests/run/slice2_T636.py0000644000175600017570000000154012606202452020427 0ustar jenkinsjenkins00000000000000# mode: run # ticket 636 # tag: slicing, getitem class Sliceable(object): """ >>> sl = Sliceable() >>> sl[1:2] (1, 2, None) >>> py_slice2(sl, 1, 2) (1, 2, None) >>> sl[1:None] (1, None, None) >>> py_slice2(sl, 1, None) (1, None, None) >>> sl[None:2] (None, 2, None) >>> py_slice2(sl, None, 2) (None, 2, None) >>> sl[None:None] (None, None, None) >>> py_slice2(sl, None, None) (None, None, None) """ def __getitem__(self, sl): return (sl.start, sl.stop, sl.step) def py_slice2(obj,a,b): """ >>> [1,2,3][1:2] [2] >>> py_slice2([1,2,3], 1, 2) [2] >>> [1,2,3][None:2] [1, 2] >>> py_slice2([1,2,3], None, 2) [1, 2] >>> [1,2,3][None:None] [1, 2, 3] >>> py_slice2([1,2,3], None, None) [1, 2, 3] """ return obj[a:b] Cython-0.23.4/tests/run/slice2.pyx0000644000175600017570000000321312606202452020074 0ustar jenkinsjenkins00000000000000# mode: run # tag: slicing def test_full(seq): """ >>> l = [1,2,3,4] >>> test_full(l) [1, 2, 3, 4] >>> l == test_full(l) True >>> l is test_full(l) False >>> try: test_full(42) ... except TypeError: pass """ obj = seq[:] return obj def test_start(seq, start): """ >>> test_start([1,2,3,4], 2) [3, 4] >>> test_start([1,2,3,4], 3) [4] >>> test_start([1,2,3,4], 4) [] >>> test_start([1,2,3,4], 8) [] >>> test_start([1,2,3,4], -3) [2, 3, 4] >>> test_start([1,2,3,4], -4) [1, 2, 3, 4] >>> test_start([1,2,3,4], -8) [1, 2, 3, 4] >>> test_start([1,2,3,4], 0) [1, 2, 3, 4] >>> try: test_start(42, 2, 3) ... except TypeError: pass """ obj = seq[start:] return obj def test_stop(seq, stop): """ >>> test_stop([1,2,3,4], 3) [1, 2, 3] >>> test_stop([1,2,3,4], -1) [1, 2, 3] >>> test_stop([1,2,3,4], -3) [1] >>> test_stop([1,2,3,4], -4) [] >>> test_stop([1,2,3,4], -8) [] >>> test_stop([1,2,3,4], 0) [] >>> try: test_stop(42, 3) ... except TypeError: pass """ obj = seq[:stop] return obj def test_start_and_stop(seq, start, stop): """ >>> l = [1,2,3,4] >>> test_start_and_stop(l, 2, 3) [3] >>> test_start_and_stop(l, -3, -1) [2, 3] >>> try: test_start_and_stop(42, 2, 3) ... except TypeError: pass """ obj = seq[start:stop] return obj class A(object): pass def slice_of_temporary_smoketest(): """ >>> slice_of_temporary_smoketest() [3, 2] """ x = A() x.a = [1, 2] x.a[:] = [3,2] return x.a Cython-0.23.4/tests/run/sizeof.pyx0000644000175600017570000000046712606202452020222 0ustar jenkinsjenkins00000000000000cdef struct Spam: char *grail def f(): """ >>> f() """ cdef int i, j, k cdef char *p i = sizeof(p) i = sizeof(j + k) i = sizeof(int) i = sizeof(long int) i = sizeof(void*) i = sizeof(Spam) i = sizeof(Spam*) i = sizeof(Spam[5]) i = sizeof(Spam (*)()) Cython-0.23.4/tests/run/size_t.pyx0000644000175600017570000000157012606202452020214 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> test(0) 0 >>> test(1) 1 >>> test(2) 2 >>> str(test((1<<32)-1)) '4294967295' >>> try: test(-1) ... except (OverflowError, TypeError): print("ERROR") ERROR >>> test(1<<128) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> a = A(1,2) >>> a.a == 1 True >>> a.b == 2 True >>> a.foo(5) 5 >>> try: a.foo(-1) ... except (OverflowError, TypeError): print("ERROR") ERROR >>> a.foo(1 << 180) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ # XXX This should generate a warning !!! cdef extern from *: ctypedef unsigned long size_t def test(size_t i): return i cdef class A: cdef public size_t a cdef readonly size_t b def __init__(self, size_t a, object b): self.a = a self.b = b cpdef size_t foo(self, size_t x): cdef object o = x return o Cython-0.23.4/tests/run/simpcall.pyx0000644000175600017570000000143212606202452020520 0ustar jenkinsjenkins00000000000000__doc__ = """ >>> z(1,9.2, b'test') """ import sys if sys.version_info[0] < 3: __doc__ = __doc__.replace(u" b'", u" '") def f(x, y): x = y cdef void g(int i, float f, char *p): f = i cdef h(int i, obj): i = obj def z(a, b, c): f(a, b) f(a, b,) g(1, 2.0, "spam") g(a, b, c) def fail0(a, b): """ >>> fail0(1,2) Traceback (most recent call last): TypeError: f() takes exactly 2 positional arguments (0 given) """ f() def fail1(a, b): """ >>> fail1(1,2) Traceback (most recent call last): TypeError: f() takes exactly 2 positional arguments (1 given) """ f(a) def failtype(): """ >>> failtype() Traceback (most recent call last): TypeError: an integer is required """ h(42, "eggs") Cython-0.23.4/tests/run/short_circuit_T404.pyx0000644000175600017570000000107712606202452022315 0ustar jenkinsjenkins00000000000000# ticket: 404 cdef long foo(long x): print "foo(%s)" % x return x def test_or(long a, long b): """ >>> test_or(1,2) foo(1) 1 >>> test_or(1,0) foo(1) 1 >>> test_or(0,2) foo(0) foo(2) 2 >>> test_or(0,0) foo(0) foo(0) 0 """ print foo(a) or foo(b) def test_and(long a, long b): """ >>> test_and(1,2) foo(1) foo(2) 2 >>> test_and(1,0) foo(1) foo(0) 0 >>> test_and(0,2) foo(0) 0 >>> test_and(0,0) foo(0) 0 """ print foo(a) and foo(b) Cython-0.23.4/tests/run/shapes.h0000644000175600017570000000242112606202452017605 0ustar jenkinsjenkins00000000000000#ifndef SHAPES_H #define SHAPES_H namespace shapes { int constructor_count = 0; int destructor_count = 0; class Shape { public: virtual float area() const = 0; Shape() { constructor_count++; } virtual ~Shape() { destructor_count++; } }; class Rectangle : public Shape { public: Rectangle() { } Rectangle(int width, int height) { this->width = width; this->height = height; } float area() const { return width * height; } int width; int height; int method(int arg) { return width * height + arg; } }; class Square : public Rectangle { public: Square(int side) : Rectangle(side, side) { this->side = side; } int side; }; class Ellipse : public Shape { public: Ellipse(int a, int b) { this->a = a; this->b = b; } float area() const { return 3.1415926535897931f * a * b; } int a, b; }; class Circle : public Ellipse { public: Circle(int radius) : Ellipse(radius, radius) { this->radius = radius; } int radius; }; class Empty : public Shape { public: float area() const { return 0; } }; } #endif Cython-0.23.4/tests/run/setjmp.pyx0000644000175600017570000000211212606202452020212 0ustar jenkinsjenkins00000000000000from libc.setjmp cimport * cdef void check_nonzero(jmp_buf ctx, int x) nogil: if x == 0: longjmp(ctx, 1) def nonzero(int x): """ >>> nonzero(-1) True >>> nonzero(0) False >>> nonzero(1) True >>> nonzero(2) True """ cdef jmp_buf ctx if setjmp(ctx) == 0: check_nonzero(ctx, x) return True else: return False from libc.string cimport strcpy cdef char[256] error_msg cdef jmp_buf error_ctx cdef void error(char msg[]) nogil: strcpy(error_msg,msg) longjmp(error_ctx, 1) cdef void c_call(int x) nogil: if x<=0: error(b"expected a positive value") def execute_c_call(int x): """ >>> execute_c_call(+2) >>> execute_c_call(+1) >>> execute_c_call(+0) Traceback (most recent call last): ... RuntimeError: expected a positive value >>> execute_c_call(-1) Traceback (most recent call last): ... RuntimeError: expected a positive value """ if not setjmp(error_ctx): c_call(x) else: raise RuntimeError(error_msg.decode()) Cython-0.23.4/tests/run/setcomp.pyx0000644000175600017570000000235712606202452020375 0ustar jenkinsjenkins00000000000000 cimport cython # Py2.3 doesn't have the set type, but Cython does :) _set = set def setcomp(): """ >>> type(setcomp()) is not list True >>> type(setcomp()) is _set True >>> sorted(setcomp()) [0, 4, 8] """ x = 'abc' result = { x*2 for x in range(5) if x % 2 == 0 } assert x == 'abc' # do not leak return result @cython.test_assert_path_exists( "//InlinedGeneratorExpressionNode", "//ComprehensionAppendNode") def genexp_set(): """ >>> type(genexp_set()) is _set True >>> sorted(genexp_set()) [0, 4, 8] """ x = 'abc' result = set( x*2 for x in range(5) if x % 2 == 0 ) assert x == 'abc' # do not leak return result cdef class A: def __repr__(self): return u"A" def __richcmp__(one, other, int op): return one is other def __hash__(self): return id(self) % 65536 def typed(): """ >>> list(typed()) [A, A, A] """ cdef A obj return {obj for obj in {A(), A(), A()}} def iterdict(): """ >>> sorted(iterdict()) [1, 2, 3] """ cdef dict d = dict(a=1,b=2,c=3) return {d[key] for key in d} def sorted(it): l = list(it) l.sort() return l Cython-0.23.4/tests/run/set_literals.py0000644000175600017570000000427212606202452021223 0ustar jenkinsjenkins00000000000000# Py2.7+ only import sys def test_set_literal(): """ >>> type(test_set_literal()) is set True >>> sorted(test_set_literal()) ['a', 'b', 1] """ s1 = {1, 'a', 1, 'b', 'a'} return s1 def test_set_add(): """ >>> type(test_set_add()) is set True >>> sorted(test_set_add()) ['a', 1, (1, 2)] """ s1 = {1, (1, 2)} s1.add(1) s1.add('a') s1.add(1) s1.add((1, 2)) return s1 def test_set_comp(): """ >>> type(test_set_comp()) is set True >>> sorted(test_set_comp()) [0, 1, 2] """ s1 = {i % 3 for i in range(5)} return s1 def test_frozenset_set_comp(): """ >>> type(test_frozenset_set_comp()) is frozenset True >>> sorted(test_frozenset_set_comp()) [0, 1, 2] """ s1 = frozenset({i % 3 for i in range(5)}) return s1 def test_set_sideeffect_unhashable_failure_literal(): """ >>> test_set_sideeffect_unhashable_failure_literal() [2, 4, 5] """ L = [] def sideeffect(x): L.append(x) return x def unhashable_value(x): L.append(x) return set() try: s = {1, sideeffect(2), 3, unhashable_value(4), sideeffect(5)} except TypeError: pass else: assert False, "expected exception not raised" return L def test_set_comp_sideeffect_unhashable_failure(): """ >>> test_set_comp_sideeffect_unhashable_failure() (None, [2, 4]) """ L = [] def value(x): return x def sideeffect(x): L.append(x) return x def unhashable_value(x): L.append(x) return set() s = None try: s = {f(i) for i, f in enumerate([value, sideeffect, value, unhashable_value, sideeffect], 1)} except TypeError: pass else: assert False, "expected exception not raised" return s, L def sorted(it): # Py3 can't compare different types chars = [] nums = [] tuples = [] for item in it: if type(item) is int: nums.append(item) elif type(item) is tuple: tuples.append(item) else: chars.append(item) nums.sort() chars.sort() tuples.sort() return chars+nums+tuples Cython-0.23.4/tests/run/set_discard_remove.py0000644000175600017570000000177112606202452022373 0ustar jenkinsjenkins00000000000000 def set_discard(): """ >>> sorted(set_discard()) [1, 2] """ s = set([1,2,3]) s.discard(3) return s def set_discard_missing(): """ >>> sorted(set_discard_missing()) [1, 2, 3] """ s = set([1,2,3]) s.discard(4) return s def set_discard_set(): """ >>> s = set_discard_set() >>> len(s) 1 >>> sorted(s.pop()) [1, 2] """ s = set([frozenset([1,2]), frozenset([2,3])]) s.discard(set([2,3])) return s def set_remove(): """ >>> sorted(set_remove()) [1, 2] """ s = set([1,2,3]) s.remove(3) return s def set_remove_missing(): """ >>> sorted(set_remove_missing()) Traceback (most recent call last): KeyError: 4 """ s = set([1,2,3]) s.remove(4) return s def set_remove_set(): """ >>> s = set_remove_set() >>> len(s) 1 >>> sorted(s.pop()) [1, 2] """ s = set([frozenset([1,2]), frozenset([2,3])]) s.remove(set([2,3])) return s Cython-0.23.4/tests/run/set.pyx0000644000175600017570000002051312606202452017510 0ustar jenkinsjenkins00000000000000 cimport cython def cython_set(): """ >>> cython_set() is set True """ assert set is cython.set return cython.set def cython_frozenset(): """ >>> cython_frozenset() is frozenset True """ assert frozenset is cython.frozenset return cython.frozenset def cython_set_override(): """ >>> cython_set_override() is set True """ set = 1 return cython.set def cython_frozenset_override(): """ >>> cython_frozenset_override() is frozenset True """ frozenset = 1 return cython.frozenset def test_set_literal(): """ >>> type(test_set_literal()) is set True >>> sorted(test_set_literal()) ['a', 'b', 1] """ cdef set s1 = {1,'a',1,'b','a'} return s1 def test_set_add(): """ >>> type(test_set_add()) is set True >>> sorted(test_set_add()) ['a', 1, (1, 2)] """ cdef set s1 s1 = set([1, (1, 2)]) s1.add(1) s1.add('a') s1.add(1) s1.add((1,2)) return s1 def test_set_update(v=None): """ >>> type(test_set_update()) is set True >>> sorted(test_set_update()) ['a', 'b', 'c', 1, 2, (1, 2)] >>> sorted(test_set_update([])) ['a', 'b', 'c', 1, 2, (1, 2)] >>> try: test_set_update(object()) ... except TypeError: pass ... else: print("NOT RAISED!") """ cdef set s1 s1 = set([1, (1, 2)]) s1.update((1,)) s1.update('abc') s1.update(set([1])) s1.update(frozenset((1,2))) if v is not None: s1.update(v) return s1 def test_object_update(v=None): """ >>> type(test_object_update()) is set True >>> sorted(test_object_update()) ['a', 'b', 'c', 1, 2, (1, 2)] >>> sorted(test_object_update([])) ['a', 'b', 'c', 1, 2, (1, 2)] >>> try: test_object_update(object()) ... except TypeError: pass ... else: print("NOT RAISED!") """ cdef object s1 s1 = set([1, (1, 2)]) s1.update((1,)) s1.update('abc') s1.update(set([1])) s1.update(frozenset((1,2))) if v is not None: s1.update(v) return s1 def test_set_clear(): """ >>> type(test_set_clear()) is set True >>> list(test_set_clear()) [] """ cdef set s1 s1 = set([1]) s1.clear() return s1 def test_set_clear_None(): """ >>> test_set_clear_None() Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'clear' """ cdef set s1 = None s1.clear() def test_set_list_comp(): """ >>> type(test_set_list_comp()) is set True >>> sorted(test_set_list_comp()) [0, 1, 2] """ cdef set s1 s1 = set([i%3 for i in range(5)]) return s1 def test_frozenset_list_comp(): """ >>> type(test_frozenset_list_comp()) is frozenset True >>> sorted(test_frozenset_list_comp()) [0, 1, 2] """ cdef frozenset s1 s1 = frozenset([i%3 for i in range(5)]) return s1 def test_set_pop(): """ >>> type(test_set_pop()) is set True >>> list(test_set_pop()) [] """ cdef set s1 s1 = set() s1.add('2') two = s1.pop() return s1 @cython.test_fail_if_path_exists("//SimpleCallNode//NameNode") def test_object_pop(s): """ >>> s = set([2]) >>> test_object_pop(s) 2 >>> list(s) [] """ return s.pop() def test_noop_pop(): """ >>> test_noop_pop() """ set([0]).pop() def test_noop_pop_exception(): """ >>> try: test_noop_pop_exception() ... except KeyError: pass ... else: print("KeyError expected but not raised!") """ set([]).pop() def test_set_discard(): """ >>> type(test_set_discard()) is set True >>> sorted(test_set_discard()) ['12', 233] """ cdef set s1 s1 = set() s1.add('12') s1.add(3) s1.add(233) s1.discard('3') s1.discard(3) return s1 def test_set_sideeffect_unhashable_failure(): """ >>> test_set_sideeffect_unhashable_failure() [2, 4, 5] """ L = [] def sideeffect(x): L.append(x) return x def unhashable_value(x): L.append(x) return set() try: s = set([1,sideeffect(2),3,unhashable_value(4),sideeffect(5)]) except TypeError: pass else: assert False, "expected exception not raised" return L def test_set_sideeffect_unhashable_failure_literal(): """ >>> test_set_sideeffect_unhashable_failure_literal() [2, 4, 5] """ L = [] def sideeffect(x): L.append(x) return x def unhashable_value(x): L.append(x) return set() try: s = {1,sideeffect(2),3,unhashable_value(4),sideeffect(5)} except TypeError: pass else: assert False, "expected exception not raised" return L def test_frozenset_sideeffect_unhashable_failure(): """ >>> test_frozenset_sideeffect_unhashable_failure() [2, 4, 5] """ L = [] def sideeffect(x): L.append(x) return x def unhashable_value(x): L.append(x) return set() try: s = frozenset([1,sideeffect(2),3,unhashable_value(4),sideeffect(5)]) except TypeError: pass else: assert False, "expected exception not raised" return L @cython.test_assert_path_exists("//SetNode") @cython.test_fail_if_path_exists( "//SimpleCallNode", "//PythonCapiCallNode" ) def test_set_of_list(): """ >>> s = test_set_of_list() >>> isinstance(s, set) True >>> sorted(s) [1, 2, 3] """ return set([1, 2, 3]) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//SetNode") def test_frozenset_of_list(): """ >>> s = test_frozenset_of_list() >>> isinstance(s, frozenset) True >>> sorted(s) [1, 2, 3] """ return frozenset([1, 2, 3]) @cython.test_assert_path_exists("//SetNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def test_set_of_tuple(): """ >>> s = test_set_of_tuple() >>> isinstance(s, set) True >>> sorted(s) [1, 2, 3] """ return set((1, 2, 3)) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//SetNode") def test_frozenset_of_tuple(): """ >>> s = test_frozenset_of_tuple() >>> isinstance(s, frozenset) True >>> sorted(s) [1, 2, 3] """ return frozenset((1, 2, 3)) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists( "//SimpleCallNode", "//SetNode" ) def test_set_of_iterable(x): """ >>> s = test_set_of_iterable([1, 2, 3]) >>> isinstance(s, set) True >>> sorted(s) [1, 2, 3] """ return set(x) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists( "//SimpleCallNode", "//SetNode" ) def test_frozenset_of_iterable(x): """ >>> s = test_frozenset_of_iterable([1, 2, 3]) >>> isinstance(s, frozenset) True >>> sorted(s) [1, 2, 3] >>> s = test_frozenset_of_iterable(frozenset([1, 2, 3])) >>> isinstance(s, frozenset) True >>> sorted(s) [1, 2, 3] """ return frozenset(x) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists( "//SimpleCallNode", "//SetNode" ) def test_empty_frozenset(): """ >>> s = test_empty_frozenset() >>> isinstance(s, frozenset) True >>> len(s) 0 >>> s is frozenset() # singleton! True """ return frozenset() @cython.test_fail_if_path_exists( '//ListNode//ListNode', '//ListNode//PythonCapiCallNode//PythonCapiCallNode', '//ListNode//SimpleCallNode//SimpleCallNode', ) def test_singleton_empty_frozenset(): """ >>> test_singleton_empty_frozenset() # from CPython's test_set.py 1 """ f = frozenset() efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''), frozenset(), frozenset([]), frozenset(()), frozenset(''), frozenset(range(0)), frozenset(frozenset()), frozenset(f), f] return len(set(map(id, efs))) def sorted(it): # Py3 can't compare different types chars = [] nums = [] tuples = [] for item in it: if type(item) is int: nums.append(item) elif type(item) is tuple: tuples.append(item) else: chars.append(item) nums.sort() chars.sort() tuples.sort() return chars+nums+tuples Cython-0.23.4/tests/run/sequential_parallel.pyx0000644000175600017570000003560712606202452022755 0ustar jenkinsjenkins00000000000000# tag: run cimport cython.parallel from cython.parallel import prange, threadid from libc.stdlib cimport malloc, calloc, free, abort from libc.stdio cimport puts import os import sys try: from builtins import next # Py3k except ImportError: def next(it): return it.next() #@cython.test_assert_path_exists( # "//ParallelWithBlockNode//ParallelRangeNode[@schedule = 'dynamic']", # "//GILStatNode[@state = 'nogil]//ParallelRangeNode") def test_prange(): """ >>> test_prange() (9, 9, 45, 45) """ cdef Py_ssize_t i, j, sum1 = 0, sum2 = 0 with nogil, cython.parallel.parallel(): for i in prange(10, schedule='dynamic'): sum1 += i for j in prange(10, nogil=True): sum2 += j return i, j, sum1, sum2 def test_descending_prange(): """ >>> test_descending_prange() 5 """ cdef int i, start = 5, stop = -5, step = -2 cdef int sum = 0 for i in prange(start, stop, step, nogil=True): sum += i return sum def test_propagation(): """ >>> test_propagation() (9, 9, 9, 9, 450, 450) """ cdef int i = 0, j = 0, x = 0, y = 0 cdef int sum1 = 0, sum2 = 0 for i in prange(10, nogil=True): for j in prange(10): sum1 += i with nogil, cython.parallel.parallel(): for x in prange(10): for y in prange(10): sum2 += y return i, j, x, y, sum1, sum2 # DISABLED, not allowed in OpenMP 3.0 (fails on Windows) #def test_unsigned_operands(): # """ # >>> test_unsigned_operands() # 10 # """ # cdef int i # cdef int start = -5 # cdef unsigned int stop = 5 # cdef int step = 1 # # cdef int steps_taken = 0 # cdef int *steps_takenp = &steps_taken # # for i in prange(start, stop, step, nogil=True): # steps_taken += 1 # if steps_takenp[0] > 10: # abort() # # return steps_taken def test_reassign_start_stop_step(): """ >>> test_reassign_start_stop_step() 20 """ cdef int start = 0, stop = 10, step = 2 cdef int i cdef int sum = 0 for i in prange(start, stop, step, nogil=True): start = -2 stop = 2 step = 0 sum += i return sum def test_closure_parallel_privates(): """ >>> test_closure_parallel_privates() 9 9 45 45 0 0 9 9 """ cdef int x def test_target(): nonlocal x for x in prange(10, nogil=True): pass return x print test_target(), x def test_reduction(): nonlocal x cdef int i x = 0 for i in prange(10, nogil=True): x += i return x print test_reduction(), x def test_generator(): nonlocal x cdef int i x = 0 yield x x = 2 for i in prange(10, nogil=True): x = i yield x g = test_generator() print next(g), x, next(g), x def test_closure_parallel_with_gil(): """ >>> test_closure_parallel_with_gil() 45 45 """ cdef int sum = 0 temp1 = 5 temp2 = -5 def test_reduction(): nonlocal sum, temp1, temp2 cdef int i for i in prange(10, nogil=True): with gil: sum += temp1 + temp2 + i # assert abs(sum - sum) == 0 return sum print test_reduction() print sum def test_pure_mode(): """ >>> test_pure_mode() 0 1 2 3 4 4 3 2 1 0 0 """ import Cython.Shadow pure_parallel = sys.modules['cython.parallel'] for i in pure_parallel.prange(5): print i for i in pure_parallel.prange(4, -1, -1, schedule='dynamic', nogil=True): print i with pure_parallel.parallel(): print pure_parallel.threadid() cdef extern from "types.h": ctypedef short actually_long_t ctypedef long actually_short_t ctypedef int myint_t def test_nan_init(): """ >>> test_nan_init() """ cdef int mybool = 0 cdef int err = 0 cdef int *errp = &err cdef signed char a1 = 10 cdef unsigned char a2 = 10 cdef short b1 = 10 cdef unsigned short b2 = 10 cdef int c1 = 10 cdef unsigned int c2 = 10 cdef long d1 = 10 cdef unsigned long d2 = 10 cdef long long e1 = 10 cdef unsigned long long e2 = 10 cdef actually_long_t miss1 = 10 cdef actually_short_t miss2 = 10 cdef myint_t typedef1 = 10 cdef float f = 10.0 cdef double g = 10.0 cdef long double h = 10.0 cdef void *p = 10 with nogil, cython.parallel.parallel(): # First, trick the error checking to make it believe these variables # are initialized after this if if mybool: # mybool is always false! a1 = a2 = b1 = b2 = c1 = c2 = d1 = d2 = e1 = e2 = 0 f = g = h = 0.0 p = NULL miss1 = miss2 = typedef1 = 0 if (a1 == 10 or a2 == 10 or b1 == 10 or b2 == 10 or c1 == 10 or c2 == 10 or d1 == 10 or d2 == 10 or e1 == 10 or e2 == 10 or f == 10.0 or g == 10.0 or h == 10.0 or p == 10 or miss1 == 10 or miss2 == 10 or typedef1 == 10): errp[0] = 1 cdef int i for i in prange(10, nogil=True): # First, trick the error checking to make it believe these variables # are initialized after this if if mybool: # mybool is always false! a1 = a2 = b1 = b2 = c1 = c2 = d1 = d2 = e1 = e2 = 0 f = g = h = 0.0 p = NULL miss1 = miss2 = typedef1 = 0 if (a1 == 10 or a2 == 10 or b1 == 10 or b2 == 10 or c1 == 10 or c2 == 10 or d1 == 10 or d2 == 10 or e1 == 10 or e2 == 10 or f == 10.0 or g == 10.0 or h == 10.0 or p == 10 or miss1 == 10 or miss2 == 10 or typedef1 == 10): errp[0] = 1 if err: raise Exception("One of the values was not initialized to a maximum " "or NaN value") c1 = 20 with nogil, cython.parallel.parallel(): c1 = 16 cdef void nogil_print(char *s) with gil: print s.decode('ascii') def test_else_clause(): """ >>> test_else_clause() else clause executed """ cdef int i for i in prange(5, nogil=True): pass else: nogil_print('else clause executed') def test_prange_break(): """ >>> test_prange_break() """ cdef int i for i in prange(10, nogil=True): if i == 8: break else: nogil_print('else clause executed') def test_prange_continue(): """ >>> test_prange_continue() else clause executed 0 0 1 0 2 2 3 0 4 4 5 0 6 6 7 0 8 8 9 0 """ cdef int i cdef int *p = calloc(10, sizeof(int)) if p == NULL: raise MemoryError for i in prange(10, nogil=True): if i % 2 != 0: continue p[i] = i else: nogil_print('else clause executed') for i in range(10): print i, p[i] free(p) def test_nested_break_continue(): """ DISABLED. For some reason this fails intermittently on jenkins, with the first line of output being '0 0 0 0'. The generated code looks awfully correct though... needs investigation >> test_nested_break_continue() 6 7 6 7 8 """ cdef int i, j, result1 = 0, result2 = 0 for i in prange(10, nogil=True, num_threads=2, schedule='static'): for j in prange(10, num_threads=2, schedule='static'): if i == 6 and j == 7: result1 = i result2 = j break else: continue break print i, j, result1, result2 with nogil, cython.parallel.parallel(num_threads=2): for i in prange(10, schedule='static'): if i == 8: break else: continue print i cdef int parallel_return() nogil: cdef int i for i in prange(10): if i == 8: return i else: return 1 return 2 def test_return(): """ >>> test_return() 8 """ print parallel_return() def test_parallel_exceptions(): """ >>> test_parallel_exceptions() I am executed first ('propagate me',) 0 """ cdef int i, j, sum = 0 mylist = [] try: for i in prange(10, nogil=True): try: for j in prange(10): with gil: raise Exception("propagate me") sum += i * j sum += i finally: with gil: mylist.append("I am executed first") except Exception, e: print mylist[0] print e.args, sum def test_parallel_exceptions_unnested(): """ >>> test_parallel_exceptions_unnested() ('I am executed first', 0) ('propagate me',) 0 """ cdef int i, sum = 0 mylist = [] try: with nogil, cython.parallel.parallel(): try: for i in prange(10): with gil: raise Exception("propagate me") sum += i finally: with gil: mylist.append(("I am executed first", sum)) except Exception, e: print mylist[0] print e.args, sum cdef int parallel_exc_cdef() except -3: cdef int i, j for i in prange(10, nogil=True): for j in prange(10, num_threads=6): with gil: raise Exception("propagate me") return 0 cdef int parallel_exc_cdef_unnested() except -3: cdef int i for i in prange(10, nogil=True): with gil: raise Exception("propagate me") return 0 def test_parallel_exc_cdef(): """ >>> test_parallel_exc_cdef() Traceback (most recent call last): ... Exception: propagate me """ parallel_exc_cdef_unnested() parallel_exc_cdef() cpdef int parallel_exc_cpdef() except -3: cdef int i, j for i in prange(10, nogil=True): for j in prange(10, num_threads=6): with gil: raise Exception("propagate me") return 0 cpdef int parallel_exc_cpdef_unnested() except -3: cdef int i, j for i in prange(10, nogil=True): with gil: raise Exception("propagate me") return 0 def test_parallel_exc_cpdef(): """ >>> test_parallel_exc_cpdef() Traceback (most recent call last): ... Exception: propagate me """ parallel_exc_cpdef_unnested() parallel_exc_cpdef() cdef int parallel_exc_nogil_swallow() except -1: cdef int i, j for i in prange(10, nogil=True): try: for j in prange(10): with gil: raise Exception("propagate me") finally: return i return 0 cdef int parallel_exc_nogil_swallow_unnested() except -1: cdef int i with nogil: try: for i in prange(10): with gil: raise Exception("propagate me") finally: return i return 0 def test_parallel_exc_nogil_swallow(): """ >>> test_parallel_exc_nogil_swallow() execute me execute me """ parallel_exc_nogil_swallow_unnested() print 'execute me' parallel_exc_nogil_swallow() print 'execute me' def parallel_exc_replace(): """ >>> parallel_exc_replace() Traceback (most recent call last): ... Exception: propagate me instead """ cdef int i, j for i in prange(10, nogil=True): with gil: try: for j in prange(10, nogil=True): with gil: raise Exception("propagate me") except Exception, e: raise Exception("propagate me instead") return 0 def parallel_exceptions2(): """ >>> parallel_exceptions2() Traceback (most recent call last): ... Exception: propagate me """ cdef int i, j, k for i in prange(10, nogil=True): for j in prange(10): for k in prange(10): if i + j + k > 20: with gil: raise Exception("propagate me") break continue return def test_parallel_with_gil_return(): """ >>> test_parallel_with_gil_return() True 45 """ cdef int i, sum = 0 for i in prange(10, nogil=True): with gil: obj = i sum += obj print obj in range(10) with nogil, cython.parallel.parallel(): with gil: return sum def test_parallel_with_gil_continue_unnested(): """ >>> test_parallel_with_gil_continue_unnested() 20 """ cdef int i, sum = 0 for i in prange(10, nogil=True): with gil: if i % 2: continue sum += i print sum cdef int inner_parallel_section() nogil: cdef int j, sum = 0 for j in prange(10): sum += j return sum def outer_parallel_section(): """ >>> outer_parallel_section() 450 """ cdef int i, sum = 0 for i in prange(10, nogil=True): sum += inner_parallel_section() return sum cdef int nogil_cdef_except_clause() nogil except 0: return 1 cdef void nogil_cdef_except_star() nogil except *: pass def test_nogil_cdef_except_clause(): """ >>> test_nogil_cdef_except_clause() """ cdef int i for i in prange(10, nogil=True): nogil_cdef_except_clause() nogil_cdef_except_star() def test_num_threads_compile(): cdef int i for i in prange(10, nogil=True, num_threads=2): pass with nogil, cython.parallel.parallel(num_threads=2): pass with nogil, cython.parallel.parallel(num_threads=2): for i in prange(10): pass cdef int chunksize() nogil: return 3 def test_chunksize(): """ >>> test_chunksize() 45 45 45 """ cdef int i, sum sum = 0 for i in prange(10, nogil=True, num_threads=2, schedule='static', chunksize=chunksize()): sum += i print sum sum = 0 for i in prange(10, nogil=True, num_threads=6, schedule='dynamic', chunksize=chunksize()): sum += i print sum sum = 0 with nogil, cython.parallel.parallel(): for i in prange(10, schedule='guided', chunksize=chunksize()): sum += i print sum cdef class PrintOnDealloc(object): def __dealloc__(self): print "deallocating..." def error(): raise Exception("propagate me") def test_clean_temps(): """ >>> test_clean_temps() deallocating... propagate me """ cdef Py_ssize_t i try: for i in prange(100, nogil=True, num_threads=1): with gil: x = PrintOnDealloc() + error() except Exception, e: print e.args[0] Cython-0.23.4/tests/run/self_in_ext_type_closure.pyx0000644000175600017570000000347312606202452024017 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 742 import cython @cython.cclass class ExtType(object): def const1(self): return 1 def ext_method0(self): """ >>> x = ExtType() >>> x.ext_method0()() 1 """ def func(): return self.const1() return func def ext_method1(self, a): """ >>> x = ExtType() >>> x.ext_method1(2)() (1, 2) """ def func(): return self.const1(), a return func def ext_method1_def(self, a=2): """ >>> x = ExtType() >>> x.ext_method1_def()() (1, 2) >>> x.ext_method1_def(3)() (1, 3) """ def func(): return self.const1(), a return func def ext_method_args(self, *args): """ >>> x = ExtType() >>> x.ext_method_args(2)() (1, 2) """ def func(): return self.const1(), args[0] return func def ext_method_args_only(*args): """ >>> x = ExtType() >>> x.ext_method_args_only(2)() (1, 2) """ def func(): return args[0].const1(), args[1] return func @cython.cclass class GenType(object): def const1(self): return 1 def gen0(self): """ >>> x = GenType() >>> tuple(x.gen0()) (1, 2) """ yield self.const1() yield 2 def gen1(self, a): """ >>> x = GenType() >>> tuple(x.gen1(2)) (1, 2) """ yield self.const1() yield a def gen_default(self, a=2): """ >>> x = GenType() >>> tuple(x.gen_default()) (1, 2) >>> tuple(x.gen_default(3)) (1, 3) """ yield self.const1() yield a Cython-0.23.4/tests/run/scanner_trace.srctree0000644000175600017570000000055512606202452022357 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace ######## setup.py ########### from distutils.core import setup from Cython.Build import cythonize import Cython.Compiler.Scanning Cython.Compiler.Scanning.trace_scanner = 1 setup( ext_modules = cythonize("*.pyx") ) import simple assert simple.test() == 123 ######## simple.pyx ########### def test(): return 123 Cython-0.23.4/tests/run/rodriguez_1.pyx0000644000175600017570000000043012606202452021143 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> b = B() >>> sorted(b.t.items()) [(1, ((1, 2, 3),)), (2, (1, 2, 3))] """ class B: def __init__(self): self.t = { 1 : ( (1, 2, 3) , ) , 2 : ( 1, 2, 3) } Cython-0.23.4/tests/run/richcmp_str_equals.py0000644000175600017570000000073112606202452022414 0ustar jenkinsjenkins00000000000000# mode: run class plop(object): def __init__(self): pass class testobj(object): def __init__(self): pass def __eq__(self, other): return plop() def test_equals(x): """ >>> x = testobj() >>> result = test_equals(x) >>> isinstance(result, plop) True >>> test_equals('hihi') False >>> test_equals('coucou') True """ eq = x == 'coucou' # not every str equals returns a bool ... return eq Cython-0.23.4/tests/run/reversed_iteration.pyx0000644000175600017570000005316012606202452022616 0ustar jenkinsjenkins00000000000000# mode: run # tag: forin, builtins, reversed, enumerate cimport cython import sys IS_PY3 = sys.version_info[0] >= 3 IS_32BIT_PY2 = not IS_PY3 and sys.maxint < 2**32 def unlongify(v): # on 32bit Py2.x platforms, 'unsigned int' coerces to a Python long => fix doctest output here. s = repr(v) if IS_32BIT_PY2: assert s.count('L') == s.count(',') + 1, s s = s.replace('L', '') return s def _reversed(it): return list(it)[::-1] @cython.test_assert_path_exists('//ForInStatNode', '//ForInStatNode/IteratorNode', '//ForInStatNode/IteratorNode[@reversed = True]', ) @cython.test_fail_if_path_exists('//ForInStatNode/IteratorNode//SimpleCallNode') def reversed_list(list l): """ >>> [ i for i in _reversed([1,2,3,4]) ] [4, 3, 2, 1] >>> reversed_list([1,2,3,4]) [4, 3, 2, 1] >>> reversed_list([]) [] >>> reversed_list(None) Traceback (most recent call last): TypeError: 'NoneType' object is not iterable """ result = [] for item in reversed(l): result.append(item) return result @cython.test_assert_path_exists('//ForInStatNode', '//ForInStatNode/IteratorNode', '//ForInStatNode/IteratorNode[@reversed = True]', ) @cython.test_fail_if_path_exists('//ForInStatNode/IteratorNode//SimpleCallNode') def reversed_tuple(tuple t): """ >>> [ i for i in _reversed((1,2,3,4)) ] [4, 3, 2, 1] >>> reversed_tuple((1,2,3,4)) [4, 3, 2, 1] >>> reversed_tuple(()) [] >>> reversed_tuple(None) Traceback (most recent call last): TypeError: 'NoneType' object is not iterable """ result = [] for item in reversed(t): result.append(item) return result @cython.test_assert_path_exists('//ForInStatNode', '//ForInStatNode/IteratorNode', '//ForInStatNode/IteratorNode[@reversed = True]', ) @cython.test_fail_if_path_exists('//ForInStatNode/IteratorNode//SimpleCallNode') def enumerate_reversed_list(list l): """ >>> list(enumerate(_reversed([1,2,3]))) [(0, 3), (1, 2), (2, 1)] >>> enumerate_reversed_list([1,2,3]) [(0, 3), (1, 2), (2, 1)] >>> enumerate_reversed_list([]) [] >>> enumerate_reversed_list(None) Traceback (most recent call last): TypeError: 'NoneType' object is not iterable """ result = [] cdef Py_ssize_t i for i, item in enumerate(reversed(l)): result.append((i, item)) return result @cython.test_assert_path_exists('//ForFromStatNode') def reversed_range(int N): """ >>> [ i for i in _reversed(range(5)) ] [4, 3, 2, 1, 0] >>> reversed_range(5) ([4, 3, 2, 1, 0], 0) >>> [ i for i in _reversed(range(0)) ] [] >>> reversed_range(0) ([], 99) """ cdef int i = 99 result = [] for i in reversed(range(N)): result.append(i) return result, i @cython.test_assert_path_exists('//ForFromStatNode') def reversed_range_step_pos(int a, int b): """ >>> [ i for i in _reversed(range(0, 5, 1)) ] [4, 3, 2, 1, 0] >>> reversed_range_step_pos(0, 5) ([4, 3, 2, 1, 0], 0) >>> [ i for i in _reversed(range(5, 0, 1)) ] [] >>> reversed_range_step_pos(5, 0) ([], 99) """ cdef int i = 99 result = [] for i in reversed(range(a, b, 1)): result.append(i) return result, i @cython.test_assert_path_exists('//ForFromStatNode') def reversed_range_step_neg(int a, int b): """ >>> [ i for i in _reversed(range(5, -1, -1)) ] [0, 1, 2, 3, 4, 5] >>> reversed_range_step_neg(5, -1) ([0, 1, 2, 3, 4, 5], 5) >>> [ i for i in _reversed(range(0, 5, -1)) ] [] >>> reversed_range_step_neg(0, 5) ([], 99) """ cdef int i = 99 result = [] for i in reversed(range(a, b, -1)): result.append(i) return result, i @cython.test_assert_path_exists('//ForFromStatNode') @cython.test_fail_if_path_exists('//ForInStatNode') def reversed_range_step3(int a, int b): """ >>> [ i for i in _reversed(range(-5, 0, 3)) ] [-2, -5] >>> reversed_range_step3(-5, 0) ([-2, -5], -5) >>> [ i for i in _reversed(range(0, 5, 3)) ] [3, 0] >>> reversed_range_step3(0, 5) ([3, 0], 0) >>> [ i for i in _reversed(range(5, 0, 3)) ] [] >>> reversed_range_step3(5, 0) ([], 99) >>> [ i for i in _reversed(range(1, 1, 3)) ] [] >>> reversed_range_step3(1, 1) ([], 99) """ cdef int i = 99 result = [] for i in reversed(range(a, b, 3)): result.append(i) return result, i @cython.test_assert_path_exists('//ForFromStatNode') @cython.test_fail_if_path_exists('//ForInStatNode') def reversed_range_step3_expr(int a, int b): """ >>> [ i for i in _reversed(range(0, 5, 3)) ] [3, 0] >>> reversed_range_step3_expr(0, 5) ([3, 0], 0) """ cdef int i = 99, c = 100 result = [] for i in reversed(range(c-c + a + c-c, c-c + b + c-c, 3)): result.append(i) return result, i @cython.test_assert_path_exists('//ForFromStatNode') @cython.test_fail_if_path_exists('//ForInStatNode') def reversed_range_step3_neg(int a, int b): """ >>> [ i for i in _reversed(range(0, -5, -3)) ] [-3, 0] >>> reversed_range_step3_neg(0, -5) ([-3, 0], 0) >>> [ i for i in _reversed(range(5, 0, -3)) ] [2, 5] >>> reversed_range_step3_neg(5, 0) ([2, 5], 5) >>> [ i for i in _reversed(range(0, 5, -3)) ] [] >>> reversed_range_step3_neg(0, 5) ([], 99) >>> [ i for i in _reversed(range(1, 1, -3)) ] [] >>> reversed_range_step3_neg(1, 1) ([], 99) """ cdef int i = 99 result = [] for i in reversed(range(a, b, -3)): result.append(i) return result, i @cython.test_assert_path_exists('//ForFromStatNode') @cython.test_fail_if_path_exists('//ForInStatNode') def reversed_range_step3_neg_expr(int a, int b): """ >>> [ i for i in _reversed(range(5, 0, -3)) ] [2, 5] >>> reversed_range_step3_neg_expr(5, 0) ([2, 5], 5) """ cdef int i = 99, c = 100 result = [] for i in reversed(range(c-c + a + c-c, c-c + b + c-c, -3)): result.append(i) return result, i def reversed_range_step3_py_args(a, b): """ >>> [ i for i in _reversed(range(-5, 0, 3)) ] [-2, -5] >>> reversed_range_step3_py_args(-5, 0) ([-2, -5], -5) >>> [ i for i in _reversed(range(0, 5, 3)) ] [3, 0] >>> reversed_range_step3_py_args(0, 5) ([3, 0], 0) >>> [ i for i in _reversed(range(5, 0, 3)) ] [] >>> reversed_range_step3_py_args(5, 0) ([], 99) >>> [ i for i in _reversed(range(1, 1, 3)) ] [] >>> reversed_range_step3_py_args(1, 1) ([], 99) >>> reversed_range_step3_py_args(set(), 1) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...integer... >>> reversed_range_step3_py_args(1, set()) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...integer... """ i = 99 result = [] for i in reversed(range(a, b, 3)): result.append(i) return result, i def reversed_range_step3_neg_py_args(a, b): """ >>> [ i for i in _reversed(range(0, -5, -3)) ] [-3, 0] >>> reversed_range_step3_neg_py_args(0, -5) ([-3, 0], 0) >>> [ i for i in _reversed(range(5, 0, -3)) ] [2, 5] >>> reversed_range_step3_neg_py_args(5, 0) ([2, 5], 5) >>> [ i for i in _reversed(range(0, 5, -3)) ] [] >>> reversed_range_step3_neg_py_args(0, 5) ([], 99) >>> [ i for i in _reversed(range(1, 1, -3)) ] [] >>> reversed_range_step3_neg_py_args(1, 1) ([], 99) >>> reversed_range_step3_neg_py_args(set(), 1) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...integer... >>> reversed_range_step3_neg_py_args(1, set()) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...integer... """ i = 99 result = [] for i in reversed(range(a, b, -3)): result.append(i) return result, i def reversed_range_step3_py_obj_left(a, int b): """ >>> reversed_range_step3_py_obj_left(set(), 0) Traceback (most recent call last): TypeError: an integer is required """ cdef long i result = [] for i in reversed(range(a, b, 3)): result.append(i) def reversed_range_step3_py_obj_right(int a, b): """ >>> reversed_range_step3_py_obj_right(0, set()) Traceback (most recent call last): TypeError: an integer is required """ cdef long i result = [] for i in reversed(range(a, b, 3)): result.append(i) def reversed_range_step3_neg_py_obj_left(a, int b): """ >>> reversed_range_step3_neg_py_obj_left(set(), 0) Traceback (most recent call last): TypeError: an integer is required """ cdef long i result = [] for i in reversed(range(a, b, -3)): result.append(i) def reversed_range_step3_neg_py_obj_right(int a, b): """ >>> reversed_range_step3_py_obj_right(0, set()) Traceback (most recent call last): TypeError: an integer is required """ cdef long i result = [] for i in reversed(range(a, b, -3)): result.append(i) @cython.test_fail_if_path_exists('//ForInStatNode') def reversed_range_constant(): """ >>> [ i for i in _reversed(range(-12, -2, 4)) ] [-4, -8, -12] >>> reversed_range_constant() ([-4, -8, -12], -12) """ cdef int i = 99 result = [] for i in reversed(range(1, 1, 4)): result.append(i) assert result == list(reversed(range(1, 1, 4))), result assert i == 99 for i in reversed(range(1, 1, 1)): result.append(i) assert result == list(reversed(range(1, 1, 1))), result result = [] for i in reversed(range(0, 1, 4)): result.append(i) assert result == list(reversed(range(0, 1, 4))), result result = [] for i in reversed(range(0, 1, 1)): result.append(i) assert result == list(reversed(range(0, 1, 1))), result result = [] for i in reversed(range(1, 8, 4)): result.append(i) assert result == list(reversed(range(1, 8, 4))), result result = [] for i in reversed(range(1, 8, 1)): result.append(i) assert result == list(reversed(range(1, 8, 1))), result result = [] for i in reversed(range(1, 9, 4)): result.append(i) assert result == list(reversed(range(1, 9, 4))), result result = [] for i in reversed(range(1, 10, 4)): result.append(i) assert result == list(reversed(range(1, 10, 4))), result result = [] for i in reversed(range(1, 11, 4)): result.append(i) assert result == list(reversed(range(1, 11, 4))), result result = [] for i in reversed(range(1, 12, 4)): result.append(i) assert result == list(reversed(range(1, 12, 4))), result result = [] for i in reversed(range(0, 8, 4)): result.append(i) assert result == list(reversed(range(0, 8, 4))), result result = [] for i in reversed(range(0, 9, 4)): result.append(i) assert result == list(reversed(range(0, 9, 4))), result result = [] for i in reversed(range(0, 10, 4)): result.append(i) assert result == list(reversed(range(0, 10, 4))), result result = [] for i in reversed(range(0, 11, 4)): result.append(i) assert result == list(reversed(range(0, 11, 4))), result result = [] for i in reversed(range(0, 12, 4)): result.append(i) assert result == list(reversed(range(0, 12, 4))), result i = 99 result = [] for i in reversed(range(-12, -2, 4)): result.append(i) assert result == list(reversed(range(-12, -2, 4))), result return result, i @cython.test_assert_path_exists('//ForFromStatNode') @cython.test_fail_if_path_exists('//ForInStatNode') def reversed_range_constant_neg(): """ >>> [ i for i in _reversed(range(-2, -12, -4)) ] [-10, -6, -2] >>> reversed_range_constant_neg() """ cdef int i = 99 result = [] for i in reversed(range(1, 1, -4)): result.append(i) assert result == list(reversed(range(1, 1, -4))), result assert i == 99 result = [] for i in reversed(range(1, 1, -1)): result.append(i) assert result == list(reversed(range(1, 1, -1))), result result = [] for i in reversed(range(1, 0, -4)): result.append(i) assert result == list(reversed(range(1, 0, -4))), result result = [] for i in reversed(range(1, 0, -1)): result.append(i) assert result == list(reversed(range(1, 0, -1))), result result = [] for i in reversed(range(8, 1, -4)): result.append(i) assert result == list(reversed(range(8, 1, -4))), result result = [] for i in reversed(range(8, 1, -1)): result.append(i) assert result == list(reversed(range(8, 1, -1))), result result = [] for i in reversed(range(9, 1, -4)): result.append(i) assert result == list(reversed(range(9, 1, -4))), result result = [] for i in reversed(range(9, 1, -1)): result.append(i) assert result == list(reversed(range(9, 1, -1))), result result = [] for i in reversed(range(10, 1, -4)): result.append(i) assert result == list(reversed(range(10, 1, -4))), result result = [] for i in reversed(range(11, 1, -4)): result.append(i) assert result == list(reversed(range(11, 1, -4))), result result = [] for i in reversed(range(11, 1, -1)): result.append(i) assert result == list(reversed(range(11, 1, -1))), result result = [] for i in reversed(range(12, 1, -4)): result.append(i) assert result == list(reversed(range(12, 1, -4))), result result = [] for i in reversed(range(12, 1, -1)): result.append(i) assert result == list(reversed(range(12, 1, -1))), result result = [] for i in reversed(range(8, 0, -4)): result.append(i) assert result == list(reversed(range(8, 0, -4))), result result = [] for i in reversed(range(8, 0, -1)): result.append(i) assert result == list(reversed(range(8, 0, -1))), result result = [] for i in reversed(range(9, 0, -4)): result.append(i) assert result == list(reversed(range(9, 0, -4))), result result = [] for i in reversed(range(9, 0, -1)): result.append(i) assert result == list(reversed(range(9, 0, -1))), result result = [] for i in reversed(range(10, 0, -4)): result.append(i) assert result == list(reversed(range(10, 0, -4))), result result = [] for i in reversed(range(10, 0, -1)): result.append(i) assert result == list(reversed(range(10, 0, -1))), result result = [] for i in reversed(range(11, 0, -4)): result.append(i) assert result == list(reversed(range(11, 0, -4))), result result = [] for i in reversed(range(11, 0, -1)): result.append(i) assert result == list(reversed(range(11, 0, -1))), result result = [] for i in reversed(range(12, 0, -4)): result.append(i) assert result == list(reversed(range(12, 0, -4))), result result = [] for i in reversed(range(12, 0, -1)): result.append(i) assert result == list(reversed(range(12, 0, -1))), result result = [] for i in reversed(range(-2, -12, -4)): result.append(i) assert result == list(reversed(range(-2, -12, -4))), result result = [] for i in reversed(range(-2, -12, -1)): result.append(i) assert result == list(reversed(range(-2, -12, -1))), result unicode_string = u"abcDEF" @cython.test_assert_path_exists('//ForFromStatNode') def reversed_unicode(unicode u): """ >>> print(''.join(_reversed(unicode_string))) FEDcba >>> print(''.join(reversed_unicode(unicode_string))) FEDcba """ result = [] for c in reversed(u): result.append(c) return result @cython.test_assert_path_exists('//ForFromStatNode') def reversed_unicode_slice(unicode u): """ >>> print(''.join(_reversed(unicode_string[1:-2]))) Dcb >>> print(''.join(reversed_unicode_slice(unicode_string))) Dcb """ result = [] for c in reversed(u[1:-2]): result.append(c) return result @cython.test_assert_path_exists('//ForFromStatNode') def reversed_unicode_slice_neg_step(unicode u): """ >>> print(''.join(_reversed(unicode_string[-2:1:-1]))) cDE >>> print(''.join(reversed_unicode_slice_neg_step(unicode_string))) cDE """ result = [] for c in reversed(u[-2:1:-1]): result.append(c) return result @cython.test_assert_path_exists('//ForFromStatNode') def reversed_unicode_slice_pos_step(unicode u): """ >>> print(''.join(_reversed(unicode_string[1:-2:1]))) Dcb >>> print(''.join(reversed_unicode_slice_pos_step(unicode_string))) Dcb """ result = [] for c in reversed(u[1:-2:1]): result.append(c) return result @cython.test_assert_path_exists('//ForFromStatNode') def reversed_unicode_slice_start_pos_step(unicode u): """ >>> print(''.join(_reversed(unicode_string[2::1]))) FEDc >>> print(''.join(reversed_unicode_slice_start_pos_step(unicode_string))) FEDc """ result = [] for c in reversed(u[2::1]): result.append(c) return result @cython.test_assert_path_exists('//ForFromStatNode') def reversed_unicode_slice_start_neg_step(unicode u): """ >>> print(''.join(_reversed(unicode_string[3::-1]))) abcD >>> print(''.join(reversed_unicode_slice_start_neg_step(unicode_string))) abcD """ result = [] for c in reversed(u[3::-1]): result.append(c) return result @cython.test_assert_path_exists('//ForFromStatNode') def reversed_unicode_slice_end_pos_step(unicode u): """ >>> print(''.join(_reversed(unicode_string[:-2:1]))) Dcba >>> print(''.join(reversed_unicode_slice_end_pos_step(unicode_string))) Dcba """ result = [] for c in reversed(u[:-2:1]): result.append(c) return result @cython.test_assert_path_exists('//ForFromStatNode') def reversed_unicode_slice_end_neg_step(unicode u): """ >>> print(''.join(_reversed(unicode_string[:-3:-1]))) EF >>> print(''.join(reversed_unicode_slice_end_neg_step(unicode_string))) EF """ result = [] for c in reversed(u[:-3:-1]): result.append(c) return result @cython.test_assert_path_exists('//ForFromStatNode') def reversed_unicode_slice_neg_step_only(unicode u): """ >>> print(''.join(_reversed(unicode_string[::-1]))) abcDEF >>> print(''.join(reversed_unicode_slice_neg_step_only(unicode_string))) abcDEF """ result = [] for c in reversed(u[::-1]): result.append(c) return result @cython.test_assert_path_exists('//ForFromStatNode') def reversed_unicode_slice_pos_step_only(unicode u): """ >>> print(''.join(_reversed(unicode_string[::1]))) FEDcba >>> print(''.join(reversed_unicode_slice_pos_step_only(unicode_string))) FEDcba """ result = [] for c in reversed(u[::1]): result.append(c) return result bytes_string = b'abcDEF' join_bytes = b''.join @cython.test_assert_path_exists('//ForFromStatNode') def reversed_bytes(bytes s): """ >>> b = IS_PY3 and bytes_string or map(ord, bytes_string) >>> list(_reversed(b)) [70, 69, 68, 99, 98, 97] >>> reversed_bytes(bytes_string) [70, 69, 68, 99, 98, 97] """ cdef char c result = [] for c in reversed(s): result.append(c) return result @cython.test_assert_path_exists('//ForFromStatNode') def reversed_bytes_slice(bytes s): """ >>> b = IS_PY3 and bytes_string or map(ord, bytes_string) >>> list(_reversed(b[1:-2])) [68, 99, 98] >>> reversed_bytes_slice(bytes_string) [68, 99, 98] """ cdef char c result = [] for c in reversed(s[1:-2]): result.append(c) return result @cython.test_assert_path_exists('//ForFromStatNode') def reversed_bytes_slice_step(bytes s): """ >>> b = IS_PY3 and bytes_string or map(ord, bytes_string) >>> list(_reversed(b[-2:1:-1])) [99, 68, 69] >>> reversed_bytes_slice_step(bytes_string) [99, 68, 69] """ cdef char c result = [] for c in reversed(s[-2:1:-1]): result.append(c) return result @cython.test_assert_path_exists('//ForFromStatNode') def reversed_bytes_slice_step_only(bytes s): """ >>> b = IS_PY3 and bytes_string or map(ord, bytes_string) >>> list(_reversed(b[::-1])) [97, 98, 99, 68, 69, 70] >>> reversed_bytes_slice_step_only(bytes_string) [97, 98, 99, 68, 69, 70] """ cdef char c result = [] for c in reversed(s[::-1]): result.append(c) return result @cython.test_assert_path_exists('//ForFromStatNode') def reversed_unsigned(int a, int b): """ >>> unlongify(reversed_unsigned(0, 5)) '[4, 3, 2, 1, 0]' >>> unlongify(reversed_unsigned(1, 5)) '[4, 3, 2, 1]' >>> reversed_unsigned(1, 1) [] """ cdef unsigned int i return [i for i in reversed(range(a, b))] @cython.test_assert_path_exists('//ForFromStatNode') def reversed_unsigned_by_3(int a, int b): """ >>> unlongify(reversed_unsigned_by_3(0, 5)) '[3, 0]' >>> unlongify(reversed_unsigned_by_3(0, 7)) '[6, 3, 0]' """ cdef unsigned int i return [i for i in reversed(range(a, b, 3))] @cython.test_assert_path_exists('//ForFromStatNode') def range_unsigned_by_neg_3(int a, int b): """ >>> unlongify(range_unsigned_by_neg_3(-1, 6)) '[6, 3, 0]' >>> unlongify(range_unsigned_by_neg_3(0, 7)) '[7, 4, 1]' """ cdef unsigned int i return [i for i in range(b, a, -3)] Cython-0.23.4/tests/run/return.pyx0000644000175600017570000000044312606202452020234 0ustar jenkinsjenkins00000000000000def f(a): """ >>> f('test') """ return return a return 42 cdef void g(): return cdef int h(a): cdef int i i = a return i def test_g(): """ >>> test_g() """ g() def test_h(i): """ >>> test_h(5) 5 """ return h(i) Cython-0.23.4/tests/run/reraise_3args.pyx0000644000175600017570000000064112606202452021446 0ustar jenkinsjenkins00000000000000 import sys class MyError(Exception): def __init__(self, name, var): self.name = name self.var = var def reraise_explicitly(): """ >>> try: reraise_explicitly() ... except MyError: print("RAISED!") ... else: print("NOT RAISED!") RAISED! """ try: raise MyError('Oh no!', 42) except MyError: tmp = sys.exc_info() raise tmp[0], tmp[1], tmp[2] Cython-0.23.4/tests/run/reraise.py0000644000175600017570000000132412606202452020156 0ustar jenkinsjenkins00000000000000 def reraise(): raise def test_reraise(): """ >>> test_reraise() Traceback (most recent call last): ValueError: TEST """ try: raise ValueError("TEST") except ValueError: raise def test_reraise_indirect(): """ >>> test_reraise_indirect() Traceback (most recent call last): ValueError: TEST INDIRECT """ try: raise ValueError("TEST INDIRECT") except ValueError: reraise() def test_reraise_error(): """ >>> try: test_reraise_error() ... except (RuntimeError, TypeError): pass # Py2, Py3, ... ... else: print("FAILED") """ import sys if hasattr(sys, 'exc_clear'): # Py2 sys.exc_clear() raise Cython-0.23.4/tests/run/relativeimport_star_T542.pyx0000644000175600017570000000027312606202452023533 0ustar jenkinsjenkins00000000000000from distutils import core, version __name__='distutils.core.cytest_relativeimport_T542' # fool Python we are in distutils from . import * __doc__ = """ >>> core.setup == setup True """ Cython-0.23.4/tests/run/relativeimport_T542.srctree0000644000175600017570000000251112606202452023326 0ustar jenkinsjenkins00000000000000# mode: run # tag: import """ PYTHON setup.py build_ext -i PYTHON test_relative_import.py """ ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize("*/*.pyx"), ) ######## test_relative_import.py ######## from relimport.testmod import test_relative, test_absolute a, bmod, afunc, bfunc = test_relative() try: test_absolute() except ImportError: pass else: assert False, "absolute import succeeded" import relimport.a import relimport.bmod import relimport.testmod assert relimport.a == a assert relimport.bmod == bmod assert afunc() == 'a', afunc assert bfunc() == 'b', bfunc ######## relimport/__init__.py ######## ######## relimport/a.pyx ######## def afunc(): return 'a' ######## relimport/bmod.pyx ######## def bfunc(): return 'b' ######## relimport/testmod.pyx ######## # cython: language_level=3 from relimport import a as global_a, bmod as global_bmod from . import * assert a is global_a, a assert bmod is global_bmod, bmod def test_relative(): from . import a, bmod from . import (a, bmod) from . import (a, bmod,) from .a import afunc from .bmod import bfunc assert afunc() == 'a', afunc() assert bfunc() == 'b', bfunc() return a, bmod, afunc, bfunc def test_absolute(): import bmod Cython-0.23.4/tests/run/relative_cimport.srctree0000644000175600017570000000235312606202452023116 0ustar jenkinsjenkins00000000000000# mode: run # tag: cimport PYTHON setup.py build_ext --inplace PYTHON -c "from pkg.b import test; assert test() == (1, 2)" PYTHON -c "from pkg.sub.c import test; assert test() == (1, 2)" ######## setup.py ######## from distutils.core import setup from Cython.Build import cythonize from Cython.Distutils.extension import Extension setup( ext_modules=cythonize('**/*.pyx'), ) ######## pkg/__init__.py ######## ######## pkg/sub/__init__.py ######## ######## pkg/a.pyx ######## from .sub.reimport cimport myint cdef myint i = 5 assert i == 5 cdef class test_pxd: pass ######## pkg/a.pxd ######## cdef class test_pxd: cdef public int x cdef public int y ######## pkg/b.pyx ######## from . cimport a from .a cimport test_pxd cimport a as implicitly_relative_a assert a.test_pxd is test_pxd assert implicitly_relative_a.test_pxd is test_pxd def test(): cdef test_pxd obj = test_pxd() obj.x = 1 obj.y = 2 return (obj.x, obj.y) ######## pkg/sub/c.pyx ######## from ..a cimport test_pxd def test(): cdef test_pxd obj = test_pxd() obj.x = 1 obj.y = 2 return (obj.x, obj.y) ######## pkg/sub/tdef.pxd ######## ctypedef int myint ######## pkg/sub/reimport.pxd ######## from .tdef cimport myint Cython-0.23.4/tests/run/reimport_from_package.srctree0000644000175600017570000000137212606202452024105 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import a" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize("**/*.pyx"), ) ######## a.pyx ######## import sys import a assert a in sys.modules.values(), list(sys.modules) assert sys.modules['a'] is a, list(sys.modules) from atest.package import module ######## atest/__init__.py ######## ######## atest/package/__init__.py ######## ######## atest/package/module.pyx ######## import sys assert 'atest.package.module' in sys.modules import a import atest.package.module as module assert module in sys.modules.values(), list(sys.modules) assert sys.modules['atest.package.module'] is module, list(sys.modules) Cython-0.23.4/tests/run/reimport.pyx0000644000175600017570000000032712606202452020557 0ustar jenkinsjenkins00000000000000# mode: run # tag: import # reimports at module init time used to be a problem in Py3 import reimport def test(): """ >>> test() True """ import sys return reimport in sys.modules.values() Cython-0.23.4/tests/run/refcount_in_meth.pyx0000644000175600017570000000236512606202452022252 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python __doc__=u""" >>> t = RefCountInMeth() >>> t.chk_meth() True >>> t.chk_nogil() True >>> t.chk_meth_if() True >>> t.chk_nogil_if() True """ from cpython.ref cimport PyObject def get_refcount(obj): return (obj).ob_refcnt cdef class RefCountInMeth(object): cdef double value def __cinit__(self): self.value = 1.5 cdef double c_get_value(self) nogil: return self.value cdef double c_get_value_if(self) nogil: cdef double v if 9>4: v = 2.3 return self.value cdef int c_meth(self): cdef int v v = get_refcount(self) return v cdef int c_meth_if(self): cdef int v if 5>6: v = 7 v = get_refcount(self) return v def chk_meth(self): cdef int a,b a = get_refcount(self) b = self.c_meth() return a==b def chk_meth_if(self): cdef int a,b a = get_refcount(self) b = self.c_meth_if() return a==b def chk_nogil(self): cdef double v v = self.c_get_value() return v==self.value def chk_nogil_if(self): cdef double v v = self.c_get_value_if() return v==self.value Cython-0.23.4/tests/run/ref2local.pyx0000644000175600017570000000011612606202452020563 0ustar jenkinsjenkins00000000000000def f(): """ >>> f() 42 """ a = 42 b = a return b Cython-0.23.4/tests/run/ref2global.py0000644000175600017570000000061712606202452020547 0ustar jenkinsjenkins00000000000000# mode: run # tag: global, nameerror try: from heapq import * # just to confuse the compiler except ImportError: pass def f(a): """ Py<=3.3 gives 'global name ...', Py3.4+ only 'name ...' >>> f(1) # doctest: +ELLIPSIS Traceback (most recent call last): NameError: ...name 'definitely_unknown_name' is not defined """ a = f a = definitely_unknown_name Cython-0.23.4/tests/run/reduce_pickle.pyx0000644000175600017570000000201712606202452021512 0ustar jenkinsjenkins00000000000000import sys if sys.version_info[0] < 3: __doc__ = """ >>> import cPickle >>> a = A(5); a A(5) >>> cPickle.loads(cPickle.dumps(a)) A(5) >>> b = B(0, 1); b B(x=0, y=1) >>> cPickle.loads(cPickle.dumps(b)) B(x=0, y=1) """ cdef class A: """ >>> a = A(3); a A(3) >>> import pickle >>> pickle.loads(pickle.dumps(a)) A(3) """ cdef int value def __init__(self, value): self.value = value def __repr__(self): return "A(%s)" % self.value def __reduce__(self): return A, (self.value,) cdef class B: """ >>> b = B(x=37, y=389); b B(x=37, y=389) >>> import pickle >>> pickle.loads(pickle.dumps(b)) B(x=37, y=389) """ cdef int x, y def __init__(self, x=0, y=0): self.x = x self.y = y def __repr__(self): return "B(x=%s, y=%s)" % (self.x, self.y) def __reduce__(self): return makeB, ({'x': self.x, 'y': self.y},) def makeB(kwds): return B(**kwds) Cython-0.23.4/tests/run/range_optimisation_T203.pyx0000644000175600017570000000515312606202452023323 0ustar jenkinsjenkins00000000000000# ticket: 203 cdef int get_bound(int m): print u"get_bound(%s)"%m return m def for_from_range(a, b): """ >>> for_from_range(5, 10) range(5) at 0 at 1 at 2 at 3 at 4 range(5, 10) at 5 at 6 at 7 at 8 at 9 range(5, 10, 2) at 5 at 7 at 9 9 >>> for_from_range(-5, -10) range(-5) range(-5, -10) range(-5, -10, 2) 100 """ cdef int i = 100 print u"range(%s)" % a for i in range(a): print u"at", i print u"range(%s, %s)" % (a, b) for i in range(a, b): print u"at", i print u"range(%s, %s, %s)" % (a, b, 2) for i in range(a, b, 2): print u"at", i return i def for_from_bound_reassignment(int bound, int fake_bound): """ >>> for_from_bound_reassignment(5, 1) at 0 at 1 at 2 at 3 at 4 5 """ cdef int i = 100 for i from 0 <= i < bound: print u"at", i bound = fake_bound return i def for_from_step_reassignment(int bound, int step, int fake_step): """ >>> for_from_step_reassignment(15, 5, 2) at 0 at 5 at 10 15 """ cdef int i = 100 for i from 0 <= i < bound by step: print u"at", i step = fake_step return i def for_from_target_reassignment(int bound, int factor): """ >>> for_from_target_reassignment(10, 2) at 0 at 1 at 3 at 7 15 """ cdef int i = 100 for i from 0 <= i < bound: print u"at", i i *= factor return i def for_from_py_target_reassignment(int bound, int factor): """ >>> for_from_py_target_reassignment(10, 2) at 0 at 1 at 3 at 7 15 """ cdef object i for i from 0 <= i < bound: print u"at", i i *= factor return i def for_from_py_global_target_reassignment(int bound, int factor): """ >>> for_from_py_global_target_reassignment(10, 2) at 0 at 1 at 3 at 7 15 """ global g_var for g_var from 0 <= g_var < bound: print u"at", g_var g_var *= factor return g_var def for_in_target_reassignment(int bound, int factor): """ >>> for_in_target_reassignment(10, 2) at 0 at 1 at 2 at 3 at 4 at 5 at 6 at 7 at 8 at 9 18 """ cdef int i = 100 for i in range(bound): print u"at", i i *= factor return i def test_func(int n): """ >>> test_func(5) get_bound(5) at 0 at 1 at 2 at 3 at 4 5 """ cdef int i = 100 for i from 0 <= i < get_bound(n): print u"at", i return i Cython-0.23.4/tests/run/raise_memory_error_T650.pyx0000644000175600017570000000171212606202452023337 0ustar jenkinsjenkins00000000000000# ticket: 650 cimport cython @cython.test_assert_path_exists( '//RaiseStatNode', '//RaiseStatNode[@builtin_exc_name = "MemoryError"]') def raise_me_type(): """ >>> try: raise_me_type() ... except MemoryError: pass ... else: print('NOT RAISED!') """ raise MemoryError @cython.test_assert_path_exists( '//RaiseStatNode', '//RaiseStatNode[@builtin_exc_name = "MemoryError"]') def raise_me_instance(): """ >>> try: raise_me_instance() ... except MemoryError: pass ... else: print('NOT RAISED!') """ raise MemoryError() def raise_me_instance_value(): """ >>> raise_me_instance_value() Traceback (most recent call last): ... MemoryError: oom """ raise MemoryError("oom") def raise_me_instance_value_separate(): """ >>> raise_me_instance_value_separate() Traceback (most recent call last): ... MemoryError: oom """ raise MemoryError, "oom" Cython-0.23.4/tests/run/r_vree_1.pyx0000644000175600017570000000131412606202452020415 0ustar jenkinsjenkins00000000000000import sys if sys.version_info[0] < 3: __doc__ = u""" >>> test(0) 0L >>> test(1) 1L >>> sys.maxint + 1 > sys.maxint True >>> type(sys.maxint * 2 + 1) is long True >>> test(sys.maxint + 1) == sys.maxint + 1 True >>> test(sys.maxint * 2 + 1) == sys.maxint * 2 + 1 True >>> test(256 ** unsigned_long_size() - 1) > 0 True >>> test(256 ** unsigned_long_size() - 1) > sys.maxint True """ else: __doc__ = u""" >>> test(0) 0 >>> test(1) 1 >>> test(256 ** unsigned_long_size() - 1) > 0 True """ def test(k): cdef unsigned long m m = k return m def unsigned_long_size(): return sizeof(unsigned long) Cython-0.23.4/tests/run/r_uintindex.pyx0000644000175600017570000000043112606202452021242 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> print(idx_uint( ["buckle", "my", "shoe"], 2)) shoe >>> print(idx_ulong(["buckle", "my", "shoe"], 2)) shoe """ def idx_ulong(seq, i): cdef unsigned long u u = i return seq[u] def idx_uint(seq, i): cdef unsigned int u u = i return seq[u] Cython-0.23.4/tests/run/r_typecast.pyx0000644000175600017570000000035112606202452021070 0ustar jenkinsjenkins00000000000000cdef class ExtType: cdef c_method(self): return self def method(self): return 1 def call_method(ExtType et): """ >>> call_method( ExtType() ).method() 1 """ return et.c_method() Cython-0.23.4/tests/run/r_toofewargs.pyx0000644000175600017570000000033312606202452021414 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> s = Spam() Traceback (most recent call last): TypeError: __init__() takes exactly 3 positional arguments (0 given) """ cdef class Spam: def __init__(self, a, b, int c): pass Cython-0.23.4/tests/run/r_starargsonly.pyx0000644000175600017570000000030712606202452021765 0ustar jenkinsjenkins00000000000000def spam(*args): """ >>> spam() Args: () >>> spam(42) Args: (42,) >>> spam("one", 2, "buckle my shoe") Args: ('one', 2, 'buckle my shoe') """ print u"Args:", args Cython-0.23.4/tests/run/r_starargs.pyx0000644000175600017570000000156712606202452021074 0ustar jenkinsjenkins00000000000000def swallow(name, airspeed, *args, **kwds): """ >>> swallow("Brian", 42) Name: Brian Airspeed: 42 Extra args: () Extra keywords: [] >>> swallow("Brian", 42, "African") Name: Brian Airspeed: 42 Extra args: ('African',) Extra keywords: [] >>> swallow("Brian", airspeed = 42) Name: Brian Airspeed: 42 Extra args: () Extra keywords: [] >>> swallow("Brian", airspeed = 42, species = "African", coconuts = 3) Name: Brian Airspeed: 42 Extra args: () Extra keywords: [('coconuts', 3), ('species', 'African')] >>> swallow("Brian", 42, "African", coconuts = 3) Name: Brian Airspeed: 42 Extra args: ('African',) Extra keywords: [('coconuts', 3)] """ print u"Name:", name print u"Airspeed:", airspeed print u"Extra args:", args print u"Extra keywords:", sorted(kwds.items()) Cython-0.23.4/tests/run/r_starargcall.pyx0000644000175600017570000000027412606202452021537 0ustar jenkinsjenkins00000000000000def spam(a, b, c): print u"Args:", a, b, c def eggs(): """ >>> eggs() Args: 1 2 3 Args: buckle my shoe """ spam(*(1,2,3)) spam(*[u"buckle",u"my",u"shoe"]) Cython-0.23.4/tests/run/r_spamtype.pyx0000644000175600017570000000107412606202452021101 0ustar jenkinsjenkins00000000000000__doc__ = """ >>> s = Spam() >>> s.get_tons() 17 >>> s.set_tons(42) >>> s.get_tons() 42 """ import platform if not hasattr(platform, 'python_implementation') or platform.python_implementation() == 'CPython': __doc__ += """ >>> s = None 42 tons of spam is history. """ cdef class Spam: cdef int tons def __cinit__(self): self.tons = 17 def __dealloc__(self): print self.tons, u"tons of spam is history." def get_tons(self): return self.tons def set_tons(self, x): self.tons = x Cython-0.23.4/tests/run/r_pythonapi.pyx0000644000175600017570000000064612606202452021256 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> x = spam() >>> print(repr(x)) u'Ftang\\x00Ftang!' """ import sys if sys.version_info[0] >= 3: __doc__ = __doc__.replace(u" u'", u" '") cdef extern from "string.h": void memcpy(char *d, char *s, int n) from cpython cimport PyUnicode_DecodeUTF8 def spam(): cdef char[12] buf memcpy(buf, "Ftang\0Ftang!", sizeof(buf)) return PyUnicode_DecodeUTF8(buf, sizeof(buf), NULL) Cython-0.23.4/tests/run/r_pyclassdefault.pyx0000644000175600017570000000121612606202452022260 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> c = CoconutCarrier() >>> c.swallow(name = "Brian") This swallow is called Brian >>> c.swallow(airspeed = 42) This swallow is flying at 42 furlongs per fortnight >>> c.swallow(coconuts = 3) This swallow is carrying 3 coconuts """ class CoconutCarrier: def swallow(self, name = None, airspeed = None, coconuts = None): if name is not None: print u"This swallow is called", name if airspeed is not None: print u"This swallow is flying at", airspeed, u"furlongs per fortnight" if coconuts is not None: print u"This swallow is carrying", coconuts, u"coconuts" Cython-0.23.4/tests/run/r_pyclass.pyx0000644000175600017570000000034412606202452020714 0ustar jenkinsjenkins00000000000000class Spam: def __init__(self, w): self.weight = w def serve(self): print self.weight, u"tons of spam!" def order(): """ >>> order() 42 tons of spam! """ s = Spam(42) s.serve() Cython-0.23.4/tests/run/r_print.pyx0000644000175600017570000000023412606202452020370 0ustar jenkinsjenkins00000000000000def frighten(): """ >>> frighten() NOBODY expects the Spanish Inquisition! """ print u"NOBODY", u"expects", u"the Spanish Inquisition!" Cython-0.23.4/tests/run/r_primes.pyx0000644000175600017570000000073612606202452020542 0ustar jenkinsjenkins00000000000000def primes(int kmax): """ >>> primes(20) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] """ cdef int n, k, i cdef int[1000] p result = [] if kmax > 1000: kmax = 1000 k = 0 n = 2 while k < kmax: i = 0 while i < k and n % p[i] <> 0: i = i + 1 if i == k: p[k] = n k = k + 1 result.append(n) n = n + 1 return result Cython-0.23.4/tests/run/r_mitch_chapman_2.pyx0000644000175600017570000000027012606202452022250 0ustar jenkinsjenkins00000000000000def boolExpressionsFail(): """ >>> boolExpressionsFail() 'Not 2b' """ dict = {1: 1} if not "2b" in dict: return "Not 2b" else: return "2b?" Cython-0.23.4/tests/run/r_mcintyre1.pyx0000644000175600017570000000041412606202452021147 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> b = Bicycle() >>> b.fall_off() Falling off extremely hard >>> b.fall_off("somewhat") Falling off somewhat hard """ class Bicycle: def fall_off(self, how_hard = u"extremely"): print u"Falling off", how_hard, u"hard" Cython-0.23.4/tests/run/r_mang1.pyx0000644000175600017570000000050512606202452020240 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> import re >>> t (u'2',) >>> t == re.search('(\\d+)', '-2.80 98\\n').groups() True """ import sys if sys.version_info[0] >= 3: __doc__ = __doc__.replace(u"(u'", u"('") # this is a string constant test, not a test for 're' import re t = re.search(u'(\d+)', u'-2.80 98\n').groups() Cython-0.23.4/tests/run/r_lepage_3.pyx0000644000175600017570000000034112606202452020712 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> g = Grail() >>> g("spam", 42, ["tomato", "sandwich"]) Grail called with: spam 42 ['tomato', 'sandwich'] """ cdef class Grail: def __call__(self, x, y, z): print u"Grail called with:", x, y, z Cython-0.23.4/tests/run/r_jiba1.pyx0000644000175600017570000000066512606202452020232 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> test() This parrot is resting. Lovely plumage! """ cdef class Parrot: cdef void describe(self): print u"This parrot is resting." def describe_python(self): self.describe() cdef class Norwegian(Parrot): cdef void describe(self): print u"Lovely plumage!" def test(): cdef Parrot p1, p2 p1 = Parrot() p2 = Norwegian() p1.describe() p2.describe() Cython-0.23.4/tests/run/r_jiba1.pxd0000644000175600017570000000012212606202452020171 0ustar jenkinsjenkins00000000000000cdef class Parrot: cdef void describe(self) cdef class Norwegian(Parrot): pass Cython-0.23.4/tests/run/r_jeff_epler_1.pyx0000644000175600017570000000017212606202452021556 0ustar jenkinsjenkins00000000000000def blowup(p): """ >>> blowup([2, 3, 5]) 1 """ cdef int n, i n = 10 i = 1 return n % p[i] Cython-0.23.4/tests/run/r_huss3.pyx0000644000175600017570000000100712606202452020300 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> try: ... foo() ... except Exception, e: ... print("%s: %s" % (e.__class__.__name__, e)) ValueError: >>> try: ... bar() ... except Exception, e: ... print("%s: %s" % (e.__class__.__name__, e)) """ import sys if sys.version_info[0] >= 3: __doc__ = __doc__.replace(u"Exception, e", u"Exception as e") def bar(): try: raise TypeError except TypeError: pass def foo(): try: raise ValueError except ValueError, e: bar() raise Cython-0.23.4/tests/run/r_hordijk1.pyx0000644000175600017570000000103112606202452020743 0ustar jenkinsjenkins00000000000000__doc__ = """ >>> try: ... s = Spam() ... except KeyError, e: ... print("Exception: %s" % e) ... else: ... print("Did not raise the expected exception") Exception: 'This is not a spanish inquisition' """ import sys if sys.version_info[0] >= 3: __doc__ = __doc__.replace("Error, e", "Error as e") cdef extern from "Python.h": ctypedef class __builtin__.list [object PyListObject]: pass cdef class Spam(list): def __init__(self): raise KeyError("This is not a spanish inquisition") Cython-0.23.4/tests/run/r_forloop.pyx0000644000175600017570000000546212606202452020724 0ustar jenkinsjenkins00000000000000def go_py(): """ >>> go_py() Spam! Spam! Spam! Spam! """ for i in range(4): print u"Spam!" def go_py_ret(): """ >>> go_py_ret() 2 """ for i in range(4): if i > 1: return i def go_c(): """ >>> go_c() Spam! Spam! Spam! Spam! """ cdef int i for i in range(4): print u"Spam!" def go_c_enumerate(): """ >>> go_c_enumerate() True True True True """ cdef int i,k for i,k in enumerate(range(4)): print i == k def go_c_int(int a, int b): """ >>> go_c_int(1,5) Spam! Spam! """ cdef int i for i in range(a,b,2): print u"Spam!" def go_c_all(): """ >>> go_c_all() Spam! Spam! Spam! """ cdef int i for i in range(8,2,-2): print u"Spam!" def go_c_all_exprs(x): """ >>> go_c_all_exprs(1) Spam! >>> go_c_all_exprs(3) Spam! Spam! """ cdef int i for i in range(4*x,2*x,-3): print u"Spam!" def go_c_const_exprs(): """ >>> go_c_const_exprs() Spam! Spam! """ cdef int i for i in range(4*2+1,2*2,-2-1): print u"Spam!" def f(x): return 2*x def go_c_calc(x): """ >>> go_c_calc(2) Spam! Spam! """ cdef int i for i in range(2*f(x),f(x), -2): print u"Spam!" def go_c_calc_ret(x): """ >>> go_c_calc_ret(2) 6 """ cdef int i for i in range(2*f(x),f(x), -2): if i < 2*f(x): return i def go_c_ret(): """ >>> go_c_ret() 2 """ cdef int i for i in range(4): if i > 1: return i def go_list(): """ >>> go_list() Spam! Spam! Spam! Spam! """ cdef list l = list(range(4)) for i in l: print u"Spam!" def go_list_ret(): """ >>> go_list_ret() 2 """ cdef list l = list(range(4)) for i in l: if i > 1: return i def go_tuple(): """ >>> go_tuple() Spam! Spam! Spam! Spam! """ cdef tuple t = tuple(range(4)) for i in t: print u"Spam!" def go_tuple_ret(): """ >>> go_tuple_ret() 2 """ cdef tuple t = tuple(range(4)) for i in t: if i > 1: return i def go_dict(): """ >>> go_dict() Spam! Spam! Spam! Spam! """ cdef dict d = dict(zip(range(4), range(4))) for i in d: print u"Spam!" def go_dict_ret(): """ >>> go_dict_ret() 2 >>> global_result 6 """ cdef dict d = dict(zip(range(4), range(4))) for i in d: if i > 1 and i < 3: return i # test global scope also global_result = None cdef int i for i in range(4*2+1,2*2,-2-1): if i < 7: global_result = i break Cython-0.23.4/tests/run/r_extstarargs.pyx0000644000175600017570000000162112606202452021604 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> s = Swallow("Brian", 42) Name: Brian Airspeed: 42 Extra args: () Extra keywords: [] >>> s = Swallow("Brian", 42, "African") Name: Brian Airspeed: 42 Extra args: ('African',) Extra keywords: [] >>> s = Swallow("Brian", airspeed = 42) Name: Brian Airspeed: 42 Extra args: () Extra keywords: [] >>> s = Swallow("Brian", airspeed = 42, species = "African", coconuts = 3) Name: Brian Airspeed: 42 Extra args: () Extra keywords: [('coconuts', 3), ('species', 'African')] >>> s = Swallow("Brian", 42, "African", coconuts = 3) Name: Brian Airspeed: 42 Extra args: ('African',) Extra keywords: [('coconuts', 3)] """ cdef class Swallow: def __init__(self, name, airspeed, *args, **kwds): print u"Name:", name print u"Airspeed:", airspeed print u"Extra args:", args print u"Extra keywords:", sorted(kwds.items()) Cython-0.23.4/tests/run/r_extcomplex2.pyx0000644000175600017570000000065512606202452021515 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> c = eggs() >>> c (17+42j) >>> spam(c) Real: 17.0 Imag: 42.0 """ cdef extern from "complexobject.h": struct Py_complex: double real double imag ctypedef class __builtin__.complex [object PyComplexObject]: cdef Py_complex cval def spam(complex c): print u"Real:", c.cval.real print u"Imag:", c.cval.imag def eggs(): return complex(17, 42) Cython-0.23.4/tests/run/r_docstrings.pyx0000644000175600017570000000351012606202452021413 0ustar jenkinsjenkins00000000000000# Some comments first # More comments 'A module docstring' doctest = u"""# Python 3 gets all of these right ... >>> __doc__ 'A module docstring' >>> f.__doc__ '\\n This is a function docstring.\\n ' >>> C.__doc__ '\\n This is a class docstring.\\n ' >>> CS.__doc__ '\\n This is a subclass docstring.\\n ' >>> print(CSS.__doc__) None >>> T.__doc__ '\\n This is an extension type docstring.\\n ' >>> TS.__doc__ '\\n This is an extension subtype docstring.\\n ' >>> TSS.__doc__ Compare with standard Python: >>> def Pyf(): ... ''' ... This is a function docstring. ... ''' >>> Pyf.__doc__ '\\n This is a function docstring.\\n ' >>> class PyC: ... ''' ... This is a class docstring. ... ''' >>> class PyCS(C): ... ''' ... This is a subclass docstring. ... ''' >>> class PyCSS(CS): ... pass >>> PyC.__doc__ '\\n This is a class docstring.\\n ' >>> PyCS.__doc__ '\\n This is a subclass docstring.\\n ' >>> PyCSS.__doc__ """ __test__ = {"test_docstrings" : doctest} def f(): """ This is a function docstring. """ class C: """ This is a class docstring. """ class CS(C): """ This is a subclass docstring. """ class CSS(CS): pass cdef class T: """ This is an extension type docstring. """ cdef class TS(T): """ This is an extension subtype docstring. """ cdef class TSS(TS): pass def n(): "This is not a docstring".lower() class PyN(object): u"This is not a docstring".lower() cdef class CN(object): b"This is not a docstring".lower() def test_non_docstrings(): """ >>> n.__doc__ >>> PyN.__doc__ >>> CN.__doc__ """ Cython-0.23.4/tests/run/r_delgado_1.pyx0000644000175600017570000000050012606202452021047 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> try: ... eggs().eat() ... except RuntimeError: ... import sys ... e = sys.exc_info()[1] ... print("%s: %s" % (e.__class__.__name__, e)) RuntimeError: I don't like that """ cdef class eggs: def __dealloc__(self): pass def eat(self): raise RuntimeError(u"I don't like that") Cython-0.23.4/tests/run/r_bowden1.pyx0000644000175600017570000000040712606202452020575 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> f(100) 101L >>> g(3000000000) 3000000001L """ import sys if sys.version_info[0] >= 3: __doc__ = __doc__.replace(u"L", u"") def f(x): cdef unsigned long long ull ull = x return ull + 1 def g(unsigned long x): return x + 1 Cython-0.23.4/tests/run/r_bishop3.pyx0000644000175600017570000000051312606202452020603 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> foo = Foo() >>> fee = Fee() >>> faa = Faa() >>> fee.bof() Fee bof 0 >>> faa.bof() Foo bof 0 """ cdef class Foo: cdef int val def __init__(self): self.val = 0 cdef class Fee(Foo): def bof(self): print u'Fee bof', self.val cdef class Faa(Fee): def bof(self): print u'Foo bof', self.val Cython-0.23.4/tests/run/r_barbieri1.pyx0000644000175600017570000000062212606202452021075 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> try: ... B() ... except Exception, e: ... print("%s: %s" % (e.__class__.__name__, e)) Exception: crash-me """ import sys if sys.version_info[0] >= 3: __doc__ = __doc__.replace(u"Exception, e", u"Exception as e") cdef class A: def __cinit__(self): raise Exception(u"crash-me") cdef class B(A): def __cinit__(self): print "hello world" Cython-0.23.4/tests/run/r_argdefault.pyx0000644000175600017570000000107412606202452021355 0ustar jenkinsjenkins00000000000000def swallow(name = None, airspeed = None, coconuts = None): """ >>> swallow(name = "Brian") This swallow is called Brian >>> swallow(airspeed = 42) This swallow is flying at 42 furlongs per fortnight >>> swallow(coconuts = 3) This swallow is carrying 3 coconuts """ if name is not None: print u"This swallow is called", name if airspeed is not None: print u"This swallow is flying at", airspeed, u"furlongs per fortnight" if coconuts is not None: print u"This swallow is carrying", coconuts, u"coconuts" Cython-0.23.4/tests/run/r_addint.pyx0000644000175600017570000000057112606202452020503 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> def test(a, b): ... return (a, b, add(a, b)) >>> test(1, 2) (1, 2, 3) >>> [ repr(f) for f in test(17.25, 88.5) ] ['17.25', '88.5', '105.75'] >>> test(u'eggs', u'spam') (u'eggs', u'spam', u'eggsspam') """ import sys if sys.version_info[0] >= 3: __doc__ = __doc__.replace(u"u'", u"'") def add(x, y): return x + y Cython-0.23.4/tests/run/qualname.pyx0000644000175600017570000000361712606202452020526 0ustar jenkinsjenkins00000000000000# cython: binding=True # mode: run # tag: cyfunction,qualname import sys def test_qualname(): """ >>> test_qualname.__qualname__ 'test_qualname' >>> test_qualname.__qualname__ = 123 #doctest:+ELLIPSIS Traceback (most recent call last): TypeError: __qualname__ must be set to a ... object >>> test_qualname.__qualname__ = 'foo' >>> test_qualname.__qualname__ 'foo' """ def test_builtin_qualname(): """ >>> test_builtin_qualname() list.append len """ if sys.version_info >= (3, 3): print([1, 2, 3].append.__qualname__) print(len.__qualname__) else: print('list.append') print('len') def test_nested_qualname(): """ >>> outer, lambda_func, XYZ = test_nested_qualname() >>> outer().__qualname__ 'test_nested_qualname..outer..Test' >>> outer().test.__qualname__ 'test_nested_qualname..outer..Test.test' >>> outer()().test.__qualname__ 'test_nested_qualname..outer..Test.test' >>> outer()().test().__qualname__ 'XYZinner' >>> outer()().test().Inner.__qualname__ 'XYZinner.Inner' >>> outer()().test().Inner.inner.__qualname__ 'XYZinner.Inner.inner' >>> lambda_func.__qualname__ 'test_nested_qualname..' >>> XYZ.__qualname__ 'XYZ' >>> XYZ.Inner.__qualname__ 'XYZ.Inner' >>> XYZ.Inner.inner.__qualname__ 'XYZ.Inner.inner' """ def outer(): class Test(object): def test(self): global XYZinner class XYZinner: class Inner: def inner(self): pass return XYZinner return Test global XYZ class XYZ(object): class Inner(object): def inner(self): pass return outer, lambda:None, XYZ Cython-0.23.4/tests/run/pytype.pyx0000644000175600017570000000060112606202452020243 0ustar jenkinsjenkins00000000000000from cpython.type cimport PyType_IsSubtype class mylist(list): pass def test_issubtype(a, b): """ >>> test_issubtype(mylist, list) True >>> test_issubtype(mylist, dict) False >>> o = object() >>> test_issubtype(o, list) Traceback (most recent call last): ... TypeError: Cannot convert object to type """ return PyType_IsSubtype(a, b) Cython-0.23.4/tests/run/python_bool_type.pyx0000644000175600017570000001172112606202452022313 0ustar jenkinsjenkins00000000000000 # tests copied from test/test_bool.py in Py2.7 cdef assertEqual(a,b): assert a == b, '%r != %r' % (a,b) cdef assertIs(a,b): assert a is b, '%r is not %r' % (a,b) cdef assertIsNot(a,b): assert a is not b, '%r is %r' % (a,b) cdef assertNotIsInstance(a,b): assert not isinstance(a,b), 'isinstance(%r, %s)' % (a,b) def test_int(): """ >>> test_int() """ assertEqual(int(False), 0) assertIsNot(int(False), False) assertEqual(int(True), 1) assertIsNot(int(True), True) def test_float(): """ >>> test_float() """ assertEqual(float(False), 0.0) assertIsNot(float(False), False) assertEqual(float(True), 1.0) assertIsNot(float(True), True) def test_repr(): """ >>> test_repr() """ assertEqual(repr(False), 'False') assertEqual(repr(True), 'True') assertEqual(eval(repr(False)), False) assertEqual(eval(repr(True)), True) def test_str(): """ >>> test_str() """ assertEqual(str(False), 'False') assertEqual(str(True), 'True') def test_math(): """ >>> test_math() """ assertEqual(+False, 0) assertIsNot(+False, False) assertEqual(-False, 0) assertIsNot(-False, False) assertEqual(abs(False), 0) assertIsNot(abs(False), False) assertEqual(+True, 1) assertIsNot(+True, True) assertEqual(-True, -1) assertEqual(abs(True), 1) assertIsNot(abs(True), True) assertEqual(~False, -1) assertEqual(~True, -2) assertEqual(False+2, 2) assertEqual(True+2, 3) assertEqual(2+False, 2) assertEqual(2+True, 3) assertEqual(False+False, 0) assertIsNot(False+False, False) assertEqual(False+True, 1) assertIsNot(False+True, True) assertEqual(True+False, 1) assertIsNot(True+False, True) assertEqual(True+True, 2) assertEqual(True-True, 0) assertIsNot(True-True, False) assertEqual(False-False, 0) assertIsNot(False-False, False) assertEqual(True-False, 1) assertIsNot(True-False, True) assertEqual(False-True, -1) assertEqual(True*1, 1) assertEqual(False*1, 0) assertIsNot(False*1, False) assertEqual(True/1, 1) assertIsNot(True/1, True) assertEqual(False/1, 0) assertIsNot(False/1, False) for b in False, True: for i in 0, 1, 2: assertEqual(b**i, int(b)**i) assertIsNot(b**i, bool(int(b)**i)) for a in False, True: for b in False, True: assertIs(a&b, bool(int(a)&int(b))) assertIs(a|b, bool(int(a)|int(b))) assertIs(a^b, bool(int(a)^int(b))) assertEqual(a&int(b), int(a)&int(b)) assertIsNot(a&int(b), bool(int(a)&int(b))) assertEqual(a|int(b), int(a)|int(b)) assertIsNot(a|int(b), bool(int(a)|int(b))) assertEqual(a^int(b), int(a)^int(b)) assertIsNot(a^int(b), bool(int(a)^int(b))) assertEqual(int(a)&b, int(a)&int(b)) assertIsNot(int(a)&b, bool(int(a)&int(b))) assertEqual(int(a)|b, int(a)|int(b)) assertIsNot(int(a)|b, bool(int(a)|int(b))) assertEqual(int(a)^b, int(a)^int(b)) assertIsNot(int(a)^b, bool(int(a)^int(b))) assertIs(1==1, True) assertIs(1==0, False) assertIs(0<1, True) assertIs(1<0, False) assertIs(0<=0, True) assertIs(1<=0, False) assertIs(1>0, True) assertIs(1>1, False) assertIs(1>=1, True) assertIs(0>=1, False) assertIs(0!=1, True) assertIs(0!=0, False) x = [1] assertIs(x is x, True) assertIs(x is not x, False) assertIs(1 in x, True) assertIs(0 in x, False) assertIs(1 not in x, False) assertIs(0 not in x, True) x = {1: 2} assertIs(x is x, True) assertIs(x is not x, False) assertIs(1 in x, True) assertIs(0 in x, False) assertIs(1 not in x, False) assertIs(0 not in x, True) assertIs(not True, False) assertIs(not False, True) def test_convert(): """ >>> test_convert() """ assertIs(bool(10), True) assertIs(bool(1), True) assertIs(bool(-1), True) assertIs(bool(0), False) assertIs(bool("hello"), True) assertIs(bool(""), False) assertIs(bool(), False) def test_isinstance(): """ >>> test_isinstance() """ assertIs(isinstance(True, bool), True) assertIs(isinstance(False, bool), True) assertIs(isinstance(True, int), True) assertIs(isinstance(False, int), True) assertIs(isinstance(1, bool), False) assertIs(isinstance(0, bool), False) def test_issubclass(): """ >>> test_issubclass() """ assertIs(issubclass(bool, int), True) assertIs(issubclass(int, bool), False) def test_boolean(): """ >>> test_boolean() """ assertEqual(True & 1, 1) assertNotIsInstance(True & 1, bool) assertIs(True & True, True) assertEqual(True | 1, 1) assertNotIsInstance(True | 1, bool) assertIs(True | True, True) assertEqual(True ^ 1, 0) assertNotIsInstance(True ^ 1, bool) assertIs(True ^ True, False) Cython-0.23.4/tests/run/pyparam_nogil.pyx0000644000175600017570000000045212606202452021556 0ustar jenkinsjenkins00000000000000 def if_list_nogil(list obj): """ >>> if_list_nogil( [] ) False >>> if_list_nogil( [1] ) True >>> if_list_nogil(None) False """ return _if_list_nogil(obj) cdef bint _if_list_nogil(list obj) nogil: if obj: return True else: return False Cython-0.23.4/tests/run/pyobjcast_T313.pyx0000644000175600017570000000051712606202452021427 0ustar jenkinsjenkins00000000000000# ticket: 313 # Ensure casting still works to void* """ >>> o = f() >>> print(o[0]) teststring >>> print(o[1]) teststring """ cdef extern from *: ctypedef void PyObject def f(): cdef void* p1 cdef PyObject* p2 cdef object a = u"teststring" p1 = a p2 = a return (p1, p2) Cython-0.23.4/tests/run/pynumop.pyx0000644000175600017570000000037112606202452020424 0ustar jenkinsjenkins00000000000000def f(): """ >>> f() 6 """ obj1 = 1 obj2 = 2 obj3 = 3 obj1 = obj2 * obj3 return obj1 def g(): """ >>> g() 2 """ obj1 = 12 obj2 = 6 obj3 = 3 obj1 = obj2 / obj3 return int(obj1) Cython-0.23.4/tests/run/pynumber_subtype_conversion.pyx0000644000175600017570000000073112606202452024576 0ustar jenkinsjenkins00000000000000# mode: run # tag: python, float, builtin class MyFloat(float): """ >>> x = MyFloat(1.0) >>> x 1.0 >>> float(x) 12.0 >>> x.float() 12.0 """ def __float__(self): return 12.0 def float(self): return float(self) class MyInt(int): """ >>> x = MyInt(1) >>> x 1 >>> int(x) 2 >>> x.int() 2 """ def __int__(self): return 2 def int(self): return int(self) Cython-0.23.4/tests/run/pylistsubtype.pyx0000644000175600017570000000101412606202452021650 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> l1 = Sub1([1,2,3]) >>> len(l1) 3 >>> l2 = Sub2([1,2,3]) >>> len(l2) 3 >>> isinstance(l1, list) True >>> isinstance(l2, list) True >>> isinstance(l1, Sub1) True >>> isinstance(l1, Sub2) True >>> isinstance(l2, Sub1) False >>> isinstance(l2, Sub2) True """ cdef extern from *: ctypedef class __builtin__.list [ object PyListObject ]: pass cdef class Sub2(list): cdef char character cdef class Sub1(Sub2): pass Cython-0.23.4/tests/run/pyintop.pyx0000644000175600017570000000402112606202452020413 0ustar jenkinsjenkins00000000000000# mode: run def bigint(x): # avoid 'L' postfix in Py2.x print(str(x).rstrip('L')) def or_obj(obj2, obj3): """ >>> or_obj(2, 3) 3 """ obj1 = obj2 | obj3 return obj1 def or_int(obj2): """ >>> or_int(1) 17 >>> or_int(16) 16 """ obj1 = obj2 | 0x10 return obj1 def xor_obj(obj2, obj3): """ >>> xor_obj(2, 3) 1 """ obj1 = obj2 ^ obj3 return obj1 def xor_int(obj2): """ >>> xor_int(2) 18 >>> xor_int(16) 0 """ obj1 = obj2 ^ 0x10 return obj1 def and_obj(obj2, obj3): """ >>> and_obj(2, 3) 2 """ obj1 = obj2 & obj3 return obj1 def and_int(obj2): """ >>> and_int(1) 0 >>> and_int(18) 16 """ obj1 = obj2 & 0x10 return obj1 def lshift_obj(obj2, obj3): """ >>> lshift_obj(2, 3) 16 """ obj1 = obj2 << obj3 return obj1 def rshift_obj(obj2, obj3): """ >>> rshift_obj(2, 3) 0 """ obj1 = obj2 >> obj3 return obj1 def rshift_int(obj2): """ >>> rshift_int(2) 0 >>> rshift_int(27) 3 >>> (-27) >> 3 -4 >>> rshift_int(-27) -4 >>> rshift_int(32) 4 >>> (-32) >> 3 -4 >>> rshift_int(-32) -4 >>> (2**28) >> 3 33554432 >>> rshift_int(2**28) 33554432 >>> (-2**28) >> 3 -33554432 >>> rshift_int(-2**28) -33554432 >>> (2**30) >> 3 134217728 >>> rshift_int(2**30) 134217728 >>> rshift_int(-2**30) -134217728 >>> bigint((2**60) >> 3) 144115188075855872 >>> bigint(rshift_int(2**60)) 144115188075855872 >>> bigint(rshift_int(-2**60)) -144115188075855872 """ obj1 = obj2 >> 3 return obj1 def mixed_obj(obj2, obj3): """ >>> mixed_obj(2, 3) 16 """ obj1 = obj2 << obj3 | obj2 >> obj3 return obj1 def mixed_int(obj2): """ >>> mixed_int(2) 18 >>> mixed_int(16) 0 >>> mixed_int(17) 1 """ obj1 = (obj2 ^ 0x10) | (obj2 & 0x01) return obj1 Cython-0.23.4/tests/run/pyfunction_redefine_T489.pyx0000644000175600017570000000176012606202452023507 0ustar jenkinsjenkins00000000000000# ticket: 489 """ >>> xxx [0, 1, 2, 3] """ xxx = [] foo = 0 xxx.append(foo) def foo(): return 1 xxx.append(foo()) def foo(): return 2 xxx.append(foo()) foo = 3 xxx.append(foo) def closure_scope(a): """ >>> closure_scope(0) [0, 1, 'X', -4, 3] """ ret = [] foo = a + 0 ret.append(foo) def foo(): return a + 1 ret.append(foo()) def foo(): return 'X' ret.append(foo()) def foo(b): return a - b ret.append(foo(4)) foo = a + 3 ret.append(foo) return ret class ClassScope(object): """ >>> obj = ClassScope() [0, 1, 2, 3] """ x = [] def __init__(self): r = [] for x in self.x: if isinstance(x, int): r.append(x) else: r.append(x(self)) print r foo = 0 x.append(foo) def foo(self): return 1 x.append(foo) def foo(self): return 2 x.append(foo) foo = 3 x.append(foo) Cython-0.23.4/tests/run/pyextattrref.pyx0000644000175600017570000000055412606202452021461 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> s = Spam(Eggs("ham")) >>> test(s) 'ham' """ cdef class Eggs: cdef object ham def __init__(self, ham): self.ham = ham cdef class Spam: cdef Eggs eggs def __init__(self, eggs): self.eggs = eggs cdef object tomato(Spam s): food = s.eggs.ham return food def test(Spam s): return tomato(s) Cython-0.23.4/tests/run/pycmp.pyx0000644000175600017570000000102512606202452020042 0ustar jenkinsjenkins00000000000000def f(): """ >>> f() """ cdef int bool, int1, int2 cdef object obj1, obj2 int1 = 0 int2 = 0 obj1 = 1 obj2 = 2 bool = obj1 == obj2 assert not bool bool = obj1 <> int2 assert bool bool = int1 == obj2 assert not bool bool = obj1 is obj2 assert not bool bool = obj1 is not obj2 assert bool def g(): """ >>> g() """ cdef int bool obj1 = 1 obj2 = [] bool = obj1 in obj2 assert not bool bool = obj1 not in obj2 assert bool Cython-0.23.4/tests/run/pyclass_special_methods.pyx0000644000175600017570000000165512606202452023624 0ustar jenkinsjenkins00000000000000# mode: run # tag: pyclass, getattr """ Python bypasses __getattribute__ overrides for some special method lookups. """ lookups = [] class PyClass(object): """ >>> del lookups[:] >>> obj = PyClass() >>> obj.test 'getattribute(test)' >>> lookups ['getattribute(test)'] """ def __getattribute__(self, name): lookup = 'getattribute(%s)' % name lookups.append(lookup) return lookup def __getattr__(self, name): lookup = 'getattr(%s)' % name lookups.append(lookup) return lookup def use_as_context_manager(obj): """ >>> del lookups[:] >>> class PyCM(PyClass): ... def __enter__(self): return '__enter__(%s)' % (self is obj or self) ... def __exit__(self, *args): pass >>> obj = PyCM() >>> use_as_context_manager(obj) '__enter__(True)' >>> lookups [] """ with obj as x: pass return x Cython-0.23.4/tests/run/pyclass_scope_T671.py0000644000175600017570000000313012606202452022111 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 671 A = 1234 class SimpleAssignment(object): """ >>> SimpleAssignment.A 1234 """ A = A class SimpleRewrite(object): """ >>> SimpleRewrite.A 4321 """ A = 4321 A = A def simple_inner(a): """ >>> simple_inner(4321).A 1234 """ A = a class X(object): A = A return X def conditional(a, cond): """ >>> conditional(4321, False).A 1234 >>> conditional(4321, True).A 4321 """ class X(object): if cond: A = a A = A return X def name_error(): """ >>> name_error() #doctest: +ELLIPSIS Traceback (most recent call last): ... NameError: ...B... """ class X(object): B = B def conditional_name_error(cond): """ >>> conditional_name_error(True).B 4321 >>> conditional_name_error(False).B #doctest: +ELLIPSIS Traceback (most recent call last): ... NameError: ...B... """ class X(object): if cond: B = 4321 B = B return X C = 1111 del C def name_error_deleted(): """ >>> name_error_deleted() #doctest: +ELLIPSIS Traceback (most recent call last): ... NameError: ...C... """ class X(object): C = C _set = set def name_lookup_order(): """ >>> Scope = name_lookup_order() >>> Scope().set(2) 42 >>> Scope.test1 == _set() True >>> Scope.test2 == _set() True """ class Scope(object): test1 = set() test2 = set() def set(self, x): return 42 return Scope Cython-0.23.4/tests/run/pyclass_dynamic_bases.pyx0000644000175600017570000000051712606202452023256 0ustar jenkinsjenkins00000000000000# mode: run # tag: pyclass class A(object): x = 1 class B(object): x = 2 def cond_if_bases(x): """ >>> c = cond_if_bases(True) >>> c().p 5 >>> c().x 1 >>> c = cond_if_bases(False) >>> c().p 5 >>> c().x 2 """ class PyClass(A if x else B): p = 5 return PyClass Cython-0.23.4/tests/run/pyarray.pyx0000644000175600017570000001021712606202452020404 0ustar jenkinsjenkins00000000000000# tag: array import array # Python builtin module from cpython cimport array # array.pxd / arrayarray.h a = array.array('f', [1.0, 2.0, 3.0]) def test_len(a): """ >>> a = array.array('f', [1.0, 2.0, 3.0]) >>> len(a) 3 >>> int(test_len(a)) 3 >>> assert len(a) == test_len(a) """ cdef array.array ca = a # for C-fast array usage return len(ca) def test_copy(a): """ >>> a = array.array('f', [1.0, 2.0, 3.0]) >>> test_copy(a) array('f', [1.0, 2.0, 3.0]) """ cdef array.array ca = a cdef array.array b b = array.copy(ca) assert a == b a[2] = 3.5 assert b[2] != a[2] return b def test_fast_access(a): """ >>> a = array.array('f', [1.0, 2.0, 3.0]) >>> test_fast_access(a) """ cdef array.array ca = a cdef float value with nogil: value = ca.data.as_floats[1] assert value == 2.0, value #assert ca._c[:5] == b'\x00\x00\x80?\x00', repr(ca._c[:5]) with nogil: ca.data.as_floats[1] += 2.0 assert ca.data.as_floats[1] == 4.0 def test_fast_buffer_access(a): """ >>> a = array.array('f', [1.0, 2.0, 3.0]) >>> test_fast_buffer_access(a) """ cdef array.array[float] ca = a cdef float value with nogil: value = ca[1] assert value == 2.0, value with nogil: ca[1] += 2.0 assert ca[1] == 4.0 def test_new_zero(a): """ >>> a = array.array('f', [1.0, 2.0, 3.0]) >>> test_new_zero(a) array('f', [0.0, 0.0, 0.0]) """ cdef array.array cb = array.clone(a, len(a), True) assert len(cb) == len(a) return cb def test_set_zero(a): """ >>> a = array.array('f', [1.0, 2.0, 3.0]) >>> test_set_zero(a) array('f', [0.0, 0.0, 0.0]) """ cdef array.array cb = array.copy(a) array.zero(cb) assert a[1] != 0.0, a assert cb[1] == 0.0, cb return cb def test_resize(a): """ >>> a = array.array('f', [1.0, 2.0, 3.0]) >>> test_resize(a) """ cdef array.array cb = array.copy(a) array.resize(cb, 10) for i in range(10): cb.data.as_floats[i] = i assert len(cb) == 10 assert cb[9] == cb[-1] == cb.data.as_floats[9] == 9 def test_resize_smart(a): """ >>> a = array.array('d', [1, 2, 3]) >>> test_resize_smart(a) 2 """ cdef array.array cb = array.copy(a) array.resize_smart(cb, 2) return len(cb) def test_buffer(): """ >>> test_buffer() """ cdef object a = array.array('i', [1, 2, 3]) cdef object[int] ca = a assert ca[0] == 1 assert ca[2] == 3 def test_buffer_typed(): """ >>> test_buffer_typed() """ cdef array.array a = array.array('i', [1, 2, 3]) cdef object[int] ca = a assert ca[0] == 1 assert ca[2] == 3 def test_view(): """ >>> test_view() """ cdef object a = array.array('i', [1, 2, 3]) cdef int[:] ca = a assert ca[0] == 1 assert ca[2] == 3 def test_view_typed(): """ >>> test_view_typed() """ cdef array.array a = array.array('i', [1, 2, 3]) cdef int[:] ca = a assert ca[0] == 1 assert ca[2] == 3 def test_extend(): """ >>> test_extend() """ cdef array.array ca = array.array('i', [1, 2, 3]) cdef array.array cb = array.array('i', [4, 5]) cdef array.array cf = array.array('f', [1.0, 2.0, 3.0]) array.extend(ca, cb) assert list(ca) == [1, 2, 3, 4, 5], list(ca) try: array.extend(ca, cf) except TypeError: pass else: assert False, 'extending incompatible array types did not raise' def test_likes(a): """ >>> a = array.array('f', [1.0, 2.0, 3.0]) >>> test_likes(a) array('f', [0.0, 0.0, 0.0]) """ cdef array.array z = array.clone(a, len(a), True) cdef array.array e = array.clone(a, len(a), False) assert len(e) == len(a) return z def test_extend_buffer(): """ >>> test_extend_buffer() array('l', [15, 37, 389, 5077]) """ cdef array.array ca = array.array('l', [15, 37]) cdef long[2] s s[0] = 389 s[1] = 5077 array.extend_buffer(ca, &s, 2) assert ca.data.as_ulongs[3] == 5077 assert len(ca) == 4 return ca Cython-0.23.4/tests/run/py_unicode_type.pyx0000644000175600017570000001311112606202452022110 0ustar jenkinsjenkins00000000000000# -*- coding: iso-8859-1 -*- cimport cython cdef Py_UNICODE char_ASCII = u'A' cdef Py_UNICODE char_KLINGON = u'\uF8D2' u_A = char_ASCII u_KLINGON = char_KLINGON def compare_ASCII(): """ >>> compare_ASCII() True False False """ print(char_ASCII == u'A') print(char_ASCII == u'B') print(char_ASCII == u'\uF8D2') def compare_klingon(): """ >>> compare_klingon() True False False """ print(char_KLINGON == u'\uF8D2') print(char_KLINGON == u'A') print(char_KLINGON == u'B') from cpython.unicode cimport PyUnicode_FromOrdinal import sys u0 = u'\x00' u1 = u'\x01' umax = PyUnicode_FromOrdinal(sys.maxunicode) def unicode_ordinal(Py_UNICODE i): """ >>> ord(unicode_ordinal(0)) == 0 True >>> ord(unicode_ordinal(1)) == 1 True >>> ord(unicode_ordinal(sys.maxunicode)) == sys.maxunicode True >>> ord(unicode_ordinal(u0)) == 0 True >>> ord(unicode_ordinal(u1)) == 1 True >>> ord(unicode_ordinal(umax)) == sys.maxunicode True Value too small: >>> unicode_ordinal(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... Value too large: >>> unicode_ordinal(sys.maxunicode+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... Less than one character: >>> unicode_ordinal(u0[:0]) Traceback (most recent call last): ... ValueError: only single character unicode strings can be converted to Py_UNICODE, got length 0 More than one character: >>> unicode_ordinal(u0+u1) Traceback (most recent call last): ... ValueError: only single character unicode strings can be converted to Py_UNICODE, got length 2 """ return i def ord_pyunicode(Py_UNICODE x): """ >>> ord_pyunicode(u0) 0 >>> ord_pyunicode(u_A) 65 >>> ord_pyunicode(u_KLINGON) 63698 """ return ord(x) @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode') def unicode_type_methods(Py_UNICODE uchar): """ >>> unicode_type_methods(ord('A')) [True, True, False, False, False, False, False, True, True] >>> unicode_type_methods(ord('a')) [True, True, False, False, True, False, False, False, False] >>> unicode_type_methods(ord('8')) [True, False, True, True, False, True, False, False, False] >>> unicode_type_methods(ord('\\t')) [False, False, False, False, False, False, True, False, False] """ return [ # character types uchar.isalnum(), uchar.isalpha(), uchar.isdecimal(), uchar.isdigit(), uchar.islower(), uchar.isnumeric(), uchar.isspace(), uchar.istitle(), uchar.isupper(), ] @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode') def unicode_methods(Py_UNICODE uchar): """ >>> unicode_methods(ord('A')) == ['a', 'A', 'A'] True >>> unicode_methods(ord('a')) == ['a', 'A', 'A'] True """ return [ # character conversion uchar.lower(), uchar.upper(), uchar.title(), ] @cython.test_assert_path_exists('//IntNode') @cython.test_fail_if_path_exists('//SimpleCallNode', '//PythonCapiCallNode') def len_uchar(Py_UNICODE uchar): """ >>> len_uchar(ord('A')) 1 """ assert uchar # just to avoid C compiler unused arg warning return len(uchar) def index_uchar(Py_UNICODE uchar, Py_ssize_t i): """ >>> index_uchar(ord('A'), 0) == ('A', 'A', 'A') True >>> index_uchar(ord('A'), -1) == ('A', 'A', 'A') True >>> index_uchar(ord('A'), 1) Traceback (most recent call last): IndexError: string index out of range """ return uchar[0], uchar[-1], uchar[i] mixed_ustring = u'AbcDefGhIjKlmnoP' lower_ustring = mixed_ustring.lower() upper_ustring = mixed_ustring.lower() @cython.test_assert_path_exists('//PythonCapiCallNode', '//ForFromStatNode') @cython.test_fail_if_path_exists('//SimpleCallNode', '//ForInStatNode') def count_lower_case_characters(unicode ustring): """ >>> count_lower_case_characters(mixed_ustring) 10 >>> count_lower_case_characters(lower_ustring) 16 """ cdef Py_ssize_t count = 0 for uchar in ustring: if uchar.islower(): count += 1 return count @cython.test_assert_path_exists('//PythonCapiCallNode', '//ForFromStatNode') @cython.test_fail_if_path_exists('//SimpleCallNode', '//ForInStatNode') def count_lower_case_characters_slice(unicode ustring): """ >>> count_lower_case_characters_slice(mixed_ustring) 10 >>> count_lower_case_characters_slice(lower_ustring) 14 """ cdef Py_ssize_t count = 0 for uchar in ustring[1:-1]: if uchar.islower(): count += 1 return count @cython.test_assert_path_exists('//SwitchStatNode', '//ForFromStatNode') @cython.test_fail_if_path_exists('//ForInStatNode') def iter_and_in(): """ >>> iter_and_in() a b e f h """ for c in u'abcdefgh': if c in u'abCDefGh': print c @cython.test_assert_path_exists('//SwitchStatNode') @cython.test_fail_if_path_exists('//ForInStatNode') def index_and_in(): """ >>> index_and_in() 1 3 4 7 8 """ cdef int i for i in range(1,9): if u'abcdefgh'[-i] in u'abCDefGh': print i Cython-0.23.4/tests/run/py_unicode_strings.pyx0000644000175600017570000000507712606202452022634 0ustar jenkinsjenkins00000000000000# tag: py_unicode_strings import sys cimport cython from libc.string cimport memcpy, strcpy cdef bint Py_UNICODE_equal(const Py_UNICODE* u1, const Py_UNICODE* u2): while u1[0] != 0 and u2[0] != 0 and u1[0] == u2[0]: u1 += 1 u2 += 1 return u1[0] == u2[0] ctypedef Py_UNICODE* LPWSTR cdef unicode uobj = u'unicode\u1234' cdef unicode uobj1 = u'u' cdef Py_UNICODE* c_pu_str = u"unicode\u1234" cdef Py_UNICODE[42] c_pu_arr cdef LPWSTR c_wstr = u"unicode\u1234" cdef Py_UNICODE* c_pu_empty = u"" cdef char* c_empty = "" cdef unicode uwide_literal = u'\U00020000\U00020001' cdef Py_UNICODE* c_pu_wide_literal = u'\U00020000\U00020001' memcpy(c_pu_arr, c_pu_str, sizeof(Py_UNICODE) * (len(uobj) + 1)) def test_c_to_python(): """ >>> test_c_to_python() """ assert c_pu_arr == uobj assert c_pu_str == uobj assert c_wstr == uobj assert c_pu_arr[1:] == uobj[1:] assert c_pu_str[1:] == uobj[1:] assert c_wstr[1:] == uobj[1:] assert c_pu_arr[:1] == uobj[:1] assert c_pu_arr[:1] == uobj[:1] assert c_pu_str[:1] == uobj[:1] assert c_wstr[:1] == uobj[:1] assert c_pu_arr[1:7] == uobj[1:7] assert c_pu_str[1:7] == uobj[1:7] assert c_wstr[1:7] == uobj[1:7] assert c_pu_arr[1] == uobj[1] assert c_pu_str[1] == uobj[1] assert c_wstr[1] == uobj[1] assert len(c_pu_str) == 8 assert len(c_pu_arr) == 8 assert len(c_wstr) == 8 assert sizeof(c_pu_arr) == sizeof(Py_UNICODE) * 42 assert sizeof(c_pu_str) == sizeof(void*) assert c_pu_wide_literal == uwide_literal if sizeof(Py_UNICODE) >= 4: assert len(c_pu_wide_literal) == 2 else: assert len(c_pu_wide_literal) == 4 if sys.version_info >= (3, 3): # Make sure len(unicode) is not reverted to pre-3.3 behavior assert len(uwide_literal) == 2 assert u'unicode' assert not u'' assert c_pu_str assert c_pu_empty def test_python_to_c(): """ >>> test_python_to_c() """ cdef unicode u assert Py_UNICODE_equal(c_pu_arr, uobj) assert Py_UNICODE_equal(c_pu_str, uobj) assert Py_UNICODE_equal(c_pu_str, uobj) u = uobj[1:] assert Py_UNICODE_equal(c_pu_str + 1, u) assert Py_UNICODE_equal(c_wstr + 1, u) u = uobj[:1] assert Py_UNICODE_equal(u"u", u) u = uobj[1:7] assert Py_UNICODE_equal(u"nicode", u) u = uobj[1] assert Py_UNICODE_equal(u"n", u) assert Py_UNICODE_equal(uwide_literal, c_pu_wide_literal) assert len(u"abc\0") == 4 assert len(u"abc\0") == 3 Cython-0.23.4/tests/run/py_ucs4_type.pyx0000644000175600017570000001743412606202452021354 0ustar jenkinsjenkins00000000000000# -*- coding: iso-8859-1 -*- cimport cython cdef Py_UCS4 char_ASCII = u'A' cdef Py_UCS4 char_KLINGON = u'\uF8D2' u_A = char_ASCII u_KLINGON = char_KLINGON def compare_ASCII(): """ >>> compare_ASCII() True False False """ print(char_ASCII == u'A') print(char_ASCII == u'B') print(char_ASCII == u'\uF8D2') def compare_klingon(): """ >>> compare_klingon() True False False """ print(char_KLINGON == u'\uF8D2') print(char_KLINGON == u'A') print(char_KLINGON == u'B') def single_uchar_compare(): """ >>> single_uchar_compare() """ assert u'\u0100' < u'\u0101' assert u'\u0101' > u'\u0100' from cpython.unicode cimport PyUnicode_FromOrdinal import sys u0 = u'\x00' u1 = u'\x01' umax = PyUnicode_FromOrdinal(sys.maxunicode) def unicode_ordinal(Py_UCS4 i): """ >>> ord(unicode_ordinal(0)) == 0 True >>> ord(unicode_ordinal(1)) == 1 True >>> ord(unicode_ordinal(sys.maxunicode)) == sys.maxunicode True >>> ord(unicode_ordinal(u0)) == 0 True >>> ord(unicode_ordinal(u1)) == 1 True >>> ord(unicode_ordinal(umax)) == sys.maxunicode True Value too small: >>> unicode_ordinal(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... Value too large: >>> unicode_ordinal(1114111+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... Less than one character: >>> unicode_ordinal(u0[:0]) Traceback (most recent call last): ... ValueError: only single character unicode strings can be converted to Py_UCS4, got length 0 More than one character: >>> unicode_ordinal(u0+u1) Traceback (most recent call last): ... ValueError: only single character unicode strings can be converted to Py_UCS4, got length 2 """ return i def ord_py_ucs4(Py_UCS4 x): """ >>> ord_py_ucs4(u0) 0 >>> ord_py_ucs4(u_A) 65 >>> ord_py_ucs4(u_KLINGON) 63698 """ return ord(x) @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode') def unicode_type_methods(Py_UCS4 uchar): """ >>> unicode_type_methods(ord('A')) [True, True, False, False, False, False, False, True, True] >>> unicode_type_methods(ord('a')) [True, True, False, False, True, False, False, False, False] >>> unicode_type_methods(ord('8')) [True, False, True, True, False, True, False, False, False] >>> unicode_type_methods(ord('\\t')) [False, False, False, False, False, False, True, False, False] """ return [ # character types uchar.isalnum(), uchar.isalpha(), uchar.isdecimal(), uchar.isdigit(), uchar.islower(), uchar.isnumeric(), uchar.isspace(), uchar.istitle(), uchar.isupper(), ] @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode') def unicode_methods(Py_UCS4 uchar): """ >>> unicode_methods(ord('A')) == ['a', 'A', 'A'] True >>> unicode_methods(ord('a')) == ['a', 'A', 'A'] True """ return [ # character conversion uchar.lower(), uchar.upper(), uchar.title(), ] @cython.test_assert_path_exists('//IntNode') @cython.test_fail_if_path_exists('//SimpleCallNode', '//PythonCapiCallNode') def len_uchar(Py_UCS4 uchar): """ >>> len_uchar(ord('A')) 1 """ return len(uchar) def index_uchar(Py_UCS4 uchar, Py_ssize_t i): """ >>> index_uchar(ord('A'), 0) == ('A', 'A', 'A') True >>> index_uchar(ord('A'), -1) == ('A', 'A', 'A') True >>> index_uchar(ord('A'), 1) Traceback (most recent call last): IndexError: string index out of range """ return uchar[0], uchar[-1], uchar[i] mixed_ustring = u'AbcDefGhIjKlmnoP' lower_ustring = mixed_ustring.lower() upper_ustring = mixed_ustring.lower() @cython.test_assert_path_exists('//PythonCapiCallNode', '//ForFromStatNode') @cython.test_fail_if_path_exists('//SimpleCallNode', '//ForInStatNode') def count_lower_case_characters(unicode ustring): """ >>> count_lower_case_characters(mixed_ustring) 10 >>> count_lower_case_characters(lower_ustring) 16 """ cdef Py_ssize_t count = 0 for uchar in ustring: if uchar.islower(): count += 1 return count @cython.test_assert_path_exists('//PythonCapiCallNode', '//ForFromStatNode') @cython.test_fail_if_path_exists('//SimpleCallNode', '//ForInStatNode') def count_lower_case_characters_slice(unicode ustring): """ >>> count_lower_case_characters_slice(mixed_ustring) 10 >>> count_lower_case_characters_slice(lower_ustring) 14 >>> sum([ 1 for uchar in lower_ustring[1:-1] if uchar.islower() ]) 14 """ cdef Py_ssize_t count = 0 for uchar in ustring[1:-1]: if uchar.islower(): count += 1 return count @cython.test_assert_path_exists('//PythonCapiCallNode', '//ForFromStatNode') @cython.test_fail_if_path_exists('//SimpleCallNode', '//ForInStatNode') def count_lower_case_characters_slice_reversed(unicode ustring): """ >>> count_lower_case_characters_slice_reversed(mixed_ustring) 10 >>> count_lower_case_characters_slice_reversed(lower_ustring) 14 >>> sum([ 1 for uchar in lower_ustring[-2:0:-1] if uchar.islower() ]) 14 """ cdef Py_ssize_t count = 0 for uchar in ustring[-2:0:-1]: if uchar.islower(): count += 1 return count def loop_object_over_latin1_unicode_literal(): """ >>> result = loop_object_over_latin1_unicode_literal() >>> print(result[:-1]) abcdefg >>> ord(result[-1]) == 0xD7 True """ cdef object uchar chars = [] for uchar in u'abcdefg\xD7': chars.append(uchar) return u''.join(chars) def loop_object_over_unicode_literal(): """ >>> result = loop_object_over_unicode_literal() >>> print(result[:-1]) abcdefg >>> ord(result[-1]) == 0xF8FD True """ cdef object uchar chars = [] for uchar in u'abcdefg\uF8FD': chars.append(uchar) return u''.join(chars) @cython.test_assert_path_exists('//SwitchStatNode') @cython.test_fail_if_path_exists('//ForInStatNode') def iter_and_in(): """ >>> iter_and_in() a b e f h """ for c in u'abcdefgh': if c in u'abCDefGh': print c @cython.test_fail_if_path_exists('//ForInStatNode') def iter_inferred(): """ >>> iter_inferred() a b c d e """ uchars = list(u"abcde") uchars = u''.join(uchars) for c in uchars: print c @cython.test_assert_path_exists('//SwitchStatNode', '//ForFromStatNode') @cython.test_fail_if_path_exists('//ForInStatNode') def index_and_in(): """ >>> index_and_in() 1 3 4 7 8 """ cdef int i for i in range(1,9): if u'abcdefgh'[-i] in u'abCDefGh': print i # special test for narrow builds high_uchar = u'\U00012345' high_ustring0 = u'\U00012345\U00012346abc' high_ustring1 = u'\U00012346\U00012345abc' high_ustring_end = u'\U00012346abc\U00012344\U00012345' high_ustring_no = u'\U00012346\U00012346abc' def uchar_in(Py_UCS4 uchar, unicode ustring): """ >>> uchar_in(high_uchar, high_ustring0) True >>> uchar_in(high_uchar, high_ustring1) True >>> uchar_in(high_uchar, high_ustring_end) True >>> uchar_in(high_uchar, high_ustring_no) False """ assert uchar == 0x12345, ('%X' % uchar) return uchar in ustring Cython-0.23.4/tests/run/py_hash_t.pyx0000644000175600017570000000064212606202452020674 0ustar jenkinsjenkins00000000000000 cimport cython def assign_py_hash_t(x): """ >>> assign_py_hash_t(12) 12 >>> assign_py_hash_t(-12) -12 """ cdef Py_hash_t h = x return h def infer_hash_type(x): """ >>> infer_hash_type(123) 'Py_hash_t' """ h = hash(x) return cython.typeof(h) def assign_to_name(x): """ >>> assign_to_name(321) 321 """ Py_hash_t = x return Py_hash_t Cython-0.23.4/tests/run/py_classbody.py0000644000175600017570000000273712606202452021230 0ustar jenkinsjenkins00000000000000# mode: run # tag: pyclass, global pyvar = 2 class TestPyAttr(object): """ >>> TestPyAttr.pyvar # doctest: +ELLIPSIS Traceback (most recent call last): AttributeError: ...TestPyAttr...has no attribute 'pyvar' >>> TestPyAttr.pyval1 3 >>> TestPyAttr.pyval2 2 """ pyvar = 3 pyval1 = pyvar del pyvar pyval2 = pyvar import cython cdefvar = cython.declare(int, 10) class TestCdefAttr(object): """ >>> TestCdefAttr.cdefvar # doctest: +ELLIPSIS Traceback (most recent call last): AttributeError: ...TestCdefAttr...has no attribute 'cdefvar' >>> TestCdefAttr.cdefval1 11 >>> #TestCdefAttr.cdefval2 """ cdefvar = 11 cdefval1 = cdefvar del cdefvar # cdefval2 = cdefvar # FIXME: doesn't currently work ... class ForLoopInPyClass(object): """ >>> ForLoopInPyClass.i # doctest: +ELLIPSIS Traceback (most recent call last): AttributeError: ...ForLoopInPyClass... has no attribute ...i... >>> ForLoopInPyClass.k 0 >>> ForLoopInPyClass.m 1 """ for i in range(0): pass for k in range(1): pass for m in range(2): pass def del_in_class(x): """ >>> del_in_class(True) no error >>> del_in_class(False) NameError """ try: class Test(object): if x: attr = 1 del attr except NameError: print("NameError") else: print("no error") Cython-0.23.4/tests/run/py3k_super.pyx0000644000175600017570000000333412606202452021023 0ustar jenkinsjenkins00000000000000# mode: run # tag: py3k_super class A(object): def method(self): return 1 @classmethod def class_method(cls): return 2 @staticmethod def static_method(): return 3 def generator_test(self): return [1, 2, 3] class B(A): """ >>> obj = B() >>> obj.method() 1 >>> B.class_method() 2 >>> B.static_method(obj) 3 >>> list(obj.generator_test()) [1, 2, 3] """ def method(self): return super().method() @classmethod def class_method(cls): return super().class_method() @staticmethod def static_method(instance): return super().static_method() def generator_test(self): for i in super().generator_test(): yield i def test_class_cell_empty(): """ >>> test_class_cell_empty() Traceback (most recent call last): ... SystemError: super(): empty __class__ cell """ class Base(type): def __new__(cls, name, bases, attrs): attrs['foo'](None) class EmptyClassCell(metaclass=Base): def foo(self): super() cdef class CClassBase(object): def method(self): return 'def' # cpdef method_cp(self): # return 'cpdef' # cdef method_c(self): # return 'cdef' # def call_method_c(self): # return self.method_c() cdef class CClassSub(CClassBase): """ >>> CClassSub().method() 'def' """ # >>> CClassSub().method_cp() # 'cpdef' # >>> CClassSub().call_method_c() # 'cdef' def method(self): return super().method() # cpdef method_cp(self): # return super().method_cp() # cdef method_c(self): # return super().method_c() Cython-0.23.4/tests/run/py35_pep492_interop.pyx0000644000175600017570000000347312606202452022366 0ustar jenkinsjenkins00000000000000# cython: language_level=3, binding=True # mode: run # tag: pep492, asyncfor, await def run_async(coro): #assert coro.__class__ is types.GeneratorType assert coro.__class__.__name__ in ('coroutine', 'GeneratorWrapper'), coro.__class__.__name__ buffer = [] result = None while True: try: buffer.append(coro.send(None)) except StopIteration as ex: result = ex.args[0] if ex.args else None break return buffer, result def run_async__await__(coro): assert coro.__class__.__name__ in ('coroutine', 'GeneratorWrapper'), coro.__class__.__name__ aw = coro.__await__() buffer = [] result = None i = 0 while True: try: if i % 2: buffer.append(next(aw)) else: buffer.append(aw.send(None)) i += 1 except StopIteration as ex: result = ex.args[0] if ex.args else None break return buffer, result async def await_pyobject(awaitable): """ >>> async def simple(): ... return 10 >>> buffer, result = run_async(await_pyobject(simple())) >>> result 10 >>> async def awaiting(awaitable): ... return await awaitable >>> buffer, result = run_async(await_pyobject(awaiting(simple()))) >>> result 10 """ return await awaitable def await_cyobject(): """ >>> async def run_await(awaitable): ... return await awaitable >>> simple, awaiting = await_cyobject() >>> buffer, result = run_async(run_await(simple())) >>> result 10 >>> buffer, result = run_async(run_await(awaiting(simple()))) >>> result 10 """ async def simple(): return 10 async def awaiting(awaitable): return await awaitable return simple, awaiting Cython-0.23.4/tests/run/py34_signature.pyx0000644000175600017570000000324512606202452021600 0ustar jenkinsjenkins00000000000000# cython: binding=True, language_level=3 # mode: run # tag: cyfunction import inspect sig = inspect.Signature.from_function def signatures_match(f1, f2): if sig(f1) == sig(f2): return None # nothing to show in doctest return sig(f1), sig(f2) def b(a, b, c): """ >>> def py_b(a, b, c): pass >>> signatures_match(b, py_b) """ def c(a, b, c=1): """ >>> def py_c(a, b, c=1): pass >>> signatures_match(c, py_c) """ def d(a, b, *, c = 88): """ >>> def py_d(a, b, *, c = 88): pass >>> signatures_match(d, py_d) """ def e(a, b, c = 88, **kwds): """ >>> def py_e(a, b, c = 88, **kwds): pass >>> signatures_match(e, py_e) """ def f(a, b, *, c, d = 42): """ >>> def py_f(a, b, *, c, d = 42): pass >>> signatures_match(f, py_f) """ def g(a, b, *, c, d = 42, e = 17, f, **kwds): """ >>> def py_g(a, b, *, c, d = 42, e = 17, f, **kwds): pass >>> signatures_match(g, py_g) """ def h(a, b, *args, c, d = 42, e = 17, f, **kwds): """ >>> def py_h(a, b, *args, c, d = 42, e = 17, f, **kwds): pass >>> signatures_match(h, py_h) """ def k(a, b, c=1, *args, d = 42, e = 17, f, **kwds): """ >>> def py_k(a, b, c=1, *args, d = 42, e = 17, f, **kwds): pass >>> signatures_match(k, py_k) """ def l(*, a, b, c = 88): """ >>> def py_l(*, a, b, c = 88): pass >>> signatures_match(l, py_l) """ def m(a, *, b, c = 88): """ >>> def py_m(a, *, b, c = 88): pass >>> signatures_match(m, py_m) """ a, b, c = b, c, a def n(a, *, b, c = 88): """ >>> def py_n(a, *, b, c = 88): pass >>> signatures_match(n, py_n) """ Cython-0.23.4/tests/run/py2_super.pyx0000644000175600017570000000342712606202452020652 0ustar jenkinsjenkins00000000000000# mode: run # tag: py3k_super class A(object): def method(self): return 1 @classmethod def class_method(cls): return 2 @staticmethod def static_method(): return 3 def generator_test(self): return [1, 2, 3] class B(A): """ >>> obj = B() >>> obj.method() 1 >>> B.class_method() 2 >>> B.static_method(obj) 3 >>> list(obj.generator_test()) [1, 2, 3] """ def method(self): return super(B, self).method() @classmethod def class_method(cls): return super(B, cls).class_method() @staticmethod def static_method(instance): return super(B, instance).static_method() def generator_test(self): for i in super(B, self).generator_test(): yield i cdef class CClassBase(object): def method(self): return 'def' cpdef method_cp(self): return 'cpdef' # cdef method_c(self): # return 'cdef' # def call_method_c(self): # return self.method_c() cdef class CClassSub(CClassBase): """ >>> CClassSub().method() 'def' >>> CClassSub().method_cp() 'cpdef' """ # >>> CClassSub().call_method_c() # 'cdef' def method(self): return super(CClassSub, self).method() cpdef method_cp(self): return super(CClassSub, self).method_cp() # cdef method_c(self): # return super(CClassSub, self).method_c() cdef class Base(object): """ >>> Base().method() 'Base' >>> Base.method(Base()) 'Base' """ cpdef method(self): return "Base" cdef class Sub(Base): """ >>> Sub().method() 'Sub' >>> Sub.method(Sub()) 'Sub' >>> Base.method(Sub()) 'Base' """ cpdef method(self): return "Sub" Cython-0.23.4/tests/run/pxd_syntax.srctree0000644000175600017570000000202112606202452021737 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import a; a.test()" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize("a.pyx"), ) ######## a.pyx ######## cdef class ExtTypeDocstringPass: pass cdef class ExtTypeDocstring: "huhu!" # this should override the .pxd docstring cdef class ExtTypePass: pass cdef class ExtTypeDocstringPassString: pass def test(): assert not ExtTypePass().__doc__, ExtTypePass().__doc__ assert ExtTypeDocstring().__doc__ == "huhu!", ExtTypeDocstring().__doc__ assert ExtTypeDocstringPass().__doc__ == "hoho!", ExtTypeDocstringPass().__doc__ assert ExtTypeDocstringPassString().__doc__ == "hoho!", ExtTypeDocstringPassString().__doc__ ######## a.pxd ######## cdef class ExtTypePass: pass cdef class ExtTypeDocstring: """ hoho """ cdef class ExtTypeDocstringPass: "hoho!" pass cdef class ExtTypeDocstringPassString: "hoho!" pass "more hoho" Cython-0.23.4/tests/run/purecdef.py0000644000175600017570000000440412606202452020323 0ustar jenkinsjenkins00000000000000import cython from cython import cfunc, cclass, ccall @cython.test_assert_path_exists('//CFuncDefNode') @cython.cfunc def ftang(): x = 0 @cython.test_assert_path_exists('//CFuncDefNode') @cfunc def fpure(a): return a*2 def test(): """ >>> test() 4 """ ftang() return fpure(2) with cfunc: @cython.test_assert_path_exists('//CFuncDefNode') def fwith1(a): return a*3 @cython.test_assert_path_exists('//CFuncDefNode') def fwith2(a): return a*4 with cclass: @cython.test_assert_path_exists('//CClassDefNode') class Egg(object): pass @cython.test_assert_path_exists('//CClassDefNode') class BigEgg(object): @cython.test_assert_path_exists('//CFuncDefNode') @cython.cfunc def f(self, a): return a*10 def test_with(): """ >>> test_with() (3, 4, 50) """ return fwith1(1), fwith2(1), BigEgg().f(5) @cython.test_assert_path_exists('//CClassDefNode') @cython.cclass class PureFoo(object): a = cython.declare(cython.double) def __init__(self, a): self.a = a def __call__(self): return self.a @cython.test_assert_path_exists('//CFuncDefNode') @cython.cfunc def puremeth(self, a): return a*2 def test_method(): """ >>> test_method() 4 True """ x = PureFoo(2) print(x.puremeth(2)) if cython.compiled: print(isinstance(x(), float)) else: print(True) return @cython.ccall def ccall_sqr(x): return x*x @cclass class Overidable(object): @ccall def meth(self): return 0 def test_ccall(): """ >>> test_ccall() 25 >>> ccall_sqr(5) 25 """ return ccall_sqr(5) def test_ccall_method(x): """ >>> test_ccall_method(Overidable()) 0 >>> Overidable().meth() 0 >>> class Foo(Overidable): ... def meth(self): ... return 1 >>> test_ccall_method(Foo()) 1 >>> Foo().meth() 1 """ return x.meth() @cython.cfunc @cython.returns(cython.p_int) @cython.locals(xptr=cython.p_int) def typed_return(xptr): return xptr def test_typed_return(): """ >>> test_typed_return() """ x = cython.declare(int, 5) assert typed_return(cython.address(x))[0] is x Cython-0.23.4/tests/run/pure_py.py0000644000175600017570000001472112606202452020214 0ustar jenkinsjenkins00000000000000import cython is_compiled = cython.compiled NULL = 5 _NULL = NULL def test_sizeof(): """ >>> test_sizeof() True True True True True """ x = cython.declare(cython.bint) print(cython.sizeof(x) == cython.sizeof(cython.bint)) print(cython.sizeof(cython.char) <= cython.sizeof(cython.short) <= cython.sizeof(cython.int) <= cython.sizeof(cython.long) <= cython.sizeof(cython.longlong)) print(cython.sizeof(cython.uint) == cython.sizeof(cython.int)) print(cython.sizeof(cython.p_int) == cython.sizeof(cython.p_double)) if cython.compiled: print(cython.sizeof(cython.char) < cython.sizeof(cython.longlong)) else: print(cython.sizeof(cython.char) == 1) def test_declare(n): """ >>> test_declare(100) (100, 100) >>> test_declare(100.5) (100, 100) >>> test_declare(None) #doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: ... """ x = cython.declare(cython.int) y = cython.declare(cython.int, n) if cython.compiled: cython.declare(xx=cython.int, yy=cython.long) i = cython.sizeof(xx) ptr = cython.declare(cython.p_int, cython.address(y)) return y, ptr[0] @cython.locals(x=cython.double, n=cython.int) def test_cast(x): """ >>> test_cast(1.5) 1 """ n = cython.cast(cython.int, x) return n @cython.locals(x=cython.int, y=cython.p_int) def test_address(x): """ >>> test_address(39) 39 """ y = cython.address(x) return y[0] @cython.wraparound(False) def test_wraparound(x): """ >>> test_wraparound([1, 2, 3]) [1, 2, 1] """ with cython.wraparound(True): x[-1] = x[0] return x @cython.boundscheck(False) def test_boundscheck(x): """ >>> test_boundscheck([1, 2, 3]) 3 >>> try: test_boundscheck([1, 2]) ... except IndexError: pass """ with cython.boundscheck(True): return x[2] ## CURRENTLY BROKEN - FIXME!! ## Is this test make sense? Implicit conversion in pure Python?? ## @cython.locals(x=cython.int) ## @cython.locals(y=cython.bint) ## def test_locals(x): ## """ ## >>> test_locals(5) ## True ## """ ## y = x ## return y def test_with_nogil(nogil): """ >>> raised = [] >>> class nogil(object): ... def __enter__(self): ... pass ... def __exit__(self, exc_class, exc, tb): ... raised.append(exc) ... return exc_class is None >>> test_with_nogil(nogil()) WORKS True >>> raised [None] """ result = False with nogil: print("WORKS") with cython.nogil: result = True return result MyUnion = cython.union(n=cython.int, x=cython.double) MyStruct = cython.struct(is_integral=cython.bint, data=MyUnion) MyStruct2 = cython.typedef(MyStruct[2]) def test_struct(n, x): """ >>> test_struct(389, 1.64493) (389, 1.64493) """ a = cython.declare(MyStruct2) a[0] = MyStruct(is_integral=True, data=MyUnion(n=n)) a[1] = MyStruct(is_integral=False, data={'x': x}) return a[0].data.n, a[1].data.x import cython as cy from cython import declare, cast, locals, address, typedef, p_void, compiled from cython import declare as my_declare, locals as my_locals, p_void as my_void_star, typedef as my_typedef, compiled as my_compiled @my_locals(a=cython.p_void) def test_imports(): """ >>> test_imports() (True, True) """ a = cython.NULL b = declare(p_void, cython.NULL) c = my_declare(my_void_star, cython.NULL) d = cy.declare(cy.p_void, cython.NULL) return a == d, compiled == my_compiled ## CURRENTLY BROKEN - FIXME!! # MyStruct3 = typedef(MyStruct[3]) # MyStruct4 = my_typedef(MyStruct[4]) # MyStruct5 = cy.typedef(MyStruct[5]) def test_declare_c_types(n): """ >>> test_declare_c_types(0) >>> test_declare_c_types(1) >>> test_declare_c_types(2) """ # b00 = cython.declare(cython.bint, 0) b01 = cython.declare(cython.bint, 1) b02 = cython.declare(cython.bint, 2) # i00 = cython.declare(cython.uchar, n) i01 = cython.declare(cython.char, n) i02 = cython.declare(cython.schar, n) i03 = cython.declare(cython.ushort, n) i04 = cython.declare(cython.short, n) i05 = cython.declare(cython.sshort, n) i06 = cython.declare(cython.uint, n) i07 = cython.declare(cython.int, n) i08 = cython.declare(cython.sint, n) i09 = cython.declare(cython.slong, n) i10 = cython.declare(cython.long, n) i11 = cython.declare(cython.ulong, n) i12 = cython.declare(cython.slonglong, n) i13 = cython.declare(cython.longlong, n) i14 = cython.declare(cython.ulonglong, n) i20 = cython.declare(cython.Py_ssize_t, n) i21 = cython.declare(cython.size_t, n) # f00 = cython.declare(cython.float, n) f01 = cython.declare(cython.double, n) f02 = cython.declare(cython.longdouble, n) # #z00 = cython.declare(cython.complex, n+1j) #z01 = cython.declare(cython.floatcomplex, n+1j) #z02 = cython.declare(cython.doublecomplex, n+1j) #z03 = cython.declare(cython.longdoublecomplex, n+1j) @cython.ccall @cython.returns(cython.double) def c_call(x): """ Test that a declared return type is honoured when compiled. >>> result, return_type = call_ccall(1) >>> (not is_compiled and 'double') or return_type 'double' >>> (is_compiled and 'int') or return_type 'int' >>> (not is_compiled and 1.0) or result 1.0 >>> (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 @cython.returns(cython.double) def cdef_inline(x): """ >>> result, return_type = call_cdef_inline(1) >>> (not is_compiled and 'float') or type(return_type).__name__ 'float' >>> (not is_compiled and 'double') or return_type 'double' >>> (is_compiled and 'int') or return_type 'int' >>> result == 2.0 or result True """ return x + 1 def call_cdef_inline(x): ret = cdef_inline(x) return ret, cython.typeof(ret) @cython.locals(counts=cython.int[10], digit=cython.int) def count_digits_in_carray(digits): """ >>> digits = '37692837651902834128342341' >>> ''.join(sorted(digits)) '01112222333334445667788899' >>> count_digits_in_carray(map(int, digits)) [1, 3, 4, 5, 3, 1, 2, 2, 3, 2] """ counts = [0] * 10 for digit in digits: assert 0 <= digit <= 9 counts[digit] += 1 return counts Cython-0.23.4/tests/run/pure_pxd.srctree0000644000175600017570000000222112606202452021366 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import a; a.test()" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules=cythonize("a.py"), ) ######## a.py ######## class ExtTypePass(object): pass class ExtTypePxdDocstring(object): pass class ExtTypeDocstring(object): """huhu!""" # this should override the .pxd docstring class ExtTypeAttributes(object): """ >>> x = ExtTypeAttributes() >>> x.b [1, 2, 3] """ def __init__(self): self.a = 123 self.b = [1, 2, 3] def test(): import os.path assert 'a.py' not in os.path.basename(__file__), __file__ assert not ExtTypePass().__doc__, ExtTypePass().__doc__ assert ExtTypeDocstring().__doc__ == "huhu!", ExtTypeDocstring().__doc__ assert ExtTypePxdDocstring().__doc__ == "ho, ho, ho!", ExtTypePxdDocstring().__doc__ import doctest doctest.testmod(verbose=True) ######## a.pxd ######## cdef class ExtTypePass: pass cdef class ExtTypePxdDocstring: """ho, ho, ho!""" cdef class ExtTypeAttributes: cdef int a cdef readonly list b Cython-0.23.4/tests/run/pure_mode_cmethod_inheritance_T583.py0000644000175600017570000000270312606202452025304 0ustar jenkinsjenkins00000000000000class Base(object): ''' >>> base = Base() >>> print(base.noargs()) Base >>> print(base.int_arg(1)) Base >>> print(base._class()) Base ''' def noargs(self): return "Base" def int_arg(self, i): return "Base" @classmethod def _class(tp): return "Base" class Derived(Base): ''' >>> derived = Derived() >>> print(derived.noargs()) Derived >>> print(derived.int_arg(1)) Derived >>> print(derived._class()) Derived ''' def noargs(self): return "Derived" def int_arg(self, i): return "Derived" @classmethod def _class(tp): return "Derived" class DerivedDerived(Derived): ''' >>> derived = DerivedDerived() >>> print(derived.noargs()) DerivedDerived >>> print(derived.int_arg(1)) DerivedDerived >>> print(derived._class()) DerivedDerived ''' def noargs(self): return "DerivedDerived" def int_arg(self, i): return "DerivedDerived" @classmethod def _class(tp): return "DerivedDerived" class Derived2(Base): ''' >>> derived = Derived2() >>> print(derived.noargs()) Derived2 >>> print(derived.int_arg(1)) Derived2 >>> print(derived._class()) Derived2 ''' def noargs(self): return "Derived2" def int_arg(self, i): return "Derived2" @classmethod def _class(tp): return "Derived2" Cython-0.23.4/tests/run/pure_mode_cmethod_inheritance_T583.pxd0000644000175600017570000000071112606202452025444 0ustar jenkinsjenkins00000000000000cdef class Base: cpdef str noargs(self) cpdef str int_arg(self, int i) cpdef str _class(tp) cdef class Derived(Base): cpdef str noargs(self) cpdef str int_arg(self, int i) cpdef str _class(tp) cdef class DerivedDerived(Derived): cpdef str noargs(self) cpdef str int_arg(self, int i) cpdef str _class(tp) cdef class Derived2(Base): cpdef str noargs(self) cpdef str int_arg(self, int i) cpdef str _class(tp) Cython-0.23.4/tests/run/pure.pyx0000644000175600017570000000762512606202452017701 0ustar jenkinsjenkins00000000000000import cython def test_sizeof(): """ >>> test_sizeof() True True True True True """ x = cython.declare(cython.bint) print sizeof(x) == sizeof(cython.bint) print sizeof(cython.char) <= sizeof(cython.short) <= sizeof(cython.int) <= sizeof(cython.long) <= sizeof(cython.longlong) print sizeof(cython.uint) == sizeof(cython.int) print sizeof(cython.p_int) == sizeof(cython.p_double) if cython.compiled: print sizeof(cython.char) < sizeof(cython.longlong) else: print sizeof(cython.char) == 1 def test_declare(n): """ >>> test_declare(100) (100, 100) >>> test_declare(100.5) (100, 100) >>> test_declare(None) Traceback (most recent call last): ... TypeError: an integer is required """ x = cython.declare(cython.int) y = cython.declare(cython.int, n) if cython.compiled: cython.declare(xx=cython.int, yy=cython.long) i = sizeof(xx) ptr = cython.declare(cython.p_int, cython.address(y)) return y, ptr[0] @cython.locals(x=cython.double, n=cython.int) def test_cast(x): """ >>> test_cast(1.5) 1 >>> try: test_cast(None) ... except TypeError: pass """ n = cython.cast(cython.int, x) return n @cython.locals(x=cython.int, y=cython.p_int) def test_address(x): """ >>> test_address(39) 39 """ y = cython.address(x) return y[0] @cython.locals(x=cython.int) @cython.locals(y=cython.bint) def test_locals(x): """ >>> test_locals(5) True """ y = x return y MyUnion = cython.union(n=cython.int, x=cython.double) MyStruct = cython.struct(is_integral=cython.bint, data=MyUnion) MyStruct2 = cython.typedef(MyStruct[2]) def test_struct(n, x): """ >>> test_struct(389, 1.64493) (389, 1.64493) """ a = cython.declare(MyStruct2) a[0] = MyStruct(True, data=MyUnion(n=n)) a[1] = MyStruct(is_integral=False, data={'x': x}) return a[0].data.n, a[1].data.x import cython as cy from cython import declare, cast, locals, address, typedef, p_void, compiled from cython import declare as my_declare, locals as my_locals, p_void as my_void_star, typedef as my_typedef, compiled as my_compiled @my_locals(a=cython.p_void) def test_imports(): """ >>> test_imports() True """ a = cython.NULL b = declare(p_void, cython.NULL) c = my_declare(my_void_star, cython.NULL) d = cy.declare(cy.p_void, cython.NULL) return a == d and compiled and my_compiled MyStruct3 = typedef(MyStruct[3]) MyStruct4 = my_typedef(MyStruct[4]) MyStruct5 = cy.typedef(MyStruct[5]) def test_declare_c_types(n): """ >>> test_declare_c_types(0) >>> test_declare_c_types(1) >>> test_declare_c_types(2) """ # b00 = cython.declare(cython.bint, 0) b01 = cython.declare(cython.bint, 1) b02 = cython.declare(cython.bint, 2) # i00 = cython.declare(cython.uchar, n) i01 = cython.declare(cython.char, n) i02 = cython.declare(cython.schar, n) i03 = cython.declare(cython.ushort, n) i04 = cython.declare(cython.short, n) i05 = cython.declare(cython.sshort, n) i06 = cython.declare(cython.uint, n) i07 = cython.declare(cython.int, n) i08 = cython.declare(cython.sint, n) i09 = cython.declare(cython.slong, n) i10 = cython.declare(cython.long, n) i11 = cython.declare(cython.ulong, n) i12 = cython.declare(cython.slonglong, n) i13 = cython.declare(cython.longlong, n) i14 = cython.declare(cython.ulonglong, n) i20 = cython.declare(cython.Py_ssize_t, n) i21 = cython.declare(cython.size_t, n) # f00 = cython.declare(cython.float, n) f01 = cython.declare(cython.double, n) f02 = cython.declare(cython.longdouble, n) # #z00 = cython.declare(cython.complex, n+1j) #z01 = cython.declare(cython.floatcomplex, n+1j) #z02 = cython.declare(cython.doublecomplex, n+1j) #z03 = cython.declare(cython.longdoublecomplex, n+1j) Cython-0.23.4/tests/run/public_fused_types.srctree0000644000175600017570000001402412606202452023434 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import b" ######## setup.py ######## from Cython.Build import cythonize from distutils.core import setup setup( ext_modules = cythonize("*.pyx"), ) ######## a.pxd ######## cimport cython cdef extern from "header.h": ctypedef int extern_int ctypedef long extern_long cdef struct mystruct_t: extern_int a ctypedef union myunion_t: extern_long a cdef public class MyExt [ type MyExtType, object MyExtObject ]: cdef unsigned char a ctypedef char *string_t simple_t = cython.fused_type(int, float) less_simple_t = cython.fused_type(int, float, string_t) struct_t = cython.fused_type(mystruct_t, myunion_t, MyExt) builtin_t = cython.fused_type(str, unicode, bytes) ctypedef fused fusedbunch: int long complex string_t ctypedef fused fused1: short string_t cdef fused fused2: float double string_t cdef struct_t add_simple(struct_t obj, simple_t simple) cdef less_simple_t add_to_simple(struct_t obj, less_simple_t simple) cdef public_optional_args(struct_t obj, simple_t simple = *) cdef class TestFusedExtMethods(object): cdef cython.floating method(self, cython.integral x, cython.floating y) cpdef cpdef_method(self, cython.integral x, cython.floating y) object_t = cython.fused_type(TestFusedExtMethods, object, list) cpdef public_cpdef(cython.integral x, cython.floating y, object_t z) ######## header.h ######## typedef int extern_int; typedef long extern_long; ######## a.pyx ######## cimport cython cdef struct_t add_simple(struct_t obj, simple_t simple): obj.a = (obj.a + simple) return obj cdef less_simple_t add_to_simple(struct_t obj, less_simple_t simple): return obj.a + simple cdef public_optional_args(struct_t obj, simple_t simple = 6): return obj.a, simple cdef class TestFusedExtMethods(object): cdef cython.floating method(self, cython.integral x, cython.floating y): if cython.integral is int: x += 1 if cython.floating is double: y += 2.0 return x + y cpdef cpdef_method(self, cython.integral x, cython.floating y): return cython.typeof(x), cython.typeof(y) def def_method(self, fused1 x, fused2 y): if (fused1 is string_t and fused2 is not string_t or not fused1 is string_t and fused2 is string_t): return x, y else: return x + y cpdef public_cpdef(cython.integral x, cython.floating y, object_t z): if cython.integral is int: pass return cython.typeof(x), cython.typeof(y), cython.typeof(z) ######## b.pyx ######## cimport cython cimport a as a_cmod from a cimport * cdef mystruct_t mystruct cdef myunion_t myunion cdef MyExt myext = MyExt() mystruct.a = 5 myunion.a = 5 myext.a = 5 assert add_simple(mystruct, 5).a == 10 assert add_simple(myunion, 5.0).a == 10.0 assert add_to_simple(mystruct, 5.0) == 10.0 assert add_to_simple(myunion, b"spamhameggs") == b"ameggs" assert add_to_simple(myext, 5) == 10 cdef mystruct_t (*f)(mystruct_t, int) f = add_simple assert f(mystruct, 5).a == 10 f = add_simple assert f(mystruct, 5).a == 10 f = add_simple[mystruct_t, int] assert f(mystruct, 5).a == 10 assert public_optional_args(mystruct, 5) == (5, 5) assert public_optional_args[mystruct_t, int](mystruct) == (5, 6) assert public_optional_args[mystruct_t, float](mystruct) == (5, 6.0) assert public_optional_args[mystruct_t, float](mystruct, 7.0) == (5, 7.0) cdef TestFusedExtMethods obj = TestFusedExtMethods() cdef int x = 4 cdef float y = 5.0 cdef long a = 6 cdef double b = 7.0 cdef double (*func)(TestFusedExtMethods, long, double) func = obj.method result = func(obj, a, b) assert result == 15.0, result func = obj.method assert func(obj, x, y) == 11.0 func = obj.method[long, double] assert func(obj, a, y) == 13.0 assert obj.method(x, a) == 13.0 assert obj.method[int, double](x, b) == 14.0 # Test inheritance cdef class Subclass(TestFusedExtMethods): cdef cython.floating method(self, cython.integral x, cython.floating y): return -x -y cpdef cpdef_method(self, cython.integral x, cython.floating y): return x, y cdef Subclass myobj = Subclass() assert myobj.method[int, float](5, 5.0) == -10 cdef float (*meth)(Subclass, int, float) meth = myobj.method assert meth(myobj, 5, 5.0) == -10 meth = myobj.method[int, float] assert meth(myobj, 5, 5.0) == -10 # Test cpdef functions and methods cy = __import__("cython") import a as a_mod def ae(result, expected): "assert equals" if result != expected: print 'result :', result print 'expected:', expected assert result == expected ae(a_mod.public_cpdef[int, float, list](5, 6, [7]), ("int", "float", "list object")) idx = cy.typeof(0), cy.typeof(0.0), cy.typeof([]) ae(a_mod.public_cpdef[idx](5, 6, [7]), ("int", "float", "list object")) ae(a_mod.public_cpdef[cy.int, cy.double, cython.typeof(obj)](5, 6, obj), ("int", "double", "TestFusedExtMethods")) ae(a_mod.public_cpdef[cy.int, cy.double, cython.typeof(obj)](5, 6, myobj), ("int", "double", "TestFusedExtMethods")) ae(public_cpdef[int, float, list](5, 6, [7]), ("int", "float", "list object")) ae(public_cpdef[int, double, TestFusedExtMethods](5, 6, obj), ("int", "double", "TestFusedExtMethods")) ae(public_cpdef[int, double, TestFusedExtMethods](5, 6, myobj), ("int", "double", "TestFusedExtMethods")) ae(obj.cpdef_method(10, 10.0), ("long", "double")) ae(myobj.cpdef_method(10, 10.0), (10, 10.0)) ae(obj.cpdef_method[int, float](10, 10.0), ("int", "float")) ae(myobj.cpdef_method[int, float](10, 10.0), (10, 10.0)) s = """\ import cython as cy ae(obj.cpdef_method[cy.int, cy.float](10, 10.0), ("int", "float")) ae(myobj.cpdef_method[cy.int, cy.float](10, 10.0), (10, 10.0)) """ d = {'obj': obj, 'myobj': myobj, 'ae': ae} # FIXME: uncomment after subclassing CyFunction #exec s in d # Test def methods # ae(obj.def_method(12, 14.9), 26) # ae(obj.def_method(13, "spam"), (13, "spam")) # ae(obj.def_method[cy.short, cy.float](13, 16.3), 29) Cython-0.23.4/tests/run/public_enum.pyx0000644000175600017570000000065312606202452021222 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> BAR == 3 True >>> HONK == 3+2+1 True >>> X == 4*5 + 1 True >>> NONPUBLIC # doctest: +ELLIPSIS Traceback (most recent call last): NameError: ...name 'NONPUBLIC' is not defined >>> NOWPUBLIC == 23 + 42 True """ DEF X = 4*5 cdef enum SECRET: NONPUBLIC = 23 + 42 cdef public enum FOO: BAR = 3 HONK = 3+2+1 NOWPUBLIC = NONPUBLIC X = X + 1 # FIXME: should this really work? Cython-0.23.4/tests/run/ptrdiff_t.pyx0000644000175600017570000000205412606202452020676 0ustar jenkinsjenkins00000000000000from cython cimport typeof def test(ptrdiff_t i): """ >>> test(0) 0 >>> test(1) 1 >>> test(2) 2 >>> test(-1) -1 >>> test(-2) -2 >>> str(test((1<<31)-1)) '2147483647' """ return i cdef class A: """ >>> try: test(1<<200) ... except (OverflowError, TypeError): print("ERROR") ERROR >>> a = A(1,2) >>> a.a == 1 True >>> a.b == 2 True >>> a.foo(5) 5 >>> try: a.foo(1<<200) ... except (OverflowError, TypeError): print("ERROR") ERROR """ cdef public ptrdiff_t a cdef readonly ptrdiff_t b def __init__(self, ptrdiff_t a, object b): self.a = a self.b = b cpdef ptrdiff_t foo(self, ptrdiff_t x): cdef object o = x return o def test_types(): """ >>> test_types() """ cdef int a = 1, b = 2 assert typeof(&a - &b) == "ptrdiff_t", typeof(&a - &b) assert typeof((&a - &b) + 1) == "ptrdiff_t", typeof((&a - &b) + 1) assert typeof(&a + (&b - &a)) == "int *", typeof(&a + (&b - &a)) Cython-0.23.4/tests/run/ptr_warning_T714.pyx0000644000175600017570000000026112606202452021764 0ustar jenkinsjenkins00000000000000# mode: run # tag: werror # ticket: 714 def test_ptr(): """ >>> test_ptr() 123 """ cdef int a cdef int *ptr ptr = &a ptr[0] = 123 return a Cython-0.23.4/tests/run/pstats_profile_test.pyx0000644000175600017570000000436312606202452023017 0ustar jenkinsjenkins00000000000000# tag: pstats # cython: profile = True __doc__ = u""" >>> import os, tempfile, cProfile as profile, pstats >>> statsfile = tempfile.mkstemp()[1] >>> profile.runctx("test_profile(100)", locals(), globals(), statsfile) >>> s = pstats.Stats(statsfile) >>> short_stats = dict([(k[2], v[1]) for k,v in s.stats.items()]) >>> short_stats['f_def'] 100 >>> short_stats['f_cdef'] 100 >>> short_stats['f_inline'] 100 >>> short_stats['f_inline_prof'] 100 >>> short_stats['f_noprof'] Traceback (most recent call last): ... KeyError: 'f_noprof' >>> short_stats['f_raise'] 100 >>> short_stats['withgil_prof'] 100 >>> short_stats['withgil_noprof'] Traceback (most recent call last): ... KeyError: 'withgil_noprof' >>> short_stats['nogil_prof'] Traceback (most recent call last): ... KeyError: 'nogil_prof' >>> short_stats['nogil_noprof'] Traceback (most recent call last): ... KeyError: 'nogil_noprof' >>> try: ... os.unlink(statsfile) ... except: ... pass """ import sys if sys.version_info < (2,5): # disable in earlier versions __doc__ = """ >>> # nothing to test here ... """ cimport cython def test_profile(long N): cdef long i, n = 0 for i from 0 <= i < N: n += f_def(i) n += f_cdef(i) n += f_inline(i) n += f_inline_prof(i) n += f_noprof(i) n += nogil_noprof(i) n += nogil_prof(i) n += withgil_noprof(i) n += withgil_prof(i) try: n += f_raise(i+2) except RuntimeError: pass return n def f_def(long a): return a cdef long f_cdef(long a): return a cdef inline long f_inline(long a): return a @cython.profile(True) cdef inline long f_inline_prof(long a): return a @cython.profile(False) cdef int f_noprof(long a): return a cdef long f_raise(long) except -2: raise RuntimeError @cython.profile(False) cdef int withgil_noprof(long a) with gil: return (a) @cython.profile(True) cdef int withgil_prof(long a) with gil: return (a) @cython.profile(False) cdef int nogil_noprof(long a) nogil: return a @cython.profile(True) cdef int nogil_prof(long a) nogil: return a Cython-0.23.4/tests/run/property_decorator_T593.py0000644000175600017570000000112312606202452023173 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 593 # tag: property, decorator class Prop(object): """ >>> p = Prop() >>> p.prop GETTING 'None' >>> p.prop = 1 SETTING '1' (previously: 'None') >>> p.prop GETTING '1' 1 >>> p.prop = 2 SETTING '2' (previously: '1') >>> p.prop GETTING '2' 2 """ _value = None @property def prop(self): print("GETTING '%s'" % self._value) return self._value @prop.setter def prop(self, value): print("SETTING '%s' (previously: '%s')" % (value, self._value)) self._value = value Cython-0.23.4/tests/run/print_refcount.pyx0000644000175600017570000000156112606202452021760 0ustar jenkinsjenkins00000000000000# mode: run import sys def test_print_refcount(): """ >>> test_print_refcount() """ old_stdout = sys.stdout class StdoutGuard: def __getattr__(self, attr): sys.stdout = old_stdout raise RuntimeError sys.stdout = StdoutGuard() try: print "Hello", "world!" except RuntimeError: pass finally: sys.stdout = old_stdout class TriggerSIGSEGV(object): pass def test_printone_refcount(): """ >>> test_printone_refcount() """ old_stdout = sys.stdout class StdoutGuard: def __getattr__(self, attr): sys.stdout = old_stdout raise RuntimeError sys.stdout = StdoutGuard() try: print "Oops!" except RuntimeError: pass finally: sys.stdout = old_stdout class TriggerSIGSEGV(object): pass Cython-0.23.4/tests/run/print_function.pyx0000644000175600017570000000213412606202452021755 0ustar jenkinsjenkins00000000000000 # Py2.6 and later only! from __future__ import print_function def print_to_stdout(a, b): """ >>> print_to_stdout(1, 'test') 1 1 test 1 test 1 test 42 spam """ print() print(a) print(a, end=' ') print(b) print(a, b) print(a, b, end=' ') print(42, u"spam") def print_assign(a, b): """ >>> print_assign(1, 'test') 1 1 test 1 test 1 test 42 spam """ x = print x() x(a) x(a, end=' ') x(b) x(a, b) x(a, b, end=' ') x(42, u"spam") try: from StringIO import StringIO except ImportError: from io import StringIO def print_to_stringio(stream, a, b): """ >>> stream = StringIO() >>> print_to_stringio(stream, 1, 'test') >>> print(stream.getvalue()) 1 1 test 1 test 1 test 42 spam """ print(file=stream) print(a, file=stream) print(a, end=' ', file=stream) print(b, file=stream) print(a, b, file=stream) print(a, b, end=' ', file=stream) print(42, u"spam", file=stream) Cython-0.23.4/tests/run/print.pyx0000644000175600017570000000135112606202452020050 0ustar jenkinsjenkins00000000000000def print_to_stdout(a, b): """ >>> print_to_stdout(1, 'test') 1 1 test 1 test 1 test 42 spam """ print print a print a, print b print a, b print a, b, print 42, u"spam" try: from StringIO import StringIO except ImportError: from io import StringIO def print_to_stringio(stream, a, b): """ >>> stream = StringIO() >>> print_to_stringio(stream, 1, 'test') >>> print(stream.getvalue()) 1 1 test 1 test 1 test 42 spam """ print >> stream print >> stream, a print >> stream, a, print >> stream, b print >> stream, a, b print >> stream, a, b, print >> stream, 42, u"spam" Cython-0.23.4/tests/run/powop.pyx0000644000175600017570000000657312606202452020073 0ustar jenkinsjenkins00000000000000def f(obj2, obj3): """ >>> f(1.0, 2.95)[0] == f(1.0, 2.95)[1] True """ cdef float flt1, flt2, flt3 flt2, flt3 = obj2, obj3 flt1 = flt2 ** flt3 obj1 = obj2 ** obj3 return flt1, obj1 def g(i): """ >>> g(4) 1024 """ return i ** 5 def h(i): """ >>> h(4) 625 """ return 5 ** i def constant_py(): """ >>> constant_py() == 2 ** 10 True """ result = (2) ** 10 return result def constant_long(): """ >>> constant_long() == 2 ** 36 True """ result = (2L) ** 36 return result def small_int_pow(long s): """ >>> small_int_pow(3) (1, 3, 9, 27, 81) >>> small_int_pow(-5) (1, -5, 25, -125, 625) """ return s**0, s**1, s**2, s**3, s**4 def int_pow(short a, short b): """ >>> int_pow(7, 2) 49 >>> int_pow(5, 3) 125 >>> int_pow(2, 10) 1024 """ return a**b class I(int): """ Copied from CPython's test_descr.py >>> I(2) ** I(3) I(8) >>> 2 ** I(3) I(8) >>> I(3).pow2() I(8) """ def __repr__(self): return 'I(%s)' % int(self) def __pow__(self, other, mod=None): if mod is None: return I(pow(int(self), int(other))) else: return I(pow(int(self), int(other), int(mod))) def __rpow__(self, other, mod=None): if mod is None: return I(pow(int(other), int(self), mod)) else: return I(pow(int(other), int(self), int(mod))) def pow2(self): return 2 ** self def optimised_pow2(n): """ >>> optimised_pow2(0) 1 >>> optimised_pow2(1) 2 >>> optimised_pow2(10) 1024 >>> optimised_pow2(30) 1073741824 >>> print(repr(optimised_pow2(31)).rstrip('L')) 2147483648 >>> print(repr(optimised_pow2(32)).rstrip('L')) 4294967296 >>> print(repr(optimised_pow2(60)).rstrip('L')) 1152921504606846976 >>> print(repr(optimised_pow2(63)).rstrip('L')) 9223372036854775808 >>> print(repr(optimised_pow2(64)).rstrip('L')) 18446744073709551616 >>> print(repr(optimised_pow2(100)).rstrip('L')) 1267650600228229401496703205376 >>> optimised_pow2(30000) == 2 ** 30000 True >>> optimised_pow2(-1) 0.5 >>> optimised_pow2(0.5) == 2 ** 0.5 True >>> optimised_pow2('test') Traceback (most recent call last): TypeError: unsupported operand type(s) for ** or pow(): 'int' and 'str' """ if isinstance(n, (int, long)) and 0 <= n < 1000: assert isinstance(2.0 ** n, float), 'float %s' % n assert isinstance(2 ** n, (int, long)), 'int %s' % n return 2 ** n def optimised_pow2_inplace(n): """ >>> optimised_pow2_inplace(0) 1 >>> optimised_pow2_inplace(1) 2 >>> optimised_pow2_inplace(10) 1024 >>> optimised_pow2_inplace(30) 1073741824 >>> print(repr(optimised_pow2_inplace(32)).rstrip('L')) 4294967296 >>> print(repr(optimised_pow2_inplace(100)).rstrip('L')) 1267650600228229401496703205376 >>> optimised_pow2_inplace(30000) == 2 ** 30000 True >>> optimised_pow2_inplace(-1) 0.5 >>> optimised_pow2_inplace(0.5) == 2 ** 0.5 True >>> optimised_pow2_inplace('test') Traceback (most recent call last): TypeError: unsupported operand type(s) for ** or pow(): 'int' and 'str' """ x = 2 x **= n return x Cython-0.23.4/tests/run/posix_time.pyx0000644000175600017570000000136712606202452021103 0ustar jenkinsjenkins00000000000000# tag: posix from posix.time cimport * def test_itimer(sec, usec): """ >>> test_itimer(10, 2) (10, 2) """ cdef itimerval t, gtime t.it_interval.tv_sec = sec t.it_interval.tv_usec = usec t.it_value.tv_sec = sec t.it_value.tv_usec = usec ret = setitimer(ITIMER_REAL, &t, NULL) assert ret == 0 ret = getitimer(ITIMER_REAL, >ime) assert ret == 0 t.it_interval.tv_sec = 0 t.it_interval.tv_usec = 0 t.it_value.tv_sec = 0 t.it_value.tv_usec = 0 ret = setitimer(ITIMER_REAL, &t, NULL) return gtime.it_interval.tv_sec, gtime.it_interval.tv_usec def test_gettimeofday(): """ >>> test_gettimeofday() """ cdef timeval t ret = gettimeofday(&t, NULL) assert ret == 0 Cython-0.23.4/tests/run/posix_test.pyx0000644000175600017570000000446012606202452021121 0ustar jenkinsjenkins00000000000000# tag: posix from libc.stdio cimport * from posix.unistd cimport * from posix.fcntl cimport * cdef int noisy_function() except -1: cdef int ret = 0 ret = printf(b"0123456789\n", 0) assert ret == 11 ret = fflush(stdout) assert ret == 0 ret = fprintf(stdout, b"0123456789\n", 0) assert ret == 11 ret = fflush(stdout) assert ret == 0 ret = write(STDOUT_FILENO, b"0123456789\n", 11) assert ret == 11 return 0 def test_silent_stdout(): """ >>> test_silent_stdout() """ cdef int ret cdef int stdout_save, dev_null stdout_save = dup(STDOUT_FILENO) assert stdout_save != -1 dev_null = open(b"/dev/null", O_WRONLY, 0) assert dev_null != -1 ret = dup2(dev_null, STDOUT_FILENO) assert ret == STDOUT_FILENO ret = close(dev_null) assert ret == 0 try: noisy_function() finally: ret = dup2(stdout_save, STDOUT_FILENO) assert ret == STDOUT_FILENO ret = close(stdout_save) assert ret == 0 cdef class silent_fd: cdef int fd_save, fd def __cinit__(self, int fd=-1): self.fd_save = -1 self.fd = STDOUT_FILENO if fd != -1: self.fd = fd def __enter__(self): cdef int ret = 0, dev_null = -1 assert self.fd_save == -1 dev_null = open(b"/dev/null", O_WRONLY, 0) assert dev_null != -1 try: self.fd_save = dup(self.fd) assert self.fd_save != -1 try: ret = dup2(dev_null, self.fd) assert ret != -1 except: ret = close(self.fd_save) self.fd_save = -1 finally: ret = close(dev_null) def __exit__(self, t, v, tb): cdef int ret = 0 if self.fd_save != -1: ret = dup2(self.fd_save, self.fd) assert ret == self.fd ret = close(self.fd_save) assert ret == 0 self.fd_save = -1 return None def test_silent_stdout_ctxmanager(): """ >> test_silent_stdout_ctxmanager() """ with silent_fd(): noisy_function() try: with silent_fd(): noisy_function() raise RuntimeError except RuntimeError: pass with silent_fd(STDOUT_FILENO): noisy_function() Cython-0.23.4/tests/run/posix_resource.pyx0000644000175600017570000000115012606202452021762 0ustar jenkinsjenkins00000000000000# tag: posix from posix.unistd cimport * from posix.resource cimport * def test_getpriority(): """ >>> test_getpriority() 0 """ ret = getpriority(PRIO_PROCESS, getpid()) # DISABLED - does not work on current test server return 0 # ret def test_getrlimit(): """ >>> test_getrlimit() 0 True """ cdef rlimit rlim rlim.rlim_cur = 0 ret = getrlimit(RLIMIT_CPU, &rlim) print(ret) return rlim.rlim_cur != 0 def test_getrusage(): """ >>> test_getrusage() 0 """ cdef rusage r ret = getrusage(RUSAGE_SELF, &r) return ret Cython-0.23.4/tests/run/pointers.pyx0000644000175600017570000000350212606202452020557 0ustar jenkinsjenkins00000000000000cimport cython cdef char* c_string = b'abcdefg' cdef void* void_ptr = c_string cdef int i = 42 cdef int* int_ptr = &i cdef float x = 42.2 cdef float* float_ptr = &x def compare(): """ >>> compare() True True True False False True True """ print c_string == c_string print c_string == void_ptr print c_string is void_ptr print c_string != void_ptr print c_string is not void_ptr print void_ptr != int_ptr print void_ptr != float_ptr def if_tests(): """ >>> if_tests() True True """ if c_string == void_ptr: print True if c_string != void_ptr: print False if int_ptr != void_ptr: print True def bool_binop(): """ >>> bool_binop() True """ if c_string == void_ptr and c_string == c_string and int_ptr != void_ptr and void_ptr != float_ptr: print True def bool_binop_truth(int x): """ >>> bool_binop_truth(1) True True >>> bool_binop_truth(0) True """ if c_string and void_ptr and int_ptr and (c_string == c_string or int_ptr != void_ptr): print True if c_string and x or not (void_ptr or int_ptr and float_ptr) or x: print True def binop_voidptr(int x, long y, char* z): """ >>> binop_voidptr(1, 3, b'abc') 'void *' """ result = &x and &y and z return cython.typeof(result) def cond_expr_voidptr(int x, long y, char* z): """ >>> cond_expr_voidptr(0, -1, b'abc') ('void *', 0) >>> cond_expr_voidptr(-1, 0, b'abc') ('void *', -1) >>> cond_expr_voidptr(-1, 0, b'') ('void *', 0) >>> cond_expr_voidptr(0, -1, b'') ('void *', -1) """ result = &x if len(z) else &y assert sizeof(long) >= sizeof(int) assert -1 == (-1L) return cython.typeof(result), (result)[0] Cython-0.23.4/tests/run/pinard8.pyx0000644000175600017570000000056212606202452020264 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> f = Fiche() >>> f[0] = 1 >>> f.geti() 1 >>> f[1] = None >>> f.geti() 0 >>> f[0] = 1 >>> f.geti() 1 """ cdef class Fiche: cdef int i def __setitem__(self, element, valeur): self.i = 0 if valeur is None: return self.i = 1 def geti(self): return self.i Cython-0.23.4/tests/run/pinard7.pyx0000644000175600017570000000051212606202452020256 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> c = build() >>> c.method() Traceback (most recent call last): AssertionError: 1 """ cdef enum Mode: a = 1 b = 2 cdef class Curseur: cdef Mode mode def method(self): assert False, self.mode def build(): cdef Curseur c c = Curseur() c.mode = a return c Cython-0.23.4/tests/run/pinard6.pyx0000644000175600017570000000007212606202452020256 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> x (1, 2) """ x = 1, x = 1, 2, Cython-0.23.4/tests/run/pinard5.pyx0000644000175600017570000000051712606202452020261 0ustar jenkinsjenkins00000000000000cdef class Tri: def test(self): return 1 cdef class Curseur: cdef Tri tri def detail(self): return produire_fiches(self.tri) cdef produire_fiches(Tri tri): return tri.test() def test(): """ >>> test() 1 """ cdef Curseur c c = Curseur() c.tri = Tri() return c.detail() Cython-0.23.4/tests/run/pep448_test_extcall.pyx0000644000175600017570000002774612606202452022533 0ustar jenkinsjenkins00000000000000# mode: run # tag: pep448 from __future__ import print_function import sys IS_PY3 = sys.version_info[0] >= 3 if IS_PY3: __doc__ = """ >>> def f(*, w): pass >>> try: errors_call_no_args(f) ... except TypeError: pass ... else: print("FAILED!") >>> def f(*, a, b, c, d, e): pass >>> try: errors_call_no_args(f) ... except TypeError: pass ... else: print("FAILED!") >>> def f(*, kw, b): pass >>> try: errors_call_3args_2kwargs(f) ... except TypeError: pass ... else: print("FAILED!") >>> def f(a, b=2, *, kw): pass >>> try: errors_call_3args_1kwarg(f) ... except TypeError: pass ... else: print("FAILED!") >>> def f(*, kw): pass >>> try: errors_call_1arg_1kwarg(f) ... except TypeError: pass ... else: print("FAILED!") """ # test for method/function calls. adapted from CPython's "test_extcall.py". def sortdict(d): return '{%s}' % ', '.join(['%r: %r' % item for item in sorted(d.items())]) # We're going the use these types for extra testing try: from collections import UserList, UserDict except ImportError: from UserList import UserList from UserDict import UserDict # We're defining four helper functions def e(a,b): print(a, b) def f(*a, **k): print(a, sortdict(k)) def g(x, *y, **z): print(x, y, sortdict(z)) def h(j=1, a=2, h=3): print(j, a, h) # Argument list examples def call_f_positional(): """ >>> call_f_positional() () {} (1,) {} (1, 2) {} (1, 2, 3) {} (1, 2, 3, 4, 5) {} (1, 2, 3, 4, 5) {} (1, 2, 3, 4, 5) {} (1, 2, 3, 4, 5) {} (1, 2, 3, 4, 5, 6, 7) {} (1, 2, 3, 4, 5, 6, 7) {} (1, 2, 3, 4, 5, 6, 7) {} (1, 2) {} """ f() f(1) f(1, 2) f(1, 2, 3) f(1, 2, 3, *(4, 5)) f(1, 2, 3, *[4, 5]) f(*[1, 2, 3], 4, 5) f(1, 2, 3, *UserList([4, 5])) f(1, 2, 3, *[4, 5], *[6, 7]) f(1, *[2, 3], 4, *[5, 6], 7) f(*UserList([1, 2]), *UserList([3, 4]), 5, *UserList([6, 7])) f(1, *[] or () and {}, *() and [], *{} or [] and (), *{} and [] or (), 2) # Here we add keyword arguments def call_f_kwargs(): """ >>> call_f_kwargs() (1, 2, 3) {'a': 4, 'b': 5} (1, 2, 3, 4, 5) {'a': 6, 'b': 7} (1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5} (1, 2, 3, 4, 5) {'a': 6, 'b': 7, 'c': 8} (1, 2, 3, 4, 5) {'a': 8, 'b': 9, 'x': 6, 'y': 7} (1, 2, 3) {'a': 4, 'b': 5} (1, 2, 3, 4, 5) {'a': 6, 'b': 7} (1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5} (1, 2, 3, 4, 5) {'a': 8, 'b': 9, 'x': 6, 'y': 7} (1, 2) {'a': 3} """ f(1, 2, 3, **{'a':4, 'b':5}) f(1, 2, 3, *[4, 5], **{'a':6, 'b':7}) f(1, 2, 3, x=4, y=5, *(6, 7), **{'a':8, 'b': 9}) f(1, 2, 3, *[4, 5], **{'c': 8}, **{'a':6, 'b':7}) f(1, 2, 3, *(4, 5), x=6, y=7, **{'a':8, 'b': 9}) f(1, 2, 3, **UserDict(a=4, b=5)) f(1, 2, 3, *(4, 5), **UserDict(a=6, b=7)) f(1, 2, 3, x=4, y=5, *(6, 7), **UserDict(a=8, b=9)) f(1, 2, 3, *(4, 5), x=6, y=7, **UserDict(a=8, b=9)) f(1, *[] or () and {}, *() and [], *{} or [] and (), *{} and [] or (), 2, **{} and {} or {}, **{} or {} and {}, **{} and {}, a=3) # Examples with invalid arguments (TypeErrors). We're also testing the function # names in the exception messages. # # Verify clearing of SF bug #733667 def errors_f1(): """ >>> errors_f1() # doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: ...got multiple values for keyword argument 'a' """ f(1, 2, **{'a': -1, 'b': 5}, **{'a': 4, 'c': 6}) def errors_f2(): """ >>> errors_f2() # doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: ...multiple values for keyword argument 'a' """ f(1, 2, **{'a': -1, 'b': 5}, a=4, c=6) def errors_e1(): """ >>> try: errors_e1() ... except TypeError: pass ... else: print("FAILED!") """ e(c=4) def errors_e2(): """ >>> try: errors_e2() ... except TypeError: pass ... else: print("FAILED!") """ e(a=1, b=2, c=4) def errors_g1(): """ >>> errors_g1() Traceback (most recent call last): ... TypeError: g() takes at least 1 positional argument (0 given) # TypeError: g() missing 1 required positional argument: 'x' """ g() def errors_g2(): """ >>> errors_g2() Traceback (most recent call last): ... TypeError: g() takes at least 1 positional argument (0 given) # TypeError: g() missing 1 required positional argument: 'x' """ g(*()) def errors_g3(): """ >>> errors_g3() Traceback (most recent call last): ... TypeError: g() takes at least 1 positional argument (0 given) # TypeError: g() missing 1 required positional argument: 'x' """ g(*(), **{}) def call_g_positional(): """ >>> call_g_positional() 1 () {} 1 (2,) {} 1 (2, 3) {} 1 (2, 3, 4, 5) {} """ g(1) g(1, 2) g(1, 2, 3) g(1, 2, 3, *(4, 5)) def call_nonseq_positional1(): """ >>> call_nonseq_positional1() Traceback (most recent call last): ... TypeError: 'Nothing' object is not iterable # TypeError: g() argument after * must be a sequence, not Nothing """ class Nothing(object): pass g(*Nothing()) def call_nonseq_positional2(): """ >>> call_nonseq_positional2() Traceback (most recent call last): ... TypeError: 'Nothing' object is not iterable # TypeError: g() argument after * must be a sequence, not Nothing """ class Nothing(object): def __len__(self): return 5 g(*Nothing()) def call_seqlike_positional1(): """ >>> call_seqlike_positional1() 0 (1, 2) {} """ class Nothing(object): def __len__(self): return 5 def __getitem__(self, i): if i<3: return i else: raise IndexError(i) g(*Nothing()) def call_seqlike_positional2(): """ >>> call_seqlike_positional2() 0 (1, 2, 3) {} """ class Nothing: def __init__(self): self.c = 0 def __iter__(self): return self def __next__(self): if self.c == 4: raise StopIteration c = self.c self.c += 1 return c next = __next__ g(*Nothing()) # Make sure that the function doesn't stomp the dictionary def call_kwargs_unmodified1(): """ >>> call_kwargs_unmodified1() 1 () {'a': 1, 'b': 2, 'c': 3, 'd': 4} True """ d = {'a': 1, 'b': 2, 'c': 3} d2 = d.copy() g(1, d=4, **d) return d == d2 # What about willful misconduct? def call_kwargs_unmodified2(): """ >>> call_kwargs_unmodified2() {} """ def saboteur(**kw): kw['x'] = 'm' return kw d = {} kw = saboteur(a=1, **d) return d def errors_args_kwargs_overlap(): """ >>> errors_args_kwargs_overlap() # doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: ...got multiple values for... argument 'x' """ g(1, 2, 3, **{'x': 4, 'y': 5}) def errors_non_string_kwarg(): """ >>> errors_non_string_kwarg() # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...keywords must be strings """ f(**{1:2}) def errors_unexpected_kwarg(): """ >>> errors_unexpected_kwarg() Traceback (most recent call last): ... TypeError: h() got an unexpected keyword argument 'e' """ h(**{'e': 2}) def errors_call_nonseq(): """ >>> try: errors_call_nonseq() ... except TypeError: pass ... else: print("FAILED!") """ h(*h) def errors_call_builtin_nonseq(): """ >>> try: errors_call_builtin_nonseq() ... except TypeError: pass ... else: print("FAILED!") """ dir(*h) def errors_call_none_nonseq(): """ >>> try: errors_call_none_nonseq() ... except TypeError: pass ... else: print("FAILED!") """ None(*h) def errors_call_nonmapping_kwargs(): """ >>> try: errors_call_nonmapping_kwargs() ... except TypeError: pass ... else: print("FAILED!") """ h(**h) def errors_call_builtin_nonmapping_kwargs(): """ >>> try: errors_call_builtin_nonmapping_kwargs() ... except TypeError: pass ... else: print("FAILED!") """ dir(**h) def errors_call_none_nonmapping_kwargs(): """ >>> try: errors_call_none_nonmapping_kwargs() ... except TypeError: pass ... else: print("FAILED!") """ None(**h) ''' # compile time error in Cython def errors_call_builtin_duplicate_kwarg(): """ >>> errors_call_builtin_duplicate_kwarg() # doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: ...got multiple values for keyword argument 'b' """ dir(b=1, **{'b': 1}) ''' # Another helper function def f2(*a, **b): return a, b def call_many_kwargs(): """ call_many_kwargs() (3, 512, True) """ d = {} for i in range(512): key = 'k%d' % i d[key] = i a, b = f2(1, *(2,3), **d) return len(a), len(b), b == d def call_method(Foo): """ >>> class Foo(object): ... def method(self, arg1, arg2): ... print(arg1+arg2) >>> call_method(Foo) 3 3 5 5 """ x = Foo() Foo.method(*(x, 1, 2)) Foo.method(x, *(1, 2)) if sys.version_info[0] >= 3: Foo.method(*(1, 2, 3)) Foo.method(1, *[2, 3]) else: print(5) print(5) # A PyCFunction that takes only positional parameters should allow an # empty keyword dictionary to pass without a complaint, but raise a # TypeError if te dictionary is not empty def call_builtin_empty_dict(): """ >>> call_builtin_empty_dict() """ silence = id(1, *{}) silence = id(1, **{}) def call_builtin_nonempty_dict(): """ >>> call_builtin_nonempty_dict() Traceback (most recent call last): ... TypeError: id() takes no keyword arguments """ return id(1, **{'foo': 1}) ''' Cython: currently just passes empty kwargs into f() while CPython keeps the content # A corner case of keyword dictionary items being deleted during # the function call setup. See . def call_kwargs_modified_while_building(): """ >>> call_kwargs_modified_while_building() 1 2 """ class Name(str): def __eq__(self, other): try: del x[self] except KeyError: pass return str.__eq__(self, other) def __hash__(self): return str.__hash__(self) x = {Name("a"):1, Name("b"):2} def f(a, b): print(a,b) f(**x) ''' # Too many arguments: def errors_call_one_arg(f): """ >>> def f(): pass >>> try: errors_call_one_arg(f) ... except TypeError: pass ... else: print("FAILED!") """ f(1) def errors_call_2args(f): """ >>> def f(a): pass >>> try: errors_call_2args(f) ... except TypeError: pass ... else: print("FAILED!") """ f(1, 2) def errors_call_3args(f): """ >>> def f(a, b=1): pass >>> try: errors_call_3args(f) ... except TypeError: pass ... else: print("FAILED!") """ f(1, 2, 3) def errors_call_1arg_1kwarg(f): # Py3 only f(1, kw=3) def errors_call_3args_2kwargs(f): # Py3 only f(1, 2, 3, b=3, kw=3) def errors_call_3args_1kwarg(f): # Py3 only f(2, 3, 4, kw=4) # Too few and missing arguments: def errors_call_no_args(f): """ >>> def f(a): pass >>> try: errors_call_no_args(f) ... except TypeError: pass ... else: print("FAILED!") >>> def f(a, b): pass >>> try: errors_call_no_args(f) ... except TypeError: pass ... else: print("FAILED!") >>> def f(a, b, c): pass >>> try: errors_call_no_args(f) ... except TypeError: pass ... else: print("FAILED!") >>> def f(a, b, c, d, e): pass >>> try: errors_call_no_args(f) ... except TypeError: pass ... else: print("FAILED!") """ f() def errors_call_one_missing_kwarg(f): """ >>> def f(a, b=4, c=5, d=5): pass >>> try: errors_call_one_missing_kwarg(f) ... except TypeError: pass ... else: print("FAILED!") """ f(c=12, b=9) Cython-0.23.4/tests/run/pep448_extended_unpacking.pyx0000644000175600017570000002604112606202452023662 0ustar jenkinsjenkins00000000000000 cimport cython class Iter(object): def __init__(self, it=()): self.it = iter(it) def __iter__(self): return self def __next__(self): return next(self.it) next = __next__ class Map(object): def __init__(self, mapping={}): self.mapping = mapping def __iter__(self): return iter(self.mapping) def keys(self): return self.mapping.keys() def __getitem__(self, key): return self.mapping[key] #### tuples @cython.test_fail_if_path_exists( "//TupleNode//TupleNode", "//MergedSequenceNode", ) def unpack_tuple_literal(): """ >>> unpack_tuple_literal() (1, 2, 4, 5) """ return (*(1, 2, *(4, 5)),) def unpack_tuple_literal_mult(): """ >>> unpack_tuple_literal_mult() (1, 2, 4, 5, 4, 5, 1, 2, 4, 5, 4, 5, 1, 2, 4, 5, 4, 5) """ return (*((1, 2, *((4, 5) * 2)) * 3),) @cython.test_fail_if_path_exists( "//TupleNode//TupleNode", "//MergedSequenceNode", ) def unpack_tuple_literal_empty(): """ >>> unpack_tuple_literal_empty() () """ return (*(*(), *()), *(), *(*(*(),),)) def unpack_tuple_simple(it): """ >>> unpack_tuple_simple([]) () >>> unpack_tuple_simple(set()) () >>> unpack_tuple_simple(Iter()) () >>> unpack_tuple_simple([1]) (1,) >>> unpack_tuple_simple([2, 1]) (2, 1) >>> unpack_tuple_simple((2, 1)) (2, 1) >>> sorted(unpack_tuple_simple(set([2, 1]))) [1, 2] >>> unpack_tuple_simple(Iter([2, 1])) (2, 1) """ return (*it,) def unpack_tuple_from_iterable(it): """ >>> unpack_tuple_from_iterable([1, 2, 3]) (1, 2, 1, 2, 3, 1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 1, 1, 2, 3) >>> unpack_tuple_from_iterable((1, 2, 3)) (1, 2, 1, 2, 3, 1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 1, 1, 2, 3) >>> sorted(unpack_tuple_from_iterable(set([1, 2, 3]))) [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3] >>> unpack_tuple_from_iterable([1, 2]) (1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2, 2, 1, 1, 2) >>> sorted(unpack_tuple_from_iterable(set([1, 2]))) [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2] >>> unpack_tuple_from_iterable(Iter([1, 2])) (1, 2, 1, 2, 1, 2, 1) >>> unpack_tuple_from_iterable([3]) (1, 2, 3, 1, 3, 3, 3, 2, 1, 3) >>> unpack_tuple_from_iterable(set([3])) (1, 2, 3, 1, 3, 3, 3, 2, 1, 3) >>> unpack_tuple_from_iterable(Iter([3])) (1, 2, 3, 1, 2, 1) >>> unpack_tuple_from_iterable([]) (1, 2, 1, 2, 1) >>> unpack_tuple_from_iterable(set([])) (1, 2, 1, 2, 1) >>> unpack_tuple_from_iterable([]) (1, 2, 1, 2, 1) >>> unpack_tuple_from_iterable(Iter([1, 2, 3])) (1, 2, 1, 2, 3, 1, 2, 1) """ return (1, 2, *it, 1, *(*it, *it), *it, 2, 1, *it) def unpack_tuple_keep_originals(a, b, c): """ >>> a = b = [1, 2] >>> c = [3, 4] >>> unpack_tuple_keep_originals(a, b, c) (1, 2, 1, 2, 2, 3, 4) >>> a [1, 2] >>> b [1, 2] >>> c [3, 4] >>> a = b = (1, 2) >>> c = (3, 4) >>> unpack_tuple_keep_originals(a, b, c) (1, 2, 1, 2, 2, 3, 4) >>> a (1, 2) >>> b (1, 2) >>> c (3, 4) """ return (*a, *b, 2, *c) #### lists @cython.test_fail_if_path_exists( "//ListNode//ListNode", "//MergedSequenceNode", ) def unpack_list_literal(): """ >>> unpack_list_literal() [1, 2, 4, 5] """ return [*[1, 2, *[4, 5]]] def unpack_list_literal_mult(): """ >>> unpack_list_literal_mult() [1, 2, 4, 5, 4, 5, 1, 2, 4, 5, 4, 5, 1, 2, 4, 5, 4, 5] """ return [*([1, 2, *([4, 5] * 2)] * 3)] @cython.test_fail_if_path_exists( "//ListNode//ListNode", "//MergedSequenceNode", ) def unpack_list_literal_empty(): """ >>> unpack_list_literal_empty() [] """ return [*[*[], *[]], *[], *[*[*[]]]] def unpack_list_simple(it): """ >>> unpack_list_simple([]) [] >>> unpack_list_simple(set()) [] >>> unpack_list_simple(Iter()) [] >>> unpack_list_simple([1]) [1] >>> unpack_list_simple([2, 1]) [2, 1] >>> unpack_list_simple((2, 1)) [2, 1] >>> sorted(unpack_list_simple(set([2, 1]))) [1, 2] >>> unpack_list_simple(Iter([2, 1])) [2, 1] """ return [*it] def unpack_list_from_iterable(it): """ >>> unpack_list_from_iterable([1, 2, 3]) [1, 2, 1, 2, 3, 1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 1, 1, 2, 3] >>> unpack_list_from_iterable((1, 2, 3)) [1, 2, 1, 2, 3, 1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 1, 1, 2, 3] >>> sorted(unpack_list_from_iterable(set([1, 2, 3]))) [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3] >>> unpack_list_from_iterable([1, 2]) [1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2, 2, 1, 1, 2] >>> sorted(unpack_list_from_iterable(set([1, 2]))) [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2] >>> unpack_list_from_iterable(Iter([1, 2])) [1, 2, 1, 2, 1, 2, 1] >>> unpack_list_from_iterable([3]) [1, 2, 3, 1, 3, 3, 3, 2, 1, 3] >>> unpack_list_from_iterable(set([3])) [1, 2, 3, 1, 3, 3, 3, 2, 1, 3] >>> unpack_list_from_iterable(Iter([3])) [1, 2, 3, 1, 2, 1] >>> unpack_list_from_iterable([]) [1, 2, 1, 2, 1] >>> unpack_list_from_iterable(set([])) [1, 2, 1, 2, 1] >>> unpack_list_from_iterable([]) [1, 2, 1, 2, 1] >>> unpack_list_from_iterable(Iter([1, 2, 3])) [1, 2, 1, 2, 3, 1, 2, 1] """ return [1, 2, *it, 1, *[*it, *it], *it, 2, 1, *it] def unpack_list_keep_originals(a, b, c): """ >>> a = b = [1, 2] >>> c = [3, 4] >>> unpack_list_keep_originals(a, b, c) [1, 2, 1, 2, 2, 3, 4] >>> a [1, 2] >>> b [1, 2] >>> c [3, 4] """ return [*a, *b, 2, *c] ###### sets @cython.test_fail_if_path_exists( "//SetNode//SetNode", "//MergedSequenceNode", ) def unpack_set_literal(): """ >>> s = unpack_set_literal() >>> s == set([1, 2, 4, 5]) or s True """ return {*{1, 2, *{4, 5}}} def unpack_set_simple(it): """ >>> s = unpack_set_simple([]) >>> s == set([]) or s True >>> s = unpack_set_simple(set()) >>> s == set([]) or s True >>> s = unpack_set_simple(Iter()) >>> s == set([]) or s True >>> s = unpack_set_simple([1]) >>> s == set([1]) or s True >>> s = unpack_set_simple([2, 1]) >>> s == set([1, 2]) or s True >>> s = unpack_set_simple((2, 1)) >>> s == set([1, 2]) or s True >>> s = unpack_set_simple(set([2, 1])) >>> s == set([1, 2]) or s True >>> s = unpack_set_simple(Iter([2, 1])) >>> s == set([1, 2]) or s True """ return {*it} def unpack_set_from_iterable(it): """ >>> s = unpack_set_from_iterable([1, 2, 3]) >>> s == set([1, 2, 3]) or s True >>> s = unpack_set_from_iterable([1, 2]) >>> s == set([1, 2]) or s True >>> s = unpack_set_from_iterable(set([1, 2])) >>> s == set([1, 2]) or s True >>> s = unpack_set_from_iterable(Iter([1, 2])) >>> s == set([1, 2]) or s True >>> s = unpack_set_from_iterable([3]) >>> s == set([1, 2, 3]) or s True >>> s = unpack_set_from_iterable(set([3])) >>> s == set([1, 2, 3]) or s True >>> s = unpack_set_from_iterable(Iter([3])) >>> s == set([1, 2, 3]) or s True >>> s = unpack_set_from_iterable([]) >>> s == set([1, 2]) or s True >>> s = unpack_set_from_iterable(set([])) >>> s == set([1, 2]) or s True >>> s = unpack_set_from_iterable([]) >>> s == set([1, 2]) or s True >>> s = unpack_set_from_iterable((1, 2, 3)) >>> s == set([1, 2, 3]) or s True >>> s = unpack_set_from_iterable(set([1, 2, 3])) >>> s == set([1, 2, 3]) or s True >>> s = unpack_set_from_iterable(Iter([1, 2, 3])) >>> s == set([1, 2, 3]) or s True """ return {1, 2, *it, 1, *{*it, *it}, *it, 2, 1, *it, *it} def unpack_set_keep_originals(a, b, c): """ >>> a = b = set([1, 2]) >>> c = set([3, 4]) >>> s = unpack_set_keep_originals(a, b, c) >>> s == set([1, 2, 3, 4]) or s True >>> a == set([1, 2]) or a True >>> b == set([1, 2]) or b True >>> c == set([3, 4]) or c True """ return {*a, *b, 2, *c} #### dicts @cython.test_fail_if_path_exists( "//DictNode//DictNode", "//MergedDictNode", ) def unpack_dict_literal(): """ >>> d = unpack_dict_literal() >>> d == dict(a=1, b=2, c=4, d=5) or d True """ return {**{'a': 1, 'b': 2, **{'c': 4, 'd': 5}}} @cython.test_fail_if_path_exists( "//DictNode//DictNode", "//MergedDictNode", ) def unpack_dict_literal_empty(): """ >>> unpack_dict_literal_empty() {} """ return {**{**{}, **{}}, **{}, **{**{**{}}}} def unpack_dict_simple(it): """ >>> d = unpack_dict_simple({}) >>> d == {} or d True >>> d = unpack_dict_simple([]) >>> d == {} or d True >>> d = unpack_dict_simple(set()) >>> d == {} or d True >>> d = unpack_dict_simple(Iter()) >>> d == {} or d True >>> d = unpack_dict_simple(Map()) >>> d == {} or d True >>> d = unpack_dict_simple(dict(a=1)) >>> d == dict(a=1) or d True >>> d = unpack_dict_simple(dict(a=1, b=2)) >>> d == dict(a=1, b=2) or d True >>> d = unpack_dict_simple(Map(dict(a=1, b=2))) >>> d == dict(a=1, b=2) or d True """ return {**it} def unpack_dict_from_iterable(it): """ >>> d = unpack_dict_from_iterable(dict(a=1, b=2, c=3)) >>> d == dict(a=1, b=2, c=3) or d True >>> d = unpack_dict_from_iterable(dict(a=1, b=2)) >>> d == dict(a=1, b=2) or d True >>> d = unpack_dict_from_iterable(Map(dict(a=1, b=2))) >>> d == dict(a=1, b=2) or d True >>> d = unpack_dict_from_iterable(dict(a=3)) >>> d == dict(a=3, b=5) or d True >>> d = unpack_dict_from_iterable(Map(dict(a=3))) >>> d == dict(a=3, b=5) or d True >>> d = unpack_dict_from_iterable({}) >>> d == dict(a=4, b=5) or d True >>> d = unpack_dict_from_iterable(Map()) >>> d == dict(a=4, b=5) or d True >>> d = unpack_dict_from_iterable(Iter()) Traceback (most recent call last): TypeError: 'Iter' object is not a mapping >>> d = unpack_dict_from_iterable([]) Traceback (most recent call last): TypeError: 'list' object is not a mapping >>> d = unpack_dict_from_iterable(dict(b=2, c=3)) >>> d == dict(a=4, b=2, c=3) or d True >>> d = unpack_dict_from_iterable(Map(dict(b=2, c=3))) >>> d == dict(a=4, b=2, c=3) or d True >>> d = unpack_dict_from_iterable(dict(a=2, c=3)) >>> d == dict(a=2, b=5, c=3) or d True >>> d = unpack_dict_from_iterable(Map(dict(a=2, c=3))) >>> d == dict(a=2, b=5, c=3) or d True """ return {'a': 2, 'b': 3, **it, 'a': 1, **{**it, **it}, **it, 'a': 4, 'b': 5, **it, **it} def unpack_dict_keep_originals(a, b, c): """ >>> a = b = {1: 2} >>> c = {2: 3, 4: 5} >>> d = unpack_dict_keep_originals(a, b, c) >>> d == {1: 2, 2: 3, 4: 5} or d True >>> a {1: 2} >>> b {1: 2} >>> c == {2: 3, 4: 5} or c True """ return {**a, **b, 2: 4, **c} Cython-0.23.4/tests/run/pass.pyx0000644000175600017570000000005612606202452017663 0ustar jenkinsjenkins00000000000000def f(): """ >>> f() """ pass Cython-0.23.4/tests/run/parallel_swap_assign_T425.pyx0000644000175600017570000001625512606202452023635 0ustar jenkinsjenkins00000000000000# ticket: 425 cimport cython @cython.test_assert_path_exists( "//ParallelAssignmentNode", "//ParallelAssignmentNode/SingleAssignmentNode", "//ParallelAssignmentNode/SingleAssignmentNode//CoerceToTempNode/NameNode", "//ParallelAssignmentNode/SingleAssignmentNode//CoerceToTempNode[@use_managed_ref=False]/NameNode", ) @cython.test_fail_if_path_exists( "//ParallelAssignmentNode/SingleAssignmentNode//CoerceToTempNode[@use_managed_ref=True]", ) def swap(a,b): """ >>> swap(1,2) (2, 1) """ a,b = b,a return a,b @cython.test_assert_path_exists( "//ParallelAssignmentNode", "//ParallelAssignmentNode/SingleAssignmentNode", "//ParallelAssignmentNode/SingleAssignmentNode//CoerceToTempNode/NameNode", "//ParallelAssignmentNode/SingleAssignmentNode//CoerceToTempNode[@use_managed_ref=False]/NameNode", ) @cython.test_fail_if_path_exists( "//ParallelAssignmentNode/SingleAssignmentNode//CoerceToTempNode[@use_managed_ref=True]", ) def swap5(a,b,c,d,e): """ >>> swap5(1,2,3,4,5) (5, 4, 3, 2, 1) """ a,b,c,d,e = e,d,c,b,a return a,b,c,d,e @cython.test_assert_path_exists( "//ParallelAssignmentNode", "//ParallelAssignmentNode/SingleAssignmentNode", "//ParallelAssignmentNode/SingleAssignmentNode//CoerceToTempNode/NameNode", "//ParallelAssignmentNode/SingleAssignmentNode//CoerceToTempNode[@use_managed_ref=False]/NameNode", ) @cython.test_fail_if_path_exists( "//ParallelAssignmentNode/SingleAssignmentNode//CoerceToTempNode[@use_managed_ref=True]", ) cdef bint c_swap_cmp5(a, b, c, d, e): a,b,c,d,e = e,d,c,b,a return a > b > c > d > e def swap_cmp5(a,b,c,d,e): """ >>> swap_cmp5(1,2,3,4,5) True """ return c_swap_cmp5(a,b,c,d,e) @cython.test_assert_path_exists( "//ParallelAssignmentNode", "//ParallelAssignmentNode/SingleAssignmentNode", "//ParallelAssignmentNode/SingleAssignmentNode//CoerceToTempNode/NameNode", "//ParallelAssignmentNode/SingleAssignmentNode//CoerceToTempNode[@use_managed_ref=True]/NameNode", ) @cython.test_fail_if_path_exists( "//ParallelAssignmentNode/SingleAssignmentNode//CoerceToTempNode[@use_managed_ref=False]", ) def swap_py(a,b): """ >>> swap_py(1,2) (1, 2) """ a,a = b,a return a,b cdef class A: cdef readonly object x cdef readonly object y def __init__(self, x, y): self.x, self.y = x, y @cython.test_assert_path_exists( "//ParallelAssignmentNode", "//ParallelAssignmentNode/SingleAssignmentNode", "//ParallelAssignmentNode/SingleAssignmentNode/CoerceToTempNode", "//ParallelAssignmentNode/SingleAssignmentNode/CoerceToTempNode[@use_managed_ref=False]", "//ParallelAssignmentNode/SingleAssignmentNode//AttributeNode/NameNode", "//ParallelAssignmentNode/SingleAssignmentNode//AttributeNode[@use_managed_ref=False]/NameNode", ) @cython.test_fail_if_path_exists( "//ParallelAssignmentNode/SingleAssignmentNode/CoerceToTempNode[@use_managed_ref=True]", "//ParallelAssignmentNode/SingleAssignmentNode/AttributeNode[@use_managed_ref=True]", ) def swap_attr_values(A a, A b): """ >>> a, b = A(1,2), A(3,4) >>> a.x, a.y, b.x, b.y (1, 2, 3, 4) >>> swap_attr_values(a,b) >>> a.x, a.y, b.x, b.y (3, 2, 1, 4) """ a.x, a.y, b.x, b.y = a.y, b.x, b.y, a.x # shift by one a.x, a.y, b.x, b.y = b.x, b.y, a.x, a.y # shift by two a.x, a.y, b.x, b.y = b.y, b.x, a.y, a.x # reverse cdef class B: cdef readonly A a1 cdef readonly A a2 def __init__(self, x1, y1, x2, y2): self.a1, self.a2 = A(x1, y1), A(x2, y2) @cython.test_assert_path_exists( "//ParallelAssignmentNode", "//ParallelAssignmentNode/SingleAssignmentNode", "//ParallelAssignmentNode/SingleAssignmentNode/CoerceToTempNode", "//ParallelAssignmentNode/SingleAssignmentNode/CoerceToTempNode[@use_managed_ref=False]", "//ParallelAssignmentNode/SingleAssignmentNode//AttributeNode/NameNode", "//ParallelAssignmentNode/SingleAssignmentNode//AttributeNode[@use_managed_ref=False]/NameNode", ) @cython.test_fail_if_path_exists( "//ParallelAssignmentNode/SingleAssignmentNode/CoerceToTempNode[@use_managed_ref=True]", "//ParallelAssignmentNode/SingleAssignmentNode/AttributeNode[@use_managed_ref=True]", ) def swap_recursive_attr_values(B a, B b): """ >>> a, b = B(1,2,3,4), B(5,6,7,8) >>> a.a1.x, a.a1.y, a.a2.x, a.a2.y (1, 2, 3, 4) >>> b.a1.x, b.a1.y, b.a2.x, b.a2.y (5, 6, 7, 8) >>> swap_recursive_attr_values(a,b) >>> a.a1.x, a.a1.y, a.a2.x, a.a2.y (2, 1, 4, 4) >>> b.a1.x, b.a1.y, b.a2.x, b.a2.y (6, 5, 8, 8) # compatibility test >>> class A: ... def __init__(self, x, y): ... self.x, self.y = x, y >>> class B: ... def __init__(self, x1, y1, x2, y2): ... self.a1, self.a2 = A(x1, y1), A(x2, y2) >>> a, b = B(1,2,3,4), B(5,6,7,8) >>> a.a1, a.a2 = a.a2, a.a1 >>> b.a1, b.a2 = b.a2, b.a1 >>> a.a1, a.a1.x, a.a2.y, a.a2, a.a1.y, a.a2.x = a.a2, a.a2.y, a.a1.x, a.a1, a.a2.x, a.a1.y >>> b.a1, b.a1.x, b.a2.y, b.a2, b.a1.y, b.a2.x = b.a2, b.a2.y, b.a1.x, b.a1, b.a2.x, b.a1.y >>> a.a1.x, a.a1.y, a.a2.x, a.a2.y (2, 1, 4, 4) >>> b.a1.x, b.a1.y, b.a2.x, b.a2.y (6, 5, 8, 8) """ a.a1, a.a2 = a.a2, a.a1 b.a1, b.a2 = b.a2, b.a1 a.a1, a.a1.x, a.a2.y, a.a2, a.a1.y, a.a2.x = a.a2, a.a2.y, a.a1.x, a.a1, a.a2.x, a.a1.y b.a1, b.a1.x, b.a2.y, b.a2, b.a1.y, b.a2.x = b.a2, b.a2.y, b.a1.x, b.a1, b.a2.x, b.a1.y @cython.test_assert_path_exists( # "//ParallelAssignmentNode", # "//ParallelAssignmentNode/SingleAssignmentNode", # "//ParallelAssignmentNode/SingleAssignmentNode//IndexNode", # "//ParallelAssignmentNode/SingleAssignmentNode//IndexNode[@use_managed_ref=False]", ) @cython.test_fail_if_path_exists( # "//ParallelAssignmentNode/SingleAssignmentNode//IndexNode[@use_managed_ref=True]", ) def swap_list_items(list a, int i, int j): """ >>> l = [1,2,3,4] >>> swap_list_items(l, 1, 2) >>> l [1, 3, 2, 4] >>> swap_list_items(l, 3, 0) >>> l [4, 3, 2, 1] >>> swap_list_items(l, 0, 5) Traceback (most recent call last): IndexError: list index out of range >>> l [4, 3, 2, 1] """ a[i], a[j] = a[j], a[i] @cython.test_assert_path_exists( "//ParallelAssignmentNode", "//ParallelAssignmentNode/SingleAssignmentNode", "//ParallelAssignmentNode/SingleAssignmentNode//IndexNode", "//ParallelAssignmentNode/SingleAssignmentNode//IndexNode[@use_managed_ref=True]", ) @cython.test_fail_if_path_exists( "//ParallelAssignmentNode/SingleAssignmentNode//IndexNode[@use_managed_ref=False]", ) def swap_list_items_py1(list a, int i, int j): a[i], a[j] = a[j+1], a[i] @cython.test_assert_path_exists( "//ParallelAssignmentNode", "//ParallelAssignmentNode/SingleAssignmentNode", "//ParallelAssignmentNode/SingleAssignmentNode//IndexNode", "//ParallelAssignmentNode/SingleAssignmentNode//IndexNode[@use_managed_ref=True]", ) @cython.test_fail_if_path_exists( "//ParallelAssignmentNode/SingleAssignmentNode//IndexNode[@use_managed_ref=False]", ) def swap_list_items_py2(list a, int i, int j): a[i], a[j] = a[i], a[i] Cython-0.23.4/tests/run/parallel.pyx0000644000175600017570000000414212606202452020511 0ustar jenkinsjenkins00000000000000# tag: run # tag: openmp cimport cython.parallel from cython.parallel import prange, threadid cimport openmp from libc.stdlib cimport malloc, free openmp.omp_set_nested(1) def test_parallel(): """ >>> test_parallel() """ cdef int maxthreads = openmp.omp_get_max_threads() cdef int *buf = malloc(sizeof(int) * maxthreads) if buf == NULL: raise MemoryError with nogil, cython.parallel.parallel(): buf[threadid()] = threadid() for i in range(maxthreads): assert buf[i] == i free(buf) cdef int get_num_threads() with gil: print "get_num_threads called" return 3 def test_num_threads(): """ >>> test_num_threads() 1 get_num_threads called 3 get_num_threads called 3 """ cdef int dyn = openmp.omp_get_dynamic() cdef int num_threads cdef int *p = &num_threads openmp.omp_set_dynamic(0) with nogil, cython.parallel.parallel(num_threads=1): p[0] = openmp.omp_get_num_threads() print num_threads with nogil, cython.parallel.parallel(num_threads=get_num_threads()): p[0] = openmp.omp_get_num_threads() print num_threads cdef int i num_threads = 0xbad for i in prange(1, nogil=True, num_threads=get_num_threads()): p[0] = openmp.omp_get_num_threads() break openmp.omp_set_dynamic(dyn) return num_threads ''' def test_parallel_catch(): """ >>> test_parallel_catch() True """ cdef int i, j, num_threads exceptions = [] for i in prange(100, nogil=True, num_threads=4): num_threads = openmp.omp_get_num_threads() with gil: try: for j in prange(100, nogil=True): if i + j > 60: with gil: raise Exception("try and catch me if you can!") except Exception, e: exceptions.append(e) break print len(exceptions) == num_threads assert len(exceptions) == num_threads, (len(exceptions), num_threads) ''' OPENMP_PARALLEL = True include "sequential_parallel.pyx" Cython-0.23.4/tests/run/packedstruct_T290.pyx0000644000175600017570000000035012606202452022124 0ustar jenkinsjenkins00000000000000# ticket: 290 """ >>> f() (9, 9) """ cdef packed struct MyCdefStruct: char a double b ctypedef packed struct MyCTypeDefStruct: char a double b def f(): return (sizeof(MyCdefStruct), sizeof(MyCTypeDefStruct)) Cython-0.23.4/tests/run/owned_arg_refs.pyx0000644000175600017570000000223412606202452021701 0ustar jenkinsjenkins00000000000000 cdef class Owner: cdef object x cdef call_me_with_owner(Owner owner, x): owner.x = "def" # overwrite external reference return x # crashes if x is not owned by function or caller def test_ext_type_attr(): """ >>> test_ext_type_attr() 'abc5' """ owner = Owner() owner.x = ''.join("abc%d" % 5) # non-interned object return call_me_with_owner(owner, owner.x) cdef void call_me_without_gil(Owner owner, x) with gil: owner.x = "def" # overwrite external reference print x # crashes if x is not owned by function or caller def test_ext_type_attr_nogil(): """ >>> test_ext_type_attr_nogil() abc5 """ owner = Owner() owner.x = ''.join("abc%d" % 5) # non-interned object with nogil: call_me_without_gil(owner, owner.x) # the following isn't dangerous as long as index access uses temps cdef call_me_with_list(list l, x): l[:] = [(1,2), (3,4)] # overwrite external reference return x # crashes if x is not owned by function or caller def test_index(): """ >>> test_index() [3, 4] """ l = [[1,2],[3,4]] return call_me_with_list(l, l[1]) Cython-0.23.4/tests/run/overflow_check_ulonglong.pyx0000644000175600017570000000014412606202452023777 0ustar jenkinsjenkins00000000000000# cython: overflowcheck.fold = True ctypedef unsigned long long INT include "overflow_check.pxi" Cython-0.23.4/tests/run/overflow_check_uint.pyx0000644000175600017570000000013712606202452022754 0ustar jenkinsjenkins00000000000000# cython: overflowcheck.fold = False ctypedef unsigned int INT include "overflow_check.pxi" Cython-0.23.4/tests/run/overflow_check_longlong.pyx0000644000175600017570000000013412606202452023611 0ustar jenkinsjenkins00000000000000# cython: overflowcheck.fold = False ctypedef long long INT include "overflow_check.pxi" Cython-0.23.4/tests/run/overflow_check_int.pyx0000644000175600017570000000012512606202452022564 0ustar jenkinsjenkins00000000000000# cython: overflowcheck.fold = True ctypedef int INT include "overflow_check.pxi" Cython-0.23.4/tests/run/overflow_check.pxi0000644000175600017570000001532312606202452021700 0ustar jenkinsjenkins00000000000000cimport cython cdef object two = 2 cdef int size_in_bits = sizeof(INT) * 8 cdef bint is_signed_ = not ((-1) > 0) cdef INT max_value_ = (two ** (size_in_bits - is_signed_) - 1) cdef INT min_value_ = ~max_value_ cdef INT half_ = max_value_ // 2 # Python visible. is_signed = is_signed_ max_value = max_value_ min_value = min_value_ half = half_ import operator from libc.math cimport sqrt cpdef check(func, op, a, b): cdef INT res = 0, op_res = 0 cdef bint func_overflow = False cdef bint assign_overflow = False try: res = func(a, b) except OverflowError: func_overflow = True try: op_res = op(a, b) except OverflowError: assign_overflow = True assert func_overflow == assign_overflow, "Inconsistant overflow: %s(%s, %s)" % (func, a, b) if not func_overflow: assert res == op_res, "Inconsistant values: %s(%s, %s) == %s != %s" % (func, a, b, res, op_res) medium_values = (max_value_ / 2, max_value_ / 3, min_value_ / 2, sqrt(max_value_) - 1, sqrt(max_value_) + 1) def run_test(func, op): cdef INT offset, b check(func, op, 300, 200) check(func, op, max_value_, max_value_) check(func, op, max_value_, min_value_) if not is_signed_ or not func is test_sub: check(func, op, min_value_, min_value_) for offset in range(5): check(func, op, max_value_ - 1, offset) check(func, op, min_value_ + 1, offset) if is_signed_: check(func, op, max_value_ - 1, 2 - offset) check(func, op, min_value_ + 1, 2 - offset) for offset in range(9): check(func, op, max_value_ / 2, offset) check(func, op, min_value_ / 3, offset) check(func, op, max_value_ / 4, offset) check(func, op, min_value_ / 5, offset) if is_signed_: check(func, op, max_value_ / 2, 4 - offset) check(func, op, min_value_ / 3, 4 - offset) check(func, op, max_value_ / -4, 3 - offset) check(func, op, min_value_ / -5, 3 - offset) for offset in range(-3, 4): for a in medium_values: for b in medium_values: check(func, op, a, b + offset) @cython.overflowcheck(True) def test_add(INT a, INT b): """ >>> test_add(1, 2) 3 >>> test_add(max_value, max_value) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large >>> run_test(test_add, operator.add) """ return int(a + b) @cython.overflowcheck(True) def test_sub(INT a, INT b): """ >>> test_sub(10, 1) 9 >>> test_sub(min_value, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large >>> run_test(test_sub, operator.sub) """ return int(a - b) @cython.overflowcheck(True) def test_mul(INT a, INT b): """ >>> test_mul(11, 13) 143 >>> test_mul(max_value / 2, max_value / 2) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large >>> run_test(test_mul, operator.mul) """ return int(a * b) @cython.overflowcheck(True) def test_nested_add(INT a, INT b, INT c): """ >>> test_nested_add(1, 2, 3) 6 >>> expect_overflow(test_nested_add, half + 1, half + 1, half + 1) >>> expect_overflow(test_nested_add, half - 1, half - 1, half - 1) """ return int(a + b + c) def expect_overflow(func, *args): try: res = func(*args) except OverflowError: return assert False, "Expected OverflowError, got %s" % res cpdef format(INT value): """ >>> format(1) '1' >>> format(half - 1) 'half - 1' >>> format(half) 'half' >>> format(half + 2) 'half + 2' >>> format(half + half - 3) 'half + half - 3' >>> format(max_value) 'max_value' """ if value == max_value_: return "max_value" elif value == half_: return "half" elif max_value_ - value <= max_value_ // 4: return "half + half - %s" % (half_ + half_ - value) elif max_value_ - value <= half_: return "half + %s" % (value - half_) elif max_value_ - value <= half_ + max_value_ // 4: return "half - %s" % (half_ - value) else: return "%s" % value cdef INT called(INT value): print("called(%s)" % format(value)) return value @cython.overflowcheck(True) def test_nested(INT a, INT b, INT c, INT d): """ >>> test_nested_func(1, 2, 3) called(5) 6 >>> expect_overflow(test_nested, half, half, 1, 1) >>> expect_overflow(test_nested, half, 1, half, half) >>> expect_overflow(test_nested, half, 2, half, 2) >>> print(format(test_nested(half, 2, 0, 1))) half + half - 0 >>> print(format(test_nested(1, 0, half, 2))) half + half - 0 >>> print(format(test_nested(half, 1, 1, half))) half + half - 0 """ return int(a * b + c * d) @cython.overflowcheck(True) def test_nested_func(INT a, INT b, INT c): """ >>> test_nested_func(1, 2, 3) called(5) 6 >>> expect_overflow(test_nested_func, half + 1, half + 1, half + 1) >>> expect_overflow(test_nested_func, half - 1, half - 1, half - 1) called(half + half - 2) >>> print(format(test_nested_func(1, half - 1, half - 1))) called(half + half - 2) half + half - 1 """ return int(a + called(b + c)) @cython.overflowcheck(True) def test_add_const(INT a): """ >>> test_add_const(1) 101 >>> expect_overflow(test_add_const, max_value) >>> expect_overflow(test_add_const , max_value - 99) >>> test_add_const(max_value - 100) == max_value True """ return int(a + 100) @cython.overflowcheck(True) def test_sub_const(INT a): """ >>> test_sub_const(101) 1 >>> expect_overflow(test_sub_const, min_value) >>> expect_overflow(test_sub_const, min_value + 99) >>> test_sub_const(min_value + 100) == min_value True """ return int(a - 100) @cython.overflowcheck(True) def test_mul_const(INT a): """ >>> test_mul_const(2) 200 >>> expect_overflow(test_mul_const, max_value) >>> expect_overflow(test_mul_const, max_value // 99) >>> test_mul_const(max_value // 100) == max_value - max_value % 100 True """ return int(a * 100) @cython.overflowcheck(True) def test_lshift(INT a, int b): """ >>> test_lshift(1, 10) 1024 >>> expect_overflow(test_lshift, 1, 100) >>> expect_overflow(test_lshift, max_value, 1) >>> test_lshift(max_value, 0) == max_value True >>> check(test_lshift, operator.lshift, 10, 15) >>> check(test_lshift, operator.lshift, 10, 30) >>> check(test_lshift, operator.lshift, 100, 60) """ return int(a << b) Cython-0.23.4/tests/run/or.pyx0000644000175600017570000000202112606202452017327 0ustar jenkinsjenkins00000000000000a,b = 'a *','b *' # use non-interned strings def or2_assign(a,b): """ >>> or2_assign(2,3) == (2 or 3) True >>> or2_assign('a', 'b') == ('a' or 'b') True >>> or2_assign(a, b) == (a or b) True """ c = a or b return c def or2(a,b): """ >>> or2(2,3) == (2 or 3) True >>> or2(0,2) == (0 or 2) True >>> or2('a', 'b') == ('a' or 'b') True >>> or2(a, b) == (a or b) True >>> or2('', 'b') == ('' or 'b') True >>> or2([], [1]) == ([] or [1]) True >>> or2([], [a]) == ([] or [a]) True """ return a or b def or3(a,b,c): """ >>> or3(0,1,2) == (0 or 1 or 2) True >>> or3([],(),[1]) == ([] or () or [1]) True """ d = a or b or c return d def or2_no_result(a,b): """ >>> or2_no_result(2,3) >>> or2_no_result(0,2) >>> or2_no_result('a','b') >>> or2_no_result(a,b) >>> a or b 'a *' """ a or b def or2_literal(): """ >>> or2_literal() 5 """ return False or 5 Cython-0.23.4/tests/run/ooo_base_classes.pyx0000644000175600017570000000042512606202452022220 0ustar jenkinsjenkins00000000000000cdef class B(A): cpdef foo(self): """ >>> B().foo() B """ print "B" cdef class A(object): cpdef foo(self): """ >>> A().foo() A """ print "A" cdef class C(A): cpdef foo(self): """ >>> C().foo() C """ print "C" Cython-0.23.4/tests/run/onelinesuite.py0000644000175600017570000000073412606202452021233 0ustar jenkinsjenkins00000000000000# mode: run # tag: syntax """ >>> y # doctest: +ELLIPSIS Traceback (most recent call last): NameError: ...name 'y' is not defined >>> z # doctest: +ELLIPSIS Traceback (most recent call last): NameError: ...name 'z' is not defined >>> f() 17 """ x = False if x: y = 42; z = 88 def f(): return 17 def suite_in_func(x): """ >>> suite_in_func(True) (42, 88) >>> suite_in_func(False) (0, 0) """ y = z = 0 if x: y = 42; z = 88 return y, z Cython-0.23.4/tests/run/numpy_test.pyx0000644000175600017570000006441112606202452021131 0ustar jenkinsjenkins00000000000000# tag: numpy # cannot be named "numpy" in order to not clash with the numpy module! cimport numpy as np cimport cython import sys from libc.stdlib cimport malloc def little_endian(): cdef int endian_detector = 1 return (&endian_detector)[0] != 0 __test__ = {} def testcase(f): __test__[f.__name__] = f.__doc__ return f def testcase_have_buffer_interface(f): major, minor, *rest = np.__version__.split('.') if (int(major), int(minor)) >= (1, 5) and sys.version_info[:2] >= (2, 6): __test__[f.__name__] = f.__doc__ return f if little_endian(): my_endian = '<' other_endian = '>' else: my_endian = '>' other_endian = '<' try: import numpy as np __doc__ = u""" >>> assert_dtype_sizes() >>> basic() [[0 1 2 3 4] [5 6 7 8 9]] 2 0 9 5 >>> three_dim() [[[ 0. 1. 2. 3.] [ 4. 5. 6. 7.]] <_BLANKLINE_> [[ 8. 9. 10. 11.] [ 12. 13. 14. 15.]] <_BLANKLINE_> [[ 16. 17. 18. 19.] [ 20. 21. 22. 23.]]] 6.0 0.0 13.0 8.0 >>> obj_array() [a 1 {}] a 1 {} Test various forms of slicing, picking etc. >>> a = np.arange(10, dtype='l').reshape(2, 5) >>> print_long_2d(a) 0 1 2 3 4 5 6 7 8 9 >>> print_long_2d(a[::-1, ::-1]) 9 8 7 6 5 4 3 2 1 0 >>> print_long_2d(a[1:2, 1:3]) 6 7 >>> print_long_2d(a[::2, ::2]) 0 2 4 >>> print_long_2d(a[::4, :]) 0 1 2 3 4 >>> print_long_2d(a[:, 1:5:2]) 1 3 6 8 >>> print_long_2d(a[:, 5:1:-2]) 4 2 9 7 >>> print_long_2d(a[:, [3, 1]]) 3 1 8 6 >>> print_long_2d(a.T) 0 5 1 6 2 7 3 8 4 9 Write to slices >>> b = a.copy() >>> put_range_long_1d(b[:, 3]) >>> print (b) [[0 1 2 0 4] [5 6 7 1 9]] >>> put_range_long_1d(b[::-1, 3]) >>> print (b) [[0 1 2 1 4] [5 6 7 0 9]] >>> a = np.zeros(9, dtype='l') >>> put_range_long_1d(a[1::3]) >>> print (a) [0 0 0 0 1 0 0 2 0] Write to picked subarrays. This should NOT change the original array as picking creates a new mutable copy. >>> a = np.zeros(10, dtype='l').reshape(2, 5) >>> put_range_long_1d(a[[0, 0, 1, 1, 0], [0, 1, 2, 4, 3]]) >>> print (a) [[0 0 0 0 0] [0 0 0 0 0]] Test contiguous access modes: >>> c_arr = np.array(np.arange(12, dtype='i').reshape(3,4), order='C') >>> f_arr = np.array(np.arange(12, dtype='i').reshape(3,4), order='F') >>> test_c_contig(c_arr) 0 1 2 3 4 5 6 7 8 9 10 11 >>> test_f_contig(f_arr) 0 1 2 3 4 5 6 7 8 9 10 11 >>> test_c_contig(f_arr) #doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: ndarray is not C...contiguous >>> test_f_contig(c_arr) #doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: ndarray is not Fortran contiguous >>> test_c_contig(c_arr[::2,::2]) #doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: ndarray is not C...contiguous >>> test_dtype('b', inc1_byte) >>> test_dtype('B', inc1_ubyte) >>> test_dtype('h', inc1_short) >>> test_dtype('H', inc1_ushort) >>> test_dtype('i', inc1_int) >>> test_dtype('I', inc1_uint) >>> test_dtype('l', inc1_long) >>> test_dtype('L', inc1_ulong) >>> test_dtype('f', inc1_float) >>> test_dtype('d', inc1_double) >>> test_dtype('g', inc1_longdouble) >>> test_dtype('O', inc1_object) >>> test_dtype('F', inc1_cfloat) # numpy format codes differ from buffer ones here >>> test_dtype('D', inc1_cdouble) >>> test_dtype('G', inc1_clongdouble) >>> test_dtype('F', inc1_cfloat_struct) >>> test_dtype('D', inc1_cdouble_struct) >>> test_dtype('G', inc1_clongdouble_struct) >>> test_dtype(np.int, inc1_int_t) >>> test_dtype(np.longlong, inc1_longlong_t) >>> test_dtype(np.float, inc1_float_t) >>> test_dtype(np.double, inc1_double_t) >>> test_dtype(np.intp, inc1_intp_t) >>> test_dtype(np.uintp, inc1_uintp_t) >>> test_dtype(np.longdouble, inc1_longdouble_t) >>> test_dtype(np.int32, inc1_int32_t) >>> test_dtype(np.float64, inc1_float64_t) Endian tests: >>> test_dtype('%si' % my_endian, inc1_int) >>> test_dtype('%si' % other_endian, inc1_int) #doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: ... >>> test_recordarray() >>> print(test_nested_dtypes(np.zeros((3,), dtype=np.dtype([\ ('a', np.dtype('i,i')),\ ('b', np.dtype('i,i'))\ ])))) array([((0, 0), (0, 0)), ((1, 2), (1, 4)), ((1, 2), (1, 4))], dtype=[('a', [('f0', '!i4'), ('f1', '!i4')]), ('b', [('f0', '!i4'), ('f1', '!i4')])]) >>> print(test_nested_dtypes(np.zeros((3,), dtype=np.dtype([\ ('a', np.dtype('i,f')),\ ('b', np.dtype('i,i'))\ ])))) Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'int' but got 'float' in 'DoubleInt.y' >>> print(test_packed_align(np.zeros((1,), dtype=np.dtype('b,i', align=False)))) [(22, 23)] The output changed in Python 3: >> print(test_unpacked_align(np.zeros((1,), dtype=np.dtype('b,i', align=True)))) array([(22, 23)], dtype=[('f0', '|i1'), ('', '|V3'), ('f1', '!i4')]) -> array([(22, 23)], dtype={'names':['f0','f1'], 'formats':['i1','!i4'], 'offsets':[0,4], 'itemsize':8, 'aligned':True}) >>> print(test_unpacked_align(np.zeros((1,), dtype=np.dtype('b,i', align=True)))) [(22, 23)] >>> print(test_packed_align(np.zeros((1,), dtype=np.dtype('b,i', align=True)))) #doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: ... >>> print(test_unpacked_align(np.zeros((1,), dtype=np.dtype('b,i', align=False)))) #doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: ... >>> test_good_cast() True >>> test_bad_cast() Traceback (most recent call last): ... ValueError: Item size of buffer (1 byte) does not match size of 'int' (4 bytes) >>> test_complextypes() 1,1 1,1 8,16 >>> test_point_record() array([(0.0, 0.0), (1.0, -1.0), (2.0, -2.0)], dtype=[('x', '!f8'), ('y', '!f8')]) """ if np.__version__ >= '1.6' and False: __doc__ += u""" Tests are DISABLED as the buffer format parser does not align members of aligned structs in padded structs in relation to the possibly unaligned initial offset. The following expose bugs in Numpy (versions prior to 2011-04-02): >>> print(test_partially_packed_align(np.zeros((1,), dtype=np.dtype([('a', 'b'), ('b', 'i'), ('sub', np.dtype('b,i')), ('c', 'i')], align=True)))) array([(22, 23, (24, 25), 26)], dtype=[('a', '|i1'), ('', '|V3'), ('b', '!i4'), ('sub', [('f0', '|i1'), ('f1', '!i4')]), ('', '|V3'), ('c', '!i4')]) >>> print(test_partially_packed_align_2(np.zeros((1,), dtype=np.dtype([('a', 'b'), ('b', 'i'), ('c', 'b'), ('sub', np.dtype('b,i', align=True))])))) array([(22, 23, 24, (27, 28))], dtype=[('a', '|i1'), ('b', '!i4'), ('c', '|i1'), ('sub', [('f0', '|i1'), ('', '|V3'), ('f1', '!i4')])]) >>> print(test_partially_packed_align(np.zeros((1,), dtype=np.dtype([('a', 'b'), ('b', 'i'), ('sub', np.dtype('b,i')), ('c', 'i')], align=False)))) #doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: ... >>> print(test_partially_packed_align_2(np.zeros((1,), dtype=np.dtype([('a', 'b'), ('b', 'i'), ('c', 'b'), ('sub', np.dtype('b,i', align=False))])))) #doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: ... """ except: __doc__ = u"" __test__[__name__] = __doc__ def assert_dtype_sizes(): assert sizeof(np.int8_t) == 1 assert sizeof(np.int16_t) == 2 assert sizeof(np.int32_t) == 4 assert sizeof(np.int64_t) == 8 assert sizeof(np.uint8_t) == 1 assert sizeof(np.uint16_t) == 2 assert sizeof(np.uint32_t) == 4 assert sizeof(np.uint64_t) == 8 assert sizeof(np.float32_t) == 4 assert sizeof(np.float64_t) == 8 assert sizeof(np.complex64_t) == 8 assert sizeof(np.complex128_t) == 16 def ndarray_str(arr): u""" Since Py2.3 doctest don't support , manually replace blank lines with <_BLANKLINE_> """ return unicode(arr).replace(u'\n\n', u'\n<_BLANKLINE_>\n') def basic(): cdef object[int, ndim=2] buf = np.arange(10, dtype='i').reshape((2, 5)) print buf print buf[0, 2], buf[0, 0], buf[1, 4], buf[1, 0] def three_dim(): cdef object[double, ndim=3] buf = np.arange(24, dtype='d').reshape((3,2,4)) print ndarray_str(buf) print buf[0, 1, 2], buf[0, 0, 0], buf[1, 1, 1], buf[1, 0, 0] def obj_array(): cdef object[object, ndim=1] buf = np.array(["a", 1, {}]) print str(buf).replace('"', '').replace("'", '') print buf[0], buf[1], buf[2] def print_long_2d(np.ndarray[long, ndim=2] arr): cdef int i, j for i in range(arr.shape[0]): print u" ".join([unicode(arr[i, j]) for j in range(arr.shape[1])]) def put_range_long_1d(np.ndarray[long] arr): u"""Writes 0,1,2,... to array and returns array""" cdef int value = 0, i for i in range(arr.shape[0]): arr[i] = value value += 1 def test_c_contig(np.ndarray[int, ndim=2, mode='c'] arr): cdef int i, j for i in range(arr.shape[0]): print u" ".join([unicode(arr[i, j]) for j in range(arr.shape[1])]) def test_f_contig(np.ndarray[int, ndim=2, mode='fortran'] arr): cdef int i, j for i in range(arr.shape[0]): print u" ".join([unicode(arr[i, j]) for j in range(arr.shape[1])]) # Exhaustive dtype tests -- increments element [1] by 1 (or 1+1j) for all dtypes def inc1_byte(np.ndarray[char] arr): arr[1] += 1 def inc1_ubyte(np.ndarray[unsigned char] arr): arr[1] += 1 def inc1_short(np.ndarray[short] arr): arr[1] += 1 def inc1_ushort(np.ndarray[unsigned short] arr): arr[1] += 1 def inc1_int(np.ndarray[int] arr): arr[1] += 1 def inc1_uint(np.ndarray[unsigned int] arr): arr[1] += 1 def inc1_long(np.ndarray[long] arr): arr[1] += 1 def inc1_ulong(np.ndarray[unsigned long] arr): arr[1] += 1 def inc1_longlong(np.ndarray[long long] arr): arr[1] += 1 def inc1_ulonglong(np.ndarray[unsigned long long] arr): arr[1] += 1 def inc1_float(np.ndarray[float] arr): arr[1] += 1 def inc1_double(np.ndarray[double] arr): arr[1] += 1 def inc1_longdouble(np.ndarray[long double] arr): arr[1] += 1 def inc1_cfloat(np.ndarray[float complex] arr): arr[1] = arr[1] + 1 + 1j def inc1_cdouble(np.ndarray[double complex] arr): arr[1] = (arr[1] + 1) + 1j def inc1_clongdouble(np.ndarray[long double complex] arr): arr[1] = arr[1] + (1 + 1j) def inc1_cfloat_struct(np.ndarray[np.cfloat_t] arr): arr[1].real += 1 arr[1].imag += 1 def inc1_cdouble_struct(np.ndarray[np.cdouble_t] arr): arr[1].real += 1 arr[1].imag += 1 def inc1_clongdouble_struct(np.ndarray[np.clongdouble_t] arr): cdef long double x x = arr[1].real + 1 arr[1].real = x arr[1].imag = arr[1].imag + 1 def inc1_object(np.ndarray[object] arr): o = arr[1] o += 1 arr[1] = o # unfortunately, += segfaults for objects def inc1_int_t(np.ndarray[np.int_t] arr): arr[1] += 1 def inc1_long_t(np.ndarray[np.long_t] arr): arr[1] += 1 def inc1_longlong_t(np.ndarray[np.longlong_t] arr): arr[1] += 1 def inc1_float_t(np.ndarray[np.float_t] arr): arr[1] += 1 def inc1_double_t(np.ndarray[np.double_t] arr): arr[1] += 1 def inc1_longdouble_t(np.ndarray[np.longdouble_t] arr): arr[1] += 1 def inc1_intp_t(np.ndarray[np.intp_t] arr): arr[1] += 1 def inc1_uintp_t(np.ndarray[np.uintp_t] arr): arr[1] += 1 # The tests below only work on platforms that has the given types def inc1_int32_t(np.ndarray[np.int32_t] arr): arr[1] += 1 def inc1_float64_t(np.ndarray[np.float64_t] arr): arr[1] += 1 def test_dtype(dtype, inc1): if dtype in ("g", np.longdouble, "G", np.clongdouble): if sizeof(double) == sizeof(long double): # MSVC return if dtype in ('F', 'D', 'G'): a = np.array([0, 10+10j], dtype=dtype) inc1(a) if a[1] != (11 + 11j): print u"failed!", a[1] else: a = np.array([0, 10], dtype=dtype) inc1(a) if a[1] != 11: print u"failed!" cdef struct DoubleInt: int x, y def test_recordarray(): cdef object[DoubleInt] arr arr = np.array([(5,5), (4, 6)], dtype=np.dtype('i,i')) cdef DoubleInt rec rec = arr[0] if rec.x != 5: print u"failed" if rec.y != 5: print u"failed" rec.y += 5 arr[1] = rec arr[0].x -= 2 arr[0].y += 3 if arr[0].x != 3: print u"failed" if arr[0].y != 8: print u"failed" if arr[1].x != 5: print u"failed" if arr[1].y != 10: print u"failed" cdef struct NestedStruct: DoubleInt a DoubleInt b cdef struct BadDoubleInt: float x int y cdef struct BadNestedStruct: DoubleInt a BadDoubleInt b def test_nested_dtypes(obj): cdef object[NestedStruct] arr = obj arr[1].a.x = 1 arr[1].a.y = 2 arr[1].b.x = arr[0].a.y + 1 arr[1].b.y = 4 arr[2] = arr[1] return repr(arr).replace('<', '!').replace('>', '!') def test_bad_nested_dtypes(): cdef object[BadNestedStruct] arr def test_good_cast(): # Check that a signed int can round-trip through casted unsigned int access cdef np.ndarray[unsigned int, cast=True] arr = np.array([-100], dtype='i') cdef unsigned int data = arr[0] return -100 == data def test_bad_cast(): # This should raise an exception cdef np.ndarray[int, cast=True] arr = np.array([1], dtype='b') cdef packed struct PackedStruct: char a int b cdef struct UnpackedStruct: char a int b cdef struct PartiallyPackedStruct: char a int b PackedStruct sub int c cdef packed struct PartiallyPackedStruct2: char a int b char c UnpackedStruct sub def test_packed_align(np.ndarray[PackedStruct] arr): arr[0].a = 22 arr[0].b = 23 return list(arr) def test_unpacked_align(np.ndarray[UnpackedStruct] arr): arr[0].a = 22 arr[0].b = 23 # return repr(arr).replace('<', '!').replace('>', '!') return list(arr) def test_partially_packed_align(np.ndarray[PartiallyPackedStruct] arr): arr[0].a = 22 arr[0].b = 23 arr[0].sub.a = 24 arr[0].sub.b = 25 arr[0].c = 26 return repr(arr).replace('<', '!').replace('>', '!') def test_partially_packed_align_2(np.ndarray[PartiallyPackedStruct2] arr): arr[0].a = 22 arr[0].b = 23 arr[0].c = 24 arr[0].sub.a = 27 arr[0].sub.b = 28 return repr(arr).replace('<', '!').replace('>', '!') def test_complextypes(): cdef np.complex64_t x64 = 1, y64 = 1j cdef np.complex128_t x128 = 1, y128 = 1j x64 = x64 + y64 print "%.0f,%.0f" % (x64.real, x64.imag) x128 = x128 + y128 print "%.0f,%.0f" % (x128.real, x128.imag) print "%d,%d" % (sizeof(x64), sizeof(x128)) cdef struct Point: np.float64_t x, y def test_point_record(): cdef np.ndarray[Point] test Point_dtype = np.dtype([('x', np.float64), ('y', np.float64)]) test = np.zeros(3, Point_dtype) cdef int i for i in range(3): test[i].x = i test[i].y = -i print repr(test).replace('<', '!').replace('>', '!') # Test fused np.ndarray dtypes and runtime dispatch @testcase def test_fused_ndarray_floating_dtype(np.ndarray[cython.floating, ndim=1] a): """ >>> import cython >>> sorted(test_fused_ndarray_floating_dtype.__signatures__) ['double', 'float'] >>> test_fused_ndarray_floating_dtype[cython.double](np.arange(10, dtype=np.float64)) ndarray[double,ndim=1] ndarray[double,ndim=1] 5.0 6.0 >>> test_fused_ndarray_floating_dtype(np.arange(10, dtype=np.float64)) ndarray[double,ndim=1] ndarray[double,ndim=1] 5.0 6.0 >>> test_fused_ndarray_floating_dtype[cython.float](np.arange(10, dtype=np.float32)) ndarray[float,ndim=1] ndarray[float,ndim=1] 5.0 6.0 >>> test_fused_ndarray_floating_dtype(np.arange(10, dtype=np.float32)) ndarray[float,ndim=1] ndarray[float,ndim=1] 5.0 6.0 """ cdef np.ndarray[cython.floating, ndim=1] b = a print cython.typeof(a), cython.typeof(b), a[5], b[6] double_array = np.linspace(0, 1, 100) int32_array = np.arange(100, dtype=np.int32) cdef fused fused_external: np.int32_t np.int64_t np.float32_t np.float64_t @testcase def test_fused_external(np.ndarray[fused_external, ndim=1] a): """ >>> import cython >>> sorted(test_fused_external.__signatures__) ['float32_t', 'float64_t', 'int32_t', 'int64_t'] >>> test_fused_external["float64_t"](double_array) float64 >>> test_fused_external["int32_t"](int32_array) int32 >>> test_fused_external(np.arange(100, dtype=np.int64)) int64 """ print a.dtype cdef fused fused_buffers: np.ndarray[np.int32_t, ndim=1] np.int64_t[::1] @testcase def test_fused_buffers(fused_buffers arg): """ >>> sorted(test_fused_buffers.__signatures__) ['int64_t[::1]', 'ndarray[int32_t,ndim=1]'] """ cpdef _fused_cpdef_buffers(np.ndarray[fused_external] a): print a.dtype @testcase def test_fused_cpdef_buffers(): """ >>> test_fused_cpdef_buffers() int32 int32 """ _fused_cpdef_buffers[np.int32_t](int32_array) cdef np.ndarray[np.int32_t] typed_array = int32_array _fused_cpdef_buffers(typed_array) @testcase def test_fused_ndarray_integral_dtype(np.ndarray[cython.integral, ndim=1] a): """ >>> import cython >>> sorted(test_fused_ndarray_integral_dtype.__signatures__) ['int', 'long', 'short'] >>> test_fused_ndarray_integral_dtype[cython.int](np.arange(10, dtype=np.dtype('i'))) 5 6 >>> test_fused_ndarray_integral_dtype(np.arange(10, dtype=np.dtype('i'))) 5 6 >>> test_fused_ndarray_integral_dtype[cython.long](np.arange(10, dtype='l')) 5 6 >>> test_fused_ndarray_integral_dtype(np.arange(10, dtype='l')) 5 6 """ cdef np.ndarray[cython.integral, ndim=1] b = a # Don't print the types, the platform specific sizes can make the dispatcher # select different integer types with equal sizeof() print a[5], b[6] cdef fused fused_dtype: float complex double complex object @testcase def test_fused_ndarray_other_dtypes(np.ndarray[fused_dtype, ndim=1] a): """ >>> import cython >>> sorted(test_fused_ndarray_other_dtypes.__signatures__) ['double complex', 'float complex', 'object'] >>> test_fused_ndarray_other_dtypes(np.arange(10, dtype=np.complex64)) ndarray[float complex,ndim=1] ndarray[float complex,ndim=1] (5+0j) (6+0j) >>> test_fused_ndarray_other_dtypes(np.arange(10, dtype=np.complex128)) ndarray[double complex,ndim=1] ndarray[double complex,ndim=1] (5+0j) (6+0j) >>> test_fused_ndarray_other_dtypes(np.arange(10, dtype=np.object)) ndarray[Python object,ndim=1] ndarray[Python object,ndim=1] 5 6 """ cdef np.ndarray[fused_dtype, ndim=1] b = a print cython.typeof(a), cython.typeof(b), a[5], b[6] # Test fusing the array types together and runtime dispatch cdef struct Foo: int a float b cdef fused fused_FooArray: np.ndarray[Foo, ndim=1] cdef fused fused_ndarray: np.ndarray[float, ndim=1] np.ndarray[double, ndim=1] np.ndarray[Foo, ndim=1] def get_Foo_array(): cdef Foo[:] result = malloc(sizeof(Foo) * 10) result[5].b = 9.0 return np.asarray(result) @testcase_have_buffer_interface def test_fused_ndarray(fused_ndarray a): """ >>> import cython >>> sorted(test_fused_ndarray.__signatures__) ['ndarray[Foo,ndim=1]', 'ndarray[double,ndim=1]', 'ndarray[float,ndim=1]'] >>> test_fused_ndarray(get_Foo_array()) ndarray[Foo,ndim=1] ndarray[Foo,ndim=1] 9.0 >>> test_fused_ndarray(np.arange(10, dtype=np.float64)) ndarray[double,ndim=1] ndarray[double,ndim=1] 5.0 >>> test_fused_ndarray(np.arange(10, dtype=np.float32)) ndarray[float,ndim=1] ndarray[float,ndim=1] 5.0 """ cdef fused_ndarray b = a print cython.typeof(a), cython.typeof(b) if fused_ndarray in fused_FooArray: print b[5].b else: print b[5] cpdef test_fused_cpdef_ndarray(fused_ndarray a): """ >>> import cython >>> sorted(test_fused_cpdef_ndarray.__signatures__) ['ndarray[Foo,ndim=1]', 'ndarray[double,ndim=1]', 'ndarray[float,ndim=1]'] >>> test_fused_cpdef_ndarray(get_Foo_array()) ndarray[Foo,ndim=1] ndarray[Foo,ndim=1] 9.0 >>> test_fused_cpdef_ndarray(np.arange(10, dtype=np.float64)) ndarray[double,ndim=1] ndarray[double,ndim=1] 5.0 >>> test_fused_cpdef_ndarray(np.arange(10, dtype=np.float32)) ndarray[float,ndim=1] ndarray[float,ndim=1] 5.0 """ cdef fused_ndarray b = a print cython.typeof(a), cython.typeof(b) if fused_ndarray in fused_FooArray: print b[5].b else: print b[5] testcase_have_buffer_interface(test_fused_cpdef_ndarray) @testcase_have_buffer_interface def test_fused_cpdef_ndarray_cdef_call(): """ >>> test_fused_cpdef_ndarray_cdef_call() ndarray[Foo,ndim=1] ndarray[Foo,ndim=1] 9.0 """ cdef np.ndarray[Foo, ndim=1] foo_array = get_Foo_array() test_fused_cpdef_ndarray(foo_array) cdef fused int_type: np.int32_t np.int64_t float64_array = np.arange(10, dtype=np.float64) float32_array = np.arange(10, dtype=np.float32) int32_array = np.arange(10, dtype=np.int32) int64_array = np.arange(10, dtype=np.int64) @testcase def test_dispatch_non_clashing_declarations_repeating_types(np.ndarray[cython.floating] a1, np.ndarray[int_type] a2, np.ndarray[cython.floating] a3, np.ndarray[int_type] a4): """ >>> test_dispatch_non_clashing_declarations_repeating_types(float64_array, int32_array, float64_array, int32_array) 1.0 2 3.0 4 >>> test_dispatch_non_clashing_declarations_repeating_types(float64_array, int64_array, float64_array, int64_array) 1.0 2 3.0 4 >>> test_dispatch_non_clashing_declarations_repeating_types(float64_array, int32_array, float64_array, int64_array) # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: Buffer dtype mismatch, expected 'int32_t'... >>> test_dispatch_non_clashing_declarations_repeating_types(float64_array, int64_array, float64_array, int32_array) # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: Buffer dtype mismatch, expected 'int64_t'... """ print a1[1], a2[2], a3[3], a4[4] ctypedef np.int32_t typedeffed_type cdef fused typedeffed_fused_type: typedeffed_type int long @testcase def test_dispatch_typedef(np.ndarray[typedeffed_fused_type] a): """ >>> test_dispatch_typedef(int32_array) 5 """ print a[5] cdef extern from "types.h": ctypedef char actually_long_t cdef fused confusing_fused_typedef: actually_long_t int unsigned long double complex unsigned char signed char def test_dispatch_external_typedef(np.ndarray[confusing_fused_typedef] a): """ >>> test_dispatch_external_typedef(np.arange(-5, 5, dtype=np.long)) -2 """ print a[3] # test fused memoryview slices cdef fused memslice_fused_dtype: float double int long float complex double complex object @testcase def test_fused_memslice_other_dtypes(memslice_fused_dtype[:] a): """ >>> import cython >>> sorted(test_fused_memslice_other_dtypes.__signatures__) ['double', 'double complex', 'float', 'float complex', 'int', 'long', 'object'] >>> test_fused_memslice_other_dtypes(np.arange(10, dtype=np.complex64)) float complex[:] float complex[:] (5+0j) (6+0j) >>> test_fused_memslice_other_dtypes(np.arange(10, dtype=np.complex128)) double complex[:] double complex[:] (5+0j) (6+0j) >>> test_fused_memslice_other_dtypes(np.arange(10, dtype=np.float32)) float[:] float[:] 5.0 6.0 >>> test_fused_memslice_other_dtypes(np.arange(10, dtype=np.dtype('i'))) int[:] int[:] 5 6 >>> test_fused_memslice_other_dtypes(np.arange(10, dtype=np.object)) object[:] object[:] 5 6 """ cdef memslice_fused_dtype[:] b = a print cython.typeof(a), cython.typeof(b), a[5], b[6] cdef fused memslice_fused: float[:] double[:] int[:] long[:] float complex[:] double complex[:] object[:] @testcase def test_fused_memslice(memslice_fused a): """ >>> import cython >>> sorted(test_fused_memslice.__signatures__) ['double complex[:]', 'double[:]', 'float complex[:]', 'float[:]', 'int[:]', 'long[:]', 'object[:]'] >>> test_fused_memslice(np.arange(10, dtype=np.complex64)) float complex[:] float complex[:] (5+0j) (6+0j) >>> test_fused_memslice(np.arange(10, dtype=np.complex128)) double complex[:] double complex[:] (5+0j) (6+0j) >>> test_fused_memslice(np.arange(10, dtype=np.float32)) float[:] float[:] 5.0 6.0 >>> test_fused_memslice(np.arange(10, dtype=np.dtype('i'))) int[:] int[:] 5 6 >>> test_fused_memslice(np.arange(10, dtype=np.object)) object[:] object[:] 5 6 """ cdef memslice_fused b = a print cython.typeof(a), cython.typeof(b), a[5], b[6] @testcase def test_dispatch_memoryview_object(): """ >>> test_dispatch_memoryview_object() int[:] int[:] 5 6 """ cdef int[:] m = np.arange(10, dtype=np.dtype('i')) cdef int[:] m2 = m cdef int[:] m3 = m test_fused_memslice(m3) cdef fused ndim_t: double[:] double[:, :] double[:, :, :] @testcase def test_dispatch_ndim(ndim_t array): """ >>> test_dispatch_ndim(np.empty(5, dtype=np.double)) double[:] 1 >>> test_dispatch_ndim(np.empty((5, 5), dtype=np.double)) double[:, :] 2 >>> test_dispatch_ndim(np.empty((5, 5, 5), dtype=np.double)) double[:, :, :] 3 Test indexing using Cython.Shadow >>> import cython >>> test_dispatch_ndim[cython.double[:]](np.empty(5, dtype=np.double)) double[:] 1 >>> test_dispatch_ndim[cython.double[:, :]](np.empty((5, 5), dtype=np.double)) double[:, :] 2 """ print cython.typeof(array), np.asarray(array).ndim include "numpy_common.pxi" Cython-0.23.4/tests/run/numpy_parallel.pyx0000644000175600017570000000116012606202452021736 0ustar jenkinsjenkins00000000000000# tag: numpy # tag: openmp cimport cython from cython.parallel import prange cimport numpy as np include "numpy_common.pxi" @cython.boundscheck(False) def test_parallel_numpy_arrays(): """ >>> test_parallel_numpy_arrays() -5 -4 -3 -2 -1 0 1 2 3 4 """ cdef Py_ssize_t i cdef np.ndarray[np.int_t] x try: import numpy except ImportError: for i in range(-5, 5): print i return x = numpy.zeros(10, dtype=numpy.int) for i in prange(x.shape[0], nogil=True): x[i] = i - 5 for i in x: print i Cython-0.23.4/tests/run/numpy_math.pyx0000644000175600017570000000225412606202452021100 0ustar jenkinsjenkins00000000000000# tag: numpy # tag: no-cpp # Numpy <= 1.7.1 doesn't have a C++ guard in the header file. cimport numpy.math as npmath def test_fp_classif(): """ >>> test_fp_classif() """ cdef double d_zero cdef float f_zero d_zero = -1 * 0. f_zero = -1 * 0. assert d_zero == npmath.NZERO assert f_zero == npmath.NZERO assert npmath.signbit(d_zero) assert npmath.signbit(f_zero) d_zero = 1 * 0. f_zero = 1 * 0. assert d_zero == npmath.PZERO assert f_zero == npmath.PZERO assert not npmath.signbit(d_zero) assert not npmath.signbit(f_zero) assert not npmath.isinf(d_zero) assert not npmath.isinf(f_zero) assert not npmath.isnan(d_zero) assert not npmath.isnan(f_zero) assert npmath.isinf(npmath.INFINITY) == 1 assert npmath.isinf(-npmath.INFINITY) == -1 assert npmath.isnan(npmath.NAN) assert npmath.signbit(npmath.copysign(1., -1.)) def test_nextafter(): """ >>> test_nextafter() """ x = npmath.nextafter(npmath.EULER, 1) assert npmath.isfinite(x) assert x > npmath.EULER x = npmath.nextafter(npmath.PI_4, -1) assert npmath.isfinite(x) assert x < npmath.PI_4 Cython-0.23.4/tests/run/numpy_common.pxi0000644000175600017570000000033512606202452021415 0ustar jenkinsjenkins00000000000000# hack to avoid C compiler warnings about unused functions in the NumPy header files cdef extern from *: bint FALSE "0" void import_array() # void import_umath() if FALSE: import_array() # import_umath() Cython-0.23.4/tests/run/numpy_cimport.pyx0000644000175600017570000000016412606202452021622 0ustar jenkinsjenkins00000000000000# tag: numpy """ >>> import sys >>> 'numpy' in sys.modules True """ cimport numpy as np include "numpy_common.pxi" Cython-0.23.4/tests/run/numpy_bufacc_T155.pyx0000644000175600017570000000045312606202452022107 0ustar jenkinsjenkins00000000000000# ticket: 155 # tag: numpy """ >>> myfunc() 0.5 """ cimport numpy as np import numpy as np def myfunc(): cdef np.ndarray[float, ndim=2] A = np.ones((1,1), dtype=np.float32) cdef int i for i from 0 <= i < A.shape[0]: A[i, :] /= 2 return A[0,0] include "numpy_common.pxi" Cython-0.23.4/tests/run/numpy_ValueError_T172.pyx0000644000175600017570000000015412606202452022747 0ustar jenkinsjenkins00000000000000# ticket: 172 # tag: numpy __doc__ = u""" >>> 1 1 """ cimport numpy class ValueError(object): pass Cython-0.23.4/tests/run/notinop.pyx0000644000175600017570000001625412606202452020412 0ustar jenkinsjenkins00000000000000 cimport cython def f(a,b): """ >>> f(1,[1,2,3]) False >>> f(5,[1,2,3]) True >>> f(2,(1,2,3)) False """ result = a not in b return result def g(a,b): """ >>> g(1,[1,2,3]) 0 >>> g(5,[1,2,3]) 1 >>> g(2,(1,2,3)) 0 """ cdef int result result = a not in b return result def h(b): """ >>> h([1,2,3,4]) False >>> h([1,3,4]) True """ result = 2 not in b return result def j(b): """ >>> j([1,2,3,4]) 0 >>> j([1,3,4]) 1 """ cdef int result result = 2 not in b return result @cython.test_fail_if_path_exists("//SwitchStatNode") def k(a): """ >>> k(1) 0 >>> k(5) 1 """ cdef int result = a not in [1,2,3,4] return result @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//PrimaryCmpNode") def m_list(int a): """ >>> m_list(2) 0 >>> m_list(5) 1 """ cdef int result = a not in [1,2,3,4] return result @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//PrimaryCmpNode") def m_tuple(int a): """ >>> m_tuple(2) 0 >>> m_tuple(5) 1 """ cdef int result = a not in (1,2,3,4) return result @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//BoolBinopNode", "//PrimaryCmpNode") def m_set(int a): """ >>> m_set(2) 0 >>> m_set(5) 1 """ cdef int result = a not in {1,2,3,4} return result cdef bytes bytes_string = b'abcdefg' @cython.test_assert_path_exists("//PrimaryCmpNode") @cython.test_fail_if_path_exists("//SwitchStatNode", "//BoolBinopNode", "//BoolBinopNode") def m_bytes(char a): """ >>> m_bytes(ord('f')) 0 >>> m_bytes(ord('X')) 1 """ cdef int result = a not in bytes_string return result @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//BoolBinopNode", "//PrimaryCmpNode") def m_bytes_literal(char a): """ >>> m_bytes_literal(ord('f')) 0 >>> m_bytes_literal(ord('X')) 1 """ cdef int result = a not in b'abcdefg' return result cdef unicode unicode_string = u'abcdefg\u1234\uF8D2' py_unicode_string = unicode_string cdef unicode klingon_character = u'\uF8D2' py_klingon_character = klingon_character @cython.test_assert_path_exists("//PrimaryCmpNode") @cython.test_fail_if_path_exists("//SwitchStatNode", "//BoolBinopNode", "//BoolBinopNode") def m_unicode(Py_UNICODE a, unicode unicode_string): """ >>> m_unicode(ord('f'), py_unicode_string) 0 >>> m_unicode(ord('X'), py_unicode_string) 1 >>> m_unicode(ord(py_klingon_character), py_unicode_string) 0 >>> 'f' in None # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...iterable... >>> m_unicode(ord('f'), None) Traceback (most recent call last): TypeError: argument of type 'NoneType' is not iterable """ cdef int result = a not in unicode_string return result @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//BoolBinopNode", "//PrimaryCmpNode") def m_unicode_literal(Py_UNICODE a): """ >>> m_unicode_literal(ord('f')) 0 >>> m_unicode_literal(ord('X')) 1 >>> m_unicode_literal(ord(py_klingon_character)) 0 """ cdef int result = a not in u'abcdefg\u1234\uF8D2' return result @cython.test_assert_path_exists("//SwitchStatNode", "//BoolBinopNode") @cython.test_fail_if_path_exists("//PrimaryCmpNode") def m_tuple_in_or_notin(int a): """ >>> m_tuple_in_or_notin(2) 0 >>> m_tuple_in_or_notin(3) 1 >>> m_tuple_in_or_notin(5) 1 """ cdef int result = a not in (1,2,3,4) or a in (3,4) return result @cython.test_assert_path_exists("//SwitchStatNode", "//BoolBinopNode") @cython.test_fail_if_path_exists("//PrimaryCmpNode") def m_tuple_notin_or_notin(int a): """ >>> m_tuple_notin_or_notin(2) 1 >>> m_tuple_notin_or_notin(6) 1 >>> m_tuple_notin_or_notin(4) 0 """ cdef int result = a not in (1,2,3,4) or a not in (4,5) return result @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//BoolBinopNode", "//PrimaryCmpNode") def m_tuple_notin_and_notin(int a): """ >>> m_tuple_notin_and_notin(2) 0 >>> m_tuple_notin_and_notin(6) 0 >>> m_tuple_notin_and_notin(5) 1 """ cdef int result = a not in (1,2,3,4) and a not in (6,7) return result @cython.test_assert_path_exists("//SwitchStatNode", "//BoolBinopNode") @cython.test_fail_if_path_exists("//PrimaryCmpNode") def m_tuple_notin_and_notin_overlap(int a): """ >>> m_tuple_notin_and_notin_overlap(2) 0 >>> m_tuple_notin_and_notin_overlap(4) 0 >>> m_tuple_notin_and_notin_overlap(5) 1 """ cdef int result = a not in (1,2,3,4) and a not in (3,4) return result @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//BoolBinopNode", "//PrimaryCmpNode") def conditional_int(int a): """ >>> conditional_int(1) 2 >>> conditional_int(0) 1 >>> conditional_int(5) 1 """ return 1 if a not in (1,2,3,4) else 2 @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//BoolBinopNode", "//PrimaryCmpNode") def conditional_object(int a): """ >>> conditional_object(1) '2' >>> conditional_object(0) 1 >>> conditional_object(5) 1 """ return 1 if a not in (1,2,3,4) else '2' @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//BoolBinopNode", "//PrimaryCmpNode") def conditional_bytes(char a): """ >>> conditional_bytes(ord('a')) '2' >>> conditional_bytes(ord('X')) 1 >>> conditional_bytes(0) 1 """ return 1 if a not in b'abc' else '2' @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//BoolBinopNode", "//PrimaryCmpNode") def conditional_unicode(Py_UNICODE a): """ >>> conditional_unicode(ord('a')) '2' >>> conditional_unicode(ord('X')) 1 >>> conditional_unicode(0) 1 """ return 1 if a not in u'abc' else '2' @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//BoolBinopNode", "//PrimaryCmpNode") def conditional_none(int a): """ >>> conditional_none(1) 1 >>> conditional_none(0) >>> conditional_none(5) """ return None if a not in {1,2,3,4} else 1 def n(a): """ >>> n('d *') 0 >>> n('xxx') 1 """ cdef int result = a.lower() not in [u'a *',u'b *',u'c *',u'd *'] return result def p(a): """ >>> p('a') 0 >>> p(1) 1 """ cdef dict d = {u'a': 1, u'b': 2} cdef int result = a not in d return result def q(a): """ >>> q(1) Traceback (most recent call last): TypeError: 'NoneType' object is not iterable """ cdef dict d = None cdef int result = a not in d # should fail with a TypeError return result Cython-0.23.4/tests/run/nononetypecheck.pyx0000644000175600017570000000014612606202452022111 0ustar jenkinsjenkins00000000000000cdef class Spam: pass cdef f(Spam s): pass def g(): """ >>> g() """ f(None) Cython-0.23.4/tests/run/nonlocal_T490.pyx0000644000175600017570000000442312606202452021244 0ustar jenkinsjenkins00000000000000def simple(): """ >>> simple() 1 2 """ x = 1 y = 2 def f(): nonlocal x nonlocal x, y print(x) print(y) f() def assign(): """ >>> assign() 1 """ xx = 0 def ff(): nonlocal xx xx += 1 print(xx) ff() def nested(): """ >>> nested() 1 """ x = 0 def fx(): def gx(): nonlocal x x=1 print(x) return gx fx()() def arg(x): """ >>> arg('x') xyy """ def appendy(): nonlocal x x += 'y' x+='y' appendy() print x return def argtype(int n): """ >>> argtype(0) 1 """ def inc(): nonlocal n n += 1 inc() print n return def ping_pong(): """ >>> f = ping_pong() >>> inc, dec = f(0) >>> inc() 1 >>> inc() 2 >>> dec() 1 >>> inc() 2 >>> dec() 1 >>> dec() 0 """ def f(x): def inc(): nonlocal x x += 1 return x def dec(): nonlocal x x -= 1 return x return inc, dec return f def methods(): """ >>> f = methods() >>> c = f(0) >>> c.inc() 1 >>> c.inc() 2 >>> c.dec() 1 >>> c.dec() 0 """ def f(x): class c: def inc(self): nonlocal x x += 1 return x def dec(self): nonlocal x x -= 1 return x return c() return f def class_body(int x, y): """ >>> c = class_body(2,99) >>> c.z (3, 2) >>> c.x #doctest: +ELLIPSIS Traceback (most recent call last): AttributeError: ... >>> c.y #doctest: +ELLIPSIS Traceback (most recent call last): AttributeError: ... """ class c(object): nonlocal x nonlocal y y = 2 x += 1 z = x,y return c() def nested_nonlocals(x): """ >>> g = nested_nonlocals(1) >>> h = g() >>> h() 3 """ def g(): nonlocal x x -= 2 def h(): nonlocal x x += 4 return x return h return g Cython-0.23.4/tests/run/nonecheck.pyx0000644000175600017570000001075512606202452020661 0ustar jenkinsjenkins00000000000000__doc__ = u""" Tests accessing attributes of extension type variables set to None """ cimport cython cdef class MyClass: cdef int a, b def __init__(self, a, b): self.a = a self.b = b @cython.nonecheck(True) def getattr_(MyClass var): """ >>> obj = MyClass(2, 3) >>> getattr_(obj) 2 >>> getattr_(None) Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'a' >>> setattr_(obj) >>> getattr_(obj) 10 """ print var.a @cython.nonecheck(True) def setattr_(MyClass var): """ >>> obj = MyClass(2, 3) >>> setattr_(obj) >>> setattr_(None) Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'a' """ var.a = 10 @cython.nonecheck(True) def getattr_nogil(MyClass var): """ >>> getattr_nogil(None) Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'a' """ with nogil: var.a @cython.nonecheck(True) def setattr_nogil(MyClass var): """ >>> setattr_nogil(None) Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'a' """ with nogil: var.a = 1 def some(): return MyClass(4, 5) @cython.nonecheck(True) def checking(MyClass var): """ >>> obj = MyClass(2, 3) >>> checking(obj) 2 2 >>> checking(None) var is None """ state = (var is None) if not state: print var.a if var is not None: print var.a else: print u"var is None" @cython.nonecheck(True) def check_and_assign(MyClass var): """ >>> obj = MyClass(2, 3) >>> check_and_assign(obj) Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'a' """ if var is not None: print var.a var = None print var.a @cython.nonecheck(True) def check_buffer_get(object[int] buf): """ >>> check_buffer_get(None) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable """ return buf[0] @cython.nonecheck(True) def check_buffer_set(object[int] buf): """ >>> check_buffer_set(None) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable """ buf[0] = 1 @cython.nonecheck(True) def test_memslice_get(double[:] buf): """ >>> test_memslice_get(None) Traceback (most recent call last): TypeError: Cannot index None memoryview slice """ return buf[0] @cython.nonecheck(True) def test_memslice_set(double[:] buf): """ >>> test_memslice_set(None) Traceback (most recent call last): TypeError: Cannot index None memoryview slice """ buf[0] = 1.0 @cython.nonecheck(True) def test_memslice_copy(double[:] buf): """ >>> test_memslice_copy(None) Traceback (most recent call last): AttributeError: Cannot access 'copy' attribute of None memoryview slice """ cdef double[:] copy = buf.copy() @cython.nonecheck(True) def test_memslice_transpose(double[:] buf): """ >>> test_memslice_transpose(None) Traceback (most recent call last): AttributeError: Cannot transpose None memoryview slice """ cdef double[:] T = buf.T @cython.nonecheck(True) def test_memslice_shape(double[:] buf): """ >>> test_memslice_shape(None) Traceback (most recent call last): AttributeError: Cannot access 'shape' attribute of None memoryview slice """ cdef Py_ssize_t extent = buf.shape[0] @cython.nonecheck(True) def test_memslice_slice(double[:] buf): """ >>> test_memslice_slice(None) Traceback (most recent call last): TypeError: Cannot slice None memoryview slice """ cdef double[:] sliced = buf[1:] @cython.nonecheck(True) def test_memslice_slice2(double[:] buf): """ Should this raise an error? It may not slice at all. >>> test_memslice_slice(None) Traceback (most recent call last): TypeError: Cannot slice None memoryview slice """ cdef double[:] sliced = buf[:] @cython.nonecheck(True) def test_memslice_slice_assign(double[:] buf): """ >>> test_memslice_slice_assign(None) Traceback (most recent call last): TypeError: Cannot assign to None memoryview slice """ buf[...] = 2 @cython.nonecheck(True) def test_memslice_slice_assign2(double[:] buf): """ >>> test_memslice_slice_assign2(None) Traceback (most recent call last): TypeError: Cannot slice None memoryview slice """ buf[:] = buf[::-1] Cython-0.23.4/tests/run/non_future_division.pyx0000644000175600017570000000611612606202452023010 0ustar jenkinsjenkins00000000000000# Py2.x mixed true-div/floor-div behaviour of '/' operator def bigints(values): for x in values: print(repr(x).rstrip('L')) def doit(x,y): """ >>> doit(1,2) (0, 0) >>> doit(4,3) (1, 1) >>> doit(4,3.0) (1.3333333333333333, 1.0) >>> doit(4,2) (2, 2) """ return x/y, x//y def doit_inplace(x,y): """ >>> doit_inplace(1,2) 0 """ x /= y return x def doit_inplace_floor(x,y): """ >>> doit_inplace_floor(1,2) 0 """ x //= y return x def constants(): """ >>> constants() (0, 0, 2.5, 2.0, 2, 2) """ return 1/2, 1//2, 5/2.0, 5//2.0, 5/2, 5//2 def py_mix(a): """ >>> py_mix(1) (0, 0, 0.5, 0.0, 0, 0) >>> py_mix(1.0) (0.5, 0.0, 0.5, 0.0, 0.5, 0.0) >>> 2**53 / 2.0 4503599627370496.0 >>> bigints(py_mix(2**53)) 4503599627370496 4503599627370496 4503599627370496.0 4503599627370496.0 4503599627370496 4503599627370496 >>> bigints(py_mix(2**53 + 1)) 4503599627370496 4503599627370496 4503599627370496.0 4503599627370496.0 4503599627370496 4503599627370496 >>> py_mix(2**53 + 1.0) (4503599627370496.0, 4503599627370496.0, 4503599627370496.0, 4503599627370496.0, 4503599627370496.0, 4503599627370496.0) """ return a/2, a//2, a/2.0, a//2.0, a/2, a//2 def py_mix_by_neg1(a): """ >>> py_mix_by_neg1(0) (0, 0, -0.0, -0.0, 0, 0) >>> py_mix_by_neg1(-1) (1, 1, 1.0, 1.0, 1, 1) >>> py_mix_by_neg1(int(2**31-1)) (-2147483647, -2147483647, -2147483647.0, -2147483647.0, -2147483647, -2147483647) >>> bigints(py_mix_by_neg1(int(-2**31-1))) 2147483649 2147483649 2147483649.0 2147483649.0 2147483649 2147483649 >>> results = py_mix_by_neg1(int(2**63-1)) >>> results[2] == results[3] == float(2**63-1) / -1.0 or results True >>> results[0] == results[1] == results[4] == results[5] == (2**63-1) // -1 or results True >>> results = py_mix_by_neg1(int(-2**63-1)) >>> results[2] == results[3] == float(-2**63-1) / -1.0 or results True >>> results[0] == results[1] == results[4] == results[5] == (-2**63-1) // -1 or results True """ return a/-1, a//-1, a/-1.0, a//-1.0, a/-1, a//-1 def py_mix_rev(a): """ >>> py_mix_rev(4) (0, 0, 1.25, 1.0, 1, 1) >>> py_mix_rev(4.0) (0.25, 0.0, 1.25, 1.0, 1.25, 1.0) """ return 1/a, 1//a, 5.0/a, 5.0//a, 5/a, 5//a def int_mix(int a): """ >>> int_mix(1) (0, 0, 0.5, 0.0, 0, 0) """ return a/2, a//2, a/2.0, a//2.0, a/2, a//2 def int_mix_rev(int a): """ >>> int_mix_rev(4) (0, 0, 1.25, 1.0, 1, 1) """ return 1/a, 1//a, 5.0/a, 5.0//a, 5/a, 5//a def float_mix(float a): """ >>> float_mix(1.0) (0.5, 0.0, 0.5, 0.0, 0.5, 0.0) """ return a/2, a//2, a/2.0, a//2.0, a/2, a//2 def float_mix_rev(float a): """ >>> float_mix_rev(4.0) (0.25, 0.0, 1.25, 1.0, 1.25, 1.0) """ return 1/a, 1//a, 5.0/a, 5.0//a, 5/a, 5//a def int_int(int a, int b): """ >>> int_int(1, 2) (0, 2) """ return a/b, b/a Cython-0.23.4/tests/run/non_dict_kwargs_T470.pyx0000644000175600017570000000156512606202452022614 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 470 def func(**kwargs): """ >>> func(**{'a' : 7}) True >>> func(**SubDict()) True >>> func(**NonDict()) True """ return type(kwargs) is dict and kwargs['a'] == 7 class NonDict(object): def __getitem__(self, k): assert k == 'a' return 7 def keys(self): return ['a'] def call_non_dict_test(): """ >>> call_non_dict_test() True """ return func(**NonDict()) def call_non_dict_test_kw(): """ >>> call_non_dict_test_kw() True """ return func(b=5, **NonDict()) class SubDict(dict): def __init__(self): self['a'] = 7 def call_sub_dict_test(): """ >>> call_sub_dict_test() True """ return func(**SubDict()) def call_sub_dict_test_kw(): """ >>> call_sub_dict_test_kw() True """ return func(b=5, **SubDict()) Cython-0.23.4/tests/run/nogil.pyx0000644000175600017570000000216612606202452020031 0ustar jenkinsjenkins00000000000000# mode: run try: from StringIO import StringIO except ImportError: from io import StringIO def test(int x): """ >>> test(5) 47 >>> test(11) 53 """ with nogil: f(x) x = g(x) return x cdef void f(int x) nogil: cdef int y y = x + 42 g(y) cdef int g(int x) nogil: cdef int y y = x + 42 return y cdef int with_gil_func() except 0 with gil: raise Exception("error!") cdef int nogil_func() nogil except 0: with_gil_func() def test_nogil_exception_propagation(): """ >>> test_nogil_exception_propagation() Traceback (most recent call last): ... Exception: error! """ with nogil: nogil_func() cdef int write_unraisable() nogil: with gil: raise ValueError() def test_unraisable(): """ >>> print(test_unraisable()) # doctest: +ELLIPSIS Exception...ignored... """ import sys old_stderr = sys.stderr stderr = sys.stderr = StringIO() try: write_unraisable() finally: sys.stderr = old_stderr return stderr.getvalue().strip() Cython-0.23.4/tests/run/no_gc_clear.pyx0000644000175600017570000000372512606202452021156 0ustar jenkinsjenkins00000000000000""" Check that the @cython.no_gc_clear decorator disables generation of the tp_clear slot so that __dealloc__ will still see the original reference contents. Discussed here: http://article.gmane.org/gmane.comp.python.cython.devel/14986 """ cimport cython from cpython.ref cimport PyObject, Py_TYPE # Pull tp_clear for PyTypeObject as I did not find another way to access it # from Cython code. cdef extern from *: ctypedef struct PyTypeObject: void (*tp_clear)(object) ctypedef struct __pyx_CyFunctionObject: PyObject* func_closure def is_tp_clear_null(obj): return (Py_TYPE(obj)).tp_clear is NULL def is_closure_tp_clear_null(func): return is_tp_clear_null( (<__pyx_CyFunctionObject*>func).func_closure) @cython.no_gc_clear cdef class DisableTpClear: """ An extension type that has a tp_clear method generated to test that it actually clears the references to NULL. >>> uut = DisableTpClear() >>> is_tp_clear_null(uut) True >>> uut.call_tp_clear() >>> type(uut.requires_cleanup) == list True >>> del uut """ cdef public object requires_cleanup def __cinit__(self): self.requires_cleanup = [ "Some object that needs cleaning in __dealloc__"] def call_tp_clear(self): cdef PyTypeObject *pto = Py_TYPE(self) if pto.tp_clear != NULL: pto.tp_clear(self) def test_closure_without_clear(str x): """ >>> c = test_closure_without_clear('abc') >>> is_tp_clear_null(c) False >>> is_closure_tp_clear_null(c) True >>> c('cba') 'abcxyzcba' """ def c(str s): return x + 'xyz' + s return c def test_closure_with_clear(list x): """ >>> c = test_closure_with_clear(list('abc')) >>> is_tp_clear_null(c) False >>> is_closure_tp_clear_null(c) False >>> c('cba') 'abcxyzcba' """ def c(str s): return ''.join(x) + 'xyz' + s return c Cython-0.23.4/tests/run/new_style_exceptions.pyx0000644000175600017570000000076512606202452023176 0ustar jenkinsjenkins00000000000000 import sys, types def test(obj): """ >>> test(Exception('hi')) Raising: Exception('hi',) Caught: Exception('hi',) """ print u"Raising: %s%r" % (obj.__class__.__name__, obj.args) try: raise obj except: info = sys.exc_info() if sys.version_info >= (2,5): assert isinstance(info[0], type) else: assert isinstance(info[0], types.ClassType) print u"Caught: %s%r" % (info[1].__class__.__name__, info[1].args) Cython-0.23.4/tests/run/new_as_nonkeyword.pyx0000644000175600017570000000075612606202452022457 0ustar jenkinsjenkins00000000000000cdef extern from *: int new(int new) def new(x): """ >>> new(3) 3 """ cdef int new = x return new def x(new): """ >>> x(10) 110 >>> x(1) 1 """ if new*new != new: return new + new**2 return new class A: def new(self, n): """ >>> a = A() >>> a.new(3) 6 >>> a.new(5) 120 """ if n <= 1: return 1 else: return n * self.new(n-1) Cython-0.23.4/tests/run/multass.pyx0000644000175600017570000000215112606202452020403 0ustar jenkinsjenkins00000000000000__doc__ = """ >>> h() (1, b'test', 3, 1, b'test', 3) """ import sys if sys.version_info[0] < 3: __doc__ = __doc__.replace(u" b'", u" '") def f(): """ >>> f() (1, 2, 1, 2) """ cdef object obj1a, obj2a, obj3a, obj1b, obj2b, obj3b obj1b, obj2b, obj3b = 1, 2, 3 obj1a, obj2a = obj1b, obj2b return obj1a, obj2a, obj1b, obj2b def g(): """ >>> g() (1, 1, 2, 2, 3, 3) """ cdef object obj1a, obj2a, obj3a, obj1b, obj2b, obj3b obj1b, obj2b, obj3b = 1, 2, 3 obj1a, [obj2a, obj3a] = [obj1b, (obj2b, obj3b)] return obj1a, obj1b, obj2a, obj2b, obj3a, obj3b def h(): cdef object obj1a, obj2a, obj3a, obj1b, obj2b, obj3b cdef int int1, int2 cdef char *ptr1, *ptr2 int2, ptr2, obj1b = 1, "test", 3 int1, ptr1, obj1a = int2, ptr2, obj1b return int1, ptr1, obj1a, int2, ptr2, obj1b def j(): """ >>> j() (2, 1, 4, 2, 6, 3) """ cdef object obj1a, obj2a, obj3a, obj1b, obj2b, obj3b obj1b, obj2b, obj3b = 1, 2, 3 obj1a, obj2a, obj3a = obj1b + 1, obj2b + 2, obj3b + 3 return obj1a, obj1b, obj2a, obj2b, obj3a, obj3b Cython-0.23.4/tests/run/moduletryexcept.pyx0000644000175600017570000000345312606202452022156 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> a 2 >>> b 3 >>> exc[0].__class__.__name__ 'AttributeError' >>> exc[1].__class__.__name__ 'KeyError' >>> exc[2].__class__.__name__ 'IndexError' >>> exc[3].__class__.__name__ 'ValueError' >>> exc[3] is val True >>> except_as_deletes # Py2 behaviour False >>> no_match_does_not_touch_target True """ a = 0 try: raise KeyError except AttributeError: a = 1 except KeyError: a = 2 except: a = 3 b = 0 try: raise IndexError except AttributeError: b = 1 except KeyError: b = 2 except: b = 3 exc = [None]*4 try: raise AttributeError except AttributeError as e: exc[0] = e except KeyError as e: exc[0] = e except IndexError as e: exc[0] = e except: exc[0] = 'SOMETHING ELSE' e = None try: raise KeyError except AttributeError as e: exc[1] = e except KeyError as e: exc[1] = e except IndexError as e: exc[1] = e except: exc[1] = 'SOMETHING ELSE' try: e except NameError: except_as_deletes = True else: except_as_deletes = False e = 123 try: raise TypeError except NameError as e: pass except TypeError: pass no_match_does_not_touch_target = (e == 123) try: raise IndexError except AttributeError as e: exc[2] = e except KeyError as e: exc[2] = e except IndexError as e: exc[2] = e except: exc[2] = 'SOMETHING ELSE' val = None try: try: try: raise ValueError except AttributeError as e: exc[3] = e except KeyError as e: exc[3] = e except IndexError as e: exc[3] = e except: raise except (AttributeError, KeyError, IndexError, ValueError) as e: val = e raise e except Exception as e: exc[3] = e Cython-0.23.4/tests/run/module_init_error.srctree0000644000175600017570000000311412606202452023263 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import test_fail_in_init; test_fail_in_init.try_import()" PYTHON -c "import test_fail_in_init_after_atexit; test_fail_in_init_after_atexit.try_import()" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize("fail_in_init*.pyx") ) ######## test_fail_in_init.py ######## import sys def try_import(): try: import fail_in_init except ValueError: pass else: raise RuntimeError("expected ValueError from import") if (3, 3) <= sys.version_info < (3, 5): assert 'fail_in_init' not in sys.modules elif 'fail_in_init' in sys.modules: try: sys.modules['fail_in_init'].fail() except AttributeError: pass # this is "ok enough" except ValueError: pass # this is what we had expected else: raise RuntimeError("expected ValueError from call through sys.modules") ######## fail_in_init.pyx ######## def fail(): raise ValueError("kaputt") fail() ######## test_fail_in_init_after_atexit.py ######## def try_import(): try: import fail_in_init_after_atexit except ValueError: pass else: raise RuntimeError("expected ValueError from import") ######## fail_in_init_after_atexit.pyx ######## X = 5 def callback(): try: print(X) except NameError: pass # NameError is acceptable, a crash is not import atexit atexit.register(callback) def fail(): raise ValueError("holla!") fail() Cython-0.23.4/tests/run/modop.pyx0000644000175600017570000000623012606202452020033 0ustar jenkinsjenkins00000000000000import sys def modobj(obj2, obj3): """ >>> modobj(9,2) 1 >>> modobj('%d', 5) '5' """ obj1 = obj2 % obj3 return obj1 def mod_obj_10(int2): """ >>> 0 % 10 0 >>> mod_obj_10(0) 0 >>> 1 % 10 1 >>> mod_obj_10(1) 1 >>> (-1) % 10 9 >>> mod_obj_10(-1) 9 >>> 9 % 10 9 >>> mod_obj_10(9) 9 >>> 10 % 10 0 >>> mod_obj_10(10) 0 >>> (-10) % 10 0 >>> mod_obj_10(-10) 0 >>> (-12) % 10 8 >>> mod_obj_10(-12) 8 >>> 10002 % 10 2 >>> mod_obj_10(10002) 2 >>> int((2**25) % 10) 2 >>> int(mod_obj_10(2**25)) 2 >>> int((-2**25) % 10) 8 >>> int(mod_obj_10(-2**25)) 8 >>> int((-2**31-1) % 10) 1 >>> int(mod_obj_10(int(-2**31-1))) 1 >>> int((2**50) % 10) 4 >>> int(mod_obj_10(2**50)) 4 >>> int((-2**50) % 10) 6 >>> int(mod_obj_10(-2**50)) 6 >>> int((-2**63-1) % 10) 1 >>> int(mod_obj_10(-2**63-1)) 1 >>> int((2**200) % 10) 6 >>> int(mod_obj_10(2**200)) 6 >>> int((-2**200) % 10) 4 >>> int(mod_obj_10(-2**200)) 4 """ int1 = int2 % 10 return int1 def mod_obj_17(int2): """ >>> 0 % 17 0 >>> mod_obj_17(0) 0 >>> 1 % 17 1 >>> mod_obj_17(1) 1 >>> (-1) % 17 16 >>> mod_obj_17(-1) 16 >>> 9 % 17 9 >>> mod_obj_17(16) 16 >>> 17 % 17 0 >>> mod_obj_17(17) 0 >>> (-17) % 17 0 >>> mod_obj_17(-17) 0 >>> (-18) % 17 16 >>> mod_obj_17(-18) 16 >>> 10002 % 17 6 >>> mod_obj_17(10002) 6 >>> int((2**25) % 17) 2 >>> int(mod_obj_17(2**25)) 2 >>> int((-2**25) % 17) 15 >>> int(mod_obj_17(-2**25)) 15 >>> int((-2**31-1) % 17) 7 >>> int(mod_obj_17(int(-2**31-1))) 7 >>> int((2**50) % 17) 4 >>> int(mod_obj_17(2**50)) 4 >>> int((-2**50) % 17) 13 >>> int(mod_obj_17(-2**50)) 13 >>> int((-2**63-1) % 17) 7 >>> int(mod_obj_17(-2**63-1)) 7 >>> int((2**200) % 17) 1 >>> int(mod_obj_17(2**200)) 1 >>> int((-2**200) % 17) 16 >>> int(mod_obj_17(-2**200)) 16 """ int1 = int2 % 17 return int1 def mod_obj_m2(int2): """ >>> 0 % -2 0 >>> mod_obj_m2(0) 0 >>> 1 % -2 -1 >>> mod_obj_m2(1) -1 >>> 9 % -2 -1 >>> mod_obj_m2(9) -1 """ int1 = int2 % -2 return int1 def mod_obj_m2f(obj2): """ >>> 0 % -2.0 == 0.0 # -0.0 in Py2.7+ True >>> mod_obj_m2f(0) -0.0 >>> 1 % -2.0 -1.0 >>> mod_obj_m2f(1) -1.0 >>> 9 % -2.0 -1.0 >>> mod_obj_m2f(9) -1.0 """ result = obj2 % -2.0 return result def modint(int int2, int int3): """ >>> modint(9,2) 1 """ cdef int int1 int1 = int2 % int3 return int1 def modptr(): """ >>> print(modptr() if sys.version_info[0] < 3 else 'spameggs') spameggs """ cdef char *str2, *str3 str2 = "spam%s" str3 = "eggs" obj1 = str2 % str3 # '%' operator doesn't work on byte strings in Py3 return obj1 Cython-0.23.4/tests/run/modbody.pyx0000644000175600017570000000031712606202452020352 0ustar jenkinsjenkins00000000000000 def f(): """ >>> f() >>> g 42 >>> x == 'spam' True >>> y == 'eggs' True >>> z == 'spameggs' True """ pass g = 42 x = u"spam" y = u"eggs" if g: z = x + y Cython-0.23.4/tests/run/mod__name__.pyx0000644000175600017570000000034112606202452021126 0ustar jenkinsjenkins00000000000000 module_name = __name__ def in_module(): """ >>> print(in_module()) mod__name__ """ return module_name def in_function(): """ >>> print(in_function()) mod__name__ """ return __name__ Cython-0.23.4/tests/run/min_max_optimization.pyx0000644000175600017570000001066112606202452023156 0ustar jenkinsjenkins00000000000000 cimport cython class loud_list(list): def __len__(self): print "calling __len__" return super(loud_list, self).__len__() # max() def test_max1(x): """ >>> test_max1([1, 2, 3]) 3 >>> test_max1([2]) 2 """ return max(x) @cython.test_assert_path_exists( '//PrintStatNode//CondExprNode') @cython.test_fail_if_path_exists( '//PrintStatNode//SimpleCallNode//CoerceToPyTypeNode', '//PrintStatNode//SimpleCallNode//ConstNode') def test_max2(): """ >>> test_max2() 2 2 2 2 2 calling __len__ 3 calling __len__ 3 """ cdef int my_int = 1 cdef object my_pyint = 2 cdef object my_list = loud_list([1,2,3]) print max(1, 2) print max(2, my_int) print max(my_int, 2) print max(my_int, my_pyint) print max(my_pyint, my_int) print max(my_int, len(my_list)) print max(len(my_list), my_int) @cython.test_assert_path_exists( '//PrintStatNode//CondExprNode') @cython.test_fail_if_path_exists( '//PrintStatNode//SimpleCallNode//CoerceToPyTypeNode', '//PrintStatNode//SimpleCallNode//ConstNode') def test_max3(): """ >>> test_max3() calling __len__ 3 calling __len__ calling __len__ 3 """ cdef int my_int = 1 cdef object my_pyint = 2 cdef object my_list = loud_list([1,2,3]) print max(my_int, my_pyint, len(my_list)) print max(my_pyint, my_list.__len__(), len(my_list)) @cython.test_assert_path_exists( '//PrintStatNode//CondExprNode') @cython.test_fail_if_path_exists( '//PrintStatNode//SimpleCallNode//CoerceToPyTypeNode', '//PrintStatNode//SimpleCallNode//ConstNode') def test_maxN(): """ >>> test_maxN() calling __len__ 3 calling __len__ 3 calling __len__ 3 """ cdef int my_int = 1 cdef object my_pyint = 2 cdef object my_list = loud_list([1,2,3]) print max(my_int, 2, my_int, 0, my_pyint, my_int, len(my_list)) print max(my_int, my_int, 0, my_pyint, my_int, len(my_list)) print max(my_int, my_int, 2, my_int, 0, my_pyint, my_int, len(my_list)) # min() @cython.test_assert_path_exists( '//PrintStatNode//CondExprNode') @cython.test_fail_if_path_exists( '//PrintStatNode//SimpleCallNode//CoerceToPyTypeNode', '//PrintStatNode//SimpleCallNode//ConstNode') def test_min2(): """ >>> test_min2() 1 1 1 1 1 calling __len__ 1 calling __len__ 1 """ cdef int my_int = 1 cdef object my_pyint = 2 cdef object my_list = loud_list([1,2,3]) print min(1, 2) print min(2, my_int) print min(my_int, 2) print min(my_int, my_pyint) print min(my_pyint, my_int) print min(my_int, len(my_list)) print min(len(my_list), my_int) @cython.test_assert_path_exists( '//PrintStatNode//CondExprNode') @cython.test_fail_if_path_exists( '//PrintStatNode//SimpleCallNode//CoerceToPyTypeNode', '//PrintStatNode//SimpleCallNode//ConstNode') def test_min3(): """ >>> test_min3() calling __len__ 1 calling __len__ calling __len__ 2 """ cdef int my_int = 1 cdef object my_pyint = 2 cdef object my_list = loud_list([1,2,3]) print min(my_int, my_pyint, len(my_list)) print min(my_pyint, my_list.__len__(), len(my_list)) @cython.test_assert_path_exists( '//PrintStatNode//CondExprNode') @cython.test_fail_if_path_exists( '//PrintStatNode//SimpleCallNode//CoerceToPyTypeNode', '//PrintStatNode//SimpleCallNode//ConstNode') def test_minN(): """ >>> test_minN() calling __len__ 0 calling __len__ 0 calling __len__ 0 """ cdef int my_int = 1 cdef object my_pyint = 2 cdef object my_list = loud_list([1,2,3]) print min(my_int, 2, my_int, 0, my_pyint, my_int, len(my_list)) print min(my_int, my_int, 0, my_pyint, my_int, len(my_list)) print min(my_int, my_int, 2, my_int, 0, my_pyint, my_int, len(my_list)) ''' # ticket 772 # FIXME: signed vs. unsigned fails to safely handle intermediate results @cython.test_assert_path_exists("//CondExprNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def max3_typed_signed_unsigned(int a, unsigned int b, int c): """ >>> max3_typed_signed_unsigned(1,2,-3) 2 >>> max3_typed_signed_unsigned(-2,3,1) 3 >>> max3_typed_signed_unsigned(-2,1,-3) 1 >>> max3_typed_signed_unsigned(3,-1,2) 3 >>> max3_typed_signed_unsigned(-3,2,1) 2 """ return max(a,b,c) ''' Cython-0.23.4/tests/run/methodmangling_T5.py0000644000175600017570000000346712606202452022103 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 5 class CyTest(object): """ >>> cy = CyTest() >>> '_CyTest__private' in dir(cy) True >>> cy._CyTest__private() 8 >>> '__private' in dir(cy) False >>> '_CyTest__x' in dir(cy) True >>> '__x' in dir(cy) False """ __x = 1 def __private(self): return 8 def get(self): """ >>> CyTest().get() (1, 1, 8) """ return self._CyTest__x, self.__x, self.__private() def get_inner(self): """ >>> CyTest().get_inner() (1, 1, 8) """ def get(o): return o._CyTest__x, o.__x, o.__private() return get(self) class CyTestSub(CyTest): """ >>> cy = CyTestSub() >>> '_CyTestSub__private' in dir(cy) True >>> cy._CyTestSub__private() 9 >>> '_CyTest__private' in dir(cy) True >>> cy._CyTest__private() 8 >>> '__private' in dir(cy) False >>> '_CyTestSub__x' in dir(cy) False >>> '_CyTestSub__y' in dir(cy) True >>> '_CyTest__x' in dir(cy) True >>> '__x' in dir(cy) False """ __y = 2 def __private(self): return 9 def get(self): """ >>> CyTestSub().get() (1, 2, 2, 9) """ return self._CyTest__x, self._CyTestSub__y, self.__y, self.__private() def get_inner(self): """ >>> CyTestSub().get_inner() (1, 2, 2, 9) """ def get(o): return o._CyTest__x, o._CyTestSub__y, o.__y, o.__private() return get(self) class _UnderscoreTest(object): """ >>> ut = _UnderscoreTest() >>> '__x' in dir(ut) False >>> '_UnderscoreTest__x' in dir(ut) True >>> ut._UnderscoreTest__x 1 >>> ut.get() 1 """ __x = 1 def get(self): return self.__x Cython-0.23.4/tests/run/method_module_name_T422.pyx0000644000175600017570000000066512606202452023263 0ustar jenkinsjenkins00000000000000# ticket: 422 """ >>> Foo.incr.__module__ is not None True >>> Foo.incr.__module__ == Foo.__module__ == bar.__module__ True >>> Simpleton.incr.__module__ == Simpleton.__module__ == bar.__module__ True """ class Foo(object): def incr(self,x): return x+1 def bar(): pass class Simpleton: def __str__(self): return "A simpleton" def incr(self,x): """Increment x by one. """ return x+1 Cython-0.23.4/tests/run/metaclass.pyx0000644000175600017570000001014512606202452020671 0ustar jenkinsjenkins00000000000000 cimport cython class Base(type): def __new__(cls, name, bases, attrs): attrs['metaclass_was_here'] = True return type.__new__(cls, name, bases, attrs) @cython.test_assert_path_exists("//PyClassMetaclassNode", "//Py3ClassNode") class Foo(object): """ >>> obj = Foo() >>> obj.metaclass_was_here True """ __metaclass__ = Base def non_type_metaclass(name, bases, namespace): namespace['BASES'] = [b.__name__ for b in bases] namespace['NAME'] = name return type(name, bases, namespace) class FunctionAsPy2Metaclass(object): """ >>> obj = FunctionAsPy2Metaclass() >>> obj.NAME 'FunctionAsPy2Metaclass' >>> obj.BASES ['object'] >>> obj.x 1 """ __metaclass__ = non_type_metaclass x = 1 class ODict(dict): def __init__(self): dict.__init__(self) self._order = [] dict.__setitem__(self, '_order', self._order) def __setitem__(self, key, value): dict.__setitem__(self, key, value) self._order.append(key) class Py3MetaclassPlusAttr(type): def __new__(cls, name, bases, attrs, **kwargs): assert isinstance(attrs, ODict), str(type(attrs)) for key, value in kwargs.items(): attrs[key] = value attrs['metaclass_was_here'] = True return type.__new__(cls, name, bases, attrs) def __init__(self, cls, attrs, obj, **kwargs): pass @staticmethod def __prepare__(*args, **kwargs): return ODict() @cython.test_fail_if_path_exists("//PyClassMetaclassNode") @cython.test_assert_path_exists("//Py3ClassNode") class Py3ClassMCOnly(object, metaclass=Py3MetaclassPlusAttr): """ >>> obj = Py3ClassMCOnly() >>> obj.bar 321 >>> obj.metaclass_was_here True >>> obj._order ['__module__', '__qualname__', '__doc__', 'bar', 'metaclass_was_here'] """ bar = 321 class Py3InheritedMetaclass(Py3ClassMCOnly): """ >>> obj = Py3InheritedMetaclass() >>> obj.bar 345 >>> obj.metaclass_was_here True >>> obj._order ['__module__', '__qualname__', '__doc__', 'bar', 'metaclass_was_here'] """ bar = 345 class Py3Base(type): def __new__(cls, name, bases, attrs, **kwargs): assert isinstance(attrs, ODict), str(type(attrs)) for key, value in kwargs.items(): attrs[key] = value return type.__new__(cls, name, bases, attrs) def __init__(self, cls, attrs, obj, **kwargs): pass @staticmethod def __prepare__(*args, **kwargs): return ODict() @cython.test_fail_if_path_exists("//PyClassMetaclassNode") @cython.test_assert_path_exists("//Py3ClassNode") class Py3Foo(object, metaclass=Py3Base, foo=123): """ >>> obj = Py3Foo() >>> obj.foo 123 >>> obj.bar 321 >>> obj._order ['__module__', '__qualname__', '__doc__', 'bar', 'foo'] """ bar = 321 @cython.test_assert_path_exists("//PyClassMetaclassNode", "//Py3ClassNode") class Py3FooInherited(Py3Foo, foo=567): """ >>> obj = Py3FooInherited() >>> obj.foo 567 >>> obj.bar 321 >>> obj._order ['__module__', '__qualname__', '__doc__', 'bar', 'foo'] """ bar = 321 kwargs = {'foo': 123, 'bar': 456} @cython.test_assert_path_exists("//PyClassMetaclassNode", "//Py3ClassNode") class Py3Mixed(metaclass=Py3Base, **kwargs): """ >>> Py3Mixed.foo 123 >>> Py3Mixed.bar 456 """ kwargs['metaclass'] = Py3Base @cython.test_assert_path_exists("//PyClassMetaclassNode") class Py3Kwargs(**kwargs): """ >>> Py3Kwargs.foo 123 >>> Py3Kwargs.bar 456 """ class Base3(type): def __new__(cls, name, bases, attrs, **kwargs): kwargs['b'] = 2 return type.__new__(cls, name, bases, attrs) def __init__(self, *args, **kwargs): self.kwargs = kwargs @staticmethod def __prepare__(*args, **kwargs): kwargs['a'] = 1 return {} kwargs = {'c': 0} @cython.test_assert_path_exists("//PyClassMetaclassNode", "//Py3ClassNode") class Foo3(metaclass=Base3, a=0, b=0, **kwargs): """ >>> sorted(Foo3.kwargs.items()) [('a', 0), ('b', 0), ('c', 0)] """ Cython-0.23.4/tests/run/menten1.pyx0000644000175600017570000000023712606202452020265 0ustar jenkinsjenkins00000000000000def loops(): """ >>> loops() 5 """ cdef int k for i from 0 <= i < 5: for j from 0 <= j < 2: k = i + j return k Cython-0.23.4/tests/run/memview_vector.pyx0000644000175600017570000000043512606202452021751 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp from libcpp.vector cimport vector def memview_test(L, int i, int x): """ >>> memview_test(range(10), 7, 100) [0, 1, 2, 3, 4, 5, 6, 100, 8, 9] """ cdef vector[int] v = L cdef int[::1] mv = &v[0] mv[i] = x return v Cython-0.23.4/tests/run/memoryview_namespace_T775.pyx0000644000175600017570000000057112606202452023664 0ustar jenkinsjenkins00000000000000 cdef int[10] data cdef int[:] myslice = data def test_memoryview_namespace(): """ >>> test_memoryview_namespace() """ namespace = dir(__import__(__name__)) assert 'array' not in namespace, namespace assert 'memoryview' not in namespace, namespace assert '_memoryviewslice' not in namespace, namespace assert 'Enum' not in namespace, namespace Cython-0.23.4/tests/run/matrix_multiplier.pyx0000644000175600017570000000567612606202452022504 0ustar jenkinsjenkins00000000000000 import sys if sys.version_info >= (3, 5): __doc__ = """\ Note: support for providing Python special methods despite missing the C-level slot is currently not supported. >>> a, b = ExtMatMult(1), ExtMatMult(2) >>> print(test_matmul(a, b)) ExtMatMult(1) @ ExtMatMult(2) >>> print(test_matmul(a, 22)) ExtMatMult(1) @ 22 >>> print(test_matmul(11, b)) 11 @ ExtMatMult(2) >>> print(test_imatmul(a, b)) ExtMatMult('ExtMatMult(1) @ ExtMatMult(2)') >>> print(test_imatmul(a, b)) ExtMatMult("ExtMatMult('ExtMatMult(1) @ ExtMatMult(2)') @ ExtMatMult(2)") >>> x = y = 1 >>> x @ y Traceback (most recent call last): TypeError: unsupported operand type(s) for @: 'int' and 'int' >>> x @= y Traceback (most recent call last): TypeError: unsupported operand type(s) for @=: 'int' and 'int' >>> y = MatMult(22) >>> x @= y >>> print(x) 1 @ MatMult(22) >>> x = MatMult(22) >>> print(x @ 1) MatMult(22) @ 1 >>> print(1 @ x) 1 @ MatMult(22) >>> x @= 1 >>> print(x) MatMult('MatMult(22) @ 1') """ class MatMult(object): def __init__(self, myself): self.myself = myself def __matmul__(self, other): return '%r @ %r' % (self, other) def __rmatmul__(self, other): return '%r @ %r' % (other, self) def __imatmul__(self, other): self.myself = '%r @ %r' % (self, other) return self def __repr__(self): return 'MatMult(%r)' % self.myself cdef class ExtMatMult: """ Note: support for providing Python special methods despite missing the C-level slot is currently not supported. """ cdef object myself def __init__(self, myself): self.myself = myself def __matmul__(self, other): return '%r @ %r' % (self, other) def __rmatmul__(self, other): return '%r @ %r' % (other, self) def __imatmul__(self, other): self.myself = '%r @ %r' % (self, other) return self def __repr__(self): return 'ExtMatMult(%r)' % self.myself def test_matmul(a, b): """ >>> print(test_matmul(MatMult(1), MatMult(2))) MatMult(1) @ MatMult(2) >>> print(test_matmul(MatMult(1), 22)) MatMult(1) @ 22 >>> print(test_matmul(11, MatMult(2))) 11 @ MatMult(2) >>> print(test_matmul(MatMult('abc'), MatMult('def'))) MatMult('abc') @ MatMult('def') >>> test_matmul(1, 2) Traceback (most recent call last): TypeError: unsupported operand type(s) for @: 'int' and 'int' """ return a @ b def test_imatmul(a, b): """ >>> print(test_imatmul(MatMult(1), MatMult(2))) MatMult('MatMult(1) @ MatMult(2)') >>> print(test_imatmul(MatMult('abc'), MatMult('def'))) MatMult("MatMult('abc') @ MatMult('def')") >>> print(test_imatmul(11, MatMult('def'))) 11 @ MatMult('def') >>> print(test_imatmul(MatMult('abc'), 11)) MatMult("MatMult('abc') @ 11") >>> test_imatmul(1, 2) Traceback (most recent call last): TypeError: unsupported operand type(s) for @=: 'int' and 'int' """ a @= b return a Cython-0.23.4/tests/run/mangle_c_keywords.pyx0000644000175600017570000000040412606202452022406 0ustar jenkinsjenkins00000000000000# Tests that illegal member and vtab entries are mangled. cdef class A: """ >>> a = A(100) >>> a.case() 100 """ def __init__(self, value): self.switch = value cdef int switch cpdef case(self): return self.switch Cython-0.23.4/tests/run/lvalue_refs.pyx0000644000175600017570000000112312606202452021220 0ustar jenkinsjenkins00000000000000# tag: cpp from libcpp.vector cimport vector __doc__ = u""" >>> test_lvalue_ref_assignment() """ ctypedef double* dp ctypedef double** dpp cdef void foo(vector[dpp] &bar, vector[vector[dp]] &baz) nogil: bar[0] = &baz[0][0] def test_lvalue_ref_assignment(): cdef vector[dpp] bar cdef vector[vector[dp]] baz cdef vector[double] data cdef dp bongle = &data[0] bar.resize(1) bar[0] = NULL baz.resize(1) baz[0].resize(1) baz[0][0] = bongle foo(bar, baz) assert bar[0] == &baz[0][0] assert bar[0][0] == bongle Cython-0.23.4/tests/run/longlongindex.pyx0000644000175600017570000000050312606202452021561 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> D = set_longlong(2**40, 2**50, 2, "yelp") >>> D[2**40] 'yelp' >>> D[2**50] 'yelp' >>> D[2] 'yelp' """ ctypedef long long foo def set_longlong(long long ob, foo x, long y, val): cdef object tank = {} tank[ob] = val tank[x] = val tank[y] = val return tank Cython-0.23.4/tests/run/locals_rebind_T429.pyx0000644000175600017570000000100012606202452022225 0ustar jenkinsjenkins00000000000000# ticket: 429 __doc__ = u""" >>> sorted( get_locals(1,2,3, k=5) .items()) [('args', (2, 3)), ('kwds', {'k': 5}), ('x', 1), ('y', 'hi'), ('z', 5)] """ def get_locals(x, *args, **kwds): cdef int z = 5 y = "hi" return locals() def get_locals_rebound(x, *args, **kwds): """ >>> get_locals_rebound(1,2,3) 'REBOUND' """ cdef int z = 5 locals = _locals y = "hi" return locals() def _locals(): return "REBOUND" def sorted(it): l = list(it) l.sort() return l Cython-0.23.4/tests/run/locals_expressions_T430.pyx0000644000175600017570000000156212606202452023351 0ustar jenkinsjenkins00000000000000# ticket: 430 __doc__ = u""" >>> sorted( get_locals(1,2,3, k=5) .items()) [('args', (2, 3)), ('kwds', {'k': 5}), ('x', 1), ('y', 'hi'), ('z', 5)] >>> sorted(get_locals_items(1,2,3, k=5)) [('args', (2, 3)), ('kwds', {'k': 5}), ('x', 1), ('y', 'hi'), ('z', 5)] >>> sorted(get_locals_items_listcomp(1,2,3, k=5)) [('args', (2, 3)), ('kwds', {'k': 5}), ('x', 1), ('y', 'hi'), ('z', 5)] """ def get_locals(x, *args, **kwds): cdef int z = 5 y = "hi" return locals() def get_locals_items(x, *args, **kwds): cdef int z = 5 y = "hi" return locals().items() def get_locals_items_listcomp(x, *args, **kwds): # FIXME: 'item' should *not* appear in locals() yet, as locals() # is evaluated before assigning to item ! cdef int z = 5 y = "hi" return [ item for item in locals().items() ] def sorted(it): l = list(it) l.sort() return l Cython-0.23.4/tests/run/locals_T732.pyx0000644000175600017570000000237712606202452020721 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 731 # tag: locals, vars, dir cimport cython LOCALS = locals() GLOBALS = globals() DIR_SAME = sorted(dir()) == sorted(globals().keys()) def test_module_locals_and_dir(): """ >>> LOCALS is GLOBALS True >>> DIR_SAME True """ def test_class_locals_and_dir(): """ >>> klass = test_class_locals_and_dir() >>> 'visible' in klass.locs and 'not_visible' not in klass.locs True >>> klass.names ['__module__', '__qualname__', 'visible'] """ not_visible = 1234 class Foo: visible = 4321 names = dir() locs = locals() return Foo @cython.test_fail_if_path_exists('//SortedDictKeysNode') def test_class_dir_contains(): """ >>> klass = test_class_dir_contains() True False True False True False True True True """ not_visible = 1234 class Foo: visible = 4321 print('visible' in dir()) print('not_visible' in dir()) print('not_visible' not in dir()) print('locs' in dir()) print('visible' in locals()) print('locs' in locals()) locs = locals() print('visible' in dir()) print('locs' in dir()) print('locs' in locals()) return Foo Cython-0.23.4/tests/run/locals.pyx0000644000175600017570000000306212606202452020172 0ustar jenkinsjenkins00000000000000# mode: run # tag: builtins, locals, dir def get_locals(x, *args, **kwds): """ >>> sorted( get_locals(1,2,3, k=5).items() ) [('args', (2, 3)), ('kwds', {'k': 5}), ('x', 1), ('y', 'hi'), ('z', 5)] """ cdef int z = 5 y = "hi" return locals() def get_vars(x, *args, **kwds): """ >>> sorted( get_vars(1,2,3, k=5).items() ) [('args', (2, 3)), ('kwds', {'k': 5}), ('x', 1), ('y', 'hi'), ('z', 5)] """ cdef int z = 5 y = "hi" return vars() def get_dir(x, *args, **kwds): """ >>> sorted( get_dir(1,2,3, k=5) ) ['args', 'kwds', 'x', 'y', 'z'] """ cdef int z = 5 y = "hi" return dir() def in_locals(x, *args, **kwds): """ >>> in_locals('z') True >>> in_locals('args') True >>> in_locals('X') False """ cdef int z = 5 y = "hi" return x in locals() def in_dir(x, *args, **kwds): """ >>> in_dir('z') True >>> in_dir('args') True >>> in_dir('X') False """ cdef int z = 5 y = "hi" return x in dir() def in_vars(x, *args, **kwds): """ >>> in_vars('z') True >>> in_vars('args') True >>> in_vars('X') False """ cdef int z = 5 y = "hi" return x in vars() def sorted(it): l = list(it) l.sort() return l def locals_ctype(): """ >>> locals_ctype() False """ cdef int *p = NULL return 'p' in locals() def locals_ctype_inferred(): """ >>> locals_ctype_inferred() False """ cdef int *p = NULL b = p return 'b' in locals() Cython-0.23.4/tests/run/literalslice.pyx0000644000175600017570000000156212606202452021374 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> test_str(1) 'b' >>> test_unicode_ascii(2) u'c' >>> test_unicode(2) == u'\u00e4' True >>> test_int_list(2) 3 >>> test_str_list(1) 'bcd' >>> test_int_tuple(2) 3 >>> test_str_tuple(0) 'a' >>> test_mix_tuple(1) 'abc' >>> test_mix_tuple(0) 1 """ import sys IS_PY3 = sys.version_info[0] >= 3 if IS_PY3: __doc__ = __doc__.replace(u" u'", u" '") else: __doc__ = __doc__.replace(u" b'", u" '") def test_str(n): return "abcd"[n] def test_unicode_ascii(n): return u"abcd"[n] def test_unicode(n): return u"\u00fc\u00f6\u00e4"[n] def test_int_list(n): return [1,2,3,4][n] def test_str_list(n): return ["a","bcd","efg","xyz"][n] def test_int_tuple(n): return (1,2,3,4)[n] def test_str_tuple(n): return ("a","bcd","efg","xyz")[n] def test_mix_tuple(n): return (1, "abc", u"\u00fc", 1.1)[n] Cython-0.23.4/tests/run/literals.pyx0000644000175600017570000000377412606202452020546 0ustar jenkinsjenkins00000000000000# mode: run def foo(): """ >>> foo() """ a = 42 a1 = 0123 an1 = -0123 assert a1 == -an1 a2 = 0xabc an2 = -0xabc assert a2 == -an2 a3 = 0xDEF an3 = -0xDEF assert a3 == -an3 a4 = 1234567890L an4 = -1234567890L assert a4 == -an4 a5 = 0o123 an5 = -0o123 assert a5 == -an5 assert a5 == a1 a6 = 0b101 an6 = -0b101 assert a6 == -an6 == 5 b = 42.88e17 b0a = 1. b0b = .1 b0c = 1.1 b0d = 1.e1 b0e = .1e1 b0f = 1.1e1 b0g = 1.1e-1 b0h = 1e1 b1 = 3j b2 = 3.1415J b3 = c'X' c = "spanish inquisition" d = "this" "parrot" "is" "resting" e = 'single quoted string' f = '"this is quoted"' g = '''Triple single quoted string.''' h = """Triple double quoted string.""" g1 = '''Two line triple single quoted string.''' h1 = """Two line triple double quoted string.""" i = 'This string\ has an ignored newline.' j = 'One-char escapes: \'\"\\\a\b\f\n\r\t\v' k = b'Oct and hex escapes: \1 \12 \123 \x45 \xaf \xAF' l = r'''This is\ a \three \line raw string with some backslashes.''' m = 'Three backslashed ordinaries: \c\g\+' n = '''Triple single quoted string with ' and " quotes''' o = """Triple double quoted string with ' and " quotes""" p = "name_like_string" q = "NameLikeString2" r = "99_percent_un_namelike" s = "Not an \escape" t = b'this' b'parrot' b'is' b'resting' u = u'this' u'parrot' u'is' u'resting' def test_float(x): """ >>> test_float(1./3) True """ return x == 1./3 def test_complex(x): """ >>> test_complex(1j/3) True """ return x == 0.3333333333333333j def test_large_int(double x): """ >>> test_large_int(0) 2e+100 """ a = x + 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 a += 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 return a Cython-0.23.4/tests/run/literal_lists.pyx0000644000175600017570000000320412606202452021565 0ustar jenkinsjenkins00000000000000__doc__ = """ >>> test_chars(b'yo') (b'a', b'bc', b'yo') >>> try: test_chars(None) ... except TypeError: pass """ import sys if sys.version_info[0] < 3: __doc__ = __doc__.replace(u"b'", u"'") def repeated_literals(): """ >>> repeated_literals() p1: [4, 4] p2: [5, 5] """ cdef int i cdef int* p1 = [4, 4] cdef int* p2 = [5, 5] print "p1: %s" % [ p1[i] for i in range(2) ] print "p2: %s" % [ p2[i] for i in range(2) ] def test_ints(int x): """ >>> test_ints(100) (100, 100, 100) """ cdef list L = [1,2,3,x] cdef int* Li = [1,2,3,x] cdef int** Lii = [Li, &x] return L[3], Li[3], Lii[1][0] def test_chars(foo): cdef char** ss = [b"a", b"bc", foo] return ss[0], ss[1], ss[2] cdef struct MyStruct: int x int y double** data cdef print_struct(MyStruct a): print a.x, a.y, a.data == NULL def test_struct(int x, y): """ >>> test_struct(-5, -10) -5 -10 True 1 2 False """ cdef MyStruct* aa = [[x,y, NULL], [x+1,y+1,NULL]] print_struct(aa[0]) print_struct([1, 2, 1]) cdef int m_int = -1 cdef int* m_iarray = [4, m_int] cdef int** m_piarray = [m_iarray, &m_int] cdef char** m_carray = [b"a", b"bc"] cdef MyStruct* m_structarray = [[m_int,0,NULL], [1,m_int+1,NULL]] def test_module_level(): """ >>> test_module_level() 4 -1 4 -1 True True 1 0 True """ print m_iarray[0], m_iarray[1] print m_piarray[0][0], m_piarray[1][0] print m_carray[0] == b"a", m_carray[1] == b"bc" print_struct(m_structarray[1]) # Make sure it's still naturally an object. [0,1,2,3].append(4) Cython-0.23.4/tests/run/listcomp.pyx0000644000175600017570000000521612606202452020552 0ustar jenkinsjenkins00000000000000cimport cython def smoketest(): """ >>> smoketest() [0, 4, 8] """ x = 'abc' result = [x*2 for x in range(5) if x % 2 == 0] assert x != 'abc' return result def list_genexp(): """ >>> list_genexp() [0, 4, 8] """ x = 'abc' result = list(x*2 for x in range(5) if x % 2 == 0) assert x == 'abc' return result def int_runvar(): """ >>> int_runvar() [0, 4, 8] """ cdef int x print [x*2 for x in range(5) if x % 2 == 0] cdef class A: def __repr__(self): return u"A" def typed(): """ >>> typed() [A, A, A] """ cdef A obj print [obj for obj in [A(), A(), A()]] def inferred_type(): """ >>> inferred_type() ['A', 'A', 'A'] """ print [cython.typeof(obj) for obj in [A(), A(), A()]] def not_inferred_type(): """ >>> not_inferred_type() ['Python object', 'Python object', 'Python object'] """ print [cython.typeof(obj) for obj in [1, A(), 'abc']] def iterdict(): """ >>> iterdict() [1, 2, 3] """ cdef dict d = dict(a=1,b=2,c=3) l = [d[key] for key in d] l.sort() print l listcomp_result = [ i*i for i in range(5) ] def global_listcomp(): """ >>> [ i*i for i in range(5) ] [0, 1, 4, 9, 16] >>> listcomp_result [0, 1, 4, 9, 16] """ def nested_result(): """ >>> nested_result() [[], [-1], [-1, 0], [-1, 0, 1]] """ result = [[a-1 for a in range(b)] for b in range(4)] return result def listcomp_as_condition(sequence): """ >>> listcomp_as_condition(['a', 'b', '+']) True >>> listcomp_as_condition('ab+') True >>> listcomp_as_condition('abc') False """ if [1 for c in sequence if c in '+-*/<=>!%&|([^~,']: return True return False @cython.test_fail_if_path_exists("//SimpleCallNode//ComprehensionNode") @cython.test_assert_path_exists("//ComprehensionNode") def sorted_listcomp(sequence): """ >>> sorted_listcomp([3,2,4]) [3, 4, 5] """ return sorted([ n+1 for n in sequence ]) @cython.test_fail_if_path_exists("//IfStatNode", "//ComprehensionAppendNode") @cython.test_assert_path_exists("//ComprehensionNode") def listcomp_const_condition_false(): """ >>> listcomp_const_condition_false() [] """ return [x*2 for x in range(3) if False] @cython.test_fail_if_path_exists("//IfStatNode") @cython.test_assert_path_exists("//ComprehensionNode", "//ComprehensionAppendNode") def listcomp_const_condition_true(): """ >>> listcomp_const_condition_true() [0, 2, 4] """ return [x*2 for x in range(3) if True] Cython-0.23.4/tests/run/list_pop.pyx0000644000175600017570000001226312606202452020551 0ustar jenkinsjenkins00000000000000cimport cython from libc.stdint cimport uint64_t class A: def pop(self, *args): print args return None cdef class B: """ >>> B().call_pop() 'B' """ cdef pop(self): return "B" def call_pop(self): return self.pop() @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode/AttributeNode') def simple_pop(L): """ >>> L = list(range(10)) >>> simple_pop(L) 9 >>> simple_pop(L) 8 >>> L [0, 1, 2, 3, 4, 5, 6, 7] >>> while L: ... _ = simple_pop(L) >>> L [] >>> simple_pop(L) Traceback (most recent call last): IndexError: pop from empty list >>> simple_pop(A()) () """ return L.pop() @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode/AttributeNode') def simple_pop_typed(list L): """ >>> L = list(range(10)) >>> simple_pop_typed(L) 9 >>> simple_pop_typed(L) 8 >>> L [0, 1, 2, 3, 4, 5, 6, 7] >>> while L: ... _ = simple_pop_typed(L) >>> L [] >>> simple_pop_typed(L) Traceback (most recent call last): IndexError: pop from empty list """ return L.pop() @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode/AttributeNode') def index_pop(L, int i): """ >>> L = list(range(10)) >>> index_pop(L, 2) 2 >>> index_pop(L, -10) Traceback (most recent call last): IndexError: pop index out of range >>> index_pop(L, -2) 8 >>> L [0, 1, 3, 4, 5, 6, 7, 9] >>> index_pop(L, 100) Traceback (most recent call last): IndexError: pop index out of range >>> index_pop(L, -100) Traceback (most recent call last): IndexError: pop index out of range >>> while L: ... _ = index_pop(L, 0) >>> L [] >>> index_pop(L, 0) Traceback (most recent call last): IndexError: pop from empty list >>> index_pop(A(), 3) (3,) """ return L.pop(i) @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode/AttributeNode') def index_pop_typed(list L, int i): """ >>> L = list(range(10)) >>> index_pop_typed(L, 2) 2 >>> index_pop_typed(L, -2) 8 >>> L [0, 1, 3, 4, 5, 6, 7, 9] >>> index_pop_typed(L, 100) Traceback (most recent call last): IndexError: pop index out of range >>> index_pop_typed(L, -100) Traceback (most recent call last): IndexError: pop index out of range >>> index_pop_typed(None, 0) Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'pop' >>> while L: ... _ = index_pop_typed(L, 0) >>> L [] >>> index_pop_typed(L, 0) Traceback (most recent call last): IndexError: pop from empty list """ return L.pop(i) @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode/AttributeNode') def index_pop_list_object_index(list L, i): """ >>> L = list(range(10)) >>> index_pop_list_object_index(L, 2) 2 >>> index_pop_list_object_index(L, -2) 8 >>> L [0, 1, 3, 4, 5, 6, 7, 9] >>> index_pop_list_object_index(L, 100) Traceback (most recent call last): IndexError: pop index out of range >>> index_pop_list_object_index(L, -100) Traceback (most recent call last): IndexError: pop index out of range >>> index_pop_list_object_index(None, 0) Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'pop' >>> index_pop_list_object_index([1], None) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> index_pop_list_object_index([1], 'abc') # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> while L: ... _ = index_pop_list_object_index(L, 0) >>> L [] >>> index_pop_list_object_index(L, 0) Traceback (most recent call last): IndexError: pop from empty list """ return L.pop(i) @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode/AttributeNode') def index_pop_literal(list L): """ >>> L = list(range(10)) >>> index_pop_literal(L) 0 >>> L [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> while L: ... _ = index_pop_literal(L) >>> L [] >>> index_pop_literal(L) Traceback (most recent call last): IndexError: pop from empty list """ return L.pop(0) @cython.test_fail_if_path_exists('//PythonCapiCallNode') def crazy_pop(L): """ >>> crazy_pop(list(range(10))) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: pop... at most ... argument... >>> crazy_pop(A()) (1, 2, 3) """ return L.pop(1, 2, 3) def method_name(): """ >>> method_name() 'pop' """ return [].pop.__name__ def object_pop_large_int(): """ >>> object_pop_large_int() {} """ cdef object foo = {} cdef uint64_t bar = 201213467776703617ULL foo[bar] = None assert (bar) in foo foo.pop(bar) return foo Cython-0.23.4/tests/run/list_comp_in_closure_T598.pyx0000644000175600017570000000457112606202452023667 0ustar jenkinsjenkins00000000000000# mode: run # tag: closures # ticket: 598 # cython: language_level=3 def list_comp_in_closure(): """ >>> list_comp_in_closure() [0, 4, 8] """ x = 'abc' def f(): return x result = [x*2 for x in range(5) if x % 2 == 0] assert x == 'abc' # don't leak in Py3 code assert f() == 'abc' # don't leak in Py3 code return result def pytyped_list_comp_in_closure(): """ >>> pytyped_list_comp_in_closure() [0, 4, 8] """ cdef object x x = 'abc' def f(): return x result = [x*2 for x in range(5) if x % 2 == 0] assert x == 'abc' # don't leak in Py3 code assert f() == 'abc' # don't leak in Py3 code return result def pytyped_list_comp_in_closure_repeated(): """ >>> pytyped_list_comp_in_closure_repeated() [0, 4, 8] """ cdef object x x = 'abc' def f(): return x for i in range(3): result = [x*2 for x in range(5) if x % 2 == 0] assert x == 'abc' # don't leak in Py3 code assert f() == 'abc' # don't leak in Py3 code return result def genexpr_in_closure(): """ >>> genexpr_in_closure() [0, 4, 8] """ x = 'abc' def f(): return x result = list( x*2 for x in range(5) if x % 2 == 0 ) assert x == 'abc' # don't leak in Py3 code assert f() == 'abc' # don't leak in Py3 code return result def pytyped_genexpr_in_closure(): """ >>> pytyped_genexpr_in_closure() [0, 4, 8] """ cdef object x x = 'abc' def f(): return x result = list( x*2 for x in range(5) if x % 2 == 0 ) assert x == 'abc' # don't leak in Py3 code assert f() == 'abc' # don't leak in Py3 code return result def pytyped_genexpr_in_closure_repeated(): """ >>> pytyped_genexpr_in_closure_repeated() [0, 4, 8] """ cdef object x x = 'abc' def f(): return x for i in range(3): result = list( x*2 for x in range(5) if x % 2 == 0 ) assert x == 'abc' # don't leak in Py3 code assert f() == 'abc' # don't leak in Py3 code return result def genexpr_scope_in_closure(): """ >>> genexpr_scope_in_closure() [0, 4, 8] """ i = 2 x = 'abc' def f(): return i, x result = list( x*i for x in range(5) if x % 2 == 0 ) assert x == 'abc' # don't leak in Py3 code assert f() == (2,'abc') # don't leak in Py3 code return result Cython-0.23.4/tests/run/list.pyx0000644000175600017570000000530412606202452017671 0ustar jenkinsjenkins00000000000000 cimport cython def f(obj1, obj2, obj3, obj4, obj5): """ >>> f(1, 2, 3, 4, 5) [] """ obj1 = [] return obj1 def g(obj1, obj2, obj3, obj4, obj5): """ >>> g(1, 2, 3, 4, 5) [2] """ obj1 = [obj2] return obj1 def h(obj1, obj2, obj3, obj4, obj5): """ >>> h(1, 2, 3, 4, 5) [2, 3] """ obj1 = [obj2, obj3] return obj1 def j(obj1, obj2, obj3, obj4, obj5): """ >>> j(1, 2, 3, 4, 5) [2, 3, 4] """ obj1 = [obj2, obj3, obj4] return obj1 def k(obj1, obj2, obj3, obj4, obj5): """ >>> k(1, 2, 3, 4, 5) [17, 42, 88] """ obj1 = [17, 42, 88] return obj1 @cython.test_fail_if_path_exists("//SimpleCallNode") def test_list_call(ob): """ >>> def f(): ... yield 1 ... yield 2 ... >>> list(f()) [1, 2] """ return list(ob) def test_list_sort(): """ >>> test_list_sort() [1, 2, 3, 4] """ cdef list l1 l1 = [2,3,1,4] l1.sort() return l1 def test_list_sort_reversed(): cdef list l1 l1 = [2,3,1,4] l1.sort(reversed=True) return l1 def test_list_reverse(): """ >>> test_list_reverse() [1, 2, 3, 4] """ cdef list l1 l1 = [4,3,2,1] l1.reverse() return l1 def test_list_append(): """ >>> test_list_append() [1, 2, 3, 4] """ cdef list l1 = [1,2] l1.append(3) l1.append(4) return l1 def test_list_append_insert(): """ >>> test_list_append_insert() ['first', 'second'] """ cdef list l = [] l.append("second") l.insert(0, "first") return l def test_list_pop(): """ >>> test_list_pop() (2, [1]) """ cdef list l1 l1 = [1,2] two = l1.pop() return two, l1 def test_list_pop0(): """ >>> test_list_pop0() (1, [2]) """ cdef list l1 l1 = [1,2] one = l1.pop(0) return one, l1 def test_list_pop_all(): """ >>> test_list_pop_all() True """ cdef list l1 l1 = [1,2] i = 0 try: l1.pop() i = 1 l1.pop(-1) i = 2 l1.pop(0) i = 3 except IndexError: return i == 2 return False def test_list_extend(): """ >>> test_list_extend() [1, 2, 3, 4, 5, 6] """ cdef list l = [1,2,3] l.extend([]) l.extend(()) l.extend(set()) assert l == [1,2,3] assert len(l) == 3 l.extend([4,5,6]) return l def test_none_list_extend(list l): """ >>> test_none_list_extend([]) [1, 2, 3] >>> test_none_list_extend([0, 0, 0]) [0, 0, 0, 1, 2, 3] >>> test_none_list_extend(None) 123 """ try: l.extend([1,2,3]) except AttributeError: return 123 return l Cython-0.23.4/tests/run/line_trace.pyx0000644000175600017570000001113712606202452021024 0ustar jenkinsjenkins00000000000000# cython: linetrace=True # distutils: define_macros=CYTHON_TRACE_NOGIL=1 # mode: run # tag: trace from cpython.ref cimport PyObject from cpython.pystate cimport ( Py_tracefunc, PyFrameObject, PyTrace_CALL, PyTrace_EXCEPTION, PyTrace_LINE, PyTrace_RETURN, PyTrace_C_CALL, PyTrace_C_EXCEPTION, PyTrace_C_RETURN) cdef extern from *: void PyEval_SetProfile(Py_tracefunc cfunc, object obj) void PyEval_SetTrace(Py_tracefunc cfunc, object obj) map_trace_types = { PyTrace_CALL: 'call', PyTrace_EXCEPTION: 'exc', PyTrace_LINE: 'line', PyTrace_RETURN: 'return', PyTrace_C_CALL: 'ccall', PyTrace_C_EXCEPTION: 'cexc', PyTrace_C_RETURN: 'cret', }.get cdef int _trace_func(PyObject* _traceobj, PyFrameObject* _frame, int what, PyObject* arg) except -1: frame, traceobj = _frame, _traceobj traceobj.append((map_trace_types(what), frame.f_lineno - frame.f_code.co_firstlineno)) return 0 cdef int _failing_call_trace_func(PyObject* _traceobj, PyFrameObject* _frame, int what, PyObject* arg) except -1: if what == PyTrace_CALL: raise ValueError("failing call trace!") return _trace_func(_traceobj, _frame, what, arg) cdef int _failing_line_trace_func(PyObject* _traceobj, PyFrameObject* _frame, int what, PyObject* arg) except -1: if what == PyTrace_LINE and _traceobj: frame, traceobj = _frame, _traceobj if traceobj and traceobj[0] == frame.f_code.co_name: # first line in the right function => fail! raise ValueError("failing line trace!") return _trace_func(_traceobj, _frame, what, arg) def cy_add(a,b): x = a + b # 1 return x # 2 def cy_add_with_nogil(a,b): cdef int z, x=a, y=b # 1 with nogil: # 2 z = 0 # 3 z += cy_add_nogil(x, y) # 4 return z # 5 cdef int cy_add_nogil(int a, int b) nogil except -1: x = a + b # 1 return x # 2 def run_trace(func, *args): """ >>> def py_add(a,b): ... x = a+b ... return x >>> run_trace(py_add, 1, 2) [('call', 0), ('line', 1), ('line', 2), ('return', 2)] >>> run_trace(cy_add, 1, 2) [('call', 0), ('line', 1), ('line', 2), ('return', 2)] >>> result = run_trace(cy_add_with_nogil, 1, 2) >>> result[:5] [('call', 0), ('line', 1), ('line', 2), ('line', 3), ('line', 4)] >>> result[5:9] [('call', 0), ('line', 1), ('line', 2), ('return', 2)] >>> result[9:] [('line', 2), ('line', 5), ('return', 5)] """ trace = [] PyEval_SetTrace(_trace_func, trace) try: func(*args) finally: PyEval_SetTrace(NULL, None) return trace def fail_on_call_trace(func, *args): """ >>> def py_add(a,b): ... x = a+b ... return x >>> fail_on_call_trace(py_add, 1, 2) Traceback (most recent call last): ValueError: failing call trace! """ trace = [] PyEval_SetTrace(_failing_call_trace_func, trace) try: func(*args) finally: PyEval_SetTrace(NULL, None) assert not trace def fail_on_line_trace(fail_func): """ >>> result = fail_on_line_trace(None) >>> len(result) 17 >>> result[:5] ['NO ERROR', ('call', 0), ('line', 1), ('line', 2), ('return', 2)] >>> result[5:10] [('call', 0), ('line', 1), ('line', 2), ('line', 3), ('line', 4)] >>> result[10:14] [('call', 0), ('line', 1), ('line', 2), ('return', 2)] >>> result[14:] [('line', 2), ('line', 5), ('return', 5)] >>> result = fail_on_line_trace('cy_add_with_nogil') failing line trace! >>> result ['cy_add_with_nogil', ('call', 0), ('line', 1), ('line', 2), ('return', 2), ('call', 0), ('return', 1)] >>> result = fail_on_line_trace('cy_add_nogil') failing line trace! >>> result[:5] ['cy_add_nogil', ('call', 0), ('line', 1), ('line', 2), ('return', 2)] >>> result[5:] [('call', 0), ('line', 1), ('line', 2), ('line', 3), ('line', 4), ('call', 0), ('return', 1), ('return', 4)] """ cdef int x = 1 trace = ['NO ERROR'] exception = None PyEval_SetTrace(_failing_line_trace_func, trace) try: x += 1 cy_add(1, 2) x += 1 if fail_func: trace[0] = fail_func # trigger error on first line x += 1 cy_add_with_nogil(3, 4) x += 1 except Exception as exc: exception = str(exc) finally: PyEval_SetTrace(NULL, None) if exception: print(exception) else: assert x == 5 return trace Cython-0.23.4/tests/run/line_profile_test.srctree0000644000175600017570000000222412606202452023251 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON test_profile.py ######## setup.py ########### from distutils.extension import Extension from distutils.core import setup from Cython.Build import cythonize from Cython.Compiler.Options import directive_defaults directive_defaults['linetrace'] = True directive_defaults['binding'] = True extensions = [ Extension("collatz", ["collatz.pyx"], define_macros=[('CYTHON_TRACE', '1')]) ] setup( ext_modules = cythonize(extensions) ) ######## test_profile.py ########### from collatz import collatz try: import line_profiler except ImportError: print("No line profiler, skipping test.") import sys sys.exit(0) profile = line_profiler.LineProfiler(collatz) profile.runcall(collatz, 19) profile.print_stats() stats = profile.get_stats() assert len(stats.timings) > 0, "No profile stats." for key, timings in stats.timings.items(): if key[-1] == 'collatz': assert len(timings) > 0 break else: raise ValueError("No stats for collatz.") ######## collatz.pyx ########### def collatz(n): while n > 1: if n % 2 == 0: n //= 2 else: n = 3*n+1 Cython-0.23.4/tests/run/libcpp_all.pyx0000644000175600017570000000526712606202452021027 0ustar jenkinsjenkins00000000000000# tag: cpp import cython cimport libcpp cimport libcpp.deque cimport libcpp.list cimport libcpp.map cimport libcpp.pair cimport libcpp.queue cimport libcpp.set cimport libcpp.stack cimport libcpp.vector cimport libcpp.complex from libcpp.deque cimport * from libcpp.list cimport * from libcpp.map cimport * from libcpp.pair cimport * from libcpp.queue cimport * from libcpp.set cimport * from libcpp.stack cimport * from libcpp.vector cimport * from libcpp.complex cimport * cdef libcpp.deque.deque[int] d1 = deque[int]() cdef libcpp.list.list[int] l1 = list[int]() cdef libcpp.map.map[int,int] m1 = map[int,int]() cdef libcpp.pair.pair[int,int] p1 = pair[int,int](1,2) cdef libcpp.queue.queue[int] q1 = queue[int]() cdef libcpp.set.set[int] s1 = set[int]() cdef libcpp.stack.stack[int] t1 = stack[int]() cdef libcpp.vector.vector[int] v1 = vector[int]() cdef deque[int].iterator id1 = d1.begin() cdef deque[int].iterator id2 = d1.end() cdef deque[int].reverse_iterator rid1 = d1.rbegin() cdef deque[int].reverse_iterator rid2 = d1.rend() cdef list[int].iterator il1 = l1.begin() cdef list[int].iterator il2 = l1.end() cdef list[int].reverse_iterator ril1 = l1.rbegin() cdef list[int].reverse_iterator ril2 = l1.rend() cdef map[int,int].iterator im1 = m1.begin() cdef map[int,int].iterator im2 = m1.end() cdef map[int,int].reverse_iterator rim1 = m1.rbegin() cdef map[int,int].reverse_iterator rim2 = m1.rend() cdef pair[map[int,int].iterator, bint] pimb = m1.insert(p1) cdef set[int].iterator is1 = s1.begin() cdef set[int].iterator is2 = s1.end() cdef set[int].reverse_iterator ris1 = s1.rbegin() cdef set[int].reverse_iterator ris2 = s1.rend() cdef pair[set[int].iterator, bint] pisb = s1.insert(4) cdef vector[int].iterator iv1 = v1.begin() cdef vector[int].iterator iv2 = v1.end() cdef vector[int].reverse_iterator riv1 = v1.rbegin() cdef vector[int].reverse_iterator riv2 = v1.rend() def test_vector_coercion(*args): """ >>> test_vector_coercion(1.75) [1.75] >>> test_vector_coercion(1, 10, 100) [1.0, 10.0, 100.0] """ v = new vector[double]() for a in args: v.push_back(a) return [v[0][i] for i in range(v.size())] def test_const_vector(*args): """ >>> test_const_vector(1.75) [1.75] >>> test_const_vector(1, 10, 100) [1.0, 10.0, 100.0] """ cdef vector[double] v for a in args: v.push_back(a) return const_vector_to_list(v) cdef const_vector_to_list(const vector[double]& cv): cdef vector[double].const_iterator iter = cv.const_begin() cdef lst = [] while iter != cv.const_end(): lst.append(cython.operator.dereference(iter)) cython.operator.preincrement(iter) return lst Cython-0.23.4/tests/run/libcpp_algo.pyx0000644000175600017570000000254312606202452021173 0ustar jenkinsjenkins00000000000000# tag: cpp from libcpp cimport bool from libcpp.algorithm cimport make_heap, sort_heap, sort, partial_sort from libcpp.vector cimport vector # XXX should use std::greater, but I don't know how to wrap that. cdef inline bool greater(int x, int y): return x > y def heapsort(l, bool reverse=False): """ >>> heapsort([3, 5, 1, 0, 2, 4]) [0, 1, 2, 3, 4, 5] >>> heapsort([3, 5, 1, 0, 2, 4], reverse=True) [5, 4, 3, 2, 1, 0] """ cdef vector[int] v = l if reverse: make_heap(v.begin(), v.end(), greater) sort_heap(v.begin(), v.end(), greater) else: make_heap(v.begin(), v.end()) sort_heap(v.begin(), v.end()) return v def partialsort(l, int k, reverse=False): """ >>> partialsort([4, 2, 3, 1, 5], k=2)[:2] [1, 2] >>> partialsort([4, 2, 3, 1, 5], k=2, reverse=True)[:2] [5, 4] """ cdef vector[int] v = l if reverse: partial_sort(v.begin(), v.begin() + k, v.end(), greater) else: partial_sort(v.begin(), v.begin() + k, v.end()) return v def stdsort(l, reverse=False): """ >>> stdsort([3, 2, 1, 4, 5]) [1, 2, 3, 4, 5] >>> stdsort([3, 2, 1, 4, 5], reverse=True) [5, 4, 3, 2, 1] """ cdef vector[int] v = l if reverse: sort(v.begin(), v.end(), greater) else: sort(v.begin(), v.end()) return v Cython-0.23.4/tests/run/libc_time.pyx0000644000175600017570000000152412606202452020645 0ustar jenkinsjenkins00000000000000# tag: posix from libc.stdlib cimport getenv from posix.stdlib cimport setenv, unsetenv from libc.time cimport * def test_time(): """ >>> test_time() """ cdef time_t t1, t2 t1 = time(NULL) assert t1 != 0 t1 = time(&t2) assert t1 == t2 def test_mktime(): """ >>> test_mktime() # doctest:+ELLIPSIS (986138177, ...'Sun Apr 1 15:16:17 2001\\n') """ cdef tm t, gmt cdef time_t tt cdef char *ct cdef char *tz tz = getenv("TZ") setenv("TZ", "UTC", 1) tzset() t.tm_sec = 17 t.tm_min = 16 t.tm_hour = 15 t.tm_year = 101 t.tm_mon = 3 t.tm_mday = 1 t.tm_isdst = 0 tt = mktime(&t) assert tt != -1 ct = ctime(&tt) assert ct != NULL if tz: setenv("TZ", tz, 1) else: unsetenv("TZ") tzset() return tt, ct Cython-0.23.4/tests/run/letnode_T766.pyx0000644000175600017570000000101712606202452021073 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 766 # tag: letnode def test_letnode_range(int n): """ >>> [i() for i in test_letnode_range(5)] [0, 1, 2, 3, 4] """ ret = [] for i in range(n): def bar(x=i): return x ret.append(bar) return ret def test_letnode_enumerate(a): """ >>> [i() for i in test_letnode_enumerate("abc")] [0, 1, 2] """ cdef int n ret = [] for n, i in enumerate(a): def bar(x=n): return x ret.append(bar) return ret Cython-0.23.4/tests/run/lepage_1.pyx0000644000175600017570000000057312606202452020376 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> a = A(1,2,3) >>> a[0] 1.0 >>> a[1] 2.0 >>> a[2] 3.0 """ cdef class A: cdef double[3] x def __init__(self, *args): cdef int i, max max = len(args) if max > 3: max = 3 for i from 0 <= i < max: self.x[i] = args[i] def __getitem__(self,i): return self.x[i] Cython-0.23.4/tests/run/large_consts_T237.pyx0000644000175600017570000000067012606202452022121 0ustar jenkinsjenkins00000000000000# ticket: 237 #def add_large_c(): # cdef unsigned long long val = 2**30 + 2**30 # return val def add_large(): """ >>> add_large() == 2147483647 + 2147483647 True #>>> add_large_c() == 2147483647 + 2147483647 #True """ return 2147483647 + 2147483647 def add_large_pow(): """ >>> add_large_pow() == 2**31 + 2**31 True >>> add_large_pow() == 2**32 True """ return 2**31 + 2**31 Cython-0.23.4/tests/run/language_level.srctree0000644000175600017570000000144212606202452022516 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import directive2; import directive3" PYTHON -c "import infile2; import infile3" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = (cythonize("infile*.py") + cythonize("directive2.py", compiler_directives={'language_level': 2}) + cythonize("directive3.py", compiler_directives={'language_level': 3}) ) ) ######## directive3.py ######## import sys print("SUCCESS", file=sys.stdout) ######## directive2.py ######## print "SUCCESS" ######## infile3.py ######## # cython: language_level=3 import sys print("SUCCESS", file=sys.stdout) ######## infile2.py ######## # cython: language_level=2 print "SUCCESS" Cython-0.23.4/tests/run/lambda_tests.pyx0000644000175600017570000002562212606202452021365 0ustar jenkinsjenkins00000000000000# mode: run # tag: closures, lambda # Battery of tests for closures in Cython. Based on the collection of # compiler tests from P423/B629 at Indiana University, Spring 1999 and # Fall 2000. Special thanks to R. Kent Dybvig, Dan Friedman, Kevin # Millikin, and everyone else who helped to generate the original # tests. Converted into a collection of Python/Cython tests by Craig # Citro. # # Note: This set of tests is split (somewhat randomly) into several # files, simply because putting all the tests in a single file causes # gcc and g++ to buckle under the load. # def g0(): """ >>> g0() 4000 """ return (lambda y_1: y_1)(4000) def g1(): """ >>> g1() 1 """ f_3 = (lambda x_2: x_2) return (f_3(0)+1) def g2(): """ >>> g2() 4 """ f_5 = (lambda y_4: y_4) return f_5(f_5(4)) def g3(): """ >>> g3() 4 """ return (lambda f_7: f_7(f_7(4)))((lambda y_6: y_6)) def g5(): """ >>> g5() 9000 """ def g4(): a_8 = 4000 return lambda b_9: ((a_8)+(b_9)) return g4()(5000) def g6(): """ >>> g6() 9000 """ return (lambda a_10: (lambda b_11: (a_10)+(b_11)))(4000)(5000) def g7(): """ >>> g7() 2 """ return (lambda f_13: f_13(f_13(0)))((lambda x_12: (x_12+1))) def g8(): """ >>> g8() 0 """ f_16 = (lambda x_15, y_14: x_15) a_17 = f_16(0, 1) return f_16(a_17, a_17) def g10(): """ >>> g10() 3 """ f_19 = (lambda x_18: x_18) def g9(): a_22 = 0 b_21 = 1 c_20 = 2 return (f_19(a_22))+((f_19(b_21))+(f_19(c_20))) return (f_19(0))+(g9()) def g12(): """ >>> g12() 2 """ def g11(): x_23 = 1 return lambda y_24: ((x_23)+(y_24)) f_25 = g11() x_26 = 0 return f_25(f_25(x_26)) def g14(): """ >>> g14() 3050 """ def g13(): t_29 = (lambda x_28: (x_28)+(50)) return lambda f_30: (t_29(f_30(1000))) return g13()((lambda y_27: (y_27)+(2000))) def g15(): """ >>> g15() 3050 """ return (lambda t_33: (lambda f_34: t_33(f_34(1000))))((lambda x_32: (x_32)+(50)))((lambda y_31: (y_31)+(2000))) def g17(): """ >>> g17() 2050 """ def g16(): t_35 = 50 return lambda f_36: ((t_35)+(f_36())) return g16()((lambda : 2000)) def g18(): """ >>> g18() 2050 """ return (lambda t_37: (lambda f_38: (t_37)+(f_38())))(50)((lambda : 2000)) def g20(): """ >>> g20() 700 """ def g19(): x_39 = 300 return lambda y_40: ((x_39)+(y_40)) return g19()(400) def g21(): """ >>> g21() 0 """ x_44 = 3 f_43 = (lambda x_42, y_41: x_42) if (f_43(0, 0)): return f_43(f_43(0, 0), x_44) else: return 0 def g22(): """ >>> g22() False """ f_46 = (lambda x_45: (x_45) if (((not ((x_45[0]) == 0))) if (isinstance(x_45, list)) else (False)) else (False)) return f_46([0,[0,[]]]) def g23(): """ >>> g23() False """ f_48 = (lambda x_47: (x_47) if (((not ((not ((x_47[0]) == 0))) if (isinstance(x_47, list)) else (False))) if (x_47) else (False)) else (False)) return f_48(0) def g24(): """ >>> g24() [] """ f_50 = (lambda x_49: (x_49) if ((True) if (isinstance(x_49, list)) else ((x_49 == []))) else ([])) return f_50(0) def g25(): """ >>> g25() 0 """ y_51 = 4 f_54 = (lambda x_53, y_52: 0) return f_54(f_54(y_51, y_51), f_54(y_51, y_51)) def g26(): """ >>> g26() 0 """ y_55 = 4 f_58 = (lambda x_57, y_56: 0) return f_58(f_58(y_55, f_58(y_55, y_55)), f_58(y_55, f_58(y_55, y_55))) def g27(): """ >>> g27() 4 """ return (lambda y_59: (lambda f_61: f_61(f_61(y_59)))((lambda y_60: y_60)))(4) def g28(): """ >>> g28() 23 """ f_63 = (lambda x_62: x_62) return ((1) if (False) else (f_63(22))+1) def g29(): """ >>> g29() 5061 """ f_68 = (lambda x_65: ((not x_65)) if (x_65) else (x_65)) f2_67 = (lambda x_64: (10)*(x_64)) x_66 = 23 return ((1) if (f_68(x_66 == 0)) else ((x_66)*(f2_67((x_66-1))))+1) def g30(): """ >>> g30() 1 """ one_69 = (lambda n_70: (1) if (n_70 == 0) else (one_69((n_70-1)))) return one_69(13) def g31(): """ >>> g31() True """ even_72 = (lambda x_74: (True) if (x_74 == 0) else (odd_71((x_74-1)))) odd_71 = (lambda x_73: (False) if (x_73 == 0) else (even_72((x_73-1)))) return odd_71(13) def g32(): """ >>> g32() False """ even_76 = (lambda x_78: (True) if (x_78 == 0) else (odd_75((x_78-1)))) odd_75 = (lambda x_77: (False) if (x_77 == 0) else (even_76((x_77-1)))) return even_76(13) def g34(): """ >>> g34() True """ even_80 = (lambda x_79: x_79) def g33(): even_82 = (lambda x_84: (True) if (x_84 == 0) else (odd_81((x_84-1)))) odd_81 = (lambda x_83: (False) if (x_83 == 0) else (even_82((x_83-1)))) return odd_81(13) return even_80(g33()) def g35(): """ >>> g35() 120 """ fact_85 = (lambda n_86: (1) if (n_86 == 0) else ((n_86)*(fact_85((n_86-1))))) return fact_85(5) def g38(): """ >>> g38() 10 """ x_87 = 5 a_90 = (lambda u_101, v_100, w_99: (b_89(v_100, w_99)) if (u_101 == 0) else (a_90((u_101)-(1), v_100, w_99))) def g37(): def g36(q_93, r_92): p_94 = (q_93)*(r_92) e_96 = (lambda n_98: (c_88(p_94)) if (n_98 == 0) else (o_95((n_98)-(1)))) o_95 = (lambda n_97: (c_88(x_87)) if (n_97 == 0) else (e_96((n_97)-(1)))) return e_96((q_93)*(r_92)) return g36 b_89 = g37() c_88 = (lambda x_91: (5)*(x_91)) return a_90(3, 2, 1) def g39(): """ >>> g39() 120 """ fact_104 = (lambda fact_103, n_102: (1) if (n_102 == 0) else ((fact_103(fact_103, (n_102-1)))*(n_102))) return fact_104(fact_104, 5) def g40(): """ >>> g40() 35 """ return (lambda x_105: (lambda y_106: (lambda z_107: (lambda w_108: (lambda u_109: (x_105)+((y_106)+((z_107)+((w_108)+(u_109)))))))))(5)(6)(7)(8)(9) def g41(): """ >>> g41() 6 """ sum_112 = (lambda sum_111, ls_110: (0) if ((ls_110 == [])) else (((ls_110[0]))+(sum_111(sum_111, (ls_110[1]))))) return sum_112(sum_112, [1,[2,[3,[]]]]) def g46(): """ >>> g46() 1500 """ def g45(): def g44(): def g42(a_113): def g43(): (a_113)+(200 if True else None) return 1500 return g43 return g42 return g44()(1000) return g45()() def g53(): """ >>> g53() 2600 """ def g52(): def g51(): def g50(): def g47(a_114): def g48(b_115): a_114 = 200 if b_115 else None def g49(c_116): c_116 = 400 if 300 else None return (a_114)+((b_115)+(c_116)) return g49 return g48 return g47 return g50()(1000) return g51()(2000) return g52()(3000) def g54(): """ >>> g54() 5 """ return (lambda f_118: f_118(f_118(5)))((lambda x_117: x_117)) def g56(): """ >>> g56() 8000 """ def g55(): f_120 = (lambda x_119: (x_119)+(3000)) return lambda y_121: (f_120(f_120(y_121))) return g55()(2000) def g57(): """ >>> g57() 120 """ fact_125 = (lambda fact_124, n_123, acc_122: (acc_122) if (n_123 == 0) else (fact_124(fact_124, (n_123-1), (n_123)*(acc_122)))) return fact_125(fact_125, 5, 1) def g58(): """ >>> g58() 3 """ f_127 = (lambda x_126: (lambda : x_126())) return f_127((lambda : 3))() def g59(): """ >>> g59() 22 """ f_129 = (lambda x_132: (x_132)+((lambda y_133: (lambda z_134: (y_133)+(z_134)))(6)(7))) g_128 = (5)+((lambda w_131, u_130: (w_131)+(u_130))(8, 9)) return g_128 def g60(): """ >>> g60() 0 """ loop_135 = (lambda : (lambda : loop_135())) loop_135() return 0 def g63(): """ >>> g63() 668 """ def g62(): def g61(): loop_137 = (lambda link_138: (lambda : link_138())) return loop_137((lambda : 668)) return g61 f_136 = g62() return f_136()() def g64(): """ >>> g64() 17 """ k_141 = (lambda x_140, y_139: x_140) b_142 = 17 return k_141(k_141(k_141, 37), 37)(b_142, (b_142)*(b_142)) def g65(): """ >>> g65() 37 """ f_145 = (lambda g_144, u_143: g_144((g_144(37)) if (u_143) else (u_143))) return f_145((lambda x_146: x_146), 75) def g66(): """ >>> g66() 4687 """ f_150 = (lambda h_148, u_147: h_148((h_148((u_147)+(37))) if (u_147) else (u_147))) w_149 = 62 return f_150((lambda x_151: (w_149)-(x_151)), (75)*(w_149)) def g67(): """ >>> g67() True """ t_153 = True f_152 = False bools_156 = [t_153,f_152] id_155 = (lambda x_154: (f_152) if ((not x_154)) else (t_153)) even_158 = (lambda x_160: ((bools_156[0])) if (id_155(x_160 == 0)) else (odd_157((x_160)-(1)))) odd_157 = (lambda y_159: (id_155((bools_156[1]))) if (y_159 == 0) else (even_158((y_159)-(1)))) return odd_157(5) def g68(): """ >>> g68() 5 """ f_162 = (lambda x_164: (x_164)+(1)) g_161 = (lambda y_163: f_162(f_162(y_163))) return (f_162(1))+(g_161(1)) def g69(): """ >>> g69() 1521 """ y_165 = 3 f_168 = (lambda x_171: (g_167((x_171)+(1))) if (x_171 == 0) else (f_168((x_171)-(y_165)))) g_167 = (lambda x_170: h_166((x_170)*(x_170))) h_166 = (lambda x_169: x_169) return g_167(39) def g70(): """ >>> g70() -1 """ f_173 = (lambda x_175: (x_175)+(1)) g_172 = (lambda y_174: f_173(f_173(y_174))) f_173 = (lambda x_176: (x_176)-(1)) return (f_173(1))+(g_172(1)) def g71(): """ >>> g71() [52, [17, [35, [17, 35]]]] """ f_180 = (lambda : (a_179)+(b_178)) a_179 = 17 b_178 = 35 h_177 = [(lambda : a_179),(lambda : b_178)] return [f_180(),[a_179,[b_178,[(h_177[0])(),(h_177[1])()]]]] def g73(): """ >>> g73() 120 """ x_183 = 5 def g72(): a_181 = 1 return lambda : (a_181) th_182 = g72() fact_184 = (lambda n_186, th_185: (th_185()) if (n_186 == 0) else ((n_186)*(fact_184((n_186)-(1), th_185)))) return fact_184(x_183, th_182) def g74(): """ >>> g74() [120, -120] """ negative_188 = (lambda n_187: (n_187 < 0)) fact_190 = (lambda n_192: (1) if (n_192 == 0) else ((n_192)*(fact_190((n_192)-(1))))) call_fact_189 = (lambda n_191: (fact_190(n_191)) if ((not negative_188(n_191))) else ((0)-(fact_190((0)-(n_191))))) return [call_fact_189(5),call_fact_189(-5)] def g75(): """ >>> g75() [[33, 55], [77, 99]] """ return (lambda a_193: (lambda b_194: (lambda c_195: (lambda d_196: [[a_193,b_194],[c_195,d_196]]))))(33)(55)(77)(99) Cython-0.23.4/tests/run/lambda_module_T603.pyx0000644000175600017570000000067012606202452022220 0ustar jenkinsjenkins00000000000000# mode: run # tag: lambda # ticket: 603 # Module scope lambda functions __doc__ = """ >>> pow2(16) 256 >>> with_closure(0) 0 >>> typed_lambda(1)(2) 3 >>> typed_lambda(1.5)(1.5) 2 >>> cdef_const_lambda() 123 >>> const_lambda() 321 """ pow2 = lambda x: x * x with_closure = lambda x:(lambda: x)() typed_lambda = lambda int x : (lambda int y: x + y) cdef int xxx = 123 cdef_const_lambda = lambda: xxx yyy = 321 const_lambda = lambda: yyy Cython-0.23.4/tests/run/lambda_class_T605.pyx0000644000175600017570000000130412606202452022035 0ustar jenkinsjenkins00000000000000# mode: run # tag: lambda # ticket: 605 cdef int cdef_CONST = 123 CONST = 456 cdef class Foo: """ >>> obj = Foo() >>> obj.id(123) 123 >>> obj.cconst_mul(1) 123 >>> obj.const_mul(1) 456 >>> obj.foo[0](1) 1 """ id = lambda self, x: x cconst_mul = lambda self, x: x * cdef_CONST const_mul = lambda self, x: x * CONST foo = (lambda x:x,) class Bar: """ >>> obj = Bar() >>> obj.id(123) 123 >>> obj.cconst_mul(1) 123 >>> obj.const_mul(1) 456 >>> obj.foo[0](1) 1 """ id = lambda self, x: x cconst_mul = lambda self, x: x * cdef_CONST const_mul = lambda self, x: x * CONST foo = (lambda x:x,) Cython-0.23.4/tests/run/lambda_T723.pyx0000644000175600017570000000022412606202452020651 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 723 # tag: lambda def t723(a): """ >>> t723(2)() 4 >>> t723(2)(3) 9 """ return lambda x=a: x * x Cython-0.23.4/tests/run/lambda_T195.pyx0000644000175600017570000000414412606202452020661 0ustar jenkinsjenkins00000000000000# mode: run # tag: lambda # ticket: 195 __doc__ = u""" #>>> py_identity = lambda x:x #>>> py_identity(1) == cy_identity(1) #True """ #cy_identity = lambda x:x def make_identity(): """ >>> idcall = make_identity() >>> idcall(1) 1 >>> idcall(2) 2 """ return lambda x:x def make_const0(x): """ >>> make_const0(1)() 1 """ return lambda :x def make_const1(x): """ >>> make_const1(1)(2) 1 >>> make_const1(1)(2) 1 """ return lambda _:x def make_const_calc0(): """ >>> make_const_calc0()() 11 """ return lambda : 1*2*3+5 def make_const_calc1(): """ >>> make_const_calc1()(2) 11 """ return lambda _: 1*2*3+5 def make_const_calc1_xy(x): """ >>> make_const_calc1_xy(8)(2) 27 """ return lambda y: x*y+(1*2*3+5) def make_lambda_lambda(x): """ >>> make_lambda_lambda(1)(2)(4) 7 """ return lambda y : \ lambda z:x+y+z def make_typed_lambda_lambda(int x): """ >>> make_typed_lambda_lambda(1)(2)(4) 7 >>> partial_lambda = make_typed_lambda_lambda(1)(2) >>> partial_lambda(4) 7 >>> partial_lambda(5) 8 """ return lambda int y : \ lambda int z:x+y+z def pass_lambda(f): """ >>> def f(a, lfunc): return lfunc(a,2) >>> pass_lambda(f) 12 """ return f(1, lambda a, b : a*10+b) def pass_lambda_with_args(f): """ >>> def f(a, lfunc): return lfunc(a,2,3) >>> pass_lambda_with_args(f) 123 """ return f(1, lambda a, *args : (a*10 + args[0])*10 + args[1]) def pass_lambda_with_args_kwargs(f): """ >>> def f(a, lfunc): return lfunc(a,2,3, b=4) >>> pass_lambda_with_args_kwargs(f) 1234 """ return f(1, lambda a, *args, **kwargs : ((a*10 + args[0])*10 + args[1])*10 + kwargs['b']) def pass_lambda_with_args_kwargs_kwonly_args(f): """ >>> def f(a, lfunc): return lfunc(a,2,3, b=4, c=5) >>> pass_lambda_with_args_kwargs_kwonly_args(f) 12345 """ return f(1, lambda a, *args, b, **kwargs : (((a*10 + args[0])*10 + args[1])*10 + b)*10 + kwargs['c']) Cython-0.23.4/tests/run/kwonlyargscall.pyx0000644000175600017570000001224412606202452021753 0ustar jenkinsjenkins00000000000000# the calls: def call0ab(f): """ >>> call0ab(b) Traceback (most recent call last): TypeError: b() takes exactly 3 positional arguments (2 given) >>> call0ab(c) 1 2 1 >>> call0ab(d) 1 2 88 """ f(a=1,b=2) def call0abc(f): """ >>> call0abc(b) 1 2 3 >>> call0abc(c) 1 2 3 >>> call0abc(d) 1 2 3 >>> call0abc(e) 1 2 3 [] >>> call0abc(f) 1 2 3 42 >>> call0abc(m) 1 2 3 """ f(a=1,b=2,c=3) def call2(f): """ >>> call2(c) 1 2 1 >>> call2(d) 1 2 88 >>> call2(e) 1 2 88 [] >>> call2(f) Traceback (most recent call last): TypeError: f() needs keyword-only argument c >>> call2(g) Traceback (most recent call last): TypeError: g() needs keyword-only argument c >>> call2(m) Traceback (most recent call last): TypeError: m() needs keyword-only argument c """ f(1,2) def call3(f): """ >>> call3(b) 1 2 3 >>> call3(c) 1 2 3 >>> call3(d) Traceback (most recent call last): TypeError: d() takes exactly 2 positional arguments (3 given) >>> call3(e) 1 2 3 [] >>> call3(f) Traceback (most recent call last): TypeError: f() takes exactly 2 positional arguments (3 given) >>> call3(g) Traceback (most recent call last): TypeError: g() takes exactly 2 positional arguments (3 given) >>> call3(h) Traceback (most recent call last): TypeError: h() needs keyword-only argument c >>> call3(k) Traceback (most recent call last): TypeError: k() needs keyword-only argument f >>> call3(m) Traceback (most recent call last): TypeError: m() takes at most 2 positional arguments (3 given) """ f(1,2,3) def call4(f): """ >>> call4(b) Traceback (most recent call last): TypeError: b() takes exactly 3 positional arguments (4 given) >>> call4(c) Traceback (most recent call last): TypeError: c() takes at most 3 positional arguments (4 given) >>> call4(e) Traceback (most recent call last): TypeError: e() takes at most 3 positional arguments (4 given) """ f(1,2,3,4) def call2c(f): """ >>> call2c(d) 1 2 1 >>> call2c(e) 1 2 1 [] >>> call2c(f) 1 2 1 42 >>> call2c(g) Traceback (most recent call last): TypeError: g() needs keyword-only argument f >>> call2c(m) 1 2 1 """ f(1,2, c=1) def call2d(f): """ >>> call2d(d) Traceback (most recent call last): TypeError: d() got an unexpected keyword argument 'd' >>> call2d(e) 1 2 88 [('d', 1)] >>> call2d(k) Traceback (most recent call last): TypeError: k() needs keyword-only argument f """ f(1,2, d=1) def call3d(f): """ >>> call3d(h) Traceback (most recent call last): TypeError: h() needs keyword-only argument c """ f(1,2,3, d=1) def call2cd(f): """ >>> call2cd(f) 1 2 1 2 >>> call2cd(m) Traceback (most recent call last): TypeError: m() got an unexpected keyword argument 'd' """ f(1,2, c=1, d=2) def call2ce(f): """ >>> call2ce(f) Traceback (most recent call last): TypeError: f() got an unexpected keyword argument 'e' """ f(1,2, c=1, e=2) def call2cde(f): """ >>> call2cde(e) 1 2 1 [('d', 2), ('e', 3)] """ f(1,2, c=1, d=2, e=3) def call2cf(f): """ >>> call2cf(g) 1 2 1 42 17 2 [] >>> call2cf(h) 1 2 1 42 17 2 () [] >>> call2cf(k) 1 2 1 42 17 2 () [] """ f(1,2, c=1, f=2) def call6cf(f): """ >>> call6cf(h) 1 2 1 42 17 2 (3, 4, 5, 6) [] """ f(1,2,3,4,5,6, c=1, f=2) def call6df(f): """ >>> call6df(k) 1 2 3 1 17 2 (4, 5, 6) [] """ f(1,2,3,4,5,6, d=1, f=2) def call2cfe(f): """ >>> call2cfe(h) 1 2 1 42 3 2 () [] >>> call2cfe(k) 1 2 1 42 3 2 () [] """ f(1,2, c=1, f=2, e=3) def call2cefd(f): """ >>> call2cefd(g) 1 2 1 11 0 2 [] """ f(1,2, c=1, e=0, f=2, d=11) def call2cfex(f): """ >>> call2cfex(g) 1 2 1 42 0 2 [('x', 25)] """ f(1,2, c=1, f=2, e=0, x=25) def call6argscfexy(f): args = (1,2,3,4,5,6) f(*args, c=1, f=2, e=3, x=25, y=11) def call6cfexy(f): """ >>> call6cfexy(h) 1 2 1 42 3 2 (3, 4, 5, 6) [('x', 25), ('y', 11)] """ f(1,2,3,4,5,6, c=1, f=2, e=3, x=25, y=11) def call6dfexy(f): """ >>> call6dfexy(k) 1 2 3 1 3 2 (4, 5, 6) [('x', 25), ('y', 11)] """ f(1,2,3,4,5,6, d=1, f=2, e=3, x=25, y=11) # the called functions: def b(a, b, c): print a,b,c def c(a, b, c=1): print a,b,c def d(a, b, *, c = 88): print a,b,c def e(a, b, c = 88, **kwds): kwlist = list(kwds.items()) kwlist.sort() print a,b,c, kwlist def f(a, b, *, c, d = 42): print a,b,c,d def g(a, b, *, c, d = 42, e = 17, f, **kwds): kwlist = list(kwds.items()) kwlist.sort() print a,b,c,d,e,f, kwlist def h(a, b, *args, c, d = 42, e = 17, f, **kwds): kwlist = list(kwds.items()) kwlist.sort() print a,b,c,d,e,f, args, kwlist def k(a, b, c=1, *args, d = 42, e = 17, f, **kwds): kwlist = list(kwds.items()) kwlist.sort() print a,b,c,d,e,f, args, kwlist def m(a, b=1, *, c): print a,b,c Cython-0.23.4/tests/run/kwonlyargs.pyx0000644000175600017570000000722112606202452021116 0ustar jenkinsjenkins00000000000000def b(a, b, c): """ >>> b(1,2,3) >>> b(1,2,3,4) Traceback (most recent call last): TypeError: b() takes exactly 3 positional arguments (4 given) """ a, b, c = b, c, a def c(a, b, c=1): """ >>> c(1,2) >>> c(1,2,3) >>> c(1,2,3,4) Traceback (most recent call last): TypeError: c() takes at most 3 positional arguments (4 given) """ a, b, c = b, c, a def d(a, b, *, c = 88): """ >>> d(1,2) >>> d(1,2, c=1) >>> d(1,2,3) Traceback (most recent call last): TypeError: d() takes exactly 2 positional arguments (3 given) >>> d(1,2, d=1) Traceback (most recent call last): TypeError: d() got an unexpected keyword argument 'd' """ a, b, c = b, c, a def e(a, b, c = 88, **kwds): """ >>> e(1,2) >>> e(1,2, c=1) >>> e(1,2, d=1) >>> e(1,2, c=1, d=2, e=3) >>> e(1,2,3) >>> e(1,2,3,4) Traceback (most recent call last): TypeError: e() takes at most 3 positional arguments (4 given) """ a, b, c = b, c, a def f(a, b, *, c, d = 42): """ >>> f(1,2, c=1) >>> f(1,2, c=1, d=2) >>> f(1,2,3) Traceback (most recent call last): TypeError: f() takes exactly 2 positional arguments (3 given) >>> f(1,2) Traceback (most recent call last): TypeError: f() needs keyword-only argument c >>> f(1,2, c=1, e=2) Traceback (most recent call last): TypeError: f() got an unexpected keyword argument 'e' """ a, b, c, d = b, c, d, a def g(a, b, *, c, d = 42, e = 17, f, **kwds): """ >>> g(1,2, c=1, f=2) >>> g(1,2, c=1, e=0, f=2, d=11) >>> g(1,2, c=1, f=2, e=0, x=25) >>> g(1,2,3) Traceback (most recent call last): TypeError: g() takes exactly 2 positional arguments (3 given) >>> g(1,2) Traceback (most recent call last): TypeError: g() needs keyword-only argument c >>> g(1,2, c=1) Traceback (most recent call last): TypeError: g() needs keyword-only argument f """ a, b, c, d, e, f = b, c, d, e, f, a def h(a, b, *args, c, d = 42, e = 17, f, **kwds): """ >>> h(1,2, c=1, f=2) >>> h(1,2, c=1, f=2, e=3) >>> h(1,2,3,4,5,6, c=1, f=2) >>> h(1,2,3,4,5,6, c=1, f=2, e=3, x=25, y=11) >>> h(1,2,3) Traceback (most recent call last): TypeError: h() needs keyword-only argument c >>> h(1,2, d=1) Traceback (most recent call last): TypeError: h() needs keyword-only argument c """ a, b, c, d, e, f = b, c, d, e, f, a def k(a, b, c=1, *args, d = 42, e = 17, f, **kwds): """ >>> k(1,2, c=1, f=2) >>> k(1,2, c=1, f=2, e=3) >>> k(1,2,3,4,5,6, d=1, f=2) >>> k(1,2,3,4,5,6, d=1, f=2, e=3, x=25, y=11) >>> k(1,2,3) Traceback (most recent call last): TypeError: k() needs keyword-only argument f >>> k(1,2, d=1) Traceback (most recent call last): TypeError: k() needs keyword-only argument f """ a, b, c, d, e, f = b, c, d, e, f, a def l(*, a, b, c = 88): """ >>> l(a=1, b=2) >>> l(a=1, b=2, c=1) >>> l(1,2,3) Traceback (most recent call last): TypeError: l() takes exactly 0 positional arguments (3 given) >>> l(1,2, d=1) Traceback (most recent call last): TypeError: l() takes exactly 0 positional arguments (2 given) >>> l(1,2,3) Traceback (most recent call last): TypeError: l() takes exactly 0 positional arguments (3 given) >>> l(1,2, d=1) Traceback (most recent call last): TypeError: l() takes exactly 0 positional arguments (2 given) """ a, b, c = b, c, a def m(a, *, b, c = 88): """ >>> m(1, b=2) >>> m(a=1, b=2) >>> m(a=1, b=2, c=1) """ a, b, c = b, c, a def n(a, *, b, c = 88): a, b, c = b, c, a Cython-0.23.4/tests/run/kwargs_passthrough.pyx0000644000175600017570000001074712606202452022652 0ustar jenkinsjenkins00000000000000cimport cython @cython.test_fail_if_path_exists('//MergedDictNode') def wrap_passthrough(f): """ >>> def f(a=1): return a >>> wrapped = wrap_passthrough(f) >>> wrapped(1) CALLED 1 >>> wrapped(a=2) CALLED 2 """ def wrapper(*args, **kwargs): print("CALLED") return f(*args, **kwargs) return wrapper @cython.test_fail_if_path_exists('//MergedDictNode') def unused(*args, **kwargs): """ >>> unused() () >>> unused(1, 2) (1, 2) """ return args @cython.test_fail_if_path_exists('//MergedDictNode') def used_in_closure(**kwargs): """ >>> used_in_closure() >>> d = {} >>> used_in_closure(**d) >>> d # must not be modified {} """ def func(): kwargs['test'] = 1 return func() @cython.test_fail_if_path_exists('//MergedDictNode') def modify_in_closure(**kwargs): """ >>> func = modify_in_closure() >>> func() >>> d = {} >>> func = modify_in_closure(**d) >>> func() >>> d # must not be modified {} """ def func(): kwargs['test'] = 1 return func @cython.test_assert_path_exists('//MergedDictNode') def wrap_passthrough_more(f): """ >>> def f(a=1, test=2): ... return a, test >>> wrapped = wrap_passthrough_more(f) >>> wrapped(1) CALLED (1, 1) >>> wrapped(a=2) CALLED (2, 1) """ def wrapper(*args, **kwargs): print("CALLED") return f(*args, test=1, **kwargs) return wrapper @cython.test_fail_if_path_exists('//MergedDictNode') def wrap_passthrough2(f): """ >>> def f(a=1): return a >>> wrapped = wrap_passthrough2(f) >>> wrapped(1) CALLED 1 >>> wrapped(a=2) CALLED 2 """ def wrapper(*args, **kwargs): print("CALLED") f(*args, **kwargs) return f(*args, **kwargs) return wrapper @cython.test_fail_if_path_exists('//MergedDictNode') def wrap_modify(f): """ >>> def f(a=1, test=2): ... return a, test >>> wrapped = wrap_modify(f) >>> wrapped(1) CALLED (1, 1) >>> wrapped(a=2) CALLED (2, 1) >>> wrapped(a=2, test=3) CALLED (2, 1) """ def wrapper(*args, **kwargs): print("CALLED") kwargs['test'] = 1 return f(*args, **kwargs) return wrapper @cython.test_fail_if_path_exists('//MergedDictNode') def wrap_modify_mix(f): """ >>> def f(a=1, test=2): ... return a, test >>> wrapped = wrap_modify_mix(f) >>> wrapped(1) CALLED (1, 1) >>> wrapped(a=2) CALLED (2, 1) >>> wrapped(a=2, test=3) CALLED (2, 1) """ def wrapper(*args, **kwargs): print("CALLED") f(*args, **kwargs) kwargs['test'] = 1 return f(*args, **kwargs) return wrapper @cython.test_assert_path_exists('//MergedDictNode') def wrap_modify_func(f): """ >>> def f(a=1, test=2): ... return a, test >>> wrapped = wrap_modify_func(f) >>> wrapped(1) CALLED (1, 1) >>> wrapped(a=2) CALLED (2, 1) >>> wrapped(a=2, test=3) CALLED (2, 1) """ def modify(kw): kw['test'] = 1 return kw def wrapper(*args, **kwargs): print("CALLED") return f(*args, **modify(kwargs)) return wrapper @cython.test_assert_path_exists('//MergedDictNode') def wrap_modify_func_mix(f): """ >>> def f(a=1, test=2): ... return a, test >>> wrapped = wrap_modify_func_mix(f) >>> wrapped(1) CALLED (1, 1) >>> wrapped(a=2) CALLED (2, 1) >>> wrapped(a=2, test=3) CALLED (2, 1) """ def modify(kw): kw['test'] = 1 return kw def wrapper(*args, **kwargs): print("CALLED") f(*args, **kwargs) return f(*args, **modify(kwargs)) return wrapper @cython.test_fail_if_path_exists('//MergedDictNode') def wrap_reassign(f): """ >>> def f(a=1, test=2): ... return a, test >>> wrapped = wrap_reassign(f) >>> wrapped(1) CALLED (1, 1) >>> wrapped(a=2) CALLED (1, 1) >>> wrapped(a=2, test=3) CALLED (1, 1) """ def wrapper(*args, **kwargs): print("CALLED") kwargs = {'test': 1} return f(*args, **kwargs) return wrapper @cython.test_fail_if_path_exists('//MergedDictNode') def kwargs_metaclass(**kwargs): """ >>> K = kwargs_metaclass() >>> K = kwargs_metaclass(metaclass=type) """ class K(**kwargs): pass return K Cython-0.23.4/tests/run/kwargproblems.pyx0000644000175600017570000000057412606202452021601 0ustar jenkinsjenkins00000000000000 def test(**kw): """ >>> d = {1 : 2} >>> test(**d) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...keywords must be strings >>> d {1: 2} >>> d = {} >>> test(**d) {'arg': 3} >>> d {} >>> d = {'arg' : 2} >>> test(**d) {'arg': 3} >>> d {'arg': 2} """ kw['arg'] = 3 return kw Cython-0.23.4/tests/run/kostyrka2.pyx0000644000175600017570000000013512606202452020644 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> x = X() >>> x.slots [''] """ class X: slots = ["", ] Cython-0.23.4/tests/run/kostyrka.pyx0000644000175600017570000000020112606202452020554 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> t = TEST() >>> 1 in t True """ cdef class TEST: def __contains__(self, x): return 42 Cython-0.23.4/tests/run/knuth_man_or_boy_test.pyx0000644000175600017570000000223112606202452023306 0ustar jenkinsjenkins00000000000000# mode: run # tag: closures # Cython version of Knuth's "man or boy" test -- "It separates the man # Algol 60 compilers from the boy Algol 60 compilers." Here's the # original (from wikipedia): # # begin # real procedure A (k, x1, x2, x3, x4, x5); # value k; integer k; # begin # real procedure B; # begin k:= k - 1; # B:= A := A (k, B, x1, x2, x3, x4); # end; # if k <= 0 then A:= x4 + x5 else B; # end; # outreal (A (10, 1, -1, -1, 1, 0)); # end; # # and a table of values: # # k A # 0 1 # 1 0 # 2 -2 # 3 0 # 4 1 # 5 0 # 6 1 # 7 -1 # 8 -10 # 9 -30 # 10 -67 # # Past 10 or so, we blow the C stack -- can't just set a higher recursion limit # to get around that one. # def compute(val): if isinstance(val, int): return val else: return val() def a(in_k, x1, x2, x3, x4, x5): """ >>> import sys >>> sys.setrecursionlimit(1350) >>> a(10, 1, -1, -1, 1, 0) -67 """ k = [in_k] def b(): k[0] -= 1 return a(k[0], b, x1, x2, x3, x4) return compute(x4) + compute(x5) if k[0] <= 0 else b() Cython-0.23.4/tests/run/king1.pyx0000644000175600017570000000051512606202452017726 0ustar jenkinsjenkins00000000000000DEF USTUFF = u"Spam" def uf(): """ >>> uf() It works! """ IF USTUFF == u"Spam": print "It works!" ELSE: print "Doesn't work" DEF BSTUFF = b"Spam" def bf(): """ >>> bf() It works! """ IF BSTUFF == b"Spam": print "It works!" ELSE: print "Doesn't work" Cython-0.23.4/tests/run/jarausch1.pyx0000644000175600017570000000043012606202452020572 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> b == br'\\\\' True >>> s == r'\\\\' True >>> u == ur'\\\\' True """ import sys if sys.version_info[0] < 3: __doc__ = __doc__.replace(u" br'", u" r'") else: __doc__ = __doc__.replace(u" ur'", u" r'") b = br'\\' s = r'\\' u = ur'\\' Cython-0.23.4/tests/run/iterdict.pyx0000644000175600017570000003201712606202452020526 0ustar jenkinsjenkins00000000000000 cimport cython dict_size = 4 d = dict(zip(range(10,dict_size+10), range(dict_size))) def dict_iteritems(dict d): """ >>> it = dict_iteritems(d) >>> type(it) is list False >>> sorted(it) [(10, 0), (11, 1), (12, 2), (13, 3)] """ return d.iteritems() def dict_iterkeys(dict d): """ >>> it = dict_iterkeys(d) >>> type(it) is list False >>> sorted(it) [10, 11, 12, 13] """ return d.iterkeys() def dict_itervalues(dict d): """ >>> it = dict_itervalues(d) >>> type(it) is list False >>> sorted(it) [0, 1, 2, 3] """ return d.itervalues() @cython.test_fail_if_path_exists( "//WhileStatNode") def items(dict d): """ >>> items(d) [(10, 0), (11, 1), (12, 2), (13, 3)] """ l = [] for k,v in d.items(): l.append((k,v)) l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def iteritems(dict d): """ >>> iteritems(d) [(10, 0), (11, 1), (12, 2), (13, 3)] >>> iteritems({}) [] """ l = [] for k,v in d.iteritems(): l.append((k,v)) l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def optimistic_iteritems(d): """ >>> optimistic_iteritems(d) [(10, 0), (11, 1), (12, 2), (13, 3)] >>> optimistic_iteritems({}) [] >>> class mydict(object): ... def __init__(self, t): self.t = t ... def iteritems(self): return self.t(d.items()) >>> optimistic_iteritems(mydict(list)) [(10, 0), (11, 1), (12, 2), (13, 3)] >>> optimistic_iteritems(mydict(tuple)) [(10, 0), (11, 1), (12, 2), (13, 3)] >>> optimistic_iteritems(mydict(iter)) [(10, 0), (11, 1), (12, 2), (13, 3)] """ l = [] for k,v in d.iteritems(): l.append((k,v)) l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def iteritems_dict(): """ >>> iteritems_dict() [(11, 1), (12, 2), (13, 3)] """ l = [] for k,v in {11 : 1, 12 : 2, 13 : 3}.iteritems(): l.append((k,v)) l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def iteritems_int(dict d): """ >>> iteritems_int(d) [(10, 0), (11, 1), (12, 2), (13, 3)] >>> iteritems_int({}) [] >>> iteritems_int({'a': 1}) Traceback (most recent call last): TypeError: an integer is required >>> iteritems_int({1: 'b'}) Traceback (most recent call last): TypeError: an integer is required >>> iteritems_int({'a': 'b'}) Traceback (most recent call last): TypeError: an integer is required """ cdef int k,v l = [] for k,v in d.iteritems(): l.append((k,v)) l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def optimistic_iteritems_int(d): """ >>> optimistic_iteritems_int(d) [(10, 0), (11, 1), (12, 2), (13, 3)] >>> optimistic_iteritems_int({}) [] >>> class mydict(object): ... def __init__(self, t): self.t = t ... def iteritems(self): return self.t(d.items()) >>> optimistic_iteritems_int(mydict(list)) [(10, 0), (11, 1), (12, 2), (13, 3)] >>> optimistic_iteritems_int(mydict(tuple)) [(10, 0), (11, 1), (12, 2), (13, 3)] >>> optimistic_iteritems_int(mydict(iter)) [(10, 0), (11, 1), (12, 2), (13, 3)] >>> optimistic_iteritems_int({'a': 1}) Traceback (most recent call last): TypeError: an integer is required >>> optimistic_iteritems_int({1: 'b'}) Traceback (most recent call last): TypeError: an integer is required >>> optimistic_iteritems_int({'a': 'b'}) Traceback (most recent call last): TypeError: an integer is required """ cdef int k,v l = [] for k,v in d.iteritems(): l.append((k,v)) l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def iteritems_tuple(dict d): """ >>> iteritems_tuple(d) [(10, 0), (11, 1), (12, 2), (13, 3)] >>> iteritems_tuple({}) [] """ l = [] for t in d.iteritems(): l.append(t) l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def iteritems_listcomp(dict d): cdef list l = [(k,v) for k,v in d.iteritems()] l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def iterkeys(dict d): """ >>> iterkeys(d) [10, 11, 12, 13] >>> iterkeys({}) [] """ l = [] for k in d.iterkeys(): l.append(k) l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def optimistic_iterkeys(d): """ >>> optimistic_iterkeys(d) [10, 11, 12, 13] >>> optimistic_iterkeys({}) [] >>> class mydict(object): ... def __init__(self, t): self.t = t ... def iterkeys(self): return self.t(d) >>> optimistic_iterkeys(mydict(lambda x:x)) [10, 11, 12, 13] >>> optimistic_iterkeys(mydict(lambda x:x.keys())) [10, 11, 12, 13] >>> optimistic_iterkeys(mydict(list)) [10, 11, 12, 13] >>> optimistic_iterkeys(mydict(tuple)) [10, 11, 12, 13] >>> optimistic_iterkeys(mydict(iter)) [10, 11, 12, 13] """ l = [] for k in d.iterkeys(): l.append(k) l.sort() return l @cython.test_fail_if_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def optimistic_iterkeys_argerror(d): """ >>> try: optimistic_iterkeys_argerror(d) ... except (TypeError, AttributeError): pass """ for k in d.iterkeys(1): print k @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def iterkeys_int(dict d): """ >>> iterkeys_int(d) [10, 11, 12, 13] >>> iterkeys_int({}) [] >>> iterkeys_int({'a': 'b'}) Traceback (most recent call last): TypeError: an integer is required """ cdef int k l = [] for k in d.iterkeys(): l.append(k) l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def iterdict(dict d): """ >>> iterdict(d) [10, 11, 12, 13] >>> iterdict({}) [] """ l = [] for k in d: l.append(k) l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def iterdict_int(dict d): """ >>> iterdict_int(d) [10, 11, 12, 13] >>> iterdict_int({}) [] >>> iterdict_int({'a': 'b'}) Traceback (most recent call last): TypeError: an integer is required """ cdef int k l = [] for k in d: l.append(k) l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def iterdict_reassign(dict d): """ >>> iterdict_reassign(d) [10, 11, 12, 13] >>> iterdict_reassign({}) [] """ cdef dict d_new = {} l = [] for k in d: d = d_new l.append(k) l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def iterdict_listcomp(dict d): """ >>> iterdict_listcomp(d) [10, 11, 12, 13] >>> iterdict_listcomp({}) [] """ cdef list l = [k for k in d] l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def itervalues(dict d): """ >>> itervalues(d) [0, 1, 2, 3] >>> itervalues({}) [] """ l = [] for v in d.itervalues(): l.append(v) l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def optimistic_itervalues(d): """ >>> optimistic_itervalues(d) [0, 1, 2, 3] >>> optimistic_itervalues({}) [] >>> class mydict(object): ... def __init__(self, t): self.t = t ... def itervalues(self): return self.t(d.values()) >>> optimistic_itervalues(mydict(lambda x:x)) [0, 1, 2, 3] >>> optimistic_itervalues(mydict(list)) [0, 1, 2, 3] >>> optimistic_itervalues(mydict(tuple)) [0, 1, 2, 3] >>> optimistic_itervalues(mydict(iter)) [0, 1, 2, 3] """ l = [] for v in d.itervalues(): l.append(v) l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def itervalues_int(dict d): """ >>> itervalues_int(d) [0, 1, 2, 3] >>> itervalues_int({}) [] >>> itervalues_int({'a': 'b'}) Traceback (most recent call last): TypeError: an integer is required """ cdef int v l = [] for v in d.itervalues(): l.append(v) l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def itervalues_listcomp(dict d): """ >>> itervalues_listcomp(d) [0, 1, 2, 3] >>> itervalues_listcomp({}) [] """ cdef list l = [v for v in d.itervalues()] l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def itervalues_kwargs(**d): """ >>> itervalues_kwargs(a=1, b=2, c=3, d=4) [1, 2, 3, 4] >>> itervalues_kwargs() [] """ cdef list l = [v for v in d.itervalues()] l.sort() return l @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def iterdict_change_size(dict d): """ >>> count, i = 0, -1 >>> d = {1:2, 10:20} >>> for i in d: ... d[i+1] = 5 ... count += 1 ... if count > 5: ... break # safety Traceback (most recent call last): RuntimeError: dictionary changed size during iteration >>> iterdict_change_size({1:2, 10:20}) Traceback (most recent call last): RuntimeError: dictionary changed size during iteration >>> print( iterdict_change_size({}) ) DONE """ cdef int count = 0 i = -1 for i in d: d[i+1] = 5 count += 1 if count > 5: break # safety return "DONE" @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def optimistic_iterdict_change_size(d): """ >>> count, i = 0, -1 >>> d = {1:2, 10:20} >>> for i in d: ... d[i+1] = 5 ... count += 1 ... if count > 5: ... break # safety Traceback (most recent call last): RuntimeError: dictionary changed size during iteration >>> optimistic_iterdict_change_size({1:2, 10:20}) Traceback (most recent call last): RuntimeError: dictionary changed size during iteration >>> print( optimistic_iterdict_change_size({}) ) DONE >>> class mydict(object): ... _d = {1:2, 10:20} ... def iterkeys(self): return self._d ... def __setitem__(self, key, value): self._d[key] = value >>> optimistic_iterdict_change_size(mydict()) Traceback (most recent call last): RuntimeError: dictionary changed size during iteration """ cdef int count = 0 i = -1 for i in d.iterkeys(): d[i+1] = 5 count += 1 if count > 5: break # safety return "DONE" @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") def values_of_expression(**kwargs): """ >>> sorted(values_of_expression(a=3, b=4)) [3, 4] """ # this can be optimised even in Py2 return [ arg for arg in dict(kwargs.items()).values() ] def items_of_expression(*args, **kwargs): """ >>> sorted(items_of_expression(a=3, b=4)) [('a', 3), ('b', 4)] >>> sorted(items_of_expression([('a', 3)], b=4)) [('a', 3), ('b', 4)] """ return [item for item in dict(*args, **kwargs).items()] def iteritems_of_expression(*args, **kwargs): """ >>> sorted(iteritems_of_expression(a=3, b=4)) [('a', 3), ('b', 4)] >>> sorted(iteritems_of_expression([('a', 3)], b=4)) [('a', 3), ('b', 4)] """ return [item for item in dict(*args, **kwargs).iteritems()] def for_in_items_of_expression(*args, **kwargs): """ >>> sorted(for_in_items_of_expression(a=3, b=4)) [('a', 3), ('b', 4)] >>> sorted(for_in_items_of_expression([('a', 3)], b=4)) [('a', 3), ('b', 4)] """ result = [] for k, v in dict(*args, **kwargs).items(): result.append((k, v)) return result def for_in_iteritems_of_expression(*args, **kwargs): """ >>> sorted(for_in_iteritems_of_expression(a=3, b=4)) [('a', 3), ('b', 4)] >>> sorted(for_in_iteritems_of_expression([('a', 3)], b=4)) [('a', 3), ('b', 4)] """ result = [] for k, v in dict(*args, **kwargs).iteritems(): result.append((k, v)) return result Cython-0.23.4/tests/run/iteratorexception.pyx0000644000175600017570000000061312606202452022464 0ustar jenkinsjenkins00000000000000class IteratorAndIterateable: def next(self): raise ValueError def __next__(self): raise ValueError def __iter__(self): return self def f(): """ >>> f() """ try: for x in IteratorAndIterateable(): pass assert False, u"Should not reach this point, iterator has thrown exception" except ValueError: pass Cython-0.23.4/tests/run/iter.pyx0000644000175600017570000000101712606202452017656 0ustar jenkinsjenkins00000000000000 def call_iter1(x): """ >>> [ i for i in iter([1,2,3]) ] [1, 2, 3] >>> [ i for i in call_iter1([1,2,3]) ] [1, 2, 3] """ return iter(x) class Ints(object): def __init__(self): self.i = 0 def __call__(self): self.i += 1 if self.i > 10: raise ValueError return self.i def call_iter2(x, sentinel): """ >>> [ i for i in iter(Ints(), 3) ] [1, 2] >>> [ i for i in call_iter2(Ints(), 3) ] [1, 2] """ return iter(x, sentinel) Cython-0.23.4/tests/run/isnot.pyx0000644000175600017570000000216512606202452020054 0ustar jenkinsjenkins00000000000000# mode: run # tag: is_not cimport cython @cython.test_fail_if_path_exists('//NotNode') def is_not(a, b): """ >>> is_not(1, 2) True >>> x = 1 >>> is_not(x, x) False """ return a is not b @cython.test_fail_if_path_exists('//NotNode') def not_is_not(a, b): """ >>> not_is_not(1, 2) False >>> x = 1 >>> not_is_not(x, x) True """ return not a is not b @cython.test_fail_if_path_exists('//NotNode') def not_is(a, b): """ >>> not_is(1, 2) True >>> x = 1 >>> not_is(x, x) False """ return not a is b @cython.test_fail_if_path_exists('//NotNode') def is_not_None(a): """ >>> is_not_None(1) True >>> is_not_None(None) False """ return a is not None @cython.test_fail_if_path_exists('//NotNode') def not_is_not_None(a): """ >>> not_is_not_None(1) False >>> not_is_not_None(None) True """ return not a is not None @cython.test_fail_if_path_exists('//NotNode') def not_is_None(a): """ >>> not_is_None(1) True >>> not_is_None(None) False """ return not a is None Cython-0.23.4/tests/run/isnonebool.pyx0000644000175600017570000000123412606202452021063 0ustar jenkinsjenkins00000000000000def test_and(a,b): """ >>> test_and(None, None) True >>> test_and(None, 1) False >>> test_and(1, None) False """ return a is None and b is None def test_more(a,b): """ >>> test_more(None, None) True >>> test_more(None, 1) True >>> test_more(1, None) False >>> test_more(None, 0) False """ return a is None and (b is None or b == 1) def test_more_c(a,b): """ >>> test_more_c(None, None) True >>> test_more_c(None, 1) True >>> test_more_c(1, None) False >>> test_more_c(None, 0) False """ return (a is None or 1 == 2) and (b is None or b == 1) Cython-0.23.4/tests/run/isinstance.pyx0000644000175600017570000001274312606202452021063 0ustar jenkinsjenkins00000000000000 cimport cython from cpython.bool cimport bool cdef class A: pass a_as_obj = A @cython.test_assert_path_exists('//SimpleCallNode//SimpleCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode//PythonCapiCallNode', '//PythonCapiCallNode//SimpleCallNode') def test_non_optimised(): """ >>> test_non_optimised() True """ # Non-optimized cdef object foo = A assert isinstance(A(), foo) return True @cython.test_assert_path_exists('//PythonCapiCallNode', '//PythonCapiCallNode//SimpleCallNode', '//PythonCapiFunctionNode[@cname = "PyType_Check"]', '//PythonCapiFunctionNode[@cname = "PyInt_Check"]', '//PythonCapiFunctionNode[@cname = "PyFloat_Check"]', '//PythonCapiFunctionNode[@cname = "PyBytes_Check"]', '//PythonCapiFunctionNode[@cname = "PyUnicode_Check"]', '//PythonCapiFunctionNode[@cname = "PyTuple_Check"]', '//PythonCapiFunctionNode[@cname = "PyList_Check"]', '//PythonCapiFunctionNode[@cname = "PyDict_Check"]', '//PythonCapiFunctionNode[@cname = "PySet_Check"]', '//PythonCapiFunctionNode[@cname = "PySlice_Check"]', '//PythonCapiFunctionNode[@cname = "PyComplex_Check"]') @cython.test_fail_if_path_exists('//SimpleCallNode//SimpleCallNode', '//SimpleCallNode//PythonCapiCallNode') def test_optimised(): """ >>> test_optimised() True """ # Optimized tests. cdef object new_type = type('a',(),{}) assert isinstance(type('a',(),{}), type) assert isinstance(new_type, type) cdef object boolval = True assert isinstance(boolval, bool) assert isinstance(True, bool) cdef object intval = int() assert isinstance(intval, int) assert isinstance(int(), int) cdef object longval = long() assert isinstance(longval, long) assert isinstance(long(), long) cdef object floatval = float() assert isinstance(floatval, float) assert isinstance(float(), float) cdef object bytesval = bytes() assert isinstance(bytesval, bytes) assert isinstance(bytes(), bytes) cdef object strval = str() assert isinstance(strval, str) assert isinstance(str(), str) cdef object unicodeval = unicode() assert isinstance(unicodeval, unicode) assert isinstance(unicode(), unicode) cdef object tupleval = tuple() assert isinstance(tupleval, tuple) assert isinstance(tuple(), tuple) cdef object listval = list() assert isinstance(listval, list) assert isinstance(list(), list) cdef object dictval = dict() assert isinstance(dictval, dict) assert isinstance(dict(), dict) cdef object setval = set() assert isinstance(setval, set) assert isinstance(set(), set) cdef object sliceval = slice(0) assert isinstance(sliceval, slice) assert isinstance(slice(0), slice) cdef object complexval = complex() assert isinstance(complexval, complex) assert isinstance(complex(), complex) assert not isinstance(u"foo", int) assert isinstance(A, type) assert isinstance(A(), A) cdef type typed_type = A assert isinstance(A(), typed_type) cdef object untyped_type = A assert isinstance(A(), untyped_type) return True @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode//SimpleCallNode', '//SimpleCallNode//PythonCapiCallNode', '//TupleNode//NameNode') def test_optimised_tuple(): """ >>> test_optimised_tuple() True """ assert isinstance(int(), (int, long, float, bytes, str, unicode, tuple, list, dict, set, slice, type, A)) assert isinstance(list(), (int, long, float, bytes, str, unicode, tuple, list, dict, set, slice, type, A)) assert isinstance(A(), (int, long, float, bytes, str, unicode, tuple, list, dict, set, slice, type, A)) assert isinstance(A(), (int, long, float, bytes, str, unicode, tuple, list, dict, set, slice, type, A, a_as_obj)) assert isinstance(A(), (int, long, float, bytes, str, unicode, tuple, list, dict, set, slice, type, a_as_obj, A)) assert isinstance(A(), (int, long, float, bytes, str, unicode, a_as_obj, tuple, list, dict, set, slice, type, A)) assert isinstance(0, (int, long)) assert not isinstance(u"xyz", (int, long)) return True def test_custom(): """ >>> test_custom() True """ assert isinstance(A(), A) return True cdef class B: pass cdef class C: pass @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.test_fail_if_path_exists('//SimpleCallNode//SimpleCallNode', '//SimpleCallNode//PythonCapiCallNode', '//TupleNode//NameNode') def test_custom_tuple(obj): """ >>> test_custom_tuple(A()) True >>> test_custom_tuple(B()) True >>> test_custom_tuple(C()) False """ return isinstance(obj, (A,B)) def test_nested(x): """ >>> test_nested(1) True >>> test_nested(1.5) True >>> test_nested("a") False """ cdef object a = (x, None) if isinstance(a[0], (int, float)): return True return False Cython-0.23.4/tests/run/ishimoto3.pyx0000644000175600017570000000036412606202452020635 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> c1 = C1() >>> c2 = C2(c1) >>> c1 is c2.getc1() True """ cdef class C1: pass cdef class C2: cdef C1 c1 def __init__(self, arg): self.c1 = arg def getc1(self): return self.c1 Cython-0.23.4/tests/run/ishimoto2.pyx0000644000175600017570000000026312606202452020632 0ustar jenkinsjenkins00000000000000 class C: """ >>> C().xxx(5) 5 >>> C().xxx() 'a b' >>> C().xxx(42) 42 >>> C().xxx() 'a b' """ def xxx(self, p="a b"): return p Cython-0.23.4/tests/run/ipow_crash_T562.pyx0000644000175600017570000000056012606202452021573 0ustar jenkinsjenkins00000000000000# ticket: 562 class IPOW: """ >>> IPOW().__ipow__('a') a >>> x = IPOW() >>> x **= 'z' z """ def __ipow__(self, other): print ("%s" % other) cdef class CrashIPOW: """ >>> CrashIPOW().__ipow__('a') a >>> x = CrashIPOW() >>> x **= 'z' z """ def __ipow__(self, other): print ("%s" % other) Cython-0.23.4/tests/run/internal_cdef_class.pyx0000644000175600017570000000076112606202452022702 0ustar jenkinsjenkins00000000000000 cimport cython @cython.internal cdef class InternalType: """ NOTE: this doesn't fail because it is never tested ! >>> i = InternalType """ cdef class PublicType: """ >>> p = PublicType """ def test(): """ >>> p,i = test() >>> p = PublicType >>> i = InternalType # doctest: +ELLIPSIS Traceback (most recent call last): NameError: ...name 'InternalType' is not defined """ p = PublicType i = InternalType return p,i Cython-0.23.4/tests/run/intern_T431.pyx0000644000175600017570000000062412606202452020730 0ustar jenkinsjenkins00000000000000# ticket: 431 __doc__ = u""" >>> s == s_interned True >>> s == s_interned_dynamic True >>> s == 'abc' == s_interned == s_interned_dynamic True """ import sys if sys.version_info[0] < 3: __doc__ += u""" >>> intern(s) is s_interned True >>> intern('abc') is s_interned True >>> intern('abc') is s_interned_dynamic True """ s = 'abc' s_interned = intern(s) s_interned_dynamic = intern('a'+'b'+'c') Cython-0.23.4/tests/run/int_literals.pyx0000644000175600017570000000730112606202452021406 0ustar jenkinsjenkins00000000000000cimport cython from cython cimport typeof import sys @cython.test_assert_path_exists( '//IntNode[@longness = "LL"]', '//IntNode[@longness = "L"]', ) @cython.test_fail_if_path_exists('//IntNode[@longness = ""]') def c_longs(): """ >>> c_longs() == (1, 1, -1, 18446744073709551615) or c_longs() True """ cdef long a = 1L cdef unsigned long ua = 1UL cdef long long aa = 0xFFFFFFFFFFFFFFFFLL cdef unsigned long long uaa = 0xFFFFFFFFFFFFFFFFULL return a, ua, int(aa), uaa @cython.test_assert_path_exists( '//IntNode[@longness = "LL"]', '//IntNode[@longness = "L"]', ) @cython.test_fail_if_path_exists('//IntNode[@longness = ""]') def negative_c_longs(): """ >>> negative_c_longs() == (-1, -9223285636854775809) or negative_c_longs() True """ cdef long a = -1L cdef long long aa = -9223285636854775809LL return a, aa def py_longs(): """ >>> py_longs() == ( ... 1, 1, 100000000000000000000000000000000, -100000000000000000000000000000000 ... ) or py_longs() True """ return 1, 1L, 100000000000000000000000000000000, -100000000000000000000000000000000 @cython.test_fail_if_path_exists("//NumBinopNode", "//IntBinopNode") @cython.test_assert_path_exists("//ReturnStatNode/IntNode") def py_huge_calculated_long(): """ >>> py_huge_calculated_long() == ( ... 1606938044258990275541962092341162602522202993782792835301376 ... ) or py_huge_calculated_long() True """ return 1 << 200 @cython.test_fail_if_path_exists("//NumBinopNode", "//IntBinopNode") @cython.test_assert_path_exists("//ReturnStatNode/IntNode") def py_huge_computation_small_result(): """ >>> py_huge_computation_small_result() 2 """ return (1 << 200) >> 199 @cython.test_fail_if_path_exists("//NumBinopNode", "//IntBinopNode") #@cython.test_assert_path_exists("//ReturnStatNode/IntNode") def py_huge_computation_small_result_neg(): """ >>> py_huge_computation_small_result_neg() == ( ... -2535301200456458802993406410752, -2535301200456458802993406410752 ... ) or py_huge_computation_small_result_neg() True """ return -(2 ** 101), (-2) ** 101 def large_literal(): """ >>> type(large_literal()) is int True """ if sys.version_info[0] >= 3 or sys.maxint > 0xFFFFFFFFFFFF: return 0xFFFFFFFFFFFF else: return 0xFFFFFFF def c_long_types(): """ >>> c_long_types() long long long long unsigned long unsigned long unsigned long long """ print typeof(1) print typeof(1L) print typeof(1LL) print typeof(1U) print typeof(1UL) print typeof(1ULL) # different ways to write an integer in Python def c_oct(): """ >>> c_oct() (1, -17, 63) """ cdef int a = 0o01 cdef int b = -0o21 cdef int c = 0o77 return a,b,c def c_oct_py2_legacy(): """ >>> c_oct_py2_legacy() (1, -17, 63) """ cdef int a = 001 cdef int b = -021 cdef int c = 077 return a,b,c def py_oct(): """ >>> py_oct() (1, -17, 63) """ return 0o01, -0o21, 0o77 def py_oct_py2_legacy(): """ >>> py_oct_py2_legacy() (1, -17, 63) """ return 001, -021, 077 def c_hex(): """ >>> c_hex() (1, -33, 255) """ cdef int a = 0x01 cdef int b = -0x21 cdef int c = 0xFF return a,b,c def py_hex(): """ >>> py_hex() (1, -33, 255) """ return 0x01, -0x21, 0xFF def c_bin(): """ >>> c_bin() (1, -2, 15) """ cdef int a = 0b01 cdef int b = -0b10 cdef int c = 0b1111 return a,b,c def py_bin(): """ >>> py_bin() (1, -2, 15) """ return 0b01, -0b10, 0b1111 Cython-0.23.4/tests/run/int_float_builtins_as_casts_T400.pyx0000644000175600017570000001152512606202452025177 0ustar jenkinsjenkins00000000000000# ticket: 400 cimport cython @cython.test_assert_path_exists("//SingleAssignmentNode/TypecastNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def double_to_short_int(double x): """ >>> double_to_short_int(4.1) 4 >>> double_to_short_int(4) 4 """ cdef short r = int(x) return r @cython.test_assert_path_exists("//SingleAssignmentNode/TypecastNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def double_to_pyssizet_int(double x): """ >>> double_to_pyssizet_int(4.1) 4 >>> double_to_pyssizet_int(4) 4 """ cdef Py_ssize_t r = int(x) return r @cython.test_assert_path_exists("//SingleAssignmentNode/TypecastNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def int_to_pyssizet_int(int x): """ >>> int_to_pyssizet_int(4.1) 4 >>> int_to_pyssizet_int(4) 4 """ cdef Py_ssize_t r = int(x) return r ## @cython.test_assert_path_exists("//SingleAssignmentNode/TypecastNode") ## @cython.test_fail_if_path_exists("//SimpleCallNode") ## def double_to_pyssizet_float(double x): ## """ ## >>> double_to_pyssizet_float(4.1) ## 4 ## >>> double_to_pyssizet_float(4) ## 4 ## """ ## cdef Py_ssize_t r = float(x) ## return r @cython.test_assert_path_exists("//SingleAssignmentNode/TypecastNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def int_to_short_int(int x): """ >>> int_to_short_int(4) 4 """ cdef short r = int(x) return r @cython.test_assert_path_exists("//SingleAssignmentNode/TypecastNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def short_to_float_float(short x): """ >>> short_to_float_float(4) 4.0 """ cdef float r = float(x) return r @cython.test_assert_path_exists("//SingleAssignmentNode/TypecastNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def short_to_double_float(short x): """ >>> short_to_double_float(4) 4.0 """ cdef double r = float(x) return r @cython.test_assert_path_exists("//SingleAssignmentNode/TypecastNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def short_to_double_int(short x): """ >>> short_to_double_int(4) 4.0 """ cdef double r = int(x) return r @cython.test_fail_if_path_exists("//SimpleCallNode") def float_to_float_float(float x): """ >>> 4.05 < float_to_float_float(4.1) < 4.15 True >>> float_to_float_float(4) 4.0 """ cdef float r = float(x) return r @cython.test_fail_if_path_exists("//SimpleCallNode", "//SingleAssignmentNode/TypecastNode") def double_to_double_float(double x): """ >>> 4.05 < double_to_double_float(4.1) < 4.15 True >>> double_to_double_float(4) 4.0 """ cdef double r = float(x) return r # tests that cannot be optimised @cython.test_fail_if_path_exists("//SingleAssignmentNode/TypecastNode") @cython.test_assert_path_exists("//SimpleCallNode") def double_to_py_int(double x): """ >>> double_to_py_int(4.1) 4 >>> double_to_py_int(4) 4 """ return int(x) @cython.test_fail_if_path_exists("//SingleAssignmentNode/TypecastNode") @cython.test_assert_path_exists("//SimpleCallNode") def double_to_double_int(double x): """ >>> double_to_double_int(4.1) 4.0 >>> double_to_double_int(4) 4.0 """ cdef double r = int(x) return r @cython.test_fail_if_path_exists("//SimpleCallNode") @cython.test_assert_path_exists("//PythonCapiCallNode") def object_float(x): """ >>> 4.05 < object_float(4.1) < 4.15 True >>> object_float(2**100) == float(2**100) True >>> object_float(2.5**100) == float(2.5**100) True >>> object_float(4) 4.0 >>> object_float('4') 4.0 >>> object_float('4.0') 4.0 >>> object_float('4'.encode('ascii')) 4.0 >>> object_float('4.0'.encode('ascii')) 4.0 """ return float(x) @cython.test_fail_if_path_exists("//SimpleCallNode") @cython.test_assert_path_exists("//PythonCapiCallNode") def object_int(x): """ >>> object_int(4) 4 >>> object_int(2**100) == 2**100 or object_int(2**100) True >>> object_int(-(2**100)) == -(2**100) or object_int(-(2**100)) True >>> object_int(4.1) 4 >>> object_int(4.0) 4 >>> object_int('4') 4 >>> object_int('4'.encode('ascii')) 4 """ return int(x) @cython.test_fail_if_path_exists("//SimpleCallNode", "//CoerceFromPyTypeNode") def no_args_int_cint(): """ >>> no_args_int_cint() 0 """ cdef int x = int() return x @cython.test_fail_if_path_exists("//SimpleCallNode", "//CoerceFromPyTypeNode") def no_args_float_cdouble(): """ >>> no_args_float_cdouble() (0.0, 0.0) """ cdef double xd = float() cdef float xf = float() return xd, xf Cython-0.23.4/tests/run/int128.pyx0000644000175600017570000000707512606202452017752 0ustar jenkinsjenkins00000000000000 cdef extern from *: ctypedef long long int128_t "__int128_t" ctypedef unsigned long long uint128_t "__uint128_t" def bigint(x): print(str(x).rstrip('L')) def unsigned_conversion(x): """ >>> bigint(unsigned_conversion(0)) 0 >>> bigint(unsigned_conversion(2)) 2 >>> unsigned_conversion(-2) # doctest: +ELLIPSIS Traceback (most recent call last): OverflowError: can't convert negative value to ...uint128_t >>> unsigned_conversion(-2**120) # doctest: +ELLIPSIS Traceback (most recent call last): OverflowError: can't convert negative value to ...uint128_t >>> unsigned_conversion(-2**127) # doctest: +ELLIPSIS Traceback (most recent call last): OverflowError: can't convert negative value to ...uint128_t >>> unsigned_conversion(-2**128) # doctest: +ELLIPSIS Traceback (most recent call last): OverflowError: can't convert negative value to ...uint128_t >>> bigint(unsigned_conversion(2**20)) 1048576 >>> bigint(unsigned_conversion(2**30-1)) 1073741823 >>> bigint(unsigned_conversion(2**30)) 1073741824 >>> bigint(unsigned_conversion(2**30+1)) 1073741825 >>> bigint(2**60) 1152921504606846976 >>> bigint(unsigned_conversion(2**60-1)) 1152921504606846975 >>> bigint(unsigned_conversion(2**60)) 1152921504606846976 >>> bigint(unsigned_conversion(2**60+1)) 1152921504606846977 >>> bigint(2**64) 18446744073709551616 >>> bigint(unsigned_conversion(2**64)) 18446744073709551616 >>> bigint(2**120) 1329227995784915872903807060280344576 >>> bigint(unsigned_conversion(2**120)) 1329227995784915872903807060280344576 >>> bigint(2**128-1) 340282366920938463463374607431768211455 >>> bigint(unsigned_conversion(2**128-1)) 340282366920938463463374607431768211455 >>> bigint(unsigned_conversion(2**128)) # doctest: +ELLIPSIS Traceback (most recent call last): OverflowError: ... too big to convert """ cdef uint128_t n = x return n def signed_conversion(x): """ >>> bigint(signed_conversion(0)) 0 >>> bigint(signed_conversion(2)) 2 >>> bigint(signed_conversion(-2)) -2 >>> bigint(signed_conversion(2**20)) 1048576 >>> bigint(signed_conversion(2**32)) 4294967296 >>> bigint(2**64) 18446744073709551616 >>> bigint(signed_conversion(2**64)) 18446744073709551616 >>> bigint(signed_conversion(-2**64)) -18446744073709551616 >>> bigint(2**118) 332306998946228968225951765070086144 >>> bigint(signed_conversion(2**118)) 332306998946228968225951765070086144 >>> bigint(signed_conversion(-2**118)) -332306998946228968225951765070086144 >>> bigint(2**120) 1329227995784915872903807060280344576 >>> bigint(signed_conversion(2**120)) 1329227995784915872903807060280344576 >>> bigint(signed_conversion(-2**120)) -1329227995784915872903807060280344576 >>> bigint(2**127-1) 170141183460469231731687303715884105727 >>> bigint(signed_conversion(2**127-2)) 170141183460469231731687303715884105726 >>> bigint(signed_conversion(2**127-1)) 170141183460469231731687303715884105727 >>> bigint(signed_conversion(2**127)) # doctest: +ELLIPSIS Traceback (most recent call last): OverflowError: ... too big to convert >>> bigint(signed_conversion(-2**127)) -170141183460469231731687303715884105728 >>> bigint(signed_conversion(-2**127-1)) # doctest: +ELLIPSIS Traceback (most recent call last): OverflowError: ... too big to convert """ cdef int128_t n = x return n Cython-0.23.4/tests/run/inplace.pyx0000644000175600017570000001157012606202452020333 0ustar jenkinsjenkins00000000000000cimport cython def f(a,b): """ >>> str(f(5, 7)) '29509034655744' """ a += b a *= b a **= b return a def g(int a, int b): """ >>> g(13, 4) 32 """ a -= b a /= b a <<= b return a def h(double a, double b): """ >>> h(56, 7) 105.0 """ a /= b a += b a *= b return a from libc cimport stdlib def arrays(): """ >>> arrays() 19 """ cdef char* buf = stdlib.malloc(10) cdef int i = 2 cdef object j = 2 buf[2] = 0 buf[i] += 2 buf[2] *= 10 buf[j] -= 1 print buf[2] stdlib.free(buf) cdef class A: cdef attr cdef int attr2 cdef char* buf def __init__(self): self.attr = 3 self.attr2 = 3 class B: attr = 3 def attributes(): """ >>> attributes() 26 26 26 """ cdef A a = A() b = B() a.attr += 10 a.attr *= 2 a.attr2 += 10 a.attr2 *= 2 b.attr += 10 b.attr *= 2 print a.attr, a.attr2, b.attr def get_2(): return 2 cdef int identity(int value): return value def smoketest(): """ >>> smoketest() 10 """ cdef char* buf = stdlib.malloc(10) cdef A a = A() a.buf = buf a.buf[identity(1)] = 0 (a.buf + identity(4) - (2*get_2() - 1))[get_2() - 2*identity(1)] += 10 print a.buf[1] stdlib.free(buf) def side_effect(x): print u"side effect", x return x cdef int c_side_effect(int x): print u"c side effect", x return x def test_side_effects(): """ >>> test_side_effects() side effect 1 c side effect 2 side effect 3 c side effect 4 ([0, 11, 102, 3, 4], [0, 1, 2, 13, 104]) """ cdef object a = list(range(5)) a[side_effect(1)] += 10 a[c_side_effect(2)] += 100 cdef int i cdef int[5] b for i from 0 <= i < 5: b[i] = i b[side_effect(3)] += 10 b[c_side_effect(4)] += 100 return a, [b[i] for i from 0 <= i < 5] @cython.cdivision(True) def test_inplace_cdivision(int a, int b): """ >>> test_inplace_cdivision(13, 10) 3 >>> test_inplace_cdivision(13, -10) 3 >>> test_inplace_cdivision(-13, 10) -3 >>> test_inplace_cdivision(-13, -10) -3 """ a %= b return a @cython.cdivision(False) def test_inplace_pydivision(int a, int b): """ >>> test_inplace_pydivision(13, 10) 3 >>> test_inplace_pydivision(13, -10) -7 >>> test_inplace_pydivision(-13, 10) 7 >>> test_inplace_pydivision(-13, -10) -3 """ a %= b return a def test_complex_inplace(double complex x, double complex y): """ >>> test_complex_inplace(1, 1) (2+0j) >>> test_complex_inplace(2, 3) (15+0j) >>> test_complex_inplace(2+3j, 4+5j) (-16+62j) """ x += y x *= y return x # The following is more subtle than one might expect. cdef struct Inner: int x cdef struct Aa: int value Inner inner cdef struct NestedA: Aa a cdef struct ArrayOfA: Aa[10] a def nested_struct_assignment(): """ >>> nested_struct_assignment() """ cdef NestedA nested nested.a.value = 2 nested.a.value += 3 assert nested.a.value == 5 nested.a.inner.x = 5 nested.a.inner.x += 10 assert nested.a.inner.x == 15 def nested_array_assignment(): """ >>> nested_array_assignment() c side effect 0 c side effect 1 """ cdef ArrayOfA array array.a[0].value = 2 array.a[c_side_effect(0)].value += 3 assert array.a[0].value == 5 array.a[1].inner.x = 5 array.a[c_side_effect(1)].inner.x += 10 assert array.a[1].inner.x == 15 cdef class VerboseDict(object): cdef name cdef dict dict def __init__(self, name, **kwds): self.name = name self.dict = kwds def __getitem__(self, key): print self.name, "__getitem__", key return self.dict[key] def __setitem__(self, key, value): print self.name, "__setitem__", key, value self.dict[key] = value def __repr__(self): return repr(self.name) def deref_and_increment(o, key): """ >>> deref_and_increment({'a': 1}, 'a') side effect a >>> v = VerboseDict('v', a=10) >>> deref_and_increment(v, 'a') side effect a v __getitem__ a v __setitem__ a 11 """ o[side_effect(key)] += 1 def double_deref_and_increment(o, key1, key2): """ >>> v = VerboseDict('v', a=10) >>> w = VerboseDict('w', vkey=v) >>> double_deref_and_increment(w, 'vkey', 'a') side effect vkey w __getitem__ vkey side effect a v __getitem__ a v __setitem__ a 11 """ o[side_effect(key1)][side_effect(key2)] += 1 def conditional_inplace(value, a, condition, b): """ >>> conditional_inplace([1, 2, 3], [100], True, [200]) [1, 2, 3, 100] >>> conditional_inplace([1, 2, 3], [100], False, [200]) [1, 2, 3, 200] """ value += a if condition else b return value Cython-0.23.4/tests/run/inop.pyx0000644000175600017570000002510112606202452017660 0ustar jenkinsjenkins00000000000000 cimport cython def f(a,b): """ >>> f(1,[1,2,3]) True >>> f(5,[1,2,3]) False >>> f(2,(1,2,3)) True """ cdef object result = a in b return result def g(a,b): """ >>> g(1,[1,2,3]) 1 >>> g(5,[1,2,3]) 0 >>> g(2,(1,2,3)) 1 """ cdef int result = a in b return result def h(b): """ >>> h([1,2,3,4]) True >>> h([1,3,4]) False """ cdef object result = 2 in b return result def j(b): """ >>> j([1,2,3,4]) 1 >>> j([1,3,4]) 0 """ cdef int result = 2 in b return result @cython.test_fail_if_path_exists("//SwitchStatNode") def k(a): """ >>> k(1) 1 >>> k(5) 0 """ cdef int result = a in [1,2,3,4] return result @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode") def m_list(int a): """ >>> m_list(2) 1 >>> m_list(5) 0 """ cdef int result = a in [1,2,3,4] return result @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode") def m_tuple(int a): """ >>> m_tuple(2) 1 >>> m_tuple(5) 0 """ cdef int result = a in (1,2,3,4) return result @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode") def m_set(int a): """ >>> m_set(2) 1 >>> m_set(5) 0 """ cdef int result = a in {1,2,3,4} return result cdef bytes bytes_string = b'ab\0cde\0f\0g' py_bytes_string = bytes_string @cython.test_assert_path_exists("//PrimaryCmpNode") @cython.test_fail_if_path_exists("//SwitchStatNode", "//BoolBinopNode") def m_bytes(char a, bytes bytes_string): """ >>> m_bytes(ord('f'), py_bytes_string) 1 >>> m_bytes(ord('X'), py_bytes_string) 0 >>> 'f'.encode('ASCII') in None # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...iterable... >>> m_bytes(ord('f'), None) Traceback (most recent call last): TypeError: argument of type 'NoneType' is not iterable """ cdef int result = a in bytes_string return result @cython.test_assert_path_exists("//PrimaryCmpNode") @cython.test_fail_if_path_exists("//SwitchStatNode", "//BoolBinopNode") def m_bytes_unsigned(unsigned char a, bytes bytes_string): """ >>> m_bytes(ord('f'), py_bytes_string) 1 >>> m_bytes(ord('X'), py_bytes_string) 0 >>> 'f'.encode('ASCII') in None # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...iterable... >>> m_bytes(ord('f'), None) Traceback (most recent call last): TypeError: argument of type 'NoneType' is not iterable """ cdef int result = a in bytes_string return result @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode") def m_bytes_literal(char a): """ >>> m_bytes_literal(ord('f')) 1 >>> m_bytes_literal(ord('X')) 0 """ cdef int result = a in b'ab\0cde\0f\0g' return result @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode") def m_bytes_literal_unsigned(unsigned char a): """ >>> m_bytes_literal(ord('f')) 1 >>> m_bytes_literal(ord('X')) 0 """ cdef int result = a in b'ab\0cde\0f\0g' return result cdef unicode unicode_string = u'abc\0defg\u1234\uF8D2' py_unicode_string = unicode_string @cython.test_assert_path_exists("//PrimaryCmpNode") @cython.test_fail_if_path_exists("//SwitchStatNode", "//BoolBinopNode") def m_unicode(Py_UNICODE a, unicode unicode_string): """ >>> m_unicode(ord('f'), py_unicode_string) 1 >>> m_unicode(ord('X'), py_unicode_string) 0 >>> m_unicode(ord(py_klingon_character), py_unicode_string) 1 >>> 'f' in None # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...iterable... >>> m_unicode(ord('f'), None) Traceback (most recent call last): TypeError: argument of type 'NoneType' is not iterable """ cdef int result = a in unicode_string return result cdef unicode klingon_character = u'\uF8D2' py_klingon_character = klingon_character @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode") def m_unicode_literal(Py_UNICODE a): """ >>> m_unicode_literal(ord('f')) 1 >>> m_unicode_literal(ord('X')) 0 >>> m_unicode_literal(ord(py_klingon_character)) 1 """ cdef int result = a in u'abc\0defg\u1234\uF8D2' return result cdef unicode wide_unicode_character = u'\U0010FEDC' py_wide_unicode_character = wide_unicode_character wide_unicode_character_surrogate1 = 0xDBFF wide_unicode_character_surrogate2 = 0xDEDC @cython.test_fail_if_path_exists("//SwitchStatNode") @cython.test_assert_path_exists("//PrimaryCmpNode") def m_wide_unicode_literal(Py_UCS4 a): """ >>> m_unicode_literal(ord('f')) 1 >>> m_unicode_literal(ord('X')) 0 >>> import sys >>> if sys.maxunicode == 65535: ... m_wide_unicode_literal(wide_unicode_character_surrogate1) ... m_wide_unicode_literal(wide_unicode_character_surrogate2) ... else: ... m_wide_unicode_literal(ord(py_wide_unicode_character)) ... 1 1 1 """ cdef int result = a in u'abc\0defg\u1234\uF8D2\U0010FEDC' return result @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode") def conditional_int(int a): """ >>> conditional_int(1) 1 >>> conditional_int(0) 2 >>> conditional_int(5) 2 """ return 1 if a in (1,2,3,4) else 2 @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode") def conditional_object(int a): """ >>> conditional_object(1) 1 >>> conditional_object(0) '2' >>> conditional_object(5) '2' """ return 1 if a in (1,2,3,4) else '2' @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode") def conditional_bytes(char a): """ >>> conditional_bytes(ord('a')) 1 >>> conditional_bytes(ord('X')) '2' >>> conditional_bytes(0) '2' """ return 1 if a in b'abc' else '2' @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode") def conditional_unicode(Py_UNICODE a): """ >>> conditional_unicode(ord('a')) 1 >>> conditional_unicode(ord('X')) '2' >>> conditional_unicode(0) '2' """ return 1 if a in u'abc' else '2' @cython.test_assert_path_exists("//SwitchStatNode") @cython.test_fail_if_path_exists("//BoolBinopNode", "//PrimaryCmpNode") def conditional_none(int a): """ >>> conditional_none(1) >>> conditional_none(0) 1 >>> conditional_none(5) 1 """ return None if a in {1,2,3,4} else 1 @cython.test_assert_path_exists( "//BoolBinopNode", "//BoolBinopNode//PrimaryCmpNode" ) @cython.test_fail_if_path_exists("//ListNode") def n(a): """ >>> n('d *') 1 >>> n('xxx') 0 """ cdef int result = a.lower() in [u'a *',u'b *',u'c *',u'd *'] return result def p(a): """ >>> p(1) 0 >>> p('a') 1 """ cdef dict d = {u'a': 1, u'b': 2} cdef int result = a in d return result def q(a): """ >>> q(1) Traceback (most recent call last): TypeError: 'NoneType' object is not iterable >>> l = [1,2,3,4] >>> l2 = [l[1:],l[:-1],l] >>> 2 in l in l2 True """ cdef dict d = None cdef int result = a in d # should fail with a TypeError return result def r(a): """ >>> r(2) 1 """ cdef object l = [1,2,3,4] cdef object l2 = [l[1:],l[:-1],l] cdef int result = a in l in l2 return result def s(a): """ >>> s(2) 1 """ cdef int result = a in [1,2,3,4] in [[1,2,3],[2,3,4],[1,2,3,4]] return result #@cython.test_assert_path_exists("//ReturnStatNode//BoolNode") #@cython.test_fail_if_path_exists("//SwitchStatNode") def constant_empty_sequence(a): """ >>> constant_empty_sequence(1) False >>> constant_empty_sequence(5) False """ return a in () @cython.test_fail_if_path_exists("//ReturnStatNode//BoolNode") @cython.test_assert_path_exists("//PrimaryCmpNode") def constant_empty_sequence_side_effect(a): """ >>> l =[] >>> def a(): ... l.append(1) ... return 1 >>> constant_empty_sequence_side_effect(a) False >>> l [1] """ return a() in () def test_error_non_iterable(x): """ >>> test_error_non_iterable(1) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...iterable... """ return x in 42 def test_error_non_iterable_cascaded(x): """ >>> test_error_non_iterable_cascaded(1) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...iterable... """ return 1 == x in 42 def test_inop_cascaded(x): """ >>> test_inop_cascaded(1) False >>> test_inop_cascaded(2) True >>> test_inop_cascaded(3) False """ return 1 != x in [2] ### The following tests are copied from CPython's test_grammar.py. ### They look stupid, but the nice thing about them is that Cython ### treats '1' as a C integer constant that triggers Python object ### coercion for the 'in' operator here, whereas the left side of ### the cascade can be evaluated entirely in C space. def test_inop_cascaded_one(): """ >>> test_inop_cascaded_one() False """ return 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1 def test_inop_cascaded_int_orig(int x): """ >>> test_inop_cascaded_int_orig(1) False """ return 1 < 1 > 1 == 1 >= 1 <= 1 != x in 1 not in 1 is 1 is not 1 def test_inop_cascaded_one_err(): """ >>> test_inop_cascaded_one_err() # doctest: +ELLIPSIS Traceback (most recent call last): TypeError:... itera... """ return 1 == 1 >= 1 <= 1 in 1 not in 1 is 1 is not 1 def test_inop_cascaded_int_orig_err(int x): """ >>> test_inop_cascaded_int_orig_err(1) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError:... itera... """ return 1 == 1 >= 1 <= 1 == x in 1 not in 1 is 1 is not 1 ### def test_inop_cascaded_int(int x): """ >>> test_inop_cascaded_int(1) False >>> test_inop_cascaded_int(2) True >>> test_inop_cascaded_int(3) False """ return 1 != x in [1,2] Cython-0.23.4/tests/run/inlinepxd_support.pxd0000644000175600017570000000010312606202452022447 0ustar jenkinsjenkins00000000000000 cdef inline int my_add(int a, int b, int c): return a + b + c Cython-0.23.4/tests/run/inlinepxd.pyx0000644000175600017570000000037412606202452020712 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> f() 3 >>> g() 6 >>> h() 6 """ cimport inlinepxd_support from inlinepxd_support cimport my_add as my_add3 def f(): return my_add(1, 2) def g(): return inlinepxd_support.my_add(1, 2, 3) def h(): return my_add3(1, 2, 3) Cython-0.23.4/tests/run/inlinepxd.pxd0000644000175600017570000000007012606202452020656 0ustar jenkinsjenkins00000000000000 cdef inline int my_add(int a, int b): return a + b Cython-0.23.4/tests/run/inlined_generator_expressions.pyx0000644000175600017570000001471112606202452025052 0ustar jenkinsjenkins00000000000000 cimport cython ## def range_tuple_genexp(int N): ## """ ## >>> range_tuple_genexp(5) ## (0, 1, 2, 3, 4) ## """ ## return tuple(i for i in range(N)) @cython.test_assert_path_exists('//ForFromStatNode', "//InlinedGeneratorExpressionNode") @cython.test_fail_if_path_exists('//SimpleCallNode', '//ForInStatNode') def range_sum(int N): """ >>> sum(range(10)) 45 >>> range_sum(10) 45 """ result = sum(i for i in range(N)) return result @cython.test_assert_path_exists('//ForFromStatNode', "//InlinedGeneratorExpressionNode") @cython.test_fail_if_path_exists('//SimpleCallNode', '//CoerceFromPyTypeNode//InlinedGeneratorExpressionNode', '//ForInStatNode') def range_sum_typed(int N): """ >>> sum(range(10)) 45 >>> range_sum_typed(10) 45 """ cdef int result = sum(i for i in range(N)) return result @cython.test_assert_path_exists('//ForFromStatNode', "//InlinedGeneratorExpressionNode", "//ReturnStatNode//InlinedGeneratorExpressionNode", "//ReturnStatNode//CoerceToPyTypeNode//InlinedGeneratorExpressionNode") @cython.test_fail_if_path_exists('//SimpleCallNode', '//CoerceFromPyTypeNode//InlinedGeneratorExpressionNode', '//TypecastNode//InlinedGeneratorExpressionNode', '//ForInStatNode') def return_range_sum_cast(int N): """ >>> sum(range(10)) 45 >>> return_range_sum_cast(10) 45 """ return sum(i for i in range(N)) @cython.test_assert_path_exists('//ForFromStatNode', "//InlinedGeneratorExpressionNode") @cython.test_fail_if_path_exists('//SimpleCallNode', '//ForInStatNode') def return_range_sum(int N): """ >>> sum(range(10)) 45 >>> return_range_sum(10) 45 """ return sum(i for i in range(N)) @cython.test_assert_path_exists('//ForFromStatNode', "//InlinedGeneratorExpressionNode") @cython.test_fail_if_path_exists('//SimpleCallNode', '//ForInStatNode') def return_range_sum_squares(int N): """ >>> sum([i*i for i in range(10)]) 285 >>> return_range_sum_squares(10) 285 >>> print(sum([i*i for i in range(10000)])) 333283335000 >>> print(return_range_sum_squares(10000)) 333283335000 """ return sum(i*i for i in range(N)) @cython.test_assert_path_exists('//ForInStatNode', "//InlinedGeneratorExpressionNode") @cython.test_fail_if_path_exists('//SimpleCallNode') def return_sum_squares(seq): """ >>> sum([i*i for i in range(10)]) 285 >>> return_sum_squares(range(10)) 285 >>> print(sum([i*i for i in range(10000)])) 333283335000 >>> print(return_sum_squares(range(10000))) 333283335000 """ return sum(i*i for i in seq) @cython.test_assert_path_exists('//ForInStatNode', "//InlinedGeneratorExpressionNode") @cython.test_fail_if_path_exists('//SimpleCallNode') def return_sum_squares_start(seq, int start): """ >>> sum([i*i for i in range(10)], -1) 284 >>> return_sum_squares_start(range(10), -1) 284 >>> print(sum([i*i for i in range(10000)], 9)) 333283335009 >>> print(return_sum_squares_start(range(10000), 9)) 333283335009 """ return sum((i*i for i in seq), start) @cython.test_assert_path_exists( '//ForInStatNode', "//InlinedGeneratorExpressionNode") @cython.test_fail_if_path_exists( '//SimpleCallNode', "//InlinedGeneratorExpressionNode//CoerceToPyTypeNode") def return_typed_sum_squares_start(seq, int start): """ >>> sum([i*i for i in range(10)], -1) 284 >>> return_typed_sum_squares_start(range(10), -1) 284 >>> print(sum([i*i for i in range(1000)], 9)) 332833509 >>> print(return_typed_sum_squares_start(range(1000), 9)) 332833509 """ cdef int i return sum((i*i for i in seq), start) @cython.test_assert_path_exists('//ForInStatNode', "//InlinedGeneratorExpressionNode") @cython.test_fail_if_path_exists('//SimpleCallNode') def return_sum_of_listcomp_consts_start(seq, int start): """ >>> sum([1 for i in range(10) if i > 3], -1) 5 >>> return_sum_of_listcomp_consts_start(range(10), -1) 5 >>> print(sum([1 for i in range(10000) if i > 3], 9)) 10005 >>> print(return_sum_of_listcomp_consts_start(range(10000), 9)) 10005 """ return sum([1 for i in seq if i > 3], start) @cython.test_assert_path_exists('//ForInStatNode', "//InlinedGeneratorExpressionNode", # the next test is for a deficiency # (see InlinedGeneratorExpressionNode.coerce_to()), # hope this breaks one day "//CoerceFromPyTypeNode//InlinedGeneratorExpressionNode") @cython.test_fail_if_path_exists('//SimpleCallNode') def return_typed_sum_of_listcomp_consts_start(seq, int start): """ >>> sum([1 for i in range(10) if i > 3], -1) 5 >>> return_typed_sum_of_listcomp_consts_start(range(10), -1) 5 >>> print(sum([1 for i in range(10000) if i > 3], 9)) 10005 >>> print(return_typed_sum_of_listcomp_consts_start(range(10000), 9)) 10005 """ return sum([1 for i in seq if i > 3], start) @cython.test_assert_path_exists( '//ForInStatNode', "//InlinedGeneratorExpressionNode") @cython.test_fail_if_path_exists( '//SimpleCallNode', "//InlinedGeneratorExpressionNode//CoerceToPyTypeNode") def return_typed_sum_cond_exp(seq): """ >>> return_typed_sum_cond_exp([1,2,3,4]) 2 """ cdef int i return sum( 0 if i%2 else 1 for i in seq ) @cython.test_assert_path_exists( '//ForInStatNode', "//InlinedGeneratorExpressionNode") @cython.test_fail_if_path_exists( '//SimpleCallNode', "//InlinedGeneratorExpressionNode//CoerceToPyTypeNode") def return_typed_sum_cond_exp_in(seq): """ >>> return_typed_sum_cond_exp_in([1,2,3,4,5,6,7,8,9]) 3 """ cdef int i return sum( 0 if i%3 in (0,1) else 1 for i in seq ) Cython-0.23.4/tests/run/inlined_context_manager.pyx0000644000175600017570000000061712606202452023600 0ustar jenkinsjenkins00000000000000# mode: run cimport cython @cython.final cdef class TypedContextManager(object): cdef double __enter__(self): # not callable from Python ! return 2.0 # FIXME: inline __exit__() as well def __exit__(self, exc_type, exc_value, exc_tb): return 0 def with_statement(): """ >>> with_statement() 2.0 """ with TypedContextManager() as x: return x Cython-0.23.4/tests/run/inline.pyx0000644000175600017570000000020312606202452020165 0ustar jenkinsjenkins00000000000000def test(x): """ >>> test(3) 3 """ return retinput(x) cdef inline int retinput(int x): o = x return o Cython-0.23.4/tests/run/initial_file_path.srctree0000644000175600017570000000453012606202452023211 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import my_test_package as p; assert not p.__file__.rstrip('co').endswith('.py'), p.__file__; p.test()" PYTHON -c "import my_test_package.a as a; a.test()" PYTHON -c "import my_test_package.another as p; assert not p.__file__.rstrip('co').endswith('.py'), p.__file__; p.test()" PYTHON -c "import my_test_package.another.a as a; a.test()" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize(["my_test_package/**/*.py"]), ) ######## my_test_package/__init__.py ######## # cython: set_initial_path=SOURCEFILE initial_path = __path__ initial_file = __file__ try: from . import a import_error = None except ImportError as e: import_error = e import traceback traceback.print_exc() def test(): print "FILE: ", initial_file print "PATH: ", initial_path assert initial_path[0].endswith('my_test_package'), initial_path assert initial_file.endswith('__init__.py'), initial_file assert import_error is None, import_error ######## my_test_package/another/__init__.py ######## # cython: set_initial_path=SOURCEFILE initial_path = __path__ initial_file = __file__ try: from . import a import_error = None except ImportError as e: import_error = e import traceback traceback.print_exc() def test(): print "FILE: ", initial_file print "PATH: ", initial_path assert initial_path[0].endswith('another'), initial_path assert initial_file.endswith('__init__.py'), initial_file assert import_error is None, import_error ######## my_test_package/a.py ######## # cython: set_initial_path=SOURCEFILE initial_file = __file__ try: initial_path = __path__ except NameError: got_name_error = True else: got_name_error = False def test(): assert initial_file.endswith('a.py'), initial_file assert got_name_error, "looks like __path__ was set at module init time: " + initial_path ######## my_test_package/another/a.py ######## # cython: set_initial_path=SOURCEFILE initial_file = __file__ try: initial_path = __path__ except NameError: got_name_error = True else: got_name_error = False def test(): assert initial_file.endswith('a.py'), initial_file assert got_name_error, "looks like __path__ was set at module init time: " + initial_path Cython-0.23.4/tests/run/inherited_final_method.pyx0000644000175600017570000000105512606202452023401 0ustar jenkinsjenkins00000000000000# mode: run # tag: exttype, final cimport cython cdef class BaseClass: """ >>> obj = BaseClass() >>> obj.call_base() True """ cdef method(self): return True def call_base(self): return self.method() @cython.final cdef class Child(BaseClass): """ >>> obj = Child() >>> obj.call_base() True >>> obj.call_child() True """ cdef method(self): return True def call_child(self): # original bug: this requires a proper cast for self return self.method() Cython-0.23.4/tests/run/inhcmethcall.pyx0000644000175600017570000000045212606202452021350 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> p = Norwegian() >>> p.describe() Norwegian Parrot """ cdef class Parrot: cdef void _describe(self): print u"Parrot" def describe(self): self._describe() cdef class Norwegian(Parrot): cdef void _describe(self): print u"Norwegian" Parrot._describe(self) Cython-0.23.4/tests/run/index.pyx0000644000175600017570000002053212606202452020025 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> index_object(100, 100) # doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: 'int' object ... """ cdef Py_ssize_t maxsize import sys if sys.version_info < (2,5): __doc__ = __doc__.replace(u"'int' object ...", u'unsubscriptable object') maxsize = min(sys.maxint, 2**31-1) else: maxsize = getattr(sys, 'maxsize', getattr(sys, 'maxint', None)) py_maxsize = maxsize import cython def index_tuple(tuple t, int i): """ >>> index_tuple((1,1,2,3,5), 0) 1 >>> index_tuple((1,1,2,3,5), 3) 3 >>> index_tuple((1,1,2,3,5), -1) 5 >>> index_tuple((1,1,2,3,5), 100) Traceback (most recent call last): IndexError: tuple index out of range >>> index_tuple(None, 0) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable """ return t[i] def index_list(list L, int i): """ >>> index_list([2,3,5,7,11,13,17,19], 0) 2 >>> index_list([2,3,5,7,11,13,17,19], 5) 13 >>> index_list([2,3,5,7,11,13,17,19], -1) 19 >>> index_list([2,3,5,7,11,13,17,19], 100) Traceback (most recent call last): IndexError: list index out of range >>> index_list(None, 0) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable """ return L[i] def index_object(object o, int i): """ >>> index_object([2,3,5,7,11,13,17,19], 1) 3 >>> index_object([2,3,5,7,11,13,17,19], -1) 19 >>> index_object((1,1,2,3,5), 2) 2 >>> index_object((1,1,2,3,5), -2) 3 >>> index_object("abcdef...z", 0) 'a' >>> index_object("abcdef...z", -1) 'z' >>> index_object("abcdef...z", 100) Traceback (most recent call last): IndexError: string index out of range >>> try: index_object(None, 0) ... except TypeError: pass """ return o[i] def del_index_list(list L, Py_ssize_t index): """ >>> del_index_list(list(range(4)), 0) [1, 2, 3] >>> del_index_list(list(range(4)), 1) [0, 2, 3] >>> del_index_list(list(range(4)), -1) [0, 1, 2] >>> del_index_list(list(range(4)), py_maxsize) # doctest: +ELLIPSIS Traceback (most recent call last): IndexError: list... index out of range >>> del_index_list(list(range(4)), -py_maxsize) # doctest: +ELLIPSIS Traceback (most recent call last): IndexError: list... index out of range """ del L[index] return L def set_index_list(list L, Py_ssize_t index): """ >>> set_index_list(list(range(4)), 0) [5, 1, 2, 3] >>> set_index_list(list(range(4)), 1) [0, 5, 2, 3] >>> set_index_list(list(range(4)), -1) [0, 1, 2, 5] >>> set_index_list(list(range(4)), py_maxsize) # doctest: +ELLIPSIS Traceback (most recent call last): IndexError: list... index out of range >>> set_index_list(list(range(4)), -py_maxsize) # doctest: +ELLIPSIS Traceback (most recent call last): IndexError: list... index out of range """ L[index] = 5 return L # These make sure that our fast indexing works with large and unsigned types. def test_unsigned_long(): """ >>> test_unsigned_long() """ cdef int i cdef unsigned long ix cdef D = {} for i from 0 <= i < sizeof(unsigned long) * 8: ix = (1) << i D[ix] = True for i from 0 <= i < sizeof(unsigned long) * 8: ix = (1) << i assert D[ix] is True del D[ix] assert len(D) == 0 def test_unsigned_short(): """ >>> test_unsigned_short() """ cdef int i cdef unsigned short ix cdef D = {} for i from 0 <= i < sizeof(unsigned short) * 8: ix = (1) << i D[ix] = True for i from 0 <= i < sizeof(unsigned short) * 8: ix = (1) << i assert D[ix] is True del D[ix] assert len(D) == 0 def test_long_long(): """ >>> test_long_long() """ cdef int i cdef long long ix cdef D = {} for i from 0 <= i < sizeof(long long) * 8: ix = (1) << i D[ix] = True for i from 0 <= i < sizeof(long long) * 8: ix = (1) << i assert D[ix] is True del D[ix] L = [1, 2, 3] try: ix = py_maxsize + 1 except OverflowError: pass # can't test this here else: try: L[ix] = 5 except IndexError: pass else: assert False, "setting large index failed to raise IndexError" try: del L[ix] except IndexError: pass else: assert False, "deleting large index failed to raise IndexError" try: ix = -py_maxsize - 2 except OverflowError: pass # can't test this here else: try: L[ix] = 5 except IndexError: pass else: assert False, "setting large index failed to raise IndexError" try: del L[ix] except IndexError: pass else: assert False, "deleting large index failed to raise IndexError" assert len(D) == 0 def test_ulong_long(): """ >>> test_ulong_long() """ cdef unsigned long long ix L = [1, 2, 3] try: ix = py_maxsize + 1 except OverflowError: pass # can't test this here else: try: L[ix] = 5 except IndexError: pass else: assert False, "setting large index failed to raise IndexError" try: del L[ix] except IndexError: pass else: assert False, "deleting large index failed to raise IndexError" @cython.boundscheck(False) def test_boundscheck_unsigned(list L, tuple t, object o, unsigned long ix): """ >>> test_boundscheck_unsigned([1, 2, 4], (1, 2, 4), [1, 2, 4], 2) (4, 4, 4) >>> test_boundscheck_unsigned([1, 2, 4], (1, 2, 4), "", 2) Traceback (most recent call last): ... IndexError: string index out of range """ return L[ix], t[ix], o[ix] @cython.boundscheck(False) def test_boundscheck_signed(list L, tuple t, object o, long ix): """ >>> test_boundscheck_signed([1, 2, 4], (1, 2, 4), [1, 2, 4], 2) (4, 4, 4) >>> test_boundscheck_signed([1, 2, 4], (1, 2, 4), "", 2) Traceback (most recent call last): ... IndexError: string index out of range """ return L[ix], t[ix], o[ix] @cython.wraparound(False) def test_wraparound_signed(list L, tuple t, object o, long ix): """ >>> test_wraparound_signed([1, 2, 4], (1, 2, 4), [1, 2, 4], 2) (4, 4, 4) >>> test_wraparound_signed([1, 2, 4], (1, 2, 4), "", 2) Traceback (most recent call last): ... IndexError: string index out of range """ return L[ix], t[ix], o[ix] def large_literal_index(object o): """ >>> large_literal_index({1000000000000000000000000000000: True}) True """ return o[1000000000000000000000000000000] class LargeIndexable(object): expected = None def __len__(self): raise OverflowError def __getitem__(self, index): return index def __setitem__(self, index, value): assert index == value == self.expected self.expected = None def __delitem__(self, index): assert self.expected == index self.expected = None def test_large_indexing(obj): """ >>> obj = LargeIndexable() >>> zero, pone, none, pmaxsize, nmaxsize = test_large_indexing(obj) >>> # , p2maxsize, n2maxsize >>> zero 0 >>> pone 1 >>> none -1 >>> pmaxsize == py_maxsize True >>> nmaxsize == -py_maxsize True #>>> p2maxsize == py_maxsize*2 #True #>>> n2maxsize == -py_maxsize*2 #True """ return ( obj[0], obj[1], obj[-1], obj[maxsize], obj[-maxsize], #obj[maxsize*2], obj[-maxsize*2] # FIXME! ) def del_large_index(obj, Py_ssize_t index): """ >>> obj = LargeIndexable() >>> del_large_index(obj, 0) >>> del_large_index(obj, 1) >>> del_large_index(obj, -1) >>> del_large_index(obj, py_maxsize) >>> del_large_index(obj, -py_maxsize) """ obj.expected = index del obj[index] assert obj.expected is None def set_large_index(obj, Py_ssize_t index): """ >>> obj = LargeIndexable() >>> set_large_index(obj, 0) >>> set_large_index(obj, 1) >>> set_large_index(obj, -1) >>> set_large_index(obj, py_maxsize) >>> set_large_index(obj, -py_maxsize) """ obj.expected = index obj[index] = index assert obj.expected is None Cython-0.23.4/tests/run/include.pyx0000644000175600017570000000015212606202452020335 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> D 2 >>> XYZ 5 """ D = 1 include "testinclude.pxi" include "includes/includefile.pxi" Cython-0.23.4/tests/run/in_list_with_side_effects_T544.pyx0000644000175600017570000000100212606202452024624 0ustar jenkinsjenkins00000000000000# ticket: 544 def count(i=[0]): i[0] += 1 return i[0] def test(x): """ >>> def py_count(i=[0]): ... i[0] += 1 ... return i[0] >>> 1 in (py_count(), py_count(), py_count(), py_count()) True >>> 4 in (py_count(), py_count(), py_count(), py_count()) False >>> 12 in (py_count(), py_count(), py_count(), py_count()) True >>> test(1) True >>> test(4) False >>> test(12) True """ return x in (count(), count(), count(), count()) Cython-0.23.4/tests/run/importfrom.pyx0000644000175600017570000000241112606202452021110 0ustar jenkinsjenkins00000000000000from distutils import cmd, core, version def import1(): """ >>> import1() == (cmd, core, version) True """ from distutils import ( cmd, core, version) return cmd, core, version def import2(): """ >>> import2() == (cmd, core, version) True """ from distutils import (cmd, core, version ) return cmd, core, version def import3(): """ >>> import3() == (cmd, core, version) True """ from distutils import (cmd, core,version) return cmd, core, version def import4(): """ >>> import4() == (cmd, core, version) True """ from distutils import cmd, core, version return cmd, core, version def typed_imports(): """ >>> typed_imports() True True an integer is required Expected type, got int """ import sys import types cdef long maxunicode cdef type t from sys import maxunicode print(maxunicode == sys.maxunicode) from types import ModuleType as t print(t is types.ModuleType) try: from sys import version_info as maxunicode except TypeError, e: print(e) try: from sys import maxunicode as t except TypeError, e: print(e) Cython-0.23.4/tests/run/importas.pyx0000644000175600017570000000143712606202452020557 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> import sys as sous >>> import distutils.core as corey >>> from copy import deepcopy as copey >>> import distutils.command as commie >>> sous is _sous True >>> corey is _corey True >>> copey is _copey True >>> _commie is commie True >>> _sous is not None True >>> _corey is not None True >>> _copey is not None True >>> _commie is not None True >>> print(_sous.__name__) sys >>> print(sous.__name__) sys >>> print(_corey.__name__) distutils.core >>> print(corey.__name__) distutils.core >>> print(_copey.__name__) deepcopy >>> print(copey.__name__) deepcopy >>> print(_commie.__name__) distutils.command >>> print(commie.__name__) distutils.command """ import sys as _sous import distutils.core as _corey from copy import deepcopy as _copey import distutils.command as _commie Cython-0.23.4/tests/run/import_star.pyx0000644000175600017570000000153212606202452021260 0ustar jenkinsjenkins00000000000000# mode: run cdef object executable, version_info cdef long hexversion ctypedef struct MyStruct: int x, y, z # conversion code for this struct will be generated but not used # (there used to be a problem getting Cython conversion code generated here) cdef MyStruct _no_such_name_ = MyStruct(1, 2, 3) from sys import * def test_cdefed_objects(): """ >>> ex, vi = test_cdefed_objects() >>> assert ex is not None >>> assert vi is not None """ return executable, version_info def test_cdefed_cvalues(): """ >>> hexver = test_cdefed_cvalues() >>> assert hexver is not None >>> assert hexver > 0x02020000 """ return hexversion def test_non_cdefed_names(): """ >>> mod, pth = test_non_cdefed_names() >>> assert mod is not None >>> assert pth is not None """ return modules, path Cython-0.23.4/tests/run/import_error_T734.py0000644000175600017570000000034412606202452021771 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 734 def test_import_error(): """ >>> test_import_error() # doctest: +ELLIPSIS Traceback (most recent call last): ImportError: cannot import name ...xxx... """ from sys import xxx Cython-0.23.4/tests/run/ifelseexpr_T267.pyx0000644000175600017570000000145512606202452021611 0ustar jenkinsjenkins00000000000000# mode: run # tag: condexpr # ticket: 267 cimport cython def ident(x): return x def constants(x): """ >>> constants(4) 1 >>> constants(5) 10 """ a = 1 if x < 5 else 10 return a def temps(x): """ >>> temps(4) 1 >>> temps(5) 10 """ return ident(1) if ident(x) < ident(5) else ident(10) def nested(x): """ >>> nested(1) 1 >>> nested(2) 2 >>> nested(3) 3 """ a = 1 if x == 1 else (2 if x == 2 else 3) return a @cython.test_fail_if_path_exists('//CondExprNode') def const_true(a,b): """ >>> const_true(1,2) 1 """ return a if 1 == 1 else b @cython.test_fail_if_path_exists('//CondExprNode') def const_false(a,b): """ >>> const_false(1,2) 2 """ return a if 1 != 1 else b Cython-0.23.4/tests/run/if_else_expr_cpp_helper.h0000644000175600017570000000032612606202452023171 0ustar jenkinsjenkins00000000000000class Holder { public: int value; Holder() : value(-1) { } Holder(int value) : value(value) { } }; Holder v1(1); Holder v2(2); Holder& get_v1() { return v1; } Holder& get_v2() { return v2; } Cython-0.23.4/tests/run/if_else_expr_cpp.pyx0000644000175600017570000000134712606202452022227 0ustar jenkinsjenkins00000000000000# mode: run # tag: condexpr, cpp cdef extern from "if_else_expr_cpp_helper.h": cdef cppclass Holder: int value Holder() Holder(int value) cdef Holder v1 cdef Holder v2 cdef Holder& get_v1() cdef Holder& get_v2() cdef reset() : v1.value = 1 v2.value = 2 def test_one_ref(bint b): """ >>> test_one_ref(False) 1 >>> test_one_ref(True) 100 """ reset() return (Holder(100) if b else get_v1()).value def test_both_ref(bint b): """ >>> test_both_ref(False) (1, 100) >>> test_both_ref(True) (100, 2) """ reset() try: (get_v1() if b else get_v2()).value = 100 return v1.value, v2.value finally: reset() Cython-0.23.4/tests/run/if_else_expr.pyx0000644000175600017570000000162512606202452021364 0ustar jenkinsjenkins00000000000000# mode: run # tag: condexpr cimport cython cdef class Foo: cdef dict data def __repr__(self): return '' cpdef test_type_cast(Foo obj, cond): """ # Regression test: obj must be cast to (PyObject *) here >>> test_type_cast(Foo(), True) [] >>> test_type_cast(Foo(), False) """ return [obj] if cond else obj cdef func(Foo foo, dict data): return foo, data @cython.test_fail_if_path_exists('//PyTypeTestNode') def test_cpp_pyobject_cast(Foo obj1, Foo obj2, cond): """ >>> test_cpp_pyobject_cast(Foo(), Foo(), True) (, None) """ return func(obj1 if cond else obj2, obj1.data if cond else obj2.data) def test_charptr_coercion(x): """ >>> print(test_charptr_coercion(True)) abc >>> print(test_charptr_coercion(False)) def """ cdef char* s = b'abc' if x else b'def' return s.decode('ascii') Cython-0.23.4/tests/run/if_const.pyx0000644000175600017570000001015212606202452020517 0ustar jenkinsjenkins00000000000000 cimport cython DEF INT_VAL = 1 def _not_constant_but_False(): return False @cython.test_fail_if_path_exists("//PrimaryCmpNode", "//IfStatNode") def int_bool_result(): """ >>> int_bool_result() True """ if 5: return True else: return False @cython.test_fail_if_path_exists("//IfStatNode") def constant_if_elif_else(): """ >>> constant_if_elif_else() True """ if 0: return False elif 5: return True else: return False @cython.test_fail_if_path_exists("//PrintStatNode") @cython.test_assert_path_exists("//IfStatNode", "//IfClauseNode") def non_constant_if_elif_else1(): """ >>> non_constant_if_elif_else1() True """ if _not_constant_but_False(): return False elif 5: return True else: print(False) @cython.test_fail_if_path_exists("//PrintStatNode") @cython.test_assert_path_exists("//IfStatNode", "//IfClauseNode") def non_constant_if_elif_else2(): """ >>> non_constant_if_elif_else2() True """ if _not_constant_but_False(): return False elif 0: print(False) else: return True @cython.test_fail_if_path_exists("//PrimaryCmpNode", "//IfStatNode") def if_not_compare_true(): """ >>> if_not_compare_true() False """ if not 0 == 0: return True else: return False @cython.test_fail_if_path_exists("//PrimaryCmpNode", "//IfStatNode") def if_compare_true(): """ >>> if_compare_true() True """ if 0 == 0: return True else: return False @cython.test_fail_if_path_exists("//PrimaryCmpNode", "//IfStatNode") def if_compare_false(): """ >>> if_compare_false() False """ if 0 == 1: return True else: return False @cython.test_fail_if_path_exists("//PrimaryCmpNode", "//IfStatNode") def if_compare_or_true(): """ >>> if_compare_or_true() True """ if 0 == 1 or 1 == 1: return True else: return False @cython.test_fail_if_path_exists("//PrimaryCmpNode", "//IfStatNode") def if_compare_or_false(): """ >>> if_compare_or_false() False """ if 0 == 1 or 1 == 0: return True else: return False @cython.test_fail_if_path_exists("//PrimaryCmpNode", "//IfStatNode") def if_compare_and_true(): """ >>> if_compare_and_true() True """ if 0 == 0 and 1 == 1: return True else: return False @cython.test_fail_if_path_exists("//PrimaryCmpNode", "//IfStatNode") def if_compare_and_false(): """ >>> if_compare_and_false() False """ if 1 == 1 and 1 == 0: return True else: return False @cython.test_fail_if_path_exists("//PrimaryCmpNode", "//IfStatNode") def if_compare_cascaded(): """ >>> if_compare_cascaded() True """ if 0 < 1 < 2 < 3: return True else: return False @cython.test_fail_if_path_exists("//CoerceToBooleanNode", "//ListNode", "//IfStatNode") def list_bool_result_true(): """ >>> list_bool_result_true() True """ if [1,2,3]: return True else: return False @cython.test_fail_if_path_exists("//CoerceToBooleanNode", "//ListNode", "//IfStatNode") def list_bool_result_false(): """ >>> list_bool_result_false() False """ if []: return True else: return False @cython.test_fail_if_path_exists("//PrimaryCmpNode", "//IfStatNode") def compile_time_DEF_if(): """ >>> compile_time_DEF_if() True """ if INT_VAL != 0: return True else: return False Cython-0.23.4/tests/run/if.pyx0000644000175600017570000000151212606202452017311 0ustar jenkinsjenkins00000000000000def f(a, b): """ >>> f(0,0) 0 >>> f(1,2) 2 >>> f(1,-1) 1 """ x = 0 if a: x = 1 if a+b: x = 2 return x def g(a, b): """ >>> g(1,2) 1 >>> g(0,2) 2 >>> g(0,0) 0 """ x = 0 if a: x = 1 elif b: x = 2 return x def h(a, b): """ >>> h(1,2) 1 >>> h(0,2) 2 >>> h(0,0) 3 """ x = 0 if a: x = 1 elif b: x = 2 else: x = 3 return x try: import __builtin__ as builtins except ImportError: import builtins def i(a, b): """ >>> i(1,2) 1 >>> i(2,2) 2 >>> i(2,1) 0 """ x = 0 if builtins.str(a).upper() == u"1": x = 1 if builtins.str(a+b).lower() not in (u"1", u"3"): x = 2 return x Cython-0.23.4/tests/run/hash_T326.pyx0000644000175600017570000000107212606202452020355 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 326 # tag: hash cdef class A: """ >>> hash(A(5)) 5 >>> hash(A(-1)) -2 >>> hash(A(-2)) -2 >>> hash(A(100)) Traceback (most recent call last): ... TypeError: That's kind of a round number... """ cdef long a def __init__(self, a): self.a = a def __hash__(self): if self.a == 100: raise TypeError, u"That's kind of a round number..." else: return self.a cpdef long __hash__(long x): """ >>> __hash__(-1) -1 """ return x Cython-0.23.4/tests/run/hasattr.pyx0000644000175600017570000000121312606202452020357 0ustar jenkinsjenkins00000000000000class Foo: @property def foo(self): return None @property def bar(self): raise AttributeError @property def baz(self): return int(1)/int(0) def wrap_hasattr(obj, name): """ >>> wrap_hasattr(None, "abc") False >>> wrap_hasattr(list, "append") True >>> wrap_hasattr(Foo(), "foo") True >>> wrap_hasattr(Foo(), "spam") False >>> wrap_hasattr(Foo(), "bar") False >>> Foo().baz #doctest: +ELLIPSIS Traceback (most recent call last): ... ZeroDivisionError: ... >>> wrap_hasattr(Foo(), "baz") False """ return hasattr(obj, name) Cython-0.23.4/tests/run/getattr3call.pyx0000644000175600017570000000175412606202452021314 0ustar jenkinsjenkins00000000000000 class test(object): a = 1 t = test() def getattr2_literal_unicode(a): """ >>> getattr2_literal_unicode(t) 1 >>> getattr2_literal_unicode(object()) Traceback (most recent call last): AttributeError: 'object' object has no attribute 'a' """ return getattr(a, u"a") def getattr3_literal_unicode(a, b): """ >>> getattr3_literal_unicode(t, 2) (1, 2) """ return getattr(a, u"a", b), getattr(a, u"b", b) def getattr2_simple(a, b): """ >>> getattr2_simple(t, 'a') 1 >>> getattr2_simple(t, 'b') Traceback (most recent call last): AttributeError: 'test' object has no attribute 'b' """ return getattr(a, b) def getattr3_explicit(a, b, c): """ >>> getattr3_explicit(t, 'a', 2) 1 >>> getattr3_explicit(t, 'b', 2) 2 """ return getattr3(a, b, c) def getattr3_args(a, b, c): """ >>> getattr3_args(t, 'a', 2) 1 >>> getattr3_args(t, 'b', 2) 2 """ return getattr(a, b, c) Cython-0.23.4/tests/run/genexpr_iterable_lookup_T600.pyx0000644000175600017570000000406012606202452024335 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 600 # tag: genexpr # cython: language_level=3 cimport cython #@cython.test_assert_path_exists('//ComprehensionNode') #@cython.test_fail_if_path_exists('//SimpleCallNode') def list_genexpr_iterable_lookup(): """ >>> x = (0,1,2,3,4,5) >>> [ x*2 for x in x if x % 2 == 0 ] # leaks in Py2 but finds the right 'x' [0, 4, 8] >>> list_genexpr_iterable_lookup() [0, 4, 8] """ x = (0,1,2,3,4,5) result = list( x*2 for x in x if x % 2 == 0 ) assert x == (0,1,2,3,4,5) return result #@cython.test_assert_path_exists('//ComprehensionNode') #@cython.test_fail_if_path_exists('//SingleAssignmentNode//SimpleCallNode') def genexpr_iterable_in_closure(): """ >>> genexpr_iterable_in_closure() ['aa', 'cc'] """ x = 'abc' def f(): return x result = list( x*2 for x in x if x != 'b' ) assert x == 'abc' # don't leak in Py3 code assert f() == 'abc' # don't leak in Py3 code return result def genexpr_over_complex_arg(func, L): """ >>> class wrapper(object): ... value = 5 >>> genexpr_over_complex_arg(list, wrapper()) [5] """ return func(d for d in set([type(L).value, L.__class__.value, L.value])) def listcomp(): """ >>> listcomp() """ data = [('red', 5), ('blue', 1), ('yellow', 8), ('black', 0)] data.sort(key=lambda r: r[1]) keys = [r[1] for r in data] return keys def genexpr_in_listcomp(L): """ >>> genexpr_in_listcomp( [[1,2,3]]*2 ) [[1, 2, 3], [1, 2, 3]] """ return list(d for d in [list(d for d in d) for d in L]) @cython.test_assert_path_exists('//ForFromStatNode') def genexpr_range_in_listcomp(L): """ >>> genexpr_range_in_listcomp( [1,2,3] ) [[0], [0, 1], [0, 1, 2]] """ cdef int z,d return [list(d for d in range(z)) for z in L] @cython.test_fail_if_path_exists('//ForInStatNode') def genexpr_in_dictcomp_dictiter(): """ >>> sorted(genexpr_in_dictcomp_dictiter()) [1, 5] """ d = {1:2, 3:4, 5:6} return {k:d for k,d in d.iteritems() if d != 4} Cython-0.23.4/tests/run/genexpr_T715.pyx0000644000175600017570000000045412606202452021107 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 715 # tag: genexpr, comprehension def t715(*items): """ # Blocked by T724 # >>> [list(i) for i in t715([1, 2, 3], [4, 5, 6])] # [[1, 2, 3], [4, 5, 6]] >>> [list(i) for i in t715([1, 2, 3])] [[1, 2, 3]] """ return [(j for j in i) for i in items] Cython-0.23.4/tests/run/genexpr_T491.pyx0000644000175600017570000000145112606202452021106 0ustar jenkinsjenkins00000000000000# ticket: 491 def test_genexpr(): """ >>> gen = test_genexpr() >>> list(gen) [0, 1, 2, 3, 4] """ return (i for i in range(5)) def test_genexpr_typed(): """ >>> gen = test_genexpr_typed() >>> list(gen) [0, 1, 2, 3, 4] """ cdef int i return (i for i in range(5)) def test_genexpr_funccall(): """ >>> test_genexpr_funccall() [0, 1, 2, 3, 4] """ return list(i for i in range(5)) def test_genexpr_scope(): """ >>> test_genexpr_scope() ([0, 1, 2, 3, 4], 'abc') """ i = 'abc' gen = (i for i in range(5)) lst = list(gen) return lst, i def test_genexpr_closure(): """ >>> gen = test_genexpr_closure() >>> list(gen) ['a', 'b', 'c'] """ abc = 'a' + 'b' + 'c' return (c for c in abc) Cython-0.23.4/tests/run/generators_py.py0000644000175600017570000001561612606202452021416 0ustar jenkinsjenkins00000000000000# mode: run # tag: generators import cython def very_simple(): """ >>> x = very_simple() >>> next(x) 1 >>> next(x) Traceback (most recent call last): StopIteration >>> next(x) Traceback (most recent call last): StopIteration >>> x = very_simple() >>> x.send(1) Traceback (most recent call last): TypeError: can't send non-None value to a just-started generator """ yield 1 def simple(): """ >>> x = simple() >>> list(x) [1, 2, 3] """ yield 1 yield 2 yield 3 def simple_seq(seq): """ >>> x = simple_seq("abc") >>> list(x) ['a', 'b', 'c'] """ for i in seq: yield i def simple_send(): """ >>> x = simple_send() >>> next(x) >>> x.send(1) 1 >>> x.send(2) 2 >>> x.send(3) 3 """ i = None while True: i = yield i def raising(): """ >>> x = raising() >>> next(x) Traceback (most recent call last): KeyError: 'foo' >>> next(x) Traceback (most recent call last): StopIteration """ yield {}['foo'] def with_outer(*args): """ >>> x = with_outer(1, 2, 3) >>> list(x()) [1, 2, 3] """ def generator(): for i in args: 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(): """ >>> x = test_close() >>> x.close() >>> x = test_close() >>> next(x) >>> x.close() >>> next(x) Traceback (most recent call last): StopIteration """ while True: yield def test_ignore_close(): """ >>> x = test_ignore_close() >>> x.close() >>> x = test_ignore_close() >>> next(x) >>> x.close() Traceback (most recent call last): RuntimeError: generator ignored GeneratorExit """ try: yield except GeneratorExit: yield def check_throw(): """ >>> x = check_throw() >>> x.throw(ValueError) Traceback (most recent call last): ValueError >>> next(x) Traceback (most recent call last): StopIteration >>> x = check_throw() >>> next(x) >>> x.throw(ValueError) >>> next(x) >>> x.throw(IndexError, "oops") Traceback (most recent call last): IndexError: oops >>> next(x) Traceback (most recent call last): StopIteration """ while True: try: yield except ValueError: pass def check_yield_in_except(): """ >>> import sys >>> orig_exc = sys.exc_info()[0] >>> g = check_yield_in_except() >>> next(g) >>> next(g) >>> orig_exc is sys.exc_info()[0] or sys.exc_info()[0] True """ try: yield raise ValueError except ValueError: yield def yield_in_except_throw_exc_type(): """ >>> import sys >>> g = yield_in_except_throw_exc_type() >>> next(g) >>> g.throw(TypeError) Traceback (most recent call last): TypeError >>> next(g) Traceback (most recent call last): StopIteration """ try: raise ValueError except ValueError: yield def yield_in_except_throw_instance(): """ >>> import sys >>> g = yield_in_except_throw_instance() >>> next(g) >>> g.throw(TypeError()) Traceback (most recent call last): TypeError >>> next(g) Traceback (most recent call last): StopIteration """ try: raise ValueError except ValueError: yield def test_swap_assignment(): """ >>> gen = test_swap_assignment() >>> next(gen) (5, 10) >>> next(gen) (10, 5) """ x,y = 5,10 yield (x,y) x,y = y,x # no ref-counting here yield (x,y) class Foo(object): """ >>> obj = Foo() >>> list(obj.simple(1, 2, 3)) [1, 2, 3] """ def simple(self, *args): for i in args: yield i def test_nested(a, b, c): """ >>> obj = test_nested(1, 2, 3) >>> [i() for i in obj] [1, 2, 3, 4] """ def one(): return a def two(): return b def three(): return c def new_closure(a, b): def sum(): return a + b return sum yield one yield two yield three yield new_closure(a, c) def tolist(func): def wrapper(*args, **kwargs): return list(func(*args, **kwargs)) return wrapper @tolist def test_decorated(*args): """ >>> test_decorated(1, 2, 3) [1, 2, 3] """ for i in args: yield i def test_return(a): """ >>> d = dict() >>> obj = test_return(d) >>> next(obj) 1 >>> next(obj) Traceback (most recent call last): StopIteration >>> d['i_was_here'] True """ yield 1 a['i_was_here'] = True return def test_copied_yield(foo): """ >>> class Manager(object): ... def __enter__(self): ... return self ... def __exit__(self, type, value, tb): ... pass >>> list(test_copied_yield(Manager())) [1] """ with foo: yield 1 def test_nested_yield(): """ >>> obj = test_nested_yield() >>> next(obj) 1 >>> obj.send(2) 2 >>> obj.send(3) 3 >>> obj.send(4) Traceback (most recent call last): StopIteration """ yield (yield (yield 1)) def test_sum_of_yields(n): """ >>> g = test_sum_of_yields(3) >>> next(g) (0, 0) >>> g.send(1) (0, 1) >>> g.send(1) (1, 2) """ x = 0 x += yield (0, x) x += yield (0, x) yield (1, x) def test_nested_gen(n): """ >>> [list(a) for a in test_nested_gen(5)] [[], [0], [0, 1], [0, 1, 2], [0, 1, 2, 3]] """ for a in range(n): yield (b for b in range(a)) def test_lambda(n): """ >>> [i() for i in test_lambda(3)] [0, 1, 2] """ for i in range(n): yield lambda : i def test_generator_cleanup(): """ >>> g = test_generator_cleanup() >>> del g >>> g = test_generator_cleanup() >>> next(g) 1 >>> del g cleanup """ try: yield 1 finally: print('cleanup') def test_del_in_generator(): """ >>> [ s for s in test_del_in_generator() ] ['abcabcabc', 'abcabcabc'] """ x = len('abc') * 'abc' a = x yield x del x yield a del a @cython.test_fail_if_path_exists("//IfStatNode", "//PrintStatNode") def test_yield_in_const_conditional_false(): """ >>> list(test_yield_in_const_conditional_false()) [] """ if False: print((yield 1)) @cython.test_fail_if_path_exists("//IfStatNode") @cython.test_assert_path_exists("//PrintStatNode") def test_yield_in_const_conditional_true(): """ >>> list(test_yield_in_const_conditional_true()) None [1] """ if True: print((yield 1)) Cython-0.23.4/tests/run/generators_pep479.pyx0000644000175600017570000000601712606202452022201 0ustar jenkinsjenkins00000000000000# mode: run # tag: generators, pep479 from __future__ import generator_stop import sys if sys.version_info[0] >= 3: # additionally test exception chaining __doc__ = u""" >>> g = test_raise_StopIteration_value() >>> next(g) 1 >>> try: next(g) ... except RuntimeError as exc: ... print(type(exc.__context__) is StopIteration or type(exc.__context__), exc.__context__) ... else: ... print("NOT RAISED!") True huhu """ def test_raise_StopIteration(): """ >>> g = test_raise_StopIteration() >>> next(g) 1 >>> next(g) Traceback (most recent call last): RuntimeError: generator raised StopIteration """ yield 1 raise StopIteration def test_raise_StopIteration_value(): """ >>> g = test_raise_StopIteration_value() >>> next(g) 1 >>> next(g) Traceback (most recent call last): RuntimeError: generator raised StopIteration """ yield 1 raise StopIteration('huhu') def test_return(): """ >>> g = test_return() >>> next(g) 1 >>> next(g) Traceback (most recent call last): StopIteration """ yield 1 return def test_return_value(): """ >>> g = test_return_value() >>> next(g) 1 >>> next(g) Traceback (most recent call last): StopIteration: 2 """ yield 1 return 2 def test_propagate_StopIteration(it): """ >>> results = [] >>> for x in test_propagate_StopIteration(iter([])): ... results.append(x) Traceback (most recent call last): RuntimeError: generator raised StopIteration >>> results [] >>> for x in test_propagate_StopIteration(iter([1, 2])): ... results.append(x) Traceback (most recent call last): RuntimeError: generator raised StopIteration >>> results [1, 2] """ while True: yield next(it) def test_catch_StopIteration(it): """ >>> for x in test_catch_StopIteration(iter([])): ... print(x) >>> for x in test_catch_StopIteration(iter([1, 2])): ... print(x) 1 2 """ try: while True: yield next(it) except StopIteration: pass else: print("NOT RAISED!") def test_yield_from(it): """ >>> for x in test_yield_from(iter([])): ... print(x) >>> for x in test_yield_from(iter([1, 2])): ... print(x) 1 2 """ yield from it def test_yield_from_gen(): """ >>> for x in test_yield_from_gen(): ... print(x) 1 RETURN: 2 """ x = yield from test_return_value() print("RETURN: %s" % x) def test_genexpr(it): """ >>> list(test_genexpr(iter([]))) [] >>> list(test_genexpr(iter([1, 2]))) [1] >>> list(test_genexpr(iter([1]))) Traceback (most recent call last): RuntimeError: generator raised StopIteration >>> list(test_genexpr(iter([1, 2, 3]))) Traceback (most recent call last): RuntimeError: generator raised StopIteration >>> list(test_genexpr(iter([1, 2]))) [1] """ return (x for x in it if next(it)) Cython-0.23.4/tests/run/generators_in_refcycles.pyx0000644000175600017570000000134212606202452023612 0ustar jenkinsjenkins00000000000000 import sys def _next(it): if sys.version_info[0] >= 3: return next(it) else: return it.next() def test_reference_cycle_cleanup(): """ >>> import gc >>> delegator, gen, deleted = test_reference_cycle_cleanup() >>> _next(delegator(gen())) 123 >>> _ = gc.collect(); print(sorted(deleted)) ['bar', 'foo'] """ deleted = [] class Destructed(object): def __init__(self, name): self.name = name def __del__(self): deleted.append(self.name) def delegator(c): d = Destructed('foo') yield from c def gen(): d = Destructed('bar') while True: yield 123 return delegator, gen, deleted Cython-0.23.4/tests/run/generators.pyx0000644000175600017570000002263312606202452021073 0ustar jenkinsjenkins00000000000000# mode: run # tag: generators try: import backports_abc except ImportError: pass else: backports_abc.patch() try: from collections.abc import Generator except ImportError: try: from collections import Generator except ImportError: Generator = object # easy win def very_simple(): """ >>> x = very_simple() >>> next(x) 1 >>> next(x) Traceback (most recent call last): StopIteration >>> next(x) Traceback (most recent call last): StopIteration >>> x = very_simple() >>> x.send(1) Traceback (most recent call last): TypeError: can't send non-None value to a just-started generator """ yield 1 def attributes(): """ >>> x = attributes() >>> x.__name__ 'attributes' >>> x.__qualname__ 'attributes' >>> x.gi_running # before next() False >>> inner = next(x) >>> x.gi_running # after next() False >>> next(x) Traceback (most recent call last): StopIteration >>> x.gi_running # after termination False >>> y = inner() >>> y.__name__ '' >>> y.__qualname__ 'attributes..inner..' >>> y.__name__ = 123 Traceback (most recent call last): TypeError: __name__ must be set to a string object >>> y.__name__ '' >>> y.__qualname__ = None Traceback (most recent call last): TypeError: __qualname__ must be set to a string object >>> y.__qualname__ 'attributes..inner..' >>> y.__name__ = 'abc' >>> y.__name__ 'abc' >>> y.__name__ = None Traceback (most recent call last): TypeError: __name__ must be set to a string object >>> y.__name__ 'abc' >>> y.__qualname__ = 'huhu' >>> y.__qualname__ 'huhu' >>> y.__qualname__ = 123 Traceback (most recent call last): TypeError: __qualname__ must be set to a string object >>> y.__qualname__ 'huhu' """ def inner(): return (lambda : (yield 1)) yield inner() def simple(): """ >>> x = simple() >>> list(x) [1, 2, 3] """ yield 1 yield 2 yield 3 def simple_seq(seq): """ >>> x = simple_seq("abc") >>> list(x) ['a', 'b', 'c'] """ for i in seq: yield i def simple_send(): """ >>> x = simple_send() >>> next(x) >>> x.send(1) 1 >>> x.send(2) 2 >>> x.send(3) 3 """ i = None while True: i = yield i def raising(): """ >>> x = raising() >>> next(x) Traceback (most recent call last): KeyError: 'foo' >>> next(x) Traceback (most recent call last): StopIteration """ yield {}['foo'] def with_outer(*args): """ >>> x = with_outer(1, 2, 3) >>> list(x()) [1, 2, 3] """ def generator(): for i in args: 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(): """ >>> x = test_close() >>> x.close() >>> x = test_close() >>> next(x) >>> x.close() >>> next(x) Traceback (most recent call last): StopIteration """ while True: yield def test_ignore_close(): """ >>> x = test_ignore_close() >>> x.close() >>> x = test_ignore_close() >>> next(x) >>> x.close() Traceback (most recent call last): RuntimeError: generator ignored GeneratorExit """ try: yield except GeneratorExit: yield def check_throw(): """ >>> x = check_throw() >>> x.throw(ValueError) Traceback (most recent call last): ValueError >>> next(x) Traceback (most recent call last): StopIteration >>> x = check_throw() >>> next(x) >>> x.throw(ValueError) >>> next(x) >>> x.throw(IndexError, "oops") Traceback (most recent call last): IndexError: oops >>> next(x) Traceback (most recent call last): StopIteration """ while True: try: yield except ValueError: pass def test_first_assignment(): """ >>> gen = test_first_assignment() >>> next(gen) 5 >>> next(gen) 10 >>> next(gen) (5, 10) """ cdef x = 5 # first yield x cdef y = 10 # first yield y yield (x,y) def test_swap_assignment(): """ >>> gen = test_swap_assignment() >>> next(gen) (5, 10) >>> next(gen) (10, 5) """ x,y = 5,10 yield (x,y) x,y = y,x # no ref-counting here yield (x,y) class Foo(object): """ >>> obj = Foo() >>> list(obj.simple(1, 2, 3)) [1, 2, 3] """ def simple(self, *args): for i in args: yield i def generator_nonlocal(): """ >>> g = generator_nonlocal() >>> list(g(5)) [2, 3, 4, 5, 6] """ def f(x): def g(y): nonlocal x for i in range(y): x += 1 yield x return g return f(1) def test_nested(a, b, c): """ >>> obj = test_nested(1, 2, 3) >>> [i() for i in obj] [1, 2, 3, 4] """ def one(): return a def two(): return b def three(): return c def new_closure(a, b): def sum(): return a + b return sum yield one yield two yield three yield new_closure(a, c) def tolist(func): def wrapper(*args, **kwargs): return list(func(*args, **kwargs)) return wrapper @tolist def test_decorated(*args): """ >>> test_decorated(1, 2, 3) [1, 2, 3] """ for i in args: yield i def test_return(a): """ >>> d = dict() >>> obj = test_return(d) >>> next(obj) 1 >>> next(obj) Traceback (most recent call last): StopIteration >>> d['i_was_here'] True """ yield 1 a['i_was_here'] = True return def test_return_in_finally(a): """ >>> d = dict() >>> obj = test_return_in_finally(d) >>> next(obj) 1 >>> next(obj) Traceback (most recent call last): StopIteration >>> d['i_was_here'] True >>> d = dict() >>> obj = test_return_in_finally(d) >>> next(obj) 1 >>> obj.send(2) Traceback (most recent call last): StopIteration >>> d['i_was_here'] True >>> obj = test_return_in_finally(None) >>> next(obj) 1 >>> next(obj) Traceback (most recent call last): StopIteration >>> obj = test_return_in_finally(None) >>> next(obj) 1 >>> obj.send(2) Traceback (most recent call last): StopIteration """ yield 1 try: a['i_was_here'] = True finally: return def test_return_none_in_finally(a): """ >>> d = dict() >>> obj = test_return_none_in_finally(d) >>> next(obj) 1 >>> next(obj) Traceback (most recent call last): StopIteration >>> d['i_was_here'] True >>> obj = test_return_none_in_finally(None) >>> next(obj) 1 >>> next(obj) Traceback (most recent call last): StopIteration """ yield 1 try: a['i_was_here'] = True finally: return None def test_copied_yield(foo): """ >>> class Manager(object): ... def __enter__(self): ... return self ... def __exit__(self, type, value, tb): ... pass >>> list(test_copied_yield(Manager())) [1] """ with foo: yield 1 def test_nested_yield(): """ >>> obj = test_nested_yield() >>> next(obj) 1 >>> obj.send(2) 2 >>> obj.send(3) 3 >>> obj.send(4) Traceback (most recent call last): StopIteration """ yield (yield (yield 1)) def test_inside_lambda(): """ >>> obj = test_inside_lambda()() >>> next(obj) 1 >>> next(obj) 2 >>> next(obj) Traceback (most recent call last): StopIteration """ return lambda:((yield 1), (yield 2)) def test_nested_gen(int n): """ >>> [list(a) for a in test_nested_gen(5)] [[], [0], [0, 1], [0, 1, 2], [0, 1, 2, 3]] """ for a in range(n): yield (b for b in range(a)) def test_lambda(n): """ >>> [i() for i in test_lambda(3)] [0, 1, 2] """ for i in range(n): yield lambda : i def test_with_gil_section(): """ >>> list(test_with_gil_section()) [0, 1, 2] """ cdef int i with nogil: for i in range(3): with gil: yield i def test_double_with_gil_section(): """ >>> list(test_double_with_gil_section()) [0, 1, 2, 3] """ cdef int i,j with nogil: for i in range(2): with gil: with nogil: for j in range(2): with gil: yield i*2+j with nogil: pass with gil: pass def test_generator_abc(): """ >>> isinstance(test_generator_abc(), Generator) True >>> try: ... from collections.abc import Generator ... except ImportError: ... try: ... from collections import Generator ... except ImportError: ... Generator = object # easy win >>> isinstance(test_generator_abc(), Generator) True >>> isinstance((lambda:(yield))(), Generator) True """ yield 1 Cython-0.23.4/tests/run/generator_type_inference.pyx0000644000175600017570000000174612606202452023771 0ustar jenkinsjenkins00000000000000# mode: run # tag: typeinference, generators cimport cython def test_type_inference(): """ >>> list(test_type_inference()) [(2.0, 'double'), (2.0, 'double'), (2.0, 'double')] """ x = 1.0 for i in range(3): yield x * 2.0, cython.typeof(x) def test_unicode_loop(): """ >>> chars = list(test_unicode_loop()) 1 Py_UCS4 2 Py_UCS4 2 Py_UCS4 2 Py_UCS4 2 Py_UCS4 >>> len(chars) 4 >>> ''.join(chars) == 'abcd' True """ ustr = u'abcd' print 1, cython.typeof(ustr[0]) for c in ustr: print 2, cython.typeof(c) yield c def test_with_nonlocal(): """ >>> chars = list(test_with_nonlocal()) 1 Py_UCS4 2 Py_UCS4 2 Py_UCS4 >>> len(chars) 2 >>> ''.join(chars) == 'ab' True """ ustr = u'ab' print 1, cython.typeof(ustr[0]) def gen(): nonlocal ustr for c in ustr: print 2, cython.typeof(c) yield c return gen() Cython-0.23.4/tests/run/generator_frame_cycle.py0000644000175600017570000000103112606202452023036 0ustar jenkinsjenkins00000000000000# mode: run # tag: generator import sys def _next(it): if sys.version_info[0] >= 3: return next(it) else: return it.next() def test_generator_frame_cycle(): """ >>> test_generator_frame_cycle() ("I'm done",) """ testit = [] def whoo(): try: yield except: yield finally: testit.append("I'm done") g = whoo() _next(g) # Frame object cycle eval('g.throw(ValueError)', {'g': g}) del g return tuple(testit) Cython-0.23.4/tests/run/generator_expressions_nested.pyx0000644000175600017570000000314212606202452024706 0ustar jenkinsjenkins00000000000000# mode: run # tag: genexpr # cython: language_level=3 """ Adapted from CPython's test_grammar.py """ def genexpr_simple(): """ >>> sum([ x**2 for x in range(10) ]) 285 >>> sum(genexpr_simple()) 285 """ return (x**2 for x in range(10)) def genexpr_conditional(): """ >>> sum([ x*x for x in range(10) if x%2 ]) 165 >>> sum(genexpr_conditional()) 165 """ return (x*x for x in range(10) if x%2) def genexpr_nested2(): """ >>> sum([x for x in range(10)]) 45 >>> sum(genexpr_nested2()) 45 """ return (x for x in (y for y in range(10))) def genexpr_nested3(): """ >>> sum([x for x in range(10)]) 45 >>> sum(genexpr_nested3()) 45 """ return (x for x in (y for y in (z for z in range(10)))) def genexpr_nested_listcomp(): """ >>> sum([x for x in range(10)]) 45 >>> sum(genexpr_nested_listcomp()) 45 """ return (x for x in [y for y in (z for z in range(10))]) def genexpr_nested_conditional(): """ >>> sum([ x for x in [y for y in [z for z in range(10) if True]] if True ]) 45 >>> sum(genexpr_nested_conditional()) 45 """ return (x for x in (y for y in (z for z in range(10) if True)) if True) def genexpr_nested2_conditional_empty(): """ >>> sum(genexpr_nested2_conditional_empty()) 0 """ return (y for y in (z for z in range(10) if True) if False) def genexpr_nested3_conditional_empty(): """ >>> sum(genexpr_nested3_conditional_empty()) 0 """ return (x for x in (y for y in (z for z in range(10) if True) if False) if True) Cython-0.23.4/tests/run/generator_expressions_in_class.py0000644000175600017570000000104712606202452025031 0ustar jenkinsjenkins00000000000000# mode: run # tag: generators class TestClass(object): """ >>> TestClass.x [1, 2, 3] >>> list(TestClass.gen) [] >>> TestClass.gen_result [2, 4, 6] >>> TestClass.test True >>> list(TestClass.gen3) [2, 4, 6, 8, 10, 12] """ x = [1, 2, 3] gen = (i * 2 for i in x) test = all(i * 2 for i in x) gen_result = list(gen) nested_list = [[1, 2, 3], [4, 5, 6]] #gen2 = (i * 2 for i in x for x in nested_list) # move to error test gen3 = (i * 2 for x in nested_list for i in x) Cython-0.23.4/tests/run/generator_expressions_and_locals.pyx0000644000175600017570000000035112606202452025522 0ustar jenkinsjenkins00000000000000# mode: run # tag: genexpr, locals # ticket: 715 def genexpr_not_in_locals(): """ >>> genexpr_not_in_locals() {'t': (0, 1, 4, 9, 16, 25, 36, 49, 64, 81)} """ t = tuple(x*x for x in range(10)) return locals() Cython-0.23.4/tests/run/generator_expressions.pyx0000644000175600017570000000252212606202452023345 0ustar jenkinsjenkins00000000000000# mode: run # tag: generators, lambda def genexpr(): """ >>> genexpr() [0, 2, 4, 6, 8] """ x = 'abc' result = list( x*2 for x in range(5) ) assert x == 'abc' # don't leak return result def genexpr_if(): """ >>> genexpr_if() [0, 4, 8] """ x = 'abc' result = list( x*2 for x in range(5) if x % 2 == 0 ) assert x == 'abc' # don't leak return result def genexpr_if_false(): """ >>> genexpr_if_false() [] """ x = 'abc' result = list( x*2 for x in range(5) if False ) assert x == 'abc' # don't leak return result def genexpr_with_lambda(): """ >>> genexpr_with_lambda() [0, 4, 8] """ x = 'abc' result = list( x*2 for x in range(5) if (lambda x:x % 2)(x) == 0 ) assert x == 'abc' # don't leak return result def genexpr_of_lambdas(int N): """ >>> [ (f(), g()) for f,g in genexpr_of_lambdas(5) ] [(0, 0), (1, 2), (2, 4), (3, 6), (4, 8)] """ return ( ((lambda : x), (lambda : x*2)) for x in range(N) ) def genexpr_with_bool_binop(values): """ >>> values = [(1, 2, 3), (None, 4, None), (5, None, 6)] >>> genexpr_with_bool_binop(values) [(1, 2, 3), ('X', 4, 'X'), (5, 'X', 6)] """ # copied from CPython's test_itertools.py return [tuple((e is None and 'X' or e) for e in t) for t in values] Cython-0.23.4/tests/run/future_unicode_literals.pyx0000644000175600017570000000060512606202452023634 0ustar jenkinsjenkins00000000000000from __future__ import unicode_literals import sys if sys.version_info[0] >= 3: __doc__ = u""" >>> u == 'test' True >>> isinstance(u, str) True >>> isinstance(b, bytes) True """ else: __doc__ = u""" >>> u == u'test' True >>> isinstance(u, unicode) True >>> isinstance(b, str) True """ u = "test" cdef char* s = "bytes test" b = s Cython-0.23.4/tests/run/future_division.pyx0000644000175600017570000000651012606202452022134 0ustar jenkinsjenkins00000000000000from __future__ import division cimport cython def bigints(values): for x in values: print(repr(x).rstrip('L')) def doit(x,y): """ >>> doit(1,2) (0.5, 0) >>> doit(4,3) (1.3333333333333333, 1) >>> doit(4,3.0) (1.3333333333333333, 1.0) >>> doit(4,2) (2.0, 2) """ return x/y, x//y def doit_inplace(x,y): """ >>> doit_inplace(1,2) 0.5 """ x /= y return x def doit_inplace_floor(x,y): """ >>> doit_inplace_floor(1,2) 0 """ x //= y return x def constants(): """ >>> constants() (0.5, 0, 2.5, 2.0, 2.5, 2) """ return 1/2, 1//2, 5/2.0, 5//2.0, 5/2, 5//2 def py_mix(a): """ >>> py_mix(1) (0.5, 0, 0.5, 0.0, 0.5, 0) >>> py_mix(1.0) (0.5, 0.0, 0.5, 0.0, 0.5, 0.0) >>> 2**53 / 2.0 4503599627370496.0 >>> bigints(py_mix(2**53)) 4503599627370496.0 4503599627370496 4503599627370496.0 4503599627370496.0 4503599627370496.0 4503599627370496 >>> bigints(py_mix(2**53 + 1)) 4503599627370496.0 4503599627370496 4503599627370496.0 4503599627370496.0 4503599627370496.0 4503599627370496 >>> py_mix(2**53 + 1.0) (4503599627370496.0, 4503599627370496.0, 4503599627370496.0, 4503599627370496.0, 4503599627370496.0, 4503599627370496.0) """ return a/2, a//2, a/2.0, a//2.0, a/2, a//2 def py_mix_by_neg1(a): """ >>> py_mix_by_neg1(0) (-0.0, 0, -0.0, -0.0, -0.0, 0) >>> py_mix_by_neg1(-1) (1.0, 1, 1.0, 1.0, 1.0, 1) >>> py_mix_by_neg1(int(2**31-1)) (-2147483647.0, -2147483647, -2147483647.0, -2147483647.0, -2147483647.0, -2147483647) >>> bigints(py_mix_by_neg1(int(-2**31-1))) 2147483649.0 2147483649 2147483649.0 2147483649.0 2147483649.0 2147483649 >>> results = py_mix_by_neg1(int(2**63-1)) >>> results[0] == results[2] == results[3] == results[4] == float(2**63-1) / -1.0 or results True >>> results[1] == results[5] == (2**63-1) // -1 or results True >>> results = py_mix_by_neg1(int(-2**63-1)) >>> results[0] == results[2] == results[3] == results[4] == float(-2**63-1) / -1.0 or results True >>> results[1] == results[5] == (-2**63-1) // -1 or results True """ return a/-1, a//-1, a/-1.0, a//-1.0, a/-1, a//-1 def py_mix_rev(a): """ >>> py_mix_rev(4) (0.25, 0, 1.25, 1.0, 1.25, 1) >>> py_mix_rev(4.0) (0.25, 0.0, 1.25, 1.0, 1.25, 1.0) """ return 1/a, 1//a, 5.0/a, 5.0//a, 5/a, 5//a def int_mix(int a): """ >>> int_mix(1) (0.5, 0, 0.5, 0.0, 0.5, 0) """ return a/2, a//2, a/2.0, a//2.0, a/2, a//2 def int_mix_rev(int a): """ >>> int_mix_rev(4) (0.25, 0, 1.25, 1.0, 1.25, 1) """ return 1/a, 1//a, 5.0/a, 5.0//a, 5/a, 5//a def float_mix(float a): """ >>> float_mix(1.0) (0.5, 0.0, 0.5, 0.0, 0.5, 0.0) """ return a/2, a//2, a/2.0, a//2.0, a/2, a//2 def float_mix_rev(float a): """ >>> float_mix_rev(4.0) (0.25, 0.0, 1.25, 1.0, 1.25, 1.0) """ return 1/a, 1//a, 5.0/a, 5.0//a, 5/a, 5//a def infer_division_type(): """ >>> v = infer_division_type() double >>> v 8333333.25 """ v = (10000**2 - 1) / 12 print(cython.typeof(v)) return v def int_int(int a, int b): """ >>> int_int(1, 2) (0.5, 2.0) """ return a/b, b/a Cython-0.23.4/tests/run/fused_types.pyx0000644000175600017570000002305412606202452021252 0ustar jenkinsjenkins00000000000000# mode: run cimport cython from cython.view cimport array from cython cimport integral from cpython cimport Py_INCREF from Cython import Shadow as pure_cython ctypedef char * string_t # floating = cython.fused_type(float, double) floating # integral = cython.fused_type(int, long) integral ctypedef cython.floating floating fused_type1 = cython.fused_type(int, long, float, double, string_t) fused_type2 = cython.fused_type(string_t) ctypedef fused_type1 *composed_t other_t = cython.fused_type(int, double) ctypedef double *p_double ctypedef int *p_int fused_type3 = cython.fused_type(int, double) fused_composite = cython.fused_type(fused_type2, fused_type3) def test_pure(): """ >>> test_pure() 10 """ mytype = pure_cython.typedef(pure_cython.fused_type(int, long, complex)) print mytype(10) cdef cdef_func_with_fused_args(fused_type1 x, fused_type1 y, fused_type2 z): if fused_type1 is string_t: print x.decode('ascii'), y.decode('ascii'), z.decode('ascii') else: print x, y, z.decode('ascii') return x + y def test_cdef_func_with_fused_args(): """ >>> test_cdef_func_with_fused_args() spam ham eggs spamham 10 20 butter 30 4.2 8.6 bunny 12.8 """ print cdef_func_with_fused_args(b'spam', b'ham', b'eggs').decode('ascii') print cdef_func_with_fused_args(10, 20, b'butter') print cdef_func_with_fused_args(4.2, 8.6, b'bunny') cdef fused_type1 fused_with_pointer(fused_type1 *array): for i in range(5): if fused_type1 is string_t: print array[i].decode('ascii') else: print array[i] obj = array[0] + array[1] + array[2] + array[3] + array[4] # if cython.typeof(fused_type1) is string_t: Py_INCREF(obj) return obj def test_fused_with_pointer(): """ >>> test_fused_with_pointer() 0 1 2 3 4 10 0 1 2 3 4 10 0.0 1.0 2.0 3.0 4.0 10.0 humpty dumpty fall splatch breakfast humptydumptyfallsplatchbreakfast """ cdef int[5] int_array cdef long[5] long_array cdef float[5] float_array cdef string_t[5] string_array cdef char *s strings = [b"humpty", b"dumpty", b"fall", b"splatch", b"breakfast"] for i in range(5): int_array[i] = i long_array[i] = i float_array[i] = i s = strings[i] string_array[i] = s print fused_with_pointer(int_array) print print fused_with_pointer(long_array) print print fused_with_pointer(float_array) print print fused_with_pointer(string_array).decode('ascii') include "cythonarrayutil.pxi" cpdef cython.integral test_fused_memoryviews(cython.integral[:, ::1] a): """ >>> import cython >>> a = create_array((3, 5), mode="c") >>> test_fused_memoryviews[cython.int](a) 7 """ return a[1, 2] ctypedef int[:, ::1] memview_int ctypedef long[:, ::1] memview_long memview_t = cython.fused_type(memview_int, memview_long) def test_fused_memoryview_def(memview_t a): """ >>> a = create_array((3, 5), mode="c") >>> test_fused_memoryview_def["memview_int"](a) 7 """ return a[1, 2] cdef test_specialize(fused_type1 x, fused_type1 *y, composed_t z, other_t *a): cdef fused_type1 result if composed_t is p_double: print "double pointer" if fused_type1 in floating: result = x + y[0] + z[0] + a[0] return result def test_specializations(): """ >>> test_specializations() double pointer double pointer double pointer double pointer double pointer """ cdef object (*f)(double, double *, double *, int *) cdef double somedouble = 2.2 cdef double otherdouble = 3.3 cdef int someint = 4 cdef p_double somedouble_p = &somedouble cdef p_double otherdouble_p = &otherdouble cdef p_int someint_p = &someint f = test_specialize assert f(1.1, somedouble_p, otherdouble_p, someint_p) == 10.6 f = test_specialize assert f(1.1, somedouble_p, otherdouble_p, someint_p) == 10.6 assert ( test_specialize)(1.1, somedouble_p, otherdouble_p, someint_p) == 10.6 f = test_specialize[double, int] assert f(1.1, somedouble_p, otherdouble_p, someint_p) == 10.6 assert test_specialize[double, int](1.1, somedouble_p, otherdouble_p, someint_p) == 10.6 # The following cases are not supported # f = test_specialize[double][p_int] # print f(1.1, somedouble_p, otherdouble_p) # print # print test_specialize[double][p_int](1.1, somedouble_p, otherdouble_p) # print # print test_specialize[double](1.1, somedouble_p, otherdouble_p) # print cdef opt_args(integral x, floating y = 4.0): print x, y def test_opt_args(): """ >>> test_opt_args() 3 4.0 3 4.0 3 4.0 3 4.0 """ opt_args[int, float](3) opt_args[int, double](3) opt_args[int, float](3, 4.0) opt_args[int, double](3, 4.0) class NormalClass(object): def method(self, cython.integral i): print cython.typeof(i), i def test_normal_class(): """ >>> test_normal_class() short 10 """ NormalClass().method[pure_cython.short](10) def test_normal_class_refcount(): """ >>> test_normal_class_refcount() short 10 0 """ import sys x = NormalClass() c = sys.getrefcount(x) x.method[pure_cython.short](10) print sys.getrefcount(x) - c def test_fused_declarations(cython.integral i, cython.floating f): """ >>> test_fused_declarations[pure_cython.short, pure_cython.float](5, 6.6) short float 25 43.56 >>> test_fused_declarations[pure_cython.long, pure_cython.double](5, 6.6) long double 25 43.56 """ cdef cython.integral squared_int = i * i cdef cython.floating squared_float = f * f assert cython.typeof(squared_int) == cython.typeof(i) assert cython.typeof(squared_float) == cython.typeof(f) print cython.typeof(squared_int) print cython.typeof(squared_float) print '%d %.2f' % (squared_int, squared_float) def test_sizeof_fused_type(fused_type1 b): """ >>> test_sizeof_fused_type[pure_cython.double](11.1) """ t = sizeof(b), sizeof(fused_type1), sizeof(double) assert t[0] == t[1] == t[2], t def get_array(itemsize, format): result = array((10,), itemsize, format) result[5] = 5.0 result[6] = 6.0 return result def get_intc_array(): result = array((10,), sizeof(int), 'i') result[5] = 5 result[6] = 6 return result def test_fused_memslice_dtype(cython.floating[:] array): """ Note: the np.ndarray dtype test is in numpy_test >>> import cython >>> sorted(test_fused_memslice_dtype.__signatures__) ['double', 'float'] >>> test_fused_memslice_dtype[cython.double](get_array(8, 'd')) double[:] double[:] 5.0 6.0 >>> test_fused_memslice_dtype[cython.float](get_array(4, 'f')) float[:] float[:] 5.0 6.0 """ cdef cython.floating[:] otherarray = array[0:100:1] print cython.typeof(array), cython.typeof(otherarray), \ array[5], otherarray[6] def test_fused_memslice_dtype_repeated(cython.floating[:] array1, cython.floating[:] array2): """ Note: the np.ndarray dtype test is in numpy_test >>> sorted(test_fused_memslice_dtype_repeated.__signatures__) ['double', 'float'] >>> test_fused_memslice_dtype_repeated(get_array(8, 'd'), get_array(8, 'd')) double[:] double[:] >>> test_fused_memslice_dtype_repeated(get_array(4, 'f'), get_array(4, 'f')) float[:] float[:] >>> test_fused_memslice_dtype_repeated(get_array(8, 'd'), get_array(4, 'f')) Traceback (most recent call last): ValueError: Buffer dtype mismatch, expected 'double' but got 'float' """ print cython.typeof(array1), cython.typeof(array2) def test_fused_memslice_dtype_repeated_2(cython.floating[:] array1, cython.floating[:] array2, fused_type3[:] array3): """ Note: the np.ndarray dtype test is in numpy_test >>> sorted(test_fused_memslice_dtype_repeated_2.__signatures__) ['double|double', 'double|int', 'float|double', 'float|int'] >>> test_fused_memslice_dtype_repeated_2(get_array(8, 'd'), get_array(8, 'd'), get_array(8, 'd')) double[:] double[:] double[:] >>> test_fused_memslice_dtype_repeated_2(get_array(8, 'd'), get_array(8, 'd'), get_intc_array()) double[:] double[:] int[:] >>> test_fused_memslice_dtype_repeated_2(get_array(4, 'f'), get_array(4, 'f'), get_intc_array()) float[:] float[:] int[:] """ print cython.typeof(array1), cython.typeof(array2), cython.typeof(array3) def test_cython_numeric(cython.numeric arg): """ Test to see whether complex numbers have their utility code declared properly. >>> test_cython_numeric(10.0 + 1j) double complex (10+1j) """ print cython.typeof(arg), arg cdef fused ints_t: int long cdef _test_index_fused_args(cython.floating f, ints_t i): print cython.typeof(f), cython.typeof(i) def test_index_fused_args(cython.floating f, ints_t i): """ >>> import cython >>> test_index_fused_args[cython.double, cython.int](2.0, 3) double int """ _test_index_fused_args[cython.floating, ints_t](f, i) def test_composite(fused_composite x): """ >>> print(test_composite(b'a').decode('ascii')) a >>> test_composite(3) 6 >>> test_composite(3.0) 6.0 """ if fused_composite is string_t: return x else: return 2 * x Cython-0.23.4/tests/run/fused_def.pyx0000644000175600017570000002232212606202452020641 0ustar jenkinsjenkins00000000000000# mode: run """ Test Python def functions without extern types """ cy = __import__("cython") cimport cython cdef class Base(object): def __repr__(self): return type(self).__name__ cdef class ExtClassA(Base): pass cdef class ExtClassB(Base): pass cdef enum MyEnum: entry0 entry1 entry2 entry3 entry4 ctypedef fused fused_t: str int long complex ExtClassA ExtClassB MyEnum ctypedef ExtClassA xxxlast ctypedef ExtClassB aaafirst ctypedef fused fused_with_object: aaafirst object xxxlast int long f = 5.6 i = 9 def opt_func(fused_t obj, cython.floating myf = 1.2, cython.integral myi = 7): """ Test runtime dispatch, indexing of various kinds and optional arguments >>> opt_func("spam", f, i) str object double long spam 5.60 9 5.60 9 >>> opt_func[str, float, int]("spam", f, i) str object float int spam 5.60 9 5.60 9 >>> opt_func[str, cy.double, cy.long]("spam", f, i) str object double long spam 5.60 9 5.60 9 >>> opt_func[str, float, cy.int]("spam", f, i) str object float int spam 5.60 9 5.60 9 >>> opt_func(ExtClassA(), f, i) ExtClassA double long ExtClassA 5.60 9 5.60 9 >>> opt_func[ExtClassA, float, int](ExtClassA(), f, i) ExtClassA float int ExtClassA 5.60 9 5.60 9 >>> opt_func[ExtClassA, cy.double, cy.long](ExtClassA(), f, i) ExtClassA double long ExtClassA 5.60 9 5.60 9 >>> opt_func(ExtClassB(), f, i) ExtClassB double long ExtClassB 5.60 9 5.60 9 >>> opt_func[ExtClassB, cy.double, cy.long](ExtClassB(), f, i) ExtClassB double long ExtClassB 5.60 9 5.60 9 >>> opt_func(10, f) long double long 10 5.60 7 5.60 9 >>> opt_func[int, float, int](10, f) int float int 10 5.60 7 5.60 9 >>> opt_func(10 + 2j, myf = 2.6) double complex double long (10+2j) 2.60 7 5.60 9 >>> opt_func[cy.py_complex, float, int](10 + 2j, myf = 2.6) double complex float int (10+2j) 2.60 7 5.60 9 >>> opt_func[cy.doublecomplex, cy.float, cy.int](10 + 2j, myf = 2.6) double complex float int (10+2j) 2.60 7 5.60 9 >>> opt_func(object(), f) Traceback (most recent call last): ... TypeError: Function call with ambiguous argument types >>> opt_func[ExtClassA, cy.float, cy.long](object(), f) Traceback (most recent call last): ... TypeError: Argument 'obj' has incorrect type (expected fused_def.ExtClassA, got object) """ print cython.typeof(obj), cython.typeof(myf), cython.typeof(myi) print obj, "%.2f" % myf, myi, "%.2f" % f, i def test_opt_func(): """ >>> test_opt_func() str object double long ham 5.60 4 5.60 9 """ opt_func("ham", f, entry4) def func_with_object(fused_with_object obj, cython.integral myi = 7): """ >>> func_with_object(1) long long 1 7 >>> func_with_object(1, 3) long long 1 3 >>> func_with_object['int', 'int'](1, 3) int int 1 3 >>> func_with_object(1j, 3) Python object long 1j 3 >>> func_with_object('abc', 3) Python object long abc 3 >>> func_with_object(ExtClassA(), 3) xxxlast long ExtClassA 3 >>> func_with_object(ExtClassB(), 3) aaafirst long ExtClassB 3 >>> func_with_object['object', 'long'](ExtClassA(), 3) Python object long ExtClassA 3 >>> func_with_object['object', 'long'](ExtClassB(), 3) Python object long ExtClassB 3 """ print cython.typeof(obj), cython.typeof(myi) print obj, myi def args_kwargs(fused_t obj, cython.floating myf = 1.2, *args, **kwargs): """ >>> args_kwargs("foo") str object double foo 1.20 5.60 () {} >>> args_kwargs("eggs", f, 1, 2, [], d={}) str object double eggs 5.60 5.60 (1, 2, []) {'d': {}} >>> args_kwargs[str, float]("eggs", f, 1, 2, [], d={}) str object float eggs 5.60 5.60 (1, 2, []) {'d': {}} """ print cython.typeof(obj), cython.typeof(myf) print obj, "%.2f" % myf, "%.2f" % f, args, kwargs class BaseClass(object): """ Test fused class/static/normal methods and super() without args """ @staticmethod def mystaticmethod(cython.integral arg1): print cython.typeof(arg1), arg1 @classmethod def myclassmethod(cls, cython.integral arg1): print cls, cython.typeof(arg1), arg1 def normalmethod(self, cython.integral arg1): print self, cython.typeof(arg1), arg1 def __repr__(self): return "<%s.%s object>" % (__name__, type(self).__name__) class SubClass(BaseClass): @staticmethod def mystaticmethod(self, cython.integral arg1): print cython.typeof(arg1), arg1 super().mystaticmethod(arg1 + 1) @classmethod def myclassmethod(cls, cython.integral arg1): print cls, cython.typeof(arg1), arg1 super().myclassmethod(arg1 + 1) def normalmethod(self, cython.integral arg1): print self, cython.typeof(arg1), arg1 super().normalmethod(arg1 + 1) class SubSubClass(SubClass): pass def test_fused_def_super(): """ >>> test_fused_def_super() long 10 long 11 long 11 long 12 short 12 long 13 short 13 long 14 long 14 long 15 long 15 long 16 short 16 long 17 short 17 long 18 long 18 long 19 long 19 long 20 short 20 long 21 short 21 long 22 """ obj = SubClass() cls = SubClass obj.mystaticmethod(obj, 10) cls.mystaticmethod(obj, 11) obj.mystaticmethod[cy.short](obj, 12) cls.mystaticmethod[cy.short](obj, 13) obj.myclassmethod(14) cls.myclassmethod(15) obj.myclassmethod[cy.short](16) cls.myclassmethod[cy.short](17) obj.normalmethod(18) cls.normalmethod(obj, 19) obj.normalmethod[cy.short](20) cls.normalmethod[cy.short](obj, 21) def test_fused_def_classmethod(): """ >>> test_fused_def_classmethod() long 10 long 11 long 11 long 12 short 12 long 13 short 13 long 14 """ SubSubClass().myclassmethod(10) SubSubClass.myclassmethod(11) SubSubClass().myclassmethod[cy.short](12) SubSubClass.myclassmethod[cy.short](13) cdef class CBaseClass(object): """ Test fused def and cpdef methods in cdef classes. >>> import cython as cy >>> obj = CBaseClass() >>> cls = CBaseClass >>> obj.mystaticmethod(10) long 10 >>> obj.mystaticmethod[cy.short](10) short 10 >>> cls.mystaticmethod(10) long 10 >>> cls.mystaticmethod[cy.short](10) short 10 >>> obj.myclassmethod(10) CBaseClass long 10 >>> obj.myclassmethod[cy.short](10) CBaseClass short 10 >>> cls.myclassmethod(10) CBaseClass long 10 >>> cls.myclassmethod[cy.short](10) CBaseClass short 10 >>> obj.normalmethod(10, 11, 12) long 10 11 12 >>> obj.normalmethod[cy.short](10, 11, 12) short 10 11 12 >>> cls.normalmethod(obj, 10, 11, 12) long 10 11 12 >>> cls.normalmethod[cy.short](obj, 10, 11, 12) short 10 11 12 >>> obj.cpdefmethod(10) long 10 >>> obj.cpdefmethod[cy.short](10) short 10 >>> cls.cpdefmethod(obj, 10) long 10 >>> cls.cpdefmethod[cy.short](obj, 10) short 10 """ @staticmethod def mystaticmethod(cython.integral arg1): print cython.typeof(arg1), arg1 @classmethod def myclassmethod(cls, cython.integral arg1): print cls.__name__, cython.typeof(arg1), arg1 def normalmethod(self, cython.integral arg1, arg2, arg3): print self, cython.typeof(arg1), arg1, arg2, arg3 cpdef cpdefmethod(self, cython.integral arg1): print self, cython.typeof(arg1), arg1 def __repr__(self): return "<%s.%s object>" % (__name__, type(self).__name__) def getcode(func): return getattr(func, '__code__', None) or func.func_code def test_code_object(cython.floating dummy = 2.0): """ A test for default arguments is in cyfunction_defaults >>> getcode(test_code_object) is getcode(test_code_object[float]) True """ def create_dec(value): def dec(f): if not hasattr(f, 'order'): f.order = [] f.order.append(value) return f return dec @create_dec(1) @create_dec(2) @create_dec(3) def test_decorators(cython.floating arg): """ >>> test_decorators.order [3, 2, 1] """ Cython-0.23.4/tests/run/fused_cpp.pyx0000644000175600017570000000073412606202452020670 0ustar jenkinsjenkins00000000000000# tag: cpp cimport cython from libcpp.vector cimport vector def test_cpp_specialization(cython.floating element): """ >>> import cython >>> test_cpp_specialization[cython.float](10.0) vector[float] * float 10.0 >>> test_cpp_specialization[cython.double](10.0) vector[double] * double 10.0 """ cdef vector[cython.floating] *v = new vector[cython.floating]() v.push_back(element) print cython.typeof(v), cython.typeof(element), v.at(0) Cython-0.23.4/tests/run/fused_cpdef.pyx0000644000175600017570000000377112606202452021173 0ustar jenkinsjenkins00000000000000cimport cython cy = __import__("cython") cpdef func1(self, cython.integral x): print "%s," % (self,), if cython.integral is int: print 'x is int', x, cython.typeof(x) else: print 'x is long', x, cython.typeof(x) class A(object): meth = func1 def __str__(self): return "A" pyfunc = func1 def test_fused_cpdef(): """ >>> test_fused_cpdef() None, x is int 2 int None, x is long 2 long None, x is long 2 long None, x is int 2 int None, x is long 2 long A, x is int 2 int A, x is long 2 long A, x is long 2 long A, x is long 2 long """ func1[int](None, 2) func1[long](None, 2) func1(None, 2) print pyfunc[cy.int](None, 2) pyfunc(None, 2) print A.meth[cy.int](A(), 2) A.meth(A(), 2) A().meth[cy.long](2) A().meth(2) def assert_raise(func, *args): try: func(*args) except TypeError: pass else: assert False, "Function call did not raise TypeError" def test_badcall(): """ >>> test_badcall() """ assert_raise(pyfunc) assert_raise(pyfunc, 1, 2, 3) assert_raise(pyfunc[cy.int], 10, 11, 12) assert_raise(pyfunc, None, object()) assert_raise(A().meth) assert_raise(A.meth) assert_raise(A().meth[cy.int]) assert_raise(A.meth[cy.int]) ctypedef long double long_double cpdef multiarg(cython.integral x, cython.floating y): if cython.integral is int: print "x is an int,", else: print "x is a long,", if cython.floating is long_double: print "y is a long double:", elif float is cython.floating: print "y is a float:", else: print "y is a double:", print x, y def test_multiarg(): """ >>> test_multiarg() x is an int, y is a float: 1 2.0 x is an int, y is a float: 1 2.0 x is a long, y is a double: 4 5.0 """ multiarg[int, float](1, 2.0) multiarg[cy.int, cy.float](1, 2.0) multiarg(4, 5.0) Cython-0.23.4/tests/run/function_binding_T494.pyx0000644000175600017570000000123512606202452022760 0ustar jenkinsjenkins00000000000000# ticket: 494 cimport cython class SomeNumber(object): def __init__(self, n): self._n = n def __repr__(self): return "SomeNumber(%s)" % self._n @cython.binding(True) def add_to_func(self, x): """ >>> add_to_func(SomeNumber(2), 5) 7 >>> SomeNumber(3).add_to(10) 13 >>> SomeNumber.add_to(SomeNumber(22), 7) 29 """ return self._n + x @cython.binding(False) def new_num(n): """ >>> new_num(11) SomeNumber(11) >>> SomeNumber.new(11) SomeNumber(11) >>> SomeNumber(3).new(11) SomeNumber(11) """ return SomeNumber(n) SomeNumber.add_to = add_to_func SomeNumber.new = new_num Cython-0.23.4/tests/run/function_as_method_py_T494.py0000644000175600017570000000021712606202452023630 0ustar jenkinsjenkins00000000000000# ticket: 494 __doc__ = """ >>> A.foo = foo >>> A().foo() True """ class A: pass def foo(self): return self is not None Cython-0.23.4/tests/run/function_as_method_T494.pyx0000644000175600017570000000024612606202452023312 0ustar jenkinsjenkins00000000000000# ticket: 494 # cython: binding=True __doc__ = """ >>> A.foo = foo >>> A().foo() True """ class A: pass def foo(self): return self is not None Cython-0.23.4/tests/run/funcexceptreturn.pyx0000644000175600017570000000062612606202452022324 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> import sys >>> if not IS_PY3: sys.exc_clear() >>> print(sys.exc_info()[0]) # 0 None >>> exc = test_c() >>> isinstance(exc, TestException) or exc True >>> print(sys.exc_info()[0]) # test_c() None """ import sys IS_PY3 = sys.version_info[0] >= 3 class TestException(Exception): pass def test_c(): try: raise TestException except TestException, e: return e Cython-0.23.4/tests/run/funcexceptreraise.pyx0000644000175600017570000000227212606202452022436 0ustar jenkinsjenkins00000000000000import sys def reraise(f, exc): """ >>> def f(exc): raise exc >>> reraise(f, TypeError) Traceback (most recent call last): TypeError >>> def f(exc): raise exc('hiho') >>> reraise(f, TypeError) Traceback (most recent call last): TypeError: hiho """ try: f(exc) except: assert sys.exc_info()[0] is exc, str(sys.exc_info()[1]) raise def reraise_original(f, exc, raise_catch): """ >>> def f(exc): raise exc >>> def raise_catch_py(): ... try: raise ValueError ... except: pass >>> reraise_original(f, TypeError, raise_catch_py) Traceback (most recent call last): TypeError >>> reraise_original(f, TypeError, raise_catch_cy) Traceback (most recent call last): TypeError >>> reraise_original(f, TypeError, raise_catch_cy_non_empty) Traceback (most recent call last): TypeError """ try: f(exc) except: raise_catch() assert sys.exc_info()[0] is exc, str(sys.exc_info()[1]) raise def raise_catch_cy(): try: raise ValueError except: pass def raise_catch_cy_non_empty(): try: raise ValueError except: a = 1+1 Cython-0.23.4/tests/run/funcexceptreplace.pyx0000644000175600017570000000051412606202452022414 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> try: exc() ... except IndexError: ... if IS_PY3: ... print(isinstance(sys.exc_info()[1].__context__, ValueError)) ... else: ... print(True) True """ import sys IS_PY3 = sys.version_info[0] >= 3 def exc(): try: raise ValueError except ValueError: raise IndexError Cython-0.23.4/tests/run/funcexceptraisefrom.pyx0000644000175600017570000000171312606202452022772 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> def bar(): ... try: ... foo() ... except ValueError: ... if IS_PY3: ... print(isinstance(sys.exc_info()[1].__cause__, TypeError)) ... else: ... print(True) >>> bar() True >>> print(sys.exc_info()) (None, None, None) >>> def bar2(): ... try: ... foo2() ... except ValueError: ... if IS_PY3: ... cause = sys.exc_info()[1].__cause__ ... print(isinstance(cause, TypeError)) ... print(cause.args==('value',)) ... pass ... else: ... print(True) ... print(True) >>> bar2() True True """ import sys IS_PY3 = sys.version_info[0] >= 3 if not IS_PY3: sys.exc_clear() def foo(): try: raise TypeError except TypeError: raise ValueError from TypeError def foo2(): try: raise TypeError except TypeError: raise ValueError() from TypeError('value') Cython-0.23.4/tests/run/funcexceptraise.pyx0000644000175600017570000000047512606202452022112 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> def bar(): ... try: ... foo() ... except ValueError: ... pass >>> bar() >>> print(sys.exc_info()) (None, None, None) """ import sys if sys.version_info[0] < 3: sys.exc_clear() def foo(): try: raise TypeError except TypeError: raise ValueError Cython-0.23.4/tests/run/funcexceptcypy.pyx0000644000175600017570000000250312606202452021765 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> import sys >>> if not IS_PY3: sys.exc_clear() >>> def test_py(): ... old_exc = sys.exc_info()[0] ... try: ... raise AttributeError("test") ... except AttributeError: ... test_c(error=AttributeError) ... print(sys.exc_info()[0] is AttributeError or sys.exc_info()[0]) ... print((IS_PY3 and sys.exc_info()[0] is old_exc) or ... (not IS_PY3 and sys.exc_info()[0] is AttributeError) or ... sys.exc_info()[0]) >>> print(sys.exc_info()[0]) # 0 None >>> test_py() True True True True >>> print(sys.exc_info()[0]) # test_py() None >>> test_c(test_py) True True True True True True >>> print(sys.exc_info()[0]) # test_c() None >>> def test_raise(): ... raise TestException("test") >>> test_catch(test_raise, TestException) True None """ import sys IS_PY3 = sys.version_info[0] >= 3 class TestException(Exception): pass def test_c(func=None, error=None): try: raise TestException(u"test") except TestException: if func: func() print(sys.exc_info()[0] is TestException or sys.exc_info()[0]) print(sys.exc_info()[0] is error or sys.exc_info()[0]) def test_catch(func, error): try: func() except error: print(sys.exc_info()[0] is error or sys.exc_info()[0]) print(sys.exc_info()[0] is error or sys.exc_info()[0]) Cython-0.23.4/tests/run/funcexceptchained.pyx0000644000175600017570000000467212606202452022405 0ustar jenkinsjenkins00000000000000# mode: run # tag: exceptions import sys IS_PY3 = sys.version_info[0] >= 3 __doc__ = u""" >>> if not IS_PY3: sys.exc_clear() >>> def test_py(outer_exc): ... try: ... raise AttributeError ... except AttributeError: ... print(sys.exc_info()[0] is AttributeError or sys.exc_info()[0]) ... try: raise KeyError ... except: ... print(sys.exc_info()[0] is KeyError or sys.exc_info()[0]) ... if IS_PY3: ... print(isinstance(sys.exc_info()[1].__context__, AttributeError) ... or sys.exc_info()[1].__context__) ... else: ... print(True) ... print((IS_PY3 and sys.exc_info()[0] is AttributeError) or ... (not IS_PY3 and sys.exc_info()[0] is KeyError) or ... sys.exc_info()[0]) ... print((IS_PY3 and sys.exc_info()[0] is outer_exc) or ... (not IS_PY3 and sys.exc_info()[0] is KeyError) or ... sys.exc_info()[0]) >>> print(sys.exc_info()[0]) # 0 None >>> test_py(None) True True True True True >>> print(sys.exc_info()[0]) # test_py() None >>> test_c(None) True True True True True >>> print(sys.exc_info()[0]) # test_c() None >>> def test_py2(): ... try: ... raise Exception ... except Exception: ... test_py(Exception) ... print(sys.exc_info()[0] is Exception or sys.exc_info()[0]) ... print((IS_PY3 and sys.exc_info()[0] is None) or ... (not IS_PY3 and sys.exc_info()[0] is Exception) or ... sys.exc_info()[0]) >>> test_py2() True True True True True True True >>> print(sys.exc_info()[0]) # test_py2() None >>> test_c2() True True True True True True True >>> print(sys.exc_info()[0]) # test_c2() None """ def test_c(outer_exc): try: raise AttributeError except AttributeError: print(sys.exc_info()[0] is AttributeError or sys.exc_info()[0]) try: raise KeyError except: print(sys.exc_info()[0] is KeyError or sys.exc_info()[0]) if IS_PY3: print(isinstance(sys.exc_info()[1].__context__, AttributeError) or sys.exc_info()[1].__context__) else: print(True) print(sys.exc_info()[0] is AttributeError or sys.exc_info()[0]) print(sys.exc_info()[0] is outer_exc or sys.exc_info()[0]) def test_c2(): try: raise Exception except Exception: test_c(Exception) print(sys.exc_info()[0] is Exception or sys.exc_info()[0]) print(sys.exc_info()[0] is None or sys.exc_info()[0]) Cython-0.23.4/tests/run/funcexcept.pyx0000644000175600017570000000146312606202452021064 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> import sys >>> if not IS_PY3: sys.exc_clear() >>> def test_py(): ... try: ... raise AttributeError ... except AttributeError: ... print(sys.exc_info()[0] == AttributeError or sys.exc_info()[0]) ... print((IS_PY3 and sys.exc_info()[0] is None) or ... (not IS_PY3 and sys.exc_info()[0] == AttributeError) or ... sys.exc_info()[0]) >>> print(sys.exc_info()[0]) # 0 None >>> test_py() True True >>> print(sys.exc_info()[0]) # test_py() None >>> test_c() True True >>> print(sys.exc_info()[0]) # test_c() None """ import sys IS_PY3 = sys.version_info[0] >= 3 def test_c(): try: raise AttributeError except AttributeError: print(sys.exc_info()[0] == AttributeError or sys.exc_info()[0]) print(sys.exc_info()[0] is None or sys.exc_info()[0]) Cython-0.23.4/tests/run/funcexc_iter_T228.pyx0000644000175600017570000000271112606202452022112 0ustar jenkinsjenkins00000000000000# ticket: 228 __doc__ = u""" >>> def py_iterator(): ... if True: return ... yield None >>> list(py_iterator()) [] >>> list(cy_iterator()) [] >>> try: ... raise ValueError ... except: ... print(sys.exc_info()[0] is ValueError or sys.exc_info()[0]) ... a = list(py_iterator()) ... print(sys.exc_info()[0] is ValueError or sys.exc_info()[0]) True True >>> print(sys.exc_info()[0] is None or sys.exc_info()[0]) True >>> try: ... raise ValueError ... except: ... print(sys.exc_info()[0] is ValueError or sys.exc_info()[0]) ... a = list(py_iterator()) ... print(sys.exc_info()[0] is ValueError or sys.exc_info()[0]) ... a = list(cy_iterator()) ... print(sys.exc_info()[0] is ValueError or sys.exc_info()[0]) True True True >>> print(sys.exc_info()[0] is None or sys.exc_info()[0]) True >>> double_raise(py_iterator) True True True >>> print(sys.exc_info()[0] is None or sys.exc_info()[0]) True """ import sys if sys.version_info[0] < 3: sys.exc_clear() cdef class cy_iterator(object): def __iter__(self): return self def __next__(self): raise StopIteration def double_raise(py_iterator): try: raise ValueError except: print(sys.exc_info()[0] is ValueError or sys.exc_info()[0]) a = list(py_iterator()) print(sys.exc_info()[0] is ValueError or sys.exc_info()[0]) a = list(cy_iterator()) print(sys.exc_info()[0] is ValueError or sys.exc_info()[0]) Cython-0.23.4/tests/run/forfrom.pyx0000644000175600017570000000052012606202452020363 0ustar jenkinsjenkins00000000000000 def for_else(): """ >>> for_else() 30 >>> print( int_comp() ) 00*01*02 """ cdef int i, j=0, k=2 for i from 0 <= i < 10: j += k else: k = j+10 return k def int_comp(): cdef int i return u'*'.join(tuple([ u"%02d" % i for i from 0 <= i < 3 ])) Cython-0.23.4/tests/run/for_in_string.pyx0000644000175600017570000001342312606202452021561 0ustar jenkinsjenkins00000000000000cimport cython bytes_abc = b'abc' bytes_ABC = b'ABC' bytes_abc_null = b'a\0b\0c' bytes_ABC_null = b'A\0B\0C' unicode_abc = u'abc' unicode_ABC = u'ABC' unicode_abc_null = u'a\0b\0c' unicode_ABC_null = u'A\0B\0C' def for_in_bytes(bytes s): """ >>> for_in_bytes(bytes_abc) 'X' >>> for_in_bytes(bytes_ABC) 'C' >>> for_in_bytes(bytes_abc_null) 'X' >>> for_in_bytes(bytes_ABC_null) 'C' """ for c in s: # Py2/Py3 if c == b'C' or c == c'C': return 'C' else: return 'X' @cython.test_assert_path_exists("//ForFromStatNode") @cython.test_fail_if_path_exists("//ForInStatNode") def for_char_in_bytes(bytes s): """ >>> for_char_in_bytes(bytes_abc) 'X' >>> for_char_in_bytes(bytes_ABC) 'C' >>> for_char_in_bytes(bytes_abc_null) 'X' >>> for_char_in_bytes(bytes_ABC_null) 'C' """ cdef char c for c in s: if c == b'C': return 'C' else: return 'X' #### Py2 and Py3 behave differently here: Py2->bytes, Py3->integer ## ## @cython.test_assert_path_exists("//ForFromStatNode") ## @cython.test_fail_if_path_exists("//ForInStatNode") ## def for_obj_in_bytes_slice(bytes s): ## """ ## >>> for_obj_in_bytes_slice(bytes_abc) ## 'X' ## >>> for_obj_in_bytes_slice(bytes_ABC) ## 'B' ## >>> for_obj_in_bytes_slice(bytes_abc_null) ## 'X' ## >>> for_obj_in_bytes_slice(bytes_ABC_null) ## 'B' ## """ ## for c in s[1:-1]: ## if c == b'B': ## return 'B' ## else: ## return 'X' @cython.test_assert_path_exists("//ForFromStatNode") @cython.test_fail_if_path_exists("//ForInStatNode") def for_char_in_bytes_slice(bytes s): """ >>> for_char_in_bytes_slice(bytes_abc) 'X' >>> for_char_in_bytes_slice(bytes_ABC) 'B' >>> for_char_in_bytes_slice(bytes_abc_null) 'X' >>> for_char_in_bytes_slice(bytes_ABC_null) 'B' """ cdef char c for c in s[1:-1]: if c == c'B': return 'B' else: return 'X' @cython.test_assert_path_exists("//ForFromStatNode") @cython.test_fail_if_path_exists("//ForInStatNode") def for_char_in_enumerate_bytes(bytes s): """ >>> for_char_in_enumerate_bytes(bytes_abc) 'X' >>> for_char_in_enumerate_bytes(bytes_ABC) 2 >>> for_char_in_enumerate_bytes(bytes_abc_null) 'X' >>> for_char_in_enumerate_bytes(bytes_ABC_null) 4 """ cdef char c cdef Py_ssize_t i for i, c in enumerate(s): if c == b'C': return i else: return 'X' #### Py2 and Py3 behave differently here: Py2->bytes, Py3->integer ## ## @cython.test_assert_path_exists("//ForFromStatNode") ## @cython.test_fail_if_path_exists("//ForInStatNode") ## def for_pyvar_in_char_ptr(char* c_string): ## """ ## >>> for_pyvar_in_char_ptr( (bytes_abc+bytes_ABC) * 2 ) ## [True, True, True, False, False, False, True, True, True, False] ## >>> for_pyvar_in_char_ptr( bytes_abc_null * 2 ) ## [True, False, True, False, True, True, False, True, False, True] ## """ ## in_test = [] ## cdef object c ## for c in c_string[:10]: ## in_test.append( c in b'abc' ) ## return in_test @cython.test_assert_path_exists("//ForFromStatNode") @cython.test_fail_if_path_exists("//ForInStatNode") def for_char_in_char_ptr(char* c_string): """ >>> for_char_in_char_ptr( (bytes_abc+bytes_ABC) * 2 ) [True, True, True, False, False, False, True, True, True, False] >>> for_char_in_char_ptr( bytes_abc_null * 2 ) [True, False, True, False, True, True, False, True, False, True] """ in_test = [] cdef char c for c in c_string[:10]: in_test.append( c in b'abc' ) return in_test @cython.test_assert_path_exists("//ForFromStatNode") @cython.test_fail_if_path_exists("//ForInStatNode") def for_pyunicode_in_unicode(unicode s): """ >>> for_pyunicode_in_unicode(unicode_abc) 'X' >>> for_pyunicode_in_unicode(unicode_ABC) 'C' >>> for_pyunicode_in_unicode(unicode_abc_null) 'X' >>> for_pyunicode_in_unicode(unicode_ABC_null) 'C' """ cdef Py_UNICODE c for c in s: if c == u'C': return 'C' else: return 'X' @cython.test_assert_path_exists("//ForFromStatNode") @cython.test_fail_if_path_exists("//ForInStatNode") def for_pyunicode_in_enumerate_unicode(unicode s): """ >>> for_pyunicode_in_enumerate_unicode(unicode_abc) 'X' >>> for_pyunicode_in_enumerate_unicode(unicode_ABC) 2 >>> for_pyunicode_in_enumerate_unicode(unicode_abc_null) 'X' >>> for_pyunicode_in_enumerate_unicode(unicode_ABC_null) 4 """ cdef Py_UNICODE c cdef Py_ssize_t i for i, c in enumerate(s): if c == u'C': return i else: return 'X' @cython.test_assert_path_exists("//ForFromStatNode") @cython.test_fail_if_path_exists("//ForInStatNode") def for_pyucs4_in_unicode(unicode s): """ >>> for_pyucs4_in_unicode(unicode_abc) 'X' >>> for_pyucs4_in_unicode(unicode_ABC) 'C' >>> for_pyucs4_in_unicode(unicode_abc_null) 'X' >>> for_pyucs4_in_unicode(unicode_ABC_null) 'C' """ cdef Py_UCS4 c for c in s: if c == u'C': return 'C' else: return 'X' @cython.test_assert_path_exists("//ForFromStatNode") @cython.test_fail_if_path_exists("//ForInStatNode") def for_pyucs4_in_enumerate_unicode(unicode s): """ >>> for_pyucs4_in_enumerate_unicode(unicode_abc) 'X' >>> for_pyucs4_in_enumerate_unicode(unicode_ABC) 2 >>> for_pyucs4_in_enumerate_unicode(unicode_abc_null) 'X' >>> for_pyucs4_in_enumerate_unicode(unicode_ABC_null) 4 """ cdef Py_UCS4 c cdef Py_ssize_t i for i, c in enumerate(s): if c == u'C': return i else: return 'X' Cython-0.23.4/tests/run/for_in_range_T372.pyx0000644000175600017570000000401612606202452022064 0ustar jenkinsjenkins00000000000000# ticket: 372 cimport cython @cython.test_assert_path_exists("//ForFromStatNode") @cython.test_fail_if_path_exists("//ForInStatNode") def test_modify(): """ >>> test_modify() 0 1 2 3 4 (4, 0) """ cdef int i, n = 5 for i in range(n): print i n = 0 print return i,n @cython.test_assert_path_exists("//ForFromStatNode") @cython.test_fail_if_path_exists("//ForInStatNode") def test_negindex(): """ >>> test_negindex() 6 5 4 3 2 (2, 0) """ cdef int i, n = 5 for i in range(n+1, 1, -1): print i n = 0 return i,n @cython.test_assert_path_exists("//ForFromStatNode", "//ForFromStatNode//PrintStatNode//CoerceToPyTypeNode") @cython.test_fail_if_path_exists("//ForInStatNode") def test_negindex_inferred(): """ >>> test_negindex_inferred() 5 4 3 2 (2, 0) """ cdef int n = 5 for i in range(n, 1, -1): print i n = 0 return i,n @cython.test_assert_path_exists("//ForFromStatNode") @cython.test_fail_if_path_exists("//ForInStatNode") def test_fix(): """ >>> test_fix() 0 1 2 3 4 4 """ cdef int i for i in range(5): print i print return i @cython.test_assert_path_exists("//ForFromStatNode") @cython.test_fail_if_path_exists("//ForInStatNode") def test_break(): """ >>> test_break() 0 1 2 (2, 0) """ cdef int i, n = 5 for i in range(n): print i n = 0 if i == 2: break else: print "FAILED!" print return i,n @cython.test_assert_path_exists("//ForFromStatNode") @cython.test_fail_if_path_exists("//ForInStatNode") def test_return(): """ >>> test_return() 0 1 2 (2, 0) """ cdef int i, n = 5 for i in range(n): print i n = 0 if i == 2: return i,n print return "FAILED!" Cython-0.23.4/tests/run/for_in_iter.py0000644000175600017570000000542512606202452021031 0ustar jenkinsjenkins00000000000000# mode: run # tag: forin import sys import cython try: from builtins import next except ImportError: def next(it): return it.next() def for_in_pyiter_pass(it): """ >>> it = Iterable(5) >>> for_in_pyiter_pass(it) >>> next(it) Traceback (most recent call last): StopIteration """ for item in it: pass def for_in_pyiter(it): """ >>> for_in_pyiter(Iterable(5)) [0, 1, 2, 3, 4] """ l = [] for item in it: l.append(item) return l def for_in_list(): """ >>> for_in_pyiter([1,2,3,4,5]) [1, 2, 3, 4, 5] """ @cython.test_assert_path_exists('//TupleNode//IntNode') @cython.test_fail_if_path_exists('//ListNode//IntNode') def for_in_literal_list(): """ >>> for_in_literal_list() [1, 2, 3, 4] """ l = [] for i in [1,2,3,4]: l.append(i) return l @cython.test_assert_path_exists('//TupleNode//IntNode') @cython.test_fail_if_path_exists('//ListNode//IntNode') def for_in_literal_mult_list(): """ >>> for_in_literal_mult_list() [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4] """ l = [] for i in [1,2,3,4] * 3: l.append(i) return l class Iterable(object): """ >>> for_in_pyiter(Iterable(5)) [0, 1, 2, 3, 4] """ def __init__(self, N): self.N = N self.i = 0 def __iter__(self): return self def __next__(self): if self.i < self.N: i = self.i self.i += 1 return i raise StopIteration next = __next__ if sys.version_info[0] >= 3: class NextReplacingIterable(object): def __init__(self): self.i = 0 def __iter__(self): return self def __next__(self): if self.i > 5: raise StopIteration self.i += 1 self.__next__ = self.next2 return 1 def next2(self): self.__next__ = self.next3 return 2 def next3(self): del self.__next__ raise StopIteration else: class NextReplacingIterable(object): def __init__(self): self.i = 0 def __iter__(self): return self def next(self): if self.i > 5: raise StopIteration self.i += 1 self.next = self.next2 return 1 def next2(self): self.next = self.next3 return 2 def next3(self): del self.next raise StopIteration def for_in_next_replacing_iter(): """ >>> for_in_pyiter(NextReplacingIterable()) [1, 1, 1, 1, 1, 1] """ def for_in_gen(N): """ >>> for_in_pyiter(for_in_gen(10)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] """ for i in range(N): yield i Cython-0.23.4/tests/run/for_in_break_continue_T533.pyx0000644000175600017570000000126712606202452023764 0ustar jenkinsjenkins00000000000000# ticket: 533 def for_in(): """ >>> for_in() CONTINUE -1 CONTINUE 4 BREAK 6 6 """ i = -1 for L in [[], range(5), range(10)]: for i in L: if i > 5: break else: print "CONTINUE", i continue print "BREAK", i break return i def for_from(): """ >>> for_from() CONTINUE 0 CONTINUE 5 BREAK 6 6 """ i = -1 for L in [[], range(5), range(10)]: for i from 0 <= i < len(L): if i > 5: break else: print "CONTINUE", i continue print "BREAK", i break return i Cython-0.23.4/tests/run/for_from_pyvar_loop_T601_extern_def.h0000644000175600017570000000003612606202452025322 0ustar jenkinsjenkins00000000000000 typedef unsigned long Ulong; Cython-0.23.4/tests/run/for_from_pyvar_loop_T601.pyx0000644000175600017570000000234012606202452023510 0ustar jenkinsjenkins00000000000000# ticket: 601 cdef unsigned long size2(): return 3 def for_from_plain_ulong(): """ >>> for_from_plain_ulong() 0 1 2 """ cdef object j = 0 for j from 0 <= j < size2(): print j def for_in_plain_ulong(): """ >>> for_in_plain_ulong() 0 1 2 """ cdef object j = 0 for j in range(size2()): print j cdef extern from "for_from_pyvar_loop_T601_extern_def.h": ctypedef unsigned long Ulong cdef Ulong size(): return 3 def for_from_ctypedef_ulong(): """ >>> for_from_ctypedef_ulong() 0 1 2 """ cdef object j = 0 for j from 0 <= j < size(): print j def for_in_ctypedef_ulong(): """ >>> for_in_ctypedef_ulong() 0 1 2 """ cdef object j = 0 for j in range(size()): print j class ForFromLoopInPyClass(object): """ >>> ForFromLoopInPyClass.i # doctest: +ELLIPSIS Traceback (most recent call last): AttributeError: ...ForLoopInPyClass... has no attribute ...i... >>> ForFromLoopInPyClass.k 0 >>> ForFromLoopInPyClass.m 1 """ for i from 0 <= i < 1: pass for k from 0 <= k < 2: pass for m from 0 <= m < 3: pass Cython-0.23.4/tests/run/for_from_float_T254.pyx0000644000175600017570000000212012606202452022423 0ustar jenkinsjenkins00000000000000# ticket: 254 def double_target(a, b): """ >>> double_target(0, 4) at 0.0 at 1.0 at 2.0 at 3.0 4.0 """ cdef double x for x from a <= x < b: print u"at", x return x def double_step(a, b, dx): """ >>> double_step(0, 2, .5) at 0.0 at 0.5 at 1.0 at 1.5 2.0 """ cdef double x for x from a <= x < b by dx: print u"at", x return x def double_step_typed(a, b, double dx): """ >>> double_step_typed(0, 2, .5) at 0.0 at 0.5 at 1.0 at 1.5 2.0 """ cdef double x for x from a <= x < b by dx: print u"at", x return x def double_step_py_target(a, b, double dx): """ >>> double_step_py_target(0, 2, .5) at 0.0 at 0.5 at 1.0 at 1.5 2.0 """ cdef object x for x from a <= x < b by dx: print u"at", x return x def int_step_py_target(a, b, int dx): """ >>> int_step_py_target(0, 2, 1) at 0 at 1 2 """ cdef object x for x from a <= x < b by dx: print u"at", x return x Cython-0.23.4/tests/run/for_decrement.pyx0000644000175600017570000000176612606202452021542 0ustar jenkinsjenkins00000000000000""" >>> range_loop_indices() ** Calculating step ** (9, 9, 8, 1, 2) >>> from_loop_indices() ** Calculating step ** (10, 10, 0) """ cdef int get_step(): """ This should only be called once, when used in range(). """ print u"** Calculating step **" return 2 def range_loop_indices(): """ Optimized integer for loops using range() should follow Python behavior, and leave the index variable with the last value of the range. """ cdef int i, j, k=0, l=10, m=10 for i in range(10): pass for j in range(2,10): pass for k in range(0,10,get_step()): pass for l in range(10,0,-1): pass for m in range(10,0,-2): pass return i, j, k, l, m def from_loop_indices(): """ for-from-loops should follow C behavior, and leave the index variable incremented one step after the last iteration. """ cdef int i, j, k for i from 0 <= i < 5+5 by get_step(): pass for j from 0 <= j < 10: pass for k from 10 > k > 0: pass return i, j, k Cython-0.23.4/tests/run/fmod.pyx0000644000175600017570000000013612606202452017641 0ustar jenkinsjenkins00000000000000def fmod(double a, double b): """ >>> fmod(7, 1.25) 0.75 """ return a % b Cython-0.23.4/tests/run/float_len_T480.pyx0000644000175600017570000000050212606202452021373 0ustar jenkinsjenkins00000000000000# ticket: 480 def f(x): return x def len_f(x): """ >>> len_f([1,2,3]) 3 """ return len(f(x)) def float_len_f(x): """ >>> float_len_f([1,2,3]) 3.0 """ return float(len(f(x))) def cast_len_f(x): """ >>> cast_len_f([1,2,3]) 3.0 """ return len(f(x)) Cython-0.23.4/tests/run/float_floor_division_T260.pyx0000644000175600017570000000041612606202452023642 0ustar jenkinsjenkins00000000000000# ticket: 260 def floor_div_float(double a, double b): """ >>> floor_div_float(2, 1.5) 1.0 >>> floor_div_float(2, -1.5) -2.0 >>> floor_div_float(-2.3, 1.5) -2.0 >>> floor_div_float(1e10, 1e-10) == 1e20 True """ return a // b Cython-0.23.4/tests/run/float_division.pyx0000644000175600017570000000613312606202452021730 0ustar jenkinsjenkins00000000000000# mode: run # tag: division def int_by_float(): """ >>> int_by_float() 0.5 """ return 1 / 2.0 def float_by_int(): """ >>> float_by_int() 2.0 """ return 2.0 / 1 def float_by_float(): """ >>> float_by_float() 1.5 """ return 3.0 / 2.0 def div_1_by(x): """ >>> div_1_by(1.0) 1.0 >>> div_1_by(2.0) 0.5 >>> div_1_by(0.5) 2.0 >>> 1.0 / float('inf') 0.0 >>> div_1_by(float('inf')) 0.0 >>> div_1_by(float('-inf')) -0.0 >>> div_1_by(float('nan')) nan """ return 1.0 / x def div_by_2(x): """ >>> div_by_2(1.0) 0.5 >>> float('inf') / 2.0 inf >>> div_by_2(float('inf')) inf >>> div_by_2(float('-inf')) -inf >>> float('nan') / 2.0 nan >>> div_by_2(float('nan')) nan """ return x / 2.0 def div_by_neg_2(x): """ >>> div_by_neg_2(1.0) -0.5 >>> div_by_neg_2(-1.0) 0.5 >>> (-2**14) / (-2.0) 8192.0 >>> div_by_neg_2(-2**14) 8192.0 >>> (-2**52) / (-2.0) 2251799813685248.0 >>> div_by_neg_2(-2**52) 2251799813685248.0 >>> (-2**53-1) / (-2.0) 4503599627370496.0 >>> div_by_neg_2(-2**53-1) 4503599627370496.0 >>> float('inf') / -2.0 -inf >>> div_by_neg_2(float('inf')) -inf >>> div_by_neg_2(float('-inf')) inf >>> float('nan') / -2.0 nan >>> div_by_neg_2(float('nan')) nan """ return x / -2.0 def div_neg_2_by(x): """ >>> div_neg_2_by(1.0) -2.0 >>> div_neg_2_by(-1) 2.0 >>> div_neg_2_by(-2.0) 1.0 >>> div_neg_2_by(-2) 1.0 >>> -2.0 / float('inf') -0.0 >>> div_neg_2_by(float('inf')) -0.0 >>> div_neg_2_by(float('-inf')) 0.0 >>> float('nan') / -2.0 nan >>> div_neg_2_by(float('nan')) nan """ return (-2.0) / x def div_by_nan(x): """ >>> 1.0 / float('nan') nan >>> div_by_nan(1.0) nan >>> float('nan') / float('nan') nan >>> div_by_nan(float('nan')) nan >>> float('inf') / float('nan') nan >>> div_by_nan(float('inf')) nan """ return x / float("nan") def div_nan_by(x): """ >>> float('nan') / 1.0 nan >>> div_nan_by(1.0) nan >>> float('nan') / float('nan') nan >>> div_nan_by(float('nan')) nan """ return float("nan") / x def div_by_inf(x): """ >>> 1 / float('inf') 0.0 >>> div_by_inf(1) 0.0 >>> 1.0 / float('inf') 0.0 >>> div_by_inf(1.0) 0.0 >>> div_by_inf(float('inf')) nan """ return x / float("inf") def div_inf_by(x): """ >>> float('inf') / 1.0 inf >>> div_inf_by(1.0) inf >>> float('inf') / float('nan') nan >>> div_inf_by(float('nan')) nan >>> float('inf') / float('-inf') nan >>> div_inf_by(float('-inf')) nan """ return float("inf") / x def div_neg_inf_by(x): """ >>> float('-inf') / 1.0 -inf >>> div_neg_inf_by(1.0) -inf >>> float('-inf') / -1.0 inf >>> div_neg_inf_by(-1.0) inf """ return float("-inf") / x Cython-0.23.4/tests/run/flatin.pyx0000644000175600017570000000156612606202452020201 0ustar jenkinsjenkins00000000000000def test_in(s): """ >>> test_in('ABC') 1 >>> test_in('abc') 2 >>> test_in('X') 3 >>> test_in('XYZ') 4 >>> test_in('ABCXYZ') 5 >>> test_in('') 5 """ if s in (u'ABC', u'BCD', u'ABC'[:3], u'ABC'[::-1], u'ABC'[-1]): return 1 elif s.upper() in (u'ABC', u'BCD'): return 2 elif len(s) in (1,2): return 3 elif len(s) in (3,4): return 4 else: return 5 def test_not_in(s): """ >>> test_not_in('abc') 1 >>> test_not_in('CDE') 2 >>> test_not_in('CDEF') 3 >>> test_not_in('BCD') 4 """ if s not in (u'ABC', u'BCD', u'CDE', u'CDEF'): return 1 elif s.upper() not in (u'ABC', u'BCD', u'CDEF'): return 2 elif len(s) not in [3]: return 3 elif len(s) not in [1,2]: return 4 else: return 5 Cython-0.23.4/tests/run/final_method_T586.pyx0000644000175600017570000000323212606202452022073 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 568 cimport cython @cython.final cdef class FinalType(object): """ >>> obj = FinalType() >>> obj.test_cdef() >>> obj.test_cpdef() """ @cython.test_assert_path_exists("//CFuncDefNode[@entry.is_final_cmethod=True]") cdef cdef_method(self): pass @cython.test_assert_path_exists("//CFuncDefNode[@entry.is_final_cmethod=True]") @cython.test_fail_if_path_exists("//CFuncDefNode//OverrideCheckNode") cpdef cpdef_method(self): pass @cython.test_assert_path_exists("//AttributeNode[@entry.is_final_cmethod=True]") def test_cdef(self): self.cdef_method() @cython.test_assert_path_exists("//AttributeNode[@entry.is_final_cmethod=True]") def test_cpdef(self): self.cpdef_method() def test_external_call(): """ >>> test_external_call() """ f = FinalType() return f.cpdef_method() def test_external_call_in_temp(): """ >>> test_external_call_in_temp() """ return FinalType().cpdef_method() cdef class BaseTypeWithFinalMethods(object): """ >>> obj = BaseTypeWithFinalMethods() >>> obj.test_cdef() """ @cython.test_assert_path_exists("//CFuncDefNode[@entry.is_final_cmethod=True]") @cython.final cdef cdef_method(self): pass @cython.test_assert_path_exists("//AttributeNode[@entry.is_final_cmethod=True]") def test_cdef(self): self.cdef_method() cdef class SubType(BaseTypeWithFinalMethods): """ >>> obj = SubType() >>> obj.test_cdef() """ @cython.test_assert_path_exists("//AttributeNode[@entry.is_final_cmethod=True]") def test_cdef(self): self.cdef_method() Cython-0.23.4/tests/run/final_in_pxd.srctree0000644000175600017570000000313712606202452022201 0ustar jenkinsjenkins00000000000000PYTHON -c "import a; assert a.__file__.rstrip('co').endswith('.py'), a.__file__; a.test()" PYTHON setup.py build_ext --inplace PYTHON -c "import a; assert not a.__file__.rstrip('co').endswith('.py'), a.__file__; a.test()" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize("a.py"), ) ######## a.pxd ######## cimport cython cdef class ExtType: @cython.final cdef int final_func(self) @cython.final cdef class FinalExtType: cdef int func(self) @cython.final cdef class FinalExtSubType(ExtType): cdef int func(self) cdef class NonFinalSubType(ExtType): cdef int func(self) ######## a.py ######## import cython class ExtType(object): @cython.test_assert_path_exists("//CFuncDefNode[@entry.is_final_cmethod=True]") def final_func(self): return 1 class FinalExtType(object): @cython.test_assert_path_exists("//CFuncDefNode[@entry.is_final_cmethod=True]") def func(self): return 2 class FinalExtSubType(ExtType): @cython.test_assert_path_exists("//CFuncDefNode[@entry.is_final_cmethod=True]") def func(self): return 3 class NonFinalSubType(ExtType): @cython.test_assert_path_exists("//CFuncDefNode[@entry.is_final_cmethod=True]") @cython.final def func(self): return 4 def test(): assert ExtType().final_func() == 1 assert FinalExtSubType().final_func() == 1 assert NonFinalSubType().final_func() == 1 assert FinalExtType().func() == 2 assert FinalExtSubType().func() == 3 assert NonFinalSubType().func() == 4 Cython-0.23.4/tests/run/final_cdef_class.pyx0000644000175600017570000000141412606202452022153 0ustar jenkinsjenkins00000000000000 cimport cython @cython.final cdef class FinalClass: """ >>> f = FinalClass() >>> test_final_class(f) Type tested >>> try: ... class SubType(FinalClass): pass ... except TypeError: ... print('PASSED!') PASSED! """ cdef class NonFinalClass: """ >>> class SubType(NonFinalClass): pass >>> s = SubType() """ @cython.final cdef class FinalSubClass(NonFinalClass): """ >>> f = FinalSubClass() >>> test_non_final_class(f) Type tested >>> try: ... class SubType(FinalSubClass): pass ... except TypeError: ... print('PASSED!') PASSED! """ def test_final_class(FinalClass c): print u"Type tested" def test_non_final_class(NonFinalClass c): print u"Type tested" Cython-0.23.4/tests/run/filenames.pyx0000644000175600017570000000012712606202452020657 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> print(spam) ftang >>> foo 42 """ include "filenames.pxi" foo = 42 Cython-0.23.4/tests/run/filenames.pxi0000644000175600017570000000002012606202452020627 0ustar jenkinsjenkins00000000000000spam = u"ftang" Cython-0.23.4/tests/run/file_encoding_T740.py0000644000175600017570000000012012606202452022020 0ustar jenkinsjenkins00000000000000# encoding: koi8-r # mode: run # ticket: 740 """ >>> wtf 'wtf' """ wtf = 'wtf' Cython-0.23.4/tests/run/exttype_freelist.pyx0000644000175600017570000002507712606202452022326 0ustar jenkinsjenkins00000000000000# mode: run # tag: freelist, cyclicgc cimport cython @cython.freelist(4) cdef class ExtTypeNoGC: """ >>> obj = ExtTypeNoGC() >>> obj = ExtTypeNoGC() >>> obj = ExtTypeNoGC() >>> obj = ExtTypeNoGC() >>> obj = ExtTypeNoGC() >>> obj = ExtTypeNoGC() >>> class PyClass(ExtTypeNoGC): a = 1 >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj >>> class PyClass(ExtTypeNoGC): __slots__ = () >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj """ cdef class ExtSubTypeNoGC(ExtTypeNoGC): """ >>> obj = ExtSubTypeNoGC() >>> obj = ExtSubTypeNoGC() >>> obj = ExtSubTypeNoGC() >>> obj = ExtSubTypeNoGC() >>> obj = ExtSubTypeNoGC() >>> obj = ExtSubTypeNoGC() >>> class PyClass(ExtSubTypeNoGC): a = 1 >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj >>> class PyClass(ExtSubTypeNoGC): __slots__ = () >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj """ cdef bytes x @cython.freelist(4) cdef class ExtTypeWithGC: """ >>> obj = ExtTypeWithGC() >>> obj = ExtTypeWithGC() >>> obj = ExtTypeWithGC() >>> obj = ExtTypeWithGC() >>> obj = ExtTypeWithGC() >>> obj = ExtTypeWithGC() >>> class PyClass(ExtTypeWithGC): a = 1 >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj >>> class PyClass(ExtTypeWithGC): __slots__ = () >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj """ cdef attribute def __init__(self): self.attribute = object() def tpnew_ExtTypeWithGC(): """ >>> obj = tpnew_ExtTypeWithGC() >>> obj = tpnew_ExtTypeWithGC() >>> obj = tpnew_ExtTypeWithGC() >>> obj = tpnew_ExtTypeWithGC() >>> obj = tpnew_ExtTypeWithGC() >>> obj = tpnew_ExtTypeWithGC() """ return ExtTypeWithGC.__new__(ExtTypeWithGC) cdef class ExtSubType(ExtTypeWithGC): """ >>> obj = ExtSubType() >>> obj = ExtSubType() >>> obj = ExtSubType() >>> obj = ExtSubType() >>> obj = ExtSubType() >>> obj = ExtSubType() >>> class PyClass(ExtSubType): a = 1 >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj >>> class PyClass(ExtSubType): __slots__ = () >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj """ cdef class LargerExtSubType(ExtSubType): """ >>> obj = LargerExtSubType() >>> obj = LargerExtSubType() >>> obj = LargerExtSubType() >>> obj = LargerExtSubType() >>> obj = LargerExtSubType() >>> obj = LargerExtSubType() >>> class PyClass(LargerExtSubType): a = 1 >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj >>> class PyClass(LargerExtSubType): __slots__ = () >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj """ cdef attribute2 def __cinit__(self): self.attribute2 = object() @cython.freelist(4) cdef class ExtTypeWithCAttr: """ >>> obj = ExtTypeWithCAttr() >>> obj = ExtTypeWithCAttr() >>> obj = ExtTypeWithCAttr() >>> obj = ExtTypeWithCAttr() >>> obj = ExtTypeWithCAttr() >>> obj = ExtTypeWithCAttr() >>> class PyClass(ExtTypeWithCAttr): a = 1 >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj >>> class PyClass(ExtTypeWithCAttr): __slots__ = () >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj """ cdef int cattr def __cinit__(self): assert self.cattr == 0 self.cattr = 1 cdef class ExtSubTypeWithCAttr(ExtTypeWithCAttr): """ >>> obj = ExtSubTypeWithCAttr() >>> obj = ExtSubTypeWithCAttr() >>> obj = ExtSubTypeWithCAttr() >>> obj = ExtSubTypeWithCAttr() >>> obj = ExtSubTypeWithCAttr() >>> obj = ExtSubTypeWithCAttr() >>> class PyClass(ExtSubTypeWithCAttr): a = 1 >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> class PyClass(ExtSubTypeWithCAttr): __slots__ = () >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() """ cdef class ExtTypeWithCAttrNoFreelist: """ For comparison with normal CPython instantiation. >>> obj = ExtTypeWithCAttrNoFreelist() >>> obj = ExtTypeWithCAttrNoFreelist() >>> obj = ExtTypeWithCAttrNoFreelist() >>> obj = ExtTypeWithCAttrNoFreelist() >>> obj = ExtTypeWithCAttrNoFreelist() >>> obj = ExtTypeWithCAttrNoFreelist() >>> class PyClass(ExtTypeWithCAttrNoFreelist): a = 1 >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj >>> class PyClass(ExtTypeWithCAttrNoFreelist): __slots__ = () >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj """ cdef int cattr def __cinit__(self): assert self.cattr == 0 self.cattr = 1 @cython.freelist(4) cdef class ExtTypeWithCMethods: """ >>> obj = ExtTypeWithCMethods() >>> test_cmethods(obj) (1, 2) >>> obj = ExtTypeWithCMethods() >>> test_cmethods(obj) (1, 2) >>> obj = ExtTypeWithCMethods() >>> test_cmethods(obj) (1, 2) >>> obj = ExtTypeWithCMethods() >>> test_cmethods(obj) (1, 2) >>> obj = ExtTypeWithCMethods() >>> test_cmethods(obj) (1, 2) >>> obj = ExtTypeWithCMethods() >>> test_cmethods(obj) (1, 2) >>> class PyClass(ExtTypeWithCMethods): a = 1 >>> obj = PyClass() >>> obj = PyClass() >>> test_cmethods(obj) (1, 2) >>> obj = PyClass() >>> test_cmethods(obj) (1, 2) >>> obj = PyClass() >>> del PyClass, obj >>> class PyClass(ExtTypeWithCMethods): __slots__ = () >>> obj = PyClass() >>> obj = PyClass() >>> test_cmethods(obj) (1, 2) >>> obj = PyClass() >>> test_cmethods(obj) (1, 2) >>> obj = PyClass() >>> del PyClass, obj """ cdef int cattr def __cinit__(self): assert self.cattr == 0 self.cattr = 1 cdef int get_cattr(self): return self.cattr cdef set_cattr(self, int value): self.cattr = value def test_cmethods(ExtTypeWithCMethods obj not None): x = obj.get_cattr() obj.set_cattr(2) return x, obj.get_cattr() cdef class ExtSubTypeWithCMethods(ExtTypeWithCMethods): """ >>> obj = ExtSubTypeWithCMethods() >>> test_cmethods(obj) (1, 2) >>> obj = ExtSubTypeWithCMethods() >>> test_cmethods(obj) (1, 2) >>> obj = ExtSubTypeWithCMethods() >>> test_cmethods(obj) (1, 2) >>> obj = ExtSubTypeWithCMethods() >>> test_cmethods(obj) (1, 2) >>> obj = ExtSubTypeWithCMethods() >>> test_cmethods(obj) (1, 2) >>> obj = ExtSubTypeWithCMethods() >>> test_cmethods(obj) (1, 2) >>> class PyClass(ExtSubTypeWithCMethods): a = 1 >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj >>> class PyClass(ExtSubTypeWithCMethods): __slots__ = () >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj """ cdef class ExtSubTypeWithMoreCMethods(ExtSubTypeWithCMethods): """ >>> obj = ExtSubTypeWithMoreCMethods() >>> test_more_cmethods(obj) (2, 3, 3) >>> obj = ExtSubTypeWithCMethods() >>> test_cmethods(obj) (1, 2) >>> obj = ExtTypeWithCMethods() >>> test_cmethods(obj) (1, 2) >>> obj = ExtSubTypeWithMoreCMethods() >>> test_more_cmethods(obj) (2, 3, 3) >>> obj2 = ExtSubTypeWithMoreCMethods() >>> test_more_cmethods(obj2) (2, 3, 3) >>> obj2 = ExtSubTypeWithCMethods() >>> test_cmethods(obj2) (1, 2) >>> obj = ExtSubTypeWithMoreCMethods() >>> test_more_cmethods(obj) (2, 3, 3) >>> obj2 = ExtTypeWithCMethods() >>> test_cmethods(obj2) (1, 2) >>> obj = ExtSubTypeWithMoreCMethods() >>> test_more_cmethods(obj) (2, 3, 3) >>> obj2 = ExtSubTypeWithCMethods() >>> test_cmethods(obj2) (1, 2) >>> obj = ExtSubTypeWithMoreCMethods() >>> test_more_cmethods(obj) (2, 3, 3) >>> obj2 = ExtSubTypeWithCMethods() >>> test_cmethods(obj2) (1, 2) >>> obj = ExtTypeWithCMethods() >>> test_cmethods(obj) (1, 2) >>> class PyClass(ExtSubTypeWithMoreCMethods): a = 1 >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj >>> class PyClass(ExtSubTypeWithMoreCMethods): __slots__ = () >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj """ def __cinit__(self): assert self.cattr == 1 self.cattr = 2 cdef int get_cattr2(self): return self.cattr cdef set_cattr2(self, int value): self.cattr = value def test_more_cmethods(ExtSubTypeWithMoreCMethods obj not None): x = obj.get_cattr() assert obj.get_cattr2() == x obj.set_cattr2(2) assert obj.get_cattr2() == 2 obj.set_cattr(3) return x, obj.get_cattr(), obj.get_cattr2() @cython.freelist(4) cdef class ExtTypeWithRefCycle: """ >>> obj = first = ExtTypeWithRefCycle() >>> obj.attribute is None True >>> obj = ExtTypeWithRefCycle(obj) >>> obj.attribute is first True >>> obj = ExtTypeWithRefCycle(obj) >>> obj = ExtTypeWithRefCycle(obj) >>> obj = ExtTypeWithRefCycle(obj) >>> obj = ExtTypeWithRefCycle(obj) >>> obj.attribute is not None True >>> first.attribute = obj >>> del obj, first >>> class PyClass(ExtTypeWithRefCycle): a = 1 >>> obj = PyClass() >>> obj.attribute = obj >>> obj.attribute = PyClass(obj) >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj >>> class PyClass(ExtTypeWithRefCycle): __slots__ = () >>> obj = PyClass() >>> obj.attribute = obj >>> obj.attribute = PyClass(obj) >>> obj = PyClass() >>> obj = PyClass() >>> del PyClass, obj """ cdef public attribute def __init__(self, obj=None): self.attribute = obj Cython-0.23.4/tests/run/exttype_dealloc.pyx0000644000175600017570000000631312606202452022104 0ustar jenkinsjenkins00000000000000# mode: run # tag: dealloc import gc import sys test_results = [] cdef void add_name(obj): name = type(obj).__name__.rsplit('.', 1)[-1] test_results.append(name) def find_name(exttype): name = exttype.__name__.rsplit('.', 1)[-1] return test_results.count(name) cdef class ExtTypeSimple: """ >>> obj = ExtTypeSimple() >>> find_name(ExtTypeSimple) 0 >>> obj = None >>> _ = gc.collect() >>> find_name(ExtTypeSimple) 1 """ cdef int x def __dealloc__(self): add_name(self) self.x = 0 class PySubTypeSimple(ExtTypeSimple): """ >>> obj = PySubTypeSimple() >>> find_name(PySubTypeSimple) 0 >>> obj = None >>> _ = gc.collect() >>> find_name(PySubTypeSimple) 1 """ class PySubTypeDel(ExtTypeSimple): """ >>> obj = PySubTypeDel() >>> find_name(PySubTypeDel) 0 >>> obj = None >>> _ = gc.collect() >>> find_name(PySubTypeDel) 2 """ def __del__(self): add_name(self) cdef class ExtSubTypeObjAttr(ExtTypeSimple): """ >>> obj = ExtSubTypeObjAttr() >>> find_name(ExtSubTypeObjAttr) 0 >>> obj = None >>> _ = gc.collect() # both this type and the base class add the same name >>> find_name(ExtSubTypeObjAttr) 2 """ cdef object attr def __dealloc__(self): add_name(self) self.x = 1 cdef class ExtTypeRaise: """ >>> obj = ExtTypeRaise() >>> find_name(ExtTypeRaise) 0 >>> obj = None >>> _ = gc.collect() >>> find_name(ExtTypeRaise) 1 """ def __dealloc__(self): add_name(self) raise RuntimeError("HUHU !") class PySubTypeRaise(ExtTypeRaise): """ >>> obj = PySubTypeRaise() >>> obj.ref = obj >>> find_name(PySubTypeRaise) 0 >>> obj = None >>> _ = gc.collect() >>> find_name(PySubTypeRaise) 1 """ cdef class ExtTypeRefCycle: """ >>> obj = ExtTypeRefCycle() >>> obj.ref = obj >>> find_name(ExtTypeRefCycle) 0 >>> obj = None >>> _ = gc.collect() >>> find_name(ExtTypeRefCycle) 1 """ cdef public object ref cdef int x def __dealloc__(self): add_name(self) self.x = 1 class PySubTypeRefCycleDel(ExtTypeRefCycle): """ >>> obj = PySubTypeRefCycleDel() >>> obj.ref = obj >>> find_name(PySubTypeRefCycleDel) 0 >>> obj = None >>> _ = gc.collect() >>> count = 2 >>> if sys.version_info >= (3, 4): ... count = find_name(PySubTypeRefCycleDel) >>> count 2 """ def __del__(self): add_name(self) cdef class ExtTypeRefCycleRaise: """ >>> obj = ExtTypeRefCycleRaise() >>> obj.ref = obj >>> find_name(ExtTypeRefCycleRaise) 0 >>> obj = None >>> _ = gc.collect() >>> find_name(ExtTypeRefCycleRaise) 1 """ cdef public object ref def __dealloc__(self): add_name(self) raise RuntimeError("Cleaning up !") class PySubTypeRefCycleRaise(ExtTypeRefCycleRaise): """ >>> obj = PySubTypeRefCycleRaise() >>> obj.ref = obj >>> find_name(PySubTypeRefCycleRaise) 0 >>> obj = None >>> _ = gc.collect() >>> find_name(PySubTypeRefCycleRaise) 1 """ Cython-0.23.4/tests/run/exttype.pyx0000644000175600017570000000142212606202452020415 0ustar jenkinsjenkins00000000000000 cdef gobble(a, b): print a, b cdef class Spam: """ >>> s = Spam(12) >>> s.eat() 12 42 """ cdef eggs cdef int ham def __cinit__(self, eggs): self.eggs = eggs self.ham = 42 def __dealloc__(self): self.ham = 0 def eat(self): gobble(self.eggs, self.ham) def f(Spam spam): """ >>> s = Spam(12) >>> f(s) # doctest: +ELLIPSIS Traceback (most recent call last): AttributeError: '...Spam' object has no attribute 'foo' >>> s.eat() 12 42 >>> class Spam2(Spam): ... foo = 1 >>> s = Spam2(12) >>> s.eat() 12 42 >>> f(s) >>> s.eat() 12 42 """ x = spam.eggs y = spam.ham z = spam.foo spam.eggs = x spam.ham = y spam.foo = z Cython-0.23.4/tests/run/extstarargs.pyx0000644000175600017570000000662312606202452021272 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> s = Silly(1,2,3, 'test') >>> (spam,grail,swallow,creosote,onlyt,onlyk,tk) = ( ... s.spam,s.grail,s.swallow,s.creosote,s.onlyt,s.onlyk,s.tk) >>> spam(1,2,3) (1, 2, 3) >>> spam(1,2) Traceback (most recent call last): TypeError: spam() takes exactly 3 positional arguments (2 given) >>> spam(1,2,3,4) Traceback (most recent call last): TypeError: spam() takes exactly 3 positional arguments (4 given) >>> spam(1,2,3, a=1) #doctest: +ELLIPSIS Traceback (most recent call last): TypeError: spam() got an unexpected keyword argument 'a' >>> grail(1,2,3) (1, 2, 3, ()) >>> grail(1,2,3,4) (1, 2, 3, (4,)) >>> grail(1,2,3,4,5,6,7,8,9) (1, 2, 3, (4, 5, 6, 7, 8, 9)) >>> grail(1,2) Traceback (most recent call last): TypeError: grail() takes at least 3 positional arguments (2 given) >>> grail(1,2,3, a=1) #doctest: +ELLIPSIS Traceback (most recent call last): TypeError: grail() got an unexpected keyword argument 'a' >>> swallow(1,2,3) (1, 2, 3, ()) >>> swallow(1,2,3,4) Traceback (most recent call last): TypeError: swallow() takes exactly 3 positional arguments (4 given) >>> swallow(1,2,3, a=1, b=2) (1, 2, 3, (('a', 1), ('b', 2))) >>> swallow(1,2,3, x=1) Traceback (most recent call last): TypeError: swallow() got multiple values for keyword argument 'x' >>> creosote(1,2,3) (1, 2, 3, (), ()) >>> creosote(1,2,3,4) (1, 2, 3, (4,), ()) >>> creosote(1,2,3, a=1) (1, 2, 3, (), (('a', 1),)) >>> creosote(1,2,3,4, a=1, b=2) (1, 2, 3, (4,), (('a', 1), ('b', 2))) >>> creosote(1,2,3,4, x=1) Traceback (most recent call last): TypeError: creosote() got multiple values for keyword argument 'x' >>> onlyt(1) (1,) >>> onlyt(1,2) (1, 2) >>> onlyt(a=1) Traceback (most recent call last): TypeError: onlyt() got an unexpected keyword argument 'a' >>> onlyt(1, a=2) Traceback (most recent call last): TypeError: onlyt() got an unexpected keyword argument 'a' >>> onlyk(a=1) (('a', 1),) >>> onlyk(a=1, b=2) (('a', 1), ('b', 2)) >>> onlyk(1) Traceback (most recent call last): TypeError: onlyk() takes exactly 0 positional arguments (1 given) >>> onlyk(1, 2) Traceback (most recent call last): TypeError: onlyk() takes exactly 0 positional arguments (2 given) >>> onlyk(1, a=1, b=2) Traceback (most recent call last): TypeError: onlyk() takes exactly 0 positional arguments (1 given) >>> tk(a=1) (('a', 1),) >>> tk(a=1, b=2) (('a', 1), ('b', 2)) >>> tk(1) (1,) >>> tk(1, 2) (1, 2) >>> tk(1, a=1, b=2) (1, ('a', 1), ('b', 2)) """ import sys, re if sys.version_info >= (2,6): __doc__ = re.sub(u"(ELLIPSIS[^>]*Error: )[^\n]*\n", u"\\1...\n", __doc__, re.M) cdef sorteditems(d): l = list(d.items()) l.sort() return tuple(l) cdef class Silly: def __init__(self, *a): pass def spam(self, x, y, z): return (x, y, z) def grail(self, x, y, z, *a): return (x, y, z, a) def swallow(self, x, y, z, **k): return (x, y, z, sorteditems(k)) def creosote(self, x, y, z, *a, **k): return (x, y, z, a, sorteditems(k)) def onlyt(self, *a): return a def onlyk(self, **k): return sorteditems(k) def tk(self, *a, **k): return a + sorteditems(k) Cython-0.23.4/tests/run/extpropertyref.pyx0000644000175600017570000000167712606202452022031 0ustar jenkinsjenkins00000000000000# cython: autotestdict=True cdef class Spam: property eggs: def __get__(self): """ This is the docstring for Spam.eggs.__get__ >>> True True """ return 42 def tomato(): """ >>> tomato() 42 >>> lines = __test__.keys() >>> len(lines) 3 >>> 'Spam.eggs.__get__ (line 7)' in lines or lines True >>> 'tomato (line 16)' in lines or lines True """ cdef Spam spam cdef object lettuce spam = Spam() lettuce = spam.eggs return lettuce cdef class Bacon(object): cdef object number_of_slices cdef public object is_a_vegetable def breakfast(): """ >>> breakfast() """ cdef Bacon myslices = Bacon() myslices.is_a_vegetable = True assert myslices.is_a_vegetable, myslices.is_a_vegetable del myslices.is_a_vegetable assert myslices.is_a_vegetable is None, myslices.is_a_vegetable Cython-0.23.4/tests/run/extmember.pyx0000644000175600017570000000077212606202452020712 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> s = Spam() >>> s.e = s >>> s.e = 1 Traceback (most recent call last): TypeError: Cannot convert int to extmember.Spam >>> s.e is s True >>> s.e = None >>> s = Bot() >>> s.e = s >>> s.e = 1 Traceback (most recent call last): TypeError: Cannot convert int to extmember.Bot >>> s.e is s True >>> s.e = None """ # declared in the pxd cdef class Spam: pass # not declared in the pxd cdef class Bot: cdef public Bot e Cython-0.23.4/tests/run/extmember.pxd0000644000175600017570000000005012606202452020652 0ustar jenkinsjenkins00000000000000cdef class Spam: cdef public Spam e Cython-0.23.4/tests/run/extlen.pyx0000644000175600017570000000015012606202452020207 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> len(Spam()) 0 """ cdef class Spam: def __len__(self): return 0 Cython-0.23.4/tests/run/extkwonlyargs.pyx0000644000175600017570000000561412606202452021643 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> ext = Ext() >>> b,c,d,e,f,g,h,k = ext.b,ext.c,ext.d,ext.e,ext.f,ext.g,ext.h,ext.k """ cdef class Ext: def b(self, a, b, c): pass def c(self, a, b, c=1): pass def d(self, a, b, *, c = 88): pass def e(self, a, b, c = 88, **kwds): pass def f(self, a, b, *, c, d = 42): pass def g(self, a, b, *, c, d = 42, e = 17, f, **kwds): pass def h(self, a, b, *args, c, d = 42, e = 17, f, **kwds): pass def k(self, a, b, c=1, *args, d = 42, e = 17, f, **kwds): pass """# c >>> c(1,2) >>> c(1,2,3) >>> c(1,2,3,4) Traceback (most recent call last): TypeError: c() takes at most 3 positional arguments (4 given) # b >>> b(1,2,3) >>> b(1,2,3,4) Traceback (most recent call last): TypeError: b() takes exactly 3 positional arguments (4 given) # e >>> e(1,2) >>> e(1,2, c=1) >>> e(1,2, d=1) >>> e(1,2, c=1, d=2, e=3) >>> e(1,2,3) >>> e(1,2,3,4) Traceback (most recent call last): TypeError: e() takes at most 3 positional arguments (4 given) # d >>> d(1,2) >>> d(1,2, c=1) >>> d(1,2,3) Traceback (most recent call last): TypeError: d() takes exactly 2 positional arguments (3 given) >>> d(1,2, d=1) Traceback (most recent call last): TypeError: d() got an unexpected keyword argument 'd' # g >>> g(1,2, c=1, f=2) >>> g(1,2, c=1, e=0, f=2, d=11) >>> g(1,2, c=1, f=2, e=0, x=25) >>> g(1,2,3) Traceback (most recent call last): TypeError: g() takes exactly 2 positional arguments (3 given) >>> g(1,2) Traceback (most recent call last): TypeError: g() needs keyword-only argument c >>> g(1,2, c=1) Traceback (most recent call last): TypeError: g() needs keyword-only argument f # f >>> f(1,2, c=1) >>> f(1,2, c=1, d=2) >>> f(1,2,3) Traceback (most recent call last): TypeError: f() takes exactly 2 positional arguments (3 given) >>> f(1,2) Traceback (most recent call last): TypeError: f() needs keyword-only argument c >>> f(1,2, c=1, e=2) Traceback (most recent call last): TypeError: f() got an unexpected keyword argument 'e' # h >>> h(1,2, c=1, f=2) >>> h(1,2, c=1, f=2, e=3) >>> h(1,2,3,4,5,6, c=1, f=2) >>> h(1,2,3,4,5,6, c=1, f=2, e=3, x=25, y=11) >>> h(1,2,3) Traceback (most recent call last): TypeError: h() needs keyword-only argument c >>> h(1,2, d=1) Traceback (most recent call last): TypeError: h() needs keyword-only argument c # k >>> k(1,2, c=1, f=2) >>> k(1,2, c=1, f=2, e=3) >>> k(1,2,3,4,5,6, d=1, f=2) >>> k(1,2,3,4,5,6, d=1, f=2, e=3, x=25, y=11) >>> k(1,2,3) Traceback (most recent call last): TypeError: k() needs keyword-only argument f >>> k(1,2, d=1) Traceback (most recent call last): TypeError: k() needs keyword-only argument f """ Cython-0.23.4/tests/run/extinstantiate.pyx0000644000175600017570000000017212606202452021760 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> type(f()).__name__ 'Spam' """ cdef class Spam: pass def f(): s = Spam() return s Cython-0.23.4/tests/run/extinherit.pyx0000644000175600017570000000077312606202452021106 0ustar jenkinsjenkins00000000000000cdef class Parrot: cdef object name cdef int alive cdef class Norwegian(Parrot): cdef object plumage_colour def create(): cdef Parrot p p = Norwegian() p.alive = 1 return p def rest(Norwegian polly): """ >>> p = create() >>> rest(p) 0 """ cdef Parrot fred cdef object spam spam = None fred = polly polly = fred polly = spam assert polly is None assert fred.alive spam = polly fred.alive = 0 return fred.alive Cython-0.23.4/tests/run/external_ref_reassignment.pyx0000644000175600017570000000104012606202452024144 0ustar jenkinsjenkins00000000000000# Test that variable visible outside of the local scope (e.g. closure, cglobals) # is set before original value is decrefed. cdef object g def test_cglobals_reassignment(): """ >>> test_cglobals_reassignment() 1234 """ global g class Special: def __del__(self): print g g = (Special(),) g = 1234 def test_closure_reassignment(): """ >>> test_closure_reassignment() 4321 """ class Special: def __del__(self): print c c = (Special(),) c = 4321 Cython-0.23.4/tests/run/external_inline_declaration.srctree0000644000175600017570000000061612606202452025273 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import a; assert a.test() == 1" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize("a.py"), ) ######## a.py ######## def inlined_func(x): return x def test(): return inlined_func(1) ######## a.pxd ######## cdef inline int inlined_func(int x) Cython-0.23.4/tests/run/external_defs.h0000644000175600017570000000110212606202452021140 0ustar jenkinsjenkins00000000000000 typedef float FloatTypedef; typedef double DoubleTypedef; typedef long double LongDoubleTypedef; typedef char CharTypedef; typedef short ShortTypedef; typedef int IntTypedef; typedef long LongTypedef; #if defined(T_LONGLONG) typedef PY_LONG_LONG LongLongTypedef; #else typedef long LongLongTypedef; #endif typedef unsigned char UCharTypedef; typedef unsigned short UShortTypedef; typedef unsigned int UIntTypedef; typedef unsigned long ULongTypedef; #if defined(T_LONGLONG) typedef unsigned PY_LONG_LONG ULongLongTypedef; #else typedef unsigned long ULongLongTypedef; #endif Cython-0.23.4/tests/run/extern_impl.srctree0000644000175600017570000000067012606202452022074 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import foo" PYTHON -c "import a" ######## setup.py ######## from Cython.Build import cythonize from distutils.core import setup setup( ext_modules = cythonize("*.pyx"), ) ######## foo.pxd ######## cdef void bar() ######## foo.pyx ######## cdef extern from "bar_impl.c": void bar() ######## bar_impl.c ######## static void bar() {} ######## a.pyx ######## from foo cimport bar Cython-0.23.4/tests/run/extern_builtins_T258.pyx0000644000175600017570000000163112606202452022655 0ustar jenkinsjenkins00000000000000# ticket: 258 cdef extern from "Python.h": ctypedef class __builtin__.list [object PyListObject]: cdef Py_ssize_t allocated ctypedef class __builtin__.dict [object PyDictObject]: pass cdef Py_ssize_t Py_SIZE(object o) cdef list L = [1,2,4] cdef dict d = {'A': 'a'} def test_list(list L): """ >>> test_list(list(range(10))) True >>> class list_subclass(list): pass >>> test_list(list_subclass([1,2,3])) True """ return Py_SIZE(L) <= L.allocated def test_tuple(tuple t): """ Actual builtin types are restrictive wrt subclassing so optimizations can be safely performed. >>> test_tuple((1,2)) 2 >>> class tuple_subclass(tuple): pass >>> test_tuple(tuple_subclass((1,2))) Traceback (most recent call last): ... TypeError: Argument 't' has incorrect type (expected tuple, got tuple_subclass) """ return len(t) Cython-0.23.4/tests/run/extended_unpacking_T409.pyx0000644000175600017570000000061212606202452023272 0ustar jenkinsjenkins00000000000000# ticket: 409 def simple(): """ >>> simple() ([1, 2], [1, 2]) """ d = e = [1,2] return d, e def simple_parallel(): """ >>> simple_parallel() (1, 2, [1, 2], [1, 2]) """ a, c = d = e = [1,2] return a, c, d, e def extended(): """ >>> extended() (1, [], 2, [1, 2], [1, 2]) """ a, *b, c = d = e = [1,2] return a, b, c, d, e Cython-0.23.4/tests/run/extended_unpacking_T235.pyx0000644000175600017570000002011512606202452023267 0ustar jenkinsjenkins00000000000000# ticket: 235 __doc__ = u""" >>> class FakeSeq(object): ... def __init__(self, length): ... self._values = list(range(1,length+1)) ... def __getitem__(self, i): ... return self._values[i] >>> unpack( FakeSeq(2) ) (1, 2) >>> unpack_recursive( FakeSeq(4) ) (1, [2, 3], 4) """ def unpack(l): """ >>> unpack([1,2]) (1, 2) >>> unpack('12') ('1', '2') """ a, b = l return a,b def unpack_list(list l): """ >>> unpack_list([1,2]) (1, 2) """ a, b = l return a,b def unpack_tuple(tuple t): """ >>> unpack_tuple((1,2)) (1, 2) """ a, b = t return a,b def unpack_single(l): """ >>> unpack_single([1]) [1] >>> unpack_single('1') ['1'] """ *a, = l return a def unpack_tuple_single(tuple t): """ >>> unpack_tuple_single((1,)) [1] """ *a, = t return a def assign(): """ >>> assign() (1, [2, 3, 4], 5) """ *a, b = 1,2,3,4,5 assert a+[b] == [1,2,3,4,5], (a,b) a, *b = 1,2,3,4,5 assert [a]+b == [1,2,3,4,5], (a,b) [a, *b, c] = 1,2,3,4,5 return a,b,c def unpack_into_list(l): """ >>> unpack_into_list('123') ('1', ['2'], '3') """ [*a, b] = l assert a+[b] == list(l), repr((a+[b],list(l))) [a, *b] = l assert [a]+b == list(l), repr(([a]+b,list(l))) [a, *b, c] = l return a,b,c def unpack_into_tuple(t): """ >>> unpack_into_tuple('123') ('1', ['2'], '3') """ (*a, b) = t assert a+[b] == list(t), repr((a+[b],list(t))) (a, *b) = t assert [a]+b == list(t), repr(([a]+b,list(t))) (a, *b, c) = t return a,b,c def unpack_in_loop(list_of_sequences): """ >>> unpack_in_loop([(1,2), (1,2,3), (1,2,3,4)]) 1 ([1], 2) ([1, 2], 3) ([1, 2, 3], 4) 2 (1, [2]) (1, [2, 3]) (1, [2, 3, 4]) 3 (1, [], 2) (1, [2], 3) (1, [2, 3], 4) """ print 1 for *a,b in list_of_sequences: print((a,b)) print 2 for a,*b in list_of_sequences: print((a,b)) print 3 for a,*b, c in list_of_sequences: print((a,b,c)) def unpack_recursive(t): """ >>> unpack_recursive((1,2,3,4)) (1, [2, 3], 4) """ *(a, *b), c = t return a,b,c def unpack_typed(t): """ >>> unpack_typed((1,2)) ([1], 2) """ cdef list a *a, b = t return a,b def unpack_right(l): """ >>> unpack_right('') Traceback (most recent call last): ValueError: need more than 0 values to unpack >>> unpack_right('1') ('1', []) >>> unpack_right([1]) (1, []) >>> unpack_right('12') ('1', ['2']) >>> unpack_right([1,2]) (1, [2]) >>> unpack_right('123') ('1', ['2', '3']) >>> unpack_right([1,2,3]) (1, [2, 3]) """ a, *b = l return a,b def unpack_right_list(list l): """ >>> unpack_right_list([]) Traceback (most recent call last): ValueError: need more than 0 values to unpack >>> unpack_right_list([1]) (1, []) >>> unpack_right_list([1,2]) (1, [2]) >>> unpack_right_list([1,2,3]) (1, [2, 3]) """ a, *b = l return a,b def unpack_right_tuple(tuple t): """ >>> unpack_right_tuple(()) Traceback (most recent call last): ValueError: need more than 0 values to unpack >>> unpack_right_tuple((1,)) (1, []) >>> unpack_right_tuple((1,2)) (1, [2]) >>> unpack_right_tuple((1,2,3)) (1, [2, 3]) """ a, *b = t return a,b def unpack_left(l): """ >>> unpack_left('') Traceback (most recent call last): ValueError: need more than 0 values to unpack >>> unpack_left('1') ([], '1') >>> unpack_left([1]) ([], 1) >>> unpack_left('12') (['1'], '2') >>> unpack_left([1,2]) ([1], 2) >>> unpack_left('123') (['1', '2'], '3') >>> unpack_left([1,2,3]) ([1, 2], 3) """ *a, b = l return a,b def unpack_left_list(list l): """ >>> unpack_left_list([]) Traceback (most recent call last): ValueError: need more than 0 values to unpack >>> unpack_left_list([1]) ([], 1) >>> unpack_left_list([1,2]) ([1], 2) >>> unpack_left_list([1,2,3]) ([1, 2], 3) """ *a, b = l return a,b def unpack_left_tuple(tuple t): """ >>> unpack_left_tuple(()) Traceback (most recent call last): ValueError: need more than 0 values to unpack >>> unpack_left_tuple((1,)) ([], 1) >>> unpack_left_tuple((1,2)) ([1], 2) >>> unpack_left_tuple((1,2,3)) ([1, 2], 3) """ *a, b = t return a,b def unpack_middle(l): """ >>> unpack_middle('') Traceback (most recent call last): ValueError: need more than 0 values to unpack >>> unpack_middle([]) Traceback (most recent call last): ValueError: need more than 0 values to unpack >>> unpack_middle(()) Traceback (most recent call last): ValueError: need more than 0 values to unpack >>> unpack_middle('1') Traceback (most recent call last): ValueError: need more than 1 value to unpack >>> unpack_middle([1]) Traceback (most recent call last): ValueError: need more than 1 value to unpack >>> unpack_middle('12') ('1', [], '2') >>> unpack_middle([1,2]) (1, [], 2) >>> unpack_middle('123') ('1', ['2'], '3') >>> unpack_middle([1,2,3]) (1, [2], 3) """ a, *b, c = l return a,b,c def unpack_middle_list(list l): """ >>> unpack_middle_list([]) Traceback (most recent call last): ValueError: need more than 0 values to unpack >>> unpack_middle_list([1]) Traceback (most recent call last): ValueError: need more than 1 value to unpack >>> unpack_middle_list([1,2]) (1, [], 2) >>> unpack_middle_list([1,2,3]) (1, [2], 3) """ a, *b, c = l return a,b,c def unpack_middle_tuple(tuple t): """ >>> unpack_middle_tuple(()) Traceback (most recent call last): ValueError: need more than 0 values to unpack >>> unpack_middle_tuple((1,)) Traceback (most recent call last): ValueError: need more than 1 value to unpack >>> unpack_middle_tuple((1,2)) (1, [], 2) >>> unpack_middle_tuple((1,2,3)) (1, [2], 3) >>> a,b,c = unpack_middle(list(range(100))) >>> a, len(b), c (0, 98, 99) >>> a,b,c = unpack_middle_list(list(range(100))) >>> a, len(b), c (0, 98, 99) >>> a,b,c = unpack_middle_tuple(tuple(range(100))) >>> a, len(b), c (0, 98, 99) """ a, *b, c = t return a,b,c def unpack_many_middle(it): """ >>> unpack_many_middle(list(range(14))) (0, 1, 2, 3, 4, [5, 6, 7, 8, 9], 10, 11, 12, 13) >>> unpack_many_middle(tuple(range(14))) (0, 1, 2, 3, 4, [5, 6, 7, 8, 9], 10, 11, 12, 13) >>> unpack_many_middle(iter(range(14))) (0, 1, 2, 3, 4, [5, 6, 7, 8, 9], 10, 11, 12, 13) """ a,b,c,d,e,*f,g,h,i,j = it return a,b,c,d,e,f,g,h,i,j def unpack_many_left(it): """ >>> unpack_many_left(list(range(14))) (0, 1, 2, 3, 4, 5, 6, 7, 8, [9, 10, 11, 12, 13]) >>> unpack_many_left(tuple(range(14))) (0, 1, 2, 3, 4, 5, 6, 7, 8, [9, 10, 11, 12, 13]) >>> unpack_many_left(iter(range(14))) (0, 1, 2, 3, 4, 5, 6, 7, 8, [9, 10, 11, 12, 13]) """ a,b,c,d,e,f,g,h,i,*j = it return a,b,c,d,e,f,g,h,i,j def unpack_many_right(it): """ >>> unpack_many_right(list(range(14))) ([0, 1, 2, 3, 4], 5, 6, 7, 8, 9, 10, 11, 12, 13) >>> unpack_many_right(tuple(range(14))) ([0, 1, 2, 3, 4], 5, 6, 7, 8, 9, 10, 11, 12, 13) >>> unpack_many_right(iter(range(14))) ([0, 1, 2, 3, 4], 5, 6, 7, 8, 9, 10, 11, 12, 13) """ *a,b,c,d,e,f,g,h,i,j = it return a,b,c,d,e,f,g,h,i,j def unpack_many_right_loop(it): """ >>> unpack_many_right_loop(list(range(14))) ([0, 1, 2, 3, 4], 5, 6, 7, 8, 9, 10, 11, 12, 13) >>> unpack_many_right_loop(tuple(range(14))) ([0, 1, 2, 3, 4], 5, 6, 7, 8, 9, 10, 11, 12, 13) >>> unpack_many_right_loop(iter(range(14))) ([0, 1, 2, 3, 4], 5, 6, 7, 8, 9, 10, 11, 12, 13) """ cdef int i for i in range(1): *a,b,c,d,e,f,g,h,i,j = it return a,b,c,d,e,f,g,h,i,j Cython-0.23.4/tests/run/extcmethod.pyx0000644000175600017570000000246112606202452021063 0ustar jenkinsjenkins00000000000000# mode: run cdef class Spam: cdef int tons cdef void add_tons(self, int x): self.tons += x cdef void eat(self): self.tons = 0 def lift(self): print self.tons cdef class SubSpam(Spam): cdef void add_tons(self, int x): self.tons += 2 * x def test_spam(): """ >>> test_spam() 5 0 20 5 """ cdef Spam s cdef SubSpam ss s = Spam() s.eat() s.add_tons(5) s.lift() ss = SubSpam() ss.eat() ss.lift() ss.add_tons(10) ss.lift() s.lift() cdef class SpamDish: cdef int spam cdef void describe(self): print "This dish contains", self.spam, "tons of spam." cdef class FancySpamDish(SpamDish): cdef int lettuce cdef void describe(self): print "This dish contains", self.spam, "tons of spam", print "and", self.lettuce, "milligrams of lettuce." cdef void describe_dish(SpamDish d): d.describe() def test_spam_dish(): """ >>> test_spam_dish() This dish contains 42 tons of spam. This dish contains 88 tons of spam and 5 milligrams of lettuce. """ cdef SpamDish s cdef FancySpamDish ss s = SpamDish() s.spam = 42 ss = FancySpamDish() ss.spam = 88 ss.lettuce = 5 describe_dish(s) describe_dish(ss) Cython-0.23.4/tests/run/extclasspass.pyx0000644000175600017570000000014112606202452021425 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> e = Eggs() >>> type(e).__name__ 'Eggs' """ cdef class Eggs: pass Cython-0.23.4/tests/run/extclassbody.pyx0000644000175600017570000000035712606202452021425 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> s = Spam() >>> s.a 2 >>> s.c 3 >>> s.test(5) 13 >>> s.b 5 """ cdef class Spam: a = 1 def test(self, a): return a + self.b + self.c b = a + 2 # 3 a = b - 1 # 2 c = 3 # 3 b = c + a # 5 Cython-0.23.4/tests/run/ext_type_none_arg.pyx0000644000175600017570000001322712606202452022432 0ustar jenkinsjenkins00000000000000 cimport cython ### extension types cdef class MyExtType: cdef object attr def __cinit__(self): self.attr = 123 cdef attr(MyExtType x): return x is None and 321 or x.attr # defaults, without 'not/or None' def ext_default(MyExtType x): # currently behaves like 'or None' """ >>> ext_default(MyExtType()) 123 >>> ext_default(None) 321 """ return attr(x) @cython.allow_none_for_extension_args(False) def ext_default_none(MyExtType x=None): # special cased default arg """ >>> ext_default_none(MyExtType()) 123 >>> ext_default_none(None) 321 >>> ext_default_none() 321 """ return attr(x) @cython.allow_none_for_extension_args(True) def ext_default_check_off(MyExtType x): """ >>> ext_default_check_off(MyExtType()) 123 >>> ext_default_check_off(None) 321 """ return attr(x) @cython.allow_none_for_extension_args(False) def ext_default_check_on(MyExtType x): """ >>> ext_default_check_on(MyExtType()) 123 >>> ext_default_check_on(None) Traceback (most recent call last): TypeError: Argument 'x' has incorrect type (expected ext_type_none_arg.MyExtType, got NoneType) """ return attr(x) # with 'or/not None' def ext_or_none(MyExtType x or None): """ >>> ext_or_none(MyExtType()) 123 >>> ext_or_none(None) 321 """ return attr(x) def ext_not_none(MyExtType x not None): """ >>> ext_not_none(MyExtType()) 123 >>> ext_not_none(None) Traceback (most recent call last): TypeError: Argument 'x' has incorrect type (expected ext_type_none_arg.MyExtType, got NoneType) """ return attr(x) ### builtin types (using list) cdef litem(list L, int item): return L is None and 321 or L[item] # defaults, without 'not/or None' def builtin_default(list L): # currently behaves like 'or None' """ >>> builtin_default([123]) 123 >>> builtin_default(None) 321 """ return litem(L, 0) @cython.allow_none_for_extension_args(False) def builtin_default_none(list L=None): # special cased default arg """ >>> builtin_default_none([123]) 123 >>> builtin_default_none(None) 321 >>> builtin_default_none() 321 """ return litem(L, 0) @cython.allow_none_for_extension_args(True) def builtin_default_check_off(list L): """ >>> builtin_default_check_off([123]) 123 >>> builtin_default_check_off(None) 321 """ return litem(L, 0) @cython.allow_none_for_extension_args(False) def builtin_default_check_on(list L): """ >>> builtin_default_check_on([123]) 123 >>> builtin_default_check_on(None) Traceback (most recent call last): TypeError: Argument 'L' has incorrect type (expected list, got NoneType) """ return litem(L, 0) # with 'or/not None' def builtin_or_none(list L or None): """ >>> builtin_or_none([123]) 123 >>> builtin_or_none(None) 321 """ return litem(L, 0) def builtin_not_none(list L not None): """ >>> builtin_not_none([123]) 123 >>> builtin_not_none(None) Traceback (most recent call last): TypeError: Argument 'L' has incorrect type (expected list, got NoneType) """ return litem(L, 0) ## builtin type 'object' - isinstance(None, object) is True! @cython.allow_none_for_extension_args(False) def object_default(object o): # always behaves like 'or None' """ >>> object_default(object()) 'object' >>> object_default([]) 'list' >>> object_default(None) 'NoneType' """ return type(o).__name__ @cython.allow_none_for_extension_args(False) def object_default_none(object o=None): # behaves like 'or None' """ >>> object_default_none(object()) 'object' >>> object_default_none([]) 'list' >>> object_default_none(None) 'NoneType' >>> object_default_none() 'NoneType' """ return type(o).__name__ @cython.allow_none_for_extension_args(False) def object_or_none(object o or None): """ >>> object_or_none(object()) 'object' >>> object_or_none([]) 'list' >>> object_or_none(None) 'NoneType' """ return type(o).__name__ @cython.allow_none_for_extension_args(False) def object_not_none(object o not None): """ >>> object_not_none(object()) 'object' >>> object_not_none([]) 'list' >>> object_not_none(None) Traceback (most recent call last): TypeError: Argument 'o' must not be None """ return type(o).__name__ ## untyped 'object' - isinstance(None, object) is True! @cython.allow_none_for_extension_args(False) def notype_default(o): # behaves like 'or None' """ >>> notype_default(object()) 'object' >>> notype_default([]) 'list' >>> notype_default(None) 'NoneType' """ return type(o).__name__ @cython.allow_none_for_extension_args(False) def notype_default_none(o=None): # behaves like 'or None' """ >>> notype_default_none(object()) 'object' >>> notype_default_none([]) 'list' >>> notype_default_none(None) 'NoneType' >>> notype_default_none() 'NoneType' """ return type(o).__name__ @cython.allow_none_for_extension_args(False) def notype_or_none(o or None): """ >>> notype_or_none(object()) 'object' >>> notype_or_none([]) 'list' >>> notype_or_none(None) 'NoneType' """ return type(o).__name__ @cython.allow_none_for_extension_args(False) def notype_not_none(o not None): """ >>> notype_not_none(object()) 'object' >>> notype_not_none([]) 'list' >>> notype_not_none(None) Traceback (most recent call last): TypeError: Argument 'o' must not be None """ return type(o).__name__ Cython-0.23.4/tests/run/ext_instance_type_T232.pyx0000644000175600017570000000032512606202452023153 0ustar jenkinsjenkins00000000000000# ticket: 232 cdef class MyExt: cdef object attr def set_attr(value): """ >>> set_attr(5) """ MyExt().attr = value def get_attr(): """ >>> get_attr() """ return MyExt().attr Cython-0.23.4/tests/run/ext_attribute_cache.pyx0000644000175600017570000000153012606202452022721 0ustar jenkinsjenkins00000000000000# mode: run # tag: tpflags, type_version_tag cimport cython cdef extern from *: unsigned long PY_VERSION_HEX unsigned long Py_TPFLAGS_HAVE_VERSION_TAG ctypedef struct PyTypeObject: unsigned long tp_flags def test_flag(t): return ((t).tp_flags & Py_TPFLAGS_HAVE_VERSION_TAG) != 0 cdef class ImplicitAttrCache(object): """ >>> flag = test_flag(ImplicitAttrCache) >>> print(flag) True """ cdef public int x cdef object y @cython.type_version_tag(True) cdef class ExplicitAttrCache(object): """ >>> flag = test_flag(ImplicitAttrCache) >>> print(flag) True """ cdef public int x cdef object y @cython.type_version_tag(False) cdef class NoAttrCache(object): """ >>> test_flag(NoAttrCache) False """ cdef public int x cdef object y Cython-0.23.4/tests/run/ext_attr_assign.pyx0000644000175600017570000000413112606202452022111 0ustar jenkinsjenkins00000000000000# mode: run # tag: assign, exttype cdef struct X: int ix X* x cdef class A: cdef int i cdef list l cdef object o cdef X x def assign_A(self): """ >>> A().assign_A() (2, [1, 2, 3]) """ a = A() a.i = 1 a.l = [1, 2, 3] a.o = a.l a.o = a.o a.l = a.o a.i = a.l[1] return a.i, a.l def assign_A_struct(self): """ >>> A().assign_A_struct() (5, 2, 2, 5) """ cdef X x a = A() a.x.ix = 2 a.x.x = &x x.ix = 5 x.x = &a.x assert a.x.x.x is &a.x a.x.x.x.x.x.x.x = a.x.x.x.x assert x.x is &x assert x.x.x is &x assert a.x.x is &x a.x.x.x.x.x.x.x, a.x.x.x = a.x.x.x.x, &a.x # replay+undo :) assert x.x is &a.x assert x.x.x is &x return x.ix, x.x.ix, a.x.ix, a.x.x.ix cdef class B(A): cdef int ib cdef object ob cdef A a def assign_B(self): """ >>> B().assign_B() (1, 2, 5, 9, 2) """ b = B() b.i = 1 b.ib = 2 b.l = [b.i, b.ib] b.o = b.l b.ob = b.o assert b.ob == b.l b.o = b.ob = b.l b.a = A() # only one reference! b.a.o = 5 b.a.i = 5 b.a, b.a.i = A(), b.a.i # overwrite b.a but keep b.a.i assert b.a.i == 5 assert b.a.o is None b.a.o = 9 b.a, b.a.i, b.a.o = A(), b.a.i, b.a.o return b.i, b.ib, b.a.i, b.a.o, b.o[1] def cross_assign_Ba(self): """ >>> B().cross_assign_Ba() 2 """ b = B() b.a = A() b.a.i = 1 b.a.o = A() # only one reference! (b.a.o).i = 2 b.a = b.a.o return b.a.i def cascaded_assign_B(self): """ >>> B().cascaded_assign_B() (2, 2) """ cdef B b = B() b.ib = 1 b.a = A() b.a.o = B() # only one reference! (b.a.o).ib = 2 b = b.ob = b.a.o return b.ib, (b.ob).ib Cython-0.23.4/tests/run/exectest.pyx0000644000175600017570000000546212606202452020547 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- __doc__ = u""" #>>> a #Traceback (most recent call last): #NameError: name 'a' is not defined #>>> test_module_scope() #>>> a """ #def test_module_scope(): # exec "a=1+1" # return __dict__['a'] def test_dict_scope1(): """ >>> test_dict_scope1() 2 """ cdef dict d = {} exec u"b=1+1" in d return d[u'b'] def test_dict_scope2(d): """ >>> d = {} >>> test_dict_scope2(d) >>> d['b'] 2 """ exec u"b=1+1" in d def test_dict_scope3(d1, d2): """ >>> d1 = {} >>> test_dict_scope3(d1, d1) >>> d1['b'] 2 >>> d1, d2 = {}, {} >>> test_dict_scope3(d1, d2) >>> (d1.get('b'), d2.get('b')) (None, 2) >>> d1, d2 = {}, {} >>> test_dict_scope3(d1, d2) >>> (d1.get('b'), d2.get('b')) (None, 2) """ exec u"b=1+1" in d1, d2 def test_dict_scope_ref(d1, d2): """ >>> d1, d2 = dict(a=11), dict(c=5) >>> test_dict_scope_ref(d1, d2) >>> (d1.get('b'), d2.get('b')) (None, 16) >>> d = dict(a=11, c=5) >>> test_dict_scope_ref(d, d) >>> d['b'] 16 >>> d1, d2 = {}, {} >>> test_dict_scope_ref(d1, d2) # doctest: +ELLIPSIS Traceback (most recent call last): NameError: ...name 'a' is not defined """ exec u"b=a+c" in d1, d2 def test_dict_scope_tuple2(): """ >>> test_dict_scope_tuple2() 2 """ cdef dict d = {} exec(u"b=1+1", d) # Py3 compatibility syntax return d[u'b'] def test_dict_scope_tuple3(d1, d2): """ >>> d1, d2 = {}, {} >>> test_dict_scope_tuple3(d1, d2) >>> (d1.get('b'), d2.get('b')) (None, 2) """ exec(u"b=1+1", d1, d2) def test_def(d, varref): """ >>> d = dict(seq = [1,2,3,4]) >>> add_iter = test_def(d, 'seq') >>> list(add_iter()) [2, 3, 4, 5] """ exec u""" def test(): for x in %s: yield x+1 """ % varref in d return d[u'test'] import sys def test_encoding(d1, d2): u""" >>> d = {} >>> test_encoding(d, None) >>> print(d['b']) üöä """ if sys.version_info[0] >= 3: s = "b = 'üöä'" else: s = "# -*- coding: utf-8 -*-" + "\n" + "b = u'üöä'" exec s in d1, d2 def test_encoding_unicode(d1, d2): u""" >>> d = {} >>> test_encoding_unicode(d, None) >>> print(d['b']) üöä """ if sys.version_info[0] >= 3: s = u"b = 'üöä'" else: s = u"b = u'üöä'" exec s in d1, d2 def test_compile(d): """ >>> d = dict(a=1, c=3) >>> test_compile(d) >>> d['b'] 4 """ c = compile(u"b = a+c", u"", u"exec") exec c in d def exec_invalid_type(x): """ >>> exec_invalid_type(42) Traceback (most recent call last): TypeError: exec: arg 1 must be string, bytes or code object, got int """ exec x in {} Cython-0.23.4/tests/run/exec_noargs.pyx0000644000175600017570000000076412606202452021220 0ustar jenkinsjenkins00000000000000# mode: run # tag: exec exec "GLOBAL = 1234" def exec_module_scope(): """ >>> globals()['GLOBAL'] 1234 """ def exec_func_scope(): """ >>> sorted(exec_func_scope().items()) [('G', 1234), ('a', 'b')] """ d = {} exec "d['a'] = 'b'; d['G'] = GLOBAL" return d def exec_pyclass_scope(): """ >>> obj = exec_pyclass_scope() >>> obj.a 'b' >>> obj.G 1234 """ class TestExec: exec "a = 'b'; G = GLOBAL" return TestExec Cython-0.23.4/tests/run/exceptions_nogil.pyx0000644000175600017570000001201412606202452022263 0ustar jenkinsjenkins00000000000000cdef void foo(int i) except * with gil: if i != 0: raise ValueError cdef int bar(int i) except? -1 with gil: if i != 0: raise ValueError return 0 cdef int spam(int i) except? -1 with gil: if i != 0: raise TypeError return -1 def test_foo(): """ >>> test_foo() """ # foo(0) foo(0) with nogil: foo(0) foo(0) # try: with nogil: foo(0) finally: pass # try: with nogil: foo(0) with nogil: foo(0) finally: pass # try: with nogil: foo(0) with nogil: foo(1) except: with nogil: foo(0) finally: with nogil: foo(0) pass # try: with nogil: foo(0) foo(0) finally: pass # try: with nogil: foo(0) foo(1) except: with nogil: foo(0) finally: with nogil: foo(0) pass # try: with nogil: foo(0) try: with nogil: foo(1) except: with nogil: foo(1) finally: with nogil: foo(0) pass except: with nogil: foo(0) finally: with nogil: foo(0) pass # try: with nogil: foo(0) try: with nogil: foo(1) except: with nogil: foo(1) finally: with nogil: foo(1) pass except: with nogil: foo(0) finally: with nogil: foo(0) pass # def test_bar(): """ >>> test_bar() """ # bar(0) bar(0) with nogil: bar(0) bar(0) # try: with nogil: bar(0) finally: pass # try: with nogil: bar(0) with nogil: bar(0) finally: pass # try: with nogil: bar(0) with nogil: bar(1) except ValueError: with nogil: bar(0) finally: with nogil: bar(0) pass # try: with nogil: bar(0) bar(0) finally: pass # try: with nogil: bar(0) bar(1) except ValueError: with nogil: bar(0) finally: with nogil: bar(0) pass # try: with nogil: bar(0) try: with nogil: bar(1) except ValueError: with nogil: bar(1) finally: with nogil: bar(0) pass except ValueError: with nogil: bar(0) finally: with nogil: bar(0) pass # try: with nogil: bar(0) try: with nogil: bar(1) except ValueError: with nogil: bar(1) finally: with nogil: bar(1) pass except ValueError: with nogil: bar(0) finally: with nogil: bar(0) pass # def test_spam(): """ >>> test_spam() """ # spam(0) spam(0) with nogil: spam(0) spam(0) # try: with nogil: spam(0) finally: pass # try: with nogil: spam(0) with nogil: spam(0) finally: pass # try: with nogil: spam(0) with nogil: spam(1) except TypeError: with nogil: spam(0) finally: with nogil: spam(0) pass # try: with nogil: spam(0) spam(0) finally: pass # try: with nogil: spam(0) spam(1) except TypeError: with nogil: spam(0) finally: with nogil: spam(0) pass # try: with nogil: spam(0) try: with nogil: spam(1) except TypeError: with nogil: spam(1) finally: with nogil: spam(0) pass except TypeError: with nogil: spam(0) finally: with nogil: spam(0) pass # try: with nogil: spam(0) try: with nogil: spam(1) except TypeError: with nogil: spam(1) finally: with nogil: spam(1) pass except TypeError: with nogil: spam(0) finally: with nogil: spam(0) pass # Cython-0.23.4/tests/run/exceptionrefcount.pyx0000644000175600017570000000272112606202452022462 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> class SampleException(Exception): pass >>> def assert_refcount(rc1, rc2, func): ... # test ref-counts, but allow a bit of freedom ... assert rc2 <= rc1 + 4, "%s, before: %d, after %d" % ( ... func.__name__, rc1, rc2) >>> def run_test(repeat, test_func): ... initial_refcount = get_refcount(SampleException) ... for i in range(repeat): ... try: raise SampleException ... except: ... refcount1 = get_refcount(SampleException) ... test_func() ... refcount2 = get_refcount(SampleException) ... ... assert_refcount(refcount1, refcount2, test_func) ... assert_refcount(initial_refcount, refcount2, test_func) ... refcount3 = get_refcount(SampleException) ... assert_refcount(refcount1, refcount3, test_func) ... assert_refcount(initial_refcount, refcount3, test_func) >>> run_test(50, test_no_exception_else) >>> run_test(50, test_no_exception) >>> run_test(50, test_exception) >>> run_test(50, test_finally) """ from cpython.ref cimport PyObject def get_refcount(obj): return (obj).ob_refcnt def test_no_exception(): try: a = 1+1 except: pass def test_no_exception_else(): try: a = 1+1 except: pass else: b = 1+1 def test_exception(): try: raise TypeError except: pass def test_finally(): try: a = 1+1 finally: b = 1+1 Cython-0.23.4/tests/run/exceptionpropagation.pyx0000644000175600017570000000164412606202452023163 0ustar jenkinsjenkins00000000000000cdef int CHKERR(int ierr) except -1: if ierr==0: return 0 raise RuntimeError cdef int obj2int(object ob) except *: return ob def foo(a): """ >>> foo(0) >>> foo(1) Traceback (most recent call last): RuntimeError """ cdef int i = obj2int(a) CHKERR(i) cdef int* except_expr(bint fire) except -1: if fire: raise RuntimeError def test_except_expr(bint fire): """ >>> test_except_expr(False) >>> test_except_expr(True) Traceback (most recent call last): ... RuntimeError """ except_expr(fire) cdef double except_big_result(bint fire) except 100000000000000000000000000000000: if fire: raise RuntimeError def test_except_big_result(bint fire): """ >>> test_except_big_result(False) >>> test_except_big_result(True) Traceback (most recent call last): ... RuntimeError """ except_big_result(fire) Cython-0.23.4/tests/run/exarkun.pyx0000644000175600017570000000112112606202452020364 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> p = Point(1,2,3) >>> p.gettuple() (1.0, 2.0, 3.0) >>> q = p + Point(2,3,4) >>> q.gettuple() (3.0, 5.0, 7.0) >>> p.gettuple() (1.0, 2.0, 3.0) """ cdef class Point: cdef double x, y, z def __init__(self, double x, double y, double z): self.x = x self.y = y self.z = z # XXX: originally, this said "def __add__(self, other)" def __add__(Point self, Point other): return Point(self.x + other.x, self.y + other.y, self.z + other.z) def gettuple(self): return (self.x, self.y, self.z) Cython-0.23.4/tests/run/eval.pyx0000644000175600017570000000070112606202452017641 0ustar jenkinsjenkins00000000000000# mode: run # tag: eval GLOBAL = 123 def eval_simple(local): """ >>> eval_simple(321) (123, 321) """ return eval('GLOBAL, local') def eval_class_scope(): """ >>> eval_class_scope().c 3 """ class TestClassScope: a = 1 b = 2 c = eval('a + b') return TestClassScope def eval_locals(a, b): """ >>> eval_locals(1, 2) (1, 2) """ return eval('a, b', {}, locals()) Cython-0.23.4/tests/run/enumerate_T316.pyx0000644000175600017570000001116412606202452021421 0ustar jenkinsjenkins00000000000000# ticket: 316 cimport cython @cython.test_fail_if_path_exists("//SimpleCallNode//NameNode[@name = 'enumerate']") def go_py_enumerate(): """ >>> go_py_enumerate() 0 1 1 2 2 3 3 4 """ for i,k in enumerate(range(1,5)): print i, k @cython.test_fail_if_path_exists("//SimpleCallNode//NameNode[@name = 'enumerate']") def py_enumerate_list_index_target(): """ >>> py_enumerate_list_index_target() [0] 1 [1] 2 [2] 3 [3] 4 """ target = [None] for target[0],k in enumerate(range(1,5)): print target, k @cython.test_fail_if_path_exists("//SimpleCallNode//NameNode[@name = 'enumerate']") def go_py_enumerate_start(): """ >>> go_py_enumerate_start() 5 1 6 2 7 3 8 4 """ for i,k in enumerate(range(1,5), 5): print i, k @cython.test_fail_if_path_exists("//SimpleCallNode//NameNode[@name = 'enumerate']") def go_c_enumerate(): """ >>> go_c_enumerate() 0 1 1 2 2 3 3 4 """ cdef int i,k for i,k in enumerate(range(1,5)): print i, k @cython.test_fail_if_path_exists("//SimpleCallNode//NameNode[@name = 'enumerate']") def c_enumerate_carray_target(): """ >>> c_enumerate_carray_target() 0 1 1 2 2 3 3 4 """ cdef int k cdef int[1] i for i[0],k in enumerate(range(1,5)): print i[0], k @cython.test_fail_if_path_exists("//SimpleCallNode//NameNode[@name = 'enumerate']") def go_c_enumerate_step(): """ >>> go_c_enumerate_step() 0 1 1 3 2 5 """ cdef int i,k for i,k in enumerate(range(1,7,2)): print i, k @cython.test_fail_if_path_exists("//SimpleCallNode//NameNode[@name = 'enumerate']") def py_enumerate_dict(dict d): """ >>> py_enumerate_dict({}) :: 55 99 >>> py_enumerate_dict(dict(a=1, b=2, c=3)) 0 True 1 True 2 True :: 2 True """ cdef int i = 55 k = 99 keys = list(d.keys()) for i,k in enumerate(d): k = keys[i] == k print i, k print u"::", i, k @cython.test_fail_if_path_exists("//SimpleCallNode") def py_enumerate_break(*t): """ >>> py_enumerate_break(1,2,3,4) 0 1 :: 0 1 """ i,k = 55,99 for i,k in enumerate(t): print i, k break print u"::", i, k @cython.test_fail_if_path_exists("//SimpleCallNode") def py_enumerate_return(*t): """ >>> py_enumerate_return() :: 55 99 >>> py_enumerate_return(1,2,3,4) 0 1 """ i,k = 55,99 for i,k in enumerate(t): print i, k return print u"::", i, k @cython.test_fail_if_path_exists("//SimpleCallNode") def py_enumerate_continue(*t): """ >>> py_enumerate_continue(1,2,3,4) 0 1 1 2 2 3 3 4 :: 3 4 """ i,k = 55,99 for i,k in enumerate(t): print i, k continue print u"::", i, k @cython.test_fail_if_path_exists("//SimpleCallNode//NameNode[@name = 'enumerate']") def empty_c_enumerate(): """ >>> empty_c_enumerate() (55, 99) """ cdef int i = 55, k = 99 for i,k in enumerate(range(0)): print i, k return i, k # not currently optimised def single_target_enumerate(): """ >>> single_target_enumerate() 0 1 1 2 2 3 3 4 """ for t in enumerate(range(1,5)): print t[0], t[1] @cython.test_fail_if_path_exists("//SimpleCallNode//NameNode[@name = 'enumerate']") def multi_enumerate(): """ >>> multi_enumerate() 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 4 """ for a,(b,(c,d)) in enumerate(enumerate(enumerate(range(1,5)))): print a,b,c,d @cython.test_fail_if_path_exists("//SimpleCallNode//NameNode[@name = 'enumerate']") def multi_enumerate_start(): """ >>> multi_enumerate_start() 0 2 0 1 1 3 1 2 2 4 2 3 3 5 3 4 """ for a,(b,(c,d)) in enumerate(enumerate(enumerate(range(1,5)), 2)): print a,b,c,d @cython.test_fail_if_path_exists("//SimpleCallNode") def multi_c_enumerate(): """ >>> multi_c_enumerate() 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 4 """ cdef int a,b,c,d for a,(b,(c,d)) in enumerate(enumerate(enumerate(range(1,5)))): print a,b,c,d @cython.test_fail_if_path_exists("//SimpleCallNode") def convert_target_enumerate(L): """ >>> convert_target_enumerate([2,3,5]) 0 2 1 3 2 5 """ cdef int a,b for a, b in enumerate(L): print a,b @cython.test_fail_if_path_exists("//SimpleCallNode") def convert_target_enumerate_start(L, int n): """ >>> convert_target_enumerate_start([2,3,5], 3) 3 2 4 3 5 5 """ cdef int a,b for a, b in enumerate(L, n): print a,b Cython-0.23.4/tests/run/enumboolctx.pyx0000644000175600017570000000124612606202452021256 0ustar jenkinsjenkins00000000000000cdef public enum Truth: FALSE=0 TRUE=1 def enum_boolctx(Truth arg): """ >>> enum_boolctx(FALSE) False >>> enum_boolctx(TRUE) True """ if arg: return True else: return False cdef extern from *: enum: FALSE_VALUE "(0)" enum: TRUE_VALUE "(1)" def extern_enum_false(): """ >>> extern_enum_false() """ if FALSE_VALUE: raise ValueError def extern_enum_true(): """ >>> extern_enum_true() """ if not TRUE_VALUE: raise ValueError def extern_enum_false_true(): """ >>> extern_enum_false_true() """ if not TRUE_VALUE or FALSE_VALUE: raise ValueError Cython-0.23.4/tests/run/empty_for_loop_T208.pyx0000644000175600017570000000044712606202452022473 0ustar jenkinsjenkins00000000000000# ticket: 208 def go_py_empty(): """ >>> go_py_empty() 20 """ i = 20 for i in range(4,0): print u"Spam!" return i def go_c_empty(): """ >>> go_c_empty() 20 """ cdef int i = 20 for i in range(4,0): print u"Spam!" return i Cython-0.23.4/tests/run/empty_declarators.pyx0000644000175600017570000000022512606202452022434 0ustar jenkinsjenkins00000000000000cpdef zed(short, long, complex, x): """ >>> zed(short=1, long=2, complex=3, x=4) (1, 2, 3, 4) """ return short, long, complex, x Cython-0.23.4/tests/run/empty_builtin_constructors.pyx0000644000175600017570000000245112606202452024432 0ustar jenkinsjenkins00000000000000 cimport cython import sys IS_PY3 = sys.version_info[0] >= 3 def _bool(): """ >>> _bool() == bool() True """ return bool() def _int(): """ >>> _int() == int() True """ return int() def _long(): """ >>> IS_PY3 or _long() == long() True """ return long() def _float(): """ >>> _float() == float() True """ return float() def _complex(): """ >>> _complex() == complex() True """ return complex() def _bytes(): """ >>> IS_PY3 and _bytes() == bytes() or _bytes() == str() True """ return bytes() def _str(): """ >>> _str() == str() True """ return str() def _unicode(): """ >>> IS_PY3 and _unicode() == str() or _unicode() == unicode() True """ return unicode() def _tuple(): """ >>> _tuple() == tuple() True """ return tuple() def _list(): """ >>> _list() == list() True """ return list() def _dict(): """ >>> _dict() == dict() True """ return dict() py_set = cython.set def _set(): """ >>> _set() == py_set() True """ return set() py_frozenset = cython.frozenset def _frozenset(): """ >>> _frozenset() == py_frozenset() True """ return frozenset() Cython-0.23.4/tests/run/embedsignatures.pyx0000644000175600017570000001675112606202452022107 0ustar jenkinsjenkins00000000000000#cython: embedsignature=True import sys if sys.version_info >= (3, 4): def funcdoc(f): if not f.__text_signature__: return f.__doc__ doc = '%s%s' % (f.__name__, f.__text_signature__) if f.__doc__: if '\n' in f.__doc__: # preceding line endings get stripped doc = '%s\n\n%s' % (doc, f.__doc__) else: doc = '%s\n%s' % (doc, f.__doc__) return doc else: def funcdoc(f): return f.__doc__ # note the r, we use \n below __doc__ = ur""" >>> print (Ext.__doc__) Ext(a, b, c=None) >>> print (Ext.attr0.__doc__) attr0: 'int' attr0 docstring >>> print (Ext.attr1.__doc__) attr1: object attr1 docstring >>> print (Ext.attr2.__doc__) attr2: list >>> print (Ext.attr3.__doc__) attr3: embedsignatures.Ext >>> print (Ext.prop0.__doc__) prop0 docstring >>> print (Ext.prop1.__doc__) None >>> print (Ext.attr4.__doc__) attr4 docstring >>> print (Ext.attr5.__doc__) attr5: 'int' attr5 docstring >>> print (Ext.a.__doc__) Ext.a(self) >>> print (Ext.b.__doc__) Ext.b(self, a, b, c) >>> print (Ext.c.__doc__) Ext.c(self, a, b, c=1) >>> print (Ext.d.__doc__) Ext.d(self, a, b, *, c=88) >>> print (Ext.e.__doc__) Ext.e(self, a, b, c=88, **kwds) >>> print (Ext.f.__doc__) Ext.f(self, a, b, *, c, d=42) >>> print (Ext.g.__doc__) Ext.g(self, a, b, *, c, d=42, e=17, f, **kwds) >>> print (Ext.h.__doc__) Ext.h(self, a, b, *args, c, d=42, e=17, f, **kwds) >>> print (Ext.k.__doc__) Ext.k(self, a, b, c=1, *args, d=42, e=17, f, **kwds) >>> print (Ext.l.__doc__) Ext.l(self, a, b, c=1, *args, d=42, e=17, f, **kwds) Existing string >>> print (Ext.m.__doc__) Ext.m(self, a=u'spam') >>> print (Ext.get_int.__doc__) Ext.get_int(self) -> int >>> print (Ext.get_float.__doc__) Ext.get_float(self) -> float >>> print (Ext.get_str.__doc__) Ext.get_str(self) -> str Existing string >>> print (Ext.clone.__doc__) Ext.clone(self) -> Ext >>> print (funcdoc(foo)) foo() >>> funcdoc(with_doc_1) 'with_doc_1(a, b, c)\nExisting string' >>> funcdoc(with_doc_2) 'with_doc_2(a, b, c)\n\n Existing string\n ' >>> funcdoc(with_doc_3) 'with_doc_3(a, b, c)\nExisting string' >>> funcdoc(with_doc_4) 'with_doc_4(int a, str b, list c) -> str\n\n Existing string\n ' >>> funcdoc(f_sd) "f_sd(str s='spam')" >>> funcdoc(cf_sd) "cf_sd(str s='spam') -> str" >>> funcdoc(types) 'types(Ext a, int b, unsigned short c, float d, e)' >>> print(funcdoc(f_c)) f_c(char c) -> char >>> print(funcdoc(f_uc)) f_uc(unsigned char c) -> unsigned char >>> print(funcdoc(f_sc)) f_sc(signed char c) -> signed char >>> print(funcdoc(f_s)) f_s(short s) -> short >>> print(funcdoc(f_us)) f_us(unsigned short s) -> unsigned short >>> print(funcdoc(f_i)) f_i(int i) -> int >>> print(funcdoc(f_ui)) f_ui(unsigned int i) -> unsigned int >>> print(funcdoc(f_bint)) f_bint(bool i) -> bool >>> print(funcdoc(f_l)) f_l(long l) -> long >>> print(funcdoc(f_ul)) f_ul(unsigned long l) -> unsigned long >>> print(funcdoc(f_L)) f_L(long long L) -> long long >>> print(funcdoc(f_uL)) f_uL(unsigned long long L) -> unsigned long long >>> print(funcdoc(f_f)) f_f(float f) -> float >>> print(funcdoc(f_d)) f_d(double d) -> double >>> print(funcdoc(f_D)) f_D(long double D) -> long double >>> print(funcdoc(f_my_i)) f_my_i(MyInt i) -> MyInt >>> print(funcdoc(f_my_f)) f_my_f(MyFloat f) -> MyFloat >>> print(funcdoc(f_defexpr1)) f_defexpr1(int x=FLAG1, int y=FLAG2) >>> print(funcdoc(f_defexpr2)) f_defexpr2(int x=FLAG1 | FLAG2, y=FLAG1 & FLAG2) >>> print(funcdoc(f_defexpr3)) f_defexpr3(int x=Ext.CONST1, f=__builtins__.abs) >>> print(funcdoc(f_defexpr4)) f_defexpr4(int x=(Ext.CONST1 + FLAG1) * Ext.CONST2) >>> print(funcdoc(f_defexpr5)) f_defexpr5(int x=4) >>> print(funcdoc(f_charptr_null)) f_charptr_null(char *s=NULL) -> char * """ cdef class Ext: cdef public int attr0 """attr0 docstring""" cdef public attr1 """attr1 docstring""" cdef public list attr2 cdef public Ext attr3 """NOT attr3 docstring""" cdef int attr4 cdef public int \ attr5 """attr5 docstring""" CONST1, CONST2 = 1, 2 property prop0: """prop0 docstring""" def __get__(self): return self.attr0 property prop1: def __get__(self): return self.attr1 property attr4: """attr4 docstring""" def __get__(self): return self.attr4 def __init__(self, a, b, c=None): pass def a(self): pass def b(self, a, b, c): pass def c(self, a, b, c=1): pass def d(self, a, b, *, c = 88): pass def e(self, a, b, c = 88, **kwds): pass def f(self, a, b, *, c, d = 42): pass def g(self, a, b, *, c, d = 42, e = 17, f, **kwds): pass def h(self, a, b, *args, c, d = 42, e = 17, f, **kwds): pass def k(self, a, b, c=1, *args, d = 42, e = 17, f, **kwds): pass def l(self, a, b, c=1, *args, d = 42, e = 17, f, **kwds): """Existing string""" pass def m(self, a=u'spam'): pass cpdef int get_int(self): return 0 cpdef float get_float(self): return 0.0 cpdef str get_str(self): """Existing string""" return "string" cpdef Ext clone(self): return Ext(1,2) def foo(): pass def types(Ext a, int b, unsigned short c, float d, e): pass def with_doc_1(a, b, c): """Existing string""" pass def with_doc_2(a, b, c): """ Existing string """ pass cpdef with_doc_3(a, b, c): """Existing string""" pass cpdef str with_doc_4(int a, str b, list c): """ Existing string """ return b def f_sd(str s='spam'): return s cpdef str cf_sd(str s='spam'): return s cpdef char f_c(char c): return c cpdef unsigned char f_uc(unsigned char c): return c cpdef signed char f_sc(signed char c): return c cpdef short f_s(short s): return s cpdef unsigned short f_us(unsigned short s): return s cpdef int f_i(int i): return i cpdef unsigned int f_ui(unsigned int i): return i cpdef bint f_bint(bint i): return i cpdef long f_l(long l): return l cpdef unsigned long f_ul(unsigned long l): return l cpdef long long f_L(long long L): return L cpdef unsigned long long f_uL(unsigned long long L): return L cpdef float f_f(float f): return f cpdef double f_d(double d): return d cpdef long double f_D(long double D): return D ctypedef int MyInt cpdef MyInt f_my_i(MyInt i): return i ctypedef float MyFloat cpdef MyFloat f_my_f(MyFloat f): return f cdef enum: FLAG1 FLAG2 cpdef f_defexpr1(int x = FLAG1, int y = FLAG2): pass cpdef f_defexpr2(int x = FLAG1 | FLAG2, y = FLAG1 & FLAG2): pass cpdef f_defexpr3(int x = Ext.CONST1, f = __builtins__.abs): pass cpdef f_defexpr4(int x = (Ext.CONST1 + FLAG1) * Ext.CONST2): pass cpdef f_defexpr5(int x = 2+2): pass cpdef (char*) f_charptr_null(char* s=NULL): return s or b'abc' # no signatures for lambda functions lambda_foo = lambda x: 10 lambda_bar = lambda x: 20 Cython-0.23.4/tests/run/ellipsis_T488.pyx0000644000175600017570000000054112606202452021267 0ustar jenkinsjenkins00000000000000# ticket: 488 """ >>> test() """ def test(): x = ... assert x is Ellipsis d = {} d[...] = 1 assert d[...] == 1 del d[...] assert ... not in d d[..., ...] = 1 assert d[..., ...] == 1 assert d[..., Ellipsis] == 1 assert (Ellipsis, Ellipsis) in d del d[..., ...] assert (Ellipsis, Ellipsis) not in d Cython-0.23.4/tests/run/dynamic_args.pyx0000644000175600017570000000074712606202452021364 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 674 cdef class Foo: cdef str name def __init__(self, name): self.name = name def __repr__(self): return '<%s>' % self.name def test_exttype_args(a, b, c): """ >>> f1 = test_exttype_args([1, 2, 3], 123, Foo('Foo')) >>> f2 = test_exttype_args([0], 0, Foo('Bar')) >>> f1() ([1, 2, 3], 123, ) >>> f2() ([0], 0, ) """ def inner(a=a, int b=b, Foo c=c): return a, b, c return inner Cython-0.23.4/tests/run/duplicate_keyword_in_call.py0000644000175600017570000000116112606202452023722 0ustar jenkinsjenkins00000000000000# mode: run # tag: kwargs, call # ticket: 717 def f(**kwargs): return sorted(kwargs.items()) def test_call(kwargs): """ >>> kwargs = {'b' : 2} >>> f(a=1, **kwargs) [('a', 1), ('b', 2)] >>> test_call(kwargs) [('a', 1), ('b', 2)] >>> kwargs = {'a' : 2} >>> f(a=1, **kwargs) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...got multiple values for keyword argument 'a' >>> test_call(kwargs) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...got multiple values for keyword argument 'a' """ return f(a=1, **kwargs) Cython-0.23.4/tests/run/double_dealloc_T796.pyx0000644000175600017570000000302412606202452022401 0ustar jenkinsjenkins00000000000000""" Initial cleanup and 'calibration': >>> _ = gc.collect() >>> old_unreachable = gc.collect() Test: >>> x = SimpleGarbage() SimpleGarbage(1) __cinit__ >>> del x SimpleGarbage(1) __dealloc__ Collector.__dealloc__ Make sure nothing changed in the environment: >>> new_unreachable = get_new_unreachable() >>> new_unreachable == old_unreachable or (old_unreachable, new_unreachable) True """ import gc cdef Py_ssize_t new_unreachable = 0 def get_new_unreachable(): return new_unreachable cdef int counter = 0 cdef int next_counter(): global counter counter += 1 return counter cdef class Collector: # Indirectly trigger garbage collection in SimpleGarbage deallocation. # The __dealloc__ method of SimpleGarbage won't trigger the bug as the # refcount is artificially inflated for the duration of that function. def __dealloc__(self): print "Collector.__dealloc__" global new_unreachable new_unreachable = gc.collect() cdef class SimpleGarbage: cdef Collector c # to participate in garbage collection cdef int index cdef bint deallocated def __cinit__(self): self.index = next_counter() self.c = Collector() print self, "__cinit__" def __dealloc__(self): print self, "__dealloc__" if self.deallocated: print "Double dealloc!" self.deallocated = True gc.collect() def __str__(self): return "SimpleGarbage(%s)" % self.index def __repr__(self): return "SimpleGarbage(%s)" % self.index Cython-0.23.4/tests/run/division_T384.pyx0000644000175600017570000000045112606202452021262 0ustar jenkinsjenkins00000000000000# ticket: 384 """ >>> test(3) (3+1j) """ cimport cython ctypedef Py_ssize_t index_t ctypedef double complex mycomplex ctypedef struct MyStruct: mycomplex a, b @cython.cdivision(False) def test(index_t x): cdef index_t y = x // 2 cdef MyStruct s s.a = x + y*1j return s.a Cython-0.23.4/tests/run/directive_locals_in_pxd.py0000644000175600017570000000106412606202452023401 0ustar jenkinsjenkins00000000000000import cython def foo(egg): if not cython.compiled: egg = float(egg) return egg def foo_defval(egg=1): if not cython.compiled: egg = float(egg) return egg**2 def cpfoo(egg=False): if not cython.compiled: egg = bool(egg) v = int(not egg) else: v = not egg return egg, v def test_pxd_locals(): """ >>> v1, v2, v3 = test_pxd_locals() >>> isinstance(v1, float) True >>> isinstance(v2, float) True >>> v3 (True, 0) """ return foo(1), foo_defval(), cpfoo(1) Cython-0.23.4/tests/run/directive_locals_in_pxd.pxd0000644000175600017570000000026512606202452023546 0ustar jenkinsjenkins00000000000000cimport cython @cython.locals(egg=double) cdef foo(egg) @cython.locals(egg=cython.double) cdef foo_defval(egg=*) @cython.locals(egg=cython.bint, v=cython.int) cpdef cpfoo(egg=*) Cython-0.23.4/tests/run/dietachmayer1.pyx0000644000175600017570000000016112606202452021432 0ustar jenkinsjenkins00000000000000def test(): """ >>> test() 1.0 """ cdef float[10][10] v v[1][2] = 1.0 return v[1][2] Cython-0.23.4/tests/run/dictintindex.pyx0000644000175600017570000001063212606202452021404 0ustar jenkinsjenkins00000000000000def test_get_char_neg(): """ >>> test_get_char_neg() 0 """ cdef char key = -1 if -1 < 0: d = {-1:0} else: d = {255:0} return d[key] def test_get_char_zero(): """ >>> test_get_char_zero() 1 """ cdef char key = 0 d = {0:1} return d[key] def test_get_char_pos(): """ >>> test_get_char_pos() 2 """ cdef char key = 1 d = {1:2} return d[key] def test_get_uchar_zero(): """ >>> test_get_uchar_zero() 1 """ cdef unsigned char key = 0 d = {0:1} return d[key] def test_get_uchar_pos(): """ >>> test_get_uchar_pos() 2 """ cdef unsigned char key = 1 d = {1:2} return d[key] def test_get_int_neg(): """ >>> test_get_int_neg() 0 """ cdef int key = -1 d = {-1:0} return d[key] def test_get_int_zero(): """ >>> test_get_int_zero() 1 """ cdef int key = 0 d = {0:1} return d[key] def test_get_int_pos(): """ >>> test_get_int_pos() 2 """ cdef int key = 1 d = {1:2} return d[key] def test_get_uint_zero(): """ >>> test_get_uint_zero() 1 """ cdef unsigned int key = 0 d = {0:1} return d[key] def test_get_uint_pos(): """ >>> test_get_uint_pos() 2 """ cdef unsigned int key = 1 d = {1:2} return d[key] def test_get_longlong_neg(): """ >>> test_get_longlong_neg() 0 """ cdef long long key = -1 d = {-1:0} return d[key] def test_get_longlong_zero(): """ >>> test_get_longlong_zero() 1 """ cdef long long key = 0 d = {0:1} return d[key] def test_get_longlong_pos(): """ >>> test_get_longlong_pos() 2 """ cdef long long key = 1 d = {1:2} return d[key] def test_get_longlong_big(): """ >>> test_get_longlong_big() 3 """ cdef unsigned int shift = sizeof(long)+2 cdef long long big = 1 cdef long long key = big<>> test_get_ulonglong_zero() 1 """ cdef unsigned long long key = 0 d = {0:1} return d[key] def test_get_ulonglong_pos(): """ >>> test_get_ulonglong_pos() 2 """ cdef unsigned long long key = 1 d = {1:2} return d[key] def test_get_ulonglong_big(): """ >>> test_get_ulonglong_big() 3 """ cdef unsigned int shift = sizeof(long)+2 cdef unsigned long long big = 1 cdef unsigned long long key = big<>> test_del_char() Traceback (most recent call last): KeyError: 0 """ cdef char key = 0 d = {0:1} del d[key] return d[key] def test_del_uchar(): """ >>> test_del_uchar() Traceback (most recent call last): KeyError: 0 """ cdef unsigned char key = 0 d = {0:1} del d[key] return d[key] def test_del_int(): """ >>> test_del_int() Traceback (most recent call last): KeyError: 0 """ cdef int key = 0 d = {0:1} del d[key] return d[key] def test_del_uint(): """ >>> test_del_uint() #doctest: +ELLIPSIS Traceback (most recent call last): KeyError: 0... """ cdef unsigned int key = 0 d = {0:1} del d[key] return d[key] def test_del_longlong(): """ >>> test_del_longlong() #doctest: +ELLIPSIS Traceback (most recent call last): KeyError: 0... """ cdef long long key = 0 d = {0:1} del d[key] return d[key] def test_del_ulonglong(): """ >>> test_del_ulonglong() #doctest: +ELLIPSIS Traceback (most recent call last): KeyError: 0... """ cdef unsigned long long key = 0 d = {0:1} del d[key] return d[key] def test_del_longlong_big(): """ >>> test_del_longlong_big() #doctest: +ELLIPSIS Traceback (most recent call last): KeyError: ... """ cdef int shift = sizeof(long)+2 cdef long long big = 1 cdef long long key = big<>> test_del_ulonglong_big() #doctest: +ELLIPSIS Traceback (most recent call last): KeyError: ... """ cdef unsigned int shift = sizeof(long)+2 cdef unsigned long long big = 1 cdef unsigned long long key = big<>> sorted(dictcomp().items()) [(2, 0), (4, 4), (6, 8)] >>> sorted(dictcomp().items()) [(2, 0), (4, 4), (6, 8)] """ x = 'abc' result = { x+2:x*2 for x in range(5) if x % 2 == 0 } assert x == 'abc' # do not leak! return result @cython.test_assert_path_exists( "//InlinedGeneratorExpressionNode", "//DictComprehensionAppendNode") def genexpr(): """ >>> type(genexpr()) is dict True >>> type(genexpr()) is dict True """ x = 'abc' result = dict( (x+2,x*2) for x in range(5) if x % 2 == 0 ) assert x == 'abc' return result cdef class A: def __repr__(self): return u"A" def __richcmp__(one, other, int op): return one is other def __hash__(self): return id(self) % 65536 def typed_dictcomp(): """ >>> list(typed_dictcomp().items()) [(A, 1), (A, 1), (A, 1)] """ cdef A obj return {obj:1 for obj in [A(), A(), A()]} def iterdict_dictcomp(): """ >>> sorted(iterdict_dictcomp().items()) [(1, 'a'), (2, 'b'), (3, 'c')] """ cdef dict d = dict(a=1,b=2,c=3) return {d[key]:key for key in d} def sorted(it): l = list(it) l.sort() return l Cython-0.23.4/tests/run/dict_values_in_expression.pyx0000644000175600017570000000060612606202452024165 0ustar jenkinsjenkins00000000000000 def values_in_expression(**kwargs): """ >>> sorted(values_in_expression(a=3, b=4)) [1, 2, 3, 4] """ return [ arg for arg in [1,2] + list(kwargs.values()) ] cdef dict make_dict(d): return dict(d) def values_of_expression(**kwargs): """ >>> sorted(values_of_expression(a=3, b=4)) [3, 4] """ return [ arg for arg in make_dict(kwargs).values() ] Cython-0.23.4/tests/run/dict_setdefault.py0000644000175600017570000000601112606202452021665 0ustar jenkinsjenkins00000000000000 import cython class Unhashable(object): def __hash__(self): raise TypeError('I am not hashable') class Hashable(object): def __hash__(self): return 1 def __eq__(self, other): return isinstance(other, Hashable) class CountedHashable(object): def __init__(self): self.hash_count = 0 self.eq_count = 0 def __hash__(self): self.hash_count += 1 return 42 def __eq__(self, other): self.eq_count += 1 return id(self) == id(other) @cython.test_fail_if_path_exists('//AttributeNode') @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.locals(d=dict) def setdefault1(d, key): """ >>> d = {} >>> setdefault1(d, 1) >>> len(d) 1 >>> setdefault1(d, 1) >>> len(d) 1 >>> d[1] >>> setdefault1(d, Unhashable()) Traceback (most recent call last): TypeError: I am not hashable >>> len(d) 1 >>> h1 = setdefault1(d, Hashable()) >>> len(d) 2 >>> h2 = setdefault1(d, Hashable()) >>> len(d) 2 >>> d[Hashable()] # CPython's behaviour depends on version and py_debug setting, so just compare to it >>> py_hashed1 = CountedHashable() >>> y = {py_hashed1: 5} >>> py_hashed2 = CountedHashable() >>> y.setdefault(py_hashed2) >>> cy_hashed1 = CountedHashable() >>> y = {cy_hashed1: 5} >>> cy_hashed2 = CountedHashable() >>> setdefault1(y, cy_hashed2) >>> py_hashed1.hash_count - cy_hashed1.hash_count 0 >>> py_hashed2.hash_count - cy_hashed2.hash_count 0 >>> (py_hashed1.eq_count + py_hashed2.eq_count) - (cy_hashed1.eq_count + cy_hashed2.eq_count) 0 """ return d.setdefault(key) @cython.test_fail_if_path_exists('//AttributeNode') @cython.test_assert_path_exists('//PythonCapiCallNode') @cython.locals(d=dict) def setdefault2(d, key, value): """ >>> d = {} >>> setdefault2(d, 1, 2) 2 >>> len(d) 1 >>> setdefault2(d, 1, 2) 2 >>> len(d) 1 >>> l = setdefault2(d, 2, []) >>> len(d) 2 >>> l.append(1) >>> setdefault2(d, 2, []) [1] >>> len(d) 2 >>> setdefault2(d, Unhashable(), 1) Traceback (most recent call last): TypeError: I am not hashable >>> h1 = setdefault2(d, Hashable(), 55) >>> len(d) 3 >>> h2 = setdefault2(d, Hashable(), 66) >>> len(d) 3 >>> d[Hashable()] 55 # CPython's behaviour depends on version and py_debug setting, so just compare to it >>> py_hashed1 = CountedHashable() >>> y = {py_hashed1: 5} >>> py_hashed2 = CountedHashable() >>> y.setdefault(py_hashed2, []) [] >>> cy_hashed1 = CountedHashable() >>> y = {cy_hashed1: 5} >>> cy_hashed2 = CountedHashable() >>> setdefault2(y, cy_hashed2, []) [] >>> py_hashed1.hash_count - cy_hashed1.hash_count 0 >>> py_hashed2.hash_count - cy_hashed2.hash_count 0 >>> (py_hashed1.eq_count + py_hashed2.eq_count) - (cy_hashed1.eq_count + cy_hashed2.eq_count) 0 """ return d.setdefault(key, value) Cython-0.23.4/tests/run/dict_iter_unpack.pyx0000644000175600017570000000070112606202452022221 0ustar jenkinsjenkins00000000000000# mode: run # tag: dictiter def iteritems_unpack(dict the_dict): """ >>> d = {(1,2): (3,4), (5,6): (7,8)} >>> iteritems_unpack(d) [(1, 2, 3, 4), (5, 6, 7, 8)] """ return sorted([ (a,b,c,d) for (a,b), (c,d) in the_dict.iteritems() ]) def itervalues_unpack(dict the_dict): """ >>> d = {1: (3,4), 2: (7,8)} >>> itervalues_unpack(d) [(3, 4), (7, 8)] """ return [(a,b) for a,b in the_dict.itervalues() ] Cython-0.23.4/tests/run/dict_getitem.pyx0000644000175600017570000000341312606202452021356 0ustar jenkinsjenkins00000000000000# mode: run # tag: dict, getitem cimport cython def test(dict d, index): """ >>> d = { 1: 10 } >>> test(d, 1) 10 >>> test(d, 2) Traceback (most recent call last): KeyError: 2 >>> test(d, (1,2)) Traceback (most recent call last): KeyError: (1, 2) >>> import sys >>> try: d[(1,)] ... except KeyError: ... args = sys.exc_info()[1].args ... if sys.version_info >= (2,5): print(args) ... else: print((args,)) # fake it for older CPython versions ((1,),) >>> import sys >>> try: test(d, (1,)) ... except KeyError: ... args = sys.exc_info()[1].args ... if sys.version_info >= (2,5): print(args) ... else: print((args,)) # fake it for older CPython versions ((1,),) >>> class Unhashable: ... def __hash__(self): ... raise ValueError >>> test(d, Unhashable()) Traceback (most recent call last): ValueError >>> test(None, 1) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...object... """ return d[index] def getitem_tuple(dict d, index): """ >>> d = {1: 1, (1,): 2} >>> getitem_tuple(d, 1) (1, 2) """ return d[index], d[index,] def getitem_in_condition(dict d, key, expected_result): """ >>> d = dict(a=1, b=2) >>> getitem_in_condition(d, 'a', 1) True """ return d[key] is expected_result or d[key] == expected_result @cython.test_fail_if_path_exists('//NoneCheckNode') def getitem_not_none(dict d not None, key): """ >>> d = { 1: 10 } >>> test(d, 1) 10 >>> test(d, 2) Traceback (most recent call last): KeyError: 2 >>> test(d, (1,2)) Traceback (most recent call last): KeyError: (1, 2) """ return d[key] Cython-0.23.4/tests/run/dict_get.pyx0000644000175600017570000000360612606202452020503 0ustar jenkinsjenkins00000000000000 cimport cython @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def get(dict d, key): """ >>> d = { 1: 10 } >>> d.get(1) 10 >>> get(d, 1) 10 >>> d.get(2) is None True >>> get(d, 2) is None True >>> d.get((1,2)) is None True >>> get(d, (1,2)) is None True >>> class Unhashable: ... def __hash__(self): ... raise ValueError >>> d.get(Unhashable()) Traceback (most recent call last): ValueError >>> get(d, Unhashable()) Traceback (most recent call last): ValueError >>> None.get(1) Traceback (most recent call last): ... AttributeError: 'NoneType' object has no attribute 'get' >>> get(None, 1) Traceback (most recent call last): ... AttributeError: 'NoneType' object has no attribute 'get' """ return d.get(key) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def get_default(dict d, key, default): """ >>> d = { 1: 10 } >>> d.get(1, 2) 10 >>> get_default(d, 1, 2) 10 >>> d.get(2, 2) 2 >>> get_default(d, 2, 2) 2 >>> d.get((1,2), 2) 2 >>> get_default(d, (1,2), 2) 2 >>> class Unhashable: ... def __hash__(self): ... raise ValueError >>> d.get(Unhashable(), 2) Traceback (most recent call last): ValueError >>> get_default(d, Unhashable(), 2) Traceback (most recent call last): ValueError """ return d.get(key, default) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def get_in_condition(dict d, key, expected_result): """ >>> d = dict(a=1, b=2) >>> get_in_condition(d, 'a', 1) True """ return d.get(key) is expected_result or d.get(key) == expected_result Cython-0.23.4/tests/run/dict.pyx0000644000175600017570000000505312606202452017642 0ustar jenkinsjenkins00000000000000import sys IS_PY35 = sys.version_info >= (3, 5) def empty(): """ >>> empty() {} """ d = {} return d def keyvalue(key, value): """ >>> keyvalue(1, 2) {1: 2} """ d = {key:value} return d def keyvalues(key1, value1, key2, value2): """ >>> sorted(keyvalues(1, 2, 3, 4).items()) [(1, 2), (3, 4)] """ d = {key1:value1, key2:value2} return d def keyvalues2(key1, value1, key2, value2): """ >>> sorted(keyvalues2(1, 2, 3, 4).items()) [(1, 2), (3, 4)] """ d = {key1:value1, key2:value2,} return d def constant(): """ >>> len(constant()) 2 >>> print(constant()['parrot']) resting >>> print(constant()['answer']) 42 """ d = {u"parrot":u"resting", u"answer":42} return d def dict_call(): """ >>> print(dict_call()['parrot']) resting >>> print(dict_call()['answer']) 42 """ d = dict(parrot=u"resting", answer=42) return d def dict_call_dict(): """ >>> print(dict_call_dict()['parrot']) resting >>> print(dict_call_dict()['answer']) 42 """ d = dict(dict(parrot=u"resting", answer=42)) return d def dict_call_kwargs(): """ >>> print(dict_call_kwargs()['parrot1']) resting >>> print(dict_call_kwargs()['parrot2']) resting >>> print(dict_call_kwargs()['answer1']) 42 >>> print(dict_call_kwargs()['answer2']) 42 """ kwargs = dict(parrot1=u"resting", answer1=42) d = dict(parrot2=u"resting", answer2=42, **kwargs) return d def items_of_dict_call(): """ >>> items_of_dict_call() [('answer1', 42), ('answer2', 42), ('parrot1', 'resting'), ('parrot2', 'resting')] """ kwargs = dict(parrot1="resting", answer1=42) items = dict(kwargs.items(), parrot2="resting", answer2=42, **kwargs).items() return sorted(items) def item_creation_sideeffect(L, sideeffect, unhashable): """ >>> def sideeffect(x): ... L.append(x) ... return x >>> def unhashable(x): ... L.append(x) ... return [x] >>> L = [] >>> item_creation_sideeffect(L, sideeffect, unhashable) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...unhashable... >>> L [2, 4] >>> L = [] >>> {1:2, sideeffect(2): 3, 3: 4, unhashable(4): 5, sideeffect(5): 6} # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...unhashable... >>> L if IS_PY35 else (L + [5]) [2, 4, 5] """ return {1:2, sideeffect(2): 3, 3: 4, unhashable(4): 5, sideeffect(5): 6} Cython-0.23.4/tests/run/delslice.py0000644000175600017570000000405212606202452020311 0ustar jenkinsjenkins00000000000000# mode: run # tag: del, slicing def del_constant_start_stop(x): """ >>> l = [1,2,3,4] >>> del_constant_start_stop(l) [1, 2] >>> l = [1,2,3,4,5,6,7] >>> del_constant_start_stop(l) [1, 2, 7] """ del x[2:6] return x def del_start(x, start): """ >>> l = [1,2,3,4] >>> del_start(l, 2) [1, 2] >>> l = [1,2,3,4,5,6,7] >>> del_start(l, 20) [1, 2, 3, 4, 5, 6, 7] >>> del_start(l, 8) [1, 2, 3, 4, 5, 6, 7] >>> del_start(l, 4) [1, 2, 3, 4] >>> del_start(l, -2) [1, 2] >>> l [1, 2] >>> del_start(l, -2) [] >>> del_start(l, 2) [] >>> del_start(l, -2) [] >>> del_start(l, 20) [] >>> del_start([1,2,3,4], -20) [] >>> del_start([1,2,3,4], 0) [] """ del x[start:] return x def del_stop(x, stop): """ >>> l = [1,2,3,4] >>> del_stop(l, 2) [3, 4] >>> l = [1,2,3,4,5,6,7] >>> del_stop(l, -20) [1, 2, 3, 4, 5, 6, 7] >>> del_stop(l, -8) [1, 2, 3, 4, 5, 6, 7] >>> del_stop(l, -4) [4, 5, 6, 7] >>> del_stop(l, -2) [6, 7] >>> l [6, 7] >>> del_stop(l, -2) [6, 7] >>> del_stop(l, 2) [] >>> del_stop(l, -2) [] >>> del_stop(l, 20) [] >>> del_stop([1,2,3,4], -20) [1, 2, 3, 4] >>> del_stop([1,2,3,4], 0) [1, 2, 3, 4] """ del x[:stop] return x def del_start_stop(x, start, stop): """ >>> l = [1,2,3,4] >>> del_start_stop(l, 0, 2) [3, 4] >>> l [3, 4] >>> l = [1,2,3,4,5,6,7] >>> del_start_stop(l, -1, -20) [1, 2, 3, 4, 5, 6, 7] >>> del_start_stop(l, -20, -8) [1, 2, 3, 4, 5, 6, 7] >>> del_start_stop(l, -6, -4) [1, 4, 5, 6, 7] >>> del_start_stop(l, -20, -2) [6, 7] >>> l [6, 7] >>> del_start_stop(l, -2, 1) [7] >>> del_start_stop(l, -2, 3) [] >>> del_start_stop(l, 2, 4) [] >>> del_start_stop([1,2,3,4], 20, -20) [1, 2, 3, 4] >>> del_start_stop([1,2,3,4], 0, 0) [1, 2, 3, 4] """ del x[start:stop] return x Cython-0.23.4/tests/run/delete.pyx0000644000175600017570000000357212606202452020165 0ustar jenkinsjenkins00000000000000 cimport cython class A(object): """ >>> a = A() >>> a.f() [2, 1] >>> a.g() (False, True) """ def f(self): self.refs = [3,2,1] del self.refs[0] return self.refs def g(self): self.a = 3 del self.a return (hasattr(self, u"a"), hasattr(self, u"g")) def del_item(L, o): """ >>> del_item({1: 'a', 2: 'b'}, 1) {2: 'b'} >>> del_item(list(range(10)), 2) [0, 1, 3, 4, 5, 6, 7, 8, 9] """ del L[o] return L @cython.test_assert_path_exists('//DelStatNode//IndexNode//NoneCheckNode') def del_dict(dict D, o): """ >>> del_dict({1: 'a', 2: 'b'}, 1) {2: 'b'} """ del D[o] return D @cython.test_fail_if_path_exists('//NoneCheckNode') def del_dict_from_literal(o): """ >>> del_dict_from_literal(1) {2: 'b'} """ D = {1: 'a', 2: 'b'} del D[o] return D def del_list(list L, o): """ >>> del_list(list(range(5)), 3) [0, 1, 2, 4] """ del L[o] return L def del_int(L, int i): """ >>> del_int(list(range(5)), 3) [0, 1, 2, 4] >>> del_int({-1: 'neg', 1: 'pos'}, -1) {1: 'pos'} """ del L[i] return L def del_list_int(L, int i): """ >>> del_list_int(list(range(5)), 3) [0, 1, 2, 4] """ del L[i] return L def del_temp_slice(a): """ >>> class A(object): ... attr = [1,2,3] >>> a = A() >>> a.attr [1, 2, 3] >>> del_temp_slice(a) [] >>> a.attr [] >>> del_temp_slice(a) [] >>> a.attr [] """ while a.attr: del a.attr[:] return a.attr def del_local(a): """ >>> del_local(object()) """ del a assert 'a' not in locals() def del_seq(a, b, c): """ >>> del_seq(1, 2, 3) """ del a, (b, c) assert 'a' not in locals() assert 'b' not in locals() assert 'c' not in locals() Cython-0.23.4/tests/run/defnode_err_val.pyx0000644000175600017570000000047412606202452022037 0ustar jenkinsjenkins00000000000000# mode: run cdef class TestErrVal(object): def __cinit__(self, TestErrVal a): pass def test_errval(): """ >>> test_errval() Traceback (most recent call last): ... TypeError: Argument 'a' has incorrect type (expected defnode_err_val.TestErrVal, got int) """ TestErrVal(123) Cython-0.23.4/tests/run/default_args_T674.py0000644000175600017570000000052212606202452021707 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 674 def test_inner(a): """ >>> a = test_inner(1) >>> b = test_inner(2) >>> a() 1 >>> b() 2 """ def inner(b=a): return b return inner def test_lambda(n): """ >>> [f() for f in test_lambda(3)] [0, 1, 2] """ return [lambda v=i: v for i in range(n)] Cython-0.23.4/tests/run/decorators_py_T593.py0000644000175600017570000000264712606202452022136 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 593 # tag: property, decorator """ >>> am_i_buggy False """ def testme(func): try: am_i_buggy return True except NameError: return False @testme def am_i_buggy(): pass def called_deco(a,b,c): a.append( (1,b,c) ) def count(f): a.append( (2,b,c) ) return f return count L = [] @called_deco(L, 5, c=6) @called_deco(L, c=3, b=4) @called_deco(L, 1, 2) def wrapped_func(x): """ >>> L [(1, 5, 6), (1, 4, 3), (1, 1, 2), (2, 1, 2), (2, 4, 3), (2, 5, 6)] >>> wrapped_func(99) 99 >>> L [(1, 5, 6), (1, 4, 3), (1, 1, 2), (2, 1, 2), (2, 4, 3), (2, 5, 6)] """ return x def class_in_closure(x): """ >>> C1, c0 = class_in_closure(5) >>> C1().smeth1() (5, ()) >>> C1.smeth1(1,2) (5, (1, 2)) >>> C1.smeth1() (5, ()) >>> c0.smeth0() 1 >>> c0.__class__.smeth0() 1 """ class ClosureClass1(object): @staticmethod def smeth1(*args): return x, args class ClosureClass0(object): @staticmethod def smeth0(): return 1 return ClosureClass1, ClosureClass0() def class_not_in_closure(): """ >>> c = class_not_in_closure() >>> c.smeth0() 1 >>> c.__class__.smeth0() 1 """ class ClosureClass0(object): @staticmethod def smeth0(): return 1 return ClosureClass0() Cython-0.23.4/tests/run/decorators_T593.pyx0000644000175600017570000000372112606202452021610 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 593 # tag: property, decorator """ >>> am_i_buggy False >>> Foo False """ def testme(func): try: am_i_buggy return True except NameError: return False @testme def am_i_buggy(): pass def testclass(klass): try: Foo return True except NameError: return False @testclass class Foo: pass def called_deco(a,b,c): def count(f): a.append( (b,c) ) return f return count L = [] @called_deco(L, 5, c=6) @called_deco(L, c=3, b=4) @called_deco(L, 1, 2) def wrapped_func(x): """ >>> L [(1, 2), (4, 3), (5, 6)] >>> wrapped_func(99) 99 >>> L [(1, 2), (4, 3), (5, 6)] """ return x def class_in_closure(x): """ >>> C1, c0 = class_in_closure(5) >>> C1().smeth1() (5, ()) >>> C1.smeth1(1,2) (5, (1, 2)) >>> C1.smeth1() (5, ()) >>> c0.smeth0() 1 >>> c0.__class__.smeth0() 1 """ class ClosureClass1(object): @staticmethod def smeth1(*args): return x, args class ClosureClass0(object): @staticmethod def smeth0(): return 1 return ClosureClass1, ClosureClass0() def class_not_in_closure(): """ >>> c = class_not_in_closure() >>> c.smeth0() 1 >>> c.__class__.smeth0() 1 """ class ClosureClass0(object): @staticmethod def smeth0(): return 1 return ClosureClass0() class ODict(dict): def __init__(self): dict.__init__(self) self._order = [] dict.__setitem__(self, '_order', self._order) def __setitem__(self, key, value): dict.__setitem__(self, key, value) self._order.append(key) class Base(type): @staticmethod def __prepare__(*args, **kwargs): return ODict() class Bar(metaclass=Base): """ >>> Bar._order ['__module__', '__qualname__', '__doc__', 'bar'] """ @property def bar(self): return 0 Cython-0.23.4/tests/run/decorators.pyx0000644000175600017570000000141012606202452021055 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> f(1,2) 4 >>> f.HERE 1 >>> g(1,2) 5 >>> g.HERE 5 >>> h(1,2) 6 >>> h.HERE 1 >>> i(4) 3 >>> i.HERE 1 """ class wrap: def __init__(self, func): self.func = func self.HERE = 1 def __call__(self, *args, **kwargs): return self.func(*args, **kwargs) def decorate(func): try: func.HERE += 1 except AttributeError: func = wrap(func) return func def decorate2(a,b): return decorate @decorate def f(a,b): return a+b+1 @decorate @decorate @decorate @decorate @decorate def g(a,b): return a+b+2 @decorate2(1,2) def h(a,b): return a+b+3 class A: def decorate(self, func): return decorate(func) a = A() @a.decorate def i(x): return x - 1 Cython-0.23.4/tests/run/decorator_lambda.pyx0000644000175600017570000000057212606202452022202 0ustar jenkinsjenkins00000000000000# mode: run # tag: decorator, lambda def decorate(f): return f @decorate(lambda x: x) class TestClassDecorator(object): """ >>> obj = TestClassDecorator() >>> obj.hello() 'Hello, world!' """ def hello(self): return "Hello, world!" @decorate(lambda x: x) def test_function(): """ >>> test_function() 123 """ return 123 Cython-0.23.4/tests/run/datetime_pxd.pyx0000644000175600017570000001342212606202452021365 0ustar jenkinsjenkins00000000000000# coding: utf-8 #cimport cpython.datetime as cy_datetime #from datetime import time, date, datetime, timedelta, tzinfo from cpython.datetime cimport import_datetime from cpython.datetime cimport time_new, date_new, datetime_new, timedelta_new from cpython.datetime cimport time_tzinfo, datetime_tzinfo from cpython.datetime cimport time_hour, time_minute, time_second, time_microsecond from cpython.datetime cimport date_day, date_month, date_year from cpython.datetime cimport datetime_day, datetime_month, datetime_year from cpython.datetime cimport datetime_hour, datetime_minute, datetime_second, \ datetime_microsecond import datetime as py_datetime import_datetime() ZERO = py_datetime.timedelta(0) # # Simple class from datetime docs # class FixedOffset(py_datetime.tzinfo): """Fixed offset in minutes east from UTC.""" def __init__(self, offset, name): self._offset = py_datetime.timedelta(minutes = offset) self._name = name def utcoffset(self, dt): return self._offset def tzname(self, dt): return self._name def dst(self, dt): return ZERO def do_date(int year, int month, int day): """ >>> do_date(2012, 12, 31) (True, True, True, True) """ v = date_new(year, month, day) return type(v) is py_datetime.date, v.year == year, v.month == month, v.day == day def do_datetime(int year, int month, int day, int hour, int minute, int second, int microsecond): """ >>> do_datetime(2012, 12, 31, 12, 23, 0, 0) (True, True, True, True, True, True, True, True, True) """ v = datetime_new(year, month, day, hour, minute, second, microsecond, None) return type(v) is py_datetime.datetime, v.year == year, v.month == month, v.day == day, \ v.hour == hour, v.minute == minute, v.second == second, \ v.microsecond == microsecond, v.tzinfo is None def do_time(int hour, int minute, int second, int microsecond): """ >>> do_time(12, 23, 0, 0) (True, True, True, True, True, True) """ v = time_new(hour, minute, second, microsecond, None) return type(v) is py_datetime.time, \ v.hour == hour, v.minute == minute, v.second == second, \ v.microsecond == microsecond, v.tzinfo is None def do_time_tzinfo(int hour, int minute, int second, int microsecond, object tz): """ >>> tz = FixedOffset(60*3, 'Moscow') >>> do_time_tzinfo(12, 23, 0, 0, tz) (True, True, True, True, True, True) """ v = time_new(hour, minute, second, microsecond, tz) return type(v) is py_datetime.time, \ v.hour == hour, v.minute == minute, v.second == second, \ v.microsecond == microsecond, v.tzinfo is tz def do_datetime_tzinfo(int year, int month, int day, int hour, int minute, int second, int microsecond, object tz): """ >>> tz = FixedOffset(60*3, 'Moscow') >>> do_datetime_tzinfo(2012, 12, 31, 12, 23, 0, 0, tz) (True, True, True, True, True, True, True, True, True) """ v = datetime_new(year, month, day, hour, minute, second, microsecond, tz) return type(v) is py_datetime.datetime, v.year == year, v.month == month, v.day == day, \ v.hour == hour, v.minute == minute, v.second == second, \ v.microsecond == microsecond, v.tzinfo is tz def do_time_tzinfo2(int hour, int minute, int second, int microsecond, object tz): """ >>> tz = FixedOffset(60*3, 'Moscow') >>> do_time_tzinfo2(12, 23, 0, 0, tz) (True, True, True, True, True, True, True, True) """ v = time_new(hour, minute, second, microsecond, None) v1 = time_new( time_hour(v), time_minute(v), time_second(v), time_microsecond(v), tz) r1 = (v1.tzinfo == tz) r2 = (tz == time_tzinfo(v1)) v2 = time_new( time_hour(v1), time_minute(v1), time_second(v1), time_microsecond(v1), None) r3 = (v2.tzinfo == None) r4 = (None == time_tzinfo(v2)) v3 = time_new( time_hour(v2), time_minute(v2), time_second(v2), time_microsecond(v2), tz) r5 = (v3.tzinfo == tz) r6 = (tz == time_tzinfo(v3)) r7 = (v2 == v) r8 = (v3 == v1) return r1, r2, r3, r4, r5, r6, r7, r8 def do_datetime_tzinfo2(int year, int month, int day, int hour, int minute, int second, int microsecond, object tz): """ >>> tz = FixedOffset(60*3, 'Moscow') >>> do_datetime_tzinfo2(2012, 12, 31, 12, 23, 0, 0, tz) (True, True, True, True, True, True, True, True) """ v = datetime_new(year, month, day, hour, minute, second, microsecond, None) v1 = datetime_new( datetime_year(v), datetime_month(v), datetime_day(v), datetime_hour(v), datetime_minute(v), datetime_second(v), datetime_microsecond(v), tz) r1 = (v1.tzinfo == tz) r2 = (tz == datetime_tzinfo(v1)) v2 = datetime_new( datetime_year(v1), datetime_month(v1), datetime_day(v1), datetime_hour(v1), datetime_minute(v1), datetime_second(v1), datetime_microsecond(v1), None) r3 = (v2.tzinfo == None) r4 = (None == datetime_tzinfo(v2)) v3 = datetime_new( datetime_year(v2), datetime_month(v2), datetime_day(v2), datetime_hour(v2), datetime_minute(v2), datetime_second(v2), datetime_microsecond(v2), tz) r5 = (v3.tzinfo == tz) r6 = (tz == datetime_tzinfo(v3)) r7 = (v2 == v) r8 = (v3 == v1) return r1, r2, r3, r4, r5, r6, r7, r8 Cython-0.23.4/tests/run/datetime_members.pyx0000644000175600017570000000427512606202452022232 0ustar jenkinsjenkins00000000000000from cpython.datetime cimport import_datetime from cpython.datetime cimport time_new, date_new, datetime_new, timedelta_new from cpython.datetime cimport time_tzinfo, datetime_tzinfo from cpython.datetime cimport time_hour, time_minute, time_second, time_microsecond from cpython.datetime cimport date_day, date_month, date_year from cpython.datetime cimport datetime_day, datetime_month, datetime_year from cpython.datetime cimport datetime_hour, datetime_minute, datetime_second, \ datetime_microsecond from cpython.datetime cimport timedelta_days, timedelta_seconds, timedelta_microseconds import_datetime() def test_date(int year, int month, int day): ''' >>> test_date(2012,12,31) (True, True, True) ''' o = date_new(year, month, day) return o.year == date_year(o), \ o.month == date_month(o), \ o.day == date_day(o) def test_datetime(int year, int month, int day, int hour, int minute, int second, int microsecond): ''' >>> test_datetime(2012, 12, 31, 12, 30, 59, 12345) (True, True, True, True, True, True, True) ''' o = datetime_new(year, month, day, hour, minute, second, microsecond, None) return o.year == datetime_year(o), \ o.month == datetime_month(o), \ o.day == datetime_day(o), \ o.hour == datetime_hour(o), \ o.minute == datetime_minute(o), \ o.second == datetime_second(o), \ o.microsecond == datetime_microsecond(o) def test_time(int hour, int minute, int second, int microsecond): ''' >>> test_time(12, 30, 59, 12345) (True, True, True, True) ''' o = time_new(hour, minute, second, microsecond, None) return o.hour == time_hour(o), \ o.minute == time_minute(o), \ o.second == time_second(o), \ o.microsecond == time_microsecond(o) def test_timedelta(int days, int seconds, int microseconds): ''' >>> test_timedelta(30, 1440, 123456) (True, True, True) ''' o = timedelta_new(days, seconds, microseconds) return o.days == timedelta_days(o), \ o.seconds == timedelta_seconds(o), \ o.microseconds == timedelta_microseconds(o) Cython-0.23.4/tests/run/datetime_cimport.pyx0000644000175600017570000000210112606202452022237 0ustar jenkinsjenkins00000000000000# coding: utf-8 from cpython.datetime cimport import_datetime from cpython.datetime cimport date, time, datetime, timedelta, PyDateTime_IMPORT import_datetime() def test_date(int year, int month, int day): ''' >>> val = test_date(2012, 12, 31) >>> print(val) 2012-12-31 ''' val = date(year, month, day) return val def test_time(int hour, int minute, int second, int microsecond): ''' >>> val = test_time(12, 20, 55, 0) >>> print(val) 12:20:55 ''' val = time(hour, minute, second, microsecond) return val def test_datetime(int year, int month, int day, int hour, int minute, int second, int microsecond): ''' >>> val = test_datetime(2012, 12, 31, 12, 20, 55, 0) >>> print(val) 2012-12-31 12:20:55 ''' val = datetime(year, month, day, hour, minute, second, microsecond) return val def test_timedelta(int days, int seconds, int useconds): ''' >>> val = test_timedelta(30, 0, 0) >>> print(val) 30 days, 0:00:00 ''' val = timedelta(days, seconds, useconds) return val Cython-0.23.4/tests/run/cythonscope.pyx0000644000175600017570000001063512606202452021257 0ustar jenkinsjenkins00000000000000cimport cython from cython cimport _testscope as tester from cython cimport TestClass, _testclass_new as TestClass_New from cython cimport test_call, test_dep from cython.view cimport _testscope as viewtester from cpython cimport PyObject cdef extern from *: # TestClass stuff cdef struct __pyx_TestClass_obj: int value # Type pointer cdef PyObject *TestClassType "__pyx_TestClass_type" # This is a cdef function cdef __pyx_TestClass_New(int) # These are methods and therefore have no prototypes cdef __pyx_TestClass_cdef_method(TestClass self, int value) cdef __pyx_TestClass_cpdef_method(TestClass self, int value, int skip_dispatch) cdef __pyx_TestClass_def_method(object self, object value) cdef __pyx_TestClass_cdef_cname(TestClass self, int value) cdef __pyx_TestClass_cpdef_cname(TestClass self, int value, int skip_dispatch) cdef __pyx_TestClass_def_cname(object self, object value) cdef __pyx_test_dep(object) cdef __pyx_test_call_other_cy_util(object) def test_cdef_cython_utility(): """ >>> test_cdef_cython_utility() hello from cython scope, value=4 hello from cython.view scope, value=4 hello from cython scope, value=3 hello from cython.view scope, value=3 """ print cython._testscope(4) print cython.view._testscope(4) print tester(3) print viewtester(3) def test_cdef_class_cython_utility(): """ >>> test_cdef_class_cython_utility() 7 14 TestClass(20) TestClass(50) """ cdef __pyx_TestClass_obj *objstruct obj = TestClass_New(7) objstruct = <__pyx_TestClass_obj *> obj print objstruct.value obj = __pyx_TestClass_New(14) objstruct = <__pyx_TestClass_obj *> obj print objstruct.value print ( TestClassType)(20) print TestClass(50) def test_extclass_c_methods(): """ >>> test_extclass_c_methods() Hello from cdef_method 1 Hello from cpdef_method 2 Hello from def_method 3 Hello from cdef_cname_method 4 Hello from cpdef_cname_method 5 Hello from def_cname_method 6 Hello from cdef_method 1 Hello from cpdef_method 2 Hello from def_method 3 Hello from cdef_cname_method 4 Hello from cpdef_cname_method 5 Hello from def_cname_method 6 """ cdef TestClass obj1 = TestClass(11) cdef TestClass obj2 = TestClass_New(22) __pyx_TestClass_cdef_method(obj1, 1) __pyx_TestClass_cpdef_method(obj1, 2, True) __pyx_TestClass_def_method(obj1, 3) __pyx_TestClass_cdef_cname(obj1, 4) __pyx_TestClass_cpdef_cname(obj1, 5, True) __pyx_TestClass_def_cname(obj1, 6) __pyx_TestClass_cdef_method(obj2, 1) __pyx_TestClass_cpdef_method(obj2, 2, True) __pyx_TestClass_def_method(obj2, 3) __pyx_TestClass_cdef_cname(obj2, 4) __pyx_TestClass_cpdef_cname(obj2, 5, True) __pyx_TestClass_def_cname(obj2, 6) def test_extclass_cython_methods(): """ >>> test_extclass_cython_methods() Hello from cdef_method 1 Hello from cpdef_method 2 Hello from def_method 3 Hello from cdef_cname_method 4 Hello from cpdef_cname_method 5 Hello from def_cname_method 6 Hello from cdef_method 1 Hello from cpdef_method 2 Hello from def_method 3 Hello from cdef_cname_method 4 Hello from cpdef_cname_method 5 Hello from def_cname_method 6 """ cdef TestClass obj1 = TestClass(11) cdef TestClass obj2 = TestClass_New(22) obj1.cdef_method(1) obj1.cpdef_method(2) obj1.def_method(3) obj1.cdef_cname_method(4) obj1.cpdef_cname_method(5) obj1.def_cname_method(6) obj2.cdef_method(1) obj2.cpdef_method(2) obj2.def_method(3) obj2.cdef_cname_method(4) obj2.cpdef_cname_method(5) obj2.def_cname_method(6) def test_cython_utility_dep(): """ >>> test_cython_utility_dep() test_dep first test_call test_dep second test_dep third test_call test_dep fourth """ test_dep('first') test_call('second') __pyx_test_dep('third') __pyx_test_call_other_cy_util('fourth') def viewobjs(): """ >>> viewobjs() """ print cython.view.generic print cython.view.strided print cython.view.indirect #print cython.view.generic_contiguous print cython.view.contiguous print cython.view.indirect_contiguous Cython-0.23.4/tests/run/cython_includes.pyx0000644000175600017570000000117712606202452022114 0ustar jenkinsjenkins00000000000000 from libc.stdio cimport sprintf from cpython cimport PyType_Check from cpython cimport PyType_Check as PyType_Check2 from cpython.type cimport PyType_Check as PyType_Check3 def libc_cimports(): """ >>> libc_cimports() hello """ cdef char[10] buf sprintf(buf, "%s", b'hello') print (buf).decode('ASCII') def cpython_cimports(): """ >>> cpython_cimports() True False True False True False """ print PyType_Check(list) print PyType_Check([]) print PyType_Check2(list) print PyType_Check2([]) print PyType_Check3(list) print PyType_Check3([]) Cython-0.23.4/tests/run/cython3.pyx0000644000175600017570000002564312606202452020315 0ustar jenkinsjenkins00000000000000# cython: language_level=3, binding=True # mode: run # tag: generators, python3, exceptions cimport cython __doc__ = """ >>> items = sorted(locals_function(1).items()) >>> for item in items: ... print('%s = %r' % item) a = 1 b = 2 x = u'abc' >>> except_as_deletes True >>> no_match_does_not_touch_target True """ import sys if sys.version_info[0] >= 3: __doc__ = __doc__.replace(" u'", " '") def locals_function(a, b=2): x = 'abc' return locals() ### true division def truediv(x): """ >>> truediv(4) 2.0 >>> truediv(3) 1.5 """ return x / 2 def truediv_int(int x): """ >>> truediv_int(4) 2.0 >>> truediv_int(3) 1.5 """ return x / 2 @cython.cdivision(True) def cdiv_int(int x): """ >>> cdiv_int(4) 2 >>> cdiv_int(3) 1 """ return x / 2 ### module level except-as tests exc = [None] e = None try: raise KeyError except AttributeError as e: exc[0] = e except KeyError as e: exc[0] = e except IndexError as e: exc[0] = e except: exc[0] = 'SOMETHING ELSE' try: e except NameError: except_as_deletes = True else: except_as_deletes = False e = 123 try: raise TypeError except NameError as e: pass except TypeError: pass no_match_does_not_touch_target = (e == 123) ### more except-as tests def except_as_no_raise_does_not_touch_target(a): """ >>> except_as_no_raise_does_not_touch_target(TypeError) (1, 1) """ d = a # mark used b = 1 try: i = 1 except a as b: i = 2 return i, b def except_as_raise_deletes_target(x, a): """ >>> except_as_raise_deletes_target(None, TypeError) 1 1 >>> except_as_raise_deletes_target(TypeError('test'), TypeError) Traceback (most recent call last): UnboundLocalError: local variable 'b' referenced before assignment >>> except_as_raise_deletes_target(ValueError('test'), TypeError) Traceback (most recent call last): ValueError: test >>> except_as_raise_deletes_target(None, TypeError) 1 1 """ b = 1 try: i = 1 if x: raise x except a as b: i = 2 assert isinstance(b, a) print(b) # raises UnboundLocalError if except clause was executed return i def except_as_raise_deletes_target_even_after_del(x, a): """ >>> except_as_raise_deletes_target_even_after_del(None, TypeError) 1 1 >>> except_as_raise_deletes_target_even_after_del(TypeError('test'), TypeError) 2 >>> except_as_raise_deletes_target_even_after_del(ValueError('test'), TypeError) Traceback (most recent call last): ValueError: test >>> except_as_raise_deletes_target_even_after_del(None, TypeError) 1 1 """ b = 1 try: i = 1 if x: raise x except a as b: i = 2 assert isinstance(b, a) del b # let's see if Cython can still 'del' it after this line! try: print(b) # raises UnboundLocalError if except clause was executed except UnboundLocalError: pass else: if x: print("UnboundLocalError not raised!") return i def except_as_raise_deletes_target_on_error(x, a): """ >>> except_as_raise_deletes_target_on_error(None, TypeError) 1 1 >>> except_as_raise_deletes_target_on_error(TypeError('test'), TypeError) Traceback (most recent call last): UnboundLocalError: local variable 'b' referenced before assignment >>> except_as_raise_deletes_target_on_error(ValueError('test'), TypeError) Traceback (most recent call last): ValueError: test >>> except_as_raise_deletes_target_on_error(None, TypeError) 1 1 """ b = 1 try: try: i = 1 if x: raise x except a as b: i = 2 raise IndexError("TEST") except IndexError as e: assert 'TEST' in str(e), str(e) print(b) # raises UnboundLocalError if except clause was executed return i def except_as_raise_with_empty_except(x, a): """ >>> except_as_raise_with_empty_except(None, TypeError) 1 >>> except_as_raise_with_empty_except(TypeError('test'), TypeError) >>> except_as_raise_with_empty_except(ValueError('test'), TypeError) Traceback (most recent call last): ValueError: test >>> except_as_raise_with_empty_except(None, TypeError) 1 """ try: if x: raise x b = 1 except a as b: # previously raised UnboundLocalError pass try: print(b) # raises UnboundLocalError if except clause was executed except UnboundLocalError: if not x: print("unexpected UnboundLocalError raised!") else: if x: print("expected UnboundLocalError not raised!") def except_as_deletes_target_in_gen(x, a): """ >>> list(except_as_deletes_target_in_gen(None, TypeError)) [(1, 1), (2, 1), (5, 1)] >>> list(except_as_deletes_target_in_gen(TypeError('test'), TypeError)) [(1, 1), 3, 6] >>> list(except_as_deletes_target_in_gen(ValueError('test'), TypeError)) [(1, 1), (4, 1), (5, 1)] """ b = 1 try: i = 1 yield (1, b) if x: raise x yield (2, b) except a as b: i = 2 assert isinstance(b, a) yield 3 except: yield (4, b) try: yield (5, b) except UnboundLocalError: yield 6 ### Py3 feature tests def print_function(*args): """ >>> print_function(1,2,3) 1 2 3 """ print(*args) # this isn't valid Py2 syntax def exec3_function(cmd): """ >>> exec3_function('a = 1+1')['a'] 2 """ g = {} l = {} exec(cmd, g, l) return l def exec2_function(cmd): """ >>> exec2_function('a = 1+1')['a'] 2 """ g = {} exec(cmd, g) return g EXEC_GLOBAL = [5] def exec1_function(cmd): """ >>> exec1_function('EXEC_GLOBAL.append(1)') [1] """ old = len(EXEC_GLOBAL) exec(cmd) return EXEC_GLOBAL[old:] ustring = "abcdefg" def unicode_literals(): """ >>> print( unicode_literals() ) True abcdefg """ print(isinstance(ustring, unicode) or type(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 loop_over_unicode_literal(): """ >>> print( loop_over_unicode_literal() ) Py_UCS4 """ # Py_UCS4 can represent any Unicode character for uchar in 'abcdefg': assert uchar in 'abcdefg' return cython.typeof(uchar) def list_comp(): """ >>> list_comp() [0, 4, 8] """ x = 'abc' result = [x*2 for x in range(5) if x % 2 == 0] assert x == 'abc' # don't leak in Py3 code return result def list_comp_with_lambda(): """ >>> list_comp_with_lambda() [0, 4, 8] """ x = 'abc' result = [x*2 for x in range(5) if (lambda x:x % 2)(x) == 0] assert x == 'abc' # don't leak in Py3 code return result module_level_lc = [ module_level_loopvar*2 for module_level_loopvar in range(4) ] def list_comp_module_level(): """ >>> module_level_lc [0, 2, 4, 6] >>> module_level_loopvar # doctest: +ELLIPSIS Traceback (most recent call last): NameError: ...name 'module_level_loopvar' is not defined """ module_level_list_genexp = list(module_level_genexp_loopvar*2 for module_level_genexp_loopvar in range(4)) def genexpr_module_level(): """ >>> module_level_list_genexp [0, 2, 4, 6] >>> module_level_genexp_loopvar # doctest: +ELLIPSIS Traceback (most recent call last): NameError: ...name 'module_level_genexp_loopvar' is not defined """ def list_comp_unknown_type(l): """ >>> list_comp_unknown_type(range(5)) [0, 4, 8] """ return [x*2 for x in l if x % 2 == 0] def listcomp_as_condition(sequence): """ >>> listcomp_as_condition(['a', 'b', '+']) True >>> listcomp_as_condition('ab+') True >>> listcomp_as_condition('abc') False """ if [1 for c in sequence if c in '+-*/<=>!%&|([^~,']: return True return False def set_comp(): """ >>> sorted(set_comp()) [0, 4, 8] """ x = 'abc' result = {x*2 for x in range(5) if x % 2 == 0} assert x == 'abc' # don't leak return result def dict_comp(): """ >>> sorted(dict_comp().items()) [(0, 0), (2, 4), (4, 8)] """ x = 'abc' result = {x:x*2 for x in range(5) if x % 2 == 0} assert x == 'abc' # don't leak return result # in Python 3, d.keys/values/items() are the iteration methods @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") @cython.test_fail_if_path_exists( "//ForInStatNode") def dict_iter(dict d): """ >>> d = {'a' : 1, 'b' : 2, 'c' : 3} >>> keys, values, items = dict_iter(d) >>> sorted(keys) ['a', 'b', 'c'] >>> sorted(values) [1, 2, 3] >>> sorted(items) [('a', 1), ('b', 2), ('c', 3)] >>> dict_iter({}) ([], [], []) """ keys = [ key for key in d.keys() ] values = [ value for value in d.values() ] items = [ item for item in d.items() ] return keys, values, items @cython.test_assert_path_exists( "//WhileStatNode", "//WhileStatNode//DictIterationNextNode") @cython.test_fail_if_path_exists( "//ForInStatNode") def dict_iter_new_dict(): """ >>> dict_keys, keys, values, items = dict_iter_new_dict() >>> sorted(dict_keys) [11, 22, 33] >>> sorted(keys) [11, 22, 33] >>> sorted(values) [1, 2, 3] >>> sorted(items) [(11, 1), (22, 2), (33, 3)] """ dict_keys = [ key for key in {11 : 1, 22 : 2, 33 : 3} ] keys = [ key for key in {11 : 1, 22 : 2, 33 : 3}.keys() ] values = [ value for value in {11 : 1, 22 : 2, 33 : 3}.values() ] items = [ item for item in {11 : 1, 22 : 2, 33 : 3}.items() ] return dict_keys, keys, values, items def int_literals(): """ >>> int_literals() long long unsigned long unsigned long """ print(cython.typeof(1L)) print(cython.typeof(10000000000000L)) print(cython.typeof(1UL)) print(cython.typeof(10000000000000UL)) def annotation_syntax(a: "test new test", b : "other" = 2, *args: "ARGS", **kwargs: "KWARGS") -> "ret": """ >>> annotation_syntax(1) 3 >>> annotation_syntax(1,3) 4 >>> len(annotation_syntax.__annotations__) 5 >>> print(annotation_syntax.__annotations__['a']) test new test >>> print(annotation_syntax.__annotations__['b']) other >>> print(annotation_syntax.__annotations__['args']) ARGS >>> print(annotation_syntax.__annotations__['kwargs']) KWARGS >>> print(annotation_syntax.__annotations__['return']) ret """ return a+b Cython-0.23.4/tests/run/cython2_bytes.pyx0000644000175600017570000000030012606202452021501 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- # cython: language_level=2 b = b'abcüöä \x12' cdef char* cs = 'abcüöä \x12' def compare_cs(): """ >>> b == compare_cs() True """ return cs Cython-0.23.4/tests/run/cyfunction_defaults.pyx0000644000175600017570000001200412606202452022761 0ustar jenkinsjenkins00000000000000# cython: binding=True # mode: run # tag: cyfunction, closures cimport cython import sys def get_defaults(func): if sys.version_info >= (2, 6, 0): return func.__defaults__ return func.func_defaults def test_defaults_none(): """ >>> get_defaults(test_defaults_none) """ def test_defaults_literal(a=1, b=(1,2,3)): """ >>> get_defaults(test_defaults_literal) is get_defaults(test_defaults_literal) True >>> get_defaults(test_defaults_literal) (1, (1, 2, 3)) >>> a, b = get_defaults(test_defaults_literal) >>> c, d = test_defaults_literal() >>> a is c True >>> b is d True """ return a, b def test_defaults_nonliteral(): """ >>> f0, f1 = test_defaults_nonliteral() >>> get_defaults(f0) is get_defaults(f0) # cached True >>> get_defaults(f0) (0, {}, (1, 2, 3)) >>> a, b = get_defaults(f0)[1:] >>> c, d = f0(0) >>> a is c True >>> b is d True >>> get_defaults(f1) is get_defaults(f1) # cached True >>> get_defaults(f1) (0, [], (1, 2, 3)) >>> a, b = get_defaults(f1)[1:] >>> c, d = f1(0) >>> a is c True >>> b is d True """ ret = [] for i in {}, []: def foo(a, b=0, c=i, d=(1,2,3)): return c, d ret.append(foo) return ret _counter = 0 def counter(): global _counter _counter += 1 return _counter def test_defaults_nonliteral_func_call(f): """ >>> f = test_defaults_nonliteral_func_call(counter) >>> f() 1 >>> get_defaults(f) (1,) >>> f = test_defaults_nonliteral_func_call(lambda: list()) >>> f() [] >>> get_defaults(f) ([],) >>> get_defaults(f)[0] is f() True """ def func(a=f()): return a return func def cy_kwonly_default_args(a, x=1, *, b=2): l = m = 1 def test_kwdefaults(value): """ >>> cy_kwonly_default_args.__defaults__ (1,) >>> cy_kwonly_default_args.func_defaults (1,) >>> cy_kwonly_default_args.__kwdefaults__ {'b': 2} >>> test_kwdefaults.__defaults__ >>> test_kwdefaults.__kwdefaults__ >>> f = test_kwdefaults(5) >>> f.__defaults__ (1,) >>> f.__kwdefaults__ {'b': 5} >>> f.__kwdefaults__ = () Traceback (most recent call last): TypeError: __kwdefaults__ must be set to a dict object >>> f.__kwdefaults__ = None >>> f.__kwdefaults__ >>> f.__kwdefaults__ = {} >>> f.__kwdefaults__ {} >>> f.__kwdefaults__ = {'a': 2} >>> f.__kwdefaults__ {'a': 2} """ def kwonly_default_args(a, x=1, *, b=value): return a, x, b return kwonly_default_args _counter2 = 1.0 def counter2(): global _counter2 _counter2 += 1.0 return _counter2 def test_defaults_fused(cython.floating arg1, cython.floating arg2 = counter2()): """ >>> test_defaults_fused(1.0) 1.0 2.0 >>> test_defaults_fused(1.0, 3.0) 1.0 3.0 >>> _counter2 2.0 >>> get_defaults(test_defaults_fused) (2.0,) >>> get_defaults(test_defaults_fused[float]) (2.0,) """ print arg1, arg2 funcs = [] for i in range(10): def defaults_fused(cython.floating a, cython.floating b = i): return a, b funcs.append(defaults_fused) def test_dynamic_defaults_fused(): """ >>> test_dynamic_defaults_fused() i 0 func result (1.0, 0.0) defaults (0,) i 1 func result (1.0, 1.0) defaults (1,) i 2 func result (1.0, 2.0) defaults (2,) i 3 func result (1.0, 3.0) defaults (3,) i 4 func result (1.0, 4.0) defaults (4,) i 5 func result (1.0, 5.0) defaults (5,) i 6 func result (1.0, 6.0) defaults (6,) i 7 func result (1.0, 7.0) defaults (7,) i 8 func result (1.0, 8.0) defaults (8,) i 9 func result (1.0, 9.0) defaults (9,) """ for i, f in enumerate(funcs): print "i", i, "func result", f(1.0), "defaults", get_defaults(f) @cython.test_fail_if_path_exists( '//NameNode[@entry.in_closure = True]', '//NameNode[@entry.from_closure = True]') def test_func_default_inlined(): """ Make sure we don't accidentally generate a closure. >>> func = test_func_default_inlined() >>> func() 1 >>> func(2) 2 """ def default(): return 1 def func(arg=default()): return arg return func @cython.test_fail_if_path_exists( '//NameNode[@entry.in_closure = True]', '//NameNode[@entry.from_closure = True]') def test_func_default_scope(): """ Test that the default value expression is evaluated in the outer scope. >>> func = test_func_default_scope() 3 >>> func() [0, 1, 2, 3] >>> func(2) 2 """ i = -1 def func(arg=[ i for i in range(4) ]): return arg print i # list comps leak in Py2 mode => i == 3 return func def test_func_default_scope_local(): """ >>> func = test_func_default_scope_local() -1 >>> func() [0, 1, 2, 3] >>> func(2) 2 """ i = -1 def func(arg=list(i for i in range(4))): return arg print i # genexprs don't leak return func Cython-0.23.4/tests/run/cyfunction.pyx0000644000175600017570000001610112606202452021074 0ustar jenkinsjenkins00000000000000# cython: binding=True # mode: run # tag: cyfunction import sys IS_PY3 = sys.version_info[0] >= 3 IS_PY34 = sys.version_info > (3, 4, 0, 'beta', 3) def inspect_isroutine(): """ >>> inspect_isroutine() True """ import inspect return inspect.isroutine(inspect_isroutine) def inspect_isfunction(): """ >>> inspect_isfunction() False False """ import inspect, types print isinstance(inspect_isfunction, types.FunctionType) return inspect.isfunction(inspect_isfunction) def inspect_isbuiltin(): """ >>> inspect_isbuiltin() False False """ import inspect, types print isinstance(inspect_isfunction, types.BuiltinFunctionType) return inspect.isbuiltin(inspect_isbuiltin) def inspect_signature(a, b, c=123, *, d=234): """ >>> sig = inspect_signature(1, 2) >>> if IS_PY34: list(sig.parameters) ... else: ['a', 'b', 'c', 'd'] ['a', 'b', 'c', 'd'] >>> if IS_PY34: sig.parameters['c'].default == 123 ... else: True True >>> if IS_PY34: sig.parameters['d'].default == 234 ... else: True True """ import inspect return inspect.signature(inspect_signature) if IS_PY34 else None # def test___signature__(a, b, c=123, *, d=234): # """ # >>> sig = test___signature__(1, 2) # >>> if IS_PY34: list(sig.parameters) # ... else: ['a', 'b', 'c', 'd'] # ['a', 'b', 'c', 'd'] # >>> if IS_PY34: sig.parameters['c'].default == 123 # ... else: True # True # >>> if IS_PY34: sig.parameters['d'].default == 234 # ... else: True # True # """ # return inspect_signature.__signature__ if IS_PY34 else None def test_dict(): """ >>> test_dict.foo = 123 >>> test_dict.__dict__ {'foo': 123} >>> test_dict.__dict__ = {'bar': 321} >>> test_dict.__dict__ {'bar': 321} >>> test_dict.func_dict {'bar': 321} """ def test_name(): """ >>> test_name.__name__ 'test_name' >>> test_name.func_name 'test_name' >>> test_name.__name__ = 123 #doctest:+ELLIPSIS Traceback (most recent call last): TypeError: __name__ must be set to a ... object >>> test_name.__name__ = 'foo' >>> test_name.__name__ 'foo' """ def test_doc(): """ >>> del test_doc.__doc__ >>> test_doc.__doc__ >>> test_doc.__doc__ = 'docstring' >>> test_doc.__doc__ 'docstring' >>> test_doc.func_doc 'docstring' """ def test_hash(): """ >>> d = {test_hash: 123} >>> test_hash in d True >>> d[test_hash] 123 >>> hash(test_hash) == hash(test_hash) True """ def test_closure(): """ >>> test_closure.func_closure is None True """ def test_globals(): """ >>> test_globals.func_globals is not None True >>> 'test_globals' in test_globals.func_globals or test_globals.func_globals True >>> 'test_name' in test_globals.func_globals or test_globals.func_globals True >>> 'not there' not in test_globals.func_globals or test_globals.func_globals True >>> try: test_globals.func_globals = {} ... except (AttributeError, TypeError): pass ... else: assert 0, 'FAILED' """ def test_reduce(): """ >>> import pickle >>> pickle.loads(pickle.dumps(test_reduce))() 'Hello, world!' """ return 'Hello, world!' def test_method(self): return self class BindingTest: """ >>> BindingTest.test_method = test_method >>> BindingTest.test_method() #doctest:+ELLIPSIS Traceback (most recent call last): TypeError: ... >>> BindingTest().test_method() """ def __repr__(self): return '' def codeof(func): if IS_PY3: return func.__code__ else: return func.func_code def varnamesof(func): code = codeof(func) varnames = code.co_varnames if sys.version_info < (2,5): pos = {'a':0, 'x':1, 'b':2, 'l':3, 'm':4} varnames = tuple(sorted(varnames, key=pos.__getitem__)) return varnames def namesof(func): code = codeof(func) names = code.co_names if sys.version_info < (2,5): names = () return names def cy_no_arg(): l = m = 1 def cy_one_arg(a): l = m = 1 def cy_two_args(x, b): l = m = 1 def cy_default_args(x=1, b=2): l = m = 1 def test_code(): """ >>> def no_arg(): l = m = 1 >>> def one_arg(a): l = m = 1 >>> def two_args(x, b): l = m = 1 >>> def default_args(x=1, b=2): l = m = 1 >>> codeof(no_arg).co_argcount 0 >>> codeof(cy_no_arg).co_argcount 0 >>> print(codeof(no_arg).co_name) no_arg >>> print(codeof(cy_no_arg).co_name) cy_no_arg >>> namesof(no_arg) () >>> codeof(cy_no_arg).co_names () >>> varnamesof(no_arg) ('l', 'm') >>> codeof(cy_no_arg).co_varnames ('l', 'm') >>> codeof(one_arg).co_argcount 1 >>> codeof(cy_one_arg).co_argcount 1 >>> print(codeof(one_arg).co_name) one_arg >>> print(codeof(cy_one_arg).co_name) cy_one_arg >>> namesof(one_arg) () >>> codeof(cy_one_arg).co_names () >>> varnamesof(one_arg) ('a', 'l', 'm') >>> codeof(cy_one_arg).co_varnames ('a', 'l', 'm') >>> codeof(two_args).co_argcount 2 >>> codeof(cy_two_args).co_argcount 2 >>> namesof(two_args) () >>> codeof(cy_two_args).co_names () >>> varnamesof(two_args) ('x', 'b', 'l', 'm') >>> codeof(cy_two_args).co_varnames ('x', 'b', 'l', 'm') >>> codeof(default_args).co_argcount 2 >>> codeof(cy_default_args).co_argcount 2 >>> namesof(default_args) () >>> codeof(cy_default_args).co_names () >>> varnamesof(default_args) ('x', 'b', 'l', 'm') >>> codeof(cy_default_args).co_varnames ('x', 'b', 'l', 'm') """ def test_annotations(a: "test", b: "other" = 2, c: 123 = 4) -> "ret": """ >>> isinstance(test_annotations.__annotations__, dict) True >>> sorted(test_annotations.__annotations__.items()) [('a', 'test'), ('b', 'other'), ('c', 123), ('return', 'ret')] >>> def func_b(): return 42 >>> def func_c(): return 99 >>> inner = test_annotations(1, func_b, func_c) >>> sorted(inner.__annotations__.items()) [('return', 99), ('x', 'banana'), ('y', 42)] >>> inner.__annotations__ = {234: 567} >>> inner.__annotations__ {234: 567} >>> inner.__annotations__ = None >>> inner.__annotations__ {} >>> inner.__annotations__ = 321 Traceback (most recent call last): TypeError: __annotations__ must be set to a dict object >>> inner.__annotations__ {} >>> inner = test_annotations(1, func_b, func_c) >>> sorted(inner.__annotations__.items()) [('return', 99), ('x', 'banana'), ('y', 42)] >>> inner.__annotations__['abc'] = 66 >>> sorted(inner.__annotations__.items()) [('abc', 66), ('return', 99), ('x', 'banana'), ('y', 42)] >>> inner = test_annotations(1, func_b, func_c) >>> sorted(inner.__annotations__.items()) [('return', 99), ('x', 'banana'), ('y', 42)] """ def inner(x: "banana", y: b()) -> c(): return x,y return inner Cython-0.23.4/tests/run/cyclic_gc.pyx0000644000175600017570000001302412606202452020633 0ustar jenkinsjenkins00000000000000# mode: run # tag: cyclicgc cimport cython @cython.test_fail_if_path_exists('//CClassDefNode[@scope.has_cyclic_pyobject_attrs = True]') @cython.test_assert_path_exists('//CClassDefNode', '//CClassDefNode[@scope]', '//CClassDefNode[@scope.has_cyclic_pyobject_attrs = False]') cdef class ExtTypeNoGC: """ >>> obj = ExtTypeNoGC() >>> obj = ExtTypeNoGC() >>> obj = ExtTypeNoGC() >>> obj = ExtTypeNoGC() >>> obj = ExtTypeNoGC() >>> obj = ExtTypeNoGC() """ @cython.test_fail_if_path_exists('//CClassDefNode[@scope.has_cyclic_pyobject_attrs = True]') @cython.test_assert_path_exists('//CClassDefNode', '//CClassDefNode[@scope]', '//CClassDefNode[@scope.has_cyclic_pyobject_attrs = False]') @cython.final cdef class ExtTypeFinalNoGC: """ >>> obj = ExtTypeFinalNoGC() >>> obj = ExtTypeFinalNoGC() >>> obj = ExtTypeFinalNoGC() >>> obj = ExtTypeFinalNoGC() >>> obj = ExtTypeFinalNoGC() >>> obj = ExtTypeFinalNoGC() """ cdef bytes s @cython.test_fail_if_path_exists('//CClassDefNode[@scope.has_cyclic_pyobject_attrs = True]') @cython.test_assert_path_exists('//CClassDefNode', '//CClassDefNode[@scope]', '//CClassDefNode[@scope.has_cyclic_pyobject_attrs = False]') cdef class ExtSubTypeNoGC(ExtTypeNoGC): """ >>> obj = ExtSubTypeNoGC() >>> obj = ExtSubTypeNoGC() >>> obj = ExtSubTypeNoGC() >>> obj = ExtSubTypeNoGC() >>> obj = ExtSubTypeNoGC() >>> obj = ExtSubTypeNoGC() """ @cython.test_fail_if_path_exists('//CClassDefNode[@scope.has_cyclic_pyobject_attrs = True]') @cython.test_assert_path_exists('//CClassDefNode', '//CClassDefNode[@scope]', '//CClassDefNode[@scope.has_cyclic_pyobject_attrs = False]') cdef class ExtTypePyArgsNoGC: """ >>> obj = ExtTypePyArgsNoGC() >>> obj = ExtTypePyArgsNoGC() >>> obj = ExtTypePyArgsNoGC() >>> obj = ExtTypePyArgsNoGC() >>> obj = ExtTypePyArgsNoGC() >>> obj = ExtTypePyArgsNoGC() """ cdef bytes b cdef str s cdef unicode u # eventually, this should work, too: # cdef ExtTypeFinalNoGC x @cython.test_fail_if_path_exists('//CClassDefNode[@scope.has_cyclic_pyobject_attrs = True]') @cython.test_assert_path_exists('//CClassDefNode', '//CClassDefNode[@scope]', '//CClassDefNode[@scope.has_cyclic_pyobject_attrs = False]') cdef class ExtSubTypePyArgsNoGC(ExtTypePyArgsNoGC): """ >>> obj = ExtSubTypePyArgsNoGC() >>> obj = ExtSubTypePyArgsNoGC() >>> obj = ExtSubTypePyArgsNoGC() >>> obj = ExtSubTypePyArgsNoGC() >>> obj = ExtSubTypePyArgsNoGC() >>> obj = ExtSubTypePyArgsNoGC() """ @cython.test_fail_if_path_exists('//CClassDefNode[@scope.has_cyclic_pyobject_attrs = False]') @cython.test_assert_path_exists('//CClassDefNode', '//CClassDefNode[@scope]', '//CClassDefNode[@scope.has_cyclic_pyobject_attrs = True]') cdef class ExtTypePyArgsWithGC: """ >>> obj = ExtTypePyArgsWithGC() >>> obj = ExtTypePyArgsWithGC() >>> obj = ExtTypePyArgsWithGC() >>> obj = ExtTypePyArgsWithGC() >>> obj = ExtTypePyArgsWithGC() >>> obj = ExtTypePyArgsWithGC() >>> obj.create_cycle() """ cdef bytes b cdef str s cdef unicode u cdef list l def create_cycle(self): self.l = [self] @cython.test_fail_if_path_exists('//CClassDefNode[@scope.has_cyclic_pyobject_attrs = True]') @cython.test_assert_path_exists('//CClassDefNode', '//CClassDefNode[@scope]', '//CClassDefNode[@scope.has_cyclic_pyobject_attrs = False]') cdef class ExtSubTypePyArgsWithGC(ExtTypePyArgsWithGC): """ >>> obj = ExtSubTypePyArgsWithGC() >>> obj = ExtSubTypePyArgsWithGC() >>> obj = ExtSubTypePyArgsWithGC() >>> obj = ExtSubTypePyArgsWithGC() >>> obj = ExtSubTypePyArgsWithGC() >>> obj = ExtSubTypePyArgsWithGC() >>> obj.create_cycle() """ @cython.test_fail_if_path_exists('//CClassDefNode[@scope.has_cyclic_pyobject_attrs = True]') @cython.test_assert_path_exists('//CClassDefNode', '//CClassDefNode[@scope]', '//CClassDefNode[@scope.has_cyclic_pyobject_attrs = False]') cdef class ExtSubTypePlusPyArgsWithGC(ExtSubTypePyArgsWithGC): """ >>> obj = ExtSubTypePlusPyArgsWithGC() >>> obj = ExtSubTypePlusPyArgsWithGC() >>> obj = ExtSubTypePlusPyArgsWithGC() >>> obj = ExtSubTypePlusPyArgsWithGC() >>> obj = ExtSubTypePlusPyArgsWithGC() >>> obj = ExtSubTypePlusPyArgsWithGC() >>> obj.create_cycle() """ cdef bytes b2 cdef unicode u2 @cython.test_fail_if_path_exists('//CClassDefNode[@scope.has_cyclic_pyobject_attrs = False]') @cython.test_assert_path_exists('//CClassDefNode', '//CClassDefNode[@scope]', '//CClassDefNode[@scope.has_cyclic_pyobject_attrs = True]') cdef class ExtSubTypePlusGCPyArgsWithGC(ExtSubTypePlusPyArgsWithGC): """ >>> obj = ExtSubTypePlusGCPyArgsWithGC() >>> obj = ExtSubTypePlusGCPyArgsWithGC() >>> obj = ExtSubTypePlusGCPyArgsWithGC() >>> obj = ExtSubTypePlusGCPyArgsWithGC() >>> obj = ExtSubTypePlusGCPyArgsWithGC() >>> obj = ExtSubTypePlusGCPyArgsWithGC() >>> obj.create_cycle() """ cdef tuple t Cython-0.23.4/tests/run/cunion.pyx0000644000175600017570000000367712606202452020224 0ustar jenkinsjenkins00000000000000cdef union Spam: int i char c float *p[42] cdef Spam spam, ham cdef void eggs_i(Spam s): cdef int j j = s.i s.i = j cdef void eggs_c(Spam s): cdef char c c = s.c s.c = c cdef void eggs_p(Spam s): cdef float *p p = s.p[0] s.p[0] = p spam = ham def test_i(): """ >>> test_i() """ spam.i = 1 eggs_i(spam) def test_c(): """ >>> test_c() """ spam.c = c'a' eggs_c(spam) def test_p(): """ >>> test_p() """ cdef float f spam.p[0] = &f eggs_p(spam) cdef union AllCharptr: char* s1 char* s2 char* s3 def test_charptr_to_py(): """ >>> result = test_charptr_to_py() >>> len(result) 3 >>> result['s1'] == b'abc' True >>> result['s2'] == b'abc' True >>> result['s3'] == b'abc' True """ cdef AllCharptr u u.s1 = b"abc" return u cdef union SafeMix: char c unsigned char uc signed char sc short w int i long l size_t z float f double d def test_safe_type_mix_from_to_py(v): """ >>> test_safe_type_mix_from_to_py({'l': 32, 'c': 32}) Traceback (most recent call last): ValueError: More than one union attribute passed: 'c' and 'l' >>> result = test_safe_type_mix_from_to_py({'c': 32}) >>> sorted(result) ['c', 'd', 'f', 'i', 'l', 'sc', 'uc', 'w', 'z'] >>> result['c'] 32 >>> result['z'] != 0 True >>> result = test_safe_type_mix_from_to_py({'uc': 32}) >>> len(result) 9 >>> result['uc'] 32 >>> result = test_safe_type_mix_from_to_py({'l': 100}) >>> result['l'] 100 >>> result = test_safe_type_mix_from_to_py({'z': 0}) >>> result['z'] 0 >>> result['i'] 0 >>> result['l'] 0 >>> result = test_safe_type_mix_from_to_py({'d': 2**52 - 1}) >>> result['d'] 4503599627370495.0 >>> result['z'] != 0 True """ cdef SafeMix u = v return u Cython-0.23.4/tests/run/ctypedef_int_types_defs_T333.pxd0000644000175600017570000000115412606202452024306 0ustar jenkinsjenkins00000000000000cdef extern from "ctypedef_int_types_chdr_T333.h": ctypedef int SChar ## "signed char" ctypedef int UChar ## "unsigned char" ctypedef int SShort ## "signed short" ctypedef int UShort ## "unsigned short" ctypedef int SInt ## "signed int" ctypedef int UInt ## "unsigned int" ctypedef int SLong ## "signed long" ctypedef int ULong ## "unsigned long" ctypedef int SLongLong ## "signed PY_LONG_LONG" ctypedef int ULongLong ## "unsigned PY_LONG_LONG" cdef extern from *: ctypedef int ExtSInt "signed short" ctypedef int ExtUInt "unsigned short" Cython-0.23.4/tests/run/ctypedef_int_types_chdr_T333.h0000644000175600017570000000054612606202452023745 0ustar jenkinsjenkins00000000000000typedef signed char SChar; typedef unsigned char UChar; typedef signed short SShort; typedef unsigned short UShort; typedef signed int SInt; typedef unsigned int UInt; typedef signed long SLong; typedef unsigned long ULong; typedef signed long long SLongLong; typedef unsigned long long ULongLong; Cython-0.23.4/tests/run/ctypedef_int_types_T333.pyx0000644000175600017570000003637012606202452023342 0ustar jenkinsjenkins00000000000000# ticket: 333 #cython: autotestdict=True # ------------------------------------------------------------------- cdef extern from "ctypedef_int_types_chdr_T333.h": ctypedef int SChar ## "signed char" ctypedef int UChar ## "unsigned char" ctypedef int SShort ## "signed short" ctypedef int UShort ## "unsigned short" ctypedef int SInt ## "signed int" ctypedef int UInt ## "unsigned int" ctypedef int SLong ## "signed long" ctypedef int ULong ## "unsigned long" ctypedef int SLongLong ## "signed PY_LONG_LONG" ctypedef int ULongLong ## "unsigned PY_LONG_LONG" # ------------------------------------------------------------------- SCHAR_MAX = ((-1)>>1) SCHAR_MIN = (-SCHAR_MAX-1) def test_schar(SChar x): u""" >>> test_schar(-129) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to SChar >>> test_schar(-128) -128 >>> test_schar(0) 0 >>> test_schar(127) 127 >>> test_schar(128) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to SChar """ return x def test_add_schar(x, y): u""" >>> test_add_schar(SCHAR_MIN, -1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to SChar >>> test_add_schar(SCHAR_MIN, 0) == SCHAR_MIN True >>> test_add_schar(SCHAR_MIN, 1) == SCHAR_MIN+1 True >>> test_add_schar(SCHAR_MAX, -1) == SCHAR_MAX-1 True >>> test_add_schar(SCHAR_MAX, 0) == SCHAR_MAX True >>> test_add_schar(SCHAR_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to SChar """ cdef SChar r = x + y return r UCHAR_MAX = ((-1)) def test_uchar(UChar x): u""" >>> test_uchar(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: can't convert negative value to UChar >>> test_uchar(0) 0 >>> test_uchar(1) 1 >>> test_uchar(UCHAR_MAX) == UCHAR_MAX True >>> test_uchar(UCHAR_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to UChar """ return x def test_add_uchar(x, y): u""" >>> test_add_uchar(UCHAR_MAX, 0) == UCHAR_MAX True >>> test_add_uchar(UCHAR_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to UChar """ cdef UChar r = x + y return r # ------------------------------------------------------------------- SSHORT_MAX = ((-1)>>1) SSHORT_MIN = (-SSHORT_MAX-1) def test_sshort(SShort x): u""" >>> test_sshort(SSHORT_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to SShort >>> test_sshort(SSHORT_MIN) == SSHORT_MIN True >>> test_sshort(-1) -1 >>> test_sshort(0) 0 >>> test_sshort(1) 1 >>> test_sshort(SSHORT_MAX) == SSHORT_MAX True >>> test_sshort(SSHORT_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_sshort(x, y): u""" >>> test_add_sshort(SSHORT_MIN, -1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to SShort >>> test_add_sshort(SSHORT_MIN, 0) == SSHORT_MIN True >>> test_add_sshort(SSHORT_MIN, 1) == SSHORT_MIN+1 True >>> test_add_sshort(SSHORT_MAX, -1) == SSHORT_MAX-1 True >>> test_add_sshort(SSHORT_MAX, 0) == SSHORT_MAX True >>> test_add_sshort(SSHORT_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to SShort """ cdef SShort r = x + y return r USHORT_MAX = ((-1)) def test_ushort(UShort x): u""" >>> test_ushort(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: can't convert negative value to UShort >>> test_ushort(0) 0 >>> test_ushort(1) 1 >>> test_ushort(USHORT_MAX) == USHORT_MAX True >>> test_ushort(USHORT_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to UShort """ return x def test_add_ushort(x, y): u""" >>> test_add_ushort(USHORT_MAX, 0) == USHORT_MAX True >>> test_add_ushort(USHORT_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to UShort """ cdef UShort r = x + y return r # ------------------------------------------------------------------- SINT_MAX = ((-1)>>1) SINT_MIN = (-SINT_MAX-1) def test_sint(SInt x): u""" >>> test_sint(SINT_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_sint(SINT_MIN) == SINT_MIN True >>> test_sint(-1) -1 >>> test_sint(0) 0 >>> test_sint(1) 1 >>> test_sint(SINT_MAX) == SINT_MAX True >>> test_sint(SINT_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_sint(x, y): u""" >>> test_add_sint(SINT_MIN, -1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_add_sint(SINT_MIN, 0) == SINT_MIN True >>> test_add_sint(SINT_MIN, 1) == SINT_MIN+1 True >>> test_add_sint(SINT_MAX, -1) == SINT_MAX-1 True >>> test_add_sint(SINT_MAX, 0) == SINT_MAX True >>> test_add_sint(SINT_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef SInt r = x + y return r UINT_MAX = (-1) def test_uint(UInt x): u""" >>> test_uint(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: can't convert negative value to UInt >>> print(test_uint(0)) 0 >>> print(test_uint(1)) 1 >>> test_uint(UINT_MAX) == UINT_MAX True >>> test_uint(UINT_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_uint(x, y): u""" >>> test_add_uint(UINT_MAX, 0) == UINT_MAX True >>> test_add_uint(UINT_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef UInt r = x + y return r # ------------------------------------------------------------------- SLONG_MAX = ((-1)>>1) SLONG_MIN = (-SLONG_MAX-1) def test_slong(long x): u""" >>> test_slong(SLONG_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_slong(SLONG_MIN) == SLONG_MIN True >>> test_slong(-1) -1 >>> test_slong(0) 0 >>> test_slong(1) 1 >>> test_slong(SLONG_MAX) == SLONG_MAX True >>> test_slong(SLONG_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_slong(x, y): u""" >>> test_add_slong(SLONG_MIN, -1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_add_slong(SLONG_MIN, 0) == SLONG_MIN True >>> test_add_slong(SLONG_MIN, 1) == SLONG_MIN+1 True >>> test_add_slong(SLONG_MAX, -1) == SLONG_MAX-1 True >>> test_add_slong(SLONG_MAX, 0) == SLONG_MAX True >>> test_add_slong(SLONG_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef SLong r = x + y return r ULONG_MAX = (-1) def test_ulong(ULong x): u""" >>> test_ulong(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: can't convert negative value to ULong >>> print(test_ulong(0)) 0 >>> print(test_ulong(1)) 1 >>> test_ulong(ULONG_MAX) == ULONG_MAX True >>> test_ulong(ULONG_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_ulong(x, y): u""" >>> test_add_ulong(ULONG_MAX, 0) == ULONG_MAX True >>> test_add_ulong(ULONG_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef ULong r = x + y return r # ------------------------------------------------------------------- SLONGLONG_MAX = ((-1)>>1) SLONGLONG_MIN = (-SLONGLONG_MAX-1) def test_slonglong(long long x): u""" >>> test_slonglong(SLONGLONG_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_slonglong(SLONGLONG_MIN) == SLONGLONG_MIN True >>> print(test_slonglong(-1)) -1 >>> print(test_slonglong(0)) 0 >>> print(test_slonglong(1)) 1 >>> test_slonglong(SLONGLONG_MAX) == SLONGLONG_MAX True >>> test_slonglong(SLONGLONG_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_slonglong(x, y): u""" >>> test_add_slonglong(SLONGLONG_MIN, -1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_add_slonglong(SLONGLONG_MIN, 0) == SLONGLONG_MIN True >>> test_add_slonglong(SLONGLONG_MIN, 1) == SLONGLONG_MIN+1 True >>> test_add_slonglong(SLONGLONG_MAX, -1) == SLONGLONG_MAX-1 True >>> test_add_slonglong(SLONGLONG_MAX, 0) == SLONGLONG_MAX True >>> test_add_slonglong(SLONGLONG_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef SLongLong r = x + y return r ULONGLONG_MAX = (-1) def test_ulonglong(ULongLong x): u""" >>> test_ulonglong(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: can't convert negative value to ULongLong >>> print(test_ulonglong(0)) 0 >>> print(test_ulonglong(1)) 1 >>> test_ulonglong(ULONGLONG_MAX) == ULONGLONG_MAX True >>> test_ulonglong(ULONGLONG_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_ulonglong(x, y): u""" >>> test_add_ulonglong(ULONGLONG_MAX, 0) == ULONGLONG_MAX True >>> test_add_ulonglong(ULONGLONG_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef ULongLong r = x + y return r # ------------------------------------------------------------------- cdef class MyClass: """ >>> a = MyClass() >>> vals = (SCHAR_MIN, UCHAR_MAX, ... SSHORT_MIN, USHORT_MAX, ... SINT_MIN, UINT_MAX, ... SLONG_MIN, ULONG_MAX, ... SLONGLONG_MIN, ULONGLONG_MAX) >>> a.setvalues(*vals) >>> a.getvalues() == vals True >>> vals = (SCHAR_MAX, UCHAR_MAX, ... SSHORT_MAX, USHORT_MAX, ... SINT_MAX, UINT_MAX, ... SLONG_MAX, ULONG_MAX, ... SLONGLONG_MAX, ULONGLONG_MAX) >>> a.setvalues(*vals) >>> a.getvalues() == vals True >>> vals = (0,) * 10 >>> a.setvalues(*vals) >>> a.getvalues() == vals True """ cdef: SChar attr_schar UChar attr_uchar SShort attr_sshort UShort attr_ushort SInt attr_sint UInt attr_uint SLong attr_slong ULong attr_ulong SLongLong attr_slonglong ULongLong attr_ulonglong cpdef setvalues(self, SChar arg_schar , UChar arg_uchar , SShort arg_sshort , UShort arg_ushort , SInt arg_sint , UInt arg_uint , SLong arg_slong , ULong arg_ulong , SLongLong arg_slonglong , ULongLong arg_ulonglong ): self.attr_schar = arg_schar self.attr_uchar = arg_uchar self.attr_sshort = arg_sshort self.attr_ushort = arg_ushort self.attr_sint = arg_sint self.attr_uint = arg_uint self.attr_slong = arg_slong self.attr_ulong = arg_ulong self.attr_slonglong = arg_slonglong self.attr_ulonglong = arg_ulonglong cpdef getvalues(self): return (self.attr_schar , self.attr_uchar , self.attr_sshort , self.attr_ushort , self.attr_sint , self.attr_uint , self.attr_slong , self.attr_ulong , self.attr_slonglong , self.attr_ulonglong ) # ------------------------------------------------------------------- cdef extern from *: ctypedef signed MySInt1 "signed short" ctypedef unsigned MyUInt1 "unsigned short" def test_MySInt1(MySInt1 x): u""" >>> test_MySInt1(-1) -1 >>> test_MySInt1(0) 0 >>> test_MySInt1(1) 1 """ return x def test_MyUInt1(MyUInt1 x): u""" >>> test_MyUInt1(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_MyUInt1(0) 0 >>> test_MyUInt1(1) 1 """ return x cdef extern from *: ctypedef signed MySInt2 "signed short" ctypedef unsigned MyUInt2 "unsigned short" def test_MySInt2(MySInt2 x): u""" >>> test_MySInt2(-1) -1 >>> test_MySInt2(0) 0 >>> test_MySInt2(1) 1 """ return x def test_MyUInt2(MyUInt2 x): u""" >>> test_MyUInt2(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: can't convert negative value to ... >>> test_MyUInt2(0) 0 >>> test_MyUInt2(1) 1 """ return x # ------------------------------------------------------------------- cimport ctypedef_int_types_defs_T333 as defs def test_DefSInt(defs.SInt x): u""" >>> test_DefSInt(-1) -1 >>> test_DefSInt(0) 0 >>> test_DefSInt(1) 1 """ return x def test_DefUChar(defs.UChar x): u""" >>> test_DefUChar(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: can't convert negative value to ... >>> test_DefUChar(0) 0 >>> test_DefUChar(1) 1 """ return x def test_ExtSInt(defs.ExtSInt x): u""" >>> test_ExtSInt(-1) -1 >>> test_ExtSInt(0) 0 >>> test_ExtSInt(1) 1 """ return x def test_ExtUInt(defs.ExtUInt x): u""" >>> test_ExtUInt(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: can't convert negative value to ... >>> test_ExtUInt(0) 0 >>> test_ExtUInt(1) 1 """ return x ctypedef defs.SShort LocSInt ctypedef defs.UShort LocUInt def test_LocSInt(LocSInt x): u""" >>> test_LocSInt(-1) -1 >>> test_LocSInt(0) 0 >>> test_LocSInt(1) 1 """ return x def test_LocUInt(LocUInt x): u""" >>> test_LocUInt(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: can't convert negative value to ... >>> test_LocUInt(0) 0 >>> test_LocUInt(1) 1 """ return x # ------------------------------------------------------------------- Cython-0.23.4/tests/run/ctypedef_delegation.pyx0000644000175600017570000000024212606202452022710 0ustar jenkinsjenkins00000000000000 ctypedef char* LPSTR def typedef_delegation(): """ >>> typedef_delegation() """ cdef LPSTR c_str = b"ascii" assert c_str == b"ascii" Cython-0.23.4/tests/run/ctypedef_char_types.pyx0000644000175600017570000000264212606202452022744 0ustar jenkinsjenkins00000000000000 cimport cython from cython cimport typeof from libc.string cimport const_char, const_uchar @cython.test_assert_path_exists( "//NameNode[@name = 'st' and @type.is_string = True]", "//NameNode[@name = 'ust' and @type.is_string = True]", "//NameNode[@name = 'my_st' and @type.is_string = True]", "//NameNode[@name = 'my_ust' and @type.is_string = True]", ) def const_charptrs(): """ >>> const_charptrs() """ cdef object obj cdef const_char* st = b'XYZ' cdef const_uchar* ust = b'XYZ' # needs cast to unsigned assert typeof(st) == "const_char *", typeof(st) my_st = st assert typeof(my_st) == "const_char *", typeof(my_st) obj = my_st assert obj == b'XYZ', obj assert typeof(ust) == "const_uchar *", typeof(ust) my_ust = ust assert typeof(my_ust) == "const_uchar *", typeof(my_ust) obj = my_ust assert obj == b'XYZ', obj ctypedef char mychar ctypedef unsigned char myuchar def const_char_arrays(): """ >>> const_char_arrays() """ cdef int i cdef object obj cdef mychar[4] st cdef myuchar[4] ust cdef char ch i = 0 for ch in b'XYZ\0': st[i] = ch ust[i] = ch i += 1 assert typeof(st) == "mychar [4]", typeof(st) obj = st assert obj == b'XYZ', obj assert typeof(ust) == "myuchar [4]", typeof(ust) obj = ust assert obj == b'XYZ', obj Cython-0.23.4/tests/run/ctuple.pyx0000644000175600017570000000732312606202452020215 0ustar jenkinsjenkins00000000000000import cython def simple_convert(*o): """ >>> simple_convert(1, 2) (1, 2.0) >>> simple_convert(1) Traceback (most recent call last): ... TypeError: Expected a tuple of size 2, got tuple >>> simple_convert(1, 2, 3) Traceback (most recent call last): ... TypeError: Expected a tuple of size 2, got tuple """ cdef (int, double) xy = o return xy def indexing((int, double) xy): """ >>> indexing((1, 2)) (2, 3.0) """ x = xy[0] y = xy[1] xy[0] = x + 1 xy[1] = y + 1 return xy def unpacking((int, double) xy): """ >>> unpacking((1, 2)) (1, 2.0) """ x, y = xy return x, y cdef (int, double) side_effect((int, double) xy): print "called with", xy return xy def unpacking_with_side_effect((int, double) xy): """ >>> unpacking_with_side_effect((1, 2)) called with (1, 2.0) (1, 2.0) """ x, y = side_effect(xy) return x, y def packing_tuple(int x, double y): """ >>> packing_tuple(1, 2) (1, 2.0) """ cdef (int, double) xy = (x, y) return xy def coerce_packing_tuple(int x, int y): cdef (int, double) xy = (x, y) """ >>> coerce_packing_tuple(1, 2) (1, 2.0) """ return xy def c_types(int a, double b): """ >>> c_types(1, 2) (1, 2.0) """ cdef int* a_ptr cdef double* b_ptr cdef (int*, double*) ab = (&a, &b) a_ptr, b_ptr = ab return a_ptr[0], b_ptr[0] cdef union Union: int x double y def union_in_ctuple_literal(): """ >>> union_in_ctuple_literal() (1, 2.0) """ cdef (Union,) a = ({"x": 1},) cdef (Union,) b = ({"y": 2},) return a[0].x, b[0].y def union_in_ctuple_dynamic(*values): """ >>> union_in_ctuple_dynamic(1, {'x': 1}) 1 >>> union_in_ctuple_dynamic(2, {'y': 2}) 2.0 >>> union_in_ctuple_dynamic(1, {'x': 1, 'y': 2}) Traceback (most recent call last): ValueError: More than one union attribute passed: 'x' and 'y' """ cdef (int, Union) a = values return a[1].x if a[0] == 1 else a[1].y cdef (int, int*) cdef_ctuple_return_type(int x, int* x_ptr): return x, x_ptr def call_cdef_ctuple_return_type(int x): """ >>> call_cdef_ctuple_return_type(2) (2, 2) """ cdef (int, int*) res = cdef_ctuple_return_type(x, &x) return res[0], res[1][0] cpdef (int, double) cpdef_ctuple_return_type(int x, double y): """ >>> cpdef_ctuple_return_type(1, 2) (1, 2.0) """ return x, y @cython.infer_types(True) def test_type_inference(): """ >>> test_type_inference() """ cdef int x = 1 cdef double y = 2 cdef object o = 3 xy = (x, y) assert cython.typeof(xy) == "(int, double)", cython.typeof(xy) xo = (x, o) assert cython.typeof(xo) == "tuple object", cython.typeof(xo) def test_equality((int, int) ab, (int, int) cd, (int, int) ef): """ >>> test_equality((1, 2), (3, 4), (5, 6)) True >>> test_equality((1, 2), (3, 4), (3, 4)) True >>> test_equality((3, 4), (3, 4), (3, 4)) False """ return ab < cd <= ef def test_equality_different_types((double, int) ab, (int, int) cd, (long, int) ef): """ >>> test_equality((1, 2), (3, 4), (5, 6)) True >>> test_equality((1, 2), (3, 4), (3, 4)) True >>> test_equality((3, 4), (3, 4), (3, 4)) False """ return ab < cd <= ef def test_binop((int, int) ab, (double, double) cd): """ >>> test_binop((1, 2), (3, 4)) (1, 2, 3.0, 4.0) """ return ab + cd def test_mul((int, int) ab, int c): """ >>> test_mul((1, 2), 3) (1, 2, 1, 2, 1, 2) """ return ab * c def test_unop((int, int) ab): """ >>> test_unop((1, 2)) True """ return not ab Cython-0.23.4/tests/run/ctruthtests.pyx0000644000175600017570000000301412606202452021306 0ustar jenkinsjenkins00000000000000def test_ptr(): """ >>> test_ptr() False """ cdef void* p = NULL if p: return True else: return False def test_ptr2(): """ >>> test_ptr2() 2 """ cdef char* p1 = NULL cdef char* p2 = NULL p1 += 1 if p1 and p2: return 1 elif p1 or p2: return 2 else: return 3 def test_int(int i): """ >>> test_int(0) False >>> test_int(1) True """ if i: return True else: return False def test_short(short i): """ >>> test_short(0) False >>> test_short(1) True """ if i: return True else: return False def test_Py_ssize_t(Py_ssize_t i): """ >>> test_Py_ssize_t(0) False >>> test_Py_ssize_t(1) True """ if i: return True else: return False cdef class TestExtInt: cdef int i def __init__(self, i): self.i = i def test_attr_int(TestExtInt e): """ >>> test_attr_int(TestExtInt(0)) False >>> test_attr_int(TestExtInt(1)) True """ if e.i: return True else: return False ctypedef union _aux: size_t i void *p cdef class TestExtPtr: cdef void* p def __init__(self, int i): cdef _aux aux aux.i = i self.p = aux.p def test_attr_ptr(TestExtPtr e): """ >>> test_attr_ptr(TestExtPtr(0)) False >>> test_attr_ptr(TestExtPtr(1)) True """ if e.p: return True else: return False Cython-0.23.4/tests/run/ct_IF.pyx0000644000175600017570000000072512606202452017704 0ustar jenkinsjenkins00000000000000DEF NO = 0 DEF YES = 1 def f(): """ >>> f() 1 """ cdef int i IF YES: i = 1 ELIF NO: i = 2 ELSE: i = 3 return i def g(): """ >>> g() 2 """ cdef int i IF NO: i = 1 ELIF YES: i = 2 ELSE: i = 3 return i def h(): """ >>> h() 3 """ cdef int i IF NO: i = 1 ELIF NO: i = 2 ELSE: i = 3 return i Cython-0.23.4/tests/run/ct_DEF.pyx0000644000175600017570000000676212606202452020013 0ustar jenkinsjenkins00000000000000 cimport cython __doc__ = u""" >>> s() b'spam' """ _unicode = unicode import sys IS_PY3 = sys.version_info[0] >= 3 if not IS_PY3: __doc__ = __doc__.replace(u" b'", u" '") def print_large_number(n): print(str(n).rstrip('L')) DEF TUPLE = (1, 2, u"buckle my shoe") DEF TRUE_FALSE = (True, False) DEF NONE = None DEF CHAR = c'x' DEF INT0 = -1 DEF INT1 = 42 DEF INT2 = 0x42 DEF INT3 = -0x42 DEF LONG = 666L DEF LARGE_NUM32 = (1 << 32) - 1 DEF LARGE_NUM64 = (1 << 64) - 1 DEF FLOAT = 12.5 DEF BYTES = b"spam" DEF UNICODE = u"spam-u" DEF TWO = TUPLE[1] DEF FIVE = TWO + 3 DEF TRUE = TRUE_FALSE[0] DEF FALSE = TRUE_FALSE[1] DEF INT_TUPLE1 = TUPLE[:2] DEF INT_TUPLE2 = TUPLE[1:4:2] DEF ELLIPSIS = ... DEF EXPRESSION = int(float(2*2)) + int(str(2)) + int(max(1,2,3)) + sum([TWO, FIVE]) def c(): """ >>> c() 120 """ cdef char c = CHAR return c def i0(): """ >>> i0() == -1 True """ cdef int i = INT0 return i def i1(): """ >>> i1() == 42 True """ cdef int i = INT1 return i def i2(): """ >>> i2() == 0x42 True """ cdef int i = INT2 return i def i3(): """ >>> i3() == -0x42 True """ cdef int i = INT3 return i def l(): """ >>> l() 666 """ cdef long l = LONG return l def large_nums(): """ >>> ul32, ul64, l64, n64 = large_nums() >>> print_large_number(ul32) 4294967295 >>> print_large_number(ul64) 18446744073709551615 >>> print_large_number(l64) 4294967295 >>> print_large_number(n64) -4294967295 """ cdef unsigned long ul32 = LARGE_NUM32 cdef unsigned long long ul64 = LARGE_NUM64 cdef long long l64 = LARGE_NUM32 cdef long long n64 = -LARGE_NUM32 return ul32, ul64, l64, n64 def f(): """ >>> f() 12.5 """ cdef float f = FLOAT return f def s(): """ see module docstring above """ cdef char* s = BYTES return s def type_of_bytes(): """ >>> t, s = type_of_bytes() >>> assert t is bytes, t >>> assert type(s) is bytes, type(s) """ t = type(BYTES) s = BYTES return t, s def type_of_unicode(): """ >>> t, s = type_of_unicode() >>> assert t is _unicode, t >>> assert type(s) is _unicode, type(s) """ t = type(UNICODE) s = UNICODE return t, s @cython.test_assert_path_exists('//TupleNode') def constant_tuple(): """ >>> constant_tuple()[:-1] (1, 2) >>> print(constant_tuple()[-1]) buckle my shoe """ cdef object t = TUPLE return t @cython.test_assert_path_exists('//IntNode') def tuple_indexing(): """ >>> tuple_indexing() 2 """ cdef int two = INT_TUPLE1[-1] return two def two(): """ >>> two() 2 """ cdef int two = TWO return two def five(): """ >>> five() 5 """ cdef int five = FIVE return five @cython.test_assert_path_exists('//BoolNode') def true(): """ >>> true() True """ cdef bint true = TRUE return true @cython.test_assert_path_exists('//BoolNode') def false(): """ >>> false() False """ cdef bint false = FALSE return false def ellipsis(): """ >>> ellipsis() Ellipsis """ return ELLIPSIS @cython.test_assert_path_exists('//IntNode') @cython.test_fail_if_path_exists('//AddNode') def expression(): """ >>> expression() 16 """ cdef int i = EXPRESSION return i def none(): """ >>> none() """ return NONE Cython-0.23.4/tests/run/cstruct.pyx0000644000175600017570000000143612606202452020407 0ustar jenkinsjenkins00000000000000cdef struct Grail cdef struct Spam: int i char c float *p[42] Grail *g cdef struct Grail: Spam *s cdef Spam spam, ham cdef void eggs_i(Spam s): cdef int j j = s.i s.i = j cdef void eggs_c(Spam s): cdef char c c = s.c s.c = c cdef void eggs_p(Spam s): cdef float *p p = s.p[0] s.p[0] = p cdef void eggs_g(Spam s): cdef float *p p = s.p[0] s.p[0] = p spam = ham def test_i(): """ >>> test_i() """ spam.i = 1 eggs_i(spam) def test_c(): """ >>> test_c() """ spam.c = c'a' eggs_c(spam) def test_p(): """ >>> test_p() """ cdef float f spam.p[0] = &f eggs_p(spam) def test_g(): """ >>> test_g() """ cdef Grail l spam.g = &l eggs_g(spam) Cython-0.23.4/tests/run/cstringmul.pyx0000644000175600017570000000025212606202452021102 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> print(spam) eggseggseggseggs >>> print(grail) tomatotomatotomatotomatotomatotomatotomato """ spam = u"eggs" * 4 grail = 7 * u"tomato" Cython-0.23.4/tests/run/cstringmeth.pyx0000644000175600017570000000014212606202452021240 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> y ('1', '2', '3') >>> x '1foo2foo3' """ y = ('1','2','3') x = 'foo'.join(y) Cython-0.23.4/tests/run/cross_closure_type_inference.pyx0000644000175600017570000000351112606202452024660 0ustar jenkinsjenkins00000000000000# mode: run # tag: typeinference cimport cython def test_outer_inner_double(): """ >>> print(test_outer_inner_double()) double """ x = 1.0 def inner(): nonlocal x x = 2.0 inner() assert x == 2.0, str(x) return cython.typeof(x) def test_outer_inner_double_int(): """ >>> print(test_outer_inner_double_int()) ('double', 'double') """ x = 1.0 y = 2 def inner(): nonlocal x, y x = 1 y = 2.0 inner() return cython.typeof(x), cython.typeof(y) def test_outer_inner_pyarg(): """ >>> print(test_outer_inner_pyarg()) 2 long """ x = 1 def inner(y): return x + y print inner(1) return cython.typeof(x) def test_outer_inner_carg(): """ >>> print(test_outer_inner_carg()) 2.0 long """ x = 1 def inner(double y): return x + y print inner(1) return cython.typeof(x) def test_outer_inner_incompatible(): """ >>> print(test_outer_inner_incompatible()) Python object """ x = 1.0 def inner(): nonlocal x x = 'test' inner() return cython.typeof(x) def test_outer_inner_ptr(): """ >>> print(test_outer_inner_ptr()) double * """ x = 1.0 xptr_outer = &x def inner(): nonlocal x x = 1 xptr_inner = &x assert cython.typeof(xptr_inner) == cython.typeof(xptr_outer), ( '%s != %s' % (cython.typeof(xptr_inner), cython.typeof(xptr_outer))) inner() return cython.typeof(xptr_outer) def test_outer_inner2_double(): """ >>> print(test_outer_inner2_double()) double """ x = 1.0 def inner1(): nonlocal x x = 2 def inner2(): nonlocal x x = 3.0 inner1() inner2() return cython.typeof(x) Cython-0.23.4/tests/run/crashT245_pxd.pxd0000644000175600017570000000011512606202452021216 0ustar jenkinsjenkins00000000000000cdef extern from "crashT245.h": ctypedef struct MyStruct: int x Cython-0.23.4/tests/run/crashT245.pyx0000644000175600017570000000022212606202452020367 0ustar jenkinsjenkins00000000000000# ticket: 245 cimport crashT245_pxd def f(): """ >>> f() {'x': 1} """ cdef crashT245_pxd.MyStruct s s.x = 1 print s Cython-0.23.4/tests/run/crashT245.h0000644000175600017570000000005112606202452017776 0ustar jenkinsjenkins00000000000000typedef struct { int x; } MyStruct; Cython-0.23.4/tests/run/cpp_vector_in_generator.pyx0000644000175600017570000000033412606202452023614 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp from libcpp.vector cimport vector def stack_vector_in_generator(vector[int] vint): """ >>> tuple( stack_vector_in_generator([1,2]) ) (1, 2) """ for i in vint: yield i Cython-0.23.4/tests/run/cpp_type_inference.pyx0000644000175600017570000000077212606202452022563 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror from cython cimport typeof from cython.operator cimport dereference as d from cython.operator cimport preincrement as incr from libcpp.vector cimport vector def test_reversed_vector_iteration(L): """ >>> test_reversed_vector_iteration([1,2,3]) int: 3 int: 2 int: 1 int """ cdef vector[int] v = L it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print('%s: %s' % (typeof(a), a)) print(typeof(a)) Cython-0.23.4/tests/run/cpp_templates_helper.h0000644000175600017570000000161112606202452022521 0ustar jenkinsjenkins00000000000000template class Wrap { T value; public: Wrap(T v) : value(v) { } void set(T v) { value = v; } T get(void) { return value; } bool operator==(Wrap other) { return value == other.value; } }; template class Pair { T1 _first; T2 _second; public: Pair() { } Pair(T1 u, T2 v) { _first = u; _second = v; } T1 first(void) { return _first; } T2 second(void) { return _second; } bool operator==(Pair other) { return _first == other._first && _second == other._second; } bool operator!=(Pair other) { return _first != other._first || _second != other._second; } }; template class SuperClass { public: SuperClass() {} }; template class SubClass : public SuperClass { }; template class Div { public: static T half(T value) { return value / 2; } }; Cython-0.23.4/tests/run/cpp_templates.pyx0000644000175600017570000000453212606202452021560 0ustar jenkinsjenkins00000000000000# tag: cpp from cython.operator import dereference as deref cdef extern from "cpp_templates_helper.h": cdef cppclass Wrap[T]: Wrap(T) void set(T) T get() bint operator==(Wrap[T]) cdef cppclass Pair[T1,T2]: Pair(T1,T2) T1 first() T2 second() bint operator==(Pair[T1,T2]) bint operator!=(Pair[T1,T2]) cdef cppclass SuperClass[T1, T2]: pass cdef cppclass SubClass[T2, T3](SuperClass[T2, T3]): pass cdef cppclass Div[T]: @staticmethod T half(T value) def test_int(int x, int y): """ >>> test_int(3, 4) (3, 4, False) >>> test_int(100, 100) (100, 100, True) """ try: a = new Wrap[int](x) b = new Wrap[int](0) b.set(y) return a.get(), b.get(), a[0] == b[0] finally: del a, b def test_double(double x, double y): """ >>> test_double(3, 3.5) (3.0, 3.5, False) >>> test_double(100, 100) (100.0, 100.0, True) """ try: a = new Wrap[double](x) b = new Wrap[double](-1) b.set(y) return a.get(), b.get(), deref(a) == deref(b) finally: del a, b def test_pair(int i, double x): """ >>> test_pair(1, 1.5) (1, 1.5, True, False) >>> test_pair(2, 2.25) (2, 2.25, True, False) """ try: pair = new Pair[int, double](i, x) return pair.first(), pair.second(), deref(pair) == deref(pair), deref(pair) != deref(pair) finally: del pair def test_ptr(int i): """ >>> test_ptr(3) 3 >>> test_ptr(5) 5 """ try: w = new Wrap[int*](&i) return deref(w.get()) finally: del w cdef double f(double x): return x*x def test_func_ptr(double x): """ >>> test_func_ptr(3) 9.0 >>> test_func_ptr(-1.5) 2.25 """ try: w = new Wrap[double (*)(double)](&f) return w.get()(x) finally: del w def test_cast_template_pointer(): """ >>> test_cast_template_pointer() """ cdef SubClass[int, float] *sub = new SubClass[int, float]() cdef SuperClass[int, float] *sup sup = sub sup = sub def test_static(x): """ >>> test_static(2) (1, 1.0) >>> test_static(3) (1, 1.5) """ return Div[int].half(x), Div[double].half(x) Cython-0.23.4/tests/run/cpp_template_subclasses_helper.h0000644000175600017570000000137512606202452024574 0ustar jenkinsjenkins00000000000000using namespace std; class Base { public: virtual const char* name() { return "Base"; } virtual ~Base() {} }; template class A : public Base { public: virtual const char* name() { return "A"; } A1 funcA(A1 x) { return x; } }; template class B : public A { public: virtual const char* name() { return "B"; } pair funcB(B1 x, B2 y) { return pair(x, y); } }; template class C : public B { public: virtual const char* name() { return "C"; } C1 funcC(C1 x) { return x; } }; template class D : public C > { virtual const char* name() { return "D"; } }; class E : public D { virtual const char* name() { return "E"; } }; Cython-0.23.4/tests/run/cpp_template_subclasses.pyx0000644000175600017570000000535412606202452023627 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror from cython.operator import dereference as deref from libcpp.pair cimport pair from libcpp.vector cimport vector cdef extern from "cpp_template_subclasses_helper.h": cdef cppclass Base: char* name() cdef cppclass A[A1](Base): A1 funcA(A1) cdef cppclass B[B1, B2](A[B2]): pair[B1, B2] funcB(B1, B2) cdef cppclass C[C1](B[long, C1]): C1 funcC(C1) cdef cppclass D[D1](C[pair[D1, D1]]): pass cdef cppclass E(D[double]): pass def testA(x): """ >>> testA(10) 10.0 """ cdef Base *base cdef A[double] *a = NULL try: a = new A[double]() base = a assert base.name() == b"A", base.name() return a.funcA(x) finally: del a def testB(x, y): """ >>> testB(1, 2) >>> testB(1, 1.5) """ cdef Base *base cdef A[double] *a cdef B[long, double] *b = NULL try: base = a = b = new B[long, double]() assert base.name() == b"B", base.name() assert a.funcA(y) == y assert b.funcB(x, y) == (x, y) finally: del b def testC(x, y): """ >>> testC(37, [1, 37]) >>> testC(25, [1, 5, 25]) >>> testC(105, [1, 3, 5, 7, 15, 21, 35, 105]) """ cdef Base *base cdef A[vector[long]] *a cdef B[long, vector[long]] *b cdef C[vector[long]] *c = NULL try: base = a = b = c = new C[vector[long]]() assert base.name() == b"C", base.name() assert a.funcA(y) == y assert b.funcB(x, y) == (x, y) assert c.funcC(y) == y finally: del c def testD(x, y): """ >>> testD(1, 1.0) >>> testD(2, 0.5) >>> testD(4, 0.25) """ cdef Base *base cdef A[pair[double, double]] *a cdef B[long, pair[double, double]] *b cdef C[pair[double, double]] *c cdef D[double] *d = NULL try: base = a = b = c = d = new D[double]() assert base.name() == b"D", base.name() assert a.funcA((y, y)) == (y, y) assert b.funcB(x, (y, y + 1)) == (x, (y, y + 1)) assert c.funcC((y, y)) == (y, y) finally: del d def testE(x, y): """ >>> testD(1, 1.0) >>> testD(2, 0.5) >>> testD(4, 0.25) """ cdef Base *base cdef A[pair[double, double]] *a cdef B[long, pair[double, double]] *b cdef C[pair[double, double]] *c cdef D[double] *d cdef E *e = NULL try: base = a = b = c = d = e = new E() assert base.name() == b"E", base.name() assert a.funcA((y, y)) == (y, y) assert b.funcB(x, (y, y + 1)) == (x, (y, y + 1)) assert c.funcC((y, y)) == (y, y) finally: del e Cython-0.23.4/tests/run/cpp_template_ref_args.pyx0000644000175600017570000000216012606202452023240 0ustar jenkinsjenkins00000000000000# tag: cpp from libcpp.vector cimport vector cdef extern from "cpp_template_ref_args.h": cdef cppclass Bar[T]: Bar() # bug: Bar[T] created before class fully defined T value Bar[T] & ref() except + const Bar[T] & const_ref() except + const Bar[T] & const_ref_const() except + cdef cppclass Foo[T]: Foo() int bar_value(Bar[int] & bar) def test_template_ref_arg(int x): """ >>> test_template_ref_arg(4) 4 """ # Templated reference parameters in method # of templated classes were not properly coalesced. cdef Foo[size_t] foo cdef Bar[int] bar bar.value = x return foo.bar_value(bar.ref()) def test_template_ref_attr(int x): """ >>> test_template_ref_attr(4) (4, 4) """ cdef Bar[int] bar bar.value = x return bar.ref().value, bar.const_ref().value def test_template_ref_const_attr(int x): """ >>> test_template_ref_const_attr(4) 4 """ cdef vector[int] v v.push_back(x) cdef const vector[int] *configs = &v cdef int value = configs.at(0) return value Cython-0.23.4/tests/run/cpp_template_ref_args.h0000644000175600017570000000053712606202452022655 0ustar jenkinsjenkins00000000000000#ifndef _TEMPLATE_ARGS_H_ #define _TEMPLATE_ARGS_H_ template struct Bar { Bar & ref() { return *this; } const Bar & const_ref() { return *this; } const Bar & const_ref_const() const { return *this; } T value; }; template struct Foo { int bar_value(const Bar & bar) { return bar.value; } }; #endif Cython-0.23.4/tests/run/cpp_template_functions_helper.h0000644000175600017570000000107412606202452024431 0ustar jenkinsjenkins00000000000000template T no_arg() { return T(); } template T one_param(T value) { return value; } template std::pair two_params(T a, U b) { return std::pair(a, b); } template class A { public: template std::pair method(T a, U b) { return std::pair(a, b); } }; template T nested_deduction(const T *a) { return *a; } template std::pair pair_arg(std::pair a) { return a; } Cython-0.23.4/tests/run/cpp_template_functions.pyx0000644000175600017570000000262412606202452023465 0ustar jenkinsjenkins00000000000000# tag: cpp from libcpp.pair cimport pair cdef extern from "cpp_template_functions_helper.h": cdef T no_arg[T]() cdef T one_param[T](T) cdef pair[T, U] two_params[T, U](T, U) cdef cppclass A[T]: pair[T, U] method[U](T, U) cdef T nested_deduction[T](const T*) pair[T, U] pair_arg[T, U](pair[T, U] a) def test_no_arg(): """ >>> test_no_arg() 0 """ return no_arg[int]() def test_one_param(int x): """ >>> test_one_param(3) (3, 3.0) """ return one_param[int](x), one_param[double](x) def test_two_params(int x, int y): """ >>> test_two_params(1, 2) (1, 2.0) """ return two_params[int, double](x, y) def test_method(int x, int y): """ >>> test_method(5, 10) ((5, 10.0), (5.0, 10)) """ cdef A[int] a_int cdef A[double] a_double return a_int.method[float](x, y), a_double.method[int](x, y) # return a_int.method[double](x, y), a_double.method[int](x, y) def test_simple_deduction(int x, double y): """ >>> test_simple_deduction(1, 2) (1, 2.0) """ return one_param(x), one_param(y) def test_more_deductions(int x, double y): """ >>> test_more_deductions(1, 2) (1, 2.0) """ return nested_deduction(&x), nested_deduction(&y) def test_class_deductions(pair[long, double] x): """ >>> test_class_deductions((1, 1.5)) (1, 1.5) """ return pair_arg(x) Cython-0.23.4/tests/run/cpp_stl_vector.pyx0000644000175600017570000000471312606202452021747 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror from cython.operator cimport dereference as d from cython.operator cimport preincrement as incr from libcpp.vector cimport vector def simple_test(double x): """ >>> simple_test(55) 3 """ v = new vector[double]() try: v.push_back(1.0) v.push_back(x) from math import pi v.push_back(pi) return v.size() finally: del v def list_test(L): """ >>> list_test([1,2,4,8]) (4, 4) >>> list_test([]) (0, 0) >>> list_test([-1] * 1000) (1000, 1000) """ v = new vector[int]() try: for a in L: v.push_back(a) return len(L), v.size() finally: del v def index_test(L): """ >>> index_test([1,2,4,8]) (1.0, 8.0) >>> index_test([1.25]) (1.25, 1.25) """ v = new vector[double]() try: for a in L: v.push_back(a) return v[0][0], v[0][len(L)-1] finally: del v def index_set_test(L): """ >>> index_set_test([1,2,4,8]) (-1.0, -8.0) >>> index_set_test([1.25]) (-1.25, -1.25) """ v = new vector[double]() try: for a in L: v.push_back(a) for i in range(v.size()): d(v)[i] = -d(v)[i] return d(v)[0], d(v)[v.size()-1] finally: del v def iteration_test(L): """ >>> iteration_test([1,2,4,8]) 1 2 4 8 """ v = new vector[int]() try: for a in L: v.push_back(a) it = v.begin() while it != v.end(): a = d(it) incr(it) print(a) finally: del v def reverse_iteration_test(L): """ >>> reverse_iteration_test([1,2,4,8]) 8 4 2 1 """ v = new vector[int]() try: for a in L: v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a) finally: del v def nogil_test(L): """ >>> nogil_test([1,2,3]) 3 """ cdef int a with nogil: v = new vector[int]() try: for a in L: with nogil: v.push_back(a) return v.size() finally: del v def item_ptr_test(L, int i, int x): """ >>> item_ptr_test(range(10), 7, 100) [0, 1, 2, 3, 4, 5, 6, 100, 8, 9] """ cdef vector[int] v = L cdef int* vi_ptr = &v[i] vi_ptr[0] = x return v Cython-0.23.4/tests/run/cpp_stl_string_ascii_auto_encoding_str.pyx0000644000175600017570000000570512606202452026713 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror # cython: c_string_encoding=ascii, c_string_type=str cimport cython from libcpp.string cimport string b_asdf = b'asdf' u_asdf = u'asdf' s_asdf = 'asdf' s_s = 's' def test_conversion(py_obj): """ >>> test_conversion(b_asdf) == s_asdf or test_conversion(b_asdf) True >>> test_conversion(u_asdf) == s_asdf or test_conversion(u_asdf) True >>> test_conversion(123) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: expected ..., int found """ cdef string s = py_obj assert len(py_obj) == s.length(), '%d != %d' % (len(py_obj), s.length()) return s def test_empty(py_obj): """ >>> test_empty('') True >>> test_empty('abc') False >>> test_empty(u_asdf[:0]) True >>> test_empty(u_asdf) False """ cdef string a = py_obj return a.empty() def test_push_back(a): """ >>> test_push_back(b_asdf) == s_asdf + s_s True >>> test_push_back(u_asdf) == s_asdf + s_s True """ cdef string s = a s.push_back(ord('s')) return s def test_clear(a): """ >>> test_clear(u_asdf) == s_s[:0] True >>> test_clear(b_asdf) == s_s[:0] True """ cdef string s = a s.clear() return s def test_assign(char *a): """ >>> test_assign(b_asdf) == 'ggg' True """ cdef string s = string(a) s.assign("ggg") return s.c_str() def test_bytes_cast(a): """ >>> b = test_bytes_cast(b'abc') >>> isinstance(b, bytes) True >>> print(b.decode('ascii')) abc >>> b = test_bytes_cast(b'abc\\xe4\\xfc') >>> isinstance(b, bytes) True >>> len(b) 5 >>> print(b[:3].decode('ascii')) abc >>> print(ord(b[3:4])) 228 >>> print(ord(b[4:5])) 252 """ cdef string s = a assert s.length() == len(a), "%d != %d" % (s.length(), len(a)) return s def test_bytearray_cast(a): """ >>> b = test_bytearray_cast(b'abc') >>> isinstance(b, bytearray) True >>> print(b.decode('ascii')) abc >>> b = test_bytearray_cast(b'abc\\xe4\\xfc') >>> isinstance(b, bytearray) True >>> len(b) 5 >>> print(b[:3].decode('ascii')) abc >>> print(ord(b[3:4])) 228 >>> print(ord(b[4:5])) 252 """ cdef string s = a assert s.length() == len(a), "%d != %d" % (s.length(), len(a)) return s def test_unicode_cast(a): """ >>> u = test_unicode_cast(b'abc') >>> type(u) is type(u_asdf) or type(u) True >>> print(u) abc """ cdef string s = a assert s.length() == len(a), "%d != %d" % (s.length(), len(a)) return s def test_str_cast(a): """ >>> s = test_str_cast(b'abc') >>> type(s) is type(s_asdf) or type(s) True >>> print(s) abc """ cdef string s = a assert s.length() == len(a), "%d != %d" % (s.length(), len(a)) return s Cython-0.23.4/tests/run/cpp_stl_string_ascii_auto_encoding.pyx0000644000175600017570000000571212606202452026021 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror # cython: c_string_encoding=ascii, c_string_type=unicode cimport cython from libcpp.string cimport string b_asdf = b'asdf' s_asdf = 'asdf' u_asdf = u'asdf' u_s = u's' def test_conversion(py_obj): """ >>> test_conversion(b_asdf) == u_asdf or test_conversion(b_asdf) True >>> test_conversion(u_asdf) == u_asdf or test_conversion(u_asdf) True >>> test_conversion(123) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: expected ..., int found """ cdef string s = py_obj assert len(py_obj) == s.length(), '%d != %d' % (len(py_obj), s.length()) return s def test_empty(py_obj): """ >>> test_empty('') True >>> test_empty('abc') False >>> test_empty(u_asdf[:0]) True >>> test_empty(u_asdf) False """ cdef string a = py_obj return a.empty() def test_push_back(a): """ >>> test_push_back(b_asdf) == u_asdf + u_s True >>> test_push_back(u_asdf) == u_asdf + u_s True """ cdef string s = a s.push_back(ord('s')) return s def test_clear(a): """ >>> test_clear(u_asdf) == u_s[:0] True >>> test_clear(b_asdf) == u_s[:0] True """ cdef string s = a s.clear() return s def test_assign(char *a): """ >>> test_assign(b_asdf) == 'ggg' True """ cdef string s = string(a) s.assign("ggg") return s.c_str() def test_bytes_cast(a): """ >>> b = test_bytes_cast(b'abc') >>> isinstance(b, bytes) True >>> print(b.decode('ascii')) abc >>> b = test_bytes_cast(b'abc\\xe4\\xfc') >>> isinstance(b, bytes) True >>> len(b) 5 >>> print(b[:3].decode('ascii')) abc >>> print(ord(b[3:4])) 228 >>> print(ord(b[4:5])) 252 """ cdef string s = a assert s.length() == len(a), "%d != %d" % (s.length(), len(a)) return s def test_bytearray_cast(a): """ >>> b = test_bytearray_cast(b'abc') >>> isinstance(b, bytearray) True >>> print(b.decode('ascii')) abc >>> b = test_bytearray_cast(b'abc\\xe4\\xfc') >>> isinstance(b, bytearray) True >>> len(b) 5 >>> print(b[:3].decode('ascii')) abc >>> print(ord(b[3:4])) 228 >>> print(ord(b[4:5])) 252 """ cdef string s = a assert s.length() == len(a), "%d != %d" % (s.length(), len(a)) return s def test_unicode_cast(a): """ >>> u = test_unicode_cast(b'abc') >>> type(u) is type(u_asdf) or type(u) True >>> print(u) abc """ cdef string s = a assert s.length() == len(a), "%d != %d" % (s.length(), len(a)) return s def test_str_cast(a): """ >>> s = test_str_cast(b'abc') >>> type(s) is type(s_asdf) or type(s) True >>> print(s) abc """ cdef string s = a assert s.length() == len(a), "%d != %d" % (s.length(), len(a)) return s Cython-0.23.4/tests/run/cpp_stl_string.pyx0000644000175600017570000001574712606202452021764 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror cimport cython from libcpp.string cimport string b_asdf = b'asdf' b_asdg = b'asdg' b_s = b's' def test_conversion(py_obj): """ >>> test_conversion(b_asdf) == b_asdf or test_conversion(b_asdf) True >>> test_conversion(123) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: expected ..., int found """ cdef string s = py_obj return s def test_indexing(char *py_str): """ >>> test_indexing(b_asdf) ('s', 's') """ cdef string s s = string(py_str) return chr(s[1]), chr(s.at(1)) def test_size(char *py_str): """ >>> test_size(b_asdf) (4, 4) """ cdef string s s = string(py_str) return s.size(), s.length() def test_compare(char *a, char *b): """ >>> test_compare(b_asdf, b_asdf) 0 >>> test_compare(b_asdf, b_asdg) < 0 True """ cdef string s = string(a) cdef string t = string(b) return s.compare(t) def test_empty(): """ >>> test_empty() (True, False) """ cdef string a = string(b"") cdef string b = string(b"aa") return a.empty(), b.empty() def test_push_back(char *a): """ >>> test_push_back(b_asdf) == b_asdf + b_s True """ cdef string s = string(a) s.push_back(ord('s')) return s.c_str() def test_insert(char *a, char *b, int i): """ >>> test_insert('AAAA'.encode('ASCII'), 'BBBB'.encode('ASCII'), 2) == 'AABBBBAA'.encode('ASCII') True """ cdef string s = string(a) cdef string t = string(b) cdef string u = s.insert(i, t) return u.c_str() def test_copy(char *a): """ >>> test_copy(b_asdf) == b_asdf[1:] True """ cdef string t = string(a) cdef char[6] buffer cdef size_t length = t.copy(buffer, 4, 1) buffer[length] = c'\0' return buffer def test_find(char *a, char *b): """ >>> test_find(b_asdf, 'df'.encode('ASCII')) 2 """ cdef string s = string(a) cdef string t = string(b) cdef size_t i = s.find(t) return i def test_clear(): """ >>> test_clear() == ''.encode('ASCII') True """ cdef string s = string("asdf") s.clear() return s.c_str() def test_assign(char *a): """ >>> test_assign(b_asdf) == 'ggg'.encode('ASCII') True """ cdef string s = string(a) s.assign("ggg") return s.c_str() def test_substr(char *a): """ >>> test_substr('ABCDEFGH'.encode('ASCII')) == ('BCDEFGH'.encode('ASCII'), 'BCDE'.encode('ASCII'), 'ABCDEFGH'.encode('ASCII')) True """ cdef string s = string(a) cdef string x, y, z x = s.substr(1) y = s.substr(1, 4) z = s.substr() return x.c_str(), y.c_str(), z.c_str() def test_append(char *a, char *b): """ >>> test_append(b_asdf, '1234'.encode('ASCII')) == b_asdf + '1234'.encode('ASCII') True """ cdef string s = string(a) cdef string t = string(b) cdef string j = s.append(t) return j.c_str() def test_char_compare(py_str): """ >>> test_char_compare(b_asdf) True """ cdef char *a = py_str cdef string b = string(a) return b.compare(b) == 0 def test_cstr(char *a): """ >>> test_cstr(b_asdf) == b_asdf True """ cdef string b = string(a) return b.c_str() @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def test_decode(char* a): """ >>> print(test_decode(b_asdf)) asdf """ cdef string b = string(a) return b.decode('ascii') @cython.test_assert_path_exists("//ReturnStatNode//PythonCapiCallNode") def test_cstr_decode(char* a): """ >>> print(test_cstr_decode(b_asdf)) asdf """ cdef string b = string(a) return b.c_str().decode('utf-8') @cython.test_assert_path_exists("//ReturnStatNode//PythonCapiCallNode") @cython.test_fail_if_path_exists("//ReturnStatNode//AttributeNode") def test_cstr_ptr_decode(char* a): """ >>> print(test_cstr_ptr_decode(b_asdf)) asdf """ cdef string b = string(a) s = b.c_str() return s.decode('utf-8') @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def test_decode_sliced(char* a): """ >>> print(test_decode_sliced(b_asdf)) sd """ cdef string b = string(a) return b[1:3].decode('ascii') @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def test_decode_sliced_negative(char* a): """ >>> a,b,c,d = test_decode_sliced_negative(b_asdf) >>> print(a) sd >>> print(b) a >>> print(c) >>> print(d) """ cdef string b = string(a) return b[-3:-1].decode('ascii'), b[-5:-3].decode('ascii'), b[-20:-4].decode('ascii'), b[-2:-20].decode('ascii') @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def test_decode_sliced_end(char* a): """ >>> a,b = test_decode_sliced_end(b_asdf) >>> print(a) asd >>> print(b) asdf """ cdef string b = string(a) return b[:3].decode('ascii'), b[:42].decode('ascii') @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def test_decode_sliced_end_negative(char* a): """ >>> a,b,c = test_decode_sliced_end_negative(b_asdf) >>> print(a) asd >>> print(b) a >>> print(c) """ cdef string b = string(a) return b[:-1].decode('ascii'), b[:-3].decode('ascii'), b[:-4].decode('ascii') @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def test_decode_sliced_start(char* a): """ >>> print(test_decode_sliced_start(b_asdf)) df """ cdef string b = string(a) return b[2:].decode('ascii') @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def test_decode_sliced_start_negative(char* a): """ >>> a,b = test_decode_sliced_start_negative(b_asdf) >>> print(a) df >>> print(b) asdf """ cdef string b = string(a) return b[-2:].decode('ascii'), b[-20:].decode('ascii') def test_equals_operator(char *a, char *b): """ >>> test_equals_operator(b_asdf, b_asdf) (True, False) """ cdef string s = string(a) cdef string t = string(b) return t == s, t != "asdf" def test_less_than(char *a, char *b): """ >>> test_less_than(b_asdf[:-1], b_asdf) (True, True, True) >>> test_less_than(b_asdf[:-1], b_asdf[:-1]) (False, False, True) """ cdef string s = string(a) cdef string t = string(b) return (s < t, s < b, s <= b) def test_greater_than(char *a, char *b): """ >>> test_greater_than(b_asdf[:-1], b_asdf) (False, False, False) >>> test_greater_than(b_asdf[:-1], b_asdf[:-1]) (False, False, True) """ cdef string s = string(a) cdef string t = string(b) return (s > t, s > b, s >= b) Cython-0.23.4/tests/run/cpp_stl_conversion.pyx0000644000175600017570000001160512606202452022630 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror # distutils: extra_compile_args=-std=c++0x import sys from libcpp.map cimport map from libcpp.unordered_map cimport unordered_map from libcpp.set cimport set as cpp_set from libcpp.unordered_set cimport unordered_set from libcpp.string cimport string from libcpp.pair cimport pair from libcpp.vector cimport vector from libcpp.list cimport list as cpp_list py_set = set py_xrange = xrange py_unicode = unicode cdef string add_strings(string a, string b): return a + b def normalize(bytes b): if sys.version_info[0] >= 3: return b.decode("ascii") else: return b def test_string(o): """ >>> normalize(test_string("abc".encode('ascii'))) 'abc' >>> normalize(test_string("abc\\x00def".encode('ascii'))) 'abc\\x00def' """ cdef string s = o return s def test_encode_to_string(o): """ >>> normalize(test_encode_to_string('abc')) 'abc' >>> normalize(test_encode_to_string('abc\\x00def')) 'abc\\x00def' """ cdef string s = o.encode('ascii') return s def test_encode_to_string_cast(o): """ >>> normalize(test_encode_to_string_cast('abc')) 'abc' >>> normalize(test_encode_to_string_cast('abc\\x00def')) 'abc\\x00def' """ s = o.encode('ascii') return s def test_unicode_encode_to_string(unicode o): """ >>> normalize(test_unicode_encode_to_string(py_unicode('abc'))) 'abc' >>> normalize(test_unicode_encode_to_string(py_unicode('abc\\x00def'))) 'abc\\x00def' """ cdef string s = o.encode('ascii') return s def test_string_call(a, b): """ >>> normalize(test_string_call("abc".encode('ascii'), "xyz".encode('ascii'))) 'abcxyz' """ return add_strings(a, b) def test_int_vector(o): """ >>> test_int_vector([1, 2, 3]) [1, 2, 3] >>> test_int_vector((1, 10, 100)) [1, 10, 100] >>> test_int_vector(py_xrange(1,10,2)) [1, 3, 5, 7, 9] >>> test_int_vector([10**20]) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef vector[int] v = o return v def test_string_vector(s): """ >>> list(map(normalize, test_string_vector('ab cd ef gh'.encode('ascii')))) ['ab', 'cd', 'ef', 'gh'] """ cdef vector[string] cpp_strings = s.split() return cpp_strings cdef list convert_string_vector(vector[string] vect): return vect def test_string_vector_temp_funcarg(s): """ >>> list(map(normalize, test_string_vector_temp_funcarg('ab cd ef gh'.encode('ascii')))) ['ab', 'cd', 'ef', 'gh'] """ return convert_string_vector(s.split()) def test_double_vector(o): """ >>> test_double_vector([1, 2, 3]) [1.0, 2.0, 3.0] >>> test_double_vector([10**20]) [1e+20] """ cdef vector[double] v = o return v def test_repeated_double_vector(a, b, int n): """ >>> test_repeated_double_vector(1, 1.5, 3) [1.0, 1.5, 1.0, 1.5, 1.0, 1.5] """ cdef vector[double] v = [a, b] * n return v ctypedef int my_int def test_typedef_vector(o): """ >>> test_typedef_vector([1, 2, 3]) [1, 2, 3] >>> test_typedef_vector([1, 2, 3**100]) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_typedef_vector([1, 2, None]) #doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: an integer is required """ cdef vector[my_int] v = o return v def test_pair(o): """ >>> test_pair((1, 2)) (1, 2.0) """ cdef pair[long, double] p = o return p def test_list(o): """ >>> test_list([1, 2, 3]) [1, 2, 3] """ cdef cpp_list[int] l = o return l def test_set(o): """ >>> sorted(test_set([1, 2, 3])) [1, 2, 3] >>> sorted(test_set([1, 2, 3, 3])) [1, 2, 3] >>> type(test_set([])) is py_set True """ cdef cpp_set[long] s = o return s def test_unordered_set(o): """ >>> sorted(test_unordered_set([1, 2, 3])) [1, 2, 3] >>> sorted(test_unordered_set([1, 2, 3, 3])) [1, 2, 3] >>> type(test_unordered_set([])) is py_set True """ cdef unordered_set[long] s = o return s def test_map(o): """ >>> test_map({1: 1.0, 2: 0.5, 3: 0.25}) {1: 1.0, 2: 0.5, 3: 0.25} """ cdef map[int, double] m = o return m def test_unordered_map(o): """ >>> test_map({1: 1.0, 2: 0.5, 3: 0.25}) {1: 1.0, 2: 0.5, 3: 0.25} """ cdef unordered_map[int, double] m = o return m def test_nested(o): """ >>> test_nested({}) {} >>> test_nested({(1.0, 2.0): [1, 2, 3], (1.0, 0.5): [1, 10, 100]}) {(1.0, 2.0): [1, 2, 3], (1.0, 0.5): [1, 10, 100]} """ cdef map[pair[double, double], vector[int]] m = o return m cpdef enum Color: RED = 0 GREEN BLUE def test_enum_map(o): """ >>> test_enum_map({RED: GREEN}) {0: 1} """ cdef map[Color, Color] m = o return m Cython-0.23.4/tests/run/cpp_stl.pyx0000644000175600017570000000242712606202452020365 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror cdef extern from "vector" namespace "std": cdef cppclass vector[T]: T at(int) void push_back(T t) void assign(int, T) void clear() int size() cppclass iterator: T operator*() iterator operator++() bint operator==(iterator) bint operator!=(iterator) iterator end() iterator begin() from cython.operator cimport dereference as deref, preincrement as inc def test_vector(L): """ >>> test_vector([1,10,100]) 1 10 100 """ v = new vector[int]() for a in L: v.push_back(a) cdef int i for i in range(len(L)): print v.at(i) del v def test_vector_iterator(L): """ >>> test_vector([11, 37, 389, 5077]) 11 37 389 5077 """ v = new vector[int]() for a in L: v.push_back(a) cdef vector[int].iterator iter = v.begin() while iter != v.end(): print deref(iter) inc(iter) del v cdef class VectorWrapper: """ >>> VectorWrapper(1, .5, .25, .125) [1.0, 0.5, 0.25, 0.125] """ cdef vector[double] vector def __init__(self, *args): self.vector = args def __repr__(self): return repr(self.vector) Cython-0.23.4/tests/run/cpp_smart_ptr_helper.h0000644000175600017570000000051412606202452022537 0ustar jenkinsjenkins00000000000000class CountAllocDealloc { public: CountAllocDealloc(int* alloc_count, int* dealloc_count) : _alloc_count(alloc_count), _dealloc_count(dealloc_count) { (*_alloc_count)++; } ~CountAllocDealloc() { (*_dealloc_count)++; } private: int* _alloc_count; int* _dealloc_count; }; Cython-0.23.4/tests/run/cpp_smart_ptr.pyx0000644000175600017570000000110012606202452021561 0ustar jenkinsjenkins00000000000000# distutils: extra_compile_args=-std=c++0x # mode: run # tag: cpp, werror from libcpp.memory cimport unique_ptr, shared_ptr cdef extern from "cpp_smart_ptr_helper.h": cdef cppclass CountAllocDealloc: CountAllocDealloc(int*, int*) def test_unique_ptr(): """ >>> test_unique_ptr() """ cdef int alloc_count = 0, dealloc_count = 0 cdef unique_ptr[CountAllocDealloc] x_ptr x_ptr.reset(new CountAllocDealloc(&alloc_count, &dealloc_count)) assert alloc_count == 1 x_ptr.reset() assert alloc_count == 1 assert dealloc_count == 1 Cython-0.23.4/tests/run/cpp_operators_helper.h0000644000175600017570000000157712606202452022554 0ustar jenkinsjenkins00000000000000#define UN_OP(op) const char* operator op () { return "unary "#op; } #define POST_UN_OP(op) const char* operator op (int x) { x++; return "post "#op; } #define BIN_OP(op) const char* operator op (int x) { x++; return "binary "#op; } #define COMMA , class TestOps { public: UN_OP(-); UN_OP(+); UN_OP(*); UN_OP(~); UN_OP(!); UN_OP(&); UN_OP(++); UN_OP(--); POST_UN_OP(++); POST_UN_OP(--); BIN_OP(+); BIN_OP(-); BIN_OP(*); BIN_OP(/); BIN_OP(%); BIN_OP(<<); BIN_OP(>>); BIN_OP(|); BIN_OP(&); BIN_OP(^); BIN_OP(COMMA); BIN_OP(==); BIN_OP(!=); BIN_OP(<=); BIN_OP(<); BIN_OP(>=); BIN_OP(>); BIN_OP([]); BIN_OP(()); }; class TruthClass { public: TruthClass() : value(false) {} TruthClass(bool value) : value(value) {} operator bool() { return value; } bool value; }; Cython-0.23.4/tests/run/cpp_operators.pyx0000644000175600017570000001121012606202452021567 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror from cython cimport typeof cimport cython.operator from cython.operator cimport dereference as deref from libc.string cimport const_char from libcpp cimport bool cdef out(s, result_type=None): print '%s [%s]' % (s.decode('ascii'), result_type) cdef extern from "cpp_operators_helper.h": cdef cppclass TestOps: const_char* operator+() const_char* operator-() const_char* operator*() const_char* operator~() const_char* operator!() const_char* operator++() const_char* operator--() const_char* operator++(int) const_char* operator--(int) const_char* operator+(int) const_char* operator-(int) const_char* operator*(int) const_char* operator/(int) const_char* operator%(int) const_char* operator|(int) const_char* operator&(int) const_char* operator^(int) const_char* operator,(int) const_char* operator<<(int) const_char* operator>>(int) const_char* operator==(int) const_char* operator!=(int) const_char* operator>=(int) const_char* operator<=(int) const_char* operator>(int) const_char* operator<(int) const_char* operator[](int) const_char* operator()(int) cppclass TruthClass: TruthClass() TruthClass(bool) bool operator bool() bool value def test_unops(): """ >>> test_unops() unary + [const_char *] unary - [const_char *] unary ~ [const_char *] unary * [const_char *] unary ! [const_char *] """ cdef TestOps* t = new TestOps() out(+t[0], typeof(+t[0])) out(-t[0], typeof(-t[0])) out(~t[0], typeof(~t[0])) x = deref(t[0]) out(x, typeof(x)) out(not t[0], typeof(not t[0])) del t def test_incdec(): """ >>> test_incdec() unary ++ [const_char *] unary -- [const_char *] post ++ [const_char *] post -- [const_char *] """ cdef TestOps* t = new TestOps() a = cython.operator.preincrement(t[0]) out(a, typeof(a)) b = cython.operator.predecrement(t[0]) out(b, typeof(b)) c = cython.operator.postincrement(t[0]) out(c, typeof(c)) d = cython.operator.postdecrement(t[0]) out(d, typeof(d)) del t def test_binop(): """ >>> test_binop() binary + [const_char *] binary - [const_char *] binary * [const_char *] binary / [const_char *] binary % [const_char *] binary & [const_char *] binary | [const_char *] binary ^ [const_char *] binary << [const_char *] binary >> [const_char *] binary COMMA [const_char *] """ cdef TestOps* t = new TestOps() out(t[0] + 1, typeof(t[0] + 1)) out(t[0] - 1, typeof(t[0] - 1)) out(t[0] * 1, typeof(t[0] * 1)) out(t[0] / 1, typeof(t[0] / 1)) out(t[0] % 1, typeof(t[0] % 1)) out(t[0] & 1, typeof(t[0] & 1)) out(t[0] | 1, typeof(t[0] | 1)) out(t[0] ^ 1, typeof(t[0] ^ 1)) out(t[0] << 1, typeof(t[0] << 1)) out(t[0] >> 1, typeof(t[0] >> 1)) x = cython.operator.comma(t[0], 1) out(x, typeof(x)) del t def test_cmp(): """ >>> test_cmp() binary == [const_char *] binary != [const_char *] binary >= [const_char *] binary > [const_char *] binary <= [const_char *] binary < [const_char *] """ cdef TestOps* t = new TestOps() out(t[0] == 1, typeof(t[0] == 1)) out(t[0] != 1, typeof(t[0] != 1)) out(t[0] >= 1, typeof(t[0] >= 1)) out(t[0] > 1, typeof(t[0] > 1)) out(t[0] <= 1, typeof(t[0] <= 1)) out(t[0] < 1, typeof(t[0] < 1)) del t def test_index_call(): """ >>> test_index_call() binary [] [const_char *] binary () [const_char *] """ cdef TestOps* t = new TestOps() out(t[0][100], typeof(t[0][100])) out(t[0](100), typeof(t[0](100))) del t def test_bool_op(): """ >>> test_bool_op() """ cdef TruthClass yes = TruthClass(True) cdef TruthClass no = TruthClass(False) if yes: pass else: assert False if no: assert False def test_bool_cond(): """ >>> test_bool_cond() """ assert (TruthClass(False) or TruthClass(False)).value == False assert (TruthClass(False) or TruthClass(True)).value == True assert (TruthClass(True) or TruthClass(False)).value == True assert (TruthClass(True) or TruthClass(True)).value == True assert (TruthClass(False) and TruthClass(False)).value == False assert (TruthClass(False) and TruthClass(True)).value == False assert (TruthClass(True) and TruthClass(False)).value == False assert (TruthClass(True) and TruthClass(True)).value == True Cython-0.23.4/tests/run/cpp_nonstdint.pyx0000644000175600017570000000570112606202452021601 0ustar jenkinsjenkins00000000000000# tag: cpp cdef extern from "cpp_nonstdint.h": ctypedef int Int24 ctypedef int Int56 ctypedef int Int88 ctypedef int Int512 cdef object one = 1 # --- INT24_MAX = (one<<(sizeof(Int24)*8-1))-one INT24_MIN = (-INT24_MAX-one) def test_int24(Int24 i): """ >>> str(test_int24(-1)) '-1' >>> str(test_int24(0)) '0' >>> str(test_int24(1)) '1' >>> test_int24(INT24_MAX) == INT24_MAX True >>> test_int24(INT24_MIN) == INT24_MIN True >>> test_int24(INT24_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_int24(INT24_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_int24("123") #doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: ... """ return i # --- INT56_MAX = (one<<(sizeof(Int56)*8-1))-one INT56_MIN = (-INT56_MAX-one) def test_int56(Int56 i): """ >>> str(test_int56(-1)) '-1' >>> str(test_int56(0)) '0' >>> str(test_int56(1)) '1' >>> test_int56(INT56_MAX) == INT56_MAX True >>> test_int56(INT56_MIN) == INT56_MIN True >>> test_int56(INT56_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_int56(INT56_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_int56("123") #doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: ... """ return i # --- INT88_MAX = (one<<(sizeof(Int88)*8-1))-one INT88_MIN = (-INT88_MAX-one) def test_int88(Int88 i): """ >>> str(test_int88(-1)) '-1' >>> str(test_int88(0)) '0' >>> str(test_int88(1)) '1' >>> test_int88(INT88_MAX) == INT88_MAX True >>> test_int88(INT88_MIN) == INT88_MIN True >>> test_int88(INT88_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_int88(INT88_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_int88("123") #doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: ... """ return i # --- INT512_MAX = (one<<(sizeof(Int512)*8-1))-one INT512_MIN = (-INT512_MAX-one) def test_int512(Int512 i): """ >>> str(test_int512(-1)) '-1' >>> str(test_int512(0)) '0' >>> str(test_int512(1)) '1' >>> test_int512(INT512_MAX) == INT512_MAX True >>> test_int512(INT512_MIN) == INT512_MIN True >>> test_int512(INT512_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_int512(INT512_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_int512("123") #doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: ... """ return i # --- Cython-0.23.4/tests/run/cpp_nonstdint.h0000644000175600017570000000671512606202452021216 0ustar jenkinsjenkins00000000000000// -*- c++ -*- #include template class Integral { unsigned char bytes[N]; public: Integral() { for (unsigned int i=0; i(const Integral &I) const { return cmp(I) > 0; } bool operator<=(const Integral &I) const { return cmp(I) <= 0; } bool operator>=(const Integral &I) const { return cmp(I) >= 0; } bool operator==(const Integral &I) const { return cmp(I) == 0; } bool operator!=(const Integral &I) const { return cmp(I) != 0; } bool operator==(const long long value) const { size_t len = sizeof(long long) > N ? sizeof(long long) : N; unsigned char* extended = new unsigned char[len]; unsigned char* other; if (sizeof(long long) < N) { resize_signed_int((unsigned char*)&value, sizeof(value), extended, len); other = bytes; } else { resize_signed_int(bytes, N, extended, len); } bool res = memcmp(extended, other, len); delete extended; return res; } bool operator!=(const long long val) const { return !(*this == val); } private: static bool is_le() { int one = 1; int b = (int)*(unsigned char *)&one; return b ? true : false; } static unsigned int lsb() { return is_le() ? 0 : N-1; } static unsigned int msb() { return is_le() ? N-1 : 0; } int cmp(const Integral& J) const { const Integral& I = *this; unsigned char sI = I.bytes[msb()] & 0x80; unsigned char sJ = J.bytes[msb()] & 0x80; if (sI > sJ) return -1; if (sI < sJ) return +1; unsigned char bI = I.bytes[msb()] & 0x7F; unsigned char bJ = J.bytes[msb()] & 0x7F; int cmpabs = 0; if (bI < bJ) cmpabs = -1; else if (bI > bJ) cmpabs = +1; else { int incr = is_le() ? -1 : 1; unsigned int i = msb() + incr; while (i != lsb()) { if (I.bytes[i] < J.bytes[i]) { cmpabs = -1; break; } if (I.bytes[i] > J.bytes[i]) { cmpabs = +1; break; } i += incr; } } if (sI) return -cmpabs; else return +cmpabs; } static void resize_signed_int(const unsigned char* src, size_t src_len, unsigned char* dst, size_t dst_len) { unsigned char msb; size_t dst_offset = 0; size_t src_offset = 0; if (is_le()) { dst_offset = 0; src_offset = 0; msb = ((unsigned char*) src)[src_len - 1]; if (src_len > dst_len) { src_len = dst_len; } } else { if (dst_len > src_len) { dst_offset = dst_len - src_len; } else { src_offset = src_len - dst_len; src_len = dst_len; } msb = ((unsigned char*) src)[0]; } if (msb & 0x80) { memset(dst, 0xFF, dst_len); } else { memset(dst, 0, dst_len); } memcpy(dst + dst_offset, src + src_offset, src_len); } }; typedef Integral<3> Int24; typedef Integral<7> Int56; typedef Integral<11> Int88; typedef Integral<64> Int512; Cython-0.23.4/tests/run/cpp_nested_templates.pyx0000644000175600017570000000240512606202452023117 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror from cython.operator cimport dereference as deref cdef extern from "cpp_templates_helper.h": cdef cppclass Wrap[T]: Wrap(T) void set(T) T get() bint operator==(Wrap[T]) cdef cppclass Pair[T1,T2]: Pair(T1,T2) T1 first() T2 second() bint operator==(Pair[T1,T2]) bint operator!=(Pair[T1,T2]) def test_wrap_pair(int i, double x): """ >>> test_wrap_pair(1, 1.5) (1, 1.5, True) >>> test_wrap_pair(2, 2.25) (2, 2.25, True) """ try: wrap = new Wrap[Pair[int, double]](Pair[int, double](i, x)) return wrap.get().first(), wrap.get().second(), deref(wrap) == deref(wrap) finally: del wrap def test_wrap_pair_pair(int i, int j, double x): """ >>> test_wrap_pair_pair(1, 3, 1.5) (1, 3, 1.5, True) >>> test_wrap_pair_pair(2, 5, 2.25) (2, 5, 2.25, True) """ try: wrap = new Wrap[Pair[int, Pair[int, double]]]( Pair[int, Pair[int, double]](i,Pair[int, double](j, x))) return (wrap.get().first(), wrap.get().second().first(), wrap.get().second().second(), deref(wrap) == deref(wrap)) finally: del wrap Cython-0.23.4/tests/run/cpp_nested_classes_support.h0000644000175600017570000000032412606202452023757 0ustar jenkinsjenkins00000000000000class A { public: class B { public: int square(int x) { return x * x; } class C { public: int cube(int x) { return x * x * x; } }; }; B* createB() { return new B(); } }; Cython-0.23.4/tests/run/cpp_nested_classes.pyx0000644000175600017570000000066312606202452022562 0ustar jenkinsjenkins00000000000000# tag: cpp cdef extern from "cpp_nested_classes_support.h": cdef cppclass A: cppclass B: int square(int) cppclass C: int cube(int) B* createB() def test(): """ >>> test() """ cdef A a cdef A.B b assert b.square(3) == 9 cdef A.B.C c assert c.cube(3) == 27 cdef A.B *b_ptr = a.createB() assert b_ptr.square(4) == 16 del b_ptr Cython-0.23.4/tests/run/cpp_namespaces_helper.h0000644000175600017570000000041312606202452022641 0ustar jenkinsjenkins00000000000000namespace outer { int x = 10; int outer_value = 10; namespace inner { int x = 100; int inner_value = 100; } } namespace A { typedef int A_t; A_t A_func(A_t first, A_t second) { return first + second; } } Cython-0.23.4/tests/run/cpp_namespaces.pyx0000644000175600017570000000124212606202452021674 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror cdef extern from "cpp_namespaces_helper.h" namespace "A": ctypedef int A_t A_t A_func(A_t first, A_t) cdef void f(A_t) cdef extern from "cpp_namespaces_helper.h" namespace "outer": int outer_value cdef extern from "cpp_namespaces_helper.h" namespace "outer::inner": int inner_value def test_function(x, y): """ >>> test_function(1, 2) 3 >>> test_function(9, 16) 25 """ return A_func(x, y) def test_nested(): """ >>> test_nested() 10 100 """ print outer_value print inner_value def test_typedef(A_t a): """ >>> test_typedef(3) 3 """ return a Cython-0.23.4/tests/run/cpp_iterators_simple.h0000644000175600017570000000036112606202452022552 0ustar jenkinsjenkins00000000000000class DoublePointerIter { public: DoublePointerIter(double* start, int len) : start_(start), len_(len) { } double* begin() { return start_; } double* end() { return start_ + len_; } private: double* start_; int len_; }; Cython-0.23.4/tests/run/cpp_iterators.pyx0000644000175600017570000000424512606202452021577 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror from libcpp.vector cimport vector from cython.operator cimport dereference as deref cdef extern from "cpp_iterators_simple.h": cdef cppclass DoublePointerIter: DoublePointerIter(double* start, int len) double* begin() double* end() def test_vector(py_v): """ >>> test_vector([1, 2, 3]) [1, 2, 3] """ cdef vector[int] v = py_v cdef vector[int] result with nogil: for item in v: result.push_back(item) return result def test_ptrs(): """ >>> test_ptrs() [1.0, 2.0, 3.0] """ cdef double a = 1 cdef double b = 2 cdef double c = 3 cdef vector[double*] v v.push_back(&a) v.push_back(&b) v.push_back(&c) return [item[0] for item in v] def test_custom(): """ >>> test_custom() [1.0, 2.0, 3.0] """ cdef double* values = [1, 2, 3] cdef DoublePointerIter* iter try: iter = new DoublePointerIter(values, 3) # TODO: It'd be nice to automatically dereference this in a way that # would not conflict with the pointer slicing iteration. return [x for x in iter[0]] finally: del iter def test_iteration_over_heap_vector(L): """ >>> test_iteration_over_heap_vector([1,2]) [1, 2] """ cdef int i cdef vector[int] *vint = new vector[int]() try: for i in L: vint.push_back(i) return [ i for i in deref(vint) ] finally: del vint def test_iteration_in_generator(vector[int] vint): """ >>> list( test_iteration_in_generator([1,2]) ) [1, 2] """ for i in vint: yield i def test_iteration_in_generator_reassigned(): """ >>> list( test_iteration_in_generator_reassigned() ) [1] """ cdef vector[int] *vint = new vector[int]() cdef vector[int] *orig_vint = vint vint.push_back(1) reassign = True try: for i in deref(vint): yield i if reassign: reassign = False vint = new vector[int]() vint.push_back(2) finally: if vint is not orig_vint: del vint del orig_vint Cython-0.23.4/tests/run/cpp_exceptions_nogil_helper.h0000644000175600017570000000010012606202452024064 0ustar jenkinsjenkins00000000000000void foo(int i) { if (i==0) return; else throw i; } Cython-0.23.4/tests/run/cpp_exceptions_nogil.pyx0000644000175600017570000001235612606202452023136 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror cdef int raise_TypeError() except *: raise TypeError("custom") cdef extern from "cpp_exceptions_nogil_helper.h" nogil: cdef void foo "foo"(int i) except + cdef void bar "foo"(int i) except +ValueError cdef void spam"foo"(int i) except +raise_TypeError cdef int foo_nogil(int i) nogil except *: foo(i) def test_foo_nogil(): """ >>> test_foo_nogil() """ foo_nogil(0) with nogil: foo_nogil(0) def test_foo(): """ >>> test_foo() """ # foo(0) foo(0) with nogil: foo(0) foo(0) # try: with nogil: foo(0) finally: pass # try: with nogil: foo(0) with nogil: foo(0) finally: pass # try: with nogil: foo(0) with nogil: foo(1) except: with nogil: foo(0) finally: with nogil: foo(0) pass # try: with nogil: foo(0) foo(0) finally: pass # try: with nogil: foo(0) foo(1) except: with nogil: foo(0) finally: with nogil: foo(0) pass # try: with nogil: foo(0) try: with nogil: foo(1) except: with nogil: foo(1) finally: with nogil: foo(0) pass except: with nogil: foo(0) finally: with nogil: foo(0) pass # try: with nogil: foo(0) try: with nogil: foo(1) except: with nogil: foo(1) finally: with nogil: foo(1) pass except: with nogil: foo(0) finally: with nogil: foo(0) pass # def test_bar(): """ >>> test_bar() """ # bar(0) bar(0) with nogil: bar(0) bar(0) # try: with nogil: bar(0) finally: pass # try: with nogil: bar(0) with nogil: bar(0) finally: pass # try: with nogil: bar(0) with nogil: bar(1) except ValueError: with nogil: bar(0) finally: with nogil: bar(0) pass # try: with nogil: bar(0) bar(0) finally: pass # try: with nogil: bar(0) bar(1) except ValueError: with nogil: bar(0) finally: with nogil: bar(0) pass # try: with nogil: bar(0) try: with nogil: bar(1) except ValueError: with nogil: bar(1) finally: with nogil: bar(0) pass except ValueError: with nogil: bar(0) finally: with nogil: bar(0) pass # try: with nogil: bar(0) try: with nogil: bar(1) except ValueError: with nogil: bar(1) finally: with nogil: bar(1) pass except ValueError: with nogil: bar(0) finally: with nogil: bar(0) pass # def test_spam(): """ >>> test_spam() """ # spam(0) spam(0) with nogil: spam(0) spam(0) # try: with nogil: spam(0) finally: pass # try: with nogil: spam(0) with nogil: spam(0) finally: pass # try: with nogil: spam(0) with nogil: spam(1) except TypeError: with nogil: spam(0) finally: with nogil: spam(0) pass # try: with nogil: spam(0) spam(0) finally: pass # try: with nogil: spam(0) spam(1) except TypeError: with nogil: spam(0) finally: with nogil: spam(0) pass # try: with nogil: spam(0) try: with nogil: spam(1) except TypeError: with nogil: spam(1) finally: with nogil: spam(0) pass except TypeError: with nogil: spam(0) finally: with nogil: spam(0) pass # try: with nogil: spam(0) try: with nogil: spam(1) except TypeError: with nogil: spam(1) finally: with nogil: spam(1) pass except TypeError: with nogil: spam(0) finally: with nogil: spam(0) pass # Cython-0.23.4/tests/run/cpp_exceptions_helper.h0000644000175600017570000000232112606202452022703 0ustar jenkinsjenkins00000000000000#include #include #include int raise_int(int fire) { if (fire) { throw 1; } return 0; } int raise_index(int fire) { if (fire) { throw std::out_of_range("c++ error"); } return 0; } class Foo { public: int bar(int fire) { if (fire) { throw 1; } return 0; } }; void raise_domain_error() { throw std::domain_error("domain_error"); } void raise_ios_failure() { throw std::ios_base::failure("iostream failure"); } void raise_memory() { // std::bad_alloc can only be default constructed, // so we have no control over the error message throw std::bad_alloc(); } void raise_overflow() { throw std::overflow_error("overflow_error"); } void raise_range_error() { throw std::range_error("range_error"); } struct Base { virtual ~Base() {} }; struct Derived : Base { void use() const { abort(); } }; void raise_typeerror() { Base foo; Base &bar = foo; // prevents "dynamic_cast can never succeed" warning Derived &baz = dynamic_cast(bar); baz.use(); // not reached; prevents "unused variable" warning } void raise_underflow() { throw std::underflow_error("underflow_error"); } Cython-0.23.4/tests/run/cpp_exceptions.pyx0000644000175600017570000001114612606202452021742 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror cdef int raise_py_error() except *: raise TypeError("custom") cdef extern from "cpp_exceptions_helper.h": cdef int raise_int_raw "raise_int"(bint fire) except + cdef int raise_int_value "raise_int"(bint fire) except +ValueError cdef int raise_int_custom "raise_int"(bint fire) except +raise_py_error cdef int raise_index_raw "raise_index"(bint fire) except + cdef int raise_index_value "raise_index"(bint fire) except +ValueError cdef int raise_index_custom "raise_index"(bint fire) except +raise_py_error cdef void raise_domain_error() except + cdef void raise_ios_failure() except + cdef void raise_memory() except + cdef void raise_overflow() except + cdef void raise_range_error() except + cdef void raise_typeerror() except + cdef void raise_underflow() except + cdef cppclass Foo: int bar_raw "bar"(bint fire) except + int bar_value "bar"(bint fire) except +ValueError int bar_custom "bar"(bint fire) except +raise_py_error def test_domain_error(): """ >>> test_domain_error() Traceback (most recent call last): ... ValueError: domain_error """ raise_domain_error() def test_ios_failure(): """ >>> try: test_ios_failure() ... except (IOError, OSError): pass """ raise_ios_failure() def test_memory(): """ >>> test_memory() Traceback (most recent call last): ... MemoryError """ # Re-raise the exception without a description string because we can't # rely on the implementation-defined value of what() in the doctest. try: raise_memory() except MemoryError: raise MemoryError def test_overflow(): """ >>> test_overflow() Traceback (most recent call last): ... OverflowError: overflow_error """ raise_overflow() def test_range_error(): """ >>> test_range_error() Traceback (most recent call last): ... ArithmeticError: range_error """ raise_range_error() def test_typeerror(): """ >>> test_typeerror() Traceback (most recent call last): ... TypeError """ # Re-raise the exception without a description string because we can't # rely on the implementation-defined value of what() in the doctest. try: raise_typeerror() except TypeError: raise TypeError def test_underflow(): """ >>> test_underflow() Traceback (most recent call last): ... ArithmeticError: underflow_error """ raise_underflow() def test_int_raw(bint fire): """ >>> test_int_raw(False) >>> test_int_raw(True) Traceback (most recent call last): ... RuntimeError: Unknown exception """ raise_int_raw(fire) def test_int_value(bint fire): """ >>> test_int_value(False) >>> test_int_value(True) Traceback (most recent call last): ... ValueError """ raise_int_value(fire) def test_int_custom(bint fire): """ >>> test_int_custom(False) >>> test_int_custom(True) Traceback (most recent call last): ... TypeError: custom """ raise_int_custom(fire) def test_index_raw(bint fire): """ >>> test_index_raw(False) >>> test_index_raw(True) Traceback (most recent call last): ... IndexError: c++ error """ raise_index_raw(fire) def test_index_value(bint fire): """ >>> test_index_value(False) >>> test_index_value(True) Traceback (most recent call last): ... ValueError: c++ error """ raise_index_value(fire) def test_index_custom(bint fire): """ >>> test_index_custom(False) >>> test_index_custom(True) Traceback (most recent call last): ... TypeError: custom """ raise_index_custom(fire) def test_cppclass_method_raw(bint fire): """ >>> test_cppclass_method_raw(False) >>> test_cppclass_method_raw(True) Traceback (most recent call last): ... RuntimeError: Unknown exception """ foo = new Foo() try: foo.bar_raw(fire) finally: del foo def test_cppclass_method_value(bint fire): """ >>> test_cppclass_method_value(False) >>> test_cppclass_method_value(True) Traceback (most recent call last): ... ValueError """ foo = new Foo() try: foo.bar_value(fire) finally: del foo def test_cppclass_method_custom(bint fire): """ >>> test_cppclass_method_custom(False) >>> test_cppclass_method_custom(True) Traceback (most recent call last): ... TypeError: custom """ foo = new Foo() try: foo.bar_custom(fire) finally: del foo Cython-0.23.4/tests/run/cpp_exception_declaration_compatibility.srctree0000644000175600017570000000125312606202452027702 0ustar jenkinsjenkins00000000000000# tag: cpp """ PYTHON setup.py build_ext -i PYTHON test.py """ ############### setup.py ################### from distutils.core import setup from Cython.Build import cythonize setup( name="cython_test", ext_modules=cythonize('*.pyx', language="c++") ) ############### test.py ################### from cpp_exc import TestClass TestClass().test_func() ############### cpp_exc.pxd ################### cdef inline void handle_exception(): pass cdef class TestClass: cpdef test_func(self) except +handle_exception ############### cpp_exc.pyx ################### cdef class TestClass: cpdef test_func(self) except +handle_exception: print('test') Cython-0.23.4/tests/run/cpp_custom_string.srctree0000644000175600017570000000245712606202452023315 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror PYTHON setup.py build_ext --inplace PYTHON -c "import a; a.test_convert()" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from Cython.Compiler import PyrexTypes PyrexTypes.cpp_string_conversions += ("MyString", "MyString2") from distutils.core import setup setup( ext_modules = cythonize("*.pyx"), ) ######## my_string.cpp ######## #include class MyString { public: MyString() { } MyString(const char* data, size_t size) : value_(data, size) { } const char* data() const { return value_.data(); } const size_t size() const { return value_.size(); } private: std::string value_; }; class MyString2 : public MyString { public: MyString2() : MyString() { } MyString2(const char* data, size_t size) : MyString(data, size) { } }; ######## a.pyx ######## # distutils: language = c++ cdef extern from "my_string.cpp": cdef cppclass MyString: pass cdef extern from "my_string.cpp": cdef cppclass MyString2: pass def do_convert(MyString value): return value def do_convert2(MyString2 value): return value def test_convert(): assert do_convert(b"abc") == b"abc" assert do_convert(b"ab\0c") == b"ab\0c" assert do_convert2(b"abc") == b"abc" assert do_convert2(b"ab\0c") == b"ab\0c" Cython-0.23.4/tests/run/cpp_const_method.pyx0000644000175600017570000000370712606202452022253 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror # cython: experimental_cpp_class_def=True from libcpp.vector cimport vector cdef cppclass Wrapper[T]: T value __init__(T &value): this.value = value void set(T &value): this.value = value T get() const: return this.value def test_const_get(int x): """ >>> test_const_get(10) 10 """ cdef const Wrapper[int] *wrapper = new Wrapper[int](x) try: return const_get(wrapper[0]) finally: del wrapper cdef int const_get(const Wrapper[int] wrapper): return wrapper.get() def test_const_ref_get(int x): """ >>> test_const_ref_get(100) 100 """ cdef const Wrapper[int] *wrapper = new Wrapper[int](x) try: return const_ref_get(wrapper[0]) finally: del wrapper cdef int const_ref_get(const Wrapper[int] &wrapper): return wrapper.get() def test_const_pointer_get(int x): """ >>> test_const_pointer_get(1000) 1000 """ cdef Wrapper[int] *wrapper = new Wrapper[int](x) cdef const Wrapper[int] *const_wrapper = wrapper try: return const_wrapper.get() finally: del wrapper # TODO: parse vector[Wrapper[int]*] ctypedef Wrapper[int] wrapInt def test_vector_members(py_a, py_b): """ >>> test_vector_members([1, 2, 3], [4,5, 6]) ([1, 2, 3], 4) """ cdef Wrapper[int] *value cdef const Wrapper[int] *const_value cdef vector[const Wrapper[int]*] a cdef vector[wrapInt*] b for x in py_a: a.push_back(new Wrapper[int](x)) for x in py_b: b.push_back(new Wrapper[int](x)) try: return vector_members(a, b) finally: for const_value in a: del const_value for value in b: del value cdef vector_members(vector[const Wrapper[int]*] a, const vector[wrapInt*] b): # TODO: Cython-level error. # b[0].set(100) # TODO: const_iterator return [x.get() for x in a], b[0].get() Cython-0.23.4/tests/run/cpp_classes_def.pyx0000644000175600017570000000465012606202452022036 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror # cython: experimental_cpp_class_def=True cdef double pi from math import pi from libc.math cimport sin, cos cdef extern from "shapes.h" namespace "shapes": cdef cppclass Shape: float area() const cdef cppclass RegularPolygon(Shape): float radius # major int n __init__(int n, float radius): this.n = n this.radius = radius float area() const: cdef double theta = pi / this.n return this.radius * this.radius * sin(theta) * cos(theta) * this.n def test_Poly(int n, float radius=1): """ >>> test_Poly(4) 2.0 >>> test_Poly(3) #doctest: +ELLIPSIS 1.29903... >>> test_Poly(3, 10.0) #doctest: +ELLIPSIS 129.903... >>> test_Poly(100) #doctest: +ELLIPSIS 3.13952... >>> test_Poly(1000) #doctest: +ELLIPSIS 3.14157... """ cdef RegularPolygon* poly try: poly = new RegularPolygon(n, radius) poly.n = n poly.radius = radius return poly.area() finally: del poly cdef cppclass WithStatic: @staticmethod double square(double x): return x * x def test_Static(x): """ >>> test_Static(2) 4.0 >>> test_Static(0.5) 0.25 """ return WithStatic.square(x) cdef cppclass InitDealloc: __init__(): try: print "Init" finally: return # swallow any exceptions __dealloc__(): try: print "Dealloc" finally: return # swallow any exceptions def test_init_dealloc(): """ >>> test_init_dealloc() start Init live Dealloc end """ print "start" cdef InitDealloc *ptr = new InitDealloc() print "live" del ptr print "end" cdef cppclass WithTemplate[T]: T value void set_value(T value): this.value = value T get_value(): return this.value cdef cppclass ResolveTemplate(WithTemplate[long]): pass def test_templates(long value): """ >>> test_templates(10) >>> test_templates(-2) """ cdef WithTemplate[long] *base = new WithTemplate[long]() del base cdef ResolveTemplate *resolved = new ResolveTemplate() resolved.set_value(value) assert resolved.value == resolved.get_value() == value, resolved.value base = resolved base.set_value(2 * value) assert base.get_value() == base.value == 2 * value, base.value del base Cython-0.23.4/tests/run/cpp_classes.pyx0000644000175600017570000001021612606202452021213 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror from libcpp.vector cimport vector cdef extern from "shapes.h" namespace "shapes": cdef cppclass Shape: float area() cdef cppclass Ellipse(Shape): Ellipse(int a, int b) except + cdef cppclass Circle(Ellipse): int radius Circle(int r) except + cdef cppclass Rectangle(Shape): int width int height Rectangle() except + Rectangle(int h, int w) except + int method(int x) int method(bint b) cdef cppclass Square(Rectangle): int side Square(int s) except + cdef cppclass Empty(Shape): pass int constructor_count, destructor_count def test_new_del(): """ >>> test_new_del() 2 0 2 2 """ c,d = constructor_count, destructor_count cdef Rectangle *rect = new Rectangle(10, 20) cdef Circle *circ = new Circle(15) print constructor_count-c, destructor_count-d del rect, circ print constructor_count-c, destructor_count-d def test_default_constructor(): """ >>> test_default_constructor() 0.0 """ shape = new Empty() try: return shape.area() finally: del shape def test_rect_area(w, h): """ >>> test_rect_area(3, 4) 12.0 """ cdef Rectangle *rect = new Rectangle(w, h) try: return rect.area() finally: del rect def test_overload_bint_int(): """ >>> test_overload_bint_int() 202 201 """ cdef Rectangle *rect1 = new Rectangle(10, 20) cdef Rectangle *rect2 = new Rectangle(10, 20) try: print rect1.method( 2) print rect2.method( True) finally: del rect1 del rect2 def test_square_area(w): """ >>> test_square_area(15) (225.0, 225.0) """ cdef Square *sqr = new Square(w) cdef Rectangle *rect = sqr try: return rect.area(), sqr.area() finally: del sqr cdef double get_area(Rectangle s): return s.area() def test_value_call(int w): """ >>> test_value_call(5) (25.0, 25.0) """ cdef Square *sqr = new Square(w) cdef Rectangle *rect = sqr try: return get_area(sqr[0]), get_area(rect[0]) finally: del sqr def get_destructor_count(): return destructor_count def test_stack_allocation(int w, int h): """ >>> d = test_stack_allocation(10, 12) 125 >>> get_destructor_count() - d 1 """ cdef Rectangle rect rect.width = w rect.height = h print rect.method(5) return destructor_count cdef class EmptyHolder: cdef Empty empty cdef class AnotherEmptyHolder(EmptyHolder): cdef Empty another_empty def test_class_member(): """ >>> test_class_member() """ start_constructor_count = constructor_count start_destructor_count = destructor_count e1 = EmptyHolder() assert constructor_count - start_constructor_count == 1, \ constructor_count - start_constructor_count e2 = EmptyHolder() assert constructor_count - start_constructor_count == 2, \ constructor_count - start_constructor_count del e1, e2 assert destructor_count - start_destructor_count == 2, \ destructor_count - start_destructor_count def test_derived_class_member(): """ >>> test_derived_class_member() """ start_constructor_count = constructor_count start_destructor_count = destructor_count e = AnotherEmptyHolder() assert constructor_count - start_constructor_count == 2, \ constructor_count - start_constructor_count del e assert destructor_count - start_destructor_count == 2, \ destructor_count - start_destructor_count cdef class TemplateClassMember: cdef vector[int] x cdef vector[vector[Empty]] vec def test_template_class_member(): """ >>> test_template_class_member() """ cdef vector[Empty] inner inner.push_back(Empty()) inner.push_back(Empty()) o = TemplateClassMember() o.vec.push_back(inner) start_destructor_count = destructor_count del o assert destructor_count - start_destructor_count == 2, \ destructor_count - start_destructor_count Cython-0.23.4/tests/run/cpp_class_redef.pyx0000644000175600017570000000061012606202452022025 0ustar jenkinsjenkins00000000000000# tag: cpp # This gives a warning, but should not give an error. cdef cppclass Foo: int _foo int get_foo(): return this._foo void set_foo(int foo): this._foo = foo def test_Foo(n): """ >>> test_Foo(1) 1 """ cdef Foo* foo = NULL try: foo = new Foo() foo.set_foo(n) return foo.get_foo() finally: del foo Cython-0.23.4/tests/run/cpp_class_redef.pxd0000644000175600017570000000015312606202452022002 0ustar jenkinsjenkins00000000000000# tag: cpp cdef extern cppclass Foo: int _foo void set_foo(int foo) nogil int get_foo() nogil Cython-0.23.4/tests/run/cpp_call_stack_allocated.srctree0000644000175600017570000000211412606202452024513 0ustar jenkinsjenkins00000000000000# tag: cpp """ PYTHON setup.py build_ext --inplace PYTHON -c "from call_stack_allocated import test; test()" """ ######## setup.py ######## from distutils.core import setup from Cython.Build import cythonize setup(ext_modules=cythonize('*.pyx', language='c++')) ######## call.cpp ######## class wint { public: long long val; wint() { val = 0; } wint(long long val) { this->val = val; } long long &operator()() { return this->val; } long long operator()(long long i) { return this->val + i; } long long operator()(long long i, long long j) { return this->val + i + j; } }; ######## call.pxd ######## cdef extern from "call.cpp" nogil: cppclass wint: long long val wint() wint(long long val) long long& operator()() long long operator()(long long i) long long operator()(long long i, long long j) ######## call_stack_allocated.pyx ######## from call cimport wint def test(): cdef wint a = wint(4) cdef long long b = 3 b = a() assert b == 4 b = a(1ll) assert b == 5 b = a(1ll, 1ll) assert b == 6 Cython-0.23.4/tests/run/cpp_bool.pyx0000644000175600017570000000045612606202452020516 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp, werror from libcpp cimport bool def test_bool(bool a): """ >>> test_bool(True) True >>> test_bool(1) True >>> test_bool(0) False >>> test_bool(100) True >>> test_bool(None) False >>> test_bool([]) False """ return a Cython-0.23.4/tests/run/cpp_assignment_overload.srctree0000644000175600017570000000250612606202452024453 0ustar jenkinsjenkins00000000000000# mode: run # tag: cpp """ PYTHON setup.py build_ext --inplace PYTHON -c "from assignment_overload import test; test()" """ ######## setup.py ######## from distutils.core import setup from Cython.Build import cythonize setup(ext_modules=cythonize("*.pyx", language='c++')) ######## assign.cpp ######## class wrapped_int { public: long long val; wrapped_int() { val = 0; } wrapped_int(long long val) { this->val = val; } wrapped_int &operator=(const wrapped_int &other) { this->val = other.val; return *this; } wrapped_int &operator=(const long long val) { this->val = val; return *this; } }; ######## assign.pxd ######## cdef extern from "assign.cpp" nogil: cppclass wrapped_int: long long val wrapped_int() wrapped_int(long long val) wrapped_int& operator=(const wrapped_int &other) wrapped_int& operator=(const long long &other) ######## assignment_overload.pyx ######## from assign cimport wrapped_int def test(): cdef wrapped_int a = wrapped_int(2) cdef wrapped_int b = wrapped_int(3) cdef long long c = 4 assert &a != &b assert a.val != b.val a = b assert &a != &b assert a.val == b.val a = c assert a.val == c a, b, c = 2, 3, 4 a = b = c assert &a != &b assert a.val == b.val assert b.val == c Cython-0.23.4/tests/run/cpdef_temps_T411.pyx0000644000175600017570000000053612606202452021722 0ustar jenkinsjenkins00000000000000# ticket: 411 cdef class A: """ >>> A().is_True() True >>> A().is_False() False """ cpdef is_True(self): return True cpdef is_False(self): return not self.is_True() class B(A): """ >>> B().is_True() True >>> B().is_False() False """ def is_True(self): return True Cython-0.23.4/tests/run/cpdef_extern_func_in_py.py0000644000175600017570000000044312606202452023404 0ustar jenkinsjenkins00000000000000 """ >>> pxd_sqrt(9) 3.0 """ import cython if not cython.compiled: from math import sqrt as pxd_sqrt @cython.test_assert_path_exists('//SimpleCallNode/NameNode[@type.is_pyobject = False]') def call_pxd_sqrt(x): """ >>> call_pxd_sqrt(9) 3.0 """ return pxd_sqrt(x) Cython-0.23.4/tests/run/cpdef_extern_func_in_py.pxd0000644000175600017570000000010512606202452023542 0ustar jenkinsjenkins00000000000000 cdef extern from "math.h": cpdef double pxd_sqrt "sqrt"(double) Cython-0.23.4/tests/run/cpdef_extern_func.pyx0000644000175600017570000000116412606202452022377 0ustar jenkinsjenkins00000000000000# cython: c_string_type=str # cython: c_string_encoding=ascii __doc__ = """ >>> sqrt(1) 1.0 >>> pyx_sqrt(4) 2.0 >>> pxd_sqrt(9) 3.0 >>> log(10) # doctest: +ELLIPSIS Traceback (most recent call last): NameError: ...name 'log' is not defined >>> strchr('abcabc', ord('c')) 'cabc' >>> strchr(needle=ord('c'), haystack='abcabc') 'cabc' """ cdef extern from "math.h": cpdef double sqrt(double) cpdef double pyx_sqrt "sqrt"(double) cdef double log(double) # not wrapped cdef extern from "string.h": # signature must be exact in C++, disagrees with C cpdef const char* strchr(const char *haystack, int needle); Cython-0.23.4/tests/run/cpdef_extern_func.pxd0000644000175600017570000000020312606202452022343 0ustar jenkinsjenkins00000000000000# cython: c_string_type=str # cython: c_string_encoding=ascii cdef extern from "math.h": cpdef double pxd_sqrt "sqrt"(double) Cython-0.23.4/tests/run/cpdef_enums_import.srctree0000644000175600017570000000135112606202452023425 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import import_enums_test" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize(["enums.pyx", "no_enums.pyx"]), ) ######## enums.pyx ######## cpdef enum: BAR cpdef foo(): pass ######## enums.pxd ######## cpdef enum: FOO cpdef foo() ######## no_enums.pyx ######## from enums cimport * ######## import_enums_test.py ######## # We can import enums with a star import. from enums import * print(dir()) assert 'BAR' in dir() and 'FOO' in dir() # enums not generated in the wrong module import no_enums print(dir(no_enums)) assert 'FOO' not in dir(no_enums) assert 'foo' not in dir(no_enums) Cython-0.23.4/tests/run/cpdef_enums.pyx0000644000175600017570000000177312606202452021214 0ustar jenkinsjenkins00000000000000""" >>> ONE, TEN, HUNDRED (1, 10, 100) >>> THOUSAND # doctest: +ELLIPSIS Traceback (most recent call last): NameError: ...name 'THOUSAND' is not defined >>> TWO == 2 or TWO True >>> THREE == 3 or THREE True >>> FIVE == 5 or FIVE True >>> SEVEN # doctest: +ELLIPSIS Traceback (most recent call last): NameError: ...name 'SEVEN' is not defined >>> FOUR == 4 or FOUR True >>> EIGHT == 8 or EIGHT True >>> SIXTEEN # doctest: +ELLIPSIS Traceback (most recent call last): NameError: ...name 'SIXTEEN' is not defined >>> RANK_0 == 11 or RANK_0 True >>> RANK_1 == 37 or RANK_1 True >>> RANK_2 == 389 or RANK_2 True >>> RANK_3 # doctest: +ELLIPSIS Traceback (most recent call last): NameError: ...name 'RANK_3' is not defined """ cdef extern from *: cpdef enum: # ExternPyx ONE "1" TEN "10" HUNDRED "100" cdef enum: # ExternSecretPyx THOUSAND "1000" cpdef enum PyxEnum: TWO = 2 THREE = 3 FIVE = 5 cdef enum SecretPyxEnum: SEVEN = 7 Cython-0.23.4/tests/run/cpdef_enums.pxd0000644000175600017570000000037412606202452021163 0ustar jenkinsjenkins00000000000000cdef extern from *: cpdef enum: # ExternPxd FOUR "4" EIGHT "8" cdef enum: # ExternSecretPxd SIXTEEN "16" cpdef enum PxdEnum: RANK_0 = 11 RANK_1 = 37 RANK_2 = 389 cdef enum PxdSecretEnum: RANK_3 = 5077 Cython-0.23.4/tests/run/cpdef.pyx0000644000175600017570000000110412606202452017771 0ustar jenkinsjenkins00000000000000cpdef void unraisable(): """ >>> unraisable() here """ print('here') raise RuntimeError() cpdef void raisable() except *: """ >>> raisable() Traceback (most recent call last): ... RuntimeError """ print('here') raise RuntimeError() cdef class A: """ >>> A().foo() A """ cpdef void foo(self): print "A" cdef class B(A): """ >>> B().foo() B """ cpdef void foo(self): print "B" class C(B): """ >>> C().foo() C """ def foo(self): print "C" Cython-0.23.4/tests/run/coverage_nogil.srctree0000644000175600017570000000455112606202452022533 0ustar jenkinsjenkins00000000000000# mode: run # tag: coverage,trace,nogil """ PYTHON setup.py build_ext -i PYTHON coverage_test.py """ ######## setup.py ######## from distutils.core import setup from Cython.Build import cythonize setup(ext_modules = cythonize([ 'coverage_test_*.pyx', ])) ######## .coveragerc ######## [run] plugins = Cython.Coverage ######## coverage_test_nogil.pyx ######## # cython: linetrace=True # distutils: define_macros=CYTHON_TRACE=1 CYTHON_TRACE_NOGIL=1 cdef int func1(int a, int b) nogil: cdef int x # 5 with gil: # 6 x = 1 # 7 cdef int c = func2(a) + b # 8 return x + c # 9 cdef int func2(int a) with gil: return a * 2 # 13 def call(int a, int b): a, b = b, a # 17 with nogil: # 18 result = func1(b, a) # 19 return result # 20 ######## coverage_test.py ######## import os.path try: # io.StringIO in Py2.x cannot handle str ... from StringIO import StringIO except ImportError: from io import StringIO from coverage import coverage import coverage_test_nogil assert not any(coverage_test_nogil.__file__.endswith(ext) for ext in '.py .pyc .pyo .pyw .pyx .pxi'.split()), \ coverage_test_nogil.__file__ def run_coverage(module): module_name = module.__name__ module_path = module_name + '.pyx' cov = coverage() cov.start() assert module.call(1, 2) == (1 * 2) + 2 + 1 cov.stop() out = StringIO() cov.report(file=out) #cov.report([module], file=out) lines = out.getvalue().splitlines() assert any(module_path in line for line in lines), \ "'%s' not found in coverage report:\n\n%s" % (module_path, out.getvalue()) mod_file, exec_lines, excl_lines, missing_lines, _ = cov.analysis2(os.path.abspath(module_path)) assert module_path in mod_file executed = set(exec_lines) - set(missing_lines) # check that everything that runs with the gil owned was executed assert all(line in executed for line in [13, 17, 18, 20]), '%s / %s' % (exec_lines, missing_lines) # check that everything that runs in nogil sections was executed assert all(line in executed for line in [6, 7, 8, 9]), '%s / %s' % (exec_lines, missing_lines) if __name__ == '__main__': run_coverage(coverage_test_nogil) Cython-0.23.4/tests/run/coverage_cmd.srctree0000644000175600017570000001335012606202452022163 0ustar jenkinsjenkins00000000000000# mode: run # tag: coverage,trace """ PYTHON -c 'import shutil; shutil.copy("pkg/coverage_test_pyx.pyx", "pkg/coverage_test_pyx.pxi")' PYTHON setup.py build_ext -i PYTHON -m coverage run coverage_test.py PYTHON collect_coverage.py """ ######## setup.py ######## from distutils.core import setup from Cython.Build import cythonize setup(ext_modules = cythonize([ 'coverage_test_*.py*', 'pkg/coverage_test_*.py*' ])) ######## .coveragerc ######## [run] plugins = Cython.Coverage ######## pkg/__init__.py ######## ######## pkg/coverage_test_py.py ######## # cython: linetrace=True # distutils: define_macros=CYTHON_TRACE=1 def func1(a, b): x = 1 # 5 c = func2(a) + b # 6 return x + c # 7 def func2(a): return a * 2 # 11 ######## pkg/coverage_test_pyx.pyx ######## # cython: linetrace=True # distutils: define_macros=CYTHON_TRACE=1 def func1(int a, int b): cdef int x = 1 # 5 c = func2(a) + b # 6 return x + c # 7 def func2(int a): return a * 2 # 11 ######## coverage_test_include_pyx.pyx ######## # cython: linetrace=True # distutils: define_macros=CYTHON_TRACE=1 cdef int x = 5 # 4 cdef int cfunc1(int x): # 6 return x * 3 # 7 include "pkg/coverage_test_pyx.pxi" # 9 def main_func(int x): # 11 return cfunc1(x) + func1(x, 4) + func2(x) # 12 ######## coverage_test.py ######## import os.path try: # io.StringIO in Py2.x cannot handle str ... from StringIO import StringIO except ImportError: from io import StringIO from pkg import coverage_test_py from pkg import coverage_test_pyx import coverage_test_include_pyx for module in [coverage_test_py, coverage_test_pyx, coverage_test_include_pyx]: assert not any(module.__file__.endswith(ext) for ext in '.py .pyc .pyo .pyw .pyx .pxi'.split()), \ module.__file__ def run_coverage(module): module_name = module.__name__ module_path = module_name.replace('.', os.path.sep) + '.' + module_name.rsplit('_', 1)[-1] assert module.func1(1, 2) == (1 * 2) + 2 + 1 assert module.func2(2) == 2 * 2 if '_include_' in module_name: assert module.main_func(2) == (2 * 3) + ((2 * 2) + 4 + 1) + (2 * 2) if __name__ == '__main__': run_coverage(coverage_test_py) run_coverage(coverage_test_pyx) run_coverage(coverage_test_include_pyx) ######## collect_coverage.py ######## import re import sys import os import os.path import subprocess from glob import iglob def run_coverage_command(*command): env = dict(os.environ, LANG='', LC_ALL='C') process = subprocess.Popen( [sys.executable, '-m', 'coverage'] + list(command), stdout=subprocess.PIPE, env=env) stdout, _ = process.communicate() return stdout def run_report(): stdout = run_coverage_command('report', '--show-missing') stdout = stdout.decode('iso8859-1') # 'safe' decoding lines = stdout.splitlines() print(stdout) # FIXME: 'coverage_test_pyx.pxi' may not be found if coverage.py requests it before the .pyx file for module_path in ('coverage_test_py.py', 'coverage_test_pyx.pyx', 'coverage_test_include_pyx.pyx'): assert any(module_path in line for line in lines), "'%s' not found in coverage report:\n\n%s" % ( module_path, stdout) files = {} line_iter = iter(lines) for line in line_iter: if line.startswith('---'): break extend = [''] * 2 for line in line_iter: if not line or line.startswith('---'): continue name, statements, missed, covered, _missing = (line.split(None, 4) + extend)[:5] missing = [] for start, end in re.findall('([0-9]+)(?:-([0-9]+))?', _missing): if end: missing.extend(range(int(start), int(end)+1)) else: missing.append(int(start)) files[os.path.basename(name)] = (statements, missed, covered, missing) assert 7 not in files['coverage_test_pyx.pyx'][-1], files['coverage_test_pyx.pyx'] assert 12 not in files['coverage_test_pyx.pyx'][-1], files['coverage_test_pyx.pyx'] def run_xml_report(): stdout = run_coverage_command('xml', '-o', '-') print(stdout) import xml.etree.ElementTree as etree data = etree.fromstring(stdout) files = {} for module in data.iterfind('.//class'): files[module.get('filename').replace('\\', '/')] = dict( (int(line.get('number')), int(line.get('hits'))) for line in module.findall('lines/line') ) assert files['pkg/coverage_test_pyx.pyx'][5] > 0, files['pkg/coverage_test_pyx.pyx'] assert files['pkg/coverage_test_pyx.pyx'][6] > 0, files['pkg/coverage_test_pyx.pyx'] assert files['pkg/coverage_test_pyx.pyx'][7] > 0, files['pkg/coverage_test_pyx.pyx'] def run_html_report(): stdout = run_coverage_command('html', '-d', 'html') _parse_lines = re.compile( r']* id=["\'][^0-9"\']*(?P[0-9]+)[^0-9"\']*["\'][^>]*' r' class=["\'][^"\']*(?Pmis|run)[^"\']*["\']').findall files = {} for file_path in iglob('html/*.html'): with open(file_path) as f: page = f.read() executed = set() missing = set() for line, has_run in _parse_lines(page): (executed if has_run == 'run' else missing).add(int(line)) files[file_path] = (executed, missing) executed, missing = [data for path, data in files.items() if 'coverage_test_pyx' in path][0] assert executed assert 5 in executed, executed assert 6 in executed, executed assert 7 in executed, executed if __name__ == '__main__': run_report() run_xml_report() run_html_report() Cython-0.23.4/tests/run/coverage_api.srctree0000644000175600017570000000736012606202452022175 0ustar jenkinsjenkins00000000000000# mode: run # tag: coverage,trace """ PYTHON -c 'import shutil; shutil.copy("pkg/coverage_test_pyx.pyx", "pkg/coverage_test_pyx.pxi")' PYTHON setup.py build_ext -i PYTHON coverage_test.py """ ######## setup.py ######## from distutils.core import setup from Cython.Build import cythonize setup(ext_modules = cythonize([ 'coverage_test_*.py*', 'pkg/coverage_test_*.py*' ])) ######## .coveragerc ######## [run] plugins = Cython.Coverage ######## pkg/__init__.py ######## ######## pkg/coverage_test_py.py ######## # cython: linetrace=True # distutils: define_macros=CYTHON_TRACE=1 def func1(a, b): x = 1 # 5 c = func2(a) + b # 6 return x + c # 7 def func2(a): return a * 2 # 11 ######## pkg/coverage_test_pyx.pyx ######## # cython: linetrace=True # distutils: define_macros=CYTHON_TRACE=1 def func1(int a, int b): cdef int x = 1 # 5 c = func2(a) + b # 6 return x + c # 7 def func2(int a): return a * 2 # 11 ######## coverage_test_include_pyx.pyx ######## # cython: linetrace=True # distutils: define_macros=CYTHON_TRACE=1 cdef int x = 5 # 4 cdef int cfunc1(int x): # 6 return x * 3 # 7 include "pkg/coverage_test_pyx.pxi" # 9 def main_func(int x): # 11 return cfunc1(x) + func1(x, 4) + func2(x) # 12 ######## coverage_test.py ######## import re import os.path try: # io.StringIO in Py2.x cannot handle str ... from StringIO import StringIO except ImportError: from io import StringIO from coverage import coverage from pkg import coverage_test_py from pkg import coverage_test_pyx import coverage_test_include_pyx for module in [coverage_test_py, coverage_test_pyx, coverage_test_include_pyx]: assert not any(module.__file__.endswith(ext) for ext in '.py .pyc .pyo .pyw .pyx .pxi'.split()), \ module.__file__ def source_file_for(module): module_name = module.__name__ path, ext = os.path.splitext(module.__file__) platform_suffix = re.search(r'[.](?:cpython|pypy)-[0-9]+[^.]*$', path, re.I) if platform_suffix: path = path[:platform_suffix.start()] return path + '.' + module_name.rsplit('_', 1)[-1] def run_coverage(module): module_name = module.__name__ module_path = module_name.replace('.', os.path.sep) + '.' + module_name.rsplit('_', 1)[-1] cov = coverage() cov.start() assert module.func1(1, 2) == (1 * 2) + 2 + 1 assert module.func2(2) == 2 * 2 if '_include_' in module_name: assert module.main_func(2) == (2 * 3) + ((2 * 2) + 4 + 1) + (2 * 2) cov.stop() out = StringIO() cov.report(file=out) #cov.report([module], file=out) lines = out.getvalue().splitlines() assert any(module_path in line for line in lines), "'%s' not found in coverage report:\n\n%s" % ( module_path, out.getvalue()) mod_file, exec_lines, excl_lines, missing_lines, _ = cov.analysis2(source_file_for(module)) assert module_path in mod_file if '_include_' in module_name: executed = set(exec_lines) - set(missing_lines) assert all(line in executed for line in [7, 12]), '%s / %s' % (exec_lines, missing_lines) # rest of test if for include file mod_file, exec_lines, excl_lines, missing_lines, _ = cov.analysis2( os.path.join(os.path.dirname(module.__file__), "pkg", "coverage_test_pyx.pxi")) executed = set(exec_lines) - set(missing_lines) assert all(line in executed for line in [5, 6, 7, 11]), '%s / %s' % (exec_lines, missing_lines) if __name__ == '__main__': run_coverage(coverage_test_py) run_coverage(coverage_test_pyx) run_coverage(coverage_test_include_pyx) Cython-0.23.4/tests/run/control_flow_stack_allocation.pyx0000644000175600017570000000143012606202452025013 0ustar jenkinsjenkins00000000000000# mode: run # tag: werror, control-flow # cython: warn.unused=True, warn.unused_arg=True, warn.unused_result=True cdef struct S: int x float y cdef stack_alloc_test(int[2] array_arg, S struct_arg): cdef int[2] array_var cdef S struct_var, struct_var_by_value for i in range(2): array_var[i] = array_arg[i] struct_var.x, struct_var.y = struct_arg.x, struct_arg.y struct_var_by_value = struct_var return [ i for i in array_var ], struct_var_by_value def test(): """ >>> a,d = test() >>> a [0, 1] >>> sorted(d.items()) [('x', 1), ('y', 2.0)] """ cdef int[2] array_var cdef S struct_var for i in range(2): array_var[i] = i struct_var = [1, 2.0] return stack_alloc_test(array_var, struct_var) Cython-0.23.4/tests/run/control_flow_except_T725.pyx0000644000175600017570000000044312606202452023515 0ustar jenkinsjenkins00000000000000def unused_except_capture(): """ >>> unused_except_capture() """ try: try: raise ValueError except TypeError, s: raise TypeError except ValueError, s: raise ValueError # segfault except ValueError: pass Cython-0.23.4/tests/run/contains_T455.pyx0000644000175600017570000000370112606202452021254 0ustar jenkinsjenkins00000000000000# ticket: 455 def in_sequence(x, seq): """ >>> in_sequence(1, []) False >>> in_sequence(1, ()) False >>> in_sequence(1, {}) False >>> in_sequence(1, [1]) True >>> in_sequence(1, (1,)) True >>> in_sequence(1, {1:None}) True >>> in_sequence(1, None) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...iterable... >>> in_sequence(1, 1) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...iterable... """ return x in seq def not_in_sequence(x, seq): """ >>> not_in_sequence(1, []) True >>> not_in_sequence(1, ()) True >>> not_in_sequence(1, {}) True >>> not_in_sequence(1, [1]) False >>> not_in_sequence(1, (1,)) False >>> not_in_sequence(1, {1:None}) False >>> not_in_sequence(1, None) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...iterable... >>> not_in_sequence(1, 1) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...iterable... """ return x not in seq def in_dict(k, dict dct): """ >>> in_dict(1, {}) False >>> in_dict(1, {1:None}) True >>> in_dict(1, None) Traceback (most recent call last): ... TypeError: 'NoneType' object is not iterable """ return k in dct def not_in_dict(k, dict dct): """ >>> not_in_dict(1, {}) True >>> not_in_dict(1, {1:None}) False >>> not_in_dict(1, None) Traceback (most recent call last): ... TypeError: 'NoneType' object is not iterable """ return k not in dct def cascaded(a, b, c): """ >>> cascaded(1, 2, 3) # doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: ...iterable... >>> cascaded(-1, (1,2), (1,3)) True >>> cascaded(1, (1,2), (1,3)) False >>> cascaded(-1, (1,2), (1,0)) False """ return a not in b < c Cython-0.23.4/tests/run/consts.pyx0000644000175600017570000001452512606202452020234 0ustar jenkinsjenkins00000000000000import sys IS_PY3 = sys.version_info[0] >= 3 cimport cython DEF INT_VAL = 1 def _func(a,b,c): return a+b+c @cython.test_fail_if_path_exists("//AddNode") def add(): """ >>> add() == 1+2+3+4 True """ return 1+2+3+4 #@cython.test_fail_if_path_exists("//AddNode") def add_var(a): """ >>> add_var(10) == 1+2+10+3+4 True """ return 1+2 +a+ 3+4 @cython.test_fail_if_path_exists("//AddNode", "//SubNode") def neg(): """ >>> neg() == -1 -2 - (-3+4) True """ return -1 -2 - (-3+4) @cython.test_fail_if_path_exists("//AddNode", "//MulNode", "//DivNode") def long_int_mix(): """ >>> long_int_mix() == 1 + (2 * 3) // 2 True >>> if IS_PY3: type(long_int_mix()) is int or type(long_int_mix()) ... else: type(long_int_mix()) is long or type(long_int_mix()) True """ return 1L + (2 * 3L) // 2 @cython.test_fail_if_path_exists("//AddNode", "//MulNode", "//DivNode") def char_int_mix(): """ >>> char_int_mix() == 1 + (ord(' ') * 3) // 2 + ord('A') True """ return 1L + (c' ' * 3L) // 2 + c'A' @cython.test_fail_if_path_exists("//AddNode", "//MulNode") def int_cast(): """ >>> int_cast() == 1 + 2 * 6000 True """ return (1 + 2 * 6000) @cython.test_fail_if_path_exists("//MulNode") def mul(): """ >>> mul() == 1*60*1000 True """ return 1*60*1000 @cython.test_fail_if_path_exists("//AddNode", "//MulNode") def arithm(): """ >>> arithm() == 9*2+3*8//6-10 True """ return 9*2+3*8//6-10 @cython.test_fail_if_path_exists("//AddNode", "//MulNode") def parameters(): """ >>> parameters() == _func(-1 -2, - (-3+4), 1*2*3) True """ return _func(-1 -2, - (-3+4), 1*2*3) #@cython.test_fail_if_path_exists("//AddNode") def lists(): """ >>> lists() == [1,2,3] + [4,5,6] True """ return [1,2,3] + [4,5,6] @cython.test_fail_if_path_exists("//MulNode") def multiplied_lists_right_len1(): """ >>> multiplied_lists_right_len1() == [1] * 5 True """ return [1] * 5 @cython.test_fail_if_path_exists("//MulNode") def multiplied_lists_right(): """ >>> multiplied_lists_right() == [1,2,3] * 5 True """ return [1,2,3] * 5 @cython.test_fail_if_path_exists("//MulNode") def multiplied_lists_left(): """ >>> multiplied_lists_left() == [1,2,3] * 5 True """ return 5 * [1,2,3] @cython.test_fail_if_path_exists("//MulNode") def multiplied_lists_neg(): """ >>> multiplied_lists_neg() == [1,2,3] * -5 True """ return [1,2,3] * -5 @cython.test_fail_if_path_exists("//MulNode") def multiplied_lists_nonconst(x): """ >>> multiplied_lists_nonconst(5) == [1,2,3] * 5 True >>> multiplied_lists_nonconst(-5) == [1,2,3] * -5 True >>> multiplied_lists_nonconst(0) == [1,2,3] * 0 True >>> try: [1,2,3] * 'abc' ... except TypeError: pass >>> try: multiplied_nonconst_tuple_arg('abc') ... except TypeError: pass >>> try: [1,2,3] * 1.0 ... except TypeError: pass >>> try: multiplied_nonconst_tuple_arg(1.0) ... except TypeError: pass """ return [1,2,3] * x @cython.test_assert_path_exists("//MulNode") def multiplied_lists_nonconst_left(x): """ >>> multiplied_lists_nonconst_left(5) == 5 * [1,2,3] True >>> multiplied_lists_nonconst_left(-5) == -5 * [1,2,3] True >>> multiplied_lists_nonconst_left(0) == 0 * [1,2,3] True """ return x * [1,2,3] @cython.test_fail_if_path_exists("//MulNode//ListNode") @cython.test_assert_path_exists("//MulNode") def multiplied_lists_nonconst_expression(x): """ >>> multiplied_lists_nonconst_expression(5) == [1,2,3] * (5 * 2) True >>> multiplied_lists_nonconst_expression(-5) == [1,2,3] * (-5 * 2) True >>> multiplied_lists_nonconst_expression(0) == [1,2,3] * (0 * 2) True """ return [1,2,3] * (x*2) cdef side_effect(int x): print x return x @cython.test_fail_if_path_exists("//MulNode") def multiplied_lists_with_side_effects(): """ >>> multiplied_lists_with_side_effects() == [1,2,3] * 5 1 2 3 True """ return [side_effect(1), side_effect(2), side_effect(3)] * 5 @cython.test_fail_if_path_exists("//MulNode") def multiplied_lists_nonconst_with_side_effects(x): """ >>> multiplied_lists_nonconst_with_side_effects(5) == [1,2,3] * 5 1 2 3 True """ return [side_effect(1), side_effect(2), side_effect(3)] * x @cython.test_fail_if_path_exists("//MulNode") def multiplied_nonconst_tuple_arg(x): """ >>> multiplied_nonconst_tuple_arg(5) == (1,2) * 5 True >>> multiplied_nonconst_tuple_arg(-5) == (1,2) * -5 True >>> multiplied_nonconst_tuple_arg(0) == (1,2) * 0 True >>> try: (1,2) * 'abc' ... except TypeError: pass >>> try: multiplied_nonconst_tuple_arg('abc') ... except TypeError: pass >>> try: (1,2) * 1.0 ... except TypeError: pass >>> try: multiplied_nonconst_tuple_arg(1.0) ... except TypeError: pass """ return (1,2) * x @cython.test_fail_if_path_exists("//MulNode") def multiplied_nonconst_tuple_int_arg(int x): """ >>> multiplied_nonconst_tuple_int_arg(5) == (1,2) * 5 True """ return (1,2) * x @cython.test_fail_if_path_exists("//MulNode") def multiplied_nonconst_tuple(x): """ >>> multiplied_nonconst_tuple(5) == (1,2) * (5+1) True """ return (1,2) * (x + 1) MULT = 5 @cython.test_fail_if_path_exists("//MulNode") def multiplied_global_nonconst_tuple(): """ >>> multiplied_global_nonconst_tuple() == (1,2,3) * 5 1 2 3 True """ return (side_effect(1), side_effect(2), side_effect(3)) * MULT @cython.test_fail_if_path_exists("//MulNode") def multiplied_const_tuple(): """ >>> multiplied_const_tuple() == (1,2) * 5 True """ return (1,2) * 5 @cython.test_fail_if_path_exists("//MulNode") def multiplied_const_tuple_len1(): """ >>> multiplied_const_tuple_len1() == (1,) * 5 True """ return (1,) * 5 @cython.test_fail_if_path_exists("//PrimaryCmpNode") def compile_time_DEF(): """ >>> compile_time_DEF() (1, False, True, True, False) """ return INT_VAL, INT_VAL == 0, INT_VAL != 0, INT_VAL == 1, INT_VAL != 1 @cython.test_fail_if_path_exists("//PrimaryCmpNode") def cascaded_compare(): """ >>> cascaded_compare() True """ return 1 < 2 < 3 < 4 Cython-0.23.4/tests/run/constant_folding_cy.pyx0000644000175600017570000000444412606202452022750 0ustar jenkinsjenkins00000000000000# coding=utf8 # mode: run # tag: constant_folding cimport cython bstring = b'abc\xE9def' ustring = u'abc\xE9def' surrogates_ustring = u'abc\U00010000def' @cython.test_fail_if_path_exists( "//SliceIndexNode", ) def bytes_slicing2(): """ >>> a,b,c,d = bytes_slicing2() >>> a == bstring[:] True >>> b == bstring[2:] True >>> c == bstring[:4] True >>> d == bstring[2:4] True """ str0 = b'abc\xE9def'[:] str1 = b'abc\xE9def'[2:] str2 = b'abc\xE9def'[:4] str3 = b'abc\xE9def'[2:4] return str0, str1, str2, str3 @cython.test_fail_if_path_exists( "//SliceIndexNode", ) def unicode_slicing2(): """ >>> a,b,c,d = unicode_slicing2() >>> a == ustring[:] True >>> b == ustring[2:] True >>> c == ustring[:4] True >>> d == ustring[2:4] True """ str0 = u'abc\xE9def'[:] str1 = u'abc\xE9def'[2:] str2 = u'abc\xE9def'[:4] str3 = u'abc\xE9def'[2:4] return str0, str1, str2, str3 @cython.test_assert_path_exists( "//SliceIndexNode", ) def unicode_slicing_unsafe_surrogates2(): """ >>> unicode_slicing_unsafe_surrogates2() == surrogates_ustring[2:] True """ ustring = u'abc\U00010000def'[2:] return ustring @cython.test_fail_if_path_exists( "//SliceIndexNode", ) def unicode_slicing_safe_surrogates2(): """ >>> unicode_slicing_safe_surrogates2() == surrogates_ustring[:2] True >>> print(unicode_slicing_safe_surrogates2()) ab """ ustring = u'abc\U00010000def'[:2] return ustring @cython.test_fail_if_path_exists( "//ComprehensionNode", "//ForInStatNode", ) @cython.test_assert_path_exists( "//SetNode", ) def for_in_empty_setcomp(): """ >>> s = for_in_empty_setcomp() >>> isinstance(s, set) True >>> len(s) 0 """ return {i for i in []} @cython.test_fail_if_path_exists( "//ReturnStatNode//AddNode", ) @cython.test_assert_path_exists( "//ListNode//AddNode", ) def add_strings(): """ >>> u, b, rest = add_strings() >>> u == 'abcdef' or u True >>> b == b'abcdef' or b True >>> rest 1 """ a = ["abc" + "def"] # not currently optimised # FIXME: test encodings and unicode escapes return u"abc" + u"def", b"abc" + b"def", a[0] and 1 Cython-0.23.4/tests/run/constant_folding.py0000644000175600017570000002373712606202452022073 0ustar jenkinsjenkins00000000000000# coding=utf8 # mode: run # tag: constant_folding import cython @cython.test_fail_if_path_exists( "//UnaryMinusNode", "//UnaryPlusNode", ) def unop_floats(): """ >>> unop_floats() (False, 2.0, -2.0, False, 2.0, -2.0, -2.0) """ not1 = not 2.0 plus1 = + 2.0 minus1 = - 2.0 not3 = not not not 2.0 plus3 = +++ 2.0 minus3 = --- 2.0 mix = +-++-- 2.0 return not1, plus1, minus1, not3, plus3, minus3, mix @cython.test_fail_if_path_exists( "//UnaryMinusNode", "//UnaryPlusNode", "//CoerceToPyTypeNode", ) def unop_py_floats_tuple(): """ >>> unop_floats() (False, 2.0, -2.0, False, 2.0, -2.0, -2.0) """ return ( not 2.0, + 2.0, - 2.0, not not not 2.0, +++ 2.0, --- 2.0, +-++-- 2.0) @cython.test_fail_if_path_exists( "//UnaryMinusNode", "//UnaryPlusNode", ) def unop_ints(): """ >>> unop_ints() (False, 2, -2, False, 2, -2, -2) """ not1 = not 2 plus1 = + 2 minus1 = - 2 not3 = not not not 2 plus3 = +++ 2 minus3 = --- 2 mix = +-++-- 2 return not1, plus1, minus1, not3, plus3, minus3, mix @cython.test_fail_if_path_exists( "//UnaryMinusNode", "//UnaryPlusNode", "//NotNode", ) def unop_bool(): """ >>> unop_bool() (False, 1, -1, False, 1, -1, -1) """ not1 = not True plus1 = + True minus1 = - True not3 = not not not True plus3 = +++ True minus3 = --- True mix = +-++-- True return not1, plus1, minus1, not3, plus3, minus3, mix @cython.test_fail_if_path_exists( "//AddNode", "//SubNode", ) def binop_bool(): """ >>> binop_bool() (2, 1, 0, True, True, 1, False, 2, 2, -2, False, True, 1, False) """ plus1 = True + True pmix1 = True + 0 minus1 = True - True and1 = True & True or1 = True | True ormix1 = True | 0 xor1 = True ^ True plus3 = False + True + False + True pmix3 = False + True + 0 + True minus3 = False - True - False - True and3 = False & True & False & True or3 = False | True | False | True ormix3 = False | 0 | False | True xor3 = False ^ True ^ False ^ True return plus1, pmix1, minus1, and1, or1, ormix1, xor1, plus3, pmix3, minus3, and3, or3, ormix3, xor3 @cython.test_fail_if_path_exists( "//SliceIndexNode", ) def slicing2(): """ >>> slicing2() ([1, 2, 3, 4], [3, 4], [1, 2, 3, 4], [3, 4], (1, 2, 3, 4), (3, 4), (1, 2, 3, 4), (3, 4)) """ lst0 = [1, 2, 3, 4][:] lst1 = [1, 2, 3, 4][2:] lst2 = [1, 2, 3, 4][:4] lst3 = [1, 2, 3, 4][2:4] tpl0 = (1, 2, 3, 4)[:] tpl1 = (1, 2, 3, 4)[2:] tpl2 = (1, 2, 3, 4)[:4] tpl3 = (1, 2, 3, 4)[2:4] return lst0, lst1, lst2, lst3, tpl0, tpl1, tpl2, tpl3 @cython.test_fail_if_path_exists( "//SliceIndexNode", ) def str_slicing2(): """ >>> a,b,c,d = str_slicing2() >>> a == 'abc\\xE9def'[:] True >>> b == 'abc\\xE9def'[2:] True >>> c == 'abc\\xE9def'[:4] True >>> d == 'abc\\xE9def'[2:4] True """ str0 = 'abc\xE9def'[:] str1 = 'abc\xE9def'[2:] str2 = 'abc\xE9def'[:4] str3 = 'abc\xE9def'[2:4] return str0, str1, str2, str3 @cython.test_fail_if_path_exists( "//IfStatNode", ) def str_in_and_not_in(): """ >>> str_in_and_not_in() True """ if 'a' in 'abc' and 'b' in 'abc' and 'c' in 'abc' and 'd' not in 'abc': return True else: return False @cython.test_fail_if_path_exists( "//WhileStatNode", ) def while_false(): """ >>> while_false() """ while 1 == 0: return False @cython.test_fail_if_path_exists( "//WhileStatNode", ) def while_false_else(): """ >>> while_false_else() True """ while 1 == 0: return False else: return True @cython.test_fail_if_path_exists( "//WhileStatNode//PrintStatNode", "//WhileStatNode//PrimaryCmpNode", "//WhileStatNode/BoolNode", "//WhileStatNode/IntNode", ) @cython.test_assert_path_exists( "//WhileStatNode", ) def while_true(): """ >>> while_true() True """ while 1 == 1: return True else: print("FAIL") @cython.test_fail_if_path_exists( "//ForInStatNode", ) def for_in_empty(): """ >>> for_in_empty() """ for i in []: print("LOOP") @cython.test_fail_if_path_exists( "//ForInStatNode", ) def for_in_empty_else(): """ >>> for_in_empty_else() True """ for i in []: print("LOOP") else: return True @cython.test_fail_if_path_exists( "//ComprehensionNode", "//ForInStatNode", ) @cython.test_assert_path_exists( "//ListNode", ) def for_in_empty_listcomp(): """ >>> for_in_empty_listcomp() [] """ return [i for i in []] @cython.test_fail_if_path_exists( "//ComprehensionNode", "//ForInStatNode", ) @cython.test_assert_path_exists( "//ListNode", ) def for_in_empty_nested_listcomp(): """ >>> for_in_empty_nested_listcomp() [] """ return [x for _ in [] for x in [1, 2, 3]] @cython.test_fail_if_path_exists( "//ForInStatNode//ForInStatNode", ) @cython.test_assert_path_exists( "//ForInStatNode", "//ComprehensionNode", ) def for_in_nested_listcomp(): """ >>> for_in_nested_listcomp() [] """ return [x for x in [1, 2, 3] for _ in []] @cython.test_fail_if_path_exists( "//MulNode", ) def mult_empty_list(): """ >>> mult_empty_list() [] """ return 5 * [] * 100 @cython.test_fail_if_path_exists( "//MulNode", ) def mult_list_int_int(): """ >>> mult_list_int_int() [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2] """ return [1, 2] * 2 * 3 @cython.test_fail_if_path_exists( "//MulNode", ) def mult_int_list_int(): """ >>> mult_int_list_int() [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2] """ return 3 * [1, 2] * 2 @cython.test_fail_if_path_exists( "//MulNode", "//ListNode//IntNode", ) def neg_mult_list(): """ >>> neg_mult_list() [] """ return -5 * [1, 2] * -100 @cython.test_fail_if_path_exists( "//MulNode", "//ListNode//IntNode", ) def zero_mult_list(): """ >>> zero_mult_list() [] """ return 0 * [1, 2] * 0 @cython.test_assert_path_exists( "//BoolNode", ) @cython.test_fail_if_path_exists( "//PrimaryCmpNode", "//MulNode", "//ListNode//IntNode", ) def in_mult_list(): """ >>> in_mult_list() False """ return 5 in 100 * [1, 2] * 0 @cython.test_assert_path_exists( "//BoolNode", ) @cython.test_fail_if_path_exists( "//PrimaryCmpNode", "//MulNode", "//ListNode//IntNode", ) def not_in_mult_list(): """ >>> not_in_mult_list() True """ return 5 not in 100 * [1, 2] * 0 @cython.test_assert_path_exists( "//BoolNode", ) @cython.test_fail_if_path_exists( "//PrimaryCmpNode", "//MulNode", "//ListNode//IntNode", ) def combined(): """ >>> combined() True """ return 5 in 100 * [1, 2] * 0 or 5 not in 100 * [] * 10 @cython.test_assert_path_exists( '//IntNode[@value = "2"]', '//IntNode[@value = "4"]', '//IntNode[@value = "5"]', '//IntNode[@value = "7"]', '//BoolBinopNode//PrimaryCmpNode', '//BoolBinopNode[.//PrimaryCmpNode//IntNode[@value = "4"] and .//PrimaryCmpNode//IntNode[@value = "5"]]', '//PrimaryCmpNode[.//IntNode[@value = "2"] and .//IntNode[@value = "4"]]', '//PrimaryCmpNode[.//IntNode[@value = "5"] and .//IntNode[@value = "7"]]', ) @cython.test_fail_if_path_exists( '//IntNode[@value = "1"]', '//IntNode[@value = "8"]', '//PrimaryCmpNode[.//IntNode[@value = "4"] and .//IntNode[@value = "5"]]', '//PrimaryCmpNode[.//IntNode[@value = "2"] and .//IntNode[@value = "7"]]', '//BoolNode', ) def cascaded_cmp_with_partial_constants(a, b): """ >>> cascaded_cmp_with_partial_constants(3, 6) True >>> cascaded_cmp_with_partial_constants(1, 6) False >>> cascaded_cmp_with_partial_constants(4, 6) False >>> cascaded_cmp_with_partial_constants(3, 7) False >>> cascaded_cmp_with_partial_constants(3, 6) True """ return 1 < 2 < a < 4 < 5 < b < 7 < 8 @cython.test_assert_path_exists( '//IntNode[@value = "2"]', '//IntNode[@value = "4"]', '//IntNode[@value = "5"]', '//IntNode[@value = "7"]', '//BoolBinopNode', '//SingleAssignmentNode//BoolBinopNode', '//SingleAssignmentNode//BoolBinopNode//NameNode[@name = "a"]', '//SingleAssignmentNode//BoolBinopNode//NameNode[@name = "b"]', '//BoolBinopNode[.//PrimaryCmpNode//IntNode[@value = "4"] and .//PrimaryCmpNode//IntNode[@value = "5"]]', '//BoolNode[@value = False]', ) @cython.test_fail_if_path_exists( '//SingleAssignmentNode//NameNode[@name = "c"]', '//IntNode[@value = "1"]', '//PrimaryCmpNode[.//IntNode[@value = "4"] and .//IntNode[@value = "5"]]', '//PrimaryCmpNode[.//IntNode[@value = "2"] and .//IntNode[@value = "7"]]', '//BoolNode[@value = True]', ) def cascaded_cmp_with_partial_constants_and_false_end(a, b, c): """ >>> cascaded_cmp_with_partial_constants_and_false_end(3, 6, 8) False >>> cascaded_cmp_with_partial_constants_and_false_end(1, 6, 8) False >>> cascaded_cmp_with_partial_constants_and_false_end(4, 6, 8) False >>> cascaded_cmp_with_partial_constants_and_false_end(3, 7, 8) False """ x = 1 < 2 < a < 4 < 5 < b < 7 < 7 < c return x @cython.test_assert_path_exists( '//PrimaryCmpNode', '//PrimaryCmpNode//IntNode', '//PrimaryCmpNode//IntNode[@value = "0"]', '//PrimaryCmpNode//IntNode[@value = "4294967296"]', ) @cython.test_fail_if_path_exists( '//PrimaryCmpNode//IntBinopNode', '//PrimaryCmpNode//IntNode[@value = "1"]', '//PrimaryCmpNode//IntNode[@value = "32"]', ) def const_in_binop(v): """ >>> const_in_binop(-1) 1 >>> const_in_binop(0) 0 >>> const_in_binop(1 << 32) 1 >>> const_in_binop(1 << 32 - 1) 0 """ if v < 0 or v >= (1 << 32): return 1 else: return 0 Cython-0.23.4/tests/run/concatcstrings.pyx0000644000175600017570000000030612606202452021737 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> spam == u'C string 1' + u'C string 2' True """ import sys if sys.version_info[0] >= 3: __doc__ = __doc__.replace(u" u'", u" '") spam = u"C string 1" + u"C string 2" Cython-0.23.4/tests/run/complex_numbers_cxx_T398.pyx0000644000175600017570000000014612606202452023530 0ustar jenkinsjenkins00000000000000# ticket: 398 cdef extern from "complex_numbers_cxx_T398.h": pass include "complex_numbers_T305.pyx" Cython-0.23.4/tests/run/complex_numbers_cxx_T398.h0000644000175600017570000000013212606202452023132 0ustar jenkinsjenkins00000000000000#if defined(__cplusplus) #define CYTHON_CCOMPLEX 1 #else #define CYTHON_CCOMPLEX 0 #endif Cython-0.23.4/tests/run/complex_numbers_c99_T398.pyx0000644000175600017570000000014612606202452023332 0ustar jenkinsjenkins00000000000000# ticket: 398 cdef extern from "complex_numbers_c99_T398.h": pass include "complex_numbers_T305.pyx" Cython-0.23.4/tests/run/complex_numbers_c99_T398.h0000644000175600017570000000062612606202452022744 0ustar jenkinsjenkins00000000000000#if !defined(__cplusplus) #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) \ || defined(__GNUC__) \ || defined(__INTEL_COMPILER) \ || defined(__IBMC__) \ #include #if !defined(_Complex_I) #error The "complex.h" header does not define the '_Complex_I' macro. #error Please report this to Cython developers #endif #endif #endif Cython-0.23.4/tests/run/complex_numbers_c89_T398.pyx0000644000175600017570000000014612606202452023331 0ustar jenkinsjenkins00000000000000# ticket: 398 cdef extern from "complex_numbers_c89_T398.h": pass include "complex_numbers_T305.pyx" Cython-0.23.4/tests/run/complex_numbers_c89_T398.h0000644000175600017570000000003212606202452022732 0ustar jenkinsjenkins00000000000000#define CYTHON_CCOMPLEX 0 Cython-0.23.4/tests/run/complex_numbers_T305.pyx0000644000175600017570000001234012606202452022631 0ustar jenkinsjenkins00000000000000# ticket: 305 cimport cython def test_object_conversion(o): """ >>> test_object_conversion(2) ((2+0j), (2+0j), (2+0j)) >>> test_object_conversion(2j - 0.5) ((-0.5+2j), (-0.5+2j), (-0.5+2j)) """ cdef float complex a = o cdef double complex b = o cdef long double complex c = o return (a, b, c) def test_arithmetic(double complex z, double complex w): """ >>> test_arithmetic(2j, 4j) (2j, -2j, 6j, -2j, (-8+0j), (0.5+0j)) >>> test_arithmetic(6+12j, 3j) ((6+12j), (-6-12j), (6+15j), (6+9j), (-36+18j), (4-2j)) >>> test_arithmetic(5-10j, 3+4j) ((5-10j), (-5+10j), (8-6j), (2-14j), (55-10j), (-1-2j)) """ return +z, -z+0, z+w, z-w, z*w, z/w def test_pow(double complex z, double complex w, tol=None): """ Various implementations produce slightly different results... >>> a = complex(3, 1) >>> test_pow(a, 1, 1e-15) True >>> test_pow(a, 2, 1e-15) True >>> test_pow(a, a, 1e-15) True >>> test_pow(complex(0.5, -.25), complex(3, 4), 1e-15) True """ if tol is None: return z**w else: return abs(z**w / z ** w - 1) < tol def test_int_pow(double complex z, int n, tol=None): """ >>> [test_int_pow(complex(0, 1), k, 1e-15) for k in range(-4, 5)] [True, True, True, True, True, True, True, True, True] >>> [test_int_pow(complex(0, 2), k, 1e-15) for k in range(-4, 5)] [True, True, True, True, True, True, True, True, True] >>> [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] """ if tol is None: return z**n + 0 # add zero to normalize zero sign else: return abs(z**n / z ** n - 1) < tol @cython.cdivision(False) def test_div_by_zero(double complex z): """ >>> test_div_by_zero(4j) -0.25j >>> test_div_by_zero(0) Traceback (most recent call last): ... ZeroDivisionError: float division """ return 1/z def test_coercion(int a, float b, double c, float complex d, double complex e): """ >>> test_coercion(1, 1.5, 2.5, 4+1j, 10j) (1+0j) (1.5+0j) (2.5+0j) (4+1j) 10j (9+21j) """ cdef double complex z z = a; print z z = b; print z z = c; print z z = d; print z z = e; print z return z + a + b + c + d + e def test_compare(double complex a, double complex b): """ >>> test_compare(3, 3) (True, False) >>> test_compare(3j, 3j) (True, False) >>> test_compare(3j, 4j) (False, True) >>> test_compare(3, 4) (False, True) """ return a == b, a != b def test_compare_coerce(double complex a, int b): """ >>> test_compare_coerce(3, 4) (False, True) >>> test_compare_coerce(4+1j, 4) (False, True) >>> test_compare_coerce(4, 4) (True, False) """ return a == b, a != b def test_literal(): """ >>> test_literal() (5j, (1-2.5j)) """ return 5j, 1-2.5j def test_real_imag(double complex z): """ >>> test_real_imag(1-3j) (1.0, -3.0) >>> test_real_imag(5) (5.0, 0.0) >>> test_real_imag(1.5j) (0.0, 1.5) """ return z.real, z.imag def test_real_imag_assignment(object a, double b): """ >>> test_real_imag_assignment(1, 2) (1+2j) >>> test_real_imag_assignment(1.5, -3.5) (1.5-3.5j) """ cdef double complex z z.real = a z.imag = b return z def test_conjugate(float complex z): """ >>> test_conjugate(2+3j) (2-3j) """ return z.conjugate() def test_conjugate_double(double complex z): """ >>> test_conjugate_double(2+3j) (2-3j) """ return z.conjugate() ctypedef double complex cdouble def test_conjugate_typedef(cdouble z): """ >>> test_conjugate_typedef(2+3j) (2-3j) """ return z.conjugate() cdef cdouble test_conjugate_nogil(cdouble z) nogil: # Really just a compile test. return z.conjugate() test_conjugate_nogil(0) # use it ## cdef extern from "complex_numbers_T305.h": ## ctypedef double double_really_float "myfloat" ## ctypedef float float_really_double "mydouble" ## ctypedef float real_float "myfloat" ## ctypedef double real_double "mydouble" ## def test_conjugate_nosizeassumptions(double_really_float x, ## float_really_double y, ## real_float z, real_double w): ## """ ## >>> test_conjugate_nosizeassumptions(1, 1, 1, 1) ## (-1j, -1j, -1j, -1j) ## >>> ["%.2f" % x.imag for x in test_conjugate_nosizeassumptions(2e300, 2e300, 2e300, 2e300)] ## ['-inf', '-2e+300', '-inf', '-2e+300'] ## """ ## cdef double complex I = 1j ## return ((x*I).conjugate(), (y*I).conjugate(), (z*I).conjugate(), (w*I).conjugate()) ctypedef double mydouble def test_coerce_typedef_multiply(mydouble x, double complex z): """ >>> test_coerce_typedef_multiply(3, 1+1j) (3+3j) """ return x * z ctypedef int myint def test_coerce_typedef_multiply_int(myint x, double complex z): """ >>> test_coerce_typedef_multiply_int(3, 1+1j) (3+3j) """ return x * z cpdef double complex complex_retval(): """ >>> complex_retval() 1j """ return 1j Cython-0.23.4/tests/run/complex_int_T446_fix.h0000644000175600017570000000011512606202452022230 0ustar jenkinsjenkins00000000000000#if defined _MSC_VER && defined __cplusplus #define CYTHON_CCOMPLEX 0 #endif Cython-0.23.4/tests/run/complex_int_T446.pyx0000644000175600017570000000234612606202452021763 0ustar jenkinsjenkins00000000000000# ticket: 446 import cython cdef extern from "complex_int_T446_fix.h": pass def test_arith(int complex a, int complex b): """ >>> test_arith(4, 2) ((-4+0j), (6+0j), (2+0j), (8+0j)) >>> test_arith(6+9j, 3j) ((-6-9j), (6+12j), (6+6j), (-27+18j)) >>> test_arith(29+11j, 5+7j) ((-29-11j), (34+18j), (24+4j), (68+258j)) """ return -a, a+b, a-b, a*b @cython.cdivision(False) def test_div_by_zero(long complex z): """ >>> test_div_by_zero(4j) -25j >>> test_div_by_zero(0) Traceback (most recent call last): ... ZeroDivisionError: float division """ return 100/z def test_coercion(int a, long b, int complex c): """ >>> test_coercion(1, -2, 3-3j) (1+0j) (-2+0j) (3-3j) (5-6j) """ cdef double complex z z = a; print z z = b; print z z = c; print z return z + a + b + c def test_conjugate(long complex z): """ >>> test_conjugate(2+3j) (2-3j) """ return z.conjugate() def test_conjugate2(short complex z): """ >>> test_conjugate2(2+3j) (2-3j) """ return z.conjugate() def test_conjugate3(long long complex z): """ >>> test_conjugate3(2+3j) (2-3j) """ return z.conjugate() Cython-0.23.4/tests/run/complex_coercion_sideeffects_T693.pyx0000644000175600017570000000052412606202452025336 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 693 cdef double complex func(double complex x): print "hello" return x def test_coercion(): """ >>> c = test_coercion() hello >>> c.real == 0.5 True >>> c.imag == 1.5 True """ cdef object x = func(0.5 + 1.5j) return x Cython-0.23.4/tests/run/complex_cast_T445.pyx0000644000175600017570000000230112606202452022111 0ustar jenkinsjenkins00000000000000# ticket: 445 def complex_double_cast(double x, double complex z): """ >>> complex_double_cast(1, 4-3j) ((1+0j), (4-3j)) """ cdef double complex xx = x cdef double complex zz = z xx = x return xx, zz def complex_double_int_cast(int x, int complex z): """ >>> complex_double_int_cast(2, 2 + 3j) ((2+0j), (3+3j)) """ cdef double complex xx = x cdef double complex zz = (z+1) return xx, zz def complex_int_double_cast(double x, double complex z): """ >>> complex_int_double_cast(2.5, 2.5 + 3.5j) ((2+0j), (2+3j)) """ cdef int complex xx = x cdef int complex zz = z return xx, zz cdef int side_effect_counter = 0 cdef double complex side_effect(double complex z): global side_effect_counter side_effect_counter += 1 print "side effect", side_effect_counter, z return z def test_side_effect(int complex z): """ >>> test_side_effect(5) side effect 1 (5+0j) (5+0j) >>> test_side_effect(3-4j) side effect 2 (3-4j) (3-4j) """ cdef int complex zz = side_effect(z) return zz Cython-0.23.4/tests/run/compiledef.pyx0000644000175600017570000000051112606202452021020 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> t True >>> f False >>> boolexpr True >>> num6 6 >>> intexpr 10 """ DEF c_t = True DEF c_f = False DEF c_boolexpr = c_t and True and not (c_f or False) DEF c_num6 = 2*3 DEF c_intexpr = c_num6 + 4 t = c_t f = c_f boolexpr = c_boolexpr num6 = c_num6 intexpr = c_intexpr Cython-0.23.4/tests/run/common_utility_types.srctree0000644000175600017570000000117512606202452024046 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import runner" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize("*.pyx"), ) ######## a.pyx ######## # cython: binding=True def funcA(): return ######## b.pyx ######## # cython: binding=True def funcB(): return ######## runner.py ######## print("importing...") import a, b print(type(a.funcA)) assert type(a.funcA).__name__ == 'cython_function_or_method' assert type(a.funcA) is type(b.funcB) assert a.funcA.func_globals is a.__dict__ assert b.funcB.func_globals is b.__dict__ Cython-0.23.4/tests/run/coercearraytoptr.pyx0000644000175600017570000000067112606202452022310 0ustar jenkinsjenkins00000000000000cdef char* cstring = "abcdefg" cdef void spam(char *target): cdef char* s = cstring while s[0]: target[0] = s[0] s += 1 target += 1 target[0] = c'\0' cdef struct Grail: char silly[42] def eggs(): """ >>> print(str(eggs()).replace("b'", "'")) ('abcdefg', 'abcdefg') """ cdef char[42] silly cdef Grail grail spam(silly) spam(grail.silly) return silly, grail.silly Cython-0.23.4/tests/run/code_object_cache.pyx0000644000175600017570000001017012606202452022276 0ustar jenkinsjenkins00000000000000# mode: run # tag: except # test the code object cache that is being used in exception raising ### low level tests cimport cython cdef extern from *: # evil hack to access the internal utility function ctypedef struct PyCodeObject ctypedef struct __Pyx_CodeObjectCacheEntry: int code_line PyCodeObject* code_object int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) def test_lowlevel_bisect2(*indices): """ >>> test_lowlevel_bisect2(1, 2, 3, 4, 5, 6) [0, 0, 1, 1, 2, 2] """ cdef __Pyx_CodeObjectCacheEntry* cache = [ __Pyx_CodeObjectCacheEntry(2, NULL), __Pyx_CodeObjectCacheEntry(4, NULL), ] return [ __pyx_bisect_code_objects(cache, 2, i) for i in indices ] def test_lowlevel_bisect5(*indices): """ >>> test_lowlevel_bisect5(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) [0, 1, 2, 2, 2, 3, 3, 3, 4, 5, 5] """ cdef __Pyx_CodeObjectCacheEntry* cache = [ __Pyx_CodeObjectCacheEntry(1, NULL), __Pyx_CodeObjectCacheEntry(2, NULL), __Pyx_CodeObjectCacheEntry(5, NULL), __Pyx_CodeObjectCacheEntry(8, NULL), __Pyx_CodeObjectCacheEntry(9, NULL), ] return [ __pyx_bisect_code_objects(cache, 5, i) for i in indices ] def test_lowlevel_bisect6(*indices): """ >>> test_lowlevel_bisect6(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) [0, 0, 1, 2, 2, 2, 3, 3, 4, 5, 5, 5, 6] """ cdef __Pyx_CodeObjectCacheEntry* cache = [ __Pyx_CodeObjectCacheEntry(2, NULL), __Pyx_CodeObjectCacheEntry(3, NULL), __Pyx_CodeObjectCacheEntry(6, NULL), __Pyx_CodeObjectCacheEntry(8, NULL), __Pyx_CodeObjectCacheEntry(9, NULL), __Pyx_CodeObjectCacheEntry(12, NULL), ] return [ __pyx_bisect_code_objects(cache, 6, i) for i in indices ] ### Python level tests import sys def tb(): return sys.exc_info()[-1] def raise_keyerror(): raise KeyError def check_code_object_identity_recursively(tb1, tb2): if tb1 is None or tb2 is None: return code1, code2 = tb1.tb_frame.f_code, tb2.tb_frame.f_code if code1 is not code2: print('%s != %s' % (code1, code2)) check_code_object_identity_recursively(tb1.tb_next, tb2.tb_next) def assert_simple_code_object_reuse(): """ >>> try: assert_simple_code_object_reuse() ... except KeyError: t1 = tb() >>> try: assert_simple_code_object_reuse() ... except KeyError: t2 = tb() >>> check_code_object_identity_recursively(t1.tb_next, t2.tb_next) """ raise KeyError def assert_multi_step_code_object_reuse(recursions=0): """ >>> for depth in range(5): ... try: assert_multi_step_code_object_reuse(depth) ... except KeyError: t1 = tb() ... try: assert_multi_step_code_object_reuse(depth) ... except KeyError: t2 = tb() ... check_code_object_identity_recursively(t1.tb_next, t2.tb_next) """ if recursions: assert_multi_step_code_object_reuse(recursions-1) else: raise_keyerror() def assert_simple_code_object_reuse_fused(cython.floating dummy): """ DISABLED: searching for code objects based on C lineno breaks for specializations >> try: assert_simple_code_object_reuse_fused["float"](1.0) ... except KeyError: t1 = tb() >> try: assert_simple_code_object_reuse_fused["double"](1.0) ... except KeyError: t2 = tb() >> check_code_object_identity_recursively(t1.tb_next, t2.tb_next) """ raise KeyError def assert_multi_step_code_object_reuse_fused(recursions=0, cython.floating dummy = 2.0): """ DISABLED: searching for code objects based on C lineno breaks for specializations >> for depth in range(5): ... try: assert_multi_step_code_object_reuse_fused(depth, 1.0) ... except KeyError: t1 = tb() ... try: assert_multi_step_code_object_reuse_fused(depth, 1.0) ... except KeyError: t2 = tb() ... check_code_object_identity_recursively(t1.tb_next, t2.tb_next) """ if recursions: assert_multi_step_code_object_reuse(recursions-1) else: raise_keyerror() Cython-0.23.4/tests/run/cmp.pyx0000644000175600017570000000326312606202452017477 0ustar jenkinsjenkins00000000000000def single_py(a, b): """ >>> single_py(1, 2) True >>> single_py(2, 1) False """ return a < b def cascaded_py(a, b, c): """ >>> cascaded_py(1, 2, 3) True >>> cascaded_py(1, 2, -1) False >>> cascaded_py(10, 2, 3) False """ return a < b < c def single_c(int a, int b): """ >>> single_c(1, 2) True >>> single_c(2, 1) False """ return a < b def cascaded_c(double a, double b, double c): """ >>> cascaded_c(1, 2, 3) True >>> cascaded_c(1, 2, -1) False >>> cascaded_c(10, 2, 3) False """ return a < b < c def cascaded_mix_pyleft(a, double b, double c): """ >>> cascaded_mix_pyleft(1, 2, 3) True >>> cascaded_mix_pyleft(1, 2, -1) False >>> cascaded_mix_pyleft(10, 2, 3) False """ return a < b < c def cascaded_mix_pyright(double a, double b, c): """ >>> cascaded_mix_pyright(1, 2, 3) True >>> cascaded_mix_pyright(1, 2, -1) False >>> cascaded_mix_pyright(10, 2, 3) False """ return a < b < c def typed_cmp(list L): """ >>> typed_cmp([1,2,3]) False False False False """ print L is Ellipsis print Ellipsis is L print 1 == L print L == 1.5 def pointer_cmp(): """ >>> pointer_cmp() True False True """ cdef int* a = NULL cdef double* b = NULL cdef double** c = NULL print a is NULL print b is not NULL print c == NULL def c_cmp(double a, int b, long c): """ >>> c_cmp(1, 2, 3) True >>> c_cmp(1.5, 2, 2) True >>> c_cmp(1.5, 2, 0) False >>> c_cmp(1, 1, 3) False """ return a < b <= c Cython-0.23.4/tests/run/cmethod_inline_T474.pyx0000644000175600017570000000135512606202452022423 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 474 cimport cython cdef class TestInlineMethod(object): """ >>> test = TestInlineMethod() >>> test.test_cdef_method() 0 """ @cython.test_assert_path_exists( "//AttributeNode[@entry.is_inline_cmethod=True]", "//AttributeNode[@entry.is_final_cmethod=True]") def test_cdef_method(self): return self.cdef_inline_method() cdef class Subtyping(TestInlineMethod): """ >>> test = Subtyping() >>> test.test_cdef_subtyping() 0 """ @cython.test_assert_path_exists( "//AttributeNode[@entry.is_inline_cmethod=True]", "//AttributeNode[@entry.is_final_cmethod=True]") def test_cdef_subtyping(self): return self.cdef_inline_method() Cython-0.23.4/tests/run/cmethod_inline_T474.pxd0000644000175600017570000000014412606202452022371 0ustar jenkinsjenkins00000000000000cdef class TestInlineMethod(object): cdef inline int cdef_inline_method(self): return 0 Cython-0.23.4/tests/run/closures_T82.pyx0000644000175600017570000001056012606202452021212 0ustar jenkinsjenkins00000000000000# mode: run # tag: closures # ticket: 82 # preparse: id # preparse: def_to_cdef cimport cython def add_n(int n): """ >>> f = add_n(3) >>> f(2) 5 >>> f = add_n(1000000) >>> f(1000000), f(-1000000) (2000000, 0) """ def f(int x): return x+n return f def a(int x): """ >>> a(5)() 8 """ def b(): def c(): return 3+x return c() return b def local_x(int arg_x): """ >>> local_x(1)(2)(4) 4 2 1 15 """ cdef int local_x = arg_x def y(arg_y): y = arg_y def z(long arg_z): cdef long z = arg_z print z, y, local_x return 8+z+y+local_x return z return y def x(int x): """ >>> x(1)(2)(4) 15 """ def y(y): def z(long z): return 8+z+y+x return z return y def x2(int x2): """ >>> x2(1)(2)(4) 4 2 1 15 """ def y2(y2): def z2(long z2): print z2, y2, x2 return 8+z2+y2+x2 return z2 return y2 def inner_override(a,b): """ >>> inner_override(2,4)() 5 """ def f(): a = 1 return a+b return f def reassign(x): """ >>> reassign(4)(2) 3 """ def f(a): return a+x x = 1 return f def reassign_int(x): """ >>> reassign_int(4)(2) 3 """ def f(int a): return a+x x = 1 return f def reassign_int_int(int x): """ >>> reassign_int_int(4)(2) 3 """ def f(int a): return a+x x = 1 return f def cy_twofuncs(x): """ >>> def py_twofuncs(x): ... def f(a): ... return g(x) + a ... def g(b): ... return x + b ... return f >>> py_twofuncs(1)(2) == cy_twofuncs(1)(2) True >>> py_twofuncs(3)(5) == cy_twofuncs(3)(5) True """ def f(a): return g(x) + a def g(b): return x + b return f def switch_funcs(a, b, int ix): """ >>> switch_funcs([1,2,3], [4,5,6], 0)([10]) [1, 2, 3, 10] >>> switch_funcs([1,2,3], [4,5,6], 1)([10]) [4, 5, 6, 10] >>> switch_funcs([1,2,3], [4,5,6], 2) is None True """ def f(x): return a + x def g(x): return b + x if ix == 0: return f elif ix == 1: return g else: return None def ignore_func(x): def f(): return x return None def call_ignore_func(): """ >>> call_ignore_func() """ ignore_func((1,2,3)) def more_inner_funcs(x): """ >>> inner_funcs = more_inner_funcs(1)(2,4,8) >>> inner_funcs[0](16), inner_funcs[1](32), inner_funcs[2](64) (19, 37, 73) """ # called with x==1 def f(a): def g(b): # called with 16 return a+b+x return g def g(b): def f(a): # called with 32 return a+b+x return f def h(b): def f(a): # called with 64 return a+b+x return f def resolve(a_f, b_g, b_h): # called with (2,4,8) return f(a_f), g(b_g), h(b_h) return resolve @cython.test_assert_path_exists("//DefNode//DefNode//DefNode//DefNode", "//DefNode[@needs_outer_scope = False]", # deep_inner() "//DefNode//DefNode//DefNode//DefNode[@needs_closure = False]", # h() ) @cython.test_fail_if_path_exists("//DefNode//DefNode[@needs_outer_scope = False]") def deep_inner(): """ >>> deep_inner()() 2 """ cdef int x = 1 def f(): def g(): def h(): return x+1 return h return g() return f() @cython.test_assert_path_exists("//DefNode//DefNode//DefNode", "//DefNode//DefNode//DefNode[@needs_outer_scope = False]", # a() "//DefNode//DefNode//DefNode[@needs_closure = False]", # a(), g(), h() ) @cython.test_fail_if_path_exists("//DefNode//DefNode//DefNode[@needs_closure = True]") # a(), g(), h() def deep_inner_sibling(): """ >>> deep_inner_sibling()() 2 """ cdef int x = 1 def f(): def a(): return 1 def g(): return x+a() def h(): return g() return h return f() Cython-0.23.4/tests/run/closure_tests_4.pyx0000644000175600017570000004353312606202452022045 0ustar jenkinsjenkins00000000000000# mode: run # tag: closures # preparse: id # preparse: def_to_cdef # # closure_tests_4.pyx # # Battery of tests for closures in Cython. Based on the collection of # compiler tests from P423/B629 at Indiana University, Spring 1999 and # Fall 2000. Special thanks to R. Kent Dybvig, Dan Friedman, Kevin # Millikin, and everyone else who helped to generate the original # tests. Converted into a collection of Python/Cython tests by Craig # Citro. # # Note: This set of tests is split (somewhat randomly) into several # files, simply because putting all the tests in a single file causes # gcc and g++ to buckle under the load. # def g1852(): """ >>> g1852() [3, 42] """ def g1851(): def g1850(x_1333): x_1334 = 3 return 3 return g1850 f_1332 = g1851() def g1848(): def g1847(x_1336): y_1337 = 14 y_1337 = 7 return y_1337 return g1847 g_1335 = g1848() def g1849(): return [g_1335,3] g_1335 = g1849() def g1846(): def g1845(x_1340): return x_1340 return g1845 h_1339 = g1846() z_1338 = 42 def g1844(): return (g_1335[1]) return [g1844(),h_1339(z_1338)] def g1864(): """ >>> g1864() True """ t_1342 = True f_1341 = False def g1863(): return [t_1342,f_1341] bools_1345 = g1863() def g1862(): def g1861(x_1343): if ((not x_1343)): return f_1341 else: return t_1342 return g1861 id_1344 = g1862() def g1860(): def g1857(x_1349): def g1859(): return x_1349 == 0 if (g1859()): def g1858(): return (bools_1345[0]) return id_1344(g1858()) else: return odd_1346((x_1349)-(1)) return g1857 even_1347 = g1860() def g1856(): def g1853(y_1348): def g1855(): return y_1348 == 0 if (g1855()): def g1854(): return (bools_1345[1]) return id_1344(g1854()) else: return even_1347((y_1348)-(1)) return g1853 odd_1346 = g1856() return odd_1346(5) def g1872(): """ >>> g1872() 35 """ a_1350 = 5 def g1871(): return [a_1350,6] b_1351 = g1871() def g1870(): def g1869(x_1352): return (x_1352)*(a_1350) return g1869 f_1353 = g1870() def g1867(): def g1866(): return (b_1351[0]) return (f_1353(a_1350))-(g1866()) if (g1867()): def g1868(): if ((not a_1350)): return (2)*(a_1350) else: return (2)+(a_1350) b_1351[0] = g1868() f_1353(a_1350) else: if ((not (not (f_1353(a_1350) < b_1351)))): (f_1353(a_1350)) def g1865(): return (b_1351[0]) return f_1353(g1865()) def g1885(): """ >>> g1885() 9 """ def g1884(): def g1883(x_1368, y_1367): if ((not x_1368)): return g_1355((x_1368+1), (y_1367+1)) else: return h_1354((x_1368)+(y_1367)) return g1883 f_1356 = g1884() def g1882(): def g1875(u_1359, v_1358): a_1361 = (u_1359)+(v_1358) b_1360 = (u_1359)*(v_1358) def g1881(): def g1876(d_1363): def g1880(): return [a_1361,b_1360] p_1365 = g1880() def g1879(): def g1877(m_1366): if ((m_1366 < u_1359)): return f_1356(m_1366, d_1363) else: def g1878(): return (p_1365[0]) return h_1354(g1878()) return g1877 q_1364 = g1879() return q_1364(f_1356(a_1361, b_1360)) return g1876 e_1362 = g1881() return e_1362(u_1359) return g1875 g_1355 = g1882() def g1874(): def g1873(w_1357): return w_1357 return g1873 h_1354 = g1874() return f_1356(4, 5) def g1897(): """ >>> g1897() 22 """ def g1896(): def g1890(x_1373): def g1895(): def g1894(): def g1893(): def g1891(y_1374): def g1892(z_1375): return (y_1374)+(z_1375) return g1892 return g1891 return g1893()(6) return g1894()(7) return (x_1373)+(g1895()) return g1890 f_1370 = g1896() def g1889(): def g1888(): def g1887(): def g1886(w_1372, u_1371): return (w_1372)+(u_1371) return g1886 return g1887()(8, 9) return (5)+(g1888()) g_1369 = g1889() return g_1369 def g1923(): """ >>> g1923() True """ y_1377 = [] z_1376 = 10 def g1911(): return [5,y_1377] test_ls_1378 = g1911() def g1922(): def g1913(f_1379): def g1921(): def g1918(g_1382): def g1920(): def g1919(x_1383): return g_1382(g_1382)(x_1383) return g1919 return f_1379(g1920()) return g1918 def g1917(): def g1914(g_1380): def g1916(): def g1915(x_1381): return g_1380(g_1380)(x_1381) return g1915 return f_1379(g1916()) return g1914 return g1921()(g1917()) return g1913 y_1377 = g1922() def g1912(): return [z_1376,test_ls_1378] test_ls_1378 = g1912() def g1910(): def g1906(ls_1385): def g1909(): return (ls_1385 == []) if (g1909()): return 0 else: def g1908(): def g1907(): return (ls_1385[1]) return length_1384(g1907()) return (1)+(g1908()) return g1906 length_1384 = g1910() len_1386 = length_1384(test_ls_1378) def g1905(): def g1904(): def g1903(): def g1898(len_1387): def g1899(ls_1388): def g1902(): return (ls_1388 == []) if (g1902()): return 0 else: def g1901(): def g1900(): return (ls_1388[1]) return len_1387(g1900()) return (1)+(g1901()) return g1899 return g1898 return y_1377(g1903()) length_1384 = g1904() return length_1384(test_ls_1378) return (g1905() == len_1386) def g1927(): """ >>> g1927() 0 """ def g1926(): def g1924(): def g1925(): return loop_1389() return g1925 return g1924 loop_1389 = g1926() loop_1389() return 0 def g1935(): """ >>> g1935() 668 """ def g1934(): def g1928(): def g1933(): def g1931(link_1392): def g1932(): return link_1392() return g1932 return g1931 loop_1391 = g1933() def g1930(): def g1929(): return 668 return g1929 return loop_1391(g1930()) return g1928 f_1390 = g1934() return f_1390()() def g1946(): """ >>> g1946() 14629 """ def g1945(): def g1944(): return 1 return g1944 if (g1945()): a_1393 = 2 def g1943(): def g1942(): def g1941(): def g1938(x_1394): def g1940(): def g1939(): a_1393 = 1 a_1393 = g1939() x_1395 = g1940() return x_1395 return g1938 return g1941()(1) if (g1942()): def g1937(): def g1936(): return None return (a_1393 == g1936()) if (g1937()): return True else: return False else: return False if (g1943()): return 778477 else: return 14629 def g1949(): """ >>> g1949() 2 """ def g1948(): def g1947(x_1396): return x_1396 return g1947 f_1397 = g1948() a_1398 = 1 return ((f_1397(a_1398))+(a_1398))*(a_1398) def g1952(): """ >>> g1952() 17 """ def g1951(): def g1950(x_1400, y_1399): return x_1400 return g1950 k_1401 = g1951() b_1402 = 17 return k_1401(k_1401(k_1401, 37), 37)(b_1402, (b_1402)*(b_1402)) def g1956(): """ >>> g1956() False """ def g1955(): def g1953(): n_1403 = 256 def g1954(): return ([0]*n_1403) v_1404 = g1954() v_1404[32] = n_1403 return v_1404[32] return g1953 f_1405 = g1955() return isinstance(f_1405(), list) def g1959(): """ >>> g1959() 60 """ w_1409 = 4 x_1408 = 8 y_1407 = 16 z_1406 = 32 def g1958(): def g1957(): return (w_1409)+((x_1408)+((y_1407)+(z_1406))) return g1957 f_1410 = g1958() return f_1410() def g1965(): """ >>> g1965() 37 """ def g1964(): def g1962(g_1412, u_1411): def g1963(): if (u_1411): return g_1412(37) else: return u_1411 return g_1412(g1963()) return g1962 f_1413 = g1964() def g1961(): def g1960(x_1414): return x_1414 return g1960 return f_1413(g1961(), 75) def g1971(): """ >>> g1971() 4687 """ def g1970(): def g1968(h_1416, u_1415): def g1969(): if (u_1415): return h_1416((u_1415)+(37)) else: return u_1415 return h_1416(g1969()) return g1968 f_1418 = g1970() w_1417 = 62 def g1967(): def g1966(x_1419): return (w_1417)-(x_1419) return g1966 return f_1418(g1967(), (75)*(w_1417)) def g1983(): """ >>> g1983() True """ t_1421 = True f_1420 = False def g1982(): return [t_1421,f_1420] bools_1424 = g1982() def g1981(): def g1980(x_1422): if ((not x_1422)): return f_1420 else: return t_1421 return g1980 id_1423 = g1981() def g1979(): def g1976(x_1428): def g1978(): def g1977(): return x_1428 == 0 return id_1423(g1977()) if (g1978()): return (bools_1424[0]) else: return odd_1425((x_1428)-(1)) return g1976 even_1426 = g1979() def g1975(): def g1972(y_1427): def g1974(): return y_1427 == 0 if (g1974()): def g1973(): return (bools_1424[1]) return id_1423(g1973()) else: return even_1426((y_1427)-(1)) return g1972 odd_1425 = g1975() return odd_1425(5) def g1990(): """ >>> g1990() 48 """ def g1989(): def g1984(x_1431, y_1430, z_1429): def g1988(): def g1987(u_1435, v_1434): x_1431 = u_1435 return (x_1431)+(v_1434) return g1987 f_1437 = g1988() def g1986(): def g1985(r_1433, s_1432): y_1430 = (z_1429)+(s_1432) return y_1430 return g1985 g_1436 = g1986() return (f_1437(1, 2))*(g_1436(3, 4)) return g1984 return g1989()(10, 11, 12) def g1997(): """ >>> g1997() 176 """ def g1996(): def g1991(x_1440, y_1439, z_1438): f_1444 = False def g1995(): def g1994(r_1442, s_1441): y_1439 = (z_1438)+(s_1441) return y_1439 return g1994 g_1443 = g1995() def g1993(): def g1992(u_1446, v_1445): v_1445 = u_1446 return (x_1440)+(v_1445) return g1992 f_1444 = g1993() return (f_1444(1, 2))*(g_1443(3, 4)) return g1991 return g1996()(10, 11, 12) def g2002(): """ >>> g2002() 5 """ def g2001(): def g2000(x_1450): return (x_1450)+(1) return g2000 f_1448 = g2001() def g1999(): def g1998(y_1449): return f_1448(f_1448(y_1449)) return g1998 g_1447 = g1999() return (f_1448(1))+(g_1447(1)) def g2010(): """ >>> g2010() 1521 """ y_1451 = 3 def g2009(): def g2007(x_1457): def g2008(): return x_1457 == 0 if (g2008()): return g_1453((x_1457)+(1)) else: return f_1454((x_1457)-(y_1451)) return g2007 f_1454 = g2009() def g2006(): def g2005(x_1456): return h_1452((x_1456)*(x_1456)) return g2005 g_1453 = g2006() def g2004(): def g2003(x_1455): return x_1455 return g2003 h_1452 = g2004() return g_1453(39) def g2017(): """ >>> g2017() -1 """ def g2014(): def g2013(x_1461): return (x_1461)+(1) return g2013 f_1459 = g2014() def g2012(): def g2011(y_1460): return f_1459(f_1459(y_1460)) return g2011 g_1458 = g2012() def g2016(): def g2015(x_1462): return (x_1462)-(1) return g2015 f_1459 = g2016() return (f_1459(1))+(g_1458(1)) def g2032(): """ >>> g2032() [52, [17, [35, [17, 35]]]] """ def g2031(): def g2030(): return (a_1465)+(b_1464) return g2030 f_1466 = g2031() a_1465 = 17 b_1464 = 35 def g2029(): def g2028(): def g2027(): return a_1465 return g2027 def g2026(): def g2025(): return b_1464 return g2025 return [g2028(),g2026()] h_1463 = g2029() def g2024(): def g2023(): def g2022(): def g2021(): def g2020(): return (h_1463[0]) return g2020()() def g2019(): def g2018(): return (h_1463[1]) return g2018()() return [g2021(),g2019()] return [b_1464,g2022()] return [a_1465,g2023()] return [f_1466(),g2024()] def g2038(): """ >>> g2038() 120 """ x_1469 = 5 def g2037(): a_1467 = 1 def g2036(): return a_1467 return g2036 th_1468 = g2037() def g2035(): def g2033(n_1472, th_1471): def g2034(): return n_1472 == 0 if (g2034()): return th_1471() else: return (n_1472)*(fact_1470((n_1472)-(1), th_1471)) return g2033 fact_1470 = g2035() return fact_1470(x_1469, th_1468) def g2046(): """ >>> g2046() [120, -120] """ def g2045(): def g2044(n_1473): return (n_1473 < 0) return g2044 negative_1474 = g2045() def g2043(): def g2041(n_1478): def g2042(): return n_1478 == 0 if (g2042()): return 1 else: return (n_1478)*(fact_1476((n_1478)-(1))) return g2041 fact_1476 = g2043() def g2040(): def g2039(n_1477): if ((not negative_1474(n_1477))): return fact_1476(n_1477) else: return (0)-(fact_1476((0)-(n_1477))) return g2039 call_fact_1475 = g2040() return [call_fact_1475(5),call_fact_1475(-5)] def g2050(): """ >>> g2050() [0, 1, 2, 3] """ def g2049(): def g2048(v_1482, i_1481, n_1480): if ((not (i_1481 == n_1480))): v_1482[i_1481] = i_1481 return iota_fill_1479(v_1482, (i_1481)+(1), n_1480) return g2048 iota_fill_1479 = g2049() n_1483 = 4 def g2047(): return ([0]*n_1483) v_1484 = g2047() iota_fill_1479(v_1484, 0, n_1483) return v_1484 def g2061(): """ >>> g2061() [[33, 55], [77, 99]] """ def g2060(): def g2059(): def g2058(): def g2057(): def g2051(a_1485): def g2052(b_1486): def g2053(c_1487): def g2054(d_1488): def g2056(): return [a_1485,b_1486] def g2055(): return [c_1487,d_1488] return [g2056(),g2055()] return g2054 return g2053 return g2052 return g2051 return g2057()(33) return g2058()(55) return g2059()(77) return g2060()(99) def g2075(): """ >>> g2075() [[[3, [21, [18, []]]], [4, [28, [24, []]]]], [[[0, [0, [0, []]]], [1, [7, [6, []]]]], [[408, 408], []]]] """ a_1489 = 17 def g2074(): def g2064(x_1490): x1_1492 = (x_1490)+(1) x2_1491 = (x_1490)+(2) y1_1494 = (x1_1492)*(7) y2_1493 = (x2_1491)*(7) z1_1496 = (y1_1494)-(x1_1492) z2_1495 = (y2_1493)-(x2_1491) w1_1498 = (z1_1496)*(a_1489) w2_1497 = (z2_1495)*(a_1489) def g2073(): def g2068(b_1500): if ((b_1500 == a_1489)): def g2072(): def g2071(): return [z1_1496,[]] return [y1_1494,g2071()] return [x1_1492,g2072()] else: def g2070(): def g2069(): return [z2_1495,[]] return [y2_1493,g2069()] return [x2_1491,g2070()] return g2068 g_1502 = g2073() def g2067(): def g2066(c_1499): if ((c_1499 == x_1490)): return w1_1498 else: return w2_1497 return g2066 h_1501 = g2067() def g2065(): if (((x_1490)*(x_1490) == (x_1490)+(x_1490))): return True else: return (x_1490 < 0) if (g2065()): return [g_1502(17),g_1502(16)] else: return [h_1501(x_1490),h_1501((x_1490)-(0))] return g2064 f_1503 = g2074() def g2063(): def g2062(): return [f_1503(3),[]] return [f_1503(-1),g2062()] return [f_1503(2),g2063()] Cython-0.23.4/tests/run/closure_tests_3.pyx0000644000175600017570000003366012606202452022044 0ustar jenkinsjenkins00000000000000# mode: run # tag: closures # preparse: id # preparse: def_to_cdef # # closure_tests_3.pyx # # Battery of tests for closures in Cython. Based on the collection of # compiler tests from P423/B629 at Indiana University, Spring 1999 and # Fall 2000. Special thanks to R. Kent Dybvig, Dan Friedman, Kevin # Millikin, and everyone else who helped to generate the original # tests. Converted into a collection of Python/Cython tests by Craig # Citro. # # Note: This set of tests is split (somewhat randomly) into several # files, simply because putting all the tests in a single file causes # gcc and g++ to buckle under the load. # def g1649(): """ >>> g1649() 6 """ def g1648(): def g1647(x_1211): return x_1211 return g1647 f_1212 = g1648() if (f_1212(True)): f_1212(3) f_1212(4) else: f_1212(5) return f_1212(6) def g1653(): """ >>> g1653() 5 """ def g1652(): def g1651(x_1213): return (x_1213+1) return g1651 f_1214 = g1652() def g1650(): f_1215 = 3 return (f_1215)+(1) return f_1214(g1650()) def g1662(): """ >>> g1662() 51 """ x_1223 = 15 def g1661(): def g1660(h_1219, v_1218): return (h_1219)*(v_1218) return g1660 f_1222 = g1661() def g1659(): def g1658(x_1217): return (x_1217)+(5) return g1658 k_1221 = g1659() def g1657(): def g1656(x_1216): return (x_1216+1) return g1656 g_1220 = g1657() def g1655(): def g1654(): g_1224 = 3 return f_1222(g_1224, x_1223) return g_1220(g1654()) return k_1221(g1655()) def g1665(): """ >>> g1665() 5 """ x_1225 = 4 def g1664(): def g1663(): return x_1225 return g1663 f_1226 = g1664() x_1225 = 5 return f_1226() def g1670(): """ >>> g1670() 5 """ def g1669(): def g1668(): def g1667(): def g1666(): return 4 return g1666 y_1227 = g1667() return y_1227() return (g1668()+1) x_1228 = g1669() return x_1228 def g1674(): """ >>> g1674() 1 """ def g1673(): def g1671(n_1230): def g1672(): return n_1230 == 0 if (g1672()): return 1 else: return one_1229((n_1230-1)) return g1671 one_1229 = g1673() return one_1229(13) def g1681(): """ >>> g1681() True """ def g1680(): def g1678(x_1234): def g1679(): return x_1234 == 0 if (g1679()): return True else: return odd_1231((x_1234-1)) return g1678 even_1232 = g1680() def g1677(): def g1675(x_1233): def g1676(): return x_1233 == 0 if (g1676()): return False else: return even_1232((x_1233-1)) return g1675 odd_1231 = g1677() return odd_1231(13) def g1688(): """ >>> g1688() True """ t_1236 = True f_1235 = False def g1687(): def g1685(x_1240): def g1686(): return x_1240 == 0 if (g1686()): return t_1236 else: return odd_1237((x_1240-1)) return g1685 even_1238 = g1687() def g1684(): def g1682(x_1239): def g1683(): return x_1239 == 0 if (g1683()): return f_1235 else: return even_1238((x_1239-1)) return g1682 odd_1237 = g1684() return odd_1237(13) def g1698(): """ >>> g1698() True """ def g1697(): def g1696(x_1241): return x_1241 return g1696 even_1242 = g1697() def g1695(): def g1694(): def g1692(x_1246): def g1693(): return x_1246 == 0 if (g1693()): return True else: return odd_1243((x_1246-1)) return g1692 even_1244 = g1694() def g1691(): def g1689(x_1245): def g1690(): return x_1245 == 0 if (g1690()): return False else: return even_1244((x_1245-1)) return g1689 odd_1243 = g1691() return odd_1243(13) return even_1242(g1695()) def g1702(): """ >>> g1702() 120 """ def g1701(): def g1699(n_1248): def g1700(): return n_1248 == 0 if (g1700()): return 1 else: return (n_1248)*(fact_1247((n_1248-1))) return g1699 fact_1247 = g1701() return fact_1247(5) def g1716(): """ >>> g1716() 10 """ x_1249 = 5 def g1715(): def g1713(u_1263, v_1262, w_1261): def g1714(): return u_1263 == 0 if (g1714()): return b_1251(v_1262, w_1261) else: return a_1252((u_1263)-(1), v_1262, w_1261) return g1713 a_1252 = g1715() def g1712(): def g1705(q_1255, r_1254): p_1256 = (q_1255)*(r_1254) def g1711(): def g1709(n_1260): def g1710(): return n_1260 == 0 if (g1710()): return c_1250(p_1256) else: return o_1257((n_1260)-(1)) return g1709 e_1258 = g1711() def g1708(): def g1706(n_1259): def g1707(): return n_1259 == 0 if (g1707()): return c_1250(x_1249) else: return e_1258((n_1259)-(1)) return g1706 o_1257 = g1708() return e_1258((q_1255)*(r_1254)) return g1705 b_1251 = g1712() def g1704(): def g1703(x_1253): return (5)*(x_1253) return g1703 c_1250 = g1704() return a_1252(3, 2, 1) def g1729(): """ >>> g1729() 537516 """ def g1728(): def g1727(x_1269): return (x_1269+1) return g1727 f_1276 = g1728() def g1726(): def g1725(x_1268): return (x_1268-1) return g1725 g_1275 = g1726() def g1724(): def g1723(x_1267): return (x_1267+1) return g1723 t_1274 = g1724() def g1722(): def g1721(x_1266): return (x_1266+1) return g1721 j_1273 = g1722() def g1720(): def g1719(x_1265): return (x_1265+1) return g1719 i_1272 = g1720() def g1718(): def g1717(x_1264): return (x_1264+1) return g1717 h_1271 = g1718() x_1270 = 80 a_1279 = f_1276(x_1270) b_1278 = g_1275(x_1270) c_1277 = h_1271(i_1272(j_1273(t_1274(x_1270)))) return (a_1279)*((b_1278)*((c_1277)+(0))) def g1733(): """ >>> g1733() 120 """ def g1732(): def g1730(fact_1281, n_1280): def g1731(): return n_1280 == 0 if (g1731()): return 1 else: return (fact_1281(fact_1281, (n_1280-1)))*(n_1280) return g1730 fact_1282 = g1732() return fact_1282(fact_1282, 5) def g1737(): """ >>> g1737() 10000 """ def g1736(): def g1735(x_1283): return (x_1283)+(1000) return g1735 f_1284 = g1736() def g1734(): return f_1284(-2) == 0 if (g1734()): return f_1284(6000) else: return f_1284(f_1284(8000)) def g1741(): """ >>> g1741() 10000 """ def g1740(): def g1739(x_1285): return (x_1285)+(1000) return g1739 f_1286 = g1740() def g1738(): return f_1286(-1) == 0 if (g1738()): return f_1286(6000) else: return f_1286(f_1286(8000)) def g1747(): """ >>> g1747() 8000 """ def g1746(): def g1745(x_1288, y_1287): return (x_1288)+(1000) return g1745 f_1289 = g1746() def g1744(): def g1743(): def g1742(): return 0 return f_1289(3000, g1742()) if (g1743()): return f_1289(f_1289(4000, 0), 0) else: return 8000 return (g1744())+(2000) def g1754(): """ >>> g1754() 24 """ def g1753(): def g1752(): def g1751(): def g1748(x_1290): def g1749(y_1291): def g1750(z_1292): return (x_1290)+((y_1291)+((z_1292)+(y_1291))) return g1750 return g1749 return g1748 return g1751()(5) return g1752()(6) return g1753()(7) def g1765(): """ >>> g1765() 35 """ def g1764(): def g1763(): def g1762(): def g1761(): def g1760(): def g1755(x_1293): def g1756(y_1294): def g1757(z_1295): def g1758(w_1296): def g1759(u_1297): return (x_1293)+((y_1294)+((z_1295)+((w_1296)+(u_1297)))) return g1759 return g1758 return g1757 return g1756 return g1755 return g1760()(5) return g1761()(6) return g1762()(7) return g1763()(8) return g1764()(9) def g1769(): """ >>> g1769() True """ def g1768(): def g1767(x_1298): return x_1298 return g1767 f_1299 = g1768() def g1766(): return hasattr(f_1299, '__call__') if (g1766()): return True else: return False def g1779(): """ >>> g1779() 6 """ def g1778(): def g1773(sum_1301, ls_1300): def g1777(): return (ls_1300 == []) if (g1777()): return 0 else: def g1776(): return (ls_1300[0]) def g1775(): def g1774(): return (ls_1300[1]) return sum_1301(sum_1301, g1774()) return (g1776())+(g1775()) return g1773 sum_1302 = g1778() def g1772(): def g1771(): def g1770(): return [3,[]] return [2,g1770()] return [1,g1771()] return sum_1302(sum_1302, g1772()) def g1785(): """ >>> g1785() 1500 """ def g1784(): def g1783(): def g1780(a_1303): def g1781(): def g1782(): if (True): return 200 (a_1303)+(g1782()) return 1500 return g1781 return g1780 return g1783()(1000) return g1784()() def g1791(): """ >>> g1791() 102 """ def g1790(): def g1789(): def g1786(b_1304): def g1787(a_1305): def g1788(): if (1): return 2 a_1305 = g1788() return (a_1305)+(b_1304) return g1787 return g1786 return g1789()(100) return g1790()(200) def g1800(): """ >>> g1800() 2600 """ def g1799(): def g1798(): def g1797(): def g1792(a_1306): def g1793(b_1307): def g1794(): if (b_1307): return 200 a_1306 = g1794() def g1795(c_1308): def g1796(): if (300): return 400 c_1308 = g1796() return (a_1306)+((b_1307)+(c_1308)) return g1795 return g1793 return g1792 return g1797()(1000) return g1798()(2000) return g1799()(3000) def g1807(): """ >>> g1807() 3628800 """ def g1806(): def g1804(x_1310): def g1805(): return x_1310 == 0 if (g1805()): return 1 else: return (x_1310)*(f_1309((x_1310)-(1))) return g1804 f_1309 = g1806() def g1803(): def g1801(a_1311): def g1802(b_1312): return a_1311(b_1312) return g1802 return g1801 g_1313 = g1803() return g_1313(f_1309)(10) def g1828(): """ >>> g1828() [52, [44, [17, [44, [52, 17]]]]] """ def g1827(): def g1826(): return (a_1316)+(b_1315) return g1826 f_1318 = g1827() def g1825(): def g1822(y_1320): def g1824(): def g1823(y_1321): return y_1321 return g1823 g_1317 = g1824() return (y_1320)+(y_1320) return g1822 g_1317 = g1825() a_1316 = 17 b_1315 = 35 def g1821(): def g1820(): def g1819(): return a_1316 return g1819 def g1818(): def g1817(v_1319): a_1316 = v_1319 return g1817 return [g1820(),g1818()] h_1314 = g1821() x1_1324 = f_1318() x2_1323 = g_1317(22) def g1816(): def g1815(): return (h_1314[0]) return g1815()() x3_1322 = g1816() x4_1325 = g_1317(22) def g1814(): return (h_1314[1]) g1814()(3) x5_1327 = f_1318() def g1813(): def g1812(): return (h_1314[0]) return g1812()() x6_1326 = g1813() def g1811(): def g1810(): def g1809(): def g1808(): return [x5_1327,x6_1326] return [x4_1325,g1808()] return [x3_1322,g1809()] return [x2_1323,g1810()] return [x1_1324,g1811()] def g1843(): """ >>> g1843() [52, [17, [35, [17, 35]]]] """ def g1842(): def g1841(): return (a_1330)+(b_1329) return g1841 f_1331 = g1842() a_1330 = 17 b_1329 = 35 def g1840(): def g1839(): def g1838(): return a_1330 return g1838 def g1837(): def g1836(): return b_1329 return g1836 return [g1839(),g1837()] h_1328 = g1840() def g1835(): def g1834(): def g1833(): def g1832(): def g1831(): return (h_1328[0]) return g1831()() def g1830(): def g1829(): return (h_1328[1]) return g1829()() return [g1832(),g1830()] return [b_1329,g1833()] return [a_1330,g1834()] return [f_1331(),g1835()] Cython-0.23.4/tests/run/closure_tests_2.pyx0000644000175600017570000002204512606202452022036 0ustar jenkinsjenkins00000000000000# mode: run # tag: closures # preparse: id # preparse: def_to_cdef # # closure_tests_2.pyx # # Battery of tests for closures in Cython. Based on the collection of # compiler tests from P423/B629 at Indiana University, Spring 1999 and # Fall 2000. Special thanks to R. Kent Dybvig, Dan Friedman, Kevin # Millikin, and everyone else who helped to generate the original # tests. Converted into a collection of Python/Cython tests by Craig # Citro. # # Note: This set of tests is split (somewhat randomly) into several # files, simply because putting all the tests in a single file causes # gcc and g++ to buckle under the load. # def g1526(): """ >>> g1526() 2 """ x_1134 = 0 def g1525(): x_1136 = 1 z_1135 = x_1134 def g1524(y_1137): return (x_1136)+((z_1135)+(y_1137)) return g1524 f_1138 = g1525() return f_1138(f_1138(x_1134)) def g1535(): """ >>> g1535() 3050 """ def g1534(): def g1533(): def g1531(t_1141): def g1532(f_1142): return t_1141(f_1142(1000)) return g1532 return g1531 def g1530(): def g1529(x_1140): return (x_1140)+(50) return g1529 return g1533()(g1530()) def g1528(): def g1527(y_1139): return (y_1139)+(2000) return g1527 return g1534()(g1528()) def g1540(): """ >>> g1540() 2050 """ def g1539(): t_1143 = 50 def g1538(f_1144): return (t_1143)+(f_1144()) return g1538 def g1537(): def g1536(): return 2000 return g1536 return g1539()(g1537()) def g1547(): """ >>> g1547() 2050 """ def g1546(): def g1545(): def g1543(t_1145): def g1544(f_1146): return (t_1145)+(f_1146()) return g1544 return g1543 return g1545()(50) def g1542(): def g1541(): return 2000 return g1541 return g1546()(g1542()) def g1550(): """ >>> g1550() 700 """ def g1549(): x_1147 = 300 def g1548(y_1148): return (x_1147)+(y_1148) return g1548 return g1549()(400) def g1553(): """ >>> g1553() 0 """ x_1152 = 3 def g1552(): def g1551(x_1150, y_1149): return x_1150 return g1551 f_1151 = g1552() if (f_1151(0, 0)): return f_1151(f_1151(0, 0), x_1152) else: return 0 def g1562(): """ >>> g1562() False """ def g1561(): def g1556(x_1153): def g1560(): def g1559(): return isinstance(x_1153, list) if (g1559()): def g1558(): def g1557(): return (x_1153[0]) return (g1557() == 0) return (not g1558()) else: return False if (g1560()): return x_1153 else: return False return g1556 f_1154 = g1561() def g1555(): def g1554(): return [0,[]] return [0,g1554()] return f_1154(g1555()) def g1570(): """ >>> g1570() False """ def g1569(): def g1563(x_1155): def g1568(): if (x_1155): def g1567(): def g1566(): return isinstance(x_1155, list) if (g1566()): def g1565(): def g1564(): return (x_1155[0]) return (g1564() == 0) return (not g1565()) else: return False return (not g1567()) else: return False if (g1568()): return x_1155 else: return False return g1563 f_1156 = g1569() return f_1156(0) def g1575(): """ >>> g1575() [] """ def g1574(): def g1571(x_1157): def g1573(): def g1572(): return isinstance(x_1157, list) if (g1572()): return True else: return (x_1157 == []) if (g1573()): return x_1157 else: return [] return g1571 f_1158 = g1574() return f_1158(0) def g1578(): """ >>> g1578() 4 """ y_1159 = 4 def g1577(): def g1576(y_1160): return y_1160 return g1576 f_1161 = g1577() return f_1161(f_1161(y_1159)) def g1581(): """ >>> g1581() 0 """ y_1162 = 4 def g1580(): def g1579(x_1164, y_1163): return 0 return g1579 f_1165 = g1580() return f_1165(f_1165(y_1162, y_1162), f_1165(y_1162, y_1162)) def g1584(): """ >>> g1584() 0 """ y_1166 = 4 def g1583(): def g1582(x_1168, y_1167): return 0 return g1582 f_1169 = g1583() return f_1169(f_1169(y_1166, y_1166), f_1169(y_1166, f_1169(y_1166, y_1166))) def g1587(): """ >>> g1587() 0 """ y_1170 = 4 def g1586(): def g1585(x_1172, y_1171): return 0 return g1585 f_1173 = g1586() return f_1173(f_1173(y_1170, f_1173(y_1170, y_1170)), f_1173(y_1170, f_1173(y_1170, y_1170))) def g1594(): """ >>> g1594() 4 """ def g1593(): def g1588(y_1174): def g1592(): def g1591(f_1176): return f_1176(f_1176(y_1174)) return g1591 def g1590(): def g1589(y_1175): return y_1175 return g1589 return g1592()(g1590()) return g1588 return g1593()(4) def g1598(): """ >>> g1598() 23 """ def g1597(): def g1596(x_1177): return x_1177 return g1596 f_1178 = g1597() def g1595(): if (False): return 1 else: return f_1178(22) return (g1595()+1) def g1603(): """ >>> g1603() 22 """ def g1602(): def g1601(x_1179): return x_1179 return g1601 f_1180 = g1602() def g1600(): def g1599(): return 23 == 0 return f_1180(g1599()) if (g1600()): return 1 else: return 22 def g1611(): """ >>> g1611() 5061 """ def g1610(): def g1609(x_1182): if (x_1182): return (not x_1182) else: return x_1182 return g1609 f_1185 = g1610() def g1608(): def g1607(x_1181): return (10)*(x_1181) return g1607 f2_1184 = g1608() x_1183 = 23 def g1606(): def g1605(): def g1604(): return x_1183 == 0 return f_1185(g1604()) if (g1605()): return 1 else: return (x_1183)*(f2_1184((x_1183-1))) return (g1606()+1) def g1614(): """ >>> g1614() 1 """ def g1613(): def g1612(): return 0 return g1612 f_1186 = g1613() x_1187 = f_1186() return 1 def g1617(): """ >>> g1617() 1 """ def g1616(): def g1615(): return 0 return g1615 f_1188 = g1616() f_1188() return 1 def g1620(): """ >>> g1620() 4 """ def g1619(): def g1618(x_1189): return x_1189 return g1618 f_1190 = g1619() if (True): f_1190(3) return 4 else: return 5 def g1623(): """ >>> g1623() 6 """ def g1622(): def g1621(x_1191): return x_1191 return g1621 f_1192 = g1622() (f_1192(4)) if (True) else (5) return 6 def g1627(): """ >>> g1627() 120 """ def g1626(): def g1624(fact_1195, n_1194, acc_1193): def g1625(): return n_1194 == 0 if (g1625()): return acc_1193 else: return fact_1195(fact_1195, (n_1194-1), (n_1194)*(acc_1193)) return g1624 fact_1196 = g1626() return fact_1196(fact_1196, 5, 1) def g1632(): """ >>> g1632() 144 """ def g1631(): def g1628(b_1199, c_1198, a_1197): b_1203 = (b_1199)+(a_1197) def g1630(): def g1629(): a_1201 = (b_1199)+(b_1199) c_1200 = (c_1198)+(c_1198) return (a_1201)+(a_1201) return (a_1197)+(g1629()) a_1202 = g1630() return (a_1202)*(a_1202) return g1628 return g1631()(2, 3, 4) def g1639(): """ >>> g1639() 3 """ def g1638(): def g1636(x_1204): def g1637(): return x_1204() return g1637 return g1636 f_1205 = g1638() def g1635(): def g1634(): def g1633(): return 3 return g1633 return f_1205(g1634()) return g1635()() def g1646(): """ >>> g1646() 3628800 """ def g1645(): def g1643(x_1207): def g1644(): return x_1207 == 0 if (g1644()): return 1 else: return (x_1207)*(f_1206((x_1207)-(1))) return g1643 f_1206 = g1645() q_1208 = 17 def g1642(): def g1640(a_1209): q_1208 = 10 def g1641(): return a_1209(q_1208) return g1641 return g1640 g_1210 = g1642() return g_1210(f_1206)() Cython-0.23.4/tests/run/closure_tests_1.pyx0000644000175600017570000001552312606202452022040 0ustar jenkinsjenkins00000000000000# mode: run # tag: closures # preparse: id # preparse: def_to_cdef # # closure_tests_1.pyx # # Battery of tests for closures in Cython. Based on the collection of # compiler tests from P423/B629 at Indiana University, Spring 1999 and # Fall 2000. Special thanks to R. Kent Dybvig, Dan Friedman, Kevin # Millikin, and everyone else who helped to generate the original # tests. Converted into a collection of Python/Cython tests by Craig # Citro. # # Note: This set of tests is split (somewhat randomly) into several # files, simply because putting all the tests in a single file causes # gcc and g++ to buckle under the load. # def g1425(): """ >>> g1425() 142 """ if (True): def g1424(): if (True): return 122 return (20)+(g1424()) else: return 10000 def g1432(): """ >>> g1432() [0, []] """ def g1431(): return [0,[]] x_1056 = g1431() if (x_1056): def g1430(): def g1429(): return (x_1056[0]) def g1428(): return (x_1056[0]) return (g1429())+(g1428()) x_1056[0] = g1430() return x_1056 def g1435(): """ >>> g1435() 4000 """ def g1434(): def g1433(y_1057): return y_1057 return g1433 return g1434()(4000) def g1438(): """ >>> g1438() 1 """ def g1437(): def g1436(x_1058): return x_1058 return g1436 f_1059 = g1437() return (f_1059(0)+1) def g1441(): """ >>> g1441() 4 """ def g1440(): def g1439(y_1060): return y_1060 return g1439 f_1061 = g1440() return f_1061(f_1061(4)) def g1446(): """ >>> g1446() 4 """ def g1445(): def g1444(f_1063): return f_1063(f_1063(4)) return g1444 def g1443(): def g1442(y_1062): return y_1062 return g1442 return g1445()(g1443()) def g1449(): """ >>> g1449() 9000 """ def g1448(): a_1064 = 4000 def g1447(b_1065): return (a_1064)+(b_1065) return g1447 return g1448()(5000) def g1454(): """ >>> g1454() 9000 """ def g1453(): def g1452(): def g1450(a_1066): def g1451(b_1067): return (a_1066)+(b_1067) return g1451 return g1450 return g1452()(4000) return g1453()(5000) def g1459(): """ >>> g1459() 2 """ def g1458(): def g1457(f_1069): return f_1069(f_1069(0)) return g1457 def g1456(): def g1455(x_1068): return (x_1068+1) return g1455 return g1458()(g1456()) def g1462(): """ >>> g1462() 0 """ x_1072 = 0 def g1461(): def g1460(x_1070): return x_1070 return g1460 f_1071 = g1461() a_1075 = f_1071(x_1072) b_1074 = f_1071(x_1072) c_1073 = f_1071(x_1072) return ((a_1075)+(b_1074))+(c_1073) def g1465(): """ >>> g1465() 3 """ x_1080 = 0 y_1079 = 1 z_1078 = 2 def g1464(): def g1463(x_1076): return x_1076 return g1463 f_1077 = g1464() a_1083 = f_1077(x_1080) b_1082 = f_1077(y_1079) c_1081 = f_1077(z_1078) return ((a_1083)+(b_1082))+(c_1081) def g1468(): """ >>> g1468() 0 """ def g1467(): def g1466(x_1085, y_1084): return x_1085 return g1466 f_1086 = g1467() a_1087 = f_1086(0, 1) return f_1086(a_1087, a_1087) def g1471(): """ >>> g1471() 0 """ x_1094 = 0 y_1093 = 1 z_1092 = 2 def g1470(): def g1469(x_1090, y_1089, z_1088): return x_1090 return g1469 f_1091 = g1470() a_1097 = f_1091(x_1094, y_1093, z_1092) b_1096 = y_1093 c_1095 = z_1092 return f_1091(a_1097, b_1096, c_1095) def g1474(): """ >>> g1474() 3 """ def g1473(): def g1472(a_1101, b_1100, c_1099, d_1098): return (a_1101)+(d_1098) return g1472 f_1102 = g1473() return f_1102(0, 1, 2, 3) def g1478(): """ >>> g1478() 3 """ def g1477(): def g1476(x_1103): return x_1103 return g1476 f_1104 = g1477() def g1475(): a_1107 = 0 b_1106 = 1 c_1105 = 2 return (f_1104(a_1107))+((f_1104(b_1106))+(f_1104(c_1105))) return (f_1104(0))+(g1475()) def g1483(): """ >>> g1483() """ a_1108 = 0 def g1482(): def g1481(): return 0 return g1481 a_1110 = g1482() def g1480(): def g1479(): return 11 return g1479 b_1109 = g1480() a_1110 = 11 def g1486(): """ >>> g1486() """ a_1111 = 0 def g1485(): def g1484(): a_1113 = 0 return g1484 a_1113 = g1485() b_1112 = 11 return a_1113() def g1491(): """ >>> g1491() 0 """ def g1490(): def g1489(): return 0 return g1489 a_1115 = g1490() def g1488(): def g1487(): return 11 return g1487 b_1114 = g1488() return a_1115() def g1494(): """ >>> g1494() 2 """ def g1493(): x_1116 = 1 def g1492(y_1117): return (x_1116)+(y_1117) return g1492 f_1118 = g1493() x_1119 = 0 return f_1118(f_1118(x_1119)) def g1501(): """ >>> g1501() 3050 """ def g1500(): def g1499(): def g1498(x_1121): return (x_1121)+(50) return g1498 t_1122 = g1499() def g1497(f_1123): return t_1122(f_1123(1000)) return g1497 def g1496(): def g1495(y_1120): return (y_1120)+(2000) return g1495 return g1500()(g1496()) def g1508(): """ >>> g1508() 60 """ def g1507(): def g1506(): def g1505(): def g1502(a_1124): def g1503(b_1125): def g1504(c_1126): return (a_1124)+((b_1125)+(c_1126)) return g1504 return g1503 return g1502 return g1505()(10) return g1506()(20) return g1507()(30) def g1513(): """ >>> g1513() 5 """ def g1512(): def g1509(b_1127): def g1511(): def g1510(a_1128): return (b_1127)+(a_1128) return g1510 return g1511()(2) return g1509 return g1512()(3) def g1518(): """ >>> g1518() 5 """ def g1517(): def g1516(f_1130): return f_1130(f_1130(5)) return g1516 def g1515(): def g1514(x_1129): return x_1129 return g1514 return g1517()(g1515()) def g1523(): """ >>> g1523() 8000 """ def g1522(): def g1521(): def g1520(x_1131): return (x_1131)+(3000) return g1520 f_1132 = g1521() def g1519(y_1133): return f_1132(f_1132(y_1133)) return g1519 return g1522()(2000) Cython-0.23.4/tests/run/closure_self.pyx0000644000175600017570000000225612606202452021406 0ustar jenkinsjenkins00000000000000# mode: run # tag: closures cdef class Test: cdef int x cdef class SelfInClosure(object): cdef Test _t cdef int x def plain(self): """ >>> o = SelfInClosure() >>> o.plain() 1 """ self.x = 1 return self.x def closure_method(self): """ >>> o = SelfInClosure() >>> o.closure_method()() == o True """ def nested(): return self return nested def closure_method_cdef_attr(self, Test t): """ >>> o = SelfInClosure() >>> o.closure_method_cdef_attr(Test())() (1, 2) """ t.x = 2 self._t = t self.x = 1 def nested(): return self.x, t.x return nested def call_closure_method_cdef_attr_c(self, Test t): """ >>> o = SelfInClosure() >>> o.call_closure_method_cdef_attr_c(Test())() (1, 2) """ return self.closure_method_cdef_attr_c(t) cdef closure_method_cdef_attr_c(self, Test t): t.x = 2 self._t = t self.x = 1 def nested(): return self.x, t.x return nested Cython-0.23.4/tests/run/closure_name_mangling_T537.pyx0000644000175600017570000000055612606202452023774 0ustar jenkinsjenkins00000000000000# mode: run # tag: closures # ticket: 537 __doc__ = u""" >>> f1 = nested1() >>> f2 = nested2() >>> f1 == f2 # inner functions (f) False >>> f1() == f2() # inner-inner functions (g) False """ def nested1(): def f(): def g(): pass return g return f def nested2(): def f(): def g(): pass return g return f Cython-0.23.4/tests/run/closure_inside_cdef_T554.pyx0000644000175600017570000000077512606202452023436 0ustar jenkinsjenkins00000000000000# mode: run # tag: closures # ticket: 554 def call_f(x): """ >>> call_f(2) 4 """ return f(x) cdef f(x): # def here => works fine def g(y): return y*x # cdef here => compile error return g(x) # faults@ INCREF(.*cur_scope->.*v_x def closure_in_void(): """ >>> genex = closure_in_void() >>> list(genex) ['a', 'b', 'c'] """ l = [] add_gen(l) return l[0] cdef void add_gen(l): x = "abc" l.append((c for c in x)) Cython-0.23.4/tests/run/closure_inlining.pyx0000644000175600017570000000754512606202452022272 0ustar jenkinsjenkins00000000000000# cython: optimize.inline_defnode_calls=True # mode: run cimport cython @cython.test_fail_if_path_exists('//SimpleCallNode') @cython.test_assert_path_exists('//InlinedDefNodeCallNode') def simple_noargs(): """ >>> simple_noargs() 123 """ def inner(): return 123 return inner() @cython.test_fail_if_path_exists('//SimpleCallNode') @cython.test_assert_path_exists('//InlinedDefNodeCallNode') def test_coerce(a, int b): """ >>> test_coerce(2, 2) 4 """ def inner(int a, b): return a * b return inner(a, b) cdef class Foo(object): def __repr__(self): return '' @cython.test_fail_if_path_exists('//SimpleCallNode') @cython.test_assert_path_exists('//InlinedDefNodeCallNode') def test_func_signature(a): """ >>> test_func_signature(Foo()) >>> test_func_signature(123) Traceback (most recent call last): TypeError: Cannot convert int to closure_inlining.Foo """ def inner(Foo a): return a return inner(a) @cython.test_fail_if_path_exists('//SimpleCallNode') @cython.test_assert_path_exists('//InlinedDefNodeCallNode') def test_func_signature2(a, b): """ >>> test_func_signature2(Foo(), 123) (, 123) >>> test_func_signature2(321, 123) Traceback (most recent call last): TypeError: Cannot convert int to closure_inlining.Foo """ def inner(Foo a, b): return a, b return inner(a, b) # Starred args and default values are not yet supported for inlining @cython.test_assert_path_exists('//SimpleCallNode') def test_defaults(a, b): """ >>> test_defaults(1, 2) (1, 2, 123) """ def inner(a, b=b, c=123): return a, b, c return inner(a) @cython.test_assert_path_exists('//SimpleCallNode') def test_kwonly_args(a, b): """ >>> test_kwonly_args(1, 2) (1, 2, 123) """ def inner(a, b=b, *, c=123): return a, b, c return inner(a) @cython.test_assert_path_exists('//SimpleCallNode') def test_kwonly_args_missing(a, b): """ >>> test_kwonly_args_missing(1, 2) Traceback (most recent call last): TypeError: inner() needs keyword-only argument c """ def inner(a, b=b, *, c): return a, b, c return inner(a) @cython.test_assert_path_exists('//SimpleCallNode') def test_starred(a): """ >>> test_starred(123) (123, (), {}) """ def inner(a, *args, **kwargs): return a, args, kwargs return inner(a) def test_global_calls_still_work(): """ >>> global_call_result 123 """ return 123 global_call_result = test_global_calls_still_work() @cython.test_fail_if_path_exists( '//InlinedDefNodeCallNode//SimpleCallNode') @cython.test_assert_path_exists( '//InlinedDefNodeCallNode', '//InlinedDefNodeCallNode[@function_name.name = "call"]', '//InlinedDefNodeCallNode//InlinedDefNodeCallNode') def test_sideeffect_call_order(): """ >>> test_sideeffect_call_order() [2, 4, 5] """ L = [] def sideeffect(x): L.append(x) return x def call(x1, x2, x3, x4, x5): pass call(1, sideeffect(2), 3, sideeffect(4), sideeffect(5)) return L def test_redef(redefine): """ >>> test_redef(False) 1 >>> test_redef(True) 2 """ def inner(): return 1 def inner2(): return 2 def redef(): nonlocal inner inner = inner2 if redefine: redef() assert inner == inner2 else: assert inner != inner2 return inner() def test_with_statement(): """ >>> test_with_statement() enter running exit """ def make_context_manager(): class CM(object): def __enter__(self): print "enter" def __exit__(self, *args): print "exit" return CM() with make_context_manager(): print "running" Cython-0.23.4/tests/run/closure_decorators_T478.pyx0000644000175600017570000000206512606202452023346 0ustar jenkinsjenkins00000000000000# mode: run # tag: closures # ticket: 478 __doc__ = """ >>> Num(13).is_prime() args (Num(13),) kwds {} True >>> Num(13).is_prime(True) args (Num(13), True) kwds {} True >>> Num(15).is_prime(print_factors=True) args (Num(15),) kwds {'print_factors': True} 3 5 False """ def print_args(func): def f(*args, **kwds): print "args", args, "kwds", kwds return func(*args, **kwds) return f cdef class Num: cdef int n def __init__(self, n): self.n = n def __repr__(self): return "Num(%s)" % self.n @print_args def is_prime(self, bint print_factors=False): if self.n == 2: return True elif self.n < 2: return False elif self.n % 2 == 0: if print_factors: print 2, self.n // 2 cdef int i = 3 while i*i <= self.n: if self.n % i == 0: if print_factors: print i, self.n // i return False i += 2 return True Cython-0.23.4/tests/run/closure_class_T596.pyx0000644000175600017570000000210112606202452022276 0ustar jenkinsjenkins00000000000000# mode: run # tag: closures # ticket: 596 def simple(a, b): """ >>> kls = simple(1, 2) >>> kls().result() 3 """ class Foo: def result(self): return a + b return Foo def nested_classes(a, b): """ >>> kls = nested_classes(1, 2) >>> kls().result(-3) 0 """ class Foo: class Bar: def result(self, c): return a + b + c return Foo.Bar def staff(a, b): """ >>> kls = staff(1, 2) >>> kls.static() (1, 2) >>> kls.klass() ('Foo', 1, 2) >>> obj = kls() >>> obj.member() (1, 2) """ class Foo: def member(self): return a, b @staticmethod def static(): return a, b @classmethod def klass(cls): return cls.__name__, a, b return Foo def nested2(a): """ >>> obj = nested2(1) >>> f = obj.run(2) >>> f() 3 """ class Foo: def run(self, b): def calc(): return a + b return calc return Foo() Cython-0.23.4/tests/run/closure_arg_type_error.pyx0000644000175600017570000000205612606202452023476 0ustar jenkinsjenkins00000000000000# mode: run # tag: closures # The arguments in f() are put into the closure one after the other, # so the reference of 'o' is filled in before the type errors are # found. This leaves a reference in the closure instance on error # return, which must be properly ref-counted to facilitate generic # closure deallocation. In the case of an argument type error, it's # actually best to just Py_CLEAR() the already handled references, as # this frees them as early as possible. # This test doesn't really check the ref-counting itself, it just # reproduces the problem. def func_with_typed_args(object o, int i, tuple t, double d): """ >>> g = func_with_typed_args(1, 2, (), 3.0) >>> g() (1, 2, (), 3.0) >>> g = func_with_typed_args(1, 'x', (), 3.0) Traceback (most recent call last): TypeError: an integer is required >>> g = func_with_typed_args(1, 2, 3, 3.0) Traceback (most recent call last): TypeError: Argument 't' has incorrect type (expected tuple, got int) """ def g(): return o, i, t, d return g Cython-0.23.4/tests/run/clone_type.pyx0000644000175600017570000000047212606202452021060 0ustar jenkinsjenkins00000000000000cdef class MyType: def dup(self): """ >>> x1 = MyType() >>> isinstance(x1, MyType) True >>> x2 = x1.dup() >>> isinstance(x2, MyType) True >>> x1 != x2 True """ cdef MyType clone = type(self)() return clone Cython-0.23.4/tests/run/clear_to_null.pyx0000644000175600017570000000351512606202452021542 0ustar jenkinsjenkins00000000000000""" Check that Cython generates a tp_clear function that actually clears object references to NULL instead of None. Discussed here: http://article.gmane.org/gmane.comp.python.cython.devel/14833 """ from cpython.ref cimport PyObject, Py_TYPE cdef class ExtensionType: """ Just a type which is handled by a specific C type (instead of PyObject) to check that tp_clear works when the C pointer is of a type different from PyObject *. """ # Pull tp_clear for PyTypeObject as I did not find another way to access it # from Cython code. cdef extern from "Python.h": ctypedef struct PyTypeObject: void (*tp_clear)(object) cdef class TpClearFixture: """ An extension type that has a tp_clear method generated to test that it actually clears the references to NULL. >>> fixture = TpClearFixture() >>> isinstance(fixture.extension_type, ExtensionType) True >>> isinstance(fixture.any_object, str) True >>> fixture.call_tp_clear() >>> fixture.check_any_object_status() 'NULL' >>> fixture.check_extension_type_status() 'NULL' """ cdef readonly object any_object cdef readonly ExtensionType extension_type def __cinit__(self): self.any_object = "Hello World" self.extension_type = ExtensionType() def call_tp_clear(self): cdef PyTypeObject *pto = Py_TYPE(self) pto.tp_clear(self) def check_any_object_status(self): if (self.any_object) == NULL: return 'NULL' elif self.any_object is None: return 'None' else: return 'not cleared' def check_extension_type_status(self): if (self.any_object) == NULL: return 'NULL' elif self.any_object is None: return 'None' else: return 'not cleared' Cython-0.23.4/tests/run/classpass.pyx0000644000175600017570000000026512606202452020713 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> s = Spam() >>> s.__class__.__name__ 'Spam' >>> s = SpamT() >>> type(s).__name__ 'SpamT' """ class Spam: pass class SpamT(object): pass Cython-0.23.4/tests/run/classmethod.pyx0000644000175600017570000000137512606202452021230 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> class1.view() class1 >>> class1.plus(1) 6 >>> class2.view() class2 >>> class2.plus(1) 7 >>> class3.view() class3 >>> class3.plus(1) 8 >>> class4.view() class4 >>> class5.view() class5 """ def f_plus(cls, a): return cls.a + a class class1: a = 5 plus = classmethod(f_plus) def view(cls): print cls.__name__ view = classmethod(view) class class2(object): a = 6 plus = classmethod(f_plus) def view(cls): print cls.__name__ view = classmethod(view) cdef class class3: a = 7 plus = classmethod(f_plus) def view(cls): print cls.__name__ view = classmethod(view) class class4: @classmethod def view(cls): print cls.__name__ class class5(class4): pass Cython-0.23.4/tests/run/classkwonlyargs.pyx0000644000175600017570000000555312606202452022152 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> spam = Spam() >>> b,c,d,e,f,g,h,k = spam.b,spam.c,spam.d,spam.e,spam.f,spam.g,spam.h,spam.k >>> b(1,2,3) >>> b(1,2,3,4) Traceback (most recent call last): TypeError: b() takes exactly 4 positional arguments (5 given) >>> c(1,2) >>> c(1,2,3) >>> c(1,2,3,4) Traceback (most recent call last): TypeError: c() takes at most 4 positional arguments (5 given) >>> d(1,2) >>> d(1,2, c=1) >>> d(1,2,3) Traceback (most recent call last): TypeError: d() takes exactly 3 positional arguments (4 given) >>> d(1,2, d=1) Traceback (most recent call last): TypeError: d() got an unexpected keyword argument 'd' >>> e(1,2) >>> e(1,2, c=1) >>> e(1,2, d=1) >>> e(1,2, c=1, d=2, e=3) >>> e(1,2,3) >>> e(1,2,3,4) Traceback (most recent call last): TypeError: e() takes at most 4 positional arguments (5 given) >>> f(1,2, c=1) >>> f(1,2, c=1, d=2) >>> f(1,2,3) Traceback (most recent call last): TypeError: f() takes exactly 3 positional arguments (4 given) >>> f(1,2) Traceback (most recent call last): TypeError: f() needs keyword-only argument c >>> f(1,2, c=1, e=2) Traceback (most recent call last): TypeError: f() got an unexpected keyword argument 'e' >>> g(1,2, c=1, f=2) >>> g(1,2, c=1, e=0, f=2, d=11) >>> g(1,2, c=1, f=2, e=0, x=25) >>> g(1,2,3) Traceback (most recent call last): TypeError: g() takes exactly 3 positional arguments (4 given) >>> g(1,2) Traceback (most recent call last): TypeError: g() needs keyword-only argument c >>> g(1,2, c=1) Traceback (most recent call last): TypeError: g() needs keyword-only argument f >>> h(1,2, c=1, f=2) >>> h(1,2, c=1, f=2, e=3) >>> h(1,2,3,4,5,6, c=1, f=2) >>> h(1,2,3,4,5,6, c=1, f=2, e=3, x=25, y=11) >>> h(1,2,3) Traceback (most recent call last): TypeError: h() needs keyword-only argument c >>> h(1,2, d=1) Traceback (most recent call last): TypeError: h() needs keyword-only argument c >>> k(1,2, c=1, f=2) >>> k(1,2, c=1, f=2, e=3) >>> k(1,2,3,4,5,6, d=1, f=2) >>> k(1,2,3,4,5,6, d=1, f=2, e=3, x=25, y=11) >>> k(1,2,3) Traceback (most recent call last): TypeError: k() needs keyword-only argument f >>> k(1,2, d=1) Traceback (most recent call last): TypeError: k() needs keyword-only argument f """ class Spam: def b(self, a, b, c): pass def c(self, a, b, c=1): pass def d(self, a, b, *, c = 88): pass def e(self, a, b, c = 88, **kwds): pass def f(self, a, b, *, c, d = 42): pass def g(self, a, b, *, c, d = 42, e = 17, f, **kwds): pass def h(self, a, b, *args, c, d = 42, e = 17, f, **kwds): pass def k(self, a, b, c=1, *args, d = 42, e = 17, f, **kwds): pass Cython-0.23.4/tests/run/classdecorators_T336.pyx0000644000175600017570000000151412606202452022627 0ustar jenkinsjenkins00000000000000# ticket: 336 __doc__ = u""" >>> print('\\n'.join(calls)) Py-Honk PyTestClass PyTestClass Py-Hello PyTestClass PyTestClass Py-Done PyTestClass >>> c = PyTestClass() Ho, Ho, Ho! """ calls = [] class print_msg(object): def __init__(self, message): self.msg = message def __call__(self, c): calls.append( self.msg + c.__name__ ) return c def print_name(c): calls.append( c.__name__ ) return c @print_msg(u"Py-Done ") @print_name @print_msg(u"Py-Hello ") @print_name @print_msg(u"Py-Honk ") class PyTestClass(object): def __init__(self): print u"Ho, Ho, Ho!" # not currently working: # ## @print_msg("Cy-Done ") ## @print_name ## @print_msg("Cy-Hello ") ## @print_name ## @print_msg("Cy-Honk ") ## cdef class CyTestClass(object): ## def __init__(self): ## print u"Ho, Ho, Ho!" Cython-0.23.4/tests/run/classbody_exec.pyx0000644000175600017570000000037012606202452021703 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> print(D) {u'answer': (42, 42)} """ import sys if sys.version_info[0] >= 3: __doc__ = __doc__.replace(u"u'", u"'") D = {} def foo(x): return x, x cdef class Spam: answer = 42 D[u'answer'] = foo(answer) Cython-0.23.4/tests/run/class_scope_del_T684.py0000644000175600017570000000042412606202452022373 0ustar jenkinsjenkins00000000000000# mode:run # tag: class, scope, del # ticket: 684 class DelInClass(object): """ >>> DelInClass.y 5 >>> DelInClass.x Traceback (most recent call last): AttributeError: type object 'DelInClass' has no attribute 'x' """ x = 5 y = x del x Cython-0.23.4/tests/run/class_scope.py0000644000175600017570000000027412606202452021025 0ustar jenkinsjenkins00000000000000# mode:run # tag: class, scope class MethodRedef(object): """ >>> MethodRedef().a(5) 7 """ def a(self, i): return i+1 def a(self, i): return i+2 Cython-0.23.4/tests/run/class_redefine.py0000644000175600017570000000041612606202452021473 0ustar jenkinsjenkins00000000000000 class set(object): def __init__(self, x): self.x = x SET = set([1]) class set(object): def __init__(self, x): self.X = x def test_class_redef(x): """ >>> SET.x [1] >>> test_class_redef(2).X [2] """ return set([x]) Cython-0.23.4/tests/run/class_func_in_control_structures_T87.pyx0000644000175600017570000000201412606202452026224 0ustar jenkinsjenkins00000000000000# ticket: 87 __doc__ = u""" >>> d = Defined() >>> n = NotDefined() # doctest: +ELLIPSIS 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 Cython-0.23.4/tests/run/class_attribute_init_values_T18.pyx0000644000175600017570000000136212606202452025144 0ustar jenkinsjenkins00000000000000# ticket: 18 __doc__ = u""" >>> f = PyFoo() >>> print(f.bar) 5 >>> print(f.baz) someval >>> f = MyPyFoo() >>> print(f.bar) 7 >>> print(f.baz) anotherval >>> f = CyFoo() >>> print(f.bar) 5 >>> print(f.baz) anotherval >>> f = MyCyFoo() >>> print(f.bar) 7 >>> print(f.baz) anotherval >>> f = AnotherFoo() >>> print(f.bar) 8 >>> print(f.baz) yetanotherval """ # this works: class PyFoo(object): bar = 5 baz = u"someval" class MyPyFoo(PyFoo): bar = 7 baz = u"anotherval" # this doesn't: cdef class CyFoo: cdef public int bar = 5 cdef public object baz = u"someval" cdef class MyCyFoo(CyFoo): cdef public int bar = 7 cdef public object baz = u"anotherval" class AnotherFoo(CyFoo): bar = 8 baz = u"yetanotherval" Cython-0.23.4/tests/run/cintop.pyx0000644000175600017570000000131412606202452020207 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> int2 = 42 >>> int3 = 7 >>> char1 = ord('C') >>> int1 = int2 | int3 >>> int1 |= int2 ^ int3 >>> int1 ^= int2 & int3 >>> int1 ^= int2 << int3 >>> int1 ^= int2 >> int3 >>> int1 ^= int2 << int3 | int2 >> int3 >>> long1 = char1 | int1 >>> (int1, long1) == f() True """ def f(): """ >>> f() (45, 111) """ cdef int int1, int2, int3 cdef char char1 cdef long long1, long2 int2 = 42 int3 = 7 char1 = c'C' int1 = int2 | int3 int1 |= int2 ^ int3 int1 ^= int2 & int3 int1 ^= int2 << int3 int1 ^= int2 >> int3 int1 ^= int2 << int3 | int2 >> int3 long1 = char1 | int1 return int1, long1 Cython-0.23.4/tests/run/cimport_from_sys_path.srctree0000644000175600017570000000105412606202452024155 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import a" ######## setup.py ######## from Cython.Build import cythonize from distutils.core import setup # Add ./site-packages to sys.path from os.path import realpath import sys sys.path.append(realpath('site-packages')) setup( ext_modules = cythonize("*.pyx"), ) ######## site-packages/b/__init__.py ######## ######## site-packages/b/other.pxd ######## cdef inline foo(int a): return a**2 ######## a.pyx ######## from b.other cimport foo print foo(10) cimport b.other print b.other.foo(10) Cython-0.23.4/tests/run/cimport_from_pyx.srctree0000644000175600017570000000210412606202452023140 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import a" ######## setup.py ######## from Cython.Build.Dependencies import cythonize import Cython.Compiler.Options Cython.Compiler.Options.cimport_from_pyx = True from distutils.core import setup setup( ext_modules = cythonize("*.pyx"), ) ######## a.pyx ######## from b cimport Bclass, Bfunc, Bstruct, Benum, Benum_value, Btypedef, Py_EQ, Py_NE cdef Bclass b = Bclass(5) assert Bfunc(&b.value) == b.value assert b.asStruct().value == b.value cdef Btypedef b_type = &b.value cdef Benum b_enum = Benum_value cdef int tmp = Py_EQ #from c cimport ClassC #cdef ClassC c = ClassC() #print c.value ######## b.pyx ######## from cpython.object cimport Py_EQ, Py_NE cdef enum Benum: Benum_value cdef struct Bstruct: int value ctypedef long *Btypedef cdef class Bclass: cdef long value def __init__(self, value): self.value = value cdef Bstruct asStruct(self): return Bstruct(value=self.value) cdef long Bfunc(Btypedef x): return x[0] ######## c.pxd ######## cdef class ClassC: cdef int value Cython-0.23.4/tests/run/cimport_cython_T505.pyx0000644000175600017570000000040612606202452022472 0ustar jenkinsjenkins00000000000000# ticket: 505 cimport cython cdef extern from "Python.h": cdef cython.unicode PyUnicode_DecodeUTF8(char* s, Py_ssize_t size, char* errors) def test_capi(): """ >>> print(test_capi()) abc """ return PyUnicode_DecodeUTF8("abc", 3, NULL) Cython-0.23.4/tests/run/cimport_alias_subclass_helper.pxd0000644000175600017570000000005112606202452024747 0ustar jenkinsjenkins00000000000000cdef class Base: cdef bint foo(self) Cython-0.23.4/tests/run/cimport_alias_subclass.pyx0000644000175600017570000000034112606202452023437 0ustar jenkinsjenkins00000000000000# mode: compile cimport cimport_alias_subclass_helper as cash cdef class Derived(cash.Base): cdef bint foo(self): print "Hello" def run(): """ >>> run() Hello """ d = Derived() d.foo() Cython-0.23.4/tests/run/cimport.srctree0000644000175600017570000000073612606202452021226 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import a" ######## setup.py ######## from Cython.Build import cythonize from distutils.core import setup setup( ext_modules = cythonize("*.pyx"), ) ######## other.pxd ######## cdef class A: pass cdef int foo(int) ######## other.pyx ######## cdef class A: pass cdef int foo(int a): return a**2 ######## a.pyx ######## from other cimport A, foo print A, foo(10) cimport other print other.A, other.foo(10) Cython-0.23.4/tests/run/check_fused_types_pxd.pxd0000644000175600017570000000007512606202452023233 0ustar jenkinsjenkins00000000000000cimport cython unresolved_t = cython.fused_type(int, float) Cython-0.23.4/tests/run/check_fused_types.pyx0000644000175600017570000001005512606202452022404 0ustar jenkinsjenkins00000000000000cimport cython cimport check_fused_types_pxd import math ctypedef char *string_t fused_t = cython.fused_type(int, long, float, string_t) other_t = cython.fused_type(int, long) base_t = cython.fused_type(short, int) # complex_t = cython.fused_type(cython.floatcomplex, cython.doublecomplex) cdef fused complex_t: float complex double complex ctypedef base_t **base_t_p_p # ctypedef cython.fused_type(char, base_t_p_p, fused_t, complex_t) composed_t cdef fused composed_t: char int float string_t cython.pp_int float complex double complex int complex long complex cdef func(fused_t a, other_t b): cdef int int_a cdef string_t string_a cdef other_t other_a if fused_t is other_t: print 'fused_t is other_t' other_a = a if fused_t is int: print 'fused_t is int' int_a = a if fused_t is string_t: print 'fused_t is string_t' string_a = a if fused_t in check_fused_types_pxd.unresolved_t: print 'fused_t in unresolved_t' if int in check_fused_types_pxd.unresolved_t: print 'int in unresolved_t' if string_t in check_fused_types_pxd.unresolved_t: print 'string_t in unresolved_t' def test_int_int(): """ >>> test_int_int() fused_t is other_t fused_t is int fused_t in unresolved_t int in unresolved_t """ cdef int x = 1 cdef int y = 2 func(x, y) def test_int_long(): """ >>> test_int_long() fused_t is int fused_t in unresolved_t int in unresolved_t """ cdef int x = 1 cdef long y = 2 func(x, y) def test_float_int(): """ >>> test_float_int() fused_t in unresolved_t int in unresolved_t """ cdef float x = 1 cdef int y = 2 func(x, y) def test_string_int(): """ >>> test_string_int() fused_t is string_t int in unresolved_t """ cdef string_t x = b"spam" cdef int y = 2 func(x, y) cdef if_then_else(fused_t a, other_t b): cdef other_t other_a cdef string_t string_a cdef fused_t specific_a if fused_t is other_t: print 'fused_t is other_t' other_a = a elif fused_t is string_t: print 'fused_t is string_t' string_a = a else: print 'none of the above' specific_a = a def test_if_then_else_long_long(): """ >>> test_if_then_else_long_long() fused_t is other_t """ cdef long x = 0, y = 0 if_then_else(x, y) def test_if_then_else_string_int(): """ >>> test_if_then_else_string_int() fused_t is string_t """ cdef string_t x = b"spam" cdef int y = 0 if_then_else(x, y) def test_if_then_else_float_int(): """ >>> test_if_then_else_float_int() none of the above """ cdef float x = 0.0 cdef int y = 1 if_then_else(x, y) cdef composed_t composed(composed_t x, composed_t y): if composed_t in base_t_p_p or composed_t is string_t: if string_t == composed_t: print x.decode('ascii'), y.decode('ascii') else: print x[0][0], y[0][0] return x elif composed_t == string_t: print 'this is never executed' elif list(): print 'neither is this one' else: if composed_t not in complex_t: print 'not a complex number' print x, y else: print 'it is a complex number' print x.real, x.imag return x + y def test_composed_types(): """ >>> test_composed_types() it is a complex number 0.5 0.6 9 4 not a complex number 7 8 15 7 8 spam eggs spam """ cdef double complex a = 0.5 + 0.6j, b = 0.4 -0.2j, result cdef int c = 7, d = 8 cdef int *cp = &c, *dp = &d cdef string_t e = "spam", f = "eggs" result = composed(a, b) print int(math.ceil(result.real * 10)), int(math.ceil(result.imag * 10)) print print composed(c, d) print composed(&cp, &dp) print print composed(e, f).decode('ascii') Cython-0.23.4/tests/run/charptr_len.pyx0000644000175600017570000000252312606202452021217 0ustar jenkinsjenkins00000000000000cimport cython cdef char* s = b"abcdefg" cdef unsigned char* us = b"abcdefg" cdef bytes pystr = b"abcdefg" @cython.test_assert_path_exists( "//PythonCapiCallNode", ) def lentest_char(): """ >>> lentest_char() 7 """ return len(s) @cython.test_assert_path_exists( "//PythonCapiCallNode", ) def lentest_char_c(): """ >>> lentest_char_c() 7 """ cdef Py_ssize_t l = len(s) return l @cython.test_assert_path_exists( "//PythonCapiCallNode", ) def lentest_char_c_short(): """ >>> lentest_char_c_short() 7 """ cdef short l = len(s) return l @cython.test_assert_path_exists( "//PythonCapiCallNode", ) def lentest_char_c_float(): """ >>> lentest_char_c_float() 7.0 """ cdef float l = len(s) return l @cython.test_assert_path_exists( "//PythonCapiCallNode", ) def lentest_uchar(): """ >>> lentest_uchar() 7 """ return len(us) @cython.test_assert_path_exists( "//PythonCapiCallNode", ) def lentest_uchar_c(): """ >>> lentest_uchar_c() 7 """ cdef Py_ssize_t l = len(us) return l def lentest_py(): """ >>> lentest_py() 7 """ return len(pystr) def lentest_py_c(): """ >>> lentest_py_c() 7 """ cdef Py_ssize_t l = len(pystr) return l Cython-0.23.4/tests/run/charptr_from_temp.pyx0000644000175600017570000000356412606202452022437 0ustar jenkinsjenkins00000000000000# mode: run from cpython.version cimport PY_MAJOR_VERSION cdef bint IS_PY2 = PY_MAJOR_VERSION == 2 cdef cfunc1(char* s): if IS_PY2: return s else: return s.decode('ASCII') cdef cfunc3(int x, char* s, object y): return cfunc1(s) def test_one_arg_indexing(s): """ >>> test_one_arg_indexing(b'xyz') 'y' """ cfunc1(s[0]) if IS_PY2 else cfunc1(s[:1]) z = cfunc1(s[2]) if IS_PY2 else cfunc1(s[2:]) assert z == 'z', repr(z) return cfunc1(s[1]) if IS_PY2 else cfunc1(s[1:2]) def test_more_args_indexing(s): """ >>> test_more_args_indexing(b'xyz') 'y' """ cfunc3(1, s[0 if IS_PY2 else slice(0,1)], 6.5) z = cfunc3(2, s[2 if IS_PY2 else slice(2,None)], 'abc' * 2) assert z == 'z', repr(z) return cfunc3(3, s[1 if IS_PY2 else slice(1,2)], 1) def test_one_arg_slicing(s): """ >>> test_one_arg_slicing(b'xyz') 'y' """ cfunc1(s[:2]) z = cfunc1(s[2:]) assert z == 'z', repr(z) return cfunc1(s[1:2]) def test_more_args_slicing(s): """ >>> test_more_args_slicing(b'xyz') 'y' """ cfunc3(1, s[:2], 'abc') z = cfunc3(123, s[2:], 5) assert z == 'z', repr(z) return cfunc3(2, s[1:2], 1.4) def test_one_arg_adding(s): """ >>> test_one_arg_adding(b'xyz') 'abxyzqr' """ return cfunc1(b"a" + b"b" + s + b"q" + b"r") def test_more_args_adding(s): """ >>> test_more_args_adding(b'xyz') 'abxyzqr' """ return cfunc3(1, b"a" + b"b" + s + b"q" + b"r", 'xyz%d' % 3) cdef char* ret_charptr(char* s): return s def test_charptr_and_charptr_func(char* s): """ >>> test_charptr_and_charptr_func(b'abc') == b'abc' True """ return s and ret_charptr(s) def test_charptr_and_ucharptr(char* s): """ >>> test_charptr_and_ucharptr(b'abc') == b'abc' True """ return s and s Cython-0.23.4/tests/run/charptr_decode.pyx0000644000175600017570000001062412606202452021665 0ustar jenkinsjenkins00000000000000 cimport cython ############################################################ # tests for char* slicing cdef char* cstring = "abcABCqtp" @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def slice_charptr_decode(): """ >>> print(str(slice_charptr_decode()).replace("u'", "'")) ('a', 'abc', 'abcABCqtp') """ return (cstring[:1].decode('UTF-8'), cstring[:3].decode('UTF-8'), cstring[:9].decode('UTF-8')) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def slice_charptr_decode_platform_encoding(): """ >>> print(str(slice_charptr_decode()).replace("u'", "'")) ('a', 'abc', 'abcABCqtp') """ cdef bytes s = u'abcABCqtp'.encode() cdef char* cstr = s return (cstr[:1].decode(), cstr[:3].decode(), cstr[:9].decode()) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def slice_charptr_decode_unknown_encoding(): """ >>> print(str(slice_charptr_decode_unknown_encoding()).replace("u'", "'")) ('abcABCqtp', 'abcABCqtp', 'abc', 'abcABCqt') """ cdef char* enc = 'UTF-8' cdef char* error_handling = 'strict' return (cstring.decode(enc), cstring.decode(enc, error_handling), cstring[:3].decode(enc), cstring[:8].decode(enc, error_handling)) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def slice_charptr_decode_slice2(): """ >>> print(str(slice_charptr_decode_slice2()).replace("u'", "'")) ('a', 'bc', 'tp') """ return (cstring[0:1].decode('UTF-8'), cstring[1:3].decode('UTF-8'), cstring[7:9].decode('UTF-8')) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def slice_charptr_decode_strlen(): """ >>> print(str(slice_charptr_decode_strlen()).replace("u'", "'")) ('abcABCqtp', 'bcABCqtp', '', 'BCq', 'abcA', '') """ return (cstring.decode('UTF-8'), cstring[1:].decode('UTF-8'), cstring[9:].decode('UTF-8'), cstring[-5:-2].decode('UTF-8'), cstring[:-5].decode('UTF-8'), cstring[:-9].decode('UTF-8')) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def slice_charptr_decode_unbound(): """ >>> print(str(slice_charptr_decode_unbound()).replace("u'", "'")) ('a', 'abc', 'abcABCqtp') """ return (bytes.decode(cstring[:1], 'UTF-8'), bytes.decode(cstring[:3], 'UTF-8', 'replace'), bytes.decode(cstring[:9], 'UTF-8')) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def slice_charptr_decode_errormode(): """ >>> print(str(slice_charptr_decode_errormode()).replace("u'", "'")) ('a', 'abc', 'abcABCqtp') """ return (cstring[:1].decode('UTF-8', 'strict'), cstring[:3].decode('UTF-8', 'replace'), cstring[:9].decode('UTF-8', 'unicode_escape')) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def slice_charptr_dynamic_bounds(): """ >>> print(str(slice_charptr_dynamic_bounds()).replace("u'", "'")) ('abc', 'abc', 'bcAB', 'BCqtp') """ return (cstring[:return3()].decode('UTF-8'), cstring[0:return3()].decode('UTF-8'), cstring[return1():return5()].decode('UTF-8'), cstring[return4():return9()].decode('UTF-8')) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//AttributeNode") def slice_charptr_dynamic_bounds_non_name(): """ >>> print(str(slice_charptr_dynamic_bounds_non_name()).replace("u'", "'")) ('bcA', 'bcA', 'BCqtp', 'ABCqtp', 'bcABCqtp', 'bcABCqtp', 'cABC') """ return ((cstring+1)[:return3()].decode('UTF-8'), (cstring+1)[0:return3()].decode('UTF-8'), (cstring+1)[return3():].decode('UTF-8'), (cstring+1)[2:].decode('UTF-8'), (cstring+1)[0:].decode('UTF-8'), (cstring+1)[:].decode('UTF-8'), (cstring+1)[return1():return5()].decode('UTF-8')) cdef return1(): return 1 cdef return3(): return 3 cdef return4(): return 4 cdef return5(): return 5 cdef return9(): return 9 Cython-0.23.4/tests/run/charptr_comparison_T582.pyx0000644000175600017570000000761212606202452023341 0ustar jenkinsjenkins00000000000000# ticket: 582 cimport cython ################################################################################ ## plain char* @cython.test_assert_path_exists('//SingleAssignmentNode') #@cython.test_fail_if_path_exists('//SingleAssignmentNode//CoerceFromPyTypeNode') def charptr_equals_literal(char* s): """ >>> charptr_equals_literal('abc'.encode('ASCII')) True >>> charptr_equals_literal('aabc'.encode('ASCII')) False >>> charptr_equals_literal('abcx'.encode('ASCII')) False >>> charptr_equals_literal('bcx'.encode('ASCII')) False """ cdef bint result = (s == b"abc") return result def charptr_gt_literal(char* s): """ >>> charptr_gt_literal('abc'.encode('ASCII')) False >>> charptr_gt_literal('aabc'.encode('ASCII')) False >>> charptr_gt_literal('abcx'.encode('ASCII')) True >>> charptr_gt_literal('bcx'.encode('ASCII')) True """ cdef bint result = (s > b"abc") return result def charptr_lt_literal(char* s): """ >>> charptr_lt_literal('abc'.encode('ASCII')) False >>> charptr_lt_literal('aabc'.encode('ASCII')) True >>> charptr_lt_literal('abcx'.encode('ASCII')) False >>> charptr_lt_literal('bcx'.encode('ASCII')) False """ cdef bint result = (s < b"abc") return result def charptr_ge_literal(char* s): """ >>> charptr_ge_literal('abc'.encode('ASCII')) True >>> charptr_ge_literal('aabc'.encode('ASCII')) False >>> charptr_ge_literal('abcx'.encode('ASCII')) True >>> charptr_ge_literal('bcx'.encode('ASCII')) True """ cdef bint result = (s >= b"abc") return result def charptr_le_literal(char* s): """ >>> charptr_le_literal('abc'.encode('ASCII')) True >>> charptr_le_literal('aabc'.encode('ASCII')) True >>> charptr_le_literal('abcx'.encode('ASCII')) False >>> charptr_le_literal('bcx'.encode('ASCII')) False """ cdef bint result = (s <= b"abc") return result ################################################################################ ## slices @cython.test_assert_path_exists('//SingleAssignmentNode') #FIXME: optimise me! #@cython.test_fail_if_path_exists('//SingleAssignmentNode//CoerceFromPyTypeNode') def slice_equals_literal(char* s): """ >>> slice_equals_literal('abc'.encode('ASCII')) True >>> slice_equals_literal('aabc'.encode('ASCII')) False >>> slice_equals_literal('abcx'.encode('ASCII')) True >>> slice_equals_literal('bcx'.encode('ASCII')) False """ cdef bint result = (s[:3] == b"abc") return result def slice_gt_literal(char* s): """ >>> slice_gt_literal('abc'.encode('ASCII')) False >>> slice_gt_literal('aabc'.encode('ASCII')) False >>> slice_gt_literal('abcx'.encode('ASCII')) False >>> slice_gt_literal('bcx'.encode('ASCII')) True """ cdef bint result = (s[:3] > b"abc") return result def slice_lt_literal(char* s): """ >>> slice_lt_literal('abc'.encode('ASCII')) False >>> slice_lt_literal('aabc'.encode('ASCII')) True >>> slice_lt_literal('abcx'.encode('ASCII')) False >>> slice_lt_literal('bcx'.encode('ASCII')) False """ cdef bint result = (s[:3] < b"abc") return result def slice_ge_literal(char* s): """ >>> slice_ge_literal('abc'.encode('ASCII')) True >>> slice_ge_literal('aabc'.encode('ASCII')) False >>> slice_ge_literal('abcx'.encode('ASCII')) True >>> slice_ge_literal('bcx'.encode('ASCII')) True """ cdef bint result = (s[:3] >= b"abc") return result def slice_le_literal(char* s): """ >>> slice_le_literal('abc'.encode('ASCII')) True >>> slice_le_literal('aabc'.encode('ASCII')) True >>> slice_le_literal('abcx'.encode('ASCII')) True >>> slice_le_literal('bcx'.encode('ASCII')) False """ cdef bint result = (s[:3] <= b"abc") return result Cython-0.23.4/tests/run/charescape.pyx0000644000175600017570000000245712606202452021022 0ustar jenkinsjenkins00000000000000import sys if sys.version_info[0] < 3: __doc__ = u""" >>> s = test() >>> assert s == ''.join(map(chr, range(1,49))), repr(s) """ else: __doc__ = u""" >>> s = test() >>> assert s == bytes(range(1,49)), repr(s) """ def test(): cdef char[50] s s[ 0] = c'\0' s[ 1] = c'\x01' s[ 2] = c'\x02' s[ 3] = c'\x03' s[ 4] = c'\x04' s[ 5] = c'\x05' s[ 6] = c'\x06' s[ 7] = c'\x07' s[ 8] = c'\x08' s[ 9] = c'\x09' s[10] = c'\x0A' s[11] = c'\x0B' s[12] = c'\x0C' s[13] = c'\x0D' s[14] = c'\x0E' s[15] = c'\x0F' s[16] = c'\x10' s[17] = c'\x11' s[18] = c'\x12' s[19] = c'\x13' s[20] = c'\x14' s[21] = c'\x15' s[22] = c'\x16' s[23] = c'\x17' s[24] = c'\x18' s[25] = c'\x19' s[26] = c'\x1A' s[27] = c'\x1B' s[28] = c'\x1C' s[29] = c'\x1D' s[30] = c'\x1E' s[31] = c'\x1F' s[32] = c'\x20' s[33] = c'\x21' s[34] = c'\x22' s[35] = c'\x23' s[36] = c'\x24' s[37] = c'\x25' s[38] = c'\x26' s[39] = c'\x27' s[40] = c'\x28' s[41] = c'\x29' s[42] = c'\x2A' s[43] = c'\x2B' s[44] = c'\x2C' s[45] = c'\x2D' s[46] = c'\x2E' s[47] = c'\x2F' s[48] = c'\x30' s[49] = c'\x00' assert s[ 0] == c'\x00' assert s[49] == c'\0' return &s[1] Cython-0.23.4/tests/run/charencoding.pyx0000644000175600017570000000230412606202452021337 0ustar jenkinsjenkins00000000000000# coding: ASCII import sys if sys.version_info[0] < 3: __doc__ = u""" >>> expected = ''.join([chr(i) for i in range(0x10,0xFF,0x11)] + [chr(0xFF)]) >>> s = test_assign() >>> assert s == expected, repr(s) >>> s = test_array() >>> assert s == expected, repr(s) """ else: __doc__ = u""" >>> expected = bytes(list(range(0x10,0xFF,0x11)) + [0xFF]) >>> s = test_assign() >>> assert s == expected, repr(s) >>> s = test_array() >>> assert s == expected, repr(s) """ def test_assign(): cdef char[17] s s[ 0] = c'\x10' s[ 1] = c'\x21' s[ 2] = c'\x32' s[ 3] = c'\x43' s[ 4] = c'\x54' s[ 5] = c'\x65' s[ 6] = c'\x76' s[ 7] = c'\x87' s[ 8] = c'\x98' s[ 9] = c'\xA9' s[10] = c'\xBA' s[11] = c'\xCB' s[12] = c'\xDC' s[13] = c'\xED' s[14] = c'\xFE' s[15] = c'\xFF' s[16] = c'\x00' return s def test_array(): cdef char* s = [ c'\x10', c'\x21', c'\x32', c'\x43', c'\x54', c'\x65', c'\x76', c'\x87', c'\x98', c'\xA9', c'\xBA', c'\xCB', c'\xDC', c'\xED', c'\xFE', c'\xFF', c'\x00', ] return s Cython-0.23.4/tests/run/charcomparisonT412.pyx0000644000175600017570000000022212606202452022273 0ustar jenkinsjenkins00000000000000# ticket: 412 def f(): """ >>> f() True True """ cdef char a a = 62 print (a == '>') print (a == '>') Cython-0.23.4/tests/run/char_constants_T99.pyx0000644000175600017570000000057612606202452022402 0ustar jenkinsjenkins00000000000000# ticket: 99 cdef char c = 'c' cdef char* s = 'abcdef' def global_c_and_s(): """ >>> global_c_and_s() 99 abcdef """ pys = s print c print (pys.decode(u'ASCII')) def local_c_and_s(): """ >>> local_c_and_s() 98 bcdefg """ cdef char c = 'b' cdef char* s = 'bcdefg' pys = s print c print (pys.decode(u'ASCII')) Cython-0.23.4/tests/run/cfuncdef.pyx0000644000175600017570000000042512606202452020472 0ustar jenkinsjenkins00000000000000cdef void ftang(): cdef int x x = 0 cdef int foo(int i, char c): cdef float f, g f = 0 g = 0 cdef spam(int i, obj, object object): cdef char c c = 0 def test(): """ >>> test() """ ftang() foo(0, c'f') spam(25, None, None) Cython-0.23.4/tests/run/cfunc_convert.pyx0000644000175600017570000001076712606202452021565 0ustar jenkinsjenkins00000000000000# mode: run # cython: always_allow_keywords=True cimport cython from libc.math cimport sqrt cdef void empty_cfunc(): print "here" # same signature cdef void another_empty_cfunc(): print "there" def call_empty_cfunc(): """ >>> call_empty_cfunc() here there """ cdef object py_func = empty_cfunc py_func() cdef object another_py_func = another_empty_cfunc another_py_func() cdef double square_c(double x): return x * x def call_square_c(x): """ >>> call_square_c(2) 4.0 >>> call_square_c(-7) 49.0 """ cdef object py_func = square_c return py_func(x) def return_square_c(): """ >>> square_c = return_square_c() >>> square_c(5) 25.0 >>> square_c(x=4) 16.0 >>> square_c.__doc__ # FIXME: try to make original C function name available 'wrap(x: float) -> float' """ return square_c def return_libc_sqrt(): """ >>> sqrt = return_libc_sqrt() >>> sqrt(9) 3.0 >>> sqrt(x=9) 3.0 >>> sqrt.__doc__ 'wrap(x: float) -> float' """ return sqrt global_csqrt = sqrt def test_global(): """ >>> global_csqrt(9) 3.0 >>> global_csqrt.__doc__ 'wrap(x: float) -> float' >>> test_global() double (double) nogil Python object """ print cython.typeof(sqrt) print cython.typeof(global_csqrt) cdef long long rad(long long x): cdef long long rad = 1 for p in range(2, sqrt(x) + 1): if x % p == 0: rad *= p while x % p == 0: x //= p if x == 1: break return rad cdef bint abc(long long a, long long b, long long c) except -1: if a + b != c: raise ValueError("Not a valid abc candidate: (%s, %s, %s)" % (a, b, c)) return rad(a*b*c) < c def call_abc(a, b, c): """ >>> call_abc(2, 3, 5) False >>> call_abc(1, 63, 64) True >>> call_abc(2, 3**10 * 109, 23**5) True >>> call_abc(a=2, b=3**10 * 109, c=23**5) True >>> call_abc(1, 1, 1) Traceback (most recent call last): ... ValueError: Not a valid abc candidate: (1, 1, 1) """ cdef object py_func = abc return py_func(a, b, c) def return_abc(): """ >>> abc = return_abc() >>> abc(2, 3, 5) False >>> abc.__doc__ "wrap(a: 'long long', b: 'long long', c: 'long long') -> bool" """ return abc ctypedef double foo cdef foo test_typedef_cfunc(foo x): return x def test_typedef(x): """ >>> test_typedef(100) 100.0 """ return (test_typedef_cfunc)(x) cdef union my_union: int a double b cdef struct my_struct: int which my_union y cdef my_struct c_struct_builder(int which, int a, double b): cdef my_struct value value.which = which if which: value.y.a = a else: value.y.b = b return value def return_struct_builder(): """ >>> make = return_struct_builder() >>> d = make(0, 1, 2) >>> d['which'] 0 >>> d['y']['b'] 2.0 >>> d = make(1, 1, 2) >>> d['which'] 1 >>> d['y']['a'] 1 >>> make.__doc__ "wrap(which: 'int', a: 'int', b: float) -> 'my_struct'" """ return c_struct_builder cdef object test_object_params_cfunc(a, b): return a, b def test_object_params(a, b): """ >>> test_object_params(1, 'a') (1, 'a') """ return (test_object_params_cfunc)(a, b) cdef tuple test_builtin_params_cfunc(list a, dict b): return a, b def test_builtin_params(a, b): """ >>> test_builtin_params([], {}) ([], {}) >>> test_builtin_params(1, 2) Traceback (most recent call last): ... TypeError: Argument 'a' has incorrect type (expected list, got int) """ return (test_builtin_params_cfunc)(a, b) def return_builtin_params_cfunc(): """ >>> cfunc = return_builtin_params_cfunc() >>> cfunc([1, 2], {'a': 3}) ([1, 2], {'a': 3}) >>> cfunc.__doc__ 'wrap(a: list, b: dict) -> tuple' """ return test_builtin_params_cfunc cdef class A: def __repr__(self): return self.__class__.__name__ cdef class B(A): pass cdef A test_cdef_class_params_cfunc(A a, B b): return b def test_cdef_class_params(a, b): """ >>> test_cdef_class_params(A(), B()) B >>> test_cdef_class_params(B(), A()) Traceback (most recent call last): ... TypeError: Argument 'b' has incorrect type (expected cfunc_convert.B, got cfunc_convert.A) """ return (test_cdef_class_params_cfunc)(a, b) Cython-0.23.4/tests/run/cfunc_call_tuple_args_T408.pyx0000644000175600017570000000056012606202452023752 0ustar jenkinsjenkins00000000000000# ticket: 408 __doc__ = """ >>> call_with_tuple(1, 1.2, 'test', [1,2,3]) (1, 1.2, 'test', [1, 2, 3]) >>> call_with_list(1, 1.2, None, None) (1, 1.2, None, None) """ cdef c_function(int a, float b, c, list d): return a,b,c,d def call_with_tuple(*args): return c_function(*args) def call_with_list(*args): args = list(args) return c_function(*args) Cython-0.23.4/tests/run/cf_none.pyx0000644000175600017570000000451112606202452020324 0ustar jenkinsjenkins00000000000000 cimport cython @cython.test_fail_if_path_exists('//NoneCheckNode') def none_checks(a): """ >>> none_checks(1) 22 >>> none_checks(None) True """ c = None d = {11:22} if a is c: return True else: return d.get(11) @cython.test_assert_path_exists('//NoneCheckNode') def dict_arg(dict a): """ >>> dict_arg({}) >>> dict_arg({1:2}) 2 """ return a.get(1) @cython.test_fail_if_path_exists('//NoneCheckNode') def dict_arg_not_none(dict a not None): """ >>> dict_arg_not_none({}) >>> dict_arg_not_none({1:2}) 2 """ return a.get(1) @cython.test_assert_path_exists('//NoneCheckNode') def reassignment(dict d): """ >>> reassignment({}) (None, 2) >>> reassignment({1:3}) (3, 2) """ a = d.get(1) d = {1:2} b = d.get(1) return a, b @cython.test_fail_if_path_exists('//NoneCheckNode') def conditional(a): """ >>> conditional(True) 2 >>> conditional(False) 3 """ if a: d = {1:2} else: d = {1:3} return d.get(1) @cython.test_assert_path_exists('//NoneCheckNode') def conditional_arg(a, dict d): """ >>> conditional_arg(True, {1:2}) >>> conditional_arg(False, {1:2}) 2 """ if a: d = {} return d.get(1) @cython.test_fail_if_path_exists('//NoneCheckNode') def conditional_not_none(a, dict d not None): """ >>> conditional_not_none(True, {1:2}) >>> conditional_not_none(False, {1:2}) 2 """ if a: d = {} return d.get(1) @cython.test_fail_if_path_exists('//NoneCheckNode') def self_dependency(int x): """ >>> self_dependency(1) (1, 2) >>> self_dependency(2) (None, None) """ cdef dict a, b a = {1:2} b = {2:1} for i in range(x): a,b = b,a return a.get(2), b.get(1) @cython.test_assert_path_exists('//NoneCheckNode') def self_dependency_none(int x): """ >>> self_dependency_none(False) 1 >>> self_dependency_none(True) Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'get' """ cdef dict a, b a = None b = {2:1} if x: a,b = b,a return b.get(2) @cython.test_fail_if_path_exists('//NoneCheckNode') def in_place_op(): vals = [0] vals += [1] for x in vals: pass Cython-0.23.4/tests/run/cdivision_CEP_516.pyx0000644000175600017570000001100312606202452021760 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> v = [(17, 10), (-17, 10), (-17, -10), (17, -10)] >>> standard = [(a % b) for a, b in v] >>> standard [7, 3, -7, -3] >>> [mod_int_py(a, b) for a, b in v] == standard True >>> [mod_short_py(a, b) for a, b in v] == standard True >>> [mod_float_py(a, b) for a, b in v] == standard True >>> [mod_double_py(a, b) for a, b in v] == standard True >>> [mod_int_c(a, b) for a, b in v] [7, -7, -7, 7] >>> [mod_float_c(a, b) for a, b in v] [7.0, -7.0, -7.0, 7.0] >>> [mod_double_c(a, b) for a, b in v] [7.0, -7.0, -7.0, 7.0] >>> [div_int_py(a, b) for a, b in v] [1, -2, 1, -2] >>> [div_int_c(a, b) for a, b in v] [1, -1, 1, -1] >>> [test_cdiv_cmod(a, b) for a, b in v] [(1, 7), (-1, -7), (1, -7), (-1, 7)] >>> all([mod_int_py(a,b) == a % b for a in range(-10, 10) for b in range(-10, 10) if b != 0]) True >>> all([div_int_py(a,b) == a // b for a in range(-10, 10) for b in range(-10, 10) if b != 0]) True """ import warnings orig_showwarning = warnings.showwarning true_py_functions = {} exec "def simple_warn(msg, *args): print(msg)" in true_py_functions simple_warn = true_py_functions['simple_warn'] del true_py_functions def _all(seq): for x in seq: if not x: return False return True try: all except NameError: all = _all cimport cython @cython.cdivision(False) def mod_int_py(int a, int b): return a % b @cython.cdivision(False) def mod_short_py(short a, short b): return a % b @cython.cdivision(False) def mod_double_py(double a, double b): return a % b @cython.cdivision(False) def mod_float_py(float a, float b): return a % b @cython.cdivision(True) def mod_int_c(int a, int b): return a % b @cython.cdivision(True) def mod_float_c(float a, float b): return a % b @cython.cdivision(True) def mod_double_c(double a, double b): return a % b @cython.cdivision(False) def div_int_py(int a, int b): return a // b @cython.cdivision(True) def div_int_c(int a, int b): return a // b @cython.cdivision(False) def test_cdiv_cmod(short a, short b): cdef short q = cython.cdiv(a, b) cdef short r = cython.cmod(a, b) return q, r @cython.cdivision(True) @cython.cdivision_warnings(True) def mod_int_c_warn(int a, int b): """ >>> warnings.showwarning = simple_warn >>> mod_int_c_warn(-17, 10) division with oppositely signed operands, C and Python semantics differ -7 >>> warnings.showwarning = orig_showwarning """ return a % b @cython.cdivision(True) @cython.cdivision_warnings(True) def div_int_c_warn(int a, int b): """ >>> warnings.showwarning = simple_warn >>> div_int_c_warn(-17, 10) division with oppositely signed operands, C and Python semantics differ -1 >>> warnings.showwarning = orig_showwarning """ return a // b @cython.cdivision(False) @cython.cdivision_warnings(True) def complex_expression(int a, int b, int c, int d): """ >>> warnings.showwarning = simple_warn >>> complex_expression(-150, 20, 19, -7) verbose_call(20) division with oppositely signed operands, C and Python semantics differ verbose_call(19) division with oppositely signed operands, C and Python semantics differ -2 >>> warnings.showwarning = orig_showwarning """ return (a // verbose_call(b)) % (verbose_call(c) // d) cdef int verbose_call(int x): print u"verbose_call(%s)" % x return x # These may segfault with cdivision @cython.cdivision(False) def mod_div_zero_int(int a, int b, int c): """ >>> mod_div_zero_int(25, 10, 2) verbose_call(5) 2 >>> print(mod_div_zero_int(25, 10, 0)) verbose_call(5) integer division or modulo by zero >>> print(mod_div_zero_int(25, 0, 0)) integer division or modulo by zero """ try: return verbose_call(a % b) / c except ZeroDivisionError, ex: return unicode(ex) @cython.cdivision(False) def mod_div_zero_float(float a, float b, float c): """ >>> mod_div_zero_float(25, 10, 2) 2.5 >>> print(mod_div_zero_float(25, 10, 0)) float division >>> print(mod_div_zero_float(25, 0, 0)) float divmod() """ try: return (a % b) / c except ZeroDivisionError, ex: return unicode(ex) @cython.cdivision(False) def py_div_long(long a, long b): """ >>> py_div_long(-5, -1) 5 >>> import sys >>> maxint = getattr(sys, ((sys.version_info[0] >= 3) and 'maxsize' or 'maxint')) >>> py_div_long(-maxint-1, -1) Traceback (most recent call last): ... OverflowError: value too large to perform division """ return a / b Cython-0.23.4/tests/run/cdefoptargs.pyx0000644000175600017570000000177112606202452021223 0ustar jenkinsjenkins00000000000000from cython cimport typeof def call2(): """ >>> call2() """ b(1,2) def call3(): """ >>> call3() """ b(1,2,3) def call4(): """ >>> call4() """ b(1,2,3,4) # the called function: cdef b(a, b, c=1, d=2): pass cdef int foo(int a, int b=1, int c=1): return a+b*c def test_foo(): """ >>> test_foo() 2 3 7 26 """ print foo(1) print foo(1, 2) print foo(1, 2, 3) print foo(1, foo(2, 3), foo(4)) cdef class A: cpdef method(self): """ >>> A().method() 'A' """ return typeof(self) cdef class B(A): cpdef method(self, int x = 0): """ >>> B().method() ('B', 0) >>> B().method(100) ('B', 100) """ return typeof(self), x cdef class C(B): cpdef method(self, int x = 10): """ >>> C().method() ('C', 10) >>> C().method(100) ('C', 100) """ return typeof(self), x Cython-0.23.4/tests/run/cdefassign.pyx0000644000175600017570000000047112606202452021024 0ustar jenkinsjenkins00000000000000cdef int g = 7 def test(x, int y): """ >>> test(1, 2) 4 1 2 2 0 7 8 """ if True: before = 0 cdef int a = 4, b = x, c = y cdef int *p = &y cdef object o = int(8) print a, b, c, p[0], before, g, o # Also test that pruning cdefs doesn't hurt def empty(): cdef int i Cython-0.23.4/tests/run/cdef_setitem_T284.pyx0000644000175600017570000000165212606202452022074 0ustar jenkinsjenkins00000000000000# ticket: 284 def no_cdef(): """ >>> no_cdef() """ cdef object lst = list(range(11)) ob = 10L lst[ob] = -10 cdef object dd = {} dd[ob] = -10 def with_cdef(): """ >>> with_cdef() """ cdef list lst = list(range(11)) ob = 10L lst[ob] = -10 cdef dict dd = {} dd[ob] = -10 def with_external_list(list L): """ >>> with_external_list([1,2,3]) [1, -10, 3] >>> with_external_list(None) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable """ ob = 1L L[ob] = -10 return L def test_list(list L, object i, object a): """ >>> test_list(list(range(11)), -2, None) [0, 1, 2, 3, 4, 5, 6, 7, 8, None, 10] >>> test_list(list(range(11)), "invalid index", None) #doctest: +ELLIPSIS Traceback (most recent call last): TypeError: list ... must be ...integer... """ L[i] = a return L Cython-0.23.4/tests/run/cdef_opt.pyx0000644000175600017570000000104512606202452020477 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> a = A() >>> a.foo() (True, 'yo') >>> a.foo(False) (False, 'yo') >>> a.foo(10, 'yes') (True, 'yes') """ cdef class A: cpdef foo(self, bint a=True, b="yo"): return a, b def call0(): """ >>> call0() (True, 'yo') """ cdef A a = A() return a.foo() def call1(): """ >>> call1() (False, 'yo') """ cdef A a = A() return a.foo(False) def call2(): """ >>> call2() (False, 'go') """ cdef A a = A() return a.foo(False, "go") Cython-0.23.4/tests/run/cdef_opt.pxd0000644000175600017570000000006112606202452020447 0ustar jenkinsjenkins00000000000000cdef class A: cpdef foo(self, bint a=*, b=*) Cython-0.23.4/tests/run/cdef_methods_T462.pyx0000644000175600017570000000161612606202452022063 0ustar jenkinsjenkins00000000000000# ticket: 462 cimport cython cdef class cclass: def test_self(self): """ >>> cclass().test_self() 'cclass' """ return cython.typeof(self) def test_self_1(self, arg): """ >>> cclass().test_self_1(1) ('cclass', 1) """ return cython.typeof(self), arg def test_self_args(self, *args): """ >>> cclass().test_self_args(1,2,3) ('cclass', (1, 2, 3)) """ return cython.typeof(self), args def test_args(*args): """ >>> cclass().test_args(1,2,3) ('Python object', (1, 2, 3)) """ return cython.typeof(args[0]), args[1:] def test_args_kwargs(*args, **kwargs): """ >>> cclass().test_args_kwargs(1,2,3, a=4) ('Python object', (1, 2, 3), {'a': 4}) """ return cython.typeof(args[0]), args[1:], kwargs Cython-0.23.4/tests/run/cdef_members_binding_properties.pyx0000644000175600017570000000552612606202452025305 0ustar jenkinsjenkins00000000000000# cython: embedsignature=True, binding=True # mode: run # same test as "cdef_members_T517.pyx" but "binding=True" __doc__ = u""" >>> a = A() >>> a.h = 7 >>> a.i = 127 >>> a.l = 255 >>> a.q = 255 >>> a.f = 1.0/2.0 >>> a.d = 1/2.0 + 1/4.0 >>> a.g = 1/2.0 + 1/4.0 + 1/8.0 >>> a.Zf = 1+2j >>> a.Zd = 3+4j >>> a.Zg = 5+6j >>> a.h, a.i, a.l (7, 127, 255) >>> a.ro_h, a.ro_i, a.ro_l (7, 127, 255) >>> a.f, a.d, a.g (0.5, 0.75, 0.875) >>> a.ro_f, a.ro_d, a.ro_g (0.5, 0.75, 0.875) >>> a.Zf, a.Zd, a.Zg ((1+2j), (3+4j), (5+6j)) >>> a.ro_Zf, a.ro_Zd, a.ro_Zg ((1+2j), (3+4j), (5+6j)) >>> b = B() >>> b.a0 #doctest: +ELLIPSIS Traceback (most recent call last): AttributeError: ... >>> b.b0 #doctest: +ELLIPSIS Traceback (most recent call last): AttributeError: ... >>> b.c0 #doctest: +ELLIPSIS Traceback (most recent call last): AttributeError: ... >>> isinstance(b.a1, type(None)) True >>> isinstance(b.a2, type(None)) True >>> isinstance(b.b1, list) True >>> isinstance(b.b2, list) True >>> isinstance(b.c1, A) True >>> isinstance(b.c2, A) True >>> b.a1 = a >>> b.a1 is not b.a2 True TYPE_FIXES_REQUIRED: >>> try: b.b1 = 1 ... except (TypeError, AttributeError): pass >>> try: b.c1 = 1 ... except (TypeError, AttributeError): pass >>> try: b.a2 = None ... except (TypeError, AttributeError): pass >>> try: b.b2 = [] ... except (TypeError, AttributeError): pass >>> try: b.c2 = A() ... except (TypeError, AttributeError): pass """ import sys if sys.version_info < (2,5): __doc__ = (__doc__.split('TYPE_FIXES_REQUIRED')[0] + __doc__.split('TYPE_FIXES_REQUIRED')[1].replace('\nAttributeError: ...', '\nTypeError: ...')) cdef class A: cdef public short h cdef public int i cdef public long l cdef public long long q cdef public float f cdef public double d cdef public long double g cdef public float complex Zf cdef public double complex Zd cdef public long double complex Zg cdef readonly short ro_h cdef readonly int ro_i cdef readonly long ro_l cdef readonly long long ro_q cdef readonly float ro_f cdef readonly double ro_d cdef readonly long double ro_g cdef readonly float complex ro_Zf cdef readonly double complex ro_Zd cdef readonly long double complex ro_Zg def __cinit__(self): self.ro_h = 7 self.ro_i = 127 self.ro_l = 255 self.ro_q = 255 self.ro_f = 1.0/2.0 self.ro_d = 1/2.0 + 1/4.0 self.ro_g = 1/2.0 + 1/4.0 + 1/8.0 self.ro_Zf = 1+2j self.ro_Zd = 3+4j self.ro_Zg = 5+6j cdef class B: cdef object a0 cdef public object a1 cdef readonly object a2 cdef list b0 cdef public list b1 cdef readonly list b2 cdef A c0 cdef public A c1 cdef readonly A c2 def __cinit__(self): self.b0 = self.b1 = self.b2 = [] self.c0 = self.c1 = self.c2 = A() Cython-0.23.4/tests/run/cdef_members_T517.pyx0000644000175600017570000000541612606202452022055 0ustar jenkinsjenkins00000000000000# ticket: 517 #cython: embedsignature=True __doc__ = u""" >>> a = A() >>> a.h = 7 >>> a.i = 127 >>> a.l = 255 >>> a.q = 255 >>> a.f = 1.0/2.0 >>> a.d = 1/2.0 + 1/4.0 >>> a.g = 1/2.0 + 1/4.0 + 1/8.0 >>> a.Zf = 1+2j >>> a.Zd = 3+4j >>> a.Zg = 5+6j >>> a.h, a.i, a.l (7, 127, 255) >>> a.ro_h, a.ro_i, a.ro_l (7, 127, 255) >>> a.f, a.d, a.g (0.5, 0.75, 0.875) >>> a.ro_f, a.ro_d, a.ro_g (0.5, 0.75, 0.875) >>> a.Zf, a.Zd, a.Zg ((1+2j), (3+4j), (5+6j)) >>> a.ro_Zf, a.ro_Zd, a.ro_Zg ((1+2j), (3+4j), (5+6j)) >>> b = B() >>> b.a0 #doctest: +ELLIPSIS Traceback (most recent call last): AttributeError: ... >>> b.b0 #doctest: +ELLIPSIS Traceback (most recent call last): AttributeError: ... >>> b.c0 #doctest: +ELLIPSIS Traceback (most recent call last): AttributeError: ... >>> isinstance(b.a1, type(None)) True >>> isinstance(b.a2, type(None)) True >>> isinstance(b.b1, list) True >>> isinstance(b.b2, list) True >>> isinstance(b.c1, A) True >>> isinstance(b.c2, A) True >>> b.a1 = a >>> b.a1 is not b.a2 True TYPE_FIXES_REQUIRED: >>> try: b.b1 = 1 ... except (TypeError, AttributeError): pass >>> try: b.c1 = 1 ... except (TypeError, AttributeError): pass >>> try: b.a2 = None ... except (TypeError, AttributeError): pass >>> try: b.b2 = [] ... except (TypeError, AttributeError): pass >>> try: b.c2 = A() ... except (TypeError, AttributeError): pass """ import sys if sys.version_info < (2,5): __doc__ = (__doc__.split('TYPE_FIXES_REQUIRED')[0] + __doc__.split('TYPE_FIXES_REQUIRED')[1].replace('\nAttributeError: ...', '\nTypeError: ...')) cdef class A: cdef public short h cdef public int i cdef public long l cdef public long long q cdef public float f cdef public double d cdef public long double g cdef public float complex Zf cdef public double complex Zd cdef public long double complex Zg cdef readonly short ro_h cdef readonly int ro_i cdef readonly long ro_l cdef readonly long long ro_q cdef readonly float ro_f cdef readonly double ro_d cdef readonly long double ro_g cdef readonly float complex ro_Zf cdef readonly double complex ro_Zd cdef readonly long double complex ro_Zg def __cinit__(self): self.ro_h = 7 self.ro_i = 127 self.ro_l = 255 self.ro_q = 255 self.ro_f = 1.0/2.0 self.ro_d = 1/2.0 + 1/4.0 self.ro_g = 1/2.0 + 1/4.0 + 1/8.0 self.ro_Zf = 1+2j self.ro_Zd = 3+4j self.ro_Zg = 5+6j cdef class B: cdef object a0 cdef public object a1 cdef readonly object a2 cdef list b0 cdef public list b1 cdef readonly list b2 cdef A c0 cdef public A c1 cdef readonly A c2 def __cinit__(self): self.b0 = self.b1 = self.b2 = [] self.c0 = self.c1 = self.c2 = A() Cython-0.23.4/tests/run/cdef_locals_decorator_T477.pyx0000644000175600017570000000071712606202452023746 0ustar jenkinsjenkins00000000000000# ticket: 477 import cython @cython.locals(x=double) cdef func(x): return x**2 @cython.locals(x=double) cdef func_defval(x=0): return x**2 def test(): """ >>> isinstance(test(), float) True """ return func(2) def test_defval(x=None): """ >>> test_defval() 0.0 >>> test_defval(1) 1.0 >>> test_defval(2.0) 4.0 """ if x is None: return func_defval() else: return func_defval(x) Cython-0.23.4/tests/run/cdef_function_kwargs.pyx0000644000175600017570000002106612606202452023105 0ustar jenkinsjenkins00000000000000cimport cython from libc.string cimport strstr cdef cfunc(a,b,c,d): return (a,b,c,d) cpdef cpfunc(a,b,c,d): return (a,b,c,d) cdef optargs(a, b=2, c=3): return (a,b,c) ctypedef int (*cfuncptr_type)(int a, int b) cdef int cfuncptr(int a, int b): print a, b cdef cfuncptr_type get_cfuncptr(): return cfuncptr sideeffect = [] cdef side_effect(x): sideeffect.append(x) return x @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def cfunc_all_keywords(): """ >>> cfunc_all_keywords() (1, 2, 3, 4) """ return cfunc(a=1, b=2, c=3, d=4) @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def cfunc_some_keywords(): """ >>> cfunc_some_keywords() (1, 2, 3, 4) """ return cfunc(1, 2, c=3, d=4) @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def cfunc_some_keywords_unordered(): """ >>> cfunc_some_keywords_unordered() (1, 2, 3, 4) """ return cfunc(1, 2, d=4, c=3) @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def cfunc_some_keywords_unordered_sideeffect(): """ >>> del sideeffect[:] >>> cfunc_some_keywords_unordered_sideeffect() (1, 2, 3, 4) >>> sideeffect [4, 3] """ return cfunc(1, 2, d=side_effect(4), c=side_effect(3)) @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def cpfunc_all_keywords(): """ >>> cpfunc_all_keywords() (1, 2, 3, 4) """ return cpfunc(a=1, b=2, c=3, d=4) @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def cpfunc_some_keywords(): """ >>> cpfunc_some_keywords() (1, 2, 3, 4) """ return cpfunc(1, 2, c=3, d=4) @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def cpfunc_some_keywords_unordered(): """ >>> cpfunc_some_keywords_unordered() (1, 2, 3, 4) """ return cpfunc(1, 2, d=4, c=3) @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def cpfunc_some_keywords_unordered_sideeffect(): """ >>> del sideeffect[:] >>> cpfunc_some_keywords_unordered_sideeffect() (1, 2, 3, 4) >>> sideeffect [4, 3] """ return cpfunc(1, 2, d=side_effect(4), c=side_effect(3)) @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def libc_strstr(): """ >>> libc_strstr() (True, True, True, True, True) """ return ( strstr("xabcy", "abc") is not NULL, strstr("abc", "xabcy") is NULL, strstr(needle="abc", haystack="xabcz") is not NULL, strstr(needle="xabcz", haystack="abc") is NULL, strstr(haystack="abc", needle="xabcz") is NULL, ) @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def cdef_optargs(): """ >>> cdef_optargs() (11, 2, 3) (11, 2, 3) (11, 12, 3) (11, 12, 3) (11, 12, 3) (11, 12, 3) (11, 12, 3) (11, 12, 13) (11, 12, 13) (11, 12, 13) (11, 12, 13) (11, 12, 13) (11, 12, 13) (11, 12, 13) """ print(optargs(11)) print(optargs(a=11)) print(optargs(11, 12)) print(optargs(11, b=12)) print(optargs(a=11, b=12)) print(optargs(b=12, a=11)) print(optargs(a=11, b=12)) print(optargs(11, 12, 13)) print(optargs(11, 12, c=13)) print(optargs(11, c=13, b=12)) print(optargs(a=11, b=12, c=13)) print(optargs(b=12, a=11, c=13)) print(optargs(b=12, c=13, a=11)) print(optargs(c=13, a=11, b=12)) @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def cdef_funcptr(): """ >>> cdef_funcptr() 1 2 1 2 1 2 1 2 """ cdef cfuncptr_type cfunc_ptr = get_cfuncptr() cfunc_ptr(1, 2) cfunc_ptr(1, b=2) cfunc_ptr(a=1, b=2) cfunc_ptr(b=2, a=1) ''' # This works but currently brings up C compiler warnings # because the format string is not a literal C string. from libc.stdio cimport snprintf @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def varargs(): """ >>> print(varargs()) abc """ cdef char[10] buffer retval = snprintf(buffer, template="abc", size=10) if retval < 0: raise MemoryError() return buffer[:retval].decode('ascii') ''' cdef class ExtType: cdef cmeth(self, a, b, c, d): return (a,b,c,d) @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def call_cmeth(self, ExtType ext): """ >>> x = ExtType() >>> x.call_cmeth(x) (1, 2, 3, 4) (1, 2, 3, 4) (1, 2, 3, 4) EXT (1, 2, 3, 4) (1, 2, 3, 4) (1, 2, 3, 4) """ print self.cmeth(1,2,3,4) print self.cmeth(1,2,c=3,d=4) print self.cmeth(a=1,b=2,c=3,d=4) print "EXT" print ext.cmeth(1,2,3,4) print ext.cmeth(1,2,c=3,d=4) print ext.cmeth(a=1,b=2,c=3,d=4) cpdef cpmeth(self, a, b, c, d): return (a,b,c,d) @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def call_cpmeth(self, ExtType ext): """ >>> x = ExtType() >>> x.call_cpmeth(x) (1, 2, 3, 4) (1, 2, 3, 4) (1, 2, 3, 4) EXT (1, 2, 3, 4) (1, 2, 3, 4) (1, 2, 3, 4) """ print self.cpmeth(1,2,3,4) print self.cpmeth(1,2,c=3,d=4) print self.cpmeth(a=1,b=2,c=3,d=4) print "EXT" print ext.cpmeth(1,2,3,4) print ext.cpmeth(1,2,c=3,d=4) print ext.cpmeth(a=1,b=2,c=3,d=4) cdef optargs(self, a=1, b=2): return (a,b) @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def call_optargs(self, ExtType ext): """ >>> x = ExtType() >>> x.call_optargs(x) (3, 4) (3, 4) (3, 4) (1, 2) (3, 2) (3, 2) EXT (3, 4) (3, 4) (3, 4) (1, 2) (3, 2) (3, 2) """ print self.optargs(3,4) print self.optargs(3,b=4) print self.optargs(a=3,b=4) print self.optargs() print self.optargs(3) print self.optargs(a=3) #print self.optargs(b=4) print "EXT" print ext.optargs(3,4) print ext.optargs(3,b=4) print ext.optargs(a=3,b=4) print ext.optargs() print ext.optargs(3) print ext.optargs(a=3) #print ext.optargs(b=4) cpdef cpmeth_optargs(self, a=1, b=2): return (a,b) @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def call_cpmeth_optargs(self, ExtType ext): """ >>> x = ExtType() >>> x.call_cpmeth_optargs(x) (3, 4) (3, 4) (3, 4) (1, 2) (3, 2) (3, 2) EXT (3, 4) (3, 4) (3, 4) (1, 2) (3, 2) (3, 2) """ print self.cpmeth_optargs(3,4) print self.cpmeth_optargs(3,b=4) print self.cpmeth_optargs(a=3,b=4) print self.cpmeth_optargs() print self.cpmeth_optargs(3) print self.cpmeth_optargs(a=3) #print self.cpmeth_optargs(b=4) print "EXT" print ext.cpmeth_optargs(3,4) print ext.cpmeth_optargs(3,b=4) print ext.cpmeth_optargs(a=3,b=4) print ext.cpmeth_optargs() print ext.cpmeth_optargs(3) print ext.cpmeth_optargs(a=3) #print ext.cpmeth_optargs(b=4) cpdef cpmeth_optargs1(self, a=1): return a @cython.test_fail_if_path_exists('//GeneralCallNode') @cython.test_assert_path_exists('//SimpleCallNode') def call_cpmeth_optargs1(self, ExtType ext): """ >>> x = ExtType() >>> x.call_cpmeth_optargs1(x) 1 3 3 EXT 1 3 3 """ print self.cpmeth_optargs1() print self.cpmeth_optargs1(3) print self.cpmeth_optargs1(a=3) print "EXT" print ext.cpmeth_optargs1() print ext.cpmeth_optargs1(3) print ext.cpmeth_optargs1(a=3) Cython-0.23.4/tests/run/cdef_decorator_directives_T183.pyx0000644000175600017570000000045112606202452024617 0ustar jenkinsjenkins00000000000000# ticket: 183 cimport cython @cython.cdivision(True) cpdef cdiv_decorator(int a, int b): """ >>> cdiv_decorator(-12, 5) -2 """ return a / b @cython.cdivision(False) cpdef pydiv_decorator(int a, int b): """ >>> pydiv_decorator(-12, 5) -3 """ return a / b Cython-0.23.4/tests/run/cdef_classmethod.pyx0000644000175600017570000000336012606202452022205 0ustar jenkinsjenkins00000000000000 cimport cython cdef class cclass: @classmethod def test0(cls): """ >>> cclass.test0() 'type object' """ return cython.typeof(cls) @classmethod def test0_args(*args): """ >>> cclass.test0_args(1,2,3) ('Python object', (1, 2, 3)) """ return cython.typeof(args[0]), args[1:] @classmethod def test1(cls, arg): """ >>> cclass.test1(1) ('type object', 1) """ return cython.typeof(cls), arg @classmethod def test2(cls, arg1, arg2): """ >>> cclass.test2(1,2) ('type object', 1, 2) """ return cython.typeof(cls), arg1, arg2 @classmethod def test1_args(cls, *args): """ >>> cclass.test1_args(1,2,3) ('type object', (1, 2, 3)) """ return cython.typeof(cls), args @classmethod def test2_args(cls, arg, *args): """ >>> cclass.test2_args(1,2,3) ('type object', 1, (2, 3)) """ return cython.typeof(cls), arg, args @classmethod def test0_args_kwargs(*args, **kwargs): """ >>> cclass.test0_args_kwargs(1,2,3) ('Python object', (1, 2, 3), {}) """ return cython.typeof(args[0]), args[1:], kwargs @classmethod def test1_args_kwargs(cls, *args, **kwargs): """ >>> cclass.test1_args_kwargs(1,2,3) ('type object', (1, 2, 3), {}) """ return cython.typeof(cls), args, kwargs @classmethod def test2_args_kwargs(cls, arg, *args, **kwargs): """ >>> cclass.test2_args_kwargs(1,2,3) ('type object', 1, (2, 3), {}) """ return cython.typeof(cls), arg, args, kwargs Cython-0.23.4/tests/run/cdef_class_order.pyx0000644000175600017570000000025512606202452022177 0ustar jenkinsjenkins00000000000000cimport cython cdef class B cdef class A(object): cdef list dealloc1 cdef class B(A): cdef list dealloc2 def test(): """ >>> test() """ A(), B() Cython-0.23.4/tests/run/cdef_class_field.pyx0000644000175600017570000000035712606202452022152 0ustar jenkinsjenkins00000000000000# mode: run # tag: exttype # ticket: 677 """ >>> str(Foo(4)) '4' >>> x 3 """ x = 3 cdef int y cdef class Foo: cdef int x cdef int y def __init__(self, x): self.x = x def __str__(self): return str(self.x) Cython-0.23.4/tests/run/cdef_bool_T227.pyx0000644000175600017570000000101212606202452021340 0ustar jenkinsjenkins00000000000000# ticket: 227 from cpython.bool cimport bool def foo(bool a): """ >>> foo(True) True >>> foo(False) False >>> foo('abc') # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... """ return a == True def call_cfoo(a): """ >>> call_cfoo(True) True >>> call_cfoo(False) False >>> call_cfoo('abc') # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... """ return cfoo(a) cdef cfoo(bool a): return a == True Cython-0.23.4/tests/run/cascadedassignment.pyx0000644000175600017570000000257612606202452022546 0ustar jenkinsjenkins00000000000000import cython @cython.test_fail_if_path_exists( '//CascadedAssignmentNode//CoerceFromPyTypeNode', '//CascadedAssignmentNode//CoerceToPyTypeNode', ) @cython.test_assert_path_exists('//CascadedAssignmentNode') def test_cascaded_assignment_simple(): """ >>> test_cascaded_assignment_simple() 5 """ a = b = c = 5 return a @cython.test_fail_if_path_exists( '//CascadedAssignmentNode//CoerceFromPyTypeNode', '//CascadedAssignmentNode//CoerceToPyTypeNode', ) @cython.test_assert_path_exists('//CascadedAssignmentNode') def test_cascaded_assignment_typed(): """ >>> test_cascaded_assignment_typed() int Python object double (5, 5, 5.0) """ cdef int a cdef object b cdef double c a = b = c = 5 print cython.typeof(a), cython.typeof(b), cython.typeof(c) return a, b, c def test_cascaded_assignment_builtin_expr(): """ This test is useful as previously the rhs expr node got replaced resulting in CloneNode generating None in the C source. >>> test_cascaded_assignment_builtin_expr() (10.0, 10.0, 10.0) """ a = b = c = float(10) return a, b, c def expr(): print "expr called" return 10 def test_cascaded_assignment_evaluate_expr(): """ >>> test_cascaded_assignment_evaluate_expr() expr called (10.0, 10.0, 10.0) """ a = b = c = float(expr()) return a, b, c Cython-0.23.4/tests/run/cascaded_typed_assignments_T466.pyx0000644000175600017570000000461512606202452025014 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 466 # extension to T409 cimport cython def simple_parallel_typed(): """ >>> simple_parallel_typed() (1, 2, [1, 2], [1, 2]) """ cdef int a,c a, c = d = e = [1,2] return a, c, d, e def simple_parallel_int_mix(): """ >>> simple_parallel_int_mix() (1, 2, 1, 2, 1, 2, [1, 2], [1, 2]) """ cdef int ai,bi cdef long al,bl cdef object ao, bo ai, bi = al, bl = ao, bo = c = d = [1,2] return ao, bo, ai, bi, al, bl, c, d def simple_parallel_int_mix_recursive(): """ >>> simple_parallel_int_mix_recursive() (1, 2, 3, 1, [2, 3], 1, 2, 3, 1, 2, 3, [1, [2, 3]], [1, [2, 3]]) """ cdef int ai, bi, ci cdef long al, bl, cl cdef object ao, bo, co cdef object xo, yo ai, [bi, ci] = al, [bl, cl] = xo, yo = ao, [bo, co] = c = d = [1, [2, 3]] return ao, bo, co, xo, yo, ai, bi, ci, al, bl, cl, c, d cdef int called = 0 cdef char* get_string(): global called called += 1 return "abcdefg" def non_simple_rhs(): """ >>> non_simple_rhs() 1 """ cdef char *a, *b cdef int orig_called = called a = b = get_string() assert a is b return called - orig_called from libc.stdlib cimport malloc, free def non_simple_rhs_malloc(): """ >>> non_simple_rhs_malloc() """ cdef char *a, *b, **c c = &b c[0] = a = malloc(2) a[0] = c'X' b[1] = c'\0' # copy from different pointers to make sure they all point to the # same memory cdef char[2] x x[0] = b[0] x[1] = a[1] # clean up free(a) if b is not a: # shouldn't happen free(b) # check copied values assert x[0] == c'X' assert x[1] == c'\0' @cython.test_assert_path_exists( '//CascadedAssignmentNode', '//CascadedAssignmentNode//CoerceToTempNode', '//CascadedAssignmentNode//CoerceToTempNode[@type.is_ptr]') def assign_carray(): """ assign_carray() (1, 2, 3) """ cdef int *b, *c cdef int[3] a a[0] = 1 a[1] = 2 a[2] = 3 b = c = a+1 assert b[0] == 2 assert c[1] == 3 return a[0], b[0], c[1] def pyobject_from_cvalue(table, key): """ >>> table = {'X':0, 'Y':1} >>> pyobject_from_cvalue(table, 'Z') 2 >>> pyobject_from_cvalue(table, 'X') 0 """ cdef int num num = table.get(key, -1) if num < 0: num = table[key] = len(table) return num Cython-0.23.4/tests/run/cascaded_list_unpacking_T467.pyx0000644000175600017570000000436312606202452024267 0ustar jenkinsjenkins00000000000000# ticket: 467 def simple_parallel_assignment_from_call(): """ >>> simple_parallel_assignment_from_call() (2, 1, 2, 1, 2, 1, 2, [1, 2], [1, 2]) """ cdef int ai, bi cdef long al, bl cdef object ao, bo reset() ai, bi = al, bl = ao, bo = c = d = [intval(1), intval(2)] return call_count, ao, bo, ai, bi, al, bl, c, d def recursive_parallel_assignment_from_call_left(): """ >>> recursive_parallel_assignment_from_call_left() (3, 1, 2, 3, 1, 2, 3, (1, 2), 3, [(1, 2), 3]) """ cdef int ai, bi, ci cdef object ao, bo, co reset() (ai, bi), ci = (ao, bo), co = t,o = d = [(intval(1), intval(2)), intval(3)] return call_count, ao, bo, co, ai, bi, ci, t, o, d def recursive_parallel_assignment_from_call_right(): """ >>> recursive_parallel_assignment_from_call_right() (3, 1, 2, 3, 1, 2, 3, 1, (2, 3), [1, (2, 3)]) """ cdef int ai, bi, ci cdef object ao, bo, co reset() ai, (bi, ci) = ao, (bo, co) = o,t = d = [intval(1), (intval(2), intval(3))] return call_count, ao, bo, co, ai, bi, ci, o, t, d def recursive_parallel_assignment_from_call_left_reversed(): """ >>> recursive_parallel_assignment_from_call_left_reversed() (3, 1, 2, 3, 1, 2, 3, (1, 2), 3, [(1, 2), 3]) """ cdef int ai, bi, ci cdef object ao, bo, co reset() d = t,o = (ao, bo), co = (ai, bi), ci = [(intval(1), intval(2)), intval(3)] return call_count, ao, bo, co, ai, bi, ci, t, o, d def recursive_parallel_assignment_from_call_right_reversed(): """ >>> recursive_parallel_assignment_from_call_right_reversed() (3, 1, 2, 3, 1, 2, 3, 1, (2, 3), [1, (2, 3)]) """ cdef int ai, bi, ci cdef object ao, bo, co reset() d = o,t = ao, (bo, co) = ai, (bi, ci) = [intval(1), (intval(2), intval(3))] return call_count, ao, bo, co, ai, bi, ci, o, t, d cdef int call_count = 0 cdef int next_expected_arg = 1 cdef reset(): global call_count, next_expected_arg call_count = 0 next_expected_arg = 1 cdef int intval(int x) except -1: global call_count, next_expected_arg call_count += 1 assert next_expected_arg == x, "calls not in source code order: expected %d, found %d" % (next_expected_arg, x) next_expected_arg += 1 return x Cython-0.23.4/tests/run/carrays.pyx0000644000175600017570000000132012606202452020354 0ustar jenkinsjenkins00000000000000def test1(): """ >>> test1() 2 """ cdef int[2][2] x x[0][0] = 1 x[0][1] = 2 x[1][0] = 3 x[1][1] = 4 return f(x)[1] cdef int* f(int x[2][2]): return x[0] def test2(): """ >>> test2() 0 """ cdef int[5] a1 cdef int a2[2+3] return sizeof(a1) - sizeof(a2) cdef enum: MY_SIZE_A = 2 MY_SIZE_B = 3 def test3(): """ >>> test3() (2, 3) """ cdef int a[MY_SIZE_A] cdef int b[MY_SIZE_B] return sizeof(a)/sizeof(int), sizeof(b)/sizeof(int) from libc cimport limits def test_cimported_attribute(): """ >>> test_cimported_attribute() True """ cdef char a[limits.CHAR_MAX] return sizeof(a) >= 127 Cython-0.23.4/tests/run/carray_slicing.pyx0000644000175600017570000002224412606202452021711 0ustar jenkinsjenkins00000000000000 cimport cython ############################################################ # tests for char* slicing cdef char* cstring = "abcABCqtp" def slice_charptr_end(): """ >>> print(str(slice_charptr_end()).replace("b'", "'")) ('a', 'abc', 'abcABCqtp') """ return cstring[:1], cstring[:3], cstring[:9] #### BROKEN: this test assumes that the result of a char* iteration #### becomes a bytes object, which is not the case when applying #### carray iteration. Contradiction. ## ## @cython.test_assert_path_exists("//ForFromStatNode", ## "//ForFromStatNode//SliceIndexNode") ## @cython.test_fail_if_path_exists("//ForInStatNode") ## def slice_charptr_for_loop_py(): ## """ ## >>> slice_charptr_for_loop_py() ## ['a', 'b', 'c'] ## ['b', 'c', 'A', 'B'] ## ['B', 'C', 'q', 't', 'p'] ## """ ## print str([ c for c in cstring[:3] ]).replace(" b'", " '").replace("[b'", "['") ## print str([ c for c in cstring[1:5] ]).replace(" b'", " '").replace("[b'", "['") ## print str([ c for c in cstring[4:9] ]).replace(" b'", " '").replace("[b'", "['") @cython.test_assert_path_exists("//ForFromStatNode", "//ForFromStatNode//IndexNode") @cython.test_fail_if_path_exists("//ForInStatNode") def slice_charptr_for_loop_c(): """ >>> slice_charptr_for_loop_c() ['a', 'b', 'c'] ['a', 'b', 'c'] ['b', 'c', 'A', 'B'] ['B', 'C', 'q', 't', 'p'] """ cdef char c print [ chr(c) for c in cstring[:3] ] print [ chr(c) for c in cstring[None:3] ] print [ chr(c) for c in cstring[1:5] ] print [ chr(c) for c in cstring[4:9] ] #@cython.test_assert_path_exists("//ForFromStatNode", # "//ForFromStatNode//IndexNode") #@cython.test_fail_if_path_exists("//ForInStatNode") def slice_charptr_for_loop_c_to_bytes(): """ >>> slice_charptr_for_loop_c_to_bytes() ['a', 'b', 'c'] ['a', 'b', 'c'] ['b', 'c', 'A', 'B'] ['B', 'C', 'q', 't', 'p'] """ cdef bytes b print str([ b for b in cstring[:3] ]).replace(" b'", " '").replace("[b'", "['") print str([ b for b in cstring[None:3] ]).replace(" b'", " '").replace("[b'", "['") print str([ b for b in cstring[1:5] ]).replace(" b'", " '").replace("[b'", "['") print str([ b for b in cstring[4:9] ]).replace(" b'", " '").replace("[b'", "['") @cython.test_assert_path_exists("//ForFromStatNode", "//ForFromStatNode//IndexNode") @cython.test_fail_if_path_exists("//ForInStatNode") def slice_charptr_for_loop_c_step(): """ >>> slice_charptr_for_loop_c_step() Acba ['A', 'c', 'b', 'a'] Acba ['A', 'c', 'b', 'a'] bA ['b', 'A'] acB ['a', 'c', 'B'] acB ['a', 'c', 'B'] [] ptqC ['p', 't', 'q', 'C'] pq ['p', 'q'] """ cdef object ustring = cstring.decode('ASCII') cdef char c print ustring[3::-1], [ chr(c) for c in cstring[3::-1] ] print ustring[3:None:-1], [ chr(c) for c in cstring[3:None:-1] ] print ustring[1:5:2], [ chr(c) for c in cstring[1:5:2] ] print ustring[:5:2], [ chr(c) for c in cstring[:5:2] ] print ustring[None:5:2], [ chr(c) for c in cstring[None:5:2] ] print ustring[4:9:-1], [ chr(c) for c in cstring[4:9:-1] ] print ustring[8:4:-1], [ chr(c) for c in cstring[8:4:-1] ] print ustring[8:4:-2], [ chr(c) for c in cstring[8:4:-2] ] @cython.test_assert_path_exists("//ForFromStatNode", "//ForFromStatNode//IndexNode") @cython.test_fail_if_path_exists("//ForInStatNode") def slice_charptr_for_loop_c_dynamic_bounds(): """ >>> slice_charptr_for_loop_c_dynamic_bounds() ['a', 'b', 'c'] ['a', 'b', 'c'] ['b', 'c', 'A', 'B'] ['B', 'C', 'q', 't', 'p'] """ cdef char c print [ chr(c) for c in cstring[0:return3()] ] print [ chr(c) for c in cstring[None:return3()] ] print [ chr(c) for c in cstring[return1():return5()] ] print [ chr(c) for c in cstring[return4():return9()] ] cdef return1(): return 1 cdef return3(): return 3 cdef return4(): return 4 cdef return5(): return 5 cdef return9(): return 9 #### BROKEN: this test assumes that the result of a char* iteration #### becomes a bytes object, which is not the case when applying #### carray iteration. Contradiction. ## ## @cython.test_assert_path_exists("//ForFromStatNode", ## "//ForFromStatNode//SliceIndexNode") ## @cython.test_fail_if_path_exists("//ForInStatNode") ## def slice_charptr_for_loop_py_enumerate(): ## """ ## >>> slice_charptr_for_loop_py_enumerate() ## [(0, 'a'), (1, 'b'), (2, 'c')] ## [(0, 'b'), (1, 'c'), (2, 'A'), (3, 'B')] ## [(0, 'B'), (1, 'C'), (2, 'q'), (3, 't'), (4, 'p')] ## """ ## print str([ (i,c) for i,c in enumerate(cstring[:3]) ]).replace(" b'", " '") ## print str([ (i,c) for i,c in enumerate(cstring[1:5]) ]).replace(" b'", " '") ## print str([ (i,c) for i,c in enumerate(cstring[4:9]) ]).replace(" b'", " '") @cython.test_assert_path_exists("//ForFromStatNode", "//ForFromStatNode//IndexNode") @cython.test_fail_if_path_exists("//ForInStatNode") def slice_charptr_for_loop_c_enumerate(): """ >>> slice_charptr_for_loop_c_enumerate() [(0, 97), (1, 98), (2, 99)] [(0, 97), (1, 98), (2, 99)] [(0, 98), (1, 99), (2, 65), (3, 66)] [(0, 66), (1, 67), (2, 113), (3, 116), (4, 112)] """ cdef int c,i print [ (i,c) for i,c in enumerate(cstring[:3]) ] print [ (i,c) for i,c in enumerate(cstring[None:3]) ] print [ (i,c) for i,c in enumerate(cstring[1:5]) ] print [ (i,c) for i,c in enumerate(cstring[4:9]) ] ############################################################ # tests for int* slicing cdef int[6] cints for i in range(6): cints[i] = i @cython.test_assert_path_exists("//ForFromStatNode", "//ForFromStatNode//IndexNode") @cython.test_fail_if_path_exists("//ForInStatNode") def slice_intarray_for_loop_c(): """ >>> slice_intarray_for_loop_c() [0, 1, 2] [0, 1, 2] [1, 2, 3, 4] [4, 5] """ cdef int i print [ i for i in cints[:3] ] print [ i for i in cints[None:3] ] print [ i for i in cints[1:5] ] print [ i for i in cints[4:6] ] @cython.test_assert_path_exists("//ForFromStatNode", "//ForFromStatNode//IndexNode") @cython.test_fail_if_path_exists("//ForInStatNode") def iter_intarray_for_loop_c(): """ >>> iter_intarray_for_loop_c() [0, 1, 2, 3, 4, 5] """ cdef int i print [ i for i in cints ] @cython.test_assert_path_exists("//ForFromStatNode", "//ForFromStatNode//IndexNode") @cython.test_fail_if_path_exists("//ForInStatNode") def slice_intptr_for_loop_c(): """ >>> slice_intptr_for_loop_c() [0, 1, 2] [0, 1, 2] [1, 2, 3, 4] [4, 5] """ cdef int* nums = cints cdef int i print [ i for i in nums[:3] ] print [ i for i in nums[None:3] ] print [ i for i in nums[1:5] ] print [ i for i in nums[4:6] ] ############################################################ # tests for slicing other arrays cdef double[6] cdoubles for i in range(6): cdoubles[i] = i + 0.5 cdef double* cdoubles_ptr = cdoubles @cython.test_assert_path_exists("//ForFromStatNode", "//ForFromStatNode//IndexNode") @cython.test_fail_if_path_exists("//ForInStatNode") def slice_doublptr_for_loop_c(): """ >>> slice_doublptr_for_loop_c() [0.5, 1.5, 2.5] [0.5, 1.5, 2.5] [1.5, 2.5, 3.5, 4.5] [4.5, 5.5] """ cdef double d print [ d for d in cdoubles_ptr[:3] ] print [ d for d in cdoubles_ptr[None:3] ] print [ d for d in cdoubles_ptr[1:5] ] print [ d for d in cdoubles_ptr[4:6] ] ## @cython.test_assert_path_exists("//ForFromStatNode", ## "//ForFromStatNode//IndexNode") ## @cython.test_fail_if_path_exists("//ForInStatNode") ## def slice_doublptr_for_loop_c_step(): ## """ ## >>> slice_doublptr_for_loop_c_step() ## """ ## cdef double d ## print [ d for d in cdoubles_ptr[:3:1] ] ## print [ d for d in cdoubles_ptr[5:1:-1] ] ## print [ d for d in cdoubles_ptr[:2:-2] ] ## print [ d for d in cdoubles_ptr[4:6:2] ] ## print [ d for d in cdoubles_ptr[4:6:-2] ] @cython.test_assert_path_exists("//ForFromStatNode", "//ForFromStatNode//IndexNode") @cython.test_fail_if_path_exists("//ForInStatNode") def iter_doublearray_for_loop_c(): """ >>> iter_doublearray_for_loop_c() [0.5, 1.5, 2.5, 3.5, 4.5, 5.5] """ cdef double d print [ d for d in cdoubles ] cdef struct MyStruct: int i @cython.test_assert_path_exists("//ForFromStatNode", "//ForFromStatNode//IndexNode") @cython.test_fail_if_path_exists("//ForInStatNode") def struct_ptr_iter(): """ >>> struct_ptr_iter() ([0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]) """ cdef MyStruct[5] my_structs for i in range(5): my_structs[i].i = i cdef MyStruct value cdef MyStruct *ptr return ([ value.i for value in my_structs[:5] ], [ ptr.i for ptr in my_structs[:5] ], [ inferred.i for inferred in my_structs[:5] ]) Cython-0.23.4/tests/run/carray_coercion.pyx0000644000175600017570000002477512606202452022075 0ustar jenkinsjenkins00000000000000# mode: run import sys IS_PY3 = sys.version_info[0] >= 3 IS_32BIT_PY2 = not IS_PY3 and sys.maxint < 2**32 def unlongify(v): # on 32bit Py2.x platforms, 'unsigned int' coerces to a Python long => fix doctest output here. s = repr(v) if IS_32BIT_PY2: assert s.count('L') == s.count(',') + 1, s s = s.replace('L', '') return s def from_int_array(): """ >>> from_int_array() [1, 2, 3] """ cdef int[3] v v[0] = 1 v[1] = 2 v[2] = 3 return v cpdef tuple tuple_from_int_array(): """ >>> tuple_from_int_array() (1, 2, 3) """ cdef int[3] v v[0] = 1 v[1] = 2 v[2] = 3 assert isinstance(v, tuple) return v cdef extern from "stdint.h": ctypedef unsigned long uint32_t def from_typedef_int_array(): """ >>> unlongify(from_typedef_int_array()) '[1, 2, 3]' """ cdef uint32_t[3] v v[0] = 1 v[1] = 2 v[2] = 3 return v cpdef tuple tuple_from_typedef_int_array(): """ >>> unlongify(tuple_from_typedef_int_array()) '(1, 2, 3)' """ cdef uint32_t[3] v v[0] = 1 v[1] = 2 v[2] = 3 return v def from_int_array_array(): """ >>> from_int_array_array() [[11, 12, 13], [21, 22, 23]] """ cdef int[2][3] v v[0][0] = 11 v[0][1] = 12 v[0][2] = 13 v[1][0] = 21 v[1][1] = 22 v[1][2] = 23 return v def assign_int_array_array(): """ >>> assign_int_array_array() [[11, 12, 13], [21, 22, 23]] """ cdef int[2][3] v = [[11, 12, 13], [21, 22, 23]] return v def assign_int_array_array_from_tuples(): """ >>> assign_int_array_array_from_tuples() [[11, 12, 13], [21, 22, 23]] """ cdef int[2][3] v = ([11, 12, 13], [21, 22, 23]) return v ''' FIXME: this currently crashes: def assign_int_array_array_from_tuples(): """ >>> assign_int_array_array_from_tuples() [[11, 12, 13], [21, 22, 23]] """ cdef int[2][3] v = ((11, 12, 13), (21, 22, 23)) return v ''' def build_from_list_of_arrays(): """ >>> build_from_list_of_arrays() [[11, 12, 13], [21, 22, 23]] """ cdef int[3] x = [11, 12, 13] cdef int[3] y = [21, 22, 23] cdef int[2][3] v = [x, y] return v def build_from_tuple_of_arrays(): """ >>> build_from_tuple_of_arrays() [[11, 12, 13], [21, 22, 23]] """ cdef int[3] x = [11, 12, 13] cdef int[3] y = [21, 22, 23] cdef int[2][3] v = (x, y) return v ctypedef struct MyStructType: int x double y cdef struct MyStruct: int x double y def from_struct_array(): """ >>> a, b = from_struct_array() >>> a['x'], a['y'] (1, 2.0) >>> b['x'], b['y'] (3, 4.0) """ cdef MyStructType[2] v cdef MyStruct[2] w v[0] = MyStructType(1, 2) v[1] = MyStructType(3, 4) assert isinstance(v, tuple) assert isinstance(v, list) w[0] = MyStruct(1, 2) w[1] = MyStruct(3, 4) assert (w) == v assert w == (v) return v def to_int_array(x): """ >>> to_int_array([1, 2, 3]) (1, 2, 3) >>> to_int_array([1, 2]) Traceback (most recent call last): IndexError: not enough values found during array assignment, expected 3, got 2 >>> to_int_array([1, 2, 3, 4]) Traceback (most recent call last): IndexError: too many values found during array assignment, expected 3 """ cdef int[3] v = x return v[0], v[1], v[2] def to_int_array_array(x): """ >>> to_int_array_array([[1, 2, 3], [4, 5, 6]]) (1, 2, 3, 4, 5, 6) >>> to_int_array_array(iter([[1, 2, 3], [4, 5, 6]])) (1, 2, 3, 4, 5, 6) >>> to_int_array_array([[1, 2, 3]]) Traceback (most recent call last): IndexError: not enough values found during array assignment, expected 2, got 1 >>> to_int_array_array(iter([[1, 2, 3]])) Traceback (most recent call last): IndexError: not enough values found during array assignment, expected 2, got 1 >>> to_int_array_array([[1, 2, 3], [4, 5]]) Traceback (most recent call last): IndexError: not enough values found during array assignment, expected 3, got 2 >>> to_int_array_array(iter([[1, 2, 3], [4, 5]])) Traceback (most recent call last): IndexError: not enough values found during array assignment, expected 3, got 2 >>> to_int_array_array([[1, 2, 3, 4], [5, 6, 7]]) Traceback (most recent call last): IndexError: too many values found during array assignment, expected 3 >>> to_int_array_array(iter([[1, 2, 3, 4], [5, 6, 7]])) Traceback (most recent call last): IndexError: too many values found during array assignment, expected 3 """ cdef int[2][3] v = x return v[0][0], v[0][1], v[0][2], v[1][0], v[1][1], v[1][2] ''' # FIXME: this isn't currently allowed cdef enum: SIZE_A = 2 SIZE_B = 3 def to_int_array_array_enumsize(x): """ >>> to_int_array_array([[1, 2, 3], [4, 5, 6]]) (1, 2, 3, 4, 5, 6) >>> to_int_array_array(iter([[1, 2, 3], [4, 5, 6]])) (1, 2, 3, 4, 5, 6) >>> to_int_array([1, 2]) Traceback (most recent call last): IndexError: not enough values found during array assignment, expected 3, got 2 >>> to_int_array([1, 2, 3, 4]) Traceback (most recent call last): IndexError: too many values found during array assignment, expected 3 """ cdef int[SIZE_A][SIZE_B] v = x return v[0][0], v[0][1], v[0][2], v[1][0], v[1][1], v[1][2] ''' ''' # FIXME: this isn't currently supported def array_as_argument(int[2] x): """ >>> array_as_argument([1, 2]) (1, 2) """ return x[0], x[1] ''' def to_int_array_slice(x): """ >>> to_int_array_slice([1, 2, 3]) (1, 2, 3) >>> to_int_array_slice([1, 2]) Traceback (most recent call last): IndexError: not enough values found during array assignment, expected 3, got 2 >>> to_int_array_slice([1, 2, 3, 4]) Traceback (most recent call last): IndexError: too many values found during array assignment, expected 3 """ cdef int[3] v v[:] = x[:3] assert v[0] == x[0] assert v[1] == x[1] assert v[2] == x[2] v[:3] = [0, 0, 0] assert v[0] == 0 assert v[1] == 0 assert v[2] == 0 v[:] = x return v[0], v[1], v[2] def iterable_to_int_array(x): """ >>> iterable_to_int_array(iter([1, 2, 3])) (1, 2, 3) >>> iterable_to_int_array(iter([1, 2])) Traceback (most recent call last): IndexError: not enough values found during array assignment, expected 3, got 2 >>> iterable_to_int_array(iter([1, 2, 3, 4])) Traceback (most recent call last): IndexError: too many values found during array assignment, expected 3 """ cdef int[3] v v[:] = x return v[0], v[1], v[2] def to_struct_array(x): """ >>> a, b = to_struct_array(({'x': 1, 'y': 2}, {'x': 3, 'y': 4})) >>> a['x'], a['y'] (1, 2.0) >>> b['x'], b['y'] (3, 4.0) """ cdef MyStructType[2] v v[:] = x cdef MyStruct[2] w w[:] = x assert w[0].x == v[0].x assert w[0].y == v[0].y assert w[1].x == v[1].x assert w[1].y == v[1].y return v[0], w[1] def to_struct_array_array(x): """ >>> (a1, a2, a3), (b1, b2, b3) = to_struct_array_array([ ... ({'x': 11, 'y': 12}, {'x': 13, 'y': 14}, {'x': 15, 'y': 16}), ... ({'x': 21, 'y': 22}, {'x': 23, 'y': 24}, {'x': 25, 'y': 26}), ... ]) >>> a1['x'], a1['y'] (11, 12.0) >>> b3['x'], b3['y'] (25, 26.0) """ cdef MyStructType[2][3] v = x return v[0], v[1] cdef struct StructWithArray: int a MyStruct[2] b def to_struct_with_array(x): """ >>> x, y = to_struct_with_array([ ... {'a': 11, 'b': [{'x': 12, 'y': 13}, {'x': 14, 'y': 15}]}, ... {'a': 21, 'b': [{'x': 22, 'y': 23}, {'x': 24, 'y': 25}]}, ... ]) >>> x['a'], y['a'] (11, 21) >>> sorted(sorted(v.items()) for v in x['b']) [[('x', 12), ('y', 13.0)], [('x', 14), ('y', 15.0)]] >>> sorted(sorted(v.items()) for v in y['b']) [[('x', 22), ('y', 23.0)], [('x', 24), ('y', 25.0)]] >>> x, y = to_struct_with_array(iter([ ... {'a': 11, 'b': iter([{'x': 12, 'y': 13}, {'x': 14, 'y': 15}])}, ... {'a': 21, 'b': iter([{'x': 22, 'y': 23}, {'x': 24, 'y': 25}])}, ... ])) >>> x['a'], y['a'] (11, 21) >>> sorted(sorted(v.items()) for v in x['b']) [[('x', 12), ('y', 13.0)], [('x', 14), ('y', 15.0)]] >>> sorted(sorted(v.items()) for v in y['b']) [[('x', 22), ('y', 23.0)], [('x', 24), ('y', 25.0)]] """ cdef StructWithArray[2] v v = x return v def to_struct_with_array_slice(x): """ >>> x, y = to_struct_with_array_slice([ ... {'a': 11, 'b': [{'x': 12, 'y': 13}, {'x': 14, 'y': 15}]}, ... {'a': 21, 'b': [{'x': 22, 'y': 23}, {'x': 24, 'y': 25}]}, ... ]) >>> x['a'], y['a'] (11, 21) >>> sorted(sorted(v.items()) for v in x['b']) [[('x', 12), ('y', 13.0)], [('x', 14), ('y', 15.0)]] >>> sorted(sorted(v.items()) for v in y['b']) [[('x', 22), ('y', 23.0)], [('x', 24), ('y', 25.0)]] >>> x, y = to_struct_with_array_slice(iter([ ... {'a': 11, 'b': iter([{'x': 12, 'y': 13}, {'x': 14, 'y': 15}])}, ... {'a': 21, 'b': iter([{'x': 22, 'y': 23}, {'x': 24, 'y': 25}])}, ... ])) >>> x['a'], y['a'] (11, 21) >>> sorted(sorted(v.items()) for v in x['b']) [[('x', 12), ('y', 13.0)], [('x', 14), ('y', 15.0)]] >>> sorted(sorted(v.items()) for v in y['b']) [[('x', 22), ('y', 23.0)], [('x', 24), ('y', 25.0)]] """ cdef StructWithArray[2] v v[:] = x return v ''' # FIXME: this isn't currently allowed def to_struct_with_array_slice_end(x): """ >>> to_struct_with_array_slice_end([ ... {'a': 11, 'b': [{'x': 12, 'y': 13}, {'x': 14, 'y': 15}]}, ... ]) [{'a': 11, 'b': [{'y': 13.0, 'x': 12}, {'y': 15.0, 'x': 14}]}] >>> to_struct_with_array_slice_end(iter([ ... {'a': 11, 'b': iter([{'x': 12, 'y': 13}, {'x': 14, 'y': 15}])}, ... ])) [{'a': 11, 'b': [{'y': 13.0, 'x': 12}, {'y': 15.0, 'x': 14}]}] >>> to_struct_with_array_slice_end(iter([ ... {'a': 11, 'b': iter([{'x': 12, 'y': 13}, {'x': 14, 'y': 15}])}, ... {'a': 21, 'b': iter([{'x': 22, 'y': 23}, {'x': 24, 'y': 25}])}, ... ])) Traceback (most recent call last): IndexError: too many values found during array assignment, expected 1 """ cdef StructWithArray[2] v v[:1] = x return v def to_int_array_slice_start_end(x): """ >>> to_int_array_slice_start_end([1, 2, 3]) (1, 2, 3, 2, 3) """ cdef int[5] v v[2:] = x v[:3] = x return v[0], v[1], v[2], v[3], v[4] ''' Cython-0.23.4/tests/run/capiimpl.pyx0000644000175600017570000000156712606202452020523 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> import sys >>> sys.getrefcount(Foo.__pyx_vtable__) 2 >>> sys.getrefcount(__pyx_capi__['bar']) 2 >>> sys.getrefcount(__pyx_capi__['spam']) 2 >>> sys.getrefcount(__pyx_capi__['ten']) 2 >>> sys.getrefcount(__pyx_capi__['pi']) 2 >>> sys.getrefcount(__pyx_capi__['obj']) 2 >>> sys.getrefcount(__pyx_capi__['dct']) 2 >>> sys.getrefcount(__pyx_capi__['tpl']) 2 >>> sys.getrefcount(__pyx_capi__['one']) 2 >>> sys.getrefcount(__pyx_capi__['two']) Traceback (most recent call last): ... KeyError: 'two' """ cdef public api class Foo [type FooType, object FooObject]: cdef void bar(self): pass cdef public api void bar(): pass cdef api void spam(): pass cdef api int ten = 10 cdef api double pi = 3.14 cdef api object obj = object() cdef api dict dct = {} cdef public api tuple tpl = () cdef public api float one = 1 cdef public float two = 2 Cython-0.23.4/tests/run/callargs.pyx0000644000175600017570000000725012606202452020510 0ustar jenkinsjenkins00000000000000def c(a=10, b=20, **kwds): """ >>> c() 10 20 0 >>> c(1) 1 20 0 >>> c(1,2) 1 2 0 >>> c(key=None) 10 20 1 >>> c(1, key=None) 1 20 1 >>> c(1,2, key=None) 1 2 1 """ print a, b, len(kwds) def d(a, b=1, *args, **kwds): """ >>> d() Traceback (most recent call last): TypeError: d() takes at least 1 positional argument (0 given) >>> d(1) 1 1 0 0 >>> d(1,2) 1 2 0 0 >>> d(1,2,3) 1 2 1 0 >>> d(key=None) Traceback (most recent call last): TypeError: d() takes at least 1 positional argument (0 given) >>> d(1, key=None) 1 1 0 1 >>> d(1,2, key=None) 1 2 0 1 >>> d(1,2,3, key=None) 1 2 1 1 """ print a, b, len(args), len(kwds) def e(*args, **kwargs): print len(args), len(kwargs) def f(*args): """ >>> f(1,2, d=5) Traceback (most recent call last): TypeError: f() got an unexpected keyword argument 'd' >>> f(1, d=5) Traceback (most recent call last): TypeError: f() got an unexpected keyword argument 'd' >>> f(d=5) Traceback (most recent call last): TypeError: f() got an unexpected keyword argument 'd' """ print len(args) def g(**kwargs): """ >>> g(1,2, d=5) Traceback (most recent call last): TypeError: g() takes exactly 0 positional arguments (2 given) >>> g(1,2) Traceback (most recent call last): TypeError: g() takes exactly 0 positional arguments (2 given) >>> g(1) Traceback (most recent call last): TypeError: g() takes exactly 0 positional arguments (1 given) """ print len(kwargs) def h(a, b, c, *args, **kwargs): """ >>> h(1,2, d=5) Traceback (most recent call last): TypeError: h() takes at least 3 positional arguments (2 given) """ print a, b, c, u'*', len(args), len(kwargs) args = (9,8,7) import sys if sys.version_info[0] >= 3: kwargs = {u"test" : u"toast"} else: kwargs = {"test" : u"toast"} def test_kw_args(f): """ >>> test_kw_args(h) 1 2 3 * 0 0 1 2 9 * 2 1 1 2 7 * 2 1 1 2 9 * 2 2 1 2 9 * 2 2 1 2 9 * 2 3 >>> test_kw_args(e) 2 1 5 1 5 1 5 2 5 2 5 3 """ f(1,2, c=3) f(1,2, d=3, *args) f(1,2, d=3, *(7,8,9)) f(1,2, d=3, *args, **kwargs) f(1,2, d=3, *args, e=5) f(1,2, d=3, *args, e=5, **kwargs) def test_pos_args(f): """ >>> test_pos_args(h) 1 2 3 * 0 0 1 2 9 * 2 0 1 2 7 * 2 0 9 8 7 * 0 0 7 8 9 * 0 0 >>> test_pos_args(f) 3 5 5 3 3 """ f(1,2,3) f(1,2, *args) f(1,2, *(7,8,9)) f(*args) f(*(7,8,9)) def test_kw(f): """ >>> test_kw(e) 0 1 0 2 0 2 0 1 >>> test_kw(g) 1 2 2 1 """ f(c=3) f(d=3, e=5) f(d=3, **kwargs) f(**kwargs) def test_noargs(f): """ >>> test_noargs(e) 0 0 >>> test_noargs(f) 0 >>> test_noargs(g) 0 # and some errors: >>> test_noargs(h) Traceback (most recent call last): TypeError: h() takes at least 3 positional arguments (0 given) """ f() def test_int_kwargs(f): """ >>> test_int_kwargs(e) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...keywords must be strings >>> test_int_kwargs(f) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...keywords must be strings >>> test_int_kwargs(g) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...keywords must be strings >>> test_int_kwargs(h) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...keywords must be strings """ f(a=1,b=2,c=3, **{10:20,30:40}) Cython-0.23.4/tests/run/call_crash.pyx0000644000175600017570000000064712606202452021016 0ustar jenkinsjenkins00000000000000cdef class A: """ >>> A().test(3) 9 """ cdef int (*func_ptr)(int) def __init__(self): self.func_ptr = &func cdef int do_it(self, int s): cdef int r = first_call(self).func_ptr(s) # the temp for first_call(self) not properly freed return r def test(self, s): return self.do_it(s) cdef A first_call(A x): return x cdef int func(int s): return s*s Cython-0.23.4/tests/run/c_type_methods_T236.pyx0000644000175600017570000000157512606202452022450 0ustar jenkinsjenkins00000000000000# ticket: 236 __doc__ = '' import sys if sys.version_info >= (2,6): __doc__ += ''' >>> float_is_integer(1.0) True >>> float_is_integer(1.1) False ''' if sys.version_info >= (3,1): __doc__ += ''' >>> int_bit_length(1) == (1).bit_length() True >>> int_bit_length(1234) == (1234).bit_length() True ''' def float_is_integer(float f): # requires Python 2.6+ return f.is_integer() def int_bit_length(int i): # requires Python 3.x return i.bit_length() def float__add__(float f): """ >>> float__add__(5.0) 7.0 """ return f.__add__(2) def float_const__add__(float f): """ >>> float_const__add__(5.0) 7.0 """ return 2. .__add__(f) def int__add__(int i): """ >>> int__add__(5) 7 """ return i.__add__(2) def int_const__add__(int i): """ >>> int_const__add__(5) 7 """ return 2 .__add__(i) Cython-0.23.4/tests/run/c_int_types_T255.pyx0000644000175600017570000004635512606202452021770 0ustar jenkinsjenkins00000000000000# ticket: 255 __doc__ = u"" # ------------------------------------------------------------------- SCHAR_MAX = ((-1)>>1) SCHAR_MIN = (-SCHAR_MAX-1) def test_schar(signed char x): u""" >>> test_schar(-129) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_schar(-128) -128 >>> test_schar(0) 0 >>> test_schar(127) 127 >>> test_schar(128) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to signed char """ return x def test_add_schar(x, y): u""" >>> test_add_schar(SCHAR_MIN, -1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_add_schar(SCHAR_MIN, 0) == SCHAR_MIN True >>> test_add_schar(SCHAR_MIN, 1) == SCHAR_MIN+1 True >>> test_add_schar(SCHAR_MAX, -1) == SCHAR_MAX-1 True >>> test_add_schar(SCHAR_MAX, 0) == SCHAR_MAX True >>> test_add_schar(SCHAR_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to signed char """ cdef signed char r = x + y return r UCHAR_MAX = ((-1)) def test_uchar(unsigned char x): u""" >>> test_uchar(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: can't convert negative value to unsigned char >>> test_uchar(0) 0 >>> test_uchar(1) 1 >>> test_uchar(UCHAR_MAX) == UCHAR_MAX True >>> test_uchar(UCHAR_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to unsigned char """ return x def test_add_uchar(x, y): u""" >>> test_add_uchar(UCHAR_MAX, 0) == UCHAR_MAX True >>> test_add_uchar(UCHAR_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to unsigned char """ cdef unsigned char r = x + y return r # chars may be signed or unsigned if (-1) < 0: CHAR_MAX = SCHAR_MAX CHAR_MIN = SCHAR_MIN else: CHAR_MAX = UCHAR_MAX CHAR_MIN = 0 def test_char(char x): u""" >>> test_char(CHAR_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> if CHAR_MIN < 0: ... assert test_char(-1) == -1 >>> test_char(CHAR_MIN) == CHAR_MIN True >>> test_char(0) 0 >>> test_char(1) 1 >>> test_char(CHAR_MAX) == CHAR_MAX True >>> test_char(CHAR_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to char """ return x def test_add_char(x, y): u""" >>> test_add_char(CHAR_MIN, -1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_add_char(CHAR_MIN, 0) == CHAR_MIN True >>> test_add_char(CHAR_MIN, 1) == CHAR_MIN+1 True >>> test_add_char(CHAR_MAX, -1) == CHAR_MAX-1 True >>> test_add_char(CHAR_MAX, 0) == CHAR_MAX True >>> test_add_char(CHAR_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to char """ cdef char r = x + y return r # ------------------------------------------------------------------- SHORT_MAX = ((-1)>>1) SHORT_MIN = (-SHORT_MAX-1) def test_short(short x): u""" >>> test_short(SHORT_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to short >>> test_short(SHORT_MIN) == SHORT_MIN True >>> test_short(-1) -1 >>> test_short(0) 0 >>> test_short(1) 1 >>> test_short(SHORT_MAX) == SHORT_MAX True >>> test_short(SHORT_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to short """ return x def test_add_short(x, y): u""" >>> test_add_short(SHORT_MIN, -1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to short >>> test_add_short(SHORT_MIN, 0) == SHORT_MIN True >>> test_add_short(SHORT_MIN, 1) == SHORT_MIN+1 True >>> test_add_short(SHORT_MAX, -1) == SHORT_MAX-1 True >>> test_add_short(SHORT_MAX, 0) == SHORT_MAX True >>> test_add_short(SHORT_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to short """ cdef short r = x + y return r SSHORT_MAX = ((-1)>>1) SSHORT_MIN = (-SSHORT_MAX-1) def test_sshort(short x): u""" >>> test_sshort(SSHORT_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to short >>> test_sshort(SSHORT_MIN) == SSHORT_MIN True >>> test_sshort(-1) -1 >>> test_sshort(0) 0 >>> test_sshort(1) 1 >>> test_sshort(SSHORT_MAX) == SSHORT_MAX True >>> test_short(SSHORT_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to short """ return x def test_add_sshort(x, y): u""" >>> test_add_sshort(SSHORT_MIN, -1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to short >>> test_add_sshort(SSHORT_MIN, 0) == SSHORT_MIN True >>> test_add_sshort(SSHORT_MIN, 1) == SSHORT_MIN+1 True >>> test_add_sshort(SSHORT_MAX, -1) == SSHORT_MAX-1 True >>> test_add_sshort(SSHORT_MAX, 0) == SSHORT_MAX True >>> test_add_sshort(SSHORT_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to short """ cdef signed short r = x + y return r USHORT_MAX = ((-1)) def test_ushort(unsigned short x): u""" >>> test_ushort(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: can't convert negative value to unsigned short >>> test_ushort(0) 0 >>> test_ushort(1) 1 >>> test_ushort(USHORT_MAX) == USHORT_MAX True >>> test_ushort(USHORT_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_ushort(x, y): u""" >>> test_add_ushort(USHORT_MAX, 0) == USHORT_MAX True >>> test_add_ushort(USHORT_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: value too large to convert to unsigned short """ cdef unsigned short r = x + y return r # ------------------------------------------------------------------- INT_MAX = ((-1)>>1) INT_MIN = (-INT_MAX-1) def test_int(int x): u""" >>> test_int(INT_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_int(INT_MIN) == INT_MIN True >>> test_int(-1) -1 >>> test_int(0) 0 >>> test_int(1) 1 >>> test_int(INT_MAX) == INT_MAX True >>> test_int(INT_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_int(x, y): u""" >>> test_add_int(INT_MIN, -1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_add_int(INT_MIN, 0) == INT_MIN True >>> test_add_int(INT_MIN, 1) == INT_MIN+1 True >>> test_add_int(INT_MAX, -1) == INT_MAX-1 True >>> test_add_int(INT_MAX, 0) == INT_MAX True >>> test_add_int(INT_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef int r = x + y return r SINT_MAX = ((-1)>>1) SINT_MIN = (-SINT_MAX-1) def test_sint(signed int x): u""" >>> test_sint(SINT_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_sint(SINT_MIN) == SINT_MIN True >>> test_sint(-1) -1 >>> test_sint(0) 0 >>> test_sint(1) 1 >>> test_sint(SINT_MAX) == SINT_MAX True >>> test_sint(SINT_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_sint(x, y): u""" >>> test_add_sint(SINT_MIN, -1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_add_sint(SINT_MIN, 0) == SINT_MIN True >>> test_add_sint(SINT_MIN, 1) == SINT_MIN+1 True >>> test_add_sint(SINT_MAX, -1) == SINT_MAX-1 True >>> test_add_sint(SINT_MAX, 0) == SINT_MAX True >>> test_add_sint(SINT_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef signed int r = x + y return r UINT_MAX = (-1) def test_uint(unsigned int x): u""" >>> test_uint(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: can't convert negative value to unsigned int >>> print(test_uint(0)) 0 >>> print(test_uint(1)) 1 >>> test_uint(UINT_MAX) == UINT_MAX True >>> test_uint(UINT_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_uint(x, y): u""" >>> test_add_uint(UINT_MAX, 0) == UINT_MAX True >>> test_add_uint(UINT_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef unsigned int r = x + y return r # ------------------------------------------------------------------- LONG_MAX = ((-1)>>1) LONG_MIN = (-LONG_MAX-1) def test_long(long x): u""" >>> test_long(LONG_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_long(LONG_MIN) == LONG_MIN True >>> test_long(-1) -1 >>> test_long(0) 0 >>> test_long(1) 1 >>> test_long(LONG_MAX) == LONG_MAX True >>> test_long(LONG_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_long(x, y): u""" >>> test_add_long(LONG_MIN, -1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_add_long(LONG_MIN, 0) == LONG_MIN True >>> test_add_long(LONG_MIN, 1) == LONG_MIN+1 True >>> test_add_long(LONG_MAX, -1) == LONG_MAX-1 True >>> test_add_long(LONG_MAX, 0) == LONG_MAX True >>> test_add_long(LONG_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef long r = x + y return r SLONG_MAX = ((-1)>>1) SLONG_MIN = (-SLONG_MAX-1) def test_slong(signed long x): u""" >>> test_slong(SLONG_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_slong(SLONG_MIN) == SLONG_MIN True >>> test_slong(-1) -1 >>> test_slong(0) 0 >>> test_slong(1) 1 >>> test_slong(SLONG_MAX) == SLONG_MAX True >>> test_slong(SLONG_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_slong(x, y): u""" >>> test_add_slong(SLONG_MIN, -1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_add_slong(SLONG_MIN, 0) == SLONG_MIN True >>> test_add_slong(SLONG_MIN, 1) == SLONG_MIN+1 True >>> test_add_slong(SLONG_MAX, -1) == SLONG_MAX-1 True >>> test_add_slong(SLONG_MAX, 0) == SLONG_MAX True >>> test_add_slong(SLONG_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef signed long r = x + y return r ULONG_MAX = (-1) def test_ulong(unsigned long x): u""" >>> test_ulong(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: can't convert negative value to unsigned long >>> print(test_ulong(0)) 0 >>> print(test_ulong(1)) 1 >>> test_ulong(ULONG_MAX) == ULONG_MAX True >>> test_ulong(ULONG_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_ulong(x, y): u""" >>> test_add_ulong(ULONG_MAX, 0) == ULONG_MAX True >>> test_add_ulong(ULONG_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef unsigned long r = x + y return r # ------------------------------------------------------------------- LONGLONG_MAX = ((-1)>>1) LONGLONG_MIN = (-LONGLONG_MAX-1) def test_longlong(long long x): u""" >>> test_longlong(LONGLONG_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_longlong(LONGLONG_MIN) == LONGLONG_MIN True >>> print(test_longlong(-1)) -1 >>> print(test_longlong(0)) 0 >>> print(test_longlong(1)) 1 >>> test_longlong(LONGLONG_MAX) == LONGLONG_MAX True >>> test_longlong(LONGLONG_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_longlong(x, y): u""" >>> test_add_longlong(LONGLONG_MIN, -1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_add_longlong(LONGLONG_MIN, 0) == LONGLONG_MIN True >>> test_add_longlong(LONGLONG_MIN, 1) == LONGLONG_MIN+1 True >>> test_add_longlong(LONGLONG_MAX, -1) == LONGLONG_MAX-1 True >>> test_add_longlong(LONGLONG_MAX, 0) == LONGLONG_MAX True >>> test_add_longlong(LONGLONG_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef long long r = x + y return r SLONGLONG_MAX = ((-1)>>1) SLONGLONG_MIN = (-SLONGLONG_MAX-1) def test_slonglong(long long x): u""" >>> test_slonglong(SLONGLONG_MIN-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_slonglong(SLONGLONG_MIN) == SLONGLONG_MIN True >>> print(test_slonglong(-1)) -1 >>> print(test_slonglong(0)) 0 >>> print(test_slonglong(1)) 1 >>> test_slonglong(SLONGLONG_MAX) == SLONGLONG_MAX True >>> test_slonglong(SLONGLONG_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_slonglong(x, y): u""" >>> test_add_slonglong(SLONGLONG_MIN, -1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... >>> test_add_slonglong(SLONGLONG_MIN, 0) == SLONGLONG_MIN True >>> test_add_slonglong(SLONGLONG_MIN, 1) == SLONGLONG_MIN+1 True >>> test_add_slonglong(SLONGLONG_MAX, -1) == SLONGLONG_MAX-1 True >>> test_add_slonglong(SLONGLONG_MAX, 0) == SLONGLONG_MAX True >>> test_add_slonglong(SLONGLONG_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef signed long long r = x + y return r ULONGLONG_MAX = (-1) def test_ulonglong(unsigned long long x): u""" >>> test_ulonglong(-1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: can't convert negative value to unsigned PY_LONG_LONG >>> print(test_ulonglong(0)) 0 >>> print(test_ulonglong(1)) 1 >>> test_ulonglong(ULONGLONG_MAX) == ULONGLONG_MAX True >>> test_ulonglong(ULONGLONG_MAX+1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ return x def test_add_ulonglong(x, y): u""" >>> test_add_ulonglong(ULONGLONG_MAX, 0) == ULONGLONG_MAX True >>> test_add_ulonglong(ULONGLONG_MAX, 1) #doctest: +ELLIPSIS Traceback (most recent call last): ... OverflowError: ... """ cdef unsigned long long r = x + y return r # ------------------------------------------------------------------- import sys class MyInt(object): def __init__(self, value): self.value = value def __int__(self): print(u"MyInt.__int__()") return self.value class MyBadInt(MyInt): def __int__(self): return u"%s" % self.value class MyInt2: def __init__(self, value): self.value = value def __int__(self): print(u"MyInt.__int__()") return self.value class MyBadInt2(MyInt2): def __int__(self): return u"%s" % self.value def test_convert_pyint(x): u""" >>> test_convert_pyint(None) Traceback (most recent call last): ... TypeError: an integer is required >>> test_convert_pyint("123") Traceback (most recent call last): ... TypeError: an integer is required >>> test_convert_pyint(MyBadInt(0)) #doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: ... returned non-... (type ...) >>> test_convert_pyint(False) == 0 True >>> test_convert_pyint(True) == 1 True >>> test_convert_pyint(3.14) == 3 True >>> test_convert_pyint(MyInt(LONG_MIN)) == LONG_MIN MyInt.__int__() True >>> test_convert_pyint(MyInt(0)) == 0 MyInt.__int__() True >>> test_convert_pyint(MyInt(LONG_MAX)) == LONG_MAX MyInt.__int__() True """ cdef long r = x return r class MyLong(object): def __init__(self, value): self.value = value def __int__(self): # Python 3 return self.__long__() def __long__(self): print(u"MyInt.__long__()") return self.value class MyBadLong(MyLong): def __long__(self): return u"%s" % self.value def test_convert_pylong(x): u""" >>> test_convert_pylong(None) Traceback (most recent call last): ... TypeError: an integer is required >>> test_convert_pylong("123") Traceback (most recent call last): ... TypeError: an integer is required >>> test_convert_pylong(MyBadLong(0)) #doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError: ... returned non-... (type ...) >>> test_convert_pylong(False) == 0 True >>> test_convert_pylong(True) == 1 True >>> test_convert_pylong(3.14) == 3 True >>> test_convert_pylong(MyLong(LONGLONG_MIN)) == LONGLONG_MIN MyInt.__long__() True >>> test_convert_pylong(MyLong(0)) == 0 MyInt.__long__() True >>> test_convert_pylong(MyLong(LONGLONG_MAX)) == LONGLONG_MAX MyInt.__long__() True """ cdef long long r = x return r # ------------------------------------------------------------------- __doc__ = u"".join([ f.__doc__ for f in ( # test_char, test_add_char, test_schar, test_add_schar, test_uchar, test_add_uchar, # test_short, test_add_short, test_sshort, test_add_sshort, test_ushort, test_add_ushort, # test_int, test_add_int, test_sint, test_add_sint, test_uint, test_add_uint, # test_long, test_add_long, test_slong, test_add_slong, test_ulong, test_add_ulong, # test_longlong, test_add_longlong, test_slonglong, test_add_slonglong, test_ulonglong, test_add_ulonglong, # test_convert_pyint, test_convert_pylong, ) ]) # ------------------------------------------------------------------- Cython-0.23.4/tests/run/bytesmethods.pyx0000644000175600017570000001376512606202452021442 0ustar jenkinsjenkins00000000000000cimport cython b_a = b'a' b_b = b'b' @cython.test_assert_path_exists( "//PythonCapiCallNode") @cython.test_fail_if_path_exists( "//SimpleCallNode") def bytes_startswith(bytes s, sub, start=None, stop=None): """ >>> bytes_startswith(b_a, b_a) True >>> bytes_startswith(b_a+b_b, b_a) True >>> bytes_startswith(b_a, b_b) False >>> bytes_startswith(b_a+b_b, b_b) False >>> bytes_startswith(b_a, (b_a, b_b)) True >>> bytes_startswith(b_a, b_a, 1) False >>> bytes_startswith(b_a, b_a, 0, 0) False """ if start is None: return s.startswith(sub) elif stop is None: return s.startswith(sub, start) else: return s.startswith(sub, start, stop) @cython.test_assert_path_exists( "//PythonCapiCallNode") @cython.test_fail_if_path_exists( "//SimpleCallNode") def bytes_endswith(bytes s, sub, start=None, stop=None): """ >>> bytes_endswith(b_a, b_a) True >>> bytes_endswith(b_b+b_a, b_a) True >>> bytes_endswith(b_a, b_b) False >>> bytes_endswith(b_b+b_a, b_b) False >>> bytes_endswith(b_a, (b_a, b_b)) True >>> bytes_endswith(b_a, b_a, 1) False >>> bytes_endswith(b_a, b_a, 0, 0) False """ if start is None: return s.endswith(sub) elif stop is None: return s.endswith(sub, start) else: return s.endswith(sub, start, stop) @cython.test_assert_path_exists( "//PythonCapiCallNode") @cython.test_fail_if_path_exists( "//SimpleCallNode") def bytes_decode(bytes s, start=None, stop=None): """ >>> s = b_a+b_b+b_a+b_a+b_b >>> print(bytes_decode(s)) abaab >>> print(bytes_decode(s, 2)) aab >>> print(bytes_decode(s, -3)) aab >>> print(bytes_decode(s, None, 4)) abaa >>> print(bytes_decode(s, None, 400)) abaab >>> print(bytes_decode(s, None, -2)) aba >>> print(bytes_decode(s, None, -4)) a >>> print(bytes_decode(s, None, -5)) >>> print(bytes_decode(s, None, -200)) >>> print(bytes_decode(s, 2, 5)) aab >>> print(bytes_decode(s, 2, 500)) aab >>> print(bytes_decode(s, 2, -1)) aa >>> print(bytes_decode(s, 2, -3)) >>> print(bytes_decode(s, 2, -300)) >>> print(bytes_decode(s, -3, -1)) aa >>> print(bytes_decode(s, -300, 300)) abaab >>> print(bytes_decode(s, -300, -4)) a >>> print(bytes_decode(s, -300, -5)) >>> print(bytes_decode(s, -300, -6)) >>> print(bytes_decode(s, -300, -500)) >>> s[:'test'] # doctest: +ELLIPSIS Traceback (most recent call last): TypeError:... >>> print(bytes_decode(s, 'test')) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError:... >>> print(bytes_decode(s, None, 'test')) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError:... >>> print(bytes_decode(s, 'test', 'test')) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError:... >>> print(bytes_decode(None)) Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'decode' >>> print(bytes_decode(None, 1)) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable >>> print(bytes_decode(None, None, 1)) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable >>> print(bytes_decode(None, 0, 1)) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable """ if start is None: if stop is None: return s.decode('utf8') else: return s[:stop].decode('utf8') elif stop is None: return s[start:].decode('utf8') else: return s[start:stop].decode('utf8') @cython.test_assert_path_exists( "//PythonCapiCallNode") @cython.test_fail_if_path_exists( "//SimpleCallNode") def bytes_decode_unbound_method(bytes s, start=None, stop=None): """ >>> s = b_a+b_b+b_a+b_a+b_b >>> print(bytes_decode_unbound_method(s)) abaab >>> print(bytes_decode_unbound_method(s, 1)) baab >>> print(bytes_decode_unbound_method(s, None, 3)) aba >>> print(bytes_decode_unbound_method(s, 1, 4)) baa >>> print(bytes_decode_unbound_method(None)) Traceback (most recent call last): TypeError: descriptor 'decode' requires a 'bytes' object but received a 'NoneType' >>> print(bytes_decode_unbound_method(None, 1)) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable >>> print(bytes_decode_unbound_method(None, None, 1)) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable >>> print(bytes_decode_unbound_method(None, 0, 1)) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable """ if start is None: if stop is None: return bytes.decode(s, 'utf8') else: return bytes.decode(s[:stop], 'utf8') elif stop is None: return bytes.decode(s[start:], 'utf8') else: return bytes.decode(s[start:stop], 'utf8') @cython.test_assert_path_exists( "//SimpleCallNode", "//SimpleCallNode//NoneCheckNode", "//SimpleCallNode//AttributeNode[@is_py_attr = false]") def bytes_join(bytes s, *args): """ >>> print(bytes_join(b_a, b_b, b_b, b_b).decode('utf8')) babab """ result = s.join(args) assert cython.typeof(result) == 'Python object', cython.typeof(result) return result @cython.test_fail_if_path_exists( "//SimpleCallNode//NoneCheckNode", ) @cython.test_assert_path_exists( "//SimpleCallNode", "//SimpleCallNode//AttributeNode[@is_py_attr = false]") def literal_join(*args): """ >>> print(literal_join(b_b, b_b, b_b, b_b).decode('utf8')) b|b|b|b """ result = b'|'.join(args) assert cython.typeof(result) == 'Python object', cython.typeof(result) return result Cython-0.23.4/tests/run/bytes_indexing.pyx0000644000175600017570000001221612606202452021731 0ustar jenkinsjenkins00000000000000 cimport cython cdef bytes b12345 = b'12345' def index_literal(int i): """ Python 3 returns integer values on indexing, Py2 returns byte string literals... >>> index_literal(0) in (ord('1'), '1') True >>> index_literal(-5) in (ord('1'), '1') True >>> index_literal(2) in (ord('3'), '3') True >>> index_literal(4) in (ord('5'), '5') True """ return b"12345"[i] @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//IndexNode", "//CoerceFromPyTypeNode") def index_literal_char_cast(int i): """ >>> index_literal_char_cast(0) == ord('1') True >>> index_literal_char_cast(-5) == ord('1') True >>> index_literal_char_cast(2) == ord('3') True >>> index_literal_char_cast(4) == ord('5') True >>> index_literal_char_cast(6) Traceback (most recent call last): IndexError: string index out of range """ return (b"12345"[i]) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//IndexNode", "//CoerceFromPyTypeNode") def index_nonliteral_char_cast(int i): """ >>> index_nonliteral_char_cast(0) == ord('1') True >>> index_nonliteral_char_cast(-5) == ord('1') True >>> index_nonliteral_char_cast(2) == ord('3') True >>> index_nonliteral_char_cast(4) == ord('5') True >>> index_nonliteral_char_cast(6) Traceback (most recent call last): IndexError: string index out of range """ return (b12345[i]) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//IndexNode", "//CoerceFromPyTypeNode") def index_literal_uchar_cast(int i): """ >>> index_literal_uchar_cast(0) == ord('1') True >>> index_literal_uchar_cast(-5) == ord('1') True >>> index_literal_uchar_cast(2) == ord('3') True >>> index_literal_uchar_cast(4) == ord('5') True >>> index_literal_uchar_cast(6) Traceback (most recent call last): IndexError: string index out of range """ return (b"12345"[i]) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//IndexNode", "//CoerceFromPyTypeNode") def index_nonliteral_uchar_cast(int i): """ >>> index_nonliteral_uchar_cast(0) == ord('1') True >>> index_nonliteral_uchar_cast(-5) == ord('1') True >>> index_nonliteral_uchar_cast(2) == ord('3') True >>> index_nonliteral_uchar_cast(4) == ord('5') True >>> index_nonliteral_uchar_cast(6) Traceback (most recent call last): IndexError: string index out of range """ return (b12345[i]) @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//IndexNode", "//CoerceFromPyTypeNode") def index_literal_char_coerce(int i): """ >>> index_literal_char_coerce(0) == ord('1') True >>> index_literal_char_coerce(-5) == ord('1') True >>> index_literal_char_coerce(2) == ord('3') True >>> index_literal_char_coerce(4) == ord('5') True >>> index_literal_char_coerce(6) Traceback (most recent call last): IndexError: string index out of range """ cdef char result = b"12345"[i] return result @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//IndexNode", "//CoerceFromPyTypeNode") def index_nonliteral_char_coerce(int i): """ >>> index_nonliteral_char_coerce(0) == ord('1') True >>> index_nonliteral_char_coerce(-5) == ord('1') True >>> index_nonliteral_char_coerce(2) == ord('3') True >>> index_nonliteral_char_coerce(4) == ord('5') True >>> index_nonliteral_char_coerce(6) Traceback (most recent call last): IndexError: string index out of range """ cdef char result = b12345[i] return result @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//IndexNode", "//CoerceFromPyTypeNode") @cython.boundscheck(False) def index_literal_char_coerce_no_check(int i): """ >>> index_literal_char_coerce_no_check(0) == ord('1') True >>> index_literal_char_coerce_no_check(-5) == ord('1') True >>> index_literal_char_coerce_no_check(2) == ord('3') True >>> index_literal_char_coerce_no_check(4) == ord('5') True """ cdef char result = b"12345"[i] return result @cython.test_assert_path_exists("//PythonCapiCallNode") @cython.test_fail_if_path_exists("//IndexNode", "//CoerceFromPyTypeNode") @cython.boundscheck(False) def index_nonliteral_char_coerce_no_check(int i): """ >>> index_nonliteral_char_coerce_no_check(0) == ord('1') True >>> index_nonliteral_char_coerce_no_check(-5) == ord('1') True >>> index_nonliteral_char_coerce_no_check(2) == ord('3') True >>> index_nonliteral_char_coerce_no_check(4) == ord('5') True """ cdef char result = b12345[i] return result Cython-0.23.4/tests/run/bytes_char_coercion.pyx0000644000175600017570000001120212606202452022714 0ustar jenkinsjenkins00000000000000 cimport cython def coerce_char_default(char c): """ Default char -> int coercion >>> coerce_char_default(ord('A')) == ord('A') True """ return c def coerce_uchar_default(unsigned char c): """ Default char -> int coercion >>> coerce_uchar_default(ord('A')) == ord('A') True """ return c @cython.test_assert_path_exists("//CoerceIntToBytesNode") @cython.test_fail_if_path_exists("//CoerceToPyTypeNode") def coerce_char_bytes_cast(char c): """ Explicit char -> bytes coercion >>> coerce_char_bytes_cast(ord('A')) == 'A'.encode('ASCII') True """ return c @cython.test_assert_path_exists("//CoerceIntToBytesNode") @cython.test_fail_if_path_exists("//CoerceToPyTypeNode") def coerce_uchar_bytes_cast(unsigned char c): """ Explicit uchar -> bytes coercion >>> coerce_uchar_bytes_cast(ord('A')) == 'A'.encode('ASCII') True >>> b = coerce_uchar_bytes_cast(ord('\\xff')) >>> b == '\\xff' or b == '\\xff'.encode('ISO-8859-1') # Py2 or Py3 True """ return c @cython.test_assert_path_exists("//CoerceIntToBytesNode") @cython.test_fail_if_path_exists("//CoerceToPyTypeNode") def coerce_int_bytes_cast(int c): """ Explicit int -> bytes coercion >>> coerce_int_bytes_cast(ord('A')) == 'A'.encode('ASCII') True >>> coerce_int_bytes_cast(ord('A') + 0x100) Traceback (most recent call last): OverflowError: value too large to pack into a byte >>> coerce_int_bytes_cast(ord('A') - 0x100) Traceback (most recent call last): OverflowError: value too large to pack into a byte """ return c @cython.test_assert_path_exists("//CoerceIntToBytesNode") @cython.test_fail_if_path_exists("//CoerceToPyTypeNode") def coerce_uint_bytes_cast(unsigned int c): """ Explicit uint -> bytes coercion >>> coerce_uint_bytes_cast(ord('A')) == 'A'.encode('ASCII') True >>> b = coerce_uint_bytes_cast(ord('\\xff')) >>> b == '\\xff' or b == '\\xff'.encode('ISO-8859-1') # Py2 or Py3 True >>> coerce_uint_bytes_cast(ord('A') + 0x100) Traceback (most recent call last): OverflowError: value too large to pack into a byte """ return c @cython.test_assert_path_exists("//CoerceIntToBytesNode") @cython.test_fail_if_path_exists("//CoerceToPyTypeNode") def coerce_char_bytes_assign(char c): """ Implicit char -> bytes coercion in assignments >>> coerce_char_bytes_assign(ord('A')) == 'A'.encode('ASCII') True """ cdef bytes s = c return s @cython.test_assert_path_exists("//CoerceIntToBytesNode") @cython.test_fail_if_path_exists("//CoerceToPyTypeNode") def coerce_uchar_bytes_assign(unsigned char c): """ Implicit uchar -> bytes coercion in assignments >>> coerce_uchar_bytes_assign(ord('A')) == 'A'.encode('ASCII') True >>> b = coerce_uchar_bytes_assign(ord('\\xff')) >>> b == '\\xff' or b == '\\xff'.encode('ISO-8859-1') # Py2 or Py3 True """ cdef bytes s = c return s @cython.test_assert_path_exists("//CoerceIntToBytesNode") @cython.test_fail_if_path_exists("//CoerceToPyTypeNode") def coerce_int_bytes_assign(int c): """ Implicit int -> bytes coercion in assignments >>> coerce_int_bytes_assign(ord('A')) == 'A'.encode('ASCII') True >>> coerce_int_bytes_assign(ord('A') + 0x100) Traceback (most recent call last): OverflowError: value too large to pack into a byte >>> coerce_int_bytes_assign(ord('A') - 0x100) Traceback (most recent call last): OverflowError: value too large to pack into a byte """ cdef bytes s = c return s @cython.test_assert_path_exists("//CoerceIntToBytesNode") @cython.test_fail_if_path_exists("//CoerceToPyTypeNode") def coerce_uint_bytes_assign(unsigned int c): """ Implicit uint -> bytes coercion in assignments >>> coerce_uint_bytes_assign(ord('A')) == 'A'.encode('ASCII') True >>> b = coerce_uint_bytes_assign(ord('\\xff')) >>> b == '\\xff' or b == '\\xff'.encode('ISO-8859-1') # Py2 or Py3 True >>> coerce_uint_bytes_assign(ord('A') + 0x100) Traceback (most recent call last): OverflowError: value too large to pack into a byte """ cdef bytes s = c return s def inplace_ops_use_arithmetic(): """ >>> print(inplace_ops_use_arithmetic().decode('ascii')) bc """ cdef char* s = 'abc' cdef object x = 1 s += 1 s += 2*x s -= 1 s -= x return s @cython.test_fail_if_path_exists('//CoerceFromPyTypeNode') def indexing_to_char(bytes s): """ >>> ord('b') 98 >>> indexing_to_char('abc'.encode('ascii')) 98 """ cdef unsigned char c = s[1] return c Cython-0.23.4/tests/run/bytearraymethods.pyx0000644000175600017570000001744112606202452022311 0ustar jenkinsjenkins00000000000000 import sys IS_PY3 = sys.version_info[0] >= 3 cimport cython b_a = bytearray(b'a') b_b = bytearray(b'b') ''' # disabled for now, enable when we consider it worth the code overhead @cython.test_assert_path_exists( "//PythonCapiCallNode") @cython.test_fail_if_path_exists( "//SimpleCallNode") def bytearray_startswith(bytearray s, sub, start=None, stop=None): """ >>> bytearray_startswith(b_a, b_a) True >>> bytearray_startswith(b_a+b_b, b_a) True >>> bytearray_startswith(b_a, b_b) False >>> bytearray_startswith(b_a+b_b, b_b) False >>> bytearray_startswith(b_a, (b_a, b_b)) True >>> bytearray_startswith(b_a, b_a, 1) False >>> bytearray_startswith(b_a, b_a, 0, 0) False """ if start is None: return s.startswith(sub) elif stop is None: return s.startswith(sub, start) else: return s.startswith(sub, start, stop) @cython.test_assert_path_exists( "//PythonCapiCallNode") @cython.test_fail_if_path_exists( "//SimpleCallNode") def bytearray_endswith(bytearray s, sub, start=None, stop=None): """ >>> bytearray_endswith(b_a, b_a) True >>> bytearray_endswith(b_b+b_a, b_a) True >>> bytearray_endswith(b_a, b_b) False >>> bytearray_endswith(b_b+b_a, b_b) False >>> bytearray_endswith(b_a, (b_a, b_b)) True >>> bytearray_endswith(b_a, b_a, 1) False >>> bytearray_endswith(b_a, b_a, 0, 0) False """ if start is None: return s.endswith(sub) elif stop is None: return s.endswith(sub, start) else: return s.endswith(sub, start, stop) ''' @cython.test_assert_path_exists( "//PythonCapiCallNode") @cython.test_fail_if_path_exists( "//SimpleCallNode") def bytearray_decode(bytearray s, start=None, stop=None): """ >>> s = b_a+b_b+b_a+b_a+b_b >>> print(bytearray_decode(s)) abaab >>> print(bytearray_decode(s, 2)) aab >>> print(bytearray_decode(s, -3)) aab >>> print(bytearray_decode(s, None, 4)) abaa >>> print(bytearray_decode(s, None, 400)) abaab >>> print(bytearray_decode(s, None, -2)) aba >>> print(bytearray_decode(s, None, -4)) a >>> print(bytearray_decode(s, None, -5)) >>> print(bytearray_decode(s, None, -200)) >>> print(bytearray_decode(s, 2, 5)) aab >>> print(bytearray_decode(s, 2, 500)) aab >>> print(bytearray_decode(s, 2, -1)) aa >>> print(bytearray_decode(s, 2, -3)) >>> print(bytearray_decode(s, 2, -300)) >>> print(bytearray_decode(s, -3, -1)) aa >>> print(bytearray_decode(s, -300, 300)) abaab >>> print(bytearray_decode(s, -300, -4)) a >>> print(bytearray_decode(s, -300, -5)) >>> print(bytearray_decode(s, -300, -6)) >>> print(bytearray_decode(s, -300, -500)) >>> s[:'test'] # doctest: +ELLIPSIS Traceback (most recent call last): TypeError:... >>> print(bytearray_decode(s, 'test')) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError:... >>> print(bytearray_decode(s, None, 'test')) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError:... >>> print(bytearray_decode(s, 'test', 'test')) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError:... >>> print(bytearray_decode(None)) Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'decode' >>> print(bytearray_decode(None, 1)) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable >>> print(bytearray_decode(None, None, 1)) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable >>> print(bytearray_decode(None, 0, 1)) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable """ if start is None: if stop is None: return s.decode('utf8') else: return s[:stop].decode('utf8') elif stop is None: return s[start:].decode('utf8') else: return s[start:stop].decode('utf8') @cython.test_assert_path_exists( "//PythonCapiCallNode") @cython.test_fail_if_path_exists( "//SimpleCallNode") def bytearray_decode_unbound_method(bytearray s, start=None, stop=None): """ >>> s = b_a+b_b+b_a+b_a+b_b >>> print(bytearray_decode_unbound_method(s)) abaab >>> print(bytearray_decode_unbound_method(s, 1)) baab >>> print(bytearray_decode_unbound_method(s, None, 3)) aba >>> print(bytearray_decode_unbound_method(s, 1, 4)) baa >>> print(bytearray_decode_unbound_method(None)) Traceback (most recent call last): TypeError: descriptor 'decode' requires a 'bytearray' object but received a 'NoneType' >>> print(bytearray_decode_unbound_method(None, 1)) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable >>> print(bytearray_decode_unbound_method(None, None, 1)) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable >>> print(bytearray_decode_unbound_method(None, 0, 1)) Traceback (most recent call last): TypeError: 'NoneType' object is not subscriptable """ if start is None: if stop is None: return bytearray.decode(s, 'utf8') else: return bytearray.decode(s[:stop], 'utf8') elif stop is None: return bytearray.decode(s[start:], 'utf8') else: return bytearray.decode(s[start:stop], 'utf8') @cython.test_fail_if_path_exists('//SimpleCallNode') @cython.test_assert_path_exists('//PythonCapiCallNode') def bytearray_append(bytearray b, signed char c, int i, object o): """ >>> b = bytearray(b'abc') >>> b = bytearray_append(b, ord('x'), ord('y'), ord('z')) >>> print(b.decode('ascii')) abcX@xyz >>> b = bytearray(b'abc') >>> b = bytearray_append(b, ord('x'), ord('y'), 0) >>> print(b.decode('ascii')[:-1]) abcX@xy >>> b[-1] 0 >>> b = bytearray(b'abc') >>> b = bytearray_append(b, ord('x'), ord('y'), ord('z') if IS_PY3 else b'z') >>> print(b.decode('ascii')) abcX@xyz >>> b = bytearray(b'abc') >>> b = bytearray_append(b, ord('x'), ord('y'), ord('\\xc3') if IS_PY3 else b'\\xc3') >>> print(b[:-1].decode('ascii')) abcX@xy >>> print('%x' % b[-1]) c3 >>> b = bytearray(b'abc') >>> try: ... b = bytearray_append(b, ord('x'), ord('y'), b'zz') ... except (TypeError, ValueError): pass # (Py3, Py2) ... else: print("FAIL") >>> print(b.decode('ascii')) abcX@xy >>> b = bytearray(b'abc') >>> b = bytearray_append(b, -1, ord('y'), ord('z')) # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: ... >>> print(b.decode('ascii')) abcX@ >>> b = bytearray(b'abc') >>> b = bytearray_append(b, ord('x'), -1, ord('z')) # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: ... >>> print(b.decode('ascii')) abcX@x >>> b = bytearray(b'abc') >>> b = bytearray_append(b, ord('x'), 256, ord('z')) # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: ... >>> print(b.decode('ascii')) abcX@x >>> b = bytearray(b'abc') >>> b = bytearray_append(b, ord('x'), ord('y'), -1) # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: ... >>> print(b.decode('ascii')) abcX@xy >>> b = bytearray(b'abc') >>> b = bytearray_append(b, ord('x'), ord('y'), 256) # doctest: +ELLIPSIS Traceback (most recent call last): ValueError: ... >>> print(b.decode('ascii')) abcX@xy """ assert b.append('X') is None b.append(64) b.append(c) b.append(i) b.append(o) return b Cython-0.23.4/tests/run/bytearray_default_auto_encoding.pyx0000644000175600017570000000077512606202452025331 0ustar jenkinsjenkins00000000000000# cython: c_string_type = bytearray # cython: c_string_encoding = default import sys if sys.version_info[0] >= 3: __doc__ = r""" >>> isinstance(as_objects("ab\xff"), bytearray) True >>> as_objects("ab\xff") == bytearray("ab\xff".encode()) True >>> isinstance(slice_as_objects("ab\xff", 1, 4), bytearray) True >>> slice_as_objects("ab\xffd", 1, 4) == bytearray("b\xff".encode()) True """ include "bytearray_ascii_auto_encoding.pyx" Cython-0.23.4/tests/run/bytearray_coercion.pyx0000644000175600017570000000742112606202452022603 0ustar jenkinsjenkins00000000000000# mode: run # NOTE: Py2.6+ only cimport cython cpdef bytearray coerce_to_charptr(char* b): """ >>> b = bytearray(b'abc') >>> coerced = coerce_to_charptr(b) >>> coerced == b or coerced True >>> isinstance(coerced, bytearray) or type(coerced) True """ return b def coerce_to_charptrs(bytearray b): """ >>> b = bytearray(b'abc') >>> coerce_to_charptrs(b) True """ cdef char* cs = b cdef unsigned char* ucs = b cdef signed char* scs = b return b == cs == ucs == scs cpdef bytearray coerce_charptr_slice(char* b): """ >>> b = bytearray(b'abc') >>> coerced = coerce_charptr_slice(b) >>> coerced == b[:2] or coerced True >>> isinstance(coerced, bytearray) or type(coerced) True """ return b[:2] def infer_index_types(bytearray b): """ >>> b = bytearray(b'a\\xFEc') >>> print(infer_index_types(b)) (254, 254, 254, 'unsigned char', 'unsigned char', 'unsigned char', 'int') """ c = b[1] with cython.wraparound(False): d = b[1] with cython.boundscheck(False): e = b[1] return c, d, e, cython.typeof(c), cython.typeof(d), cython.typeof(e), cython.typeof(b[1]) def infer_slice_types(bytearray b): """ >>> b = bytearray(b'abc') >>> print(infer_slice_types(b)) (bytearray(b'bc'), bytearray(b'bc'), bytearray(b'bc'), 'Python object', 'Python object', 'Python object', 'bytearray object') """ c = b[1:] with cython.boundscheck(False): d = b[1:] with cython.boundscheck(False), cython.wraparound(False): e = b[1:] return c, d, e, cython.typeof(c), cython.typeof(d), cython.typeof(e), cython.typeof(b[1:]) def assign_to_index(bytearray b, value): """ >>> b = bytearray(b'0abcdefg') >>> assign_to_index(b, 1) bytearray(b'xyzee\\x01h') >>> b bytearray(b'xyzee\\x01h') >>> assign_to_index(bytearray(b'0ABCDEFG'), 40) bytearray(b'xyzEE(o') >>> assign_to_index(bytearray(b'0abcdefg'), -1) Traceback (most recent call last): OverflowError: can't convert negative value to unsigned char >>> assign_to_index(bytearray(b'0abcdef\\x00'), 255) bytearray(b'xyzee\\xff\\xff') >>> assign_to_index(bytearray(b'0abcdef\\x01'), 255) Traceback (most recent call last): OverflowError: value too large to convert to unsigned char >>> assign_to_index(bytearray(b'0abcdef\\x00'), 256) Traceback (most recent call last): OverflowError: value too large to convert to unsigned char """ b[1] = 'x' b[2] = b'y' b[3] = c'z' b[4] += 1 b[5] |= 1 b[6] = value b[7] += value del b[0] try: b[7] = 1 except IndexError: pass else: assert False, "IndexError not raised" try: b[int(str(len(b)))] = 1 # test non-int-index assignment except IndexError: pass else: assert False, "IndexError not raised" return b def check_bounds(int cvalue): """ >>> check_bounds(0) 0 >>> check_bounds(255) 255 >>> check_bounds(256) Traceback (most recent call last): ValueError: byte must be in range(0, 256) >>> check_bounds(-1) Traceback (most recent call last): ValueError: byte must be in range(0, 256) """ b = bytearray(b'x') try: b[0] = 256 except ValueError: pass else: assert False, "ValueError not raised" try: b[0] = -1 except ValueError: pass else: assert False, "ValueError not raised" b[0] = cvalue return b[0] def nogil_assignment(bytearray x, int value): """ >>> b = bytearray(b'abc') >>> nogil_assignment(b, ord('y')) >>> b bytearray(b'xyc') """ with nogil: x[0] = 'x' x[1] = value Cython-0.23.4/tests/run/bytearray_ascii_auto_encoding.pyx0000644000175600017570000000044312606202452024765 0ustar jenkinsjenkins00000000000000#cython: c_string_type = bytearray #cython: c_string_encoding = ascii "End of first directives" include "unicode_ascii_auto_encoding.pyx" auto_string_type = bytearray def check_auto_string_type(): """ >>> check_auto_string_type() """ assert auto_string_type is bytearray Cython-0.23.4/tests/run/builtinslice.pyx0000644000175600017570000000161412606202452021404 0ustar jenkinsjenkins00000000000000cimport cython def unbound_method_lookup(): """ >>> unbound_method_lookup() """ ignore = slice.indices @cython.test_assert_path_exists('//SingleAssignmentNode//AttributeNode[@is_py_attr = False]') @cython.test_fail_if_path_exists('//SingleAssignmentNode//AttributeNode[@is_py_attr = True]') def typed_slice(): """ >>> typed_slice() (1, 2, 3) """ cdef slice s cdef object z cdef Py_ssize_t a,b,c z = slice s = slice(1, 2, 3) s.indices a = s.start b = s.stop c = s.step return (a,b,c) @cython.test_fail_if_path_exists('//SingleAssignmentNode//AttributeNode[@is_py_attr = False]') def plain_object_slice(): """ >>> plain_object_slice() (1, 2, 3) """ cdef object s cdef object z cdef Py_ssize_t a,b,c s = slice(1, 2, 3) s.indices a = s.start b = s.stop c = s.step return (a,b,c) Cython-0.23.4/tests/run/builtins_truth_test.pyx0000644000175600017570000001061612606202452023036 0ustar jenkinsjenkins00000000000000 def bool_list(list obj): """ >>> bool_list( [] ) False >>> bool_list( [1] ) True >>> bool_list(None) False """ return bool(obj) def if_list(list obj): """ >>> if_list( [] ) False >>> if_list( [1] ) True >>> if_list(None) False """ if obj: return True else: return False def if_list_nogil(list obj): """ >>> if_list_nogil( [] ) False >>> if_list_nogil( [1] ) True >>> if_list_nogil(None) False """ cdef bint result with nogil: if obj: result = True else: result = False return result def if_list_literal(t): """ >>> if_list_literal(True) True >>> if_list_literal(False) False """ if t: if [1,2,3]: return True else: return False else: if []: return True else: return False def bool_tuple(tuple obj): """ >>> bool_tuple( () ) False >>> bool_tuple( (1,) ) True >>> bool_tuple(None) False """ return bool(obj) def if_tuple(tuple obj): """ >>> if_tuple( () ) False >>> if_tuple( (1,) ) True >>> if_tuple(None) False """ if obj: return True else: return False def if_tuple_literal(t): """ >>> if_tuple_literal(True) True >>> if_tuple_literal(False) False """ if t: if (1,2,3): return True else: return False else: if (): return True else: return False def bool_set(set obj): """ >>> bool_set( set() ) False >>> bool_set( set([1]) ) True >>> bool_set(None) False """ return bool(obj) def if_set(set obj): """ >>> if_set( set() ) False >>> if_set( set([1]) ) True >>> if_set(None) False """ if obj: return True else: return False def if_set_nogil(set obj): """ >>> if_set_nogil( set() ) False >>> if_set_nogil( set([1]) ) True >>> if_set_nogil(None) False """ cdef bint result with nogil: if obj: result = True else: result = False return result def if_set_literal(t): """ >>> if_set_literal(True) True >>> if_set_literal(False) False """ if t: if {1,2,3}: return True else: return False else: if set(): return True else: return False def bool_frozenset(frozenset obj): """ >>> bool_frozenset( frozenset() ) False >>> bool_frozenset( frozenset([1]) ) True >>> bool_frozenset(None) False """ return bool(obj) def if_frozenset(frozenset obj): """ >>> if_frozenset( frozenset() ) False >>> if_frozenset( frozenset([1]) ) True >>> if_frozenset(None) False """ if obj: return True else: return False b0 = b'' b1 = b'abc' def bool_bytes(bytes obj): """ >>> bool_bytes(b0) False >>> bool_bytes(b1) True >>> bool_bytes(None) False """ return bool(obj) def if_bytes(bytes obj): """ >>> if_bytes(b0) False >>> if_bytes(b1) True >>> if_bytes(None) False """ if obj: return True else: return False def if_bytes_literal(t): """ >>> if_bytes_literal(True) True >>> if_bytes_literal(False) False """ if t: if b'abc': return True else: return False else: if b'': return True else: return False u0 = u'' u1 = u'abc' def bool_unicode(unicode obj): """ >>> bool_unicode(u0) False >>> bool_unicode(u1) True >>> bool_unicode(None) False """ return bool(obj) def if_unicode(unicode obj): """ >>> if_unicode(u0) False >>> if_unicode(u1) True >>> if_unicode(None) False """ if obj: return True else: return False def if_unicode_literal(t): """ >>> if_unicode_literal(True) True >>> if_unicode_literal(False) False """ if t: if u'abc': return True else: return False else: if u'': return True else: return False Cython-0.23.4/tests/run/builtinnames.pyx0000644000175600017570000000265112606202452021412 0ustar jenkinsjenkins00000000000000cimport cython def test_file_py(file): assert isinstance(file, (str, unicode)), \ u"not a string, found '%s' instead" % file.__class__.__name__ return file cdef test_file_c(file): assert isinstance(file, (str, unicode)), \ u"not a string, found '%s' instead" % file.__class__.__name__ return u'file' + file def range(arg): return u'range' + arg def len(arg): return u'len' + arg cdef type(arg): return u'type' + arg @cython.test_fail_if_path_exists( '//PyMethodCallNode/NameNode[@name="type" and @entry.is_cfunction=False]', '//SimpleCallNode/NameNode[@name="type" and @entry.is_cfunction=False]', '//SimpleCallNode/NameNode[@name="len" and @entry.is_cfunction=True]', ) @cython.test_assert_path_exists( '//SimpleCallNode/NameNode[@name="type"]', '//SimpleCallNode/NameNode[@name="type" and @entry.is_cfunction=True]', '//PyMethodCallNode/NameNode[@name="len"]', ) def test_c(arg): """ >>> test_c('abc') fileabc lenabc typeabc >>> print(test_file_py('abc')) abc >>> print(range('abc')) rangeabc >>> print(len('abc')) lenabc """ print test_file_c(arg) print len(arg) print type(arg) def test_for_in_range(arg): """ >>> print(str(test_for_in_range('abc')).replace("u'", "'")) ['r', 'a', 'n', 'g', 'e', 'a', 'b', 'c'] """ l = [] for c in range(arg): l.append(c) return l Cython-0.23.4/tests/run/builtincomplex.pyx0000644000175600017570000000236412606202452021757 0ustar jenkinsjenkins00000000000000 from cpython.complex cimport complex def complex_attributes(): """ >>> complex_attributes() (1.0, 2.0) """ cdef complex c = 1+2j return (c.real, c.imag) def complex_attributes_assign(): """ >>> complex_attributes_assign() (10.0, 20.0) """ cdef complex c = 1+2j c.cval.real, c.cval.imag = 10, 20 return (c.real, c.imag) def complex_cstruct_assign(): """ >>> complex_cstruct_assign() (10.0, 20.0) """ cdef complex c = 1+2j cval = &c.cval cval.real, cval.imag = 10, 20 return (c.real, c.imag) def complex_coercion(): """ >>> complex_coercion() (1.0, 2.0, 1.0, 2.0) """ cdef complex py_c = 1+2j cdef double complex c_c = py_c cdef object py = c_c return (c_c.real, c_c.imag, py.real, py.imag) def complex_arg(complex c): """ >>> complex_arg(1+2j) (1.0, 2.0) """ return (c.real, c.imag) def complex_conjugate_nonsimple_float(): """ >>> complex_conjugate_nonsimple_float() 1.0 """ x = float(1.0).conjugate() return x cdef double float_result(): return 1.0 def complex_conjugate_nonsimple(): """ >>> complex_conjugate_nonsimple() 1.0 """ x = float_result().conjugate() return x Cython-0.23.4/tests/run/builtin_types_none_T166.pyx0000644000175600017570000000055512606202452023352 0ustar jenkinsjenkins00000000000000# ticket: 166 __doc__ = u""" >>> l = None >>> l.append(2) Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'append' """ def append_to_none(): """ >>> append_to_none() Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'append' """ cdef list l = None l.append(2) Cython-0.23.4/tests/run/builtin_type_inheritance_T608.pyx0000644000175600017570000000410312606202452024513 0ustar jenkinsjenkins00000000000000# ticket: 608 cdef class MyInt(int): """ >>> MyInt(2) == 2 True >>> MyInt(2).attr is None True """ 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): """ >>> MyFloat(1.0)== 1.0 True >>> MyFloat(1.0).attr is None True """ cdef readonly object attr ustring = u'abc' cdef class MyUnicode(unicode): """ >>> MyUnicode(ustring) == ustring True >>> MyUnicode(ustring + ustring) == ustring False >>> MyUnicode(ustring).attr is None True """ cdef readonly object attr cdef class MyList(list): """ >>> MyList([1,2,3]) == [1,2,3] True >>> MyList([1,2,3]).attr is None True """ 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): """ >>> MyDict({1:2, 3:4}) == {1:2, 3:4} True >>> MyDict({1:2, 3:4}).attr is None True """ cdef readonly object attr Cython-0.23.4/tests/run/builtin_type.pyx0000644000175600017570000000243212606202452021424 0ustar jenkinsjenkins00000000000000cimport cython @cython.test_assert_path_exists( '//PythonCapiCallNode/PythonCapiFunctionNode[@cname="Py_TYPE"]') def get_type_of(a): """ >>> get_type_of(object()) is object True """ return type(a) @cython.test_assert_path_exists( '//PythonCapiCallNode/PythonCapiFunctionNode[@cname="Py_TYPE"]') def get_type_through_local(a): """ >>> get_type_of(object()) is object True """ t = type(a) return t @cython.test_assert_path_exists( '//PythonCapiCallNode/PythonCapiFunctionNode[@cname="Py_TYPE"]') @cython.test_fail_if_path_exists( '//PythonCapiCallNode/PythonCapiFunctionNode[@cname="__Pyx_Type"]', '//NameNode[@name="type"]') def test_type(a, t): """ >>> test_type(object(), object) True """ return type(a) and type(a) is t and type(a) == t @cython.test_assert_path_exists('//NameNode[@name="type"]') def type_type(): """ >>> type_type()(object()) is object True """ return type cpdef type pass_type(type x): """ >>> pass_type(int) == int True >>> class MyType(object): pass >>> pass_type(MyType) == MyType True >>> pass_type(object()) Traceback (most recent call last): TypeError: Argument 'x' has incorrect type (expected type, got object) """ return x Cython-0.23.4/tests/run/builtin_subtype_methods_cy3.pyx0000644000175600017570000000214112606202452024434 0ustar jenkinsjenkins00000000000000# cython: language_level=3 # mode: run # ticket: 653 class DictPySubtype(dict): def keys(self): """ >>> d = DictPySubtype(one=42, two=17, three=0) >>> for v in sorted(d.keys()): ... print(v) three two """ for key in dict.keys(self): if key != 'one': yield key def values(self): """ >>> d = DictPySubtype(one=42, two=17, three=0) >>> for v in sorted(d.values()): ... print(v) 17 42 """ for value in dict.values(self): if value: yield value def items(self): """ >>> d = DictPySubtype(one=42, two=17, three=0) >>> for v in sorted(d.items()): ... print(v) one two """ for key, value in dict.items(self): if value: yield key class ListPySubtype(list): """ >>> lst = ListPySubtype([1,2,3]) >>> lst.append(4) >>> lst [1, 2, 3, 5] """ def append(self, value): list.append(self, value+1) Cython-0.23.4/tests/run/builtin_subtype_methods_T653.pyx0000644000175600017570000001030612606202452024401 0ustar jenkinsjenkins00000000000000#cython: language_level=2 # mode: run # ticket: 653 cimport cython cdef class MyList(list): def test_append(self, x): """ >>> l = MyList() >>> type(l) is MyList True >>> list(l) [] >>> l.test_append(5) >>> list(l) [5] """ self.append(x) cdef class MyDict(dict): @cython.test_assert_path_exists("//ComprehensionNode//AttributeNode", "//ComprehensionNode//AttributeNode[@attribute='items']") @cython.test_fail_if_path_exists("//ComprehensionNode//CMethodSelfCloneNode") def test_items(self): """ >>> MyDict(a=1, b=2).test_items() [('a', 1), ('b', 2)] """ l = [ (key, value) for key, value in self.items() ] l.sort() return l def test_values(self): """ >>> MyDict(a=1, b=2).test_values() [1, 2] """ l = [ v for v in self.values() ] l.sort() return l @cython.final cdef class MyDictFinal(dict): @cython.test_assert_path_exists("//ComprehensionNode//CMethodSelfCloneNode") def test_items(self): """ >>> MyDictFinal(a=1, b=2).test_items() [('a', 1), ('b', 2)] """ l = [ (key, value) for key, value in self.items() ] l.sort() return l def test_values(self): """ >>> MyDictFinal(a=1, b=2).test_values() [1, 2] """ l = [ v for v in self.values() ] l.sort() return l cdef class MyDict2(MyDict): @cython.test_assert_path_exists("//ComprehensionNode//AttributeNode", "//ComprehensionNode//AttributeNode[@attribute='items']") @cython.test_fail_if_path_exists("//ComprehensionNode//CMethodSelfCloneNode") def test_items(self): """ >>> MyDict2(a=1, b=2).test_items() [('a', 1), ('b', 2)] """ l = [ (key, value) for key, value in self.items() ] l.sort() return l def test_values(self): """ >>> MyDict2(a=1, b=2).test_values() [1, 2] """ l = [ v for v in self.values() ] l.sort() return l @cython.final cdef class MyDict2Final(MyDict): @cython.test_assert_path_exists("//ComprehensionNode//CMethodSelfCloneNode") def test_items(self): """ >>> MyDict2Final(a=1, b=2).test_items() [('a', 1), ('b', 2)] """ l = [ (key, value) for key, value in self.items() ] l.sort() return l def test_values(self): """ >>> MyDict2Final(a=1, b=2).test_values() [1, 2] """ l = [ v for v in self.values() ] l.sort() return l @cython.final cdef class MyDictOverride(dict): def items(self): return [(1,2), (3,4)] @cython.test_assert_path_exists("//ComprehensionNode//AttributeNode", "//ComprehensionNode//AttributeNode[@attribute='items']") @cython.test_fail_if_path_exists("//ComprehensionNode//CMethodSelfCloneNode") def test_items(self): """ >>> MyDictOverride(a=1, b=2).test_items() [(1, 2), (3, 4)] """ l = [ (key, value) for key, value in self.items() ] l.sort() return l def test_values(self): """ >>> MyDictOverride(a=1, b=2).test_values() [1, 2] """ l = [ v for v in self.values() ] l.sort() return l @cython.final cdef class MyDictOverride2(MyDict): def items(self): return [(1,2), (3,4)] @cython.test_assert_path_exists("//ComprehensionNode//AttributeNode", "//ComprehensionNode//AttributeNode[@attribute='items']") @cython.test_fail_if_path_exists("//ComprehensionNode//CMethodSelfCloneNode") def test_items(self): """ >>> MyDictOverride2(a=1, b=2).test_items() [(1, 2), (3, 4)] """ l = [ (key, value) for key, value in self.items() ] l.sort() return l def test_values(self): """ >>> MyDictOverride2(a=1, b=2).test_values() [1, 2] """ l = [ v for v in self.values() ] l.sort() return l Cython-0.23.4/tests/run/builtin_sorted.pyx0000644000175600017570000000311112606202452021736 0ustar jenkinsjenkins00000000000000cimport cython def generator(): yield 2 yield 1 yield 3 def returns_set(): return {"foo", "bar", "baz"} def returns_tuple(): return (1, 2, 3, 0) @cython.test_fail_if_path_exists("//SimpleCallNode") def sorted_arg(x): """ >>> a = [3, 2, 1] >>> sorted_arg(a) [1, 2, 3] >>> a [3, 2, 1] >>> sorted(generator()) [1, 2, 3] >>> sorted(returns_set()) ['bar', 'baz', 'foo'] >>> sorted(returns_tuple()) [0, 1, 2, 3] >>> sorted(object()) Traceback (most recent call last): TypeError: 'object' object is not iterable """ return sorted(x) @cython.test_fail_if_path_exists("//YieldExprNode", "//NoneCheckNode") @cython.test_assert_path_exists("//InlinedGeneratorExpressionNode") def sorted_genexp(): """ >>> sorted_genexp() [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] """ return sorted(i*i for i in range(10,0,-1)) @cython.test_fail_if_path_exists("//SimpleCallNode//SimpleCallNode") @cython.test_assert_path_exists("//SimpleCallNode/NameNode[@name = 'range']") def sorted_list_of_range(): """ >>> sorted_list_of_range() [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] """ return sorted(list(range(10,0,-1))) @cython.test_fail_if_path_exists("//SimpleCallNode") def sorted_list_literal(): """ >>> sorted_list_literal() [1, 1, 2, 2, 3, 3] """ return sorted([3, 1, 2] * 2) @cython.test_fail_if_path_exists("//SimpleCallNode") def sorted_tuple_literal(): """ >>> sorted_tuple_literal() [1, 1, 2, 2, 3, 3] """ return sorted((1, 3, 2) * 2) Cython-0.23.4/tests/run/builtin_slice.pyx0000644000175600017570000000251212606202452021541 0ustar jenkinsjenkins00000000000000# mode: run def slice1(stop): """ >>> list(range(8)) [0, 1, 2, 3, 4, 5, 6, 7] >>> list(range(10))[slice1(8)] [0, 1, 2, 3, 4, 5, 6, 7] >>> slice1(1) slice(None, 1, None) >>> slice1(10) slice(None, 10, None) >>> slice1(None) slice(None, None, None) >>> slice1(1) == slice(1) True >>> slice1(None) == slice(None) True """ return slice(stop) def slice1_const(): """ >>> slice1_const() == slice(12) True """ return slice(12) def slice2(start, stop): """ >>> list(range(2, 8)) [2, 3, 4, 5, 6, 7] >>> list(range(10))[slice2(2, 8)] [2, 3, 4, 5, 6, 7] >>> slice2(1, 10) slice(1, 10, None) >>> slice2(None, 10) slice(None, 10, None) >>> slice2(4, None) slice(4, None, None) """ return slice(start, stop) def slice2_const(): """ >>> slice2_const() == slice(None, 12) True """ return slice(None, 12) def slice3(start, stop, step): """ >>> list(range(2, 8, 3)) [2, 5] >>> list(range(10))[slice3(2, 8, 3)] [2, 5] >>> slice3(2, None, 3) slice(2, None, 3) >>> slice3(None, 3, 2) slice(None, 3, 2) """ return slice(start, stop, step) def slice3_const(): """ >>> slice3_const() == slice(12, None, 34) True """ return slice(12, None, 34) Cython-0.23.4/tests/run/builtin_py3.pyx0000644000175600017570000000133112606202452021153 0ustar jenkinsjenkins00000000000000# tag: py3 __doc__ = u""" >>> test_xrange() 0 1 2 >>> test_range() 0 1 2 >>> test_long() == 12 True >>> test_int() == 12 True """ # the builtins 'xrange' and 'long' are not available in Py3, but they # can safely be replaced by 'range' and 'int' on that platform import sys IS_PY3 = sys.version_info[0] >= 3 def test_xrange(): r = xrange(3) assert type(r) is xrange for i in r: print i def test_range(): r = range(3) assert (type(r) is range) if IS_PY3 else (type(r) is list) for i in r: print i def test_long(): long_val = long(12) assert type(long_val) is long return long_val def test_int(): int_val = int(12) assert type(int_val) is int return int_val Cython-0.23.4/tests/run/builtin_pow.pyx0000644000175600017570000000075512606202452021256 0ustar jenkinsjenkins00000000000000 def pow3(a,b,c): """ >>> pow3(2,3,5) 3 >>> pow3(3,3,5) 2 """ return pow(a,b,c) def pow3_const(): """ >>> pow3_const() 3 """ return pow(2,3,5) def pow2(a,b): """ >>> pow2(2,3) 8 >>> pow2(3,3) 27 """ return pow(a,b) def pow2_const(): """ >>> pow2_const() 8 """ return pow(2,3) def pow_args(*args): """ >>> pow_args(2,3) 8 >>> pow_args(2,3,5) 3 """ return pow(*args) Cython-0.23.4/tests/run/builtin_ord.pyx0000644000175600017570000000351512606202452021232 0ustar jenkinsjenkins00000000000000 cimport cython import sys uspace = u' ' ustring_with_a = u'abcdefg' ustring_without_a = u'bcdefg' @cython.test_assert_path_exists( # ord() should receive and return a C value '//ReturnStatNode//CoerceToPyTypeNode//SimpleCallNode') @cython.test_fail_if_path_exists( '//ReturnStatNode//SimpleCallNode//CoerceToPyTypeNode') def ord_Py_UNICODE(unicode s): """ >>> ord_Py_UNICODE(uspace) 32 """ cdef Py_UNICODE u u = s[0] return ord(u) @cython.test_assert_path_exists('//TupleNode//IntNode') @cython.test_fail_if_path_exists('//SimpleCallNode') def ord_const(): """ >>> ord(b' ') 32 >>> ord(' ') 32 >>> ord_const() (32, 32, 32, 255, 255, 4660, 0) """ return ord(u' '), ord(b' '), ord(' '), ord('\xff'), ord(b'\xff'), ord(u'\u1234'), ord('\0') @cython.test_assert_path_exists('//PrimaryCmpNode//IntNode') #@cython.test_fail_if_path_exists('//SimpleCallNode') def unicode_for_loop_ord(unicode s): """ >>> unicode_for_loop_ord(ustring_with_a) True >>> unicode_for_loop_ord(ustring_without_a) False """ for c in s: if ord(c) == ord(u'a'): return True return False def compare_to_char(s): """ >>> compare_to_char(uspace) False >>> compare_to_char(b'a') False >>> compare_to_char(b'x') True >>> compare_to_char('x') True """ cdef char c = b'x' return ord(s) == c def ord_object(s): """ >>> try: ord_object('abc') ... except ValueError: assert sys.version_info[0] >= 3 ... except TypeError: assert sys.version_info[0] < 3 >>> ord_object('a') 97 >>> ord_object(b'a') 97 """ return ord(s) def non_builtin_ord(s): """ >>> non_builtin_ord('x') (123, 123) """ def _ord(s): return 123 ord = _ord return ord(s), _ord(s) Cython-0.23.4/tests/run/builtin_next.pyx0000644000175600017570000000317512606202452021426 0ustar jenkinsjenkins00000000000000 import sys IS_PY3 = sys.version_info[0] >= 3 __doc__ = """ >>> it = iter([1,2,3]) >>> if not IS_PY3: ... next = type(it).next >>> next(it) 1 >>> next(it) 2 >>> next(it) 3 >>> next(it) Traceback (most recent call last): StopIteration >>> next(it) Traceback (most recent call last): StopIteration >>> if IS_PY3: next(it, 123) ... else: print(123) 123 """ if IS_PY3: __doc__ += """ >>> next(123) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...int... object is not an iterator """ def test_next_not_iterable(it): """ >>> test_next_not_iterable(123) Traceback (most recent call last): TypeError: int object is not an iterator """ return next(it) def test_single_next(it): """ >>> it = iter([1,2,3]) >>> test_single_next(it) 1 >>> test_single_next(it) 2 >>> test_single_next(it) 3 >>> test_single_next(it) Traceback (most recent call last): StopIteration >>> test_single_next(it) Traceback (most recent call last): StopIteration """ return next(it) def test_default_next(it, default): """ >>> it = iter([1,2,3]) >>> test_default_next(it, 99) 1 >>> test_default_next(it, 99) 2 >>> test_default_next(it, 99) 3 >>> test_default_next(it, 99) 99 >>> test_default_next(it, 99) 99 """ return next(it, default) def test_next_override(it): """ >>> it = iter([1,2,3]) >>> test_next_override(it) 1 >>> test_next_override(it) 1 >>> test_next_override(it) 1 >>> test_next_override(it) 1 """ def next(it): return 1 return next(it) Cython-0.23.4/tests/run/builtin_min_max.pyx0000644000175600017570000000461412606202452022077 0ustar jenkinsjenkins00000000000000 cimport cython # min() @cython.test_assert_path_exists("//CondExprNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def min3(a,b,c): """ >>> min3(1,2,3) 1 >>> min3(2,3,1) 1 >>> min3(2,1,3) 1 >>> min3(3,1,2) 1 >>> min3(3,2,1) 1 """ return min(a,b,c) @cython.test_assert_path_exists("//CondExprNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def min3_list(a,b,c): """ >>> min3_list(1,2,3) 1 >>> min3_list(2,3,1) 1 >>> min3_list(2,1,3) 1 >>> min3_list(3,1,2) 1 >>> min3_list(3,2,1) 1 """ return min([a,b,c]) @cython.test_assert_path_exists("//CondExprNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def min3_tuple(a,b,c): """ >>> min3_tuple(1,2,3) 1 >>> min3_tuple(2,3,1) 1 >>> min3_tuple(2,1,3) 1 >>> min3_tuple(3,1,2) 1 >>> min3_tuple(3,2,1) 1 """ return min((a,b,c)) @cython.test_assert_path_exists("//CondExprNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def min3_typed(int a, int b, int c): """ >>> min3_typed(1,2,3) 1 >>> min3_typed(2,3,1) 1 >>> min3_typed(2,1,3) 1 >>> min3_typed(3,1,2) 1 >>> min3_typed(3,2,1) 1 """ return min(a,b,c) @cython.test_assert_path_exists("//CondExprNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def literal_min3(): """ >>> literal_min3() (1, 1, 1, 1, 1) """ return min(1,2,3), min(2,1,3), min(2,3,1), min(3,1,2), min(3,2,1) # max() @cython.test_assert_path_exists("//CondExprNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def max3(a,b,c): """ >>> max3(1,2,3) 3 >>> max3(2,3,1) 3 >>> max3(2,1,3) 3 >>> max3(3,1,2) 3 >>> max3(3,2,1) 3 """ return max(a,b,c) @cython.test_assert_path_exists("//CondExprNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def max3_typed(int a, int b, int c): """ >>> max3_typed(1,2,3) 3 >>> max3_typed(2,3,1) 3 >>> max3_typed(2,1,3) 3 >>> max3_typed(3,1,2) 3 >>> max3_typed(3,2,1) 3 """ return max(a,b,c) @cython.test_assert_path_exists("//CondExprNode") @cython.test_fail_if_path_exists("//SimpleCallNode") def literal_max3(): """ >>> literal_max3() (3, 3, 3, 3, 3) """ return max(1,2,3), max(2,1,3), max(2,3,1), max(3,1,2), max(3,2,1) Cython-0.23.4/tests/run/builtin_methods_return_values.pyx0000644000175600017570000000342712606202452025071 0ustar jenkinsjenkins00000000000000# mode: run # tag: list, set, builtins # ticket: 688 _set = set class TestObj(object): pass def _setattr(obj): """ >>> t = TestObj() >>> _setattr(t) is None True >>> t.test is None True """ setattr(obj, 'test', None) return setattr(obj, 'test', None) def _delattr(obj): """ >>> t = TestObj() >>> t.test1 = t.test2 = True >>> _delattr(t) is None True >>> hasattr(t, 'test1') False >>> hasattr(t, 'test2') False """ delattr(obj, 'test1') return delattr(obj, 'test2') def list_sort(list l): """ >>> list_sort([1,2,3]) is None True """ l.sort() return l.sort() def list_reverse(list l): """ >>> list_reverse([1,2,3]) is None True """ l.reverse() return l.reverse() def list_insert(list l): """ >>> list_insert([1,2,3]) is None True """ l.insert(1, 2) return l.insert(1, 2) def list_append(list l): """ >>> list_append([1,2,3]) is None True """ l.append(1) return l.append(2) def set_clear(set s): """ >>> set_clear(_set([1,2,3])) is None True >>> set_clear(None) Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'clear' """ s.clear() return s.clear() def set_discard(set s): """ >>> set_discard(_set([1,2,3])) is None True """ s.discard(1) return s.discard(2) def set_add(set s): """ >>> set_add(_set([1,2,3])) is None True """ s.add(1) return s.add(2) def dict_clear(dict d): """ >>> dict_clear({1:2,3:4}) is None True >>> dict_clear(None) Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'clear' """ d.clear() return d.clear() Cython-0.23.4/tests/run/builtin_len.pyx0000644000175600017570000000547412606202452021232 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- cimport cython unicode_str = u'ab jd üöä ôñ ÄÖ' bytes_str = b'ab jd sdflk as sa sadas asdas fsdf ' _frozenset = frozenset _set = set @cython.test_assert_path_exists( "//CoerceToPyTypeNode", "//PythonCapiCallNode") def len_unicode(unicode s): """ >>> len(unicode_str) 16 >>> len_unicode(unicode_str) 16 >>> len_unicode(None) Traceback (most recent call last): TypeError: object of type 'NoneType' has no len() """ return len(s) @cython.test_assert_path_exists( "//CoerceToPyTypeNode", "//PythonCapiCallNode") def len_bytes(bytes s): """ >>> len(bytes_str) 37 >>> len_bytes(bytes_str) 37 >>> len_bytes(None) Traceback (most recent call last): TypeError: object of type 'NoneType' has no len() """ return len(s) #@cython.test_assert_path_exists( # "//CoerceToPyTypeNode", # "//PythonCapiCallNode") def len_str(str s): """ >>> len('abcdefg') 7 >>> len_str('abcdefg') 7 >>> len_unicode(None) Traceback (most recent call last): TypeError: object of type 'NoneType' has no len() """ return len(s) @cython.test_assert_path_exists( "//CoerceToPyTypeNode", "//PythonCapiCallNode") def len_list(list s): """ >>> l = [1,2,3,4] >>> len(l) 4 >>> len_list(l) 4 >>> len_list(None) Traceback (most recent call last): TypeError: object of type 'NoneType' has no len() """ return len(s) @cython.test_assert_path_exists( "//CoerceToPyTypeNode", "//PythonCapiCallNode") def len_tuple(tuple s): """ >>> t = (1,2,3,4) >>> len(t) 4 >>> len_tuple(t) 4 >>> len_tuple(None) Traceback (most recent call last): TypeError: object of type 'NoneType' has no len() """ return len(s) @cython.test_assert_path_exists( "//CoerceToPyTypeNode", "//PythonCapiCallNode") def len_dict(dict s): """ >>> d = dict(a=1, b=2, c=3, d=4) >>> len(d) 4 >>> len_dict(d) 4 >>> len_dict(None) Traceback (most recent call last): TypeError: object of type 'NoneType' has no len() """ return len(s) @cython.test_assert_path_exists( "//CoerceToPyTypeNode", "//PythonCapiCallNode") def len_set(set s): """ >>> s = _set((1,2,3,4)) >>> len(s) 4 >>> len_set(s) 4 >>> len_set(None) Traceback (most recent call last): TypeError: object of type 'NoneType' has no len() """ return len(s) @cython.test_assert_path_exists( "//CoerceToPyTypeNode", "//PythonCapiCallNode") def len_frozenset(frozenset s): """ >>> s = _frozenset((1,2,3,4)) >>> len(s) 4 >>> len_frozenset(s) 4 >>> len_set(None) Traceback (most recent call last): TypeError: object of type 'NoneType' has no len() """ return len(s) Cython-0.23.4/tests/run/builtin_globals.py0000644000175600017570000000033512606202452021676 0ustar jenkinsjenkins00000000000000# mode: run # tag: allow_unknown_names assert "NEW" not in globals() globals().update(NEW=True) assert "NEW" in globals() def default_args(value=NEW): """ >>> default_args() True """ return value Cython-0.23.4/tests/run/builtin_float.py0000644000175600017570000000077012606202452021363 0ustar jenkinsjenkins00000000000000 import sys def empty_float(): """ >>> float() 0.0 >>> empty_float() 0.0 """ x = float() return x def float_conjugate(): """ >>> float_call_conjugate() 1.5 """ if sys.version_info >= (2,6): x = 1.5 .conjugate() else: x = 1.5 return x def float_call_conjugate(): """ >>> float_call_conjugate() 1.5 """ if sys.version_info >= (2,6): x = float(1.5).conjugate() else: x = 1.5 return x Cython-0.23.4/tests/run/builtin_callable.pyx0000644000175600017570000000071212606202452022201 0ustar jenkinsjenkins00000000000000# mode: run # tag: builtin, callable cimport cython @cython.test_assert_path_exists("//SimpleCallNode[@type.is_pyobject = False]") def test_callable(x): """ >>> test_callable(None) False >>> test_callable('ABC') False >>> class C: pass >>> test_callable(C) True >>> test_callable(C()) False >>> test_callable(int) True >>> test_callable(test_callable) True """ b = callable(x) return b Cython-0.23.4/tests/run/builtin_basestring.pyx0000644000175600017570000000521612606202452022607 0ustar jenkinsjenkins00000000000000 cimport cython import sys IS_PY3 = sys.version_info[0] >= 3 ustring = u'abcdef' sstring = 'abcdef' bstring = b'abcdef' def isinstance_basestring(obj): """ >>> isinstance_basestring(ustring) True >>> isinstance_basestring(sstring) True >>> if IS_PY3: print(not isinstance_basestring(bstring)) ... else: print(isinstance_basestring(bstring)) True """ return isinstance(obj, basestring) def basestring_is_unicode_in_py3(): """ >>> basestring_is_unicode_in_py3() True """ if IS_PY3: return basestring is unicode else: return basestring is not unicode def unicode_subtypes_basestring(): """ >>> unicode_subtypes_basestring() True """ return issubclass(unicode, basestring) def basestring_typed_variable(obj): """ >>> basestring_typed_variable(None) is None True >>> basestring_typed_variable(ustring) is ustring True >>> basestring_typed_variable(sstring) is sstring True >>> if IS_PY3: print(True) ... else: print(basestring_typed_variable(bstring) is bstring) True >>> class S(str): pass >>> basestring_typed_variable(S()) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...got S... """ cdef basestring s s = u'abc' assert s s = 'abc' assert s # make sure coercion also works in conditional expressions s = u'abc' if obj else 'abc' assert s s = obj return s def basestring_typed_argument(basestring obj): """ >>> basestring_typed_argument(None) is None True >>> basestring_typed_argument(ustring) is ustring True >>> basestring_typed_argument(sstring) is sstring True >>> if IS_PY3: print(True) ... else: print(basestring_typed_argument(bstring) is bstring) True >>> class S(str): pass >>> basestring_typed_argument(S()) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ...got S... """ return obj @cython.test_assert_path_exists( "//SimpleCallNode", "//SimpleCallNode//NoneCheckNode", "//SimpleCallNode//AttributeNode[@is_py_attr = false]") def basestring_join(basestring s, *values): """ >>> print(basestring_join(ustring, 'a', 'b', 'c')) aabcdefbabcdefc >>> print(basestring_join(sstring, 'a', 'b', 'c')) aabcdefbabcdefc >>> if IS_PY3: print('abcdefabcdefabcdef') ... else: print(basestring_join(bstring, bstring, bstring).decode('utf8')) abcdefabcdefabcdef >>> basestring_join(None, 'a', 'b', 'c') Traceback (most recent call last): AttributeError: 'NoneType' object has no attribute 'join' """ return s.join(values) Cython-0.23.4/tests/run/builtin_abs.pyx0000644000175600017570000000711712606202452021215 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 698 cdef extern from *: int INT_MAX long LONG_MAX max_int = INT_MAX max_long = LONG_MAX max_long_long = 2 ** (sizeof(long long) * 8 - 1) - 1 cimport cython def abs_as_name(): """ >>> _abs = abs_as_name() >>> _abs(-5) 5 """ x = abs return x def py_abs(a): """ >>> py_abs(-5) 5 >>> py_abs(-5.5) 5.5 """ return abs(a) @cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']", "//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_int']") def int_abs(int a): """ >>> int_abs(-5) == 5 True >>> int_abs(-5.1) == 5 True >>> int_abs(-max_int-1) > 0 True >>> int_abs(-max_int-1) == abs(-max_int-1) or (max_int, int_abs(-max_int-1), abs(-max_int-1)) True >>> int_abs(max_int) == abs(max_int) or (max_int, int_abs(max_int), abs(max_int)) True """ return abs(a) @cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']") @cython.test_fail_if_path_exists("//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_int']", "//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_long']") def uint_abs(unsigned int a): """ >>> uint_abs(max_int) == abs(max_int) or (max_int, uint_abs(max_int), abs(max_int)) True """ return abs(a) @cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']", "//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_long']") def long_abs(long a): """ >>> long_abs(-5) == 5 True >>> long_abs(-5.1) == 5 True >>> long_abs(-max_long-1) > 0 True >>> long_abs(-max_long-1) == abs(-max_long-1) or (max_long, long_abs(-max_long-1), abs(-max_long-1)) True >>> long_abs(max_long) == abs(max_long) or (max_long, long_abs(max_long), abs(max_long)) True """ return abs(a) @cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']") @cython.test_fail_if_path_exists("//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_int']", "//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_long']") def ulong_abs(unsigned long a): """ >>> ulong_abs(max_long) == abs(max_long) or (max_int, ulong_abs(max_long), abs(max_long)) True """ return abs(a) @cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']", "//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_longlong']") def long_long_abs(long long a): """ >>> long_long_abs(-(2**33)) == 2**33 True >>> long_long_abs(-max_long_long-1) > 0 True >>> long_long_abs(-max_long_long-1) == abs(-max_long_long-1) or (max_long_long, long_long_abs(-max_long_long-1), abs(-max_long_long-1)) True >>> long_long_abs(max_long_long) == abs(max_long_long) or (max_long_long, long_long_abs(max_long_long), abs(max_long_long)) True """ return abs(a) @cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']", "//ReturnStatNode//NameNode[@entry.cname = 'fabs']") def double_abs(double a): """ >>> double_abs(-5) 5.0 >>> double_abs(-5.5) 5.5 """ return abs(a) @cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']", "//ReturnStatNode//NameNode[@entry.cname = 'fabsf']") def float_abs(float a): """ >>> float_abs(-5) 5.0 >>> float_abs(-5.5) 5.5 """ return abs(a) Cython-0.23.4/tests/run/broken_exception.pyx0000644000175600017570000000065212606202452022255 0ustar jenkinsjenkins00000000000000 import sys def exception_creates_invalid_instance(): """ >>> print( exception_creates_invalid_instance() ) OK """ class MyException(Exception): def __new__(cls, *args): return object() if sys.version_info[0] >= 3: expected_error = TypeError else: expected_error = MyException try: raise MyException except expected_error: return "OK" Cython-0.23.4/tests/run/bound_builtin_methods_T589.pyx0000644000175600017570000000370012606202452024025 0ustar jenkinsjenkins00000000000000# ticket: 589 cimport cython _set = set # CPython may not define it (in Py2.3), but Cython does :) def test_set_clear_bound(): """ >>> type(test_set_clear_bound()) is _set True >>> list(test_set_clear_bound()) [] """ cdef set s1 = set([1]) clear = s1.clear clear() return s1 text = u'ab jd sdflk as sa sadas asdas fsdf ' pipe_sep = u'|' @cython.test_assert_path_exists( "//PythonCapiCallNode", ) def test_unicode_join_bound(unicode sep, l): """ >>> l = text.split() >>> len(l) 8 >>> print( pipe_sep.join(l) ) ab|jd|sdflk|as|sa|sadas|asdas|fsdf >>> print( test_unicode_join_bound(pipe_sep, l) ) ab|jd|sdflk|as|sa|sadas|asdas|fsdf """ join = sep.join return join(l) def test_unicode_join_bound_no_assignment(unicode sep): """ >>> test_unicode_join_bound_no_assignment(text) """ sep.join def test_dict_items_bound_no_assignment(dict d): """ >>> test_dict_items_bound_no_assignment({1:2}) """ d.items def list_pop(list l): """ >>> list_pop([1,2,3]) (2, [1, 3]) """ pop = l.pop r = pop(1) return r, l def list_pop_literal(): """ >>> list_pop_literal() (2, [1, 3]) """ l = [1,2,3] pop = l.pop r = pop(1) return r, l def list_pop_reassign(): """ >>> list_pop_reassign() 2 """ l = [1,2,3] pop = l.pop l = None r = pop(1) return r def list_insert(list l): """ >>> list_insert([1,2,3]) (None, [1, 4, 2, 3]) """ insert = l.insert r = insert(1, 4) return r, l def list_insert_literal(): """ >>> list_insert_literal() (None, [1, 4, 2, 3]) """ l = [1,2,3] insert = l.insert r = insert(1, 4) return r, l def list_insert_reassign(): """ >>> list_insert_reassign() (None, [1, 4, 2, 3]) """ l = [1,2,3] insert = l.insert m, l = l, None r = insert(1, 4) return r, m Cython-0.23.4/tests/run/boolop_py.py0000644000175600017570000000177112606202452020534 0ustar jenkinsjenkins00000000000000 def non_simple_values(obj1, obj2, obj3, obj4): """ >>> non_simple_values(1, 2, 3, 4) (7, 3, 7, 3, 7, 7, 5, 5) >>> non_simple_values(0, 0, 3, 4) (0, 7, 4, 4, 4, 4, 4, 4) >>> non_simple_values(0, 0, 1, -1) (0, 0, -1, 0, -1, -1, 0, 0) >>> non_simple_values(1, -1, 1, -1) (0, 0, 0, 0, 0, 0, 0, 0) >>> non_simple_values(1, 2, 1, -1) (0, 3, 0, 3, 0, 0, 1, 1) >>> non_simple_values(2, 1, 1, -1) (0, 3, 1, 3, 0, 0, 1, 1) """ and1 = obj1 + obj2 and obj3 + obj4 or1 = obj1 + obj2 or obj3 + obj4 and_or = obj1 + obj2 and obj3 + obj4 or obj1 + obj4 or_and = obj1 + obj2 or obj3 + obj4 and obj1 + obj4 and_or_and = obj1 + obj2 and obj3 + obj4 or obj1 + obj4 and obj2 + obj4 and1_or_and = (and1 or (obj1 + obj4 and obj2 + obj4)) or_and_or = (obj1 + obj2 or obj3 + obj4) and (obj1 + obj4 or obj2 + obj4) or1_and_or = (or1 and (obj1 + obj4 or obj2 + obj4)) return (and1, or1, and_or, or_and, and_or_and, and1_or_and, or_and_or, or1_and_or) Cython-0.23.4/tests/run/boolop.pyx0000644000175600017570000000314712606202452020213 0ustar jenkinsjenkins00000000000000 def simple_values(obj1, obj2, obj3, obj4): """ >>> simple_values(True, False, 23, 'test') (0.0, 1.0, False, False) """ cdef int bool1, bool2 cdef float bool3, bool4 cdef char *ptr1, *ptr2, *ptr0 cdef float f bool1 = 1 bool2 = 0 ptr1 = ptr2 = NULL f = 0.0 bool3 = bool1 and bool2 bool3 = bool1 or bool2 bool3 = obj1 and obj2 ptr0 = ptr1 and ptr2 bool3 = bool1 and f bool4 = bool1 and bool2 and bool3 bool4 = bool1 or bool2 and bool3 obj4 = obj1 and obj2 and obj3 obj5 = (obj1 + obj2 + obj3) and obj4 return bool3, bool4, obj4, obj5 def non_simple_values(obj1, obj2, obj3, obj4): """ >>> non_simple_values(1, 2, 3, 4) (7, 3, 7, 3, 7, 7, 5, 5) >>> non_simple_values(0, 0, 3, 4) (0, 7, 4, 4, 4, 4, 4, 4) >>> non_simple_values(0, 0, 1, -1) (0, 0, -1, 0, -1, -1, 0, 0) >>> non_simple_values(1, -1, 1, -1) (0, 0, 0, 0, 0, 0, 0, 0) >>> non_simple_values(1, 2, 1, -1) (0, 3, 0, 3, 0, 0, 1, 1) >>> non_simple_values(2, 1, 1, -1) (0, 3, 1, 3, 0, 0, 1, 1) """ and1 = obj1 + obj2 and obj3 + obj4 or1 = obj1 + obj2 or obj3 + obj4 and_or = obj1 + obj2 and obj3 + obj4 or obj1 + obj4 or_and = obj1 + obj2 or obj3 + obj4 and obj1 + obj4 and_or_and = obj1 + obj2 and obj3 + obj4 or obj1 + obj4 and obj2 + obj4 and1_or_and = (and1 or (obj1 + obj4 and obj2 + obj4)) or_and_or = (obj1 + obj2 or obj3 + obj4) and (obj1 + obj4 or obj2 + obj4) or1_and_or = (or1 and (obj1 + obj4 or obj2 + obj4)) return (and1, or1, and_or, or_and, and_or_and, and1_or_and, or_and_or, or1_and_or) Cython-0.23.4/tests/run/boolean_context.pyx0000644000175600017570000000034012606202452022074 0ustar jenkinsjenkins00000000000000 def test(): """ >>> test() True """ cdef int x = 5 return bool(x) def test_bool_and_int(): """ >>> test_bool_and_int() 1 """ cdef int x = 5 cdef int b = bool(x) return b Cython-0.23.4/tests/run/bishop2.pyx0000644000175600017570000000022512606202452020261 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> f = foo() >>> 'a' in f True >>> 1 in f True """ cdef class foo: def __contains__(self, key): return 1 Cython-0.23.4/tests/run/bishop1.pyx0000644000175600017570000000050712606202452020263 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> m = fmatrix() >>> m[1] = True >>> m.getfoo() 1 >>> m[0] = True >>> m.getfoo() 0 """ cdef class fmatrix: cdef int foo def __setitem__(self, int key, int value): if key: self.foo = value return self.foo = not value def getfoo(self): return self.foo Cython-0.23.4/tests/run/bint_property_T354.pyx0000644000175600017570000000051012606202452022327 0ustar jenkinsjenkins00000000000000# ticket: 354 cdef class Test: """ >>> t = Test(True) >>> t.some_ro_bool True >>> t.some_public_bool True """ cdef public bint some_public_bool cdef readonly bint some_ro_bool def __init__(self, bint boolval): self.some_ro_bool = boolval self.some_public_bool = boolval Cython-0.23.4/tests/run/bint_binop_T145.pyx0000644000175600017570000000450712606202452021562 0ustar jenkinsjenkins00000000000000# ticket: 145 cimport cython @cython.test_fail_if_path_exists('//BoolBinopNode') def or_literal_bint(): """ >>> True or 5 True >>> or_literal_bint() True """ return True or 5 @cython.test_fail_if_path_exists('//BoolBinopNode') def and_literal_bint(): """ >>> 5 and True True >>> and_literal_bint() True """ return 5 and True @cython.test_fail_if_path_exists('//BoolBinopNode') def False_and_True_or_0(): """ >>> False and True or 0 0 >>> False_and_True_or_0() 0 """ return False and True or 0 @cython.test_fail_if_path_exists('//BoolBinopNode') def True_and_True_or_0(): """ >>> True and True or 0 True >>> True_and_True_or_0() True """ return True and True or 0 def x_and_True_or_False(x): """ >>> x_and_True_or_False(0) False >>> x_and_True_or_False(1) True >>> x_and_True_or_False('abc') True >>> x_and_True_or_False([]) False """ return x and True or False def x_and_True_or_0(x): """ >>> 0 and True or 0 0 >>> x_and_True_or_0(0) 0 >>> 1 and True or 0 True >>> x_and_True_or_0(1) True >>> x_and_True_or_0('abc') True >>> x_and_True_or_0([]) 0 """ return x and True or 0 def x_and_True_or_1(x): """ >>> 0 and True or 1 1 >>> x_and_True_or_1(0) 1 >>> 1 and True or 1 True >>> x_and_True_or_1(1) True >>> x_and_True_or_1('abc') True >>> x_and_True_or_1([]) 1 """ return x and True or 1 def x_and_1_or_False(x): """ >>> 0 and 1 or False False >>> x_and_1_or_False(0) False >>> 1 and 1 or False 1 >>> x_and_1_or_False(1) 1 >>> x_and_1_or_False('abc') 1 >>> x_and_1_or_False([]) False """ return x and 1 or False def test_large_int(unsigned long x): """ >>> try: test_large_int(1 << 127) ... except OverflowError: print(True) True >>> try: test_large_int(1 << 63) ... except OverflowError: print(True) True >>> try: test_large_int(1 << 48) ... except OverflowError: print(True) True >>> try: test_large_int(1 << 31) ... except OverflowError: print(True) True >>> test_large_int(0) False """ if True and x: return True else: return False Cython-0.23.4/tests/run/bint.pyx0000644000175600017570000000114612606202452017652 0ustar jenkinsjenkins00000000000000from cython cimport typeof def test(bint value): """ >>> test(True) True >>> test(False) False >>> test(None) False >>> test(0) False >>> test(1) True >>> test(-1) True >>> test(100) True >>> test(0.0) False >>> test(0.1) True >>> test([]) False >>> test([1, 2, 3]) True """ return value def test_types(bint a): """ >>> test_types(None) """ cdef bint b = a assert typeof(a) == 'bint', typeof(a) assert typeof(b) == 'bint', typeof(b) c = b assert typeof(c) == 'bint', typeof(c) Cython-0.23.4/tests/run/big_indices.pyx0000644000175600017570000000060212606202452021151 0ustar jenkinsjenkins00000000000000def test(): """ >>> test() neg False pos True neg pos neg pos """ cdef object D cdef long neg = -1 cdef unsigned long pos = -2 # will be a large positive number print u"neg", neg > 0 print u"pos", pos > 0 D = { neg: u'neg', pos: u'pos' } print D[neg] print D[pos] print D[neg] print D[pos] Cython-0.23.4/tests/run/behnel3.pyx0000644000175600017570000000013312606202452020231 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> y >>> y or {} {} >>> x {} """ y = None x = y or {} Cython-0.23.4/tests/run/behnel2.pyx0000644000175600017570000000014012606202452020226 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> y 1 >>> y and {} {} >>> x {} """ y = 1 x = y and {} Cython-0.23.4/tests/run/behnel1.pyx0000644000175600017570000000026112606202452020231 0ustar jenkinsjenkins00000000000000cdef class Spam: cdef eggs(self, a): return a cdef Spam spam(): return Spam() def viking(a): """ >>> viking(5) 5 """ return spam().eggs(a) Cython-0.23.4/tests/run/bad_c_struct_T252.pyx0000644000175600017570000000151412606202452022065 0ustar jenkinsjenkins00000000000000# ticket: 252 cdef cf(default=None): return default cpdef cpf(default=100): """ >>> cpf() 100 >>> cpf(1) 1 >>> cpf(default=2) 2 """ default = cf(default) return default def pf(default=100): """ >>> pf() 100 >>> pf(1) 1 >>> pf(default=2) 2 """ return default cdef struct foo: int void int default def test_struct(): """ >>> test_struct() (1, 2) """ cdef foo foo_struct foo_struct.void = 1 foo_struct.default = 2 return foo_struct.void, foo_struct.default cdef class Foo: cdef int void cdef int default def test_class(): """ >>> test_class() (1, 2) """ cdef Foo foo_instance = Foo() foo_instance.void = 1 foo_instance.default = 2 return foo_instance.void, foo_instance.default Cython-0.23.4/tests/run/backquote.pyx0000644000175600017570000000030412606202452020667 0ustar jenkinsjenkins00000000000000def f(obj2): """ >>> f(20) '20' >>> f('test') "'test'" """ obj1 = `obj2` return obj1 def g(): """ >>> g() '42' """ obj1 = `42` return obj1 Cython-0.23.4/tests/run/baas3.pyx0000644000175600017570000000025112606202452017703 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> m = MyClass() >>> m is foo(m) True """ cdef class MyClass: pass def foo(MyClass c): cdef MyClass res res = c return res Cython-0.23.4/tests/run/autotestdict_skip.pyx0000644000175600017570000000051712606202452022461 0ustar jenkinsjenkins00000000000000#cython: autotestdict=True """ Tests that autotestdict doesn't come into effect when a __test__ is defined manually. If this doesn't work, then the function doctest should fail. >>> True True """ import sys def func(): """ >>> sys.version_info < (3, 4) False """ __test__ = { u"one" : """ >>> True True """ } Cython-0.23.4/tests/run/autotestdict_cdef.pyx0000644000175600017570000000622612606202452022417 0ustar jenkinsjenkins00000000000000# cython: autotestdict=True, autotestdict.cdef=True """ Tests autotestdict compiler directive. Both module test and individual tests are run; finally, all_tests_run() is executed which does final validation. >>> items = list(__test__.items()) >>> items.sort() >>> for key, value in items: ... print('%s ; %s' % (key, value)) MyCdefClass.cdef_method (line 78) ; >>> add_log("cdef class cmethod") MyCdefClass.cpdef_method (line 75) ; >>> add_log("cpdef class method") MyCdefClass.method (line 72) ; >>> add_log("cdef class method") MyClass.method (line 61) ; >>> add_log("class method") cdeffunc (line 25) ; >>> add_log("cdef") mycpdeffunc (line 48) ; >>> add_log("cpdef") myfunc (line 39) ; >>> add_log("def") """ import sys log = [] cdef cdeffunc(): """>>> add_log("cdef")""" cdeffunc() # make sure it's being used def all_tests_run(): assert sorted(log) == sorted([u'cdef', u'cdef class', u'cdef class cmethod', u'class'] + ( ((1 if sys.version_info < (3, 4) else 2) * [u'cdef class method', u'class method', u'cpdef', u'cpdef class method', u'def']))), sorted(log) def add_log(s): log.append(unicode(s)) if len(log) == len(__test__) + (2 if sys.version_info < (3, 4) else 7): # Final per-function doctest executed all_tests_run() def myfunc(): """>>> add_log("def")""" def doc_without_test(): """Some docs""" def nodocstring(): pass cpdef mycpdeffunc(): """>>> add_log("cpdef")""" class MyClass: """ Needs no hack >>> add_log("class") >>> True True """ def method(self): """>>> add_log("class method")""" cdef class MyCdefClass: """ Needs no hack >>> add_log("cdef class") >>> True True """ def method(self): """>>> add_log("cdef class method")""" cpdef cpdef_method(self): """>>> add_log("cpdef class method")""" cdef cdef_method(self): """>>> add_log("cdef class cmethod")""" def __cinit__(self): """ Should not be included, as it can't be looked up with getattr >>> True False """ def __dealloc__(self): """ Should not be included, as it can't be looked up with getattr >>> True False """ def __richcmp__(self, other, int op): """ Should not be included, as it can't be looked up with getattr in Py 2 >>> True False """ def __nonzero__(self): """ Should not be included, as it can't be looked up with getattr in Py 3.1 >>> True False """ def __len__(self): """ Should not be included, as it can't be looked up with getattr in Py 3.1 >>> sys.version_info < (3, 4) False """ def __contains__(self, value): """ Should not be included, as it can't be looked up with getattr in Py 3.1 >>> sys.version_info < (3, 4) False """ cdef class MyOtherCdefClass: """ Needs no hack >>> True True """ def __bool__(self): """ Should not be included, as it can't be looked up with getattr in Py 2 >>> True False """ Cython-0.23.4/tests/run/autotestdict_all.pyx0000644000175600017570000000627212606202452022267 0ustar jenkinsjenkins00000000000000# cython: autotestdict=True, autotestdict.all=True """ Tests autotestdict compiler directive. Both module test and individual tests are run; finally, all_tests_run() is executed which does final validation. >>> items = list(__test__.items()) >>> items.sort() >>> for key, value in items: ... print('%s ; %s' % (key, value)) MyCdefClass.cdef_method (line 79) ; >>> add_log("cdef class cmethod") MyCdefClass.cpdef_method (line 76) ; >>> add_log("cpdef class method") MyCdefClass.method (line 73) ; >>> add_log("cdef class method") MyClass.method (line 62) ; >>> add_log("class method") cdeffunc (line 26) ; >>> add_log("cdef") doc_without_test (line 43) ; Some docs mycpdeffunc (line 49) ; >>> add_log("cpdef") myfunc (line 40) ; >>> add_log("def") """ import sys log = [] cdef cdeffunc(): """>>> add_log("cdef")""" cdeffunc() # make sure it's being used def all_tests_run(): assert sorted(log) == sorted([u'cdef', u'cdef class', u'class', u'cdef class cmethod'] + ( (1 if sys.version_info < (3, 4) else 2) * [u'cdef class method', u'class method', u'cpdef', u'cpdef class method', u'def'])), sorted(log) def add_log(s): log.append(unicode(s)) if len(log) == len(__test__) + (1 if sys.version_info < (3, 4) else 6): # Final per-function doctest executed all_tests_run() def myfunc(): """>>> add_log("def")""" def doc_without_test(): """Some docs""" def nodocstring(): pass cpdef mycpdeffunc(): """>>> add_log("cpdef")""" class MyClass: """ Needs no hack >>> add_log("class") >>> True True """ def method(self): """>>> add_log("class method")""" cdef class MyCdefClass: """ Needs no hack >>> add_log("cdef class") >>> True True """ def method(self): """>>> add_log("cdef class method")""" cpdef cpdef_method(self): """>>> add_log("cpdef class method")""" cdef cdef_method(self): """>>> add_log("cdef class cmethod")""" def __cinit__(self): """ Should not be included, as it can't be looked up with getattr >>> True False """ def __dealloc__(self): """ Should not be included, as it can't be looked up with getattr >>> True False """ def __richcmp__(self, other, int op): """ Should not be included, as it can't be looked up with getattr in Py 2 >>> True False """ def __nonzero__(self): """ Should not be included, as it can't be looked up with getattr in Py 3.1 >>> True False """ def __len__(self): """ Should not be included, as it can't be looked up with getattr in Py 3.1 >>> sys.version_info < (3, 4) False """ def __contains__(self, value): """ Should not be included, as it can't be looked up with getattr in Py 3.1 >>> sys.version_info < (3, 4) False """ cdef class MyOtherCdefClass: """ Needs no hack >>> True True """ def __bool__(self): """ Should not be included, as it can't be looked up with getattr in Py 2 >>> True False """ Cython-0.23.4/tests/run/autotestdict.pyx0000644000175600017570000000613412606202452021434 0ustar jenkinsjenkins00000000000000# cython: autotestdict=True # Directive defaults to True, but not when testing in Py3.4 """ Tests autotestdict compiler directive. Both module test and individual tests are run; finally, all_tests_run() is executed which does final validation. >>> items = list(__test__.items()) >>> items.sort() >>> for key, value in items: ... print('%s ; %s' % (key, value)) MyCdefClass.cpdef_method (line 77) ; >>> add_log("cpdef class method") MyCdefClass.method (line 74) ; >>> add_log("cdef class method") MyClass.method (line 63) ; >>> add_log("class method") mycpdeffunc (line 50) ; >>> add_log("cpdef") myfunc (line 40) ; >>> add_log("def") """ import sys log = [] cdef cdeffunc(): """ >>> True False """ cdeffunc() # make sure it's being used def all_tests_run(): assert sorted(log) == sorted([u'cdef class', u'class'] + ( (1 if sys.version_info < (3, 4) else 2) * [u'cdef class method', u'class method', u'cpdef', u'cpdef class method', u'def'])), sorted(log) def add_log(s): log.append(unicode(s)) if len(log) == len(__test__) + (2 if sys.version_info < (3, 4) else 7): # Final per-function doctest executed all_tests_run() def myfunc(): """>>> add_log("def")""" x = lambda a:1 # no docstring here ... def doc_without_test(): """Some docs""" def nodocstring(): pass cpdef mycpdeffunc(): """>>> add_log("cpdef")""" class MyClass: """ Needs no hack >>> add_log("class") >>> True True """ def method(self): """>>> add_log("class method")""" cdef class MyCdefClass: """ Needs no hack >>> add_log("cdef class") >>> True True """ def method(self): """>>> add_log("cdef class method")""" cpdef cpdef_method(self): """>>> add_log("cpdef class method")""" cdef cdef_method(self): """>>> add_log("cdef class cmethod")""" def __cinit__(self): """ Should not be included, as it can't be looked up with getattr >>> True False """ def __dealloc__(self): """ Should not be included, as it can't be looked up with getattr >>> True False """ def __richcmp__(self, other, int op): """ Should not be included, as it can't be looked up with getattr in Py 2 >>> True False """ def __nonzero__(self): """ Should not be included, as it can't be looked up with getattr in Py 3.1 >>> True False """ def __len__(self): """ Should not be included, as it can't be looked up with getattr in Py 3.1 >>> sys.version_info < (3, 4) False """ def __contains__(self, value): """ Should not be included, as it can't be looked up with getattr in Py 3.1 >>> sys.version_info < (3, 4) False """ cdef class MyOtherCdefClass: """ Needs no hack >>> True True """ def __bool__(self): """ Should not be included, as it can't be looked up with getattr in Py 2 >>> True False """ Cython-0.23.4/tests/run/autotestdict.pxd0000644000175600017570000000001712606202452021401 0ustar jenkinsjenkins00000000000000# I just exist Cython-0.23.4/tests/run/auto_cpdef_closures.py0000644000175600017570000000050012606202452022547 0ustar jenkinsjenkins00000000000000# cython: auto_cpdef=True # mode:run # tag: directive,auto_cpdef,closures def closure_func(x): """ >>> c = closure_func(2) >>> c() 2 """ def c(): return x return c def generator_func(): """ >>> for i in generator_func(): print(i) 1 2 """ yield 1 yield 2 Cython-0.23.4/tests/run/auto_cpdef.py0000644000175600017570000000243212606202452020636 0ustar jenkinsjenkins00000000000000# cython: auto_cpdef=True # mode:run # tag: directive,auto_cpdef import cython def str(arg): """ This is a bit evil - str gets mapped to a C-API function and is being redefined here. >>> print(str('TEST')) STR """ return 'STR' @cython.test_assert_path_exists('//SimpleCallNode[@function.type.is_cfunction = True]') @cython.test_fail_if_path_exists('//SimpleCallNode[@function.type.is_builtin_type = True]') def call_str(arg): """ >>> print(call_str('TEST')) STR """ return str(arg) def stararg_func(*args): """ >>> stararg_func(1, 2) (1, 2) """ return args def starstararg_func(**kwargs): """ >>> starstararg_func(a=1) 1 """ return kwargs['a'] l = lambda x: 1 def test_lambda(): """ >>> l(1) 1 """ # test classical import fallbacks try: from math import fabs except ImportError: def fabs(x): if x < 0: return -x else: return x try: from math import no_such_function except ImportError: def no_such_function(x): return x + 1.0 def test_import_fallback(): """ >>> fabs(1.0) 1.0 >>> no_such_function(1.0) 2.0 >>> test_import_fallback() (1.0, 2.0) """ return fabs(1.0), no_such_function(1.0) Cython-0.23.4/tests/run/attribute_and_lambda.pyx0000644000175600017570000000035412606202452023043 0ustar jenkinsjenkins00000000000000# mode: run # tag: lambda, attribute, regression class TestClass(object): bar = 123 def test_attribute_and_lambda(f): """ >>> test_attribute_and_lambda(lambda _: TestClass()) 123 """ return f(lambda x: x).bar Cython-0.23.4/tests/run/attr.pyx0000644000175600017570000000226612606202452017674 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> class Test(object): ... def __init__(self, i): ... self.i = i >>> b = Test(1) >>> b.spam = Test(2) >>> b.spam.eggs = Test(3) >>> b.spam.eggs.spam = Test(4) >>> b.spam.eggs.spam.eggs = Test(5) >>> a = f(b) >>> a.i 2 >>> b.i 1 >>> a.spam.i 1 >>> b.spam.i 2 >>> a.spam.eggs.i Traceback (most recent call last): AttributeError: 'Test' object has no attribute 'eggs' >>> b.spam.eggs.i 3 >>> a.spam.spam.i 2 >>> b.spam.spam.i 1 >>> a.spam.eggs.spam.i Traceback (most recent call last): AttributeError: 'Test' object has no attribute 'eggs' >>> b.spam.eggs.spam.i 4 >>> a = g(b) >>> a.i 3 >>> b.i 1 >>> a.spam.i 4 >>> b.spam.i 2 >>> a.spam.eggs.i 1 >>> b.spam.eggs.i 3 >>> a.spam.spam.i Traceback (most recent call last): AttributeError: 'Test' object has no attribute 'spam' >>> b.spam.spam.i 1 >>> a.spam.eggs.spam.i 2 >>> b.spam.eggs.spam.i 4 """ def f(b): a = b.spam a.spam = b return a def g(b): a = b.spam.eggs a.spam.eggs = b return a Cython-0.23.4/tests/run/asyncio_generators.srctree0000644000175600017570000001157212606202452023447 0ustar jenkinsjenkins00000000000000# mode: run # tag: asyncio, pep492 """ PYTHON setup.py build_ext -i PYTHON test_from_import.py PYTHON test_import.py PYTHON test_async_def.py PYTHON test_async_def_future.py PYTHON test_all.py """ ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize("*.pyx"), ) ######## test_from_import.py ######## import from_asyncio_import import asyncio def runloop(task): loop = asyncio.get_event_loop() result = loop.run_until_complete(task()) assert 3 == result, result runloop(from_asyncio_import.wait3) ######## test_import.py ######## import import_asyncio import asyncio def runloop(task): loop = asyncio.get_event_loop() result = loop.run_until_complete(task()) assert 3 == result, result runloop(import_asyncio.wait3) ######## test_async_def.py ######## import sys ASYNCIO_SUPPORTS_COROUTINE = sys.version_info[:2] >= (3, 5) if ASYNCIO_SUPPORTS_COROUTINE: import async_def import asyncio def runloop(task): loop = asyncio.get_event_loop() result = loop.run_until_complete(task()) assert 3 == result, result runloop(async_def.wait3) ######## test_async_def_future.py ######## import sys ASYNCIO_SUPPORTS_COROUTINE = sys.version_info[:2] >= (3, 5) if ASYNCIO_SUPPORTS_COROUTINE: from async_def_future import await_future import asyncio def runloop(): loop = asyncio.get_event_loop() task, events, expected = await_future(loop) result = loop.run_until_complete(task()) assert events == expected, events runloop() ######## test_all.py ######## import sys import asyncio ASYNCIO_SUPPORTS_COROUTINE = sys.version_info[:2] >= (3, 5) def runloop(task): loop = asyncio.get_event_loop() result = loop.run_until_complete(task()) assert 3 == result, result import import_asyncio runloop(import_asyncio.wait3) # 1a) import from_asyncio_import runloop(from_asyncio_import.wait3) # 1b) import async_def if ASYNCIO_SUPPORTS_COROUTINE: runloop(async_def.wait3) # 1c) runloop(from_asyncio_import.wait3) # 2a) runloop(import_asyncio.wait3) # 2b) if ASYNCIO_SUPPORTS_COROUTINE: runloop(async_def.wait3) # 2c) runloop(from_asyncio_import.wait3) # 3a) runloop(import_asyncio.wait3) # 3b) if ASYNCIO_SUPPORTS_COROUTINE: runloop(async_def.wait3) # 3c) try: from collections.abc import Generator except ImportError: try: from collections import Generator except ImportError: assert sys.version_info < (3,5), "Python 3.5+ should have collections.abc.Generator" Generator = object # easy win :) assert isinstance(from_asyncio_import.wait3(), Generator) assert isinstance(import_asyncio.wait3(), Generator) assert isinstance((lambda:(yield))(), Generator) try: from collections.abc import Awaitable except ImportError: try: from collections import Awaitable except ImportError: assert sys.version_info < (3,5), "Python 3.5+ should have collections.abc.Awaitable" Awaitable = object # easy win :) assert isinstance(async_def.wait3(), Awaitable) try: from collections.abc import Coroutine except ImportError: try: from collections import Coroutine except ImportError: assert sys.version_info < (3,5), "Python 3.5+ should have collections.abc.Coroutine" Coroutine = object # easy win :) assert isinstance(async_def.wait3(), Coroutine) ######## import_asyncio.pyx ######## # cython: binding=True try: from types import coroutine as types_coroutine except ImportError: types_coroutine = lambda f:f import asyncio @asyncio.coroutine @types_coroutine def wait3(): counter = 0 for i in range(3): print(counter) yield from asyncio.sleep(0.01) counter += 1 return counter ######## from_asyncio_import.pyx ######## # cython: binding=True try: from types import coroutine as types_coroutine except ImportError: types_coroutine = lambda f:f from asyncio import coroutine, sleep @coroutine @types_coroutine def wait3(): counter = 0 for i in range(3): print(counter) yield from sleep(0.01) counter += 1 return counter ######## async_def.pyx ######## # cython: binding=True import asyncio async def wait3(): counter = 0 for i in range(3): print(counter) await asyncio.sleep(0.01) counter += 1 return counter ######## async_def_future.pyx ######## import asyncio def await_future(loop): events = [] async def worker(): fut = asyncio.Future() def setval(): events.append('setval') fut.set_result(123) events.append('setup') loop.call_later(0.2, setval) events.append(await fut) async def test(): await worker() expected = ['setup', 'setval', 123] return test, events, expected Cython-0.23.4/tests/run/async_iter_pep492.pyx0000644000175600017570000001414212606202452022161 0ustar jenkinsjenkins00000000000000# mode: run # tag: pep492, asyncfor, await import sys if sys.version_info >= (3, 5, 0, 'beta'): # pass Cython implemented AsyncIter() into a Python async-for loop __doc__ = u""" >>> def test_py35(): ... buffer = [] ... async def coro(): ... async for i1, i2 in AsyncIter(1): ... buffer.append(i1 + i2) ... return coro, buffer >>> testfunc, buffer = test_py35() >>> buffer [] >>> yielded, _ = run_async(testfunc(), check_type=False) >>> yielded == [i * 100 for i in range(1, 11)] or yielded True >>> buffer == [i*2 for i in range(1, 101)] or buffer True """ cdef class AsyncYieldFrom: cdef object obj def __init__(self, obj): self.obj = obj def __await__(self): yield from self.obj cdef class AsyncYield: cdef object value def __init__(self, value): self.value = value def __await__(self): yield self.value def run_async(coro, check_type='coroutine'): if check_type: assert coro.__class__.__name__ == check_type, \ 'type(%s) != %s' % (coro.__class__, check_type) buffer = [] result = None while True: try: buffer.append(coro.send(None)) except StopIteration as ex: result = ex.args[0] if ex.args else None break return buffer, result cdef class AsyncIter: cdef long i cdef long aiter_calls cdef long max_iter_calls def __init__(self, long max_iter_calls=1): self.i = 0 self.aiter_calls = 0 self.max_iter_calls = max_iter_calls async def __aiter__(self): self.aiter_calls += 1 return self async def __anext__(self): self.i += 1 assert self.aiter_calls <= self.max_iter_calls if not (self.i % 10): await AsyncYield(self.i * 10) if self.i > 100: raise StopAsyncIteration return self.i, self.i def test_for_1(): """ >>> testfunc, buffer = test_for_1() >>> buffer [] >>> yielded, _ = run_async(testfunc()) >>> yielded == [i * 100 for i in range(1, 11)] or yielded True >>> buffer == [i*2 for i in range(1, 101)] or buffer True """ buffer = [] async def test1(): async for i1, i2 in AsyncIter(1): buffer.append(i1 + i2) return test1, buffer def test_for_2(): """ >>> testfunc, buffer = test_for_2() >>> buffer [] >>> yielded, _ = run_async(testfunc()) >>> yielded == [100, 200] or yielded True >>> buffer == [i for i in range(1, 21)] + ['end'] or buffer True """ buffer = [] async def test2(): nonlocal buffer async for i in AsyncIter(2): buffer.append(i[0]) if i[0] == 20: break else: buffer.append('what?') buffer.append('end') return test2, buffer def test_for_3(): """ >>> testfunc, buffer = test_for_3() >>> buffer [] >>> yielded, _ = run_async(testfunc()) >>> yielded == [i * 100 for i in range(1, 11)] or yielded True >>> buffer == [i for i in range(1, 21)] + ['what?', 'end'] or buffer True """ buffer = [] async def test3(): nonlocal buffer async for i in AsyncIter(3): if i[0] > 20: continue buffer.append(i[0]) else: buffer.append('what?') buffer.append('end') return test3, buffer cdef class NonAwaitableFromAnext: async def __aiter__(self): return self def __anext__(self): return 123 def test_broken_anext(): """ >>> testfunc = test_broken_anext() >>> try: run_async(testfunc()) ... except TypeError as exc: ... assert ' int ' in str(exc) ... else: ... print("NOT RAISED!") """ async def foo(): async for i in NonAwaitableFromAnext(): print('never going to happen') return foo cdef class Manager: cdef readonly list counter def __init__(self, counter): self.counter = counter async def __aenter__(self): self.counter[0] += 10000 async def __aexit__(self, *args): self.counter[0] += 100000 cdef class Iterable: cdef long i def __init__(self): self.i = 0 async def __aiter__(self): return self async def __anext__(self): if self.i > 10: raise StopAsyncIteration self.i += 1 return self.i def test_with_for(): """ >>> test_with_for() 111011 333033 20555255 """ I = [0] manager = Manager(I) iterable = Iterable() mrefs_before = sys.getrefcount(manager) irefs_before = sys.getrefcount(iterable) async def main(): async with manager: async for i in iterable: I[0] += 1 I[0] += 1000 run_async(main()) print(I[0]) assert sys.getrefcount(manager) == mrefs_before assert sys.getrefcount(iterable) == irefs_before ############## async def main(): nonlocal I async with Manager(I): async for i in Iterable(): I[0] += 1 I[0] += 1000 async with Manager(I): async for i in Iterable(): I[0] += 1 I[0] += 1000 run_async(main()) print(I[0]) ############## async def main(): async with Manager(I): I[0] += 100 async for i in Iterable(): I[0] += 1 else: I[0] += 10000000 I[0] += 1000 async with Manager(I): I[0] += 100 async for i in Iterable(): I[0] += 1 else: I[0] += 10000000 I[0] += 1000 run_async(main()) print(I[0]) cdef class AI: async def __aiter__(self): 1/0 def test_aiter_raises(): """ >>> test_aiter_raises() RAISED 0 """ CNT = 0 async def foo(): nonlocal CNT async for i in AI(): CNT += 1 CNT += 10 try: run_async(foo()) except ZeroDivisionError: print("RAISED") else: print("NOT RAISED") return CNT Cython-0.23.4/tests/run/assigned_builtin_methods.pyx0000644000175600017570000000320412606202452023761 0ustar jenkinsjenkins00000000000000# mode: run # tag: builtins cimport cython @cython.test_assert_path_exists( '//ReturnStatNode//PythonCapiCallNode') def unbound_dict_get(d): """ >>> unbound_dict_get({}) >>> unbound_dict_get({1:2}) 2 """ get = dict.get return get(d, 1) @cython.test_assert_path_exists( '//ReturnStatNode//PythonCapiCallNode') def bound_dict_get(dict d): """ >>> bound_dict_get({}) >>> bound_dict_get({1:2}) 2 """ get = d.get return get(1) @cython.test_fail_if_path_exists( '//ReturnStatNode//PythonCapiCallNode') @cython.test_assert_path_exists( '//ReturnStatNode//SimpleCallNode') def bound_dict_get_reassign(dict d): """ >>> bound_dict_get_reassign({}) >>> bound_dict_get_reassign({1:2}) 2 """ get = d.get d = {1: 3} return get(1) @cython.test_assert_path_exists( '//PythonCapiCallNode//NameNode[@name="l"]') def unbound_list_sort(list l): """ >>> unbound_list_sort([1, 3, 2]) [1, 2, 3] >>> unbound_list_sort([1, 3, 2]) [1, 2, 3] """ sort = list.sort sort(l) return l @cython.test_assert_path_exists( '//PythonCapiCallNode//NameNode[@name="l"]') def bound_list_sort(list l): """ >>> bound_list_sort([1, 3, 2]) [1, 2, 3] >>> bound_list_sort([1, 3, 2]) [1, 2, 3] """ sort = l.sort sort() return l @cython.test_fail_if_path_exists( '//PythonCapiCallNode') def bound_list_sort_reassign(list l): """ >>> bound_list_sort_reassign([1, 3, 2]) [3, 2, 1] >>> bound_list_sort_reassign([1, 3, 2]) [3, 2, 1] """ sort = l.sort l = [3, 2, 1] sort() return l Cython-0.23.4/tests/run/assert.pyx0000644000175600017570000000324112606202452020215 0ustar jenkinsjenkins00000000000000# mode: run cimport cython def f(a, b, int i): """ >>> f(1, 2, 1) >>> f(0, 2, 1) Traceback (most recent call last): AssertionError >>> f(1, -1, 1) Traceback (most recent call last): AssertionError >>> f(1, 2, 0) Traceback (most recent call last): AssertionError """ assert a assert a+b assert i @cython.test_assert_path_exists( '//AssertStatNode', '//AssertStatNode//TupleNode') def g(a, b): """ >>> g(1, "works") >>> g(0, "fails") Traceback (most recent call last): AssertionError: fails >>> g(0, (1, 2)) Traceback (most recent call last): AssertionError: (1, 2) """ assert a, b @cython.test_assert_path_exists( '//AssertStatNode', '//AssertStatNode//TupleNode') def g(a, b): """ >>> g(1, "works") >>> g(0, "fails") Traceback (most recent call last): AssertionError: fails >>> g(0, (1, 2)) Traceback (most recent call last): AssertionError: (1, 2) """ assert a, b @cython.test_assert_path_exists( '//AssertStatNode', '//AssertStatNode//TupleNode', '//AssertStatNode//TupleNode//TupleNode') def assert_with_tuple_arg(a): """ >>> assert_with_tuple_arg(True) >>> assert_with_tuple_arg(False) Traceback (most recent call last): AssertionError: (1, 2) """ assert a, (1, 2) @cython.test_assert_path_exists( '//AssertStatNode') @cython.test_fail_if_path_exists( '//AssertStatNode//TupleNode') def assert_with_str_arg(a): """ >>> assert_with_str_arg(True) >>> assert_with_str_arg(False) Traceback (most recent call last): AssertionError: abc """ assert a, 'abc' Cython-0.23.4/tests/run/ass2local.pyx0000644000175600017570000000010412606202452020572 0ustar jenkinsjenkins00000000000000def f(): """ >>> f() 42 """ a = 42 return a Cython-0.23.4/tests/run/ass2global.py0000644000175600017570000000103412606202452020553 0ustar jenkinsjenkins00000000000000""" >>> getg() 5 >>> setg(42) >>> getg() 42 """ g = 5 def setg(a): global g g = a def getg(): return g class Test(object): """ >>> global_in_class 9 >>> Test.global_in_class Traceback (most recent call last): AttributeError: type object 'Test' has no attribute 'global_in_class' >>> Test().global_in_class Traceback (most recent call last): AttributeError: 'Test' object has no attribute 'global_in_class' """ global global_in_class global_in_class = 9 Cython-0.23.4/tests/run/ass2cglobal.pyx0000644000175600017570000000033312606202452021107 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> what() 0 5 >>> f(5) >>> what() 42 5 >>> f(6) >>> what() 42 6 >>> f("spam") >>> what() 42 spam """ cdef int i = 0 cdef x = 5 def f(a): global i, x i = 42 x = a def what(): print i,x Cython-0.23.4/tests/run/arrayassign.pyx0000644000175600017570000002247612606202452021252 0ustar jenkinsjenkins00000000000000# mode: run cimport cython def test_literal_list(): """ >>> test_literal_list() (1, 2, 3, 4, 5) """ cdef int a[5] a = [1,2,3,4,5] return (a[0], a[1], a[2], a[3], a[4]) def test_literal_list_multiplied(): """ >>> test_literal_list_multiplied() (1, 2, 1, 2, 1, 2) """ cdef int a[6] a = [1,2] * 3 return (a[0], a[1], a[2], a[3], a[4], a[5]) def test_literal_list_slice_all(): """ >>> test_literal_list_slice_all() (1, 2, 3, 4, 5) """ cdef int a[5] # = [5,4,3,2,1] a[:] = [1,2,3,4,5] return (a[0], a[1], a[2], a[3], a[4]) def test_literal_list_slice_start(): """ >>> test_literal_list_slice_start() (1, 2, 3, 4, 5) """ cdef int a[7] # = [7,6,5,4,3,2,1] a[2:] = [1,2,3,4,5] return (a[2], a[3], a[4], a[5], a[6]) def test_literal_list_slice_end(): """ >>> test_literal_list_slice_end() (1, 2, 3, 4, 5) """ cdef int a[7] # = [7,6,5,4,3,2,1] a[:5] = [1,2,3,4,5] return (a[0], a[1], a[2], a[3], a[4]) def test_literal_list_slice_start_end(): """ >>> test_literal_list_slice_start_end() (1, 2, 3, 4, 5) """ cdef int a[9] # = [9,8,7,6,5,4,3,2,1] a[2:7] = [1,2,3,4,5] return (a[2], a[3], a[4], a[5], a[6]) def test_literal_list_slice_start_param(s): """ >>> test_literal_list_slice_start_param(4) (1, 2, 3, 4, 5) >>> test_literal_list_slice_start_param(3) Traceback (most recent call last): ValueError: Assignment to slice of wrong length, expected 5, got 6 >>> test_literal_list_slice_start_param(5) Traceback (most recent call last): ValueError: Assignment to slice of wrong length, expected 5, got 4 """ cdef int a[9] # = [9,8,7,6,5,4,3,2,1] a[s:] = [1,2,3,4,5] return (a[4], a[5], a[6], a[7], a[8]) # return a[s:] def test_literal_list_slice_end_param(e): """ >>> test_literal_list_slice_end_param(5) (1, 2, 3, 4, 5) >>> test_literal_list_slice_end_param(4) Traceback (most recent call last): ValueError: Assignment to slice of wrong length, expected 5, got 4 >>> test_literal_list_slice_end_param(6) Traceback (most recent call last): ValueError: Assignment to slice of wrong length, expected 5, got 6 """ cdef int a[9] # = [9,8,7,6,5,4,3,2,1] a[:e] = [1,2,3,4,5] return (a[0], a[1], a[2], a[3], a[4]) # return a[:e] def test_literal_list_slice_start_end_param(s,e): """ >>> test_literal_list_slice_start_end_param(2,7) (1, 2, 3, 4, 5) >>> test_literal_list_slice_start_end_param(3,7) Traceback (most recent call last): ValueError: Assignment to slice of wrong length, expected 5, got 4 >>> test_literal_list_slice_start_end_param(1,7) Traceback (most recent call last): ValueError: Assignment to slice of wrong length, expected 5, got 6 >>> test_literal_list_slice_start_end_param(2,6) Traceback (most recent call last): ValueError: Assignment to slice of wrong length, expected 5, got 4 >>> test_literal_list_slice_start_end_param(2,8) Traceback (most recent call last): ValueError: Assignment to slice of wrong length, expected 5, got 6 >>> test_literal_list_slice_start_end_param(3,6) Traceback (most recent call last): ValueError: Assignment to slice of wrong length, expected 5, got 3 >>> test_literal_list_slice_start_end_param(1,8) Traceback (most recent call last): ValueError: Assignment to slice of wrong length, expected 5, got 7 """ cdef int a[9] # = [9,8,7,6,5,4,3,2,1] a[s:e] = [1,2,3,4,5] return (a[2], a[3], a[4], a[5], a[6]) # return a[s:e] def test_ptr_literal_list_slice_all(): """ >>> test_ptr_literal_list_slice_all() (1, 2, 3, 4, 5) """ cdef int *a = [6,5,4,3,2] a[:] = [1,2,3,4,5] return (a[0], a[1], a[2], a[3], a[4]) def test_ptr_literal_list_slice_start(): """ >>> test_ptr_literal_list_slice_start() (1, 2, 3, 4, 5) """ cdef int *a = [6,5,4,3,2,1] a[1:] = [1,2,3,4,5] return (a[1], a[2], a[3], a[4], a[5]) def test_ptr_literal_list_slice_end(): """ >>> test_ptr_literal_list_slice_end() (1, 2, 3, 4, 5) """ cdef int *a = [6,5,4,3,2,1] a[:5] = [1,2,3,4,5] return (a[0], a[1], a[2], a[3], a[4]) @cython.test_assert_path_exists( '//ReturnStatNode//CoerceToPyTypeNode' ) def test_starred_from_array(): """ >>> test_starred_from_array() (1, [2, 3, 4], 5) """ cdef int[5] a a[0] = 1 a[1] = 2 a[2] = 3 a[3] = 4 a[4] = 5 x, *y, z = a return x, y, z @cython.test_fail_if_path_exists( '//ParallelAssignmentNode//CoerceToPyTypeNode', '//ParallelAssignmentNode//CoerceFromPyTypeNode', ) @cython.test_assert_path_exists( '//ParallelAssignmentNode', '//ReturnStatNode//CoerceToPyTypeNode' ) def test_multiple_from_array(): """ >>> test_multiple_from_array() (1, 2, 3) """ cdef int[3] a a[0] = 1 a[1] = 2 a[2] = 3 x, y, z = a return x, y, z @cython.test_fail_if_path_exists( '//ParallelAssignmentNode//CoerceToPyTypeNode' ) @cython.test_assert_path_exists( '//ParallelAssignmentNode', '//ReturnStatNode//CoerceToPyTypeNode' ) def test_multiple_from_array_full_slice(): """ >>> test_multiple_from_array_full_slice() (1, 2, 3) """ cdef int[3] a a[0] = 1 a[1] = 2 a[2] = 3 x, y, z = a[:] return x, y, z @cython.test_fail_if_path_exists( '//ParallelAssignmentNode//CoerceToPyTypeNode' ) @cython.test_assert_path_exists( '//ParallelAssignmentNode', '//ReturnStatNode//CoerceToPyTypeNode' ) def test_multiple_from_slice(): """ >>> test_multiple_from_slice() (5, 4, 3) """ cdef int *a = [6,5,4,3,2,1] x, y, z = a[1:4] return x, y, z def test_slice_from_multiple(): """ >>> test_slice_from_multiple() (6, -1, -2, -3, 2, 1) """ cdef int *a = [6,5,4,3,2,1] a[1:4] = -1, -2, -3 return a[0], a[1], a[2], a[3], a[4], a[5] def test_literal_tuple(): """ >>> test_literal_tuple() (1, 2, 3, 4, 5) """ cdef int a[5] a = (1,2,3,4,5) return (a[0], a[1], a[2], a[3], a[4]) def test_list(list l): """ >>> test_list([1, 2, 3, 4, 5]) (1, 2, 3, 4, 5) """ cdef int a[5] a[:] = l return (a[0], a[1], a[2], a[3], a[4]) def assign_all_from_pointer(): """ >>> assign_all_from_pointer() (1, 2, 3, 4, 5) """ cdef int *v = [1, 2, 3, 4, 5] cdef int[5] a a = v return (a[0], a[1], a[2], a[3], a[4]) def assign_full_from_pointer(): """ >>> assign_full_from_pointer() (1, 2, 3, 4, 5) """ cdef int *v = [1, 2, 3, 4, 5] cdef int[5] a a[:] = v return (a[0], a[1], a[2], a[3], a[4]) def assign_slice_end_from_pointer(): """ >>> assign_slice_end_from_pointer() (1, 2, 3, 4, 123) """ cdef int *v = [1, 2, 3, 4, 5] cdef int[5] a a[4] = 123 a[:4] = v return (a[0], a[1], a[2], a[3], a[4]) def assign_slice_start_from_pointer(): """ >>> assign_slice_start_from_pointer() (123, 234, 1, 2, 3) """ cdef int *v = [1, 2, 3, 4, 5] cdef int[5] a a[0] = 123 a[1] = 234 a[2:] = v return (a[0], a[1], a[2], a[3], a[4]) def assign_slice_start_end_from_pointer(): """ >>> assign_slice_start_end_from_pointer() (123, 234, 1, 2, 345) """ cdef int *v = [1, 2, 3, 4, 5] cdef int[5] a a[0] = 123 a[1] = 234 a[4] = 345 a[2:4] = v return (a[0], a[1], a[2], a[3], a[4]) ''' # FIXME: make this work: def assign_slice_start_end_from_sliced_pointer(): """ >>> assign_slice_start_end_from_sliced_pointer() (123, 234, 3, 4, 345) """ cdef int *v = [1, 2, 3, 4, 5] cdef int[5] a a[0] = 123 a[1] = 234 a[4] = 345 a[2:4] = v[2:4] return (a[0], a[1], a[2], a[3], a[4]) def assign_from_longer_array_slice(): """ >>> assign_from_longer_array_slice() [3, 4, 5] """ cdef int[5] a cdef int[3] b a[0] = 1 a[1] = 2 a[2] = 3 a[3] = 4 a[4] = 5 b[0] = 11 b[1] = 12 b[2] = 13 b = a[2:] return b ''' def assign_slice_from_shorter_array(): """ >>> assign_slice_from_shorter_array() [1, 11, 12, 13, 5] """ cdef int[5] a cdef int[3] b a[0] = 1 a[1] = 2 a[2] = 3 a[3] = 4 a[4] = 5 b[0] = 11 b[1] = 12 b[2] = 13 a[1:4] = b return a cdef enum: SIZE = 2 ctypedef int[SIZE] int_array_dyn def assign_ptr_to_unknown_csize(): """ >>> assign_ptr_to_unknown_csize() [1, 2] """ cdef int* v = [1, 2, 3, 4, 5] cdef int_array_dyn d d = v return d def assign_to_wrong_csize(): """ >>> assign_to_wrong_csize() Traceback (most recent call last): ValueError: Assignment to slice of wrong length, expected 3, got 2 """ cdef int_array_dyn d cdef int v[3] v[0] = 1 v[1] = 2 v[2] = 3 d = v return d def assign_full_array_slice_to_array(): """ >>> assign_full_array_slice_to_array() [1, 2, 3] """ cdef int[3] x, y x[0] = 1 x[1] = 2 x[2] = 3 y = x[:] return y cdef class ArrayOwner: cdef readonly int[3] array def __init__(self, a, b, c): self.array = (a, b, c) def assign_from_array_attribute(): """ >>> assign_from_array_attribute() [1, 2, 3] """ cdef int[3] v a = ArrayOwner(1, 2, 3) v = a.array[:] return v Cython-0.23.4/tests/run/array_cimport.srctree0000644000175600017570000000116012606202452022414 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import ttt" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize("*.pyx"), ) ######## tt.pxd ######## from cpython.array cimport array cdef class Foo: cdef array obj ######## tt.pyx ######## cdef class Foo: def __init__(self, data): self.obj = data ######## ttt.pyx ######## from array import array from cpython.array cimport array from tt cimport Foo cdef array a = array('i', [1,2,3]) cdef Foo x print a.data.as_ints[0] x = Foo(a) print x.obj.data.as_ints[0] Cython-0.23.4/tests/run/array_address.pyx0000644000175600017570000000043512606202452021541 0ustar jenkinsjenkins00000000000000ctypedef int five_ints[5] def test_array_address(int ix, int x): """ >>> test_array_address(0, 100) 100 >>> test_array_address(2, 200) 200 """ cdef five_ints a a[:] = [1, 2, 3, 4, 5] cdef five_ints *a_ptr = &a a_ptr[0][ix] = x return a[ix] Cython-0.23.4/tests/run/arithmetic_analyse_types_helper.h0000644000175600017570000000105612606202452024755 0ustar jenkinsjenkins00000000000000/* A set of mutually incompatable return types. */ struct short_return { char *msg; }; struct int_return { char *msg; }; struct longlong_return { char *msg; }; /* A set of overloaded methods. */ short_return f(short arg) { short_return val; arg++; val.msg = (char*)"short called"; return val; } int_return f(int arg) { int_return val; arg++; val.msg = (char*)"int called"; return val; } longlong_return f(long long arg) { longlong_return val; arg++; val.msg = (char*)"long long called"; return val; } Cython-0.23.4/tests/run/arithmetic_analyse_types.pyx0000644000175600017570000000272612606202452024014 0ustar jenkinsjenkins00000000000000# ticket: 676 # tag: cpp from cython cimport typeof cdef extern from "arithmetic_analyse_types_helper.h": cdef struct short_return: char *msg cdef struct int_return: char *msg cdef struct longlong_return: char *msg cdef short_return f(short) cdef int_return f(int) cdef longlong_return f(long long) def short_binop(short val): """ Arithmetic in C is always done with at least int precision. >>> print(short_binop(3)) int called """ assert typeof(val + val) == "int", typeof(val + val) assert typeof(val - val) == "int", typeof(val - val) assert typeof(val & val) == "int", typeof(val & val) cdef int_return x = f(val + val) return x.msg.decode('ASCII') def short_unnop(short val): """ Arithmetic in C is always done with at least int precision. >>> print(short_unnop(3)) int called """ cdef int_return x = f(-val) return x.msg.decode('ASCII') def longlong_binop(long long val): """ >>> print(longlong_binop(3)) long long called """ cdef longlong_return x = f(val * val) return x.msg.decode('ASCII') def longlong_unnop(long long val): """ >>> print(longlong_unnop(3)) long long called """ cdef longlong_return x = f(~val) return x.msg.decode('ASCII') def test_bint(bint a): """ >>> test_bint(True) """ assert typeof(a + a) == "int", typeof(a + a) assert typeof(a & a) == "bint", typeof(a & a) Cython-0.23.4/tests/run/argument_unpacking_closure_T736.py0000644000175600017570000000102612606202452024663 0ustar jenkinsjenkins00000000000000# mode: run # ticket: 736 # tag: default arguments, closure def default_args_for_closure(a=1, b=2): """ >>> default_args_for_closure()() (1, 2) >>> default_args_for_closure(1, 2)() (1, 2) >>> default_args_for_closure(2)() (2, 2) >>> default_args_for_closure(8,9)() (8, 9) >>> default_args_for_closure(7, b=6)() (7, 6) >>> default_args_for_closure(a=5, b=4)() (5, 4) >>> default_args_for_closure(b=5, a=6)() (6, 5) """ def func(): return a,b return func Cython-0.23.4/tests/run/args_unpacking_in_closure_T658.pyx0000644000175600017570000000053312606202452024660 0ustar jenkinsjenkins00000000000000# mode: run # tag: closures # ticket: 658 def outer(int x, *args, **kwargs): """ >>> inner = outer(1, 2, a=3) >>> inner() (1, (2,), {'a': 3}) >>> inner = outer('abc', 2, a=3) Traceback (most recent call last): TypeError: an integer is required """ def inner(): return x, args, kwargs return inner Cython-0.23.4/tests/run/argerrors.py0000644000175600017570000000504212606202452020533 0ustar jenkinsjenkins00000000000000# mode: run # tag: kwargs, argument unpacking # This test validates the error handling in the different specialised # code paths of the argument unpacking code. The have-kwargs and # no-kwargs branches take different paths, so we always test with and # without a keyword dict (even if it's empty). def test_single_arg(a): """ >>> test_single_arg(1) 1 >>> test_single_arg(1, **{}) 1 >>> test_single_arg() # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> test_single_arg(1,2) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> test_single_arg(1,2, **{}) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> test_single_arg(**{}) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> test_single_arg(*(), **{}) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> test_single_arg(**{'b':2}) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> test_single_arg(**{'a':1, 'b':2}) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... """ return a def test_two_args(a,b): """ >>> test_two_args(1,2) (1, 2) >>> test_two_args(1,2, **{}) (1, 2) >>> test_two_args(1,**{'b':2}) (1, 2) >>> test_two_args(**{'a':1, 'b':2}) (1, 2) >>> test_two_args() # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> test_two_args(1) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> test_two_args(1, **{}) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> test_two_args(1,2,3) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> test_two_args(1,2,3, **{}) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> test_two_args(**{}) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> test_two_args(*(), **{}) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> test_two_args(**{'a':1}) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... >>> test_two_args(**{'a':1, 'b':2, 'c':3}) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... """ return a,b Cython-0.23.4/tests/run/argdefault.pyx0000644000175600017570000000275312606202452021041 0ustar jenkinsjenkins00000000000000GLB0 = (1, 2) def f0(arg=GLB0): """ >>> f0() (1, 2) """ return arg def g0(arg=(1, 2)): """ >>> g0() (1, 2) """ return arg GLB1 = [1, 2] def f1(arg=GLB1): """ >>> f1() [1, 2] """ return arg def g1(arg=[1, 2]): """ >>> g1() [1, 2] """ return arg cdef GLB2 = {1: 2} def f2(arg=GLB2): """ >>> f2() {1: 2} """ return arg def g2(arg={1: 2}): """ >>> g2() {1: 2} """ return arg class Foo(object): pass cdef GLB3 = Foo() def f3(arg=GLB3): """ >>> f3() #doctest: +ELLIPSIS """ return arg def g3(arg=Foo()): """ >>> g3() #doctest: +ELLIPSIS """ return arg cdef class Bar: pass cdef Bar GLB4 = Bar() def f4(arg=GLB4): """ >>> f4() #doctest: +ELLIPSIS """ return arg def g4(arg=Bar()): """ >>> g4() #doctest: +ELLIPSIS """ return arg cdef class Bla: pass cdef Bla GLB5 = Bla() def f5(Bla arg=GLB5): """ >>> f5() #doctest: +ELLIPSIS """ return arg def g5(Bla arg=Bla()): """ >>> g5() #doctest: +ELLIPSIS """ return arg cdef int GLB6 = 7 def f6(int arg=GLB6): """ >>> f6() 7 """ return arg def g6(int arg=7): """ >>> g6() 7 """ return arg Cython-0.23.4/tests/run/arg_incref.pyx0000644000175600017570000000027112606202452021013 0ustar jenkinsjenkins00000000000000def f(dict d, x=4): """ >>> f({1:1, 2:2}) [1, 2] """ cdef dict d_new = {} l = [] for k in d: d = d_new l.append(k) l.sort() return l Cython-0.23.4/tests/run/append.pyx0000644000175600017570000000312212606202452020161 0ustar jenkinsjenkins00000000000000class A: def append(self, x): print u"appending", x return x class B(list): def append(self, *args): for arg in args: list.append(self, arg) cdef class C: """ >>> c = C(100) appending 100 """ def __init__(self, value): self.append(value) cdef append(self, value): print u"appending", value return value def test_append(L): """ >>> test_append([]) None None None got error [1, 2, (3, 4)] >>> _ = test_append(A()) appending 1 1 appending 2 2 appending (3, 4) (3, 4) got error >>> test_append(B()) None None None None [1, 2, (3, 4), 5, 6] """ print L.append(1) print L.append(2) print L.append((3,4)) try: print L.append(5,6) except TypeError: print u"got error" return L def test_append_typed(list L not None): """ >>> test_append_typed([]) None None [1, 2, (3, 4)] """ print L.append(1) L.append(2) print L.append((3,4)) return L def append_unused_retval(L): """ >>> append_unused_retval([]) got error [1, 2, (3, 4)] >>> _ = append_unused_retval(A()) appending 1 appending 2 appending (3, 4) got error >>> append_unused_retval(B()) [1, 2, (3, 4), 5, 6] """ L.append(1) L.append(2) L.append((3,4)) try: L.append(5,6) except TypeError: print u"got error" return L def method_name(): """ >>> method_name() 'append' """ return [].append.__name__ Cython-0.23.4/tests/run/any.pyx0000644000175600017570000001245112606202452017506 0ustar jenkinsjenkins00000000000000 cdef class VerboseGetItem(object): cdef object sequence def __init__(self, seq): self.sequence = seq def __getitem__(self, i): print i return self.sequence[i] # may raise IndexError cimport cython @cython.test_assert_path_exists("//SimpleCallNode") @cython.test_fail_if_path_exists("//ForInStatNode") def any_item(x): """ >>> any_item([0,0,1,0,0]) True >>> any_item([0,0,0,0,1]) True >>> any_item([0,0,0,0,0]) False >>> any(VerboseGetItem([0,0,1,0,0])) 0 1 2 True >>> any_item(VerboseGetItem([0,0,1,0,0])) 0 1 2 True >>> any(VerboseGetItem([0,0,0,0,0])) 0 1 2 3 4 5 False >>> any_item(VerboseGetItem([0,0,0,0,0])) 0 1 2 3 4 5 False """ return any(x) @cython.test_assert_path_exists( "//ForInStatNode", "//InlinedGeneratorExpressionNode" ) @cython.test_fail_if_path_exists( "//SimpleCallNode", "//YieldExprNode" ) def any_in_simple_gen(seq): """ >>> any_in_simple_gen([0,1,0]) True >>> any_in_simple_gen([0,0,0]) False >>> any_in_simple_gen(VerboseGetItem([0,0,1,0,0])) 0 1 2 True >>> any_in_simple_gen(VerboseGetItem([0,0,0,0,0])) 0 1 2 3 4 5 False """ return any(x for x in seq) @cython.test_assert_path_exists( "//ForInStatNode", "//InlinedGeneratorExpressionNode" ) @cython.test_fail_if_path_exists( "//SimpleCallNode", "//YieldExprNode" ) def any_in_simple_gen_scope(seq): """ >>> any_in_simple_gen_scope([0,1,0]) True >>> any_in_simple_gen_scope([0,0,0]) False >>> any_in_simple_gen_scope(VerboseGetItem([0,0,1,0,0])) 0 1 2 True >>> any_in_simple_gen_scope(VerboseGetItem([0,0,0,0,0])) 0 1 2 3 4 5 False """ x = 'abc' result = any(x for x in seq) assert x == 'abc' return result @cython.test_assert_path_exists( "//ForInStatNode", "//InlinedGeneratorExpressionNode" ) @cython.test_fail_if_path_exists( "//SimpleCallNode", "//YieldExprNode" ) def any_in_conditional_gen(seq): """ >>> any_in_conditional_gen([3,6,9]) False >>> any_in_conditional_gen([0,3,7]) True >>> any_in_conditional_gen([1,0,1]) True >>> any_in_conditional_gen(VerboseGetItem([0,0,3,0,0])) 0 1 2 3 4 5 False >>> any_in_conditional_gen(VerboseGetItem([0,3,0,1,1])) 0 1 2 3 True """ return any(x%3 for x in seq if x%2 == 1) mixed_ustring = u'AbcDefGhIjKlmnoP' lower_ustring = mixed_ustring.lower() upper_ustring = mixed_ustring.upper() @cython.test_assert_path_exists( '//PythonCapiCallNode', '//ForFromStatNode', "//InlinedGeneratorExpressionNode" ) @cython.test_fail_if_path_exists( '//SimpleCallNode', '//ForInStatNode' ) def any_lower_case_characters(unicode ustring): """ >>> any_lower_case_characters(upper_ustring) False >>> any_lower_case_characters(mixed_ustring) True >>> any_lower_case_characters(lower_ustring) True """ return any(uchar.islower() for uchar in ustring) @cython.test_assert_path_exists( "//ForInStatNode", "//InlinedGeneratorExpressionNode", "//InlinedGeneratorExpressionNode//IfStatNode" ) @cython.test_fail_if_path_exists( "//SimpleCallNode", "//YieldExprNode", # "//IfStatNode//CoerceToBooleanNode" ) def any_in_typed_gen(seq): """ >>> any_in_typed_gen([0,1,0]) True >>> any_in_typed_gen([0,0,0]) False >>> any_in_typed_gen(VerboseGetItem([0,0,1,0,0])) 0 1 2 True >>> any_in_typed_gen(VerboseGetItem([0,0,0,0,0])) 0 1 2 3 4 5 False """ cdef int x return any(x for x in seq) @cython.test_assert_path_exists( "//ForInStatNode", "//InlinedGeneratorExpressionNode", "//InlinedGeneratorExpressionNode//IfStatNode" ) @cython.test_fail_if_path_exists( "//SimpleCallNode", "//YieldExprNode" ) def any_in_gen_builtin_name(seq): """ >>> any_in_gen_builtin_name([0,1,0]) True >>> any_in_gen_builtin_name([0,0,0]) False >>> any_in_gen_builtin_name(VerboseGetItem([0,0,1,0,0])) 0 1 2 True >>> any_in_gen_builtin_name(VerboseGetItem([0,0,0,0,0])) 0 1 2 3 4 5 False """ return any(type for type in seq) @cython.test_assert_path_exists( "//ForInStatNode", "//InlinedGeneratorExpressionNode", "//InlinedGeneratorExpressionNode//IfStatNode" ) @cython.test_fail_if_path_exists( "//SimpleCallNode", "//YieldExprNode", # "//IfStatNode//CoerceToBooleanNode" ) def any_in_double_gen(seq): """ >>> any(x for L in [[0,0,0],[0,0,1],[0,0,0]] for x in L) True >>> any_in_double_gen([[0,0,0],[0,0,1],[0,0,0]]) True >>> any(x for L in [[0,0,0],[0,0,0],[0,0,0]] for x in L) False >>> any_in_double_gen([[0,0,0],[0,0,0],[0,0,0]]) False >>> any_in_double_gen([VerboseGetItem([0,0,0]), VerboseGetItem([0,0,1,0,0])]) 0 1 2 3 0 1 2 True >>> any_in_double_gen([VerboseGetItem([0,0,0]),VerboseGetItem([0,0]),VerboseGetItem([0,0,0])]) 0 1 2 3 0 1 2 0 1 2 3 False """ cdef int x return any(x for L in seq for x in L) Cython-0.23.4/tests/run/anonymousenum.pyx0000644000175600017570000000014112606202452021625 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> p 42 """ cdef enum: spam = 42 grail = 17 cdef int i i = spam p = i Cython-0.23.4/tests/run/annotation_typing.pyx0000644000175600017570000000357712606202452022474 0ustar jenkinsjenkins00000000000000# cython: annotation_typing=True from cython cimport typeof def pytypes_def(a: list, b: "int" = 2, c: {'ctype': 'long int'} = 3, d: {'type': 'float'} = 4) -> list: """ >>> pytypes_def([1]) ('list object', 'int', 'long', 'float') [1, 2, 3, 4.0] >>> pytypes_def([1], 3) ('list object', 'int', 'long', 'float') [1, 3, 3, 4.0] >>> pytypes_def(123) Traceback (most recent call last): TypeError: Argument 'a' has incorrect type (expected list, got int) """ print(typeof(a), typeof(b), typeof(c), typeof(d)) a.append(b) a.append(c) a.append(d) return a cpdef pytypes_cpdef(a: list, b: "int" = 2, c: {'ctype': 'long int'} = 3, d: {'type': 'float'} = 4): """ >>> pytypes_cpdef([1]) ('list object', 'int', 'long', 'float') [1, 2, 3, 4.0] >>> pytypes_cpdef([1], 3) ('list object', 'int', 'long', 'float') [1, 3, 3, 4.0] >>> pytypes_cpdef(123) Traceback (most recent call last): TypeError: Argument 'a' has incorrect type (expected list, got int) """ print(typeof(a), typeof(b), typeof(c), typeof(d)) a.append(b) a.append(c) a.append(d) return a cdef c_pytypes_cdef(a: list, b: "int" = 2, c: {'ctype': 'long int'} = 3, d: {'type': 'float'} = 4): print(typeof(a), typeof(b), typeof(c), typeof(d)) a.append(b) a.append(c) a.append(d) return a def pytypes_cdef(a, b=2, c=3, d=4): """ >>> pytypes_cdef([1]) ('list object', 'int', 'long', 'float') [1, 2, 3, 4.0] >>> pytypes_cdef([1], 3) ('list object', 'int', 'long', 'float') [1, 3, 3, 4.0] >>> pytypes_cdef(123) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: ... """ return c_pytypes_cdef(a, b, c, d) def return_tuple_for_carray() -> tuple: """ >>> return_tuple_for_carray() (1, 2, 3) """ cdef int[3] x x = [1, 2, 3] return x Cython-0.23.4/tests/run/and.pyx0000644000175600017570000000255112606202452017461 0ustar jenkinsjenkins00000000000000a,b = 'a *','b *' # use non-interned strings def and2_assign(a,b): """ >>> a,b = 'a *','b *' # use non-interned strings >>> and2_assign(2,3) == (2 and 3) True >>> and2_assign('a', 'b') == ('a' and 'b') True >>> and2_assign(a, b) == (a and b) True """ c = a and b return c def and2(a,b): """ >>> and2(2,3) == (2 and 3) True >>> and2(0,2) == (0 and 2) True >>> and2('a', 'b') == ('a' and 'b') True >>> and2(a, b) == (a and b) True >>> and2('', 'b') == ('' and 'b') True >>> and2([], [1]) == ([] and [1]) True >>> and2([], [a]) == ([] and [a]) True """ return a and b def and3(a,b,c): """ >>> and3(0,1,2) == (0 and 1 and 2) True >>> and3([],(),[1]) == ([] and () and [1]) True """ d = a and b and c return d def and2_no_result(a,b): """ >>> and2_no_result(2,3) >>> and2_no_result(0,2) >>> and2_no_result('a','b') >>> and2_no_result(a,b) >>> a and b 'b *' """ a and b def and2_literal(): """ >>> and2_literal() 5 """ return True and 5 def c_int_results(int x): """ >>> c_int_results(7) (0, 0) >>> c_int_results(5) (1, 1) """ cdef int expr1, expr2, r1, r2 expr1 = x == 5 expr2 = 1 r1 = expr1 and expr2 r2 = (x==5) and 1 return r1, r2 Cython-0.23.4/tests/run/always_allow_keywords_T295.pyx0000644000175600017570000000241012606202452024061 0ustar jenkinsjenkins00000000000000# ticket: 295 cimport cython def func1(arg): """ >>> func1(None) >>> func1(*[None]) >>> func1(arg=None) Traceback (most recent call last): ... TypeError: func1() takes no keyword arguments """ pass @cython.always_allow_keywords(False) def func2(arg): """ >>> func2(None) >>> func2(*[None]) >>> func2(arg=None) Traceback (most recent call last): ... TypeError: func2() takes no keyword arguments """ pass @cython.always_allow_keywords(True) def func3(arg): """ >>> func3(None) >>> func3(*[None]) >>> func3(arg=None) """ pass cdef class A: """ >>> A().meth1(None) >>> A().meth1(*[None]) >>> A().meth1(arg=None) Traceback (most recent call last): ... TypeError: meth1() takes no keyword arguments >>> A().meth2(None) >>> A().meth2(*[None]) >>> A().meth2(arg=None) Traceback (most recent call last): ... TypeError: meth2() takes no keyword arguments >>> A().meth3(None) >>> A().meth3(*[None]) >>> A().meth3(arg=None) """ def meth1(self, arg): pass @cython.always_allow_keywords(False) def meth2(self, arg): pass @cython.always_allow_keywords(True) def meth3(self, arg): pass Cython-0.23.4/tests/run/altet2.pyx0000644000175600017570000000032512606202452020107 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> iter(C()) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError: iter() returned non-iterator... """ cdef class C: def __iter__(self): "This is a doc string." Cython-0.23.4/tests/run/all.pyx0000644000175600017570000001165312606202452017472 0ustar jenkinsjenkins00000000000000 cdef class VerboseGetItem(object): cdef object sequence def __init__(self, seq): self.sequence = seq def __getitem__(self, i): print i return self.sequence[i] # may raise IndexError cimport cython @cython.test_assert_path_exists("//SimpleCallNode") @cython.test_fail_if_path_exists("//ForInStatNode") def all_item(x): """ >>> all_item([1,1,1,1,1]) True >>> all_item([1,1,1,1,0]) False >>> all_item([0,1,1,1,0]) False >>> all(VerboseGetItem([1,1,1,0,0])) 0 1 2 3 False >>> all_item(VerboseGetItem([1,1,1,0,0])) 0 1 2 3 False >>> all(VerboseGetItem([1,1,1,1,1])) 0 1 2 3 4 5 True >>> all_item(VerboseGetItem([1,1,1,1,1])) 0 1 2 3 4 5 True """ return all(x) @cython.test_assert_path_exists( "//ForInStatNode", "//InlinedGeneratorExpressionNode" ) @cython.test_fail_if_path_exists( "//SimpleCallNode", "//YieldExprNode" ) def all_in_simple_gen(seq): """ >>> all_in_simple_gen([1,1,1]) True >>> all_in_simple_gen([1,1,0]) False >>> all_in_simple_gen([1,0,1]) False >>> all_in_simple_gen(VerboseGetItem([1,1,1,1,1])) 0 1 2 3 4 5 True >>> all_in_simple_gen(VerboseGetItem([1,1,0,1,1])) 0 1 2 False """ return all(x for x in seq) @cython.test_assert_path_exists( "//ForInStatNode", "//InlinedGeneratorExpressionNode" ) @cython.test_fail_if_path_exists( "//SimpleCallNode", "//YieldExprNode" ) def all_in_simple_gen_scope(seq): """ >>> all_in_simple_gen_scope([1,1,1]) True >>> all_in_simple_gen_scope([1,1,0]) False >>> all_in_simple_gen_scope([1,0,1]) False >>> all_in_simple_gen_scope(VerboseGetItem([1,1,1,1,1])) 0 1 2 3 4 5 True >>> all_in_simple_gen_scope(VerboseGetItem([1,1,0,1,1])) 0 1 2 False """ x = 'abc' result = all(x for x in seq) assert x == 'abc' return result @cython.test_assert_path_exists( "//ForInStatNode", "//InlinedGeneratorExpressionNode" ) @cython.test_fail_if_path_exists( "//SimpleCallNode", "//YieldExprNode" ) def all_in_conditional_gen(seq): """ >>> all_in_conditional_gen([3,6,9]) False >>> all_in_conditional_gen([0,3,7]) False >>> all_in_conditional_gen([1,0,1]) True >>> all_in_conditional_gen(VerboseGetItem([1,1,1,1,1])) 0 1 2 3 4 5 True >>> all_in_conditional_gen(VerboseGetItem([1,1,0,1,1])) 0 1 2 3 4 5 True """ return all(x%3 for x in seq if x%2 == 1) mixed_ustring = u'AbcDefGhIjKlmnoP' lower_ustring = mixed_ustring.lower() upper_ustring = mixed_ustring.upper() @cython.test_assert_path_exists( '//PythonCapiCallNode', '//ForFromStatNode' ) @cython.test_fail_if_path_exists( '//SimpleCallNode', '//ForInStatNode' ) def all_lower_case_characters(unicode ustring): """ >>> all_lower_case_characters(mixed_ustring) False >>> all_lower_case_characters(upper_ustring) False >>> all_lower_case_characters(lower_ustring) True """ return all(uchar.islower() for uchar in ustring) @cython.test_assert_path_exists( "//ForInStatNode", "//InlinedGeneratorExpressionNode", "//InlinedGeneratorExpressionNode//IfStatNode" ) @cython.test_fail_if_path_exists( "//SimpleCallNode", "//YieldExprNode", # "//IfStatNode//CoerceToBooleanNode" ) def all_in_typed_gen(seq): """ >>> all_in_typed_gen([1,1,1]) True >>> all_in_typed_gen([1,0,0]) False >>> all_in_typed_gen(VerboseGetItem([1,1,1,1,1])) 0 1 2 3 4 5 True >>> all_in_typed_gen(VerboseGetItem([1,1,1,1,0])) 0 1 2 3 4 False """ cdef int x return all(x for x in seq) @cython.test_assert_path_exists( "//ForInStatNode", "//InlinedGeneratorExpressionNode", "//InlinedGeneratorExpressionNode//IfStatNode" ) @cython.test_fail_if_path_exists( "//SimpleCallNode", "//YieldExprNode", # "//IfStatNode//CoerceToBooleanNode" ) def all_in_double_gen(seq): """ >>> all(x for L in [[1,1,1],[1,1,1],[1,1,1]] for x in L) True >>> all_in_double_gen([[1,1,1],[1,1,1],[1,1,1]]) True >>> all(x for L in [[1,1,1],[1,1,1],[1,1,0]] for x in L) False >>> all_in_double_gen([[1,1,1],[1,1,1],[1,1,0]]) False >>> all(x for L in [[1,1,1],[0,1,1],[1,1,1]] for x in L) False >>> all_in_double_gen([[1,1,1],[0,1,1],[1,1,1]]) False >>> all_in_double_gen([VerboseGetItem([1,1,1]), VerboseGetItem([1,1,1,1,1])]) 0 1 2 3 0 1 2 3 4 5 True >>> all_in_double_gen([VerboseGetItem([1,1,1]),VerboseGetItem([1,1]),VerboseGetItem([1,1,0])]) 0 1 2 3 0 1 2 0 1 2 False """ cdef int x return all(x for L in seq for x in L) Cython-0.23.4/tests/run/addressof.pyx0000644000175600017570000000020112606202452020657 0ustar jenkinsjenkins00000000000000def f(int a): """ >>> f(5) 5 """ cdef int i,j cdef int *p i = a p = &i j = p[0] return j Cython-0.23.4/tests/run/addop.pyx0000644000175600017570000000605012606202452020004 0ustar jenkinsjenkins00000000000000cimport cython def bigint(x): print(str(x).rstrip('L')) def mixed_test(): """ >>> mixed_test() (30, 22) """ cdef int int1, int2, int3 cdef char *ptr1, *ptr2 = "test", *ptr3 = "toast" int2 = 10 int3 = 20 obj1 = 1 obj2 = 2 obj3 = 3 int1 = int2 + int3 ptr1 = ptr2 + int3 ptr1 = int2 + ptr3 obj1 = obj2 + int3 return int1, obj1 @cython.test_fail_if_path_exists('//AddNode') def add_x_1(x): """ >>> add_x_1(0) 1 >>> add_x_1(1) 2 >>> add_x_1(-1) 0 >>> bigint(2**50 + 1) 1125899906842625 >>> bigint(add_x_1(2**50)) 1125899906842625 >>> add_x_1(1.5) 2.5 >>> add_x_1(-1.5) -0.5 >>> try: add_x_1("abc") ... except TypeError: pass """ return x + 1 @cython.test_fail_if_path_exists('//AddNode') def add_x_1f(x): """ >>> add_x_1f(0) 1.0 >>> add_x_1f(1) 2.0 >>> add_x_1f(-1) 0.0 >>> add_x_1f(1.5) 2.5 >>> add_x_1f(-1.5) -0.5 >>> try: add_x_1f("abc") ... except TypeError: pass """ return x + 1.0 @cython.test_fail_if_path_exists('//AddNode') def add_x_large(x): """ >>> add_x_large(0) 1073741824 >>> add_x_large(1) 1073741825 >>> add_x_large(-1) 1073741823 >>> add_x_large(1.5) 1073741825.5 >>> add_x_large(-2.0**31) -1073741824.0 >>> bigint(add_x_large(2**30 + 1)) 2147483649 >>> bigint(2**50 + 1 + 2**30) 1125900980584449 >>> bigint(add_x_large(2**50 + 1)) 1125900980584449 >>> bigint(2**31 + 2**30) 3221225472 >>> bigint(add_x_large(2**31)) 3221225472 >>> bigint(2**66 + 2**30) 73786976295911948288 >>> bigint(add_x_large(2**66)) 73786976295911948288 >>> try: add_x_large("abc") ... except TypeError: pass """ return x + 2**30 @cython.test_fail_if_path_exists('//AddNode') def add_1_x(x): """ >>> add_1_x(0) 1 >>> add_1_x(1) 2 >>> add_1_x(-1) 0 >>> bigint(2**50 + 1) 1125899906842625 >>> bigint(add_1_x(2**50)) 1125899906842625 >>> add_1_x(1.5) 2.5 >>> add_1_x(-1.5) -0.5 >>> try: add_1_x("abc") ... except TypeError: pass """ return 1 + x @cython.test_fail_if_path_exists('//AddNode') def add_1f_x(x): """ >>> add_1f_x(0) 1.0 >>> add_1f_x(1) 2.0 >>> add_1f_x(-1) 0.0 >>> 1.0 + 2**52 4503599627370497.0 >>> add_1f_x(2**52) 4503599627370497.0 >>> add_1f_x(2**60) == 1.0 + 2**60 or add_1f_x(2**60) True >>> add_1f_x(1.5) 2.5 >>> add_1f_x(-1.5) -0.5 >>> try: add_1f_x("abc") ... except TypeError: pass """ return 1.0 + x @cython.test_fail_if_path_exists('//AddNode') def add_large_x(x): """ >>> add_large_x(0) 1073741824 >>> add_large_x(1) 1073741825 >>> add_large_x(-1) 1073741823 >>> add_large_x(1.5) 1073741825.5 >>> add_large_x(-2.0**30) 0.0 >>> add_large_x(-2.0**31) -1073741824.0 >>> try: add_large_x("abc") ... except TypeError: pass """ return 2**30 + x Cython-0.23.4/tests/run/addloop.pyx0000644000175600017570000000100012606202452020325 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> x = 1 >>> for i in range(10): ... x = x + i >>> x 46 """ def add_pyrange(max): """ >>> add_pyrange(10) 46 """ x = 1 for i in range(max): x = x + i return x def add_py(max): """ >>> add_py(10) 46 """ x = 1 for i from 0 <= i < max: x = x + i return x def add_c(max): """ >>> add_c(10) 46 """ cdef int x,i x = 1 for i from 0 <= i < max: x = x + i return x Cython-0.23.4/tests/run/absolute_import.srctree0000644000175600017570000000263412606202452022760 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import pkg.my_test_module" PYTHON -c "import pkg.b; pkg.b.test_reimport()" PYTHON -c "import pkg.c; pkg.c.test_reimport()" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize("**/*.pyx"), ) ######## pkg/__init__.py ######## ######## pkg/a_module.pyx ######## ######## pkg/my_test_module.pyx ######## import sys from . import a_module assert a_module in sys.modules.values(), list(sys.modules) assert sys.modules['pkg.a_module'] is a_module, list(sys.modules) ######## pkg/b.pyx ######## from __future__ import absolute_import import sys try: import my_test_module except ImportError: pass else: assert "expected ImportError on absolute import" import pkg.my_test_module assert pkg.my_test_module in sys.modules.values(), list(sys.modules) assert sys.modules['pkg.my_test_module'] is pkg.my_test_module, list(sys.modules) def test_reimport(): import pkg.my_test_module as mod assert pkg.my_test_module is mod ######## pkg/c.pyx ######## from __future__ import absolute_import import sys from pkg import my_test_module assert my_test_module in sys.modules.values(), list(sys.modules) assert sys.modules['pkg.my_test_module'] is my_test_module, list(sys.modules) def test_reimport(): from pkg import my_test_module as mod assert my_test_module is mod Cython-0.23.4/tests/run/__getattribute_subclasses__.pyx0000644000175600017570000000663512606202452024454 0ustar jenkinsjenkins00000000000000__doc__ = u""" __getattribute__ and __getattr__ special methods and subclasses. getattr does not override members. >>> a = getattr_boring() >>> a.boring_member 10 >>> print(a.resolved_by) getattr_boring getattribute does. >>> a = getattribute_boring() >>> a.boring_member Traceback (most recent call last): AttributeError >>> print(a.resolved_by) getattribute_boring Is inherited. >>> a = boring_boring_getattribute() >>> a.boring_getattribute_member Traceback (most recent call last): AttributeError >>> a.boring_boring_getattribute_member Traceback (most recent call last): AttributeError >>> print(a.resolved_by) _getattribute __getattribute__ is always tried first, then __getattr__, regardless of where in the inheritance hiarchy they came from. >>> a = getattribute_boring_boring_getattr() >>> a.foo Traceback (most recent call last): AttributeError >>> print(a.resolved_by) getattribute_boring_boring_getattr >>> a.getattribute_boring_boring_getattr True >>> a._getattr True >>> a = getattr_boring_boring_getattribute() >>> a.foo Traceback (most recent call last): AttributeError >>> print(a.resolved_by) _getattribute >>> a.getattr_boring_boring_getattribute True >>> a._getattribute True """ cdef class boring: cdef readonly int boring_member def __init__(self): self.boring_member = 10 cdef class getattr_boring(boring): def __getattr__(self,n): if n == u'resolved_by': return u'getattr_boring' elif n == u'getattr_boring': return True else: raise AttributeError cdef class getattribute_boring(boring): def __getattribute__(self,n): if n == u'resolved_by': return u'getattribute_boring' elif n == u'getattribute_boring': return True else: raise AttributeError cdef class _getattr: def __getattr__(self,n): if n == u'resolved_by': return u'_getattr' elif n == u'_getattr': return True else: raise AttributeError cdef class _getattribute(boring): def __getattribute__(self,n): if n == u'resolved_by': return u'_getattribute' elif n == u'_getattribute': return True else: raise AttributeError cdef class boring_getattribute(_getattribute): cdef readonly int boring_getattribute_member cdef class boring_boring_getattribute(boring_getattribute): cdef readonly int boring_boring_getattribute_member cdef class boring_getattr(_getattr): cdef readonly int boring_getattr_member cdef class boring_boring_getattr(boring_getattr): cdef readonly int boring_boring_getattr_member cdef class getattribute_boring_boring_getattr(boring_boring_getattr): def __getattribute__(self,n): if n == u'resolved_by': return u'getattribute_boring_boring_getattr' elif n == u'getattribute_boring_boring_getattr': return True else: raise AttributeError cdef class getattr_boring_boring_getattribute(boring_boring_getattribute): def __getattr__(self,n): if n == u'resolved_by': return u'getattr_boring_boring_getattribute' elif n == u'getattr_boring_boring_getattribute': return True else: raise AttributeError Cython-0.23.4/tests/run/__getattribute__.pyx0000644000175600017570000000237012606202452022215 0ustar jenkinsjenkins00000000000000__doc__ = u""" __getattribute__ and __getattr__ special methods for a single class. """ cdef class just_getattribute: """ >>> a = just_getattribute() >>> a.bar 'bar' >>> a.invalid Traceback (most recent call last): AttributeError """ def __getattribute__(self,n): if n == 'bar': return n else: raise AttributeError cdef class just_getattr: """ >>> a = just_getattr() >>> a.foo 10 >>> a.bar 'bar' >>> a.invalid Traceback (most recent call last): AttributeError """ cdef readonly int foo def __init__(self): self.foo = 10 def __getattr__(self,n): if n == 'bar': return n else: raise AttributeError cdef class both: """ >>> a = both() >>> a.foo 10 >>> a.bar 'bar' >>> a.invalid Traceback (most recent call last): AttributeError """ cdef readonly int foo def __init__(self): self.foo = 10 def __getattribute__(self,n): if n == 'foo': return self.foo else: raise AttributeError def __getattr__(self,n): if n == 'bar': return n else: raise AttributeError Cython-0.23.4/tests/run/__debug__.srctree0000644000175600017570000000311112606202452021421 0ustar jenkinsjenkins00000000000000""" PYTHON setup.py build_ext -i PYTHON debug_test.py PYTHON -O debug_test.py PYTHON -OO debug_test.py """ ######## setup.py ######## from distutils.core import setup from Cython.Build import cythonize setup(ext_modules = cythonize('debug_test_cython.pyx')) ######## debug_test.py ######## if __debug__: DBG = True else: DBG = False import sys try: optimised = bool(sys.flags.optimize) except AttributeError: # Py2.[45] optimised = eval('not __debug__') if DBG == optimised: raise RuntimeError( "PYTHON: unexpected debug value %s, expected %s" % ( DBG, optimised)) ASSERT_CALLED = False def sideeffect(): global ASSERT_CALLED ASSERT_CALLED = True return True assert sideeffect() if ASSERT_CALLED == optimised: raise RuntimeError("Assert called in optimised Python run") import debug_test_cython if debug_test_cython.DBG == optimised: raise RuntimeError( "CYTHON: unexpected debug value %s, expected %s" % ( debug_test_cython.DBG, optimised)) ######## debug_test_cython.pyx ######## if __debug__: DBG = True else: DBG = False import sys try: optimised = bool(sys.flags.optimize) except AttributeError: # Py2.[45] optimised = eval('not __debug__') ASSERT_CALLED = False def sideeffect(): global ASSERT_CALLED ASSERT_CALLED = True return True if DBG == optimised: raise RuntimeError("Unexpected debug value %s, expected %s" % ( DBG, optimised)) assert sideeffect() if ASSERT_CALLED == optimised: raise RuntimeError("Assert called in optimised Python run") Cython-0.23.4/tests/run/includes/0000755000175600017570000000000012606202455017763 5ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/run/includes/indirect_d.pxd0000644000175600017570000000002112606202452022572 0ustar jenkinsjenkins00000000000000from d cimport d Cython-0.23.4/tests/run/includes/includefile.pxi0000644000175600017570000000004612606202452022765 0ustar jenkinsjenkins00000000000000# this file will be included XYZ = 5 Cython-0.23.4/tests/run/includes/e.h0000644000175600017570000000001412606202452020350 0ustar jenkinsjenkins00000000000000int e = d+1;Cython-0.23.4/tests/run/includes/d.pxd0000644000175600017570000000004712606202452020721 0ustar jenkinsjenkins00000000000000cdef extern from "d.h": cdef int d Cython-0.23.4/tests/run/includes/d.h0000644000175600017570000000001412606202452020347 0ustar jenkinsjenkins00000000000000int d = c+1;Cython-0.23.4/tests/run/includes/c.h0000644000175600017570000000001412606202452020346 0ustar jenkinsjenkins00000000000000int c = b+1;Cython-0.23.4/tests/run/includes/b.pxd0000644000175600017570000000004712606202452020717 0ustar jenkinsjenkins00000000000000cdef extern from "b.h": cdef int b Cython-0.23.4/tests/run/includes/b.h0000644000175600017570000000001412606202452020345 0ustar jenkinsjenkins00000000000000int b = a+1;Cython-0.23.4/tests/run/includes/all.pyx0000644000175600017570000000045412606202452021275 0ustar jenkinsjenkins00000000000000__doc__ = """ >>> test() 1, 2, 3, 4, 5 """ # Make sure all of these happen in order. cdef extern from "a.h": cdef int a from b cimport b cdef extern from "c.h": cdef int c cimport indirect_d cdef extern from "e.h": cdef int e def test(): print a, b, c, indirect_d.d, e Cython-0.23.4/tests/run/includes/a.h0000644000175600017570000000001212606202452020342 0ustar jenkinsjenkins00000000000000int a = 1;Cython-0.23.4/tests/pyximport/0000755000175600017570000000000012606202455017424 5ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/pyximport/pyximport_pyimport.srctree0000644000175600017570000000113612606202452025031 0ustar jenkinsjenkins00000000000000 PYTHON -c "import pyimport_test; pyimport_test.test()" ######## pyimport_test.py ######## import os.path import pyximport # blacklist for speed import pyximport.pyxbuild, Cython.Compiler.Pipeline import distutils.core, distutils.ccompiler, distutils.command.build pyximport.install(pyximport=False, pyimport=True, build_dir=os.path.join(os.path.dirname(__file__), "BUILD")) def test(): import mymodule assert mymodule.test_string == "TEST" assert not mymodule.__file__.rstrip('oc').endswith('.py'), mymodule.__file__ ######## mymodule.py ######## test_string = "TEST" Cython-0.23.4/tests/pyximport/pyximport_errors.srctree0000644000175600017570000000134612606202452024465 0ustar jenkinsjenkins00000000000000 PYTHON -c "import pyximport_test; pyximport_test.test()" ######## pyximport_test.py ######## import os.path from contextlib import contextmanager import pyximport pyximport.install(build_dir=os.path.join(os.path.dirname(__file__), "BUILD")) @contextmanager def fails(exc=ImportError): try: yield except exc: pass else: raise RuntimeError("NOT RAISED!") def test(): with fails(): import compiler_error with fails(): import syntax_error with fails(): import runtime_error ######## compiler_error.pyx ######## from __future__ import braces ######## syntax_error.pyx ######## def test { BRACES! } ######## runtime_error.pyx ######## raise ValueError() Cython-0.23.4/tests/pyximport/pyximport_basic.srctree0000644000175600017570000000062512606202452024231 0ustar jenkinsjenkins00000000000000 PYTHON -c "import basic_test; basic_test.test()" ######## basic_test.py ######## import os.path import pyximport pyximport.install(build_dir=os.path.join(os.path.dirname(__file__), "BUILD")) def test(): import mymodule assert mymodule.test_string == "TEST" assert not mymodule.__file__.rstrip('oc').endswith('.py'), mymodule.__file__ ######## mymodule.pyx ######## test_string = "TEST" Cython-0.23.4/tests/memoryview/0000755000175600017570000000000012606202455017554 5ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/memoryview/view_return_errors.pyx0000644000175600017570000000133012606202452024255 0ustar jenkinsjenkins00000000000000# mode: run # tag: memoryview cdef double[:] foo(int i): if i == 1: raise AttributeError('dummy') if i == 2: raise RuntimeError('dummy') if i == 3: raise ValueError('dummy') if i == 4: raise TypeError('dummy') def propagate(i): """ >>> propagate(0) TypeError('Memoryview return value is not initialized') >>> propagate(1) AttributeError('dummy') >>> propagate(2) RuntimeError('dummy') >>> propagate(3) ValueError('dummy') >>> propagate(4) TypeError('dummy') """ try: foo(i) except Exception as e: print '%s(%r)' % (e.__class__.__name__, e.args[0]) else: print 'Exception subclass not raised' Cython-0.23.4/tests/memoryview/transpose_refcount.pyx0000644000175600017570000000122312606202452024234 0ustar jenkinsjenkins00000000000000# mode: run from cython cimport view cdef bint print_upper_right(double[:, :] M): print M[0, 1] cdef class MemViewContainer: cdef double[:, :] A def __init__(self, A): self.A = A cpdef run(self): print_upper_right(self.A) print_upper_right(self.A.T) print_upper_right(self.A.T) def test_transpose_refcount(): """ >>> test_transpose_refcount() 2.0 3.0 3.0 """ cdef double[:, :] A = view.array(shape=(2, 2), itemsize=sizeof(double), format="d") A[0, 0], A[0, 1], A[1, 0], A[1, 1] = 1., 2., 3., 4. cdef MemViewContainer container = MemViewContainer(A) container.run() Cython-0.23.4/tests/memoryview/relaxed_strides.pyx0000644000175600017570000000325712606202452023503 0ustar jenkinsjenkins00000000000000# mode: run # tag: numpy """ Test accepting NumPy arrays with arbitrary strides for zero- or one-sized dimensions. Thanks to Nathaniel Smith and Sebastian Berg. See also: Mailing list threads: http://thread.gmane.org/gmane.comp.python.cython.devel/14762 http://thread.gmane.org/gmane.comp.python.cython.devel/14634 Detailed discussion of the difference between numpy/cython's current definition of "contiguity", and the correct definition: http://thread.gmane.org/gmane.comp.python.cython.devel/14634/focus=14640 The PR implementing NPY_RELAXED_STRIDES_CHECKING: https://github.com/numpy/numpy/pull/3162 Another test case: https://github.com/numpy/numpy/issues/2956 """ import numpy as np numpy_version = np.__version__.split('.')[:2] try: numpy_version = tuple(map(int, numpy_version)) except ValueError: numpy_version = (20, 0) NUMPY_HAS_RELAXED_STRIDES = ( numpy_version < (1, 8) or np.ones((10, 1), order="C").flags.f_contiguous) def test_one_sized(array): """ >>> contig = np.ascontiguousarray(np.arange(10, dtype=np.double)[::100]) >>> test_one_sized(contig)[0] 1.0 >>> a = np.arange(10, dtype=np.double)[::100] >>> if NUMPY_HAS_RELAXED_STRIDES: print(test_one_sized(a)[0]) ... else: print(1.0) 1.0 """ cdef double[::1] a = array a[0] += 1. return array def test_zero_sized(array): """ >>> contig = np.ascontiguousarray(np.arange(10, dtype=np.double)[100:200:10]) >>> _ = test_zero_sized(contig) >>> a = np.arange(10, dtype=np.double)[100:200:10] >>> if NUMPY_HAS_RELAXED_STRIDES: _ = test_zero_sized(a) """ cdef double[::1] a = array return a Cython-0.23.4/tests/memoryview/numpy_memoryview.pyx0000644000175600017570000004162512606202452023756 0ustar jenkinsjenkins00000000000000# tag: numpy # mode: run """ Test slicing for memoryviews and memoryviewslices """ import sys cimport numpy as np import numpy as np cimport cython from cython cimport view include "cythonarrayutil.pxi" include "../buffers/mockbuffers.pxi" ctypedef np.int32_t dtype_t def get_array(): # We need to type our array to get a __pyx_get_buffer() that typechecks # for np.ndarray and calls __getbuffer__ in numpy.pxd cdef np.ndarray[dtype_t, ndim=3] a a = np.arange(8 * 14 * 11, dtype=np.int32).reshape(8, 14, 11) return a a = get_array() def ae(*args): "assert equals" for x in args: if x != args[0]: raise AssertionError(args) __test__ = {} def testcase(f): __test__[f.__name__] = f.__doc__ return f def testcase_numpy_1_5(f): major, minor, *rest = np.__version__.split('.') if (int(major), int(minor)) >= (1, 5): __test__[f.__name__] = f.__doc__ return f # ### Test slicing memoryview slices # @testcase def test_partial_slicing(array): """ >>> test_partial_slicing(a) """ cdef dtype_t[:, :, :] a = array obj = array[4] cdef dtype_t[:, :] b = a[4, :] cdef dtype_t[:, :] c = a[4] ae(b.shape[0], c.shape[0], obj.shape[0]) ae(b.shape[1], c.shape[1], obj.shape[1]) ae(b.strides[0], c.strides[0], obj.strides[0]) ae(b.strides[1], c.strides[1], obj.strides[1]) @testcase def test_ellipsis(array): """ >>> test_ellipsis(a) """ cdef dtype_t[:, :, :] a = array cdef dtype_t[:, :] b = a[..., 4] b_obj = array[..., 4] cdef dtype_t[:, :] c = a[4, ...] c_obj = array[4, ...] cdef dtype_t[:, :] d = a[2:8, ..., 2] d_obj = array[2:8, ..., 2] ae(tuple([b.shape[i] for i in range(2)]), b_obj.shape) ae(tuple([b.strides[i] for i in range(2)]), b_obj.strides) for i in range(b.shape[0]): for j in range(b.shape[1]): ae(b[i, j], b_obj[i, j]) ae(tuple([c.shape[i] for i in range(2)]), c_obj.shape) ae(tuple([c.strides[i] for i in range(2)]), c_obj.strides) for i in range(c.shape[0]): for j in range(c.shape[1]): ae(c[i, j], c_obj[i, j]) ae(tuple([d.shape[i] for i in range(2)]), d_obj.shape) ae(tuple([d.strides[i] for i in range(2)]), d_obj.strides) for i in range(d.shape[0]): for j in range(d.shape[1]): ae(d[i, j], d_obj[i, j]) cdef dtype_t[:] e = a[..., 5, 6] e_obj = array[..., 5, 6] ae(e.shape[0], e_obj.shape[0]) ae(e.strides[0], e_obj.strides[0]) # ### Test slicing memoryview objects # @testcase def test_partial_slicing_memoryview(array): """ >>> test_partial_slicing_memoryview(a) """ cdef dtype_t[:, :, :] _a = array a = _a obj = array[4] b = a[4, :] c = a[4] ae(b.shape[0], c.shape[0], obj.shape[0]) ae(b.shape[1], c.shape[1], obj.shape[1]) ae(b.strides[0], c.strides[0], obj.strides[0]) ae(b.strides[1], c.strides[1], obj.strides[1]) @testcase def test_ellipsis_memoryview(array): """ >>> test_ellipsis_memoryview(a) """ cdef dtype_t[:, :, :] _a = array a = _a b = a[..., 4] b_obj = array[..., 4] c = a[4, ...] c_obj = array[4, ...] d = a[2:8, ..., 2] d_obj = array[2:8, ..., 2] ae(tuple([b.shape[i] for i in range(2)]), b_obj.shape) ae(tuple([b.strides[i] for i in range(2)]), b_obj.strides) for i in range(b.shape[0]): for j in range(b.shape[1]): ae(b[i, j], b_obj[i, j]) ae(tuple([c.shape[i] for i in range(2)]), c_obj.shape) ae(tuple([c.strides[i] for i in range(2)]), c_obj.strides) for i in range(c.shape[0]): for j in range(c.shape[1]): ae(c[i, j], c_obj[i, j]) ae(tuple([d.shape[i] for i in range(2)]), d_obj.shape) ae(tuple([d.strides[i] for i in range(2)]), d_obj.strides) for i in range(d.shape[0]): for j in range(d.shape[1]): ae(d[i, j], d_obj[i, j]) e = a[..., 5, 6] e_obj = array[..., 5, 6] ae(e.shape[0], e_obj.shape[0]) ae(e.strides[0], e_obj.strides[0]) @testcase def test_transpose(): """ >>> test_transpose() 3 4 (3, 4) (3, 4) 11 11 11 11 11 11 """ cdef dtype_t[:, :] a numpy_obj = np.arange(4 * 3, dtype=np.int32).reshape(4, 3) a = numpy_obj a_obj = a cdef dtype_t[:, :] b = a.T print a.T.shape[0], a.T.shape[1] print a_obj.T.shape print numpy_obj.T.shape cdef dtype_t[:, :] c with nogil: c = a.T.T assert ( a).shape == ( c).shape assert ( a).strides == ( c).strides print a[3, 2], a.T[2, 3], a_obj[3, 2], a_obj.T[2, 3], numpy_obj[3, 2], numpy_obj.T[2, 3] @testcase_numpy_1_5 def test_numpy_like_attributes(cyarray): """ For some reason this fails in numpy 1.4, with shape () and strides (40, 8) instead of 20, 4 on my machine. Investigate this. >>> cyarray = create_array(shape=(8, 5), mode="c") >>> test_numpy_like_attributes(cyarray) >>> test_numpy_like_attributes(cyarray.memview) """ numarray = np.asarray(cyarray) assert cyarray.shape == numarray.shape, (cyarray.shape, numarray.shape) assert cyarray.strides == numarray.strides, (cyarray.strides, numarray.strides) assert cyarray.ndim == numarray.ndim, (cyarray.ndim, numarray.ndim) assert cyarray.size == numarray.size, (cyarray.size, numarray.size) assert cyarray.nbytes == numarray.nbytes, (cyarray.nbytes, numarray.nbytes) cdef int[:, :] mslice = numarray assert ( mslice).base is numarray @testcase_numpy_1_5 def test_copy_and_contig_attributes(a): """ >>> a = np.arange(20, dtype=np.int32).reshape(5, 4) >>> test_copy_and_contig_attributes(a) """ cdef np.int32_t[:, :] mslice = a m = mslice # Test object copy attributes assert np.all(a == np.array(m.copy())) assert a.strides == m.strides == m.copy().strides assert np.all(a == np.array(m.copy_fortran())) assert m.copy_fortran().strides == (4, 20) # Test object is_*_contig attributes assert m.is_c_contig() and m.copy().is_c_contig() assert m.copy_fortran().is_f_contig() and not m.is_f_contig() ctypedef int td_cy_int cdef extern from "bufaccess.h": ctypedef td_cy_int td_h_short # Defined as short, but Cython doesn't know this! ctypedef float td_h_double # Defined as double ctypedef unsigned int td_h_ushort # Defined as unsigned short ctypedef td_h_short td_h_cy_short cdef void dealloc_callback(void *data): print "deallocating..." def build_numarray(array array): array.callback_free_data = dealloc_callback return np.asarray(array) def index(array array): print build_numarray(array)[3, 2] @testcase_numpy_1_5 def test_coerce_to_numpy(): """ Test coercion to NumPy arrays, especially with automatically generated format strings. >>> test_coerce_to_numpy() [97, 98, 600, 700, 800] deallocating... (600, 700) deallocating... ((100, 200), (300, 400), 500) deallocating... (97, 900) deallocating... 99 deallocating... 111 deallocating... 222 deallocating... 333 deallocating... 11.1 deallocating... 12.2 deallocating... 13.3 deallocating... (14.4+15.5j) deallocating... (16.6+17.7j) deallocating... (18.8+19.9j) deallocating... 22 deallocating... 33.33 deallocating... 44 deallocating... """ # ### First set up some C arrays that will be used to hold data # cdef MyStruct[20] mystructs cdef SmallStruct[20] smallstructs cdef NestedStruct[20] nestedstructs cdef PackedStruct[20] packedstructs cdef signed char[20] chars cdef short[20] shorts cdef int[20] ints cdef long long[20] longlongs cdef td_h_short[20] externs cdef float[20] floats cdef double[20] doubles cdef long double[20] longdoubles cdef float complex[20] floatcomplex cdef double complex[20] doublecomplex cdef long double complex[20] longdoublecomplex cdef td_h_short[20] h_shorts cdef td_h_double[20] h_doubles cdef td_h_ushort[20] h_ushorts cdef Py_ssize_t idx = 17 # ### Initialize one element in each array # mystructs[idx] = { 'a': 'a', 'b': 'b', 'c': 600, 'd': 700, 'e': 800, } smallstructs[idx] = { 'a': 600, 'b': 700 } nestedstructs[idx] = { 'x': { 'a': 100, 'b': 200 }, 'y': { 'a': 300, 'b': 400 }, 'z': 500, } packedstructs[idx] = { 'a': 'a', 'b': 900 } chars[idx] = 99 shorts[idx] = 111 ints[idx] = 222 longlongs[idx] = 333 externs[idx] = 444 floats[idx] = 11.1 doubles[idx] = 12.2 longdoubles[idx] = 13.3 floatcomplex[idx] = 14.4 + 15.5j doublecomplex[idx] = 16.6 + 17.7j longdoublecomplex[idx] = 18.8 + 19.9j h_shorts[idx] = 22 h_doubles[idx] = 33.33 h_ushorts[idx] = 44 # ### Create a NumPy array and see if our element can be correctly retrieved # mystruct_array = build_numarray( mystructs) print [int(x) for x in mystruct_array[3, 2]] del mystruct_array index( smallstructs) index( nestedstructs) index( packedstructs) index( chars) index( shorts) index( ints) index( longlongs) index( floats) index( doubles) index( longdoubles) index( floatcomplex) index( doublecomplex) index( longdoublecomplex) index( h_shorts) index( h_doubles) index( h_ushorts) @testcase_numpy_1_5 def test_memslice_getbuffer(): """ >>> test_memslice_getbuffer() [[ 0 2 4] [10 12 14]] callback called """ cdef int[:, :] array = create_array((4, 5), mode="c", use_callback=True) print np.asarray(array)[::2, ::2] cdef class DeallocateMe(object): def __dealloc__(self): print "deallocated!" # Disabled! References cycles don't seem to be supported by NumPy # @testcase def acquire_release_cycle(obj): DISABLED_DOCSTRING = """ >>> a = np.arange(20, dtype=np.object) >>> a[10] = DeallocateMe() >>> acquire_release_cycle(a) deallocated! """ import gc cdef object[:] buf = obj buf[1] = buf gc.collect() del buf gc.collect() cdef packed struct StructArray: int a[4] signed char b[5] @testcase_numpy_1_5 def test_memslice_structarray(data, dtype): """ >>> def b(s): return s.encode('ascii') >>> def to_byte_values(b): ... if sys.version_info[0] >= 3: return list(b) ... else: return map(ord, b) >>> data = [(range(4), b('spam\\0')), (range(4, 8), b('ham\\0\\0')), (range(8, 12), b('eggs\\0'))] >>> dtype = np.dtype([('a', '4i'), ('b', '5b')]) >>> test_memslice_structarray([(L, to_byte_values(s)) for L, s in data], dtype) 0 1 2 3 spam 4 5 6 7 ham 8 9 10 11 eggs Test the same thing with the string format specifier >>> dtype = np.dtype([('a', '4i'), ('b', 'S5')]) >>> test_memslice_structarray(data, dtype) 0 1 2 3 spam 4 5 6 7 ham 8 9 10 11 eggs """ a = np.empty((3,), dtype=dtype) a[:] = data cdef StructArray[:] myslice = a cdef int i, j for i in range(3): for j in range(4): print myslice[i].a[j] print myslice[i].b.decode('ASCII') @testcase_numpy_1_5 def test_structarray_errors(StructArray[:] a): """ >>> dtype = np.dtype([('a', '4i'), ('b', '5b')]) >>> test_structarray_errors(np.empty((5,), dtype=dtype)) >>> dtype = np.dtype([('a', '6i'), ('b', '5b')]) >>> test_structarray_errors(np.empty((5,), dtype=dtype)) Traceback (most recent call last): ... ValueError: Expected a dimension of size 4, got 6 >>> dtype = np.dtype([('a', '(4,4)i'), ('b', '5b')]) >>> test_structarray_errors(np.empty((5,), dtype=dtype)) Traceback (most recent call last): ... ValueError: Expected 1 dimension(s), got 2 Test the same thing with the string format specifier >>> dtype = np.dtype([('a', '4i'), ('b', 'S5')]) >>> test_structarray_errors(np.empty((5,), dtype=dtype)) >>> dtype = np.dtype([('a', '6i'), ('b', 'S5')]) >>> test_structarray_errors(np.empty((5,), dtype=dtype)) Traceback (most recent call last): ... ValueError: Expected a dimension of size 4, got 6 >>> dtype = np.dtype([('a', '(4,4)i'), ('b', 'S5')]) >>> test_structarray_errors(np.empty((5,), dtype=dtype)) Traceback (most recent call last): ... ValueError: Expected 1 dimension(s), got 2 """ cdef struct StringStruct: signed char c[4][4] ctypedef signed char String[4][4] def stringstructtest(StringStruct[:] view): pass def stringtest(String[:] view): pass @testcase_numpy_1_5 def test_string_invalid_dims(): """ >>> def b(s): return s.encode('ascii') >>> dtype = np.dtype([('a', 'S4')]) >>> data = [b('spam'), b('eggs')] >>> stringstructtest(np.array(data, dtype=dtype)) Traceback (most recent call last): ... ValueError: Expected 2 dimensions, got 1 >>> stringtest(np.array(data, dtype='S4')) Traceback (most recent call last): ... ValueError: Expected 2 dimensions, got 1 """ ctypedef struct AttributesStruct: int attrib1 float attrib2 StringStruct attrib3 @testcase_numpy_1_5 def test_struct_attributes(): """ >>> test_struct_attributes() 1 2.0 c """ cdef AttributesStruct[10] a cdef AttributesStruct[:] myslice = a myslice[0].attrib1 = 1 myslice[0].attrib2 = 2.0 myslice[0].attrib3.c[0][0] = 'c' array = np.asarray(myslice) print array[0]['attrib1'] print array[0]['attrib2'] print chr(array[0]['attrib3']['c'][0][0]) # ### Test for NULL strides (C contiguous buffers) # cdef getbuffer(Buffer self, Py_buffer *info): info.buf = &self.m[0, 0] info.len = 10 * 20 info.ndim = 2 info.shape = self._shape info.strides = NULL info.suboffsets = NULL info.itemsize = 4 info.readonly = 0 self.format = b"f" info.format = self.format cdef class Buffer(object): cdef Py_ssize_t[2] _shape cdef bytes format cdef float[:, :] m cdef object shape, strides def __init__(self): a = np.arange(200, dtype=np.float32).reshape(10, 20) self.m = a self.shape = a.shape self.strides = a.strides self._shape[0] = 10 self._shape[1] = 20 def __getbuffer__(self, Py_buffer *info, int flags): getbuffer(self, info) cdef class SuboffsetsNoStridesBuffer(Buffer): def __getbuffer__(self, Py_buffer *info, int flags): getbuffer(self, info) info.suboffsets = self._shape @testcase def test_null_strides(Buffer buffer_obj): """ >>> test_null_strides(Buffer()) """ cdef float[:, :] m1 = buffer_obj cdef float[:, ::1] m2 = buffer_obj cdef float[:, ::view.contiguous] m3 = buffer_obj assert ( m1).strides == buffer_obj.strides assert ( m2).strides == buffer_obj.strides, (( m2).strides, buffer_obj.strides) assert ( m3).strides == buffer_obj.strides cdef int i, j for i in range(m1.shape[0]): for j in range(m1.shape[1]): assert m1[i, j] == buffer_obj.m[i, j] assert m2[i, j] == buffer_obj.m[i, j], (i, j, m2[i, j], buffer_obj.m[i, j]) assert m3[i, j] == buffer_obj.m[i, j] @testcase def test_null_strides_error(buffer_obj): """ >>> test_null_strides_error(Buffer()) C-contiguous buffer is not indirect in dimension 1 C-contiguous buffer is not indirect in dimension 0 C-contiguous buffer is not contiguous in dimension 0 C-contiguous buffer is not contiguous in dimension 0 >>> test_null_strides_error(SuboffsetsNoStridesBuffer()) Traceback (most recent call last): ... ValueError: Buffer exposes suboffsets but no strides """ # valid cdef float[::view.generic, ::view.generic] full_buf = buffer_obj # invalid cdef float[:, ::view.indirect] indirect_buf1 cdef float[::view.indirect, :] indirect_buf2 cdef float[::1, :] fortran_buf1 cdef float[::view.contiguous, :] fortran_buf2 try: indirect_buf1 = buffer_obj except ValueError, e: print e try: indirect_buf2 = buffer_obj except ValueError, e: print e try: fortran_buf1 = buffer_obj except ValueError, e: print e try: fortran_buf2 = buffer_obj except ValueError, e: print e Cython-0.23.4/tests/memoryview/memslice.pyx0000644000175600017570000015560212606202452022122 0ustar jenkinsjenkins00000000000000# mode: run # Note: see also bufaccess.pyx from __future__ import unicode_literals from cpython.object cimport PyObject from cpython.ref cimport Py_INCREF, Py_DECREF cimport cython from cython cimport view from cython.view cimport array from cython.parallel cimport prange, parallel import gc import sys if sys.version_info[0] < 3: import __builtin__ as builtins else: import builtins __test__ = {} def testcase(func): doctest = func.__doc__ if sys.version_info >= (3, 0): _u = str else: _u = unicode if not isinstance(doctest, _u): doctest = doctest.decode('UTF-8') __test__[func.__name__] = doctest def wrapper(*args, **kwargs): gc.collect() result = func(*args, **kwargs) gc.collect() return result return wrapper include "../buffers/mockbuffers.pxi" include "cythonarrayutil.pxi" def _print_attributes(memview): print "shape: " + " ".join(map(str, memview.shape)) print "strides: " + " ".join([str(stride // memview.itemsize) for stride in memview.strides]) print "suboffsets: " + " ".join( [str(suboffset if suboffset < 0 else suboffset // memview.itemsize) for suboffset in memview.suboffsets]) # # Buffer acquire and release tests # def nousage(): """ The challenge here is just compilation. """ cdef int[:, :] buf @testcase def acquire_release(o1, o2): """ >>> A = IntMockBuffer("A", range(6)) >>> B = IntMockBuffer("B", range(6)) >>> acquire_release(A, B) acquired A acquired B released A released B >>> acquire_release(None, B) acquired B released B """ cdef int[:] buf buf = o1 buf = o2 @testcase def acquire_raise(o): """ Apparently, doctest won't handle mixed exceptions and print stats, so need to circumvent this. >>> A = IntMockBuffer("A", range(6)) >>> A.resetlog() >>> acquire_raise(A) Traceback (most recent call last): ... Exception: on purpose >>> A.printlog() acquired A released A """ cdef int[:] buf buf = o raise Exception("on purpose") @testcase def acquire_failure1(): """ >>> acquire_failure1() acquired working 0 3 0 3 released working """ cdef int[:] buf buf = IntMockBuffer("working", range(4)) print buf[0], buf[3] try: buf = ErrorBuffer() assert False except Exception: print buf[0], buf[3] @testcase def acquire_failure2(): """ >>> acquire_failure2() acquired working 0 3 0 3 released working """ cdef int[:] buf = IntMockBuffer("working", range(4)) print buf[0], buf[3] try: buf = ErrorBuffer() assert False except Exception: print buf[0], buf[3] @testcase def acquire_failure3(): """ >>> acquire_failure3() acquired working 0 3 0 3 released working """ cdef int[:] buf buf = IntMockBuffer("working", range(4)) print buf[0], buf[3] try: buf = object() assert False except Exception: print buf[0], buf[3] @testcase def acquire_nonbuffer1(first, second=None): """ >>> acquire_nonbuffer1(3) # doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError:... 'int'... >>> acquire_nonbuffer1(type) # doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError:... 'type'... >>> acquire_nonbuffer1(None, 2) # doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError:... 'int'... >>> acquire_nonbuffer1(4, object()) # doctest: +ELLIPSIS Traceback (most recent call last): ... TypeError:... 'int'... """ cdef int[:] buf buf = first buf = second @testcase def acquire_nonbuffer2(): """ >>> acquire_nonbuffer2() acquired working 0 3 0 3 released working """ cdef int[:] buf = IntMockBuffer("working", range(4)) print buf[0], buf[3] try: buf = ErrorBuffer assert False except Exception: print buf[0], buf[3] @testcase def as_argument(int[:] bufarg, int n): """ >>> A = IntMockBuffer("A", range(6)) >>> as_argument(A, 6) acquired A 0 1 2 3 4 5 END released A """ cdef int i for i in range(n): print bufarg[i], print 'END' @testcase def as_argument_defval(int[:] bufarg=IntMockBuffer('default', range(6)), int n=6): """ >>> as_argument_defval() 0 1 2 3 4 5 END >>> A = IntMockBuffer("A", range(6)) >>> as_argument_defval(A, 6) acquired A 0 1 2 3 4 5 END released A """ cdef int i for i in range(n): print bufarg[i], print 'END' @testcase def cdef_assignment(obj, n): """ >>> A = IntMockBuffer("A", range(6)) >>> cdef_assignment(A, 6) acquired A 0 1 2 3 4 5 END released A """ cdef int[:] buf = obj cdef int i for i in range(n): print buf[i], print 'END' @testcase def forin_assignment(objs, int pick): """ >>> A = IntMockBuffer("A", range(6)) >>> B = IntMockBuffer("B", range(6)) >>> forin_assignment([A, B, A, A], 2) acquired A 2 acquired B released A 2 acquired A released B 2 acquired A released A 2 released A """ cdef int[:] buf for buf in objs: print buf[pick] @testcase def cascaded_buffer_assignment(obj): """ >>> A = IntMockBuffer("A", range(6)) >>> cascaded_buffer_assignment(A) acquired A released A """ cdef int[:] a, b a = b = obj @testcase def tuple_buffer_assignment1(a, b): """ >>> A = IntMockBuffer("A", range(6)) >>> B = IntMockBuffer("B", range(6)) >>> tuple_buffer_assignment1(A, B) acquired A acquired B released A released B """ cdef int[:] x, y x, y = a, b @testcase def tuple_buffer_assignment2(tup): """ >>> A = IntMockBuffer("A", range(6)) >>> B = IntMockBuffer("B", range(6)) >>> tuple_buffer_assignment2((A, B)) acquired A acquired B released A released B """ cdef int[:] x, y x, y = tup @testcase def explicitly_release_buffer(): """ >>> explicitly_release_buffer() acquired A released A After release """ cdef int[:] x = IntMockBuffer("A", range(10)) del x print "After release" # # Getting items and index bounds checking # @testcase def get_int_2d(int[:, :] buf, int i, int j): """ >>> C = IntMockBuffer("C", range(6), (2,3)) >>> get_int_2d(C, 1, 1) acquired C released C 4 Check negative indexing: >>> get_int_2d(C, -1, 0) acquired C released C 3 >>> get_int_2d(C, -1, -2) acquired C released C 4 >>> get_int_2d(C, -2, -3) acquired C released C 0 Out-of-bounds errors: >>> get_int_2d(C, 2, 0) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) >>> get_int_2d(C, 0, -4) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 1) """ return buf[i, j] @testcase def get_int_2d_uintindex(int[:, :] buf, unsigned int i, unsigned int j): """ Unsigned indexing: >>> C = IntMockBuffer("C", range(6), (2,3)) >>> get_int_2d_uintindex(C, 0, 0) acquired C released C 0 >>> get_int_2d_uintindex(C, 1, 2) acquired C released C 5 """ # This is most interesting with regards to the C code # generated. return buf[i, j] @testcase def set_int_2d(int[:, :] buf, int i, int j, int value): """ Uses get_int_2d to read back the value afterwards. For pure unit test, one should support reading in MockBuffer instead. >>> C = IntMockBuffer("C", range(6), (2,3)) >>> set_int_2d(C, 1, 1, 10) acquired C released C >>> get_int_2d(C, 1, 1) acquired C released C 10 Check negative indexing: >>> set_int_2d(C, -1, 0, 3) acquired C released C >>> get_int_2d(C, -1, 0) acquired C released C 3 >>> set_int_2d(C, -1, -2, 8) acquired C released C >>> get_int_2d(C, -1, -2) acquired C released C 8 >>> set_int_2d(C, -2, -3, 9) acquired C released C >>> get_int_2d(C, -2, -3) acquired C released C 9 Out-of-bounds errors: >>> set_int_2d(C, 2, 0, 19) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) >>> set_int_2d(C, 0, -4, 19) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 1) """ buf[i, j] = value def _read_int2d(int[:, :] buf, int i, int j): return buf[i, j] @testcase def schar_index_vars(int[:, :] buf, signed char i, signed char j, int value): """ >>> C = IntMockBuffer("C", range(300*300), (300, 300)) # > sizeof(char) >>> schar_index_vars(C, 1, 1, 5) acquired C reading writing validated released C 301 >>> _read_int2d(C, 1, 1) # validate with int indices acquired C released C 5 >>> schar_index_vars(C, -1, 1, 6) acquired C reading writing validated released C 89701 >>> _read_int2d(C, -1, 1) # validate with int indices acquired C released C 6 >>> schar_index_vars(C, -1, -2, 7) acquired C reading writing validated released C 89998 >>> _read_int2d(C, -1, -2) # validate with int indices acquired C released C 7 >>> schar_index_vars(C, -2, -3, 8) acquired C reading writing validated released C 89697 >>> _read_int2d(C, -2, -3) # validate with int indices acquired C released C 8 >>> C = IntMockBuffer("C", range(6), (2, 3)) >>> schar_index_vars(C, 5, 1, 10) Traceback (most recent call last): IndexError: Out of bounds on buffer access (axis 0) >>> schar_index_vars(C, 1, 5, 10) Traceback (most recent call last): IndexError: Out of bounds on buffer access (axis 1) >>> schar_index_vars(C, -2, 1, 10) acquired C reading writing validated released C 1 >>> schar_index_vars(C, -3, 1, 10) Traceback (most recent call last): IndexError: Out of bounds on buffer access (axis 0) >>> schar_index_vars(C, 1, -3, 10) acquired C reading writing validated released C 3 >>> schar_index_vars(C, 1, -4, 10) Traceback (most recent call last): IndexError: Out of bounds on buffer access (axis 1) """ print("reading") old_value = buf[i, j] print("writing") buf[i, j] = value if buf[i, j] == value: print("validated") return old_value @testcase def uchar_index_vars(int[:, :] buf, unsigned char i, unsigned char j, int value): """ >>> C = IntMockBuffer("C", range(300*300), (300, 300)) # > sizeof(char) >>> uchar_index_vars(C, 1, 1, 5) acquired C reading writing validated released C 301 >>> _read_int2d(C, 1, 1) # validate with int indices acquired C released C 5 >>> C = IntMockBuffer("C", range(6), (2, 3)) >>> uchar_index_vars(C, 5, 1, 10) Traceback (most recent call last): IndexError: Out of bounds on buffer access (axis 0) >>> uchar_index_vars(C, 1, 5, 10) Traceback (most recent call last): IndexError: Out of bounds on buffer access (axis 1) """ print("reading") old_value = buf[i, j] print("writing") buf[i, j] = value if buf[i, j] == value: print("validated") return old_value @testcase def char_index_vars(int[:, :] buf, char i, char j, int value): """ >>> C = IntMockBuffer("C", range(300*300), (300, 300)) # > sizeof(char) >>> char_index_vars(C, 1, 1, 5) acquired C reading writing validated released C 301 >>> _read_int2d(C, 1, 1) # validate with int indices acquired C released C 5 >>> C = IntMockBuffer("C", range(6), (2, 3)) >>> char_index_vars(C, 5, 1, 10) Traceback (most recent call last): IndexError: Out of bounds on buffer access (axis 0) >>> char_index_vars(C, 1, 5, 10) Traceback (most recent call last): IndexError: Out of bounds on buffer access (axis 1) """ print("reading") old_value = buf[i, j] print("writing") buf[i, j] = value if buf[i, j] == value: print("validated") return old_value @testcase def list_comprehension(int[:] buf, len): """ >>> list_comprehension(IntMockBuffer(None, [1,2,3]), 3) 1|2|3 """ cdef int i print u"|".join([unicode(buf[i]) for i in range(len)]) @testcase @cython.wraparound(False) def wraparound_directive(int[:] buf, int pos_idx, int neg_idx): """ Again, the most interesting thing here is to inspect the C source. >>> A = IntMockBuffer(None, range(4)) >>> wraparound_directive(A, 2, -1) 5 >>> wraparound_directive(A, -1, 2) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) """ cdef int byneg with cython.wraparound(True): byneg = buf[neg_idx] return buf[pos_idx] + byneg # # Test all kinds of indexing and flags # @testcase def writable(obj): """ >>> R = UnsignedShortMockBuffer("R", range(27), shape=(3, 3, 3)) >>> writable(R) acquired R released R >>> [str(x) for x in R.recieved_flags] # Py2/3 ['FORMAT', 'ND', 'STRIDES', 'WRITABLE'] """ cdef unsigned short int[:, :, :] buf = obj buf[2, 2, 1] = 23 @testcase def strided(int[:] buf): """ >>> A = IntMockBuffer("A", range(4)) >>> strided(A) acquired A released A 2 >>> [str(x) for x in A.recieved_flags] # Py2/3 ['FORMAT', 'ND', 'STRIDES', 'WRITABLE'] Check that the suboffsets were patched back prior to release. >>> A.release_ok True """ return buf[2] @testcase def c_contig(int[::1] buf): """ >>> A = IntMockBuffer(None, range(4)) >>> c_contig(A) 2 >>> [str(x) for x in A.recieved_flags] ['FORMAT', 'ND', 'STRIDES', 'C_CONTIGUOUS', 'WRITABLE'] """ return buf[2] @testcase def c_contig_2d(int[:, ::1] buf): """ Multi-dim has seperate implementation >>> A = IntMockBuffer(None, range(12), shape=(3,4)) >>> c_contig_2d(A) 7 >>> [str(x) for x in A.recieved_flags] ['FORMAT', 'ND', 'STRIDES', 'C_CONTIGUOUS', 'WRITABLE'] """ return buf[1, 3] @testcase def f_contig(int[::1, :] buf): """ >>> A = IntMockBuffer(None, range(4), shape=(2, 2), strides=(1, 2)) >>> f_contig(A) 2 >>> [str(x) for x in A.recieved_flags] ['FORMAT', 'ND', 'STRIDES', 'F_CONTIGUOUS', 'WRITABLE'] """ return buf[0, 1] @testcase def f_contig_2d(int[::1, :] buf): """ Must set up strides manually to ensure Fortran ordering. >>> A = IntMockBuffer(None, range(12), shape=(4,3), strides=(1, 4)) >>> f_contig_2d(A) 7 >>> [str(x) for x in A.recieved_flags] ['FORMAT', 'ND', 'STRIDES', 'F_CONTIGUOUS', 'WRITABLE'] """ return buf[3, 1] @testcase def generic(int[::view.generic, ::view.generic] buf1, int[::view.generic, ::view.generic] buf2): """ >>> A = IntMockBuffer("A", [[0,1,2], [3,4,5], [6,7,8]]) >>> B = IntMockBuffer("B", [[0,1,2], [3,4,5], [6,7,8]], shape=(3, 3), strides=(1, 3)) >>> generic(A, B) acquired A acquired B 4 4 10 11 released A released B >>> [str(x) for x in A.recieved_flags] ['FORMAT', 'INDIRECT', 'ND', 'STRIDES', 'WRITABLE'] >>> [str(x) for x in B.recieved_flags] ['FORMAT', 'INDIRECT', 'ND', 'STRIDES', 'WRITABLE'] """ print buf1[1, 1] print buf2[1, 1] buf1[2, -1] = 10 buf2[2, -1] = 11 print buf1[2, 2] print buf2[2, 2] # Note: disabled. generic_contiguous isn't very useful (you have to check suboffsets, # might as well multiply with strides) # def generic_contig(int[::view.generic_contiguous, :] buf1, # int[::view.generic_contiguous, :] buf2): # """ # >>> A = IntMockBuffer("A", [[0,1,2], [3,4,5], [6,7,8]]) # >>> B = IntMockBuffer("B", [[0,1,2], [3,4,5], [6,7,8]], shape=(3, 3), strides=(1, 3)) # >>> generic_contig(A, B) # acquired A # acquired B # 4 # 4 # 10 # 11 # released A # released B # >>> [str(x) for x in A.recieved_flags] # ['FORMAT', 'INDIRECT', 'ND', 'STRIDES', 'WRITABLE'] # >>> [str(x) for x in B.recieved_flags] # ['FORMAT', 'INDIRECT', 'ND', 'STRIDES', 'WRITABLE'] # """ # print buf1[1, 1] # print buf2[1, 1] # # buf1[2, -1] = 10 # buf2[2, -1] = 11 # # print buf1[2, 2] # print buf2[2, 2] @testcase def indirect_strided_and_contig( int[::view.indirect, ::view.strided] buf1, int[::view.indirect, ::view.contiguous] buf2): """ >>> A = IntMockBuffer("A", [[0,1,2], [3,4,5], [6,7,8]]) >>> B = IntMockBuffer("B", [[0,1,2], [3,4,5], [6,7,8]], shape=(3, 3), strides=(1, 3)) >>> indirect_strided_and_contig(A, B) acquired A acquired B 4 4 10 11 released A released B >>> [str(x) for x in A.recieved_flags] ['FORMAT', 'INDIRECT', 'ND', 'STRIDES', 'WRITABLE'] >>> [str(x) for x in B.recieved_flags] ['FORMAT', 'INDIRECT', 'ND', 'STRIDES', 'WRITABLE'] """ print buf1[1, 1] print buf2[1, 1] buf1[2, -1] = 10 buf2[2, -1] = 11 print buf1[2, 2] print buf2[2, 2] @testcase def indirect_contig( int[::view.indirect_contiguous, ::view.contiguous] buf1, int[::view.indirect_contiguous, ::view.generic] buf2): """ >>> A = IntMockBuffer("A", [[0,1,2], [3,4,5], [6,7,8]]) >>> B = IntMockBuffer("B", [[0,1,2], [3,4,5], [6,7,8]], shape=(3, 3), strides=(1, 3)) >>> indirect_contig(A, B) acquired A acquired B 4 4 10 11 released A released B >>> [str(x) for x in A.recieved_flags] ['FORMAT', 'INDIRECT', 'ND', 'STRIDES', 'WRITABLE'] >>> [str(x) for x in B.recieved_flags] ['FORMAT', 'INDIRECT', 'ND', 'STRIDES', 'WRITABLE'] """ print buf1[1, 1] print buf2[1, 1] buf1[2, -1] = 10 buf2[2, -1] = 11 print buf1[2, 2] print buf2[2, 2] # # Test compiler options for bounds checking. We create an array with a # safe "boundary" (memory # allocated outside of what it published) and then check whether we get back # what we stored in the memory or an error. @testcase def safe_get(int[:] buf, int idx): """ >>> A = IntMockBuffer(None, range(10), shape=(3,), offset=5) Validate our testing buffer... >>> safe_get(A, 0) 5 >>> safe_get(A, 2) 7 >>> safe_get(A, -3) 5 Access outside it. This is already done above for bounds check testing but we include it to tell the story right. >>> safe_get(A, -4) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) >>> safe_get(A, 3) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) """ return buf[idx] @testcase @cython.boundscheck(False) # outer decorators should take precedence @cython.boundscheck(True) def unsafe_get(int[:] buf, int idx): """ Access outside of the area the buffer publishes. >>> A = IntMockBuffer(None, range(10), shape=(3,), offset=5) >>> unsafe_get(A, -4) 4 >>> unsafe_get(A, -5) 3 >>> unsafe_get(A, 3) 8 """ return buf[idx] @testcase def mixed_get(int[:] buf, int unsafe_idx, int safe_idx): """ >>> A = IntMockBuffer(None, range(10), shape=(3,), offset=5) >>> mixed_get(A, -4, 0) (4, 5) >>> mixed_get(A, 0, -4) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) """ with cython.boundscheck(False): one = buf[unsafe_idx] with cython.boundscheck(True): two = buf[safe_idx] return (one, two) # # Testing that accessing data using various types of buffer access # all works. # def printbuf_int(int[:] buf, shape): # Utility func cdef int i for i in range(shape[0]): print buf[i], print 'END' @testcase def printbuf_int_2d(o, shape): """ Strided: >>> printbuf_int_2d(IntMockBuffer("A", range(6), (2,3)), (2,3)) acquired A 0 1 2 END 3 4 5 END released A >>> printbuf_int_2d(IntMockBuffer("A", range(100), (3,3), strides=(20,5)), (3,3)) acquired A 0 5 10 END 20 25 30 END 40 45 50 END released A Indirect: >>> printbuf_int_2d(IntMockBuffer("A", [[1,2],[3,4]]), (2,2)) acquired A 1 2 END 3 4 END released A """ # should make shape builtin cdef int[::view.generic, ::view.generic] buf buf = o cdef int i, j for i in range(shape[0]): for j in range(shape[1]): print buf[i, j], print 'END' @testcase def printbuf_float(o, shape): """ >>> printbuf_float(FloatMockBuffer("F", [1.0, 1.25, 0.75, 1.0]), (4,)) acquired F 1.0 1.25 0.75 1.0 END released F """ # should make shape builtin cdef float[:] buf buf = o cdef int i, j for i in range(shape[0]): print buf[i], print "END" # # Test assignments # @testcase def inplace_operators(int[:] buf): """ >>> buf = IntMockBuffer(None, [2, 2]) >>> inplace_operators(buf) >>> printbuf_int(buf, (2,)) 0 3 END """ cdef int j = 0 buf[1] += 1 buf[j] *= 2 buf[0] -= 4 # # Typedefs # # Test three layers of typedefs going through a h file for plain int, and # simply a header file typedef for floats and unsigned. ctypedef int td_cy_int cdef extern from "bufaccess.h": ctypedef td_cy_int td_h_short # Defined as short, but Cython doesn't know this! ctypedef float td_h_double # Defined as double ctypedef unsigned int td_h_ushort # Defined as unsigned short ctypedef td_h_short td_h_cy_short @testcase def printbuf_td_cy_int(td_cy_int[:] buf, shape): """ >>> printbuf_td_cy_int(IntMockBuffer(None, range(3)), (3,)) 0 1 2 END >>> printbuf_td_cy_int(ShortMockBuffer(None, range(3)), (3,)) Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'td_cy_int' but got 'short' """ cdef int i for i in range(shape[0]): print buf[i], print 'END' @testcase def printbuf_td_h_short(td_h_short[:] buf, shape): """ >>> printbuf_td_h_short(ShortMockBuffer(None, range(3)), (3,)) 0 1 2 END >>> printbuf_td_h_short(IntMockBuffer(None, range(3)), (3,)) Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'td_h_short' but got 'int' """ cdef int i for i in range(shape[0]): print buf[i], print 'END' @testcase def printbuf_td_h_cy_short(td_h_cy_short[:] buf, shape): """ >>> printbuf_td_h_cy_short(ShortMockBuffer(None, range(3)), (3,)) 0 1 2 END >>> printbuf_td_h_cy_short(IntMockBuffer(None, range(3)), (3,)) Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'td_h_cy_short' but got 'int' """ cdef int i for i in range(shape[0]): print buf[i], print 'END' @testcase def printbuf_td_h_ushort(td_h_ushort[:] buf, shape): """ >>> printbuf_td_h_ushort(UnsignedShortMockBuffer(None, range(3)), (3,)) 0 1 2 END >>> printbuf_td_h_ushort(ShortMockBuffer(None, range(3)), (3,)) Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'td_h_ushort' but got 'short' """ cdef int i for i in range(shape[0]): print buf[i], print 'END' @testcase def printbuf_td_h_double(td_h_double[:] buf, shape): """ >>> printbuf_td_h_double(DoubleMockBuffer(None, [0.25, 1, 3.125]), (3,)) 0.25 1.0 3.125 END >>> printbuf_td_h_double(FloatMockBuffer(None, [0.25, 1, 3.125]), (3,)) Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'td_h_double' but got 'float' """ cdef int i for i in range(shape[0]): print buf[i], print 'END' # # Object access # def addref(*args): for item in args: Py_INCREF(item) def decref(*args): for item in args: Py_DECREF(item) def get_refcount(x): return (x).ob_refcnt @testcase def printbuf_object(object[:] buf, shape): """ Only play with unique objects, interned numbers etc. will have unpredictable refcounts. ObjectMockBuffer doesn't do anything about increfing/decrefing, we to the "buffer implementor" refcounting directly in the testcase. >>> a, b, c = "globally_unique_string_23234123", {4:23}, [34,3] >>> get_refcount(a), get_refcount(b), get_refcount(c) (2, 2, 2) >>> A = ObjectMockBuffer(None, [a, b, c]) >>> printbuf_object(A, (3,)) 'globally_unique_string_23234123' 2 {4: 23} 2 [34, 3] 2 """ cdef int i for i in range(shape[0]): print repr(buf[i]), (buf[i]).ob_refcnt @testcase def assign_to_object(object[:] buf, int idx, obj): """ See comments on printbuf_object above. >>> a, b = [1, 2, 3], [4, 5, 6] >>> get_refcount(a), get_refcount(b) (2, 2) >>> addref(a) >>> A = ObjectMockBuffer(None, [1, a]) # 1, ...,otherwise it thinks nested lists... >>> get_refcount(a), get_refcount(b) (3, 2) >>> assign_to_object(A, 1, b) >>> get_refcount(a), get_refcount(b) (2, 3) >>> decref(b) """ buf[idx] = obj @testcase def assign_temporary_to_object(object[:] buf): """ See comments on printbuf_object above. >>> a, b = [1, 2, 3], {4:23} >>> get_refcount(a) 2 >>> addref(a) >>> A = ObjectMockBuffer(None, [b, a]) >>> get_refcount(a) 3 >>> assign_temporary_to_object(A) >>> get_refcount(a) 2 >>> printbuf_object(A, (2,)) {4: 23} 2 {1: 8} 2 To avoid leaking a reference in our testcase we need to replace the temporary with something we can manually decref :-) >>> assign_to_object(A, 1, a) >>> decref(a) """ buf[1] = {3-2: 2+(2*4)-2} # # Test __cythonbufferdefaults__ # @testcase def bufdefaults1(int[:] buf): """ For IntStridedMockBuffer, mode should be "strided" by defaults which should show up in the flags. >>> A = IntStridedMockBuffer("A", range(10)) >>> bufdefaults1(A) acquired A released A >>> [str(x) for x in A.recieved_flags] ['FORMAT', 'ND', 'STRIDES', 'WRITABLE'] """ pass @testcase def basic_struct(MyStruct[:] buf): """ See also buffmt.pyx >>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)])) 1 2 3 4 5 >>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="ccqii")) 1 2 3 4 5 """ print buf[0].a, buf[0].b, buf[0].c, buf[0].d, buf[0].e @testcase def nested_struct(NestedStruct[:] buf): """ See also buffmt.pyx >>> nested_struct(NestedStructMockBuffer(None, [(1, 2, 3, 4, 5)])) 1 2 3 4 5 >>> nested_struct(NestedStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="T{ii}T{2i}i")) 1 2 3 4 5 """ print buf[0].x.a, buf[0].x.b, buf[0].y.a, buf[0].y.b, buf[0].z @testcase def packed_struct(PackedStruct[:] buf): """ See also buffmt.pyx >>> packed_struct(PackedStructMockBuffer(None, [(1, 2)])) 1 2 >>> packed_struct(PackedStructMockBuffer(None, [(1, 2)], format="T{c^i}")) 1 2 >>> packed_struct(PackedStructMockBuffer(None, [(1, 2)], format="T{c=i}")) 1 2 """ print buf[0].a, buf[0].b @testcase def nested_packed_struct(NestedPackedStruct[:] buf): """ See also buffmt.pyx >>> nested_packed_struct(NestedPackedStructMockBuffer(None, [(1, 2, 3, 4, 5)])) 1 2 3 4 5 >>> nested_packed_struct(NestedPackedStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="ci^ci@i")) 1 2 3 4 5 >>> nested_packed_struct(NestedPackedStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="^c@i^ci@i")) 1 2 3 4 5 """ print buf[0].a, buf[0].b, buf[0].sub.a, buf[0].sub.b, buf[0].c @testcase def complex_dtype(long double complex[:] buf): """ >>> complex_dtype(LongComplexMockBuffer(None, [(0, -1)])) -1j """ print buf[0] @testcase def complex_inplace(long double complex[:] buf): """ >>> complex_inplace(LongComplexMockBuffer(None, [(0, -1)])) (1+1j) """ buf[0] = buf[0] + 1 + 2j print buf[0] @testcase def complex_struct_dtype(LongComplex[:] buf): """ Note that the format string is "Zg" rather than "2g", yet a struct is accessed. >>> complex_struct_dtype(LongComplexMockBuffer(None, [(0, -1)])) 0.0 -1.0 """ print buf[0].real, buf[0].imag @testcase def complex_struct_inplace(LongComplex[:] buf): """ >>> complex_struct_inplace(LongComplexMockBuffer(None, [(0, -1)])) 1.0 1.0 """ buf[0].real += 1 buf[0].imag += 2 print buf[0].real, buf[0].imag # # Nogil # @testcase @cython.boundscheck(False) def buffer_nogil(): """ >>> buffer_nogil() (10, 10) """ cdef int[:] buf = IntMockBuffer(None, [1,2,3]) cdef int[:] buf2 = IntMockBuffer(None, [4,5,6]) with nogil: buf[1] = 10 buf2 = buf return buf[1], buf2[1] # ### Test cdef functions # class UniqueObject(object): def __init__(self, value): self.value = value def __repr__(self): return self.value objs = [[UniqueObject("spam")], [UniqueObject("ham")], [UniqueObject("eggs")]] addref(*[obj for L in objs for obj in L]) cdef cdef_function(int[:] buf1, object[::view.indirect, :] buf2 = ObjectMockBuffer(None, objs)): print 'cdef called' print buf1[6], buf2[1, 0] buf2[1, 0] = UniqueObject("eggs") @testcase def test_cdef_function(o1, o2=None): """ >>> A = IntMockBuffer("A", range(10)) >>> test_cdef_function(A) acquired A cdef called 6 ham released A acquired A cdef called 6 eggs released A >>> L = [[x] for x in range(25)] >>> addref(*[obj for mylist in L for obj in mylist]) >>> B = ObjectMockBuffer("B", L, shape=(5, 5)) >>> test_cdef_function(A, B) acquired A cdef called 6 eggs released A acquired A cdef called 6 eggs released A acquired A acquired B cdef called 6 1 released A released B """ cdef_function(o1) cdef_function(o1) if o2: cdef_function(o1, o2) cdef int[:] global_A = IntMockBuffer("Global_A", range(10)) addref(*[obj for L in objs for obj in L]) cdef object[::view.indirect, :] global_B = ObjectMockBuffer(None, objs) cdef cdef_function2(int[:] buf1, object[::view.indirect, :] buf2 = global_B): print 'cdef2 called' print buf1[6], buf2[1, 0] buf2[1, 0] = UniqueObject("eggs") @testcase def test_cdef_function2(): """ >>> test_cdef_function2() cdef2 called 6 ham eggs cdef2 called 6 eggs """ cdef int[:] A = global_A cdef object[::view.indirect, :] B = global_B cdef_function2(A, B) del A del B print global_B[1, 0] cdef_function2(global_A, global_B) @testcase def test_generic_slicing(arg, indirect=False): """ Test simple slicing >>> test_generic_slicing(IntMockBuffer("A", range(8 * 14 * 11), shape=(8, 14, 11))) acquired A 3 9 2 308 -11 1 -1 -1 -1 released A Test direct slicing, negative slice oob in dim 2 >>> test_generic_slicing(IntMockBuffer("A", range(1 * 2 * 3), shape=(1, 2, 3))) acquired A 0 0 2 12 -3 1 -1 -1 -1 released A Test indirect slicing >>> test_generic_slicing(IntMockBuffer("A", shape_5_3_4_list, shape=(5, 3, 4)), indirect=True) acquired A 2 0 2 0 1 -1 released A >>> test_generic_slicing(IntMockBuffer("A", shape_9_14_21_list, shape=(9, 14, 21)), indirect=True) acquired A 3 9 2 10 1 -1 released A """ cdef int[::view.generic, ::view.generic, :] a = arg cdef int[::view.generic, ::view.generic, :] b = a[2:8:2, -4:1:-1, 1:3] print b.shape[0], b.shape[1], b.shape[2] if indirect: print b.suboffsets[0] // sizeof(int *), print b.suboffsets[1] // sizeof(int), print b.suboffsets[2] else: print_int_offsets(b.strides[0], b.strides[1], b.strides[2]) print_int_offsets(b.suboffsets[0], b.suboffsets[1], b.suboffsets[2]) cdef int i, j, k for i in range(b.shape[0]): for j in range(b.shape[1]): for k in range(b.shape[2]): itemA = a[2 + 2 * i, -4 - j, 1 + k] itemB = b[i, j, k] assert itemA == itemB, (i, j, k, itemA, itemB) @testcase def test_indirect_slicing(arg): """ Test indirect slicing >>> test_indirect_slicing(IntMockBuffer("A", shape_5_3_4_list, shape=(5, 3, 4))) acquired A 5 3 2 0 0 -1 58 56 58 index away indirect 58 58 index away generic 58 58 released A >>> test_indirect_slicing(IntMockBuffer("A", shape_9_14_21_list, shape=(9, 14, 21))) acquired A 5 14 3 0 16 -1 2412 2410 2412 index away indirect 2412 2412 index away generic 2412 2412 released A """ cdef int[::view.indirect, ::view.indirect, :] a = arg cdef int[::view.indirect, ::view.indirect, :] b = a[-5:, ..., -5:100:2] cdef int[::view.generic , :: view.generic, :] generic_b = a[-5:, ..., -5:100:2] cdef int[::view.indirect, ::view.indirect] c = b[..., 0] # try indexing away leading indirect dimensions cdef int[::view.indirect, :] d = b[4] cdef int[:] e = b[4, 2] cdef int[::view.generic, :] generic_d = generic_b[4] cdef int[:] generic_e = generic_b[4, 2] print b.shape[0], b.shape[1], b.shape[2] print b.suboffsets[0] // sizeof(int *), print b.suboffsets[1] // sizeof(int), print b.suboffsets[2] print b[4, 2, 1] print c[4, 2] # test adding offset from last dimension to suboffset print b[..., 1][4, 2] print "index away indirect" print d[2, 1] print e[1] print "index away generic" print generic_d[2, 1] print generic_e[1] cdef class TestIndexSlicingDirectIndirectDims(object): "Test a int[:, ::view.indirect, :] slice" cdef Py_ssize_t[3] shape, strides, suboffsets cdef int[5] c_array cdef int *myarray[5][5] cdef bytes format def __init__(self): cdef int i self.c_array[3] = 20 self.myarray[1][2] = self.c_array for i in range(3): self.shape[i] = 5 self.strides[0] = sizeof(int *) * 5 self.strides[1] = sizeof(int *) self.strides[2] = sizeof(int) self.suboffsets[0] = -1 self.suboffsets[1] = 0 self.suboffsets[2] = -1 self.format = b"i" def __getbuffer__(self, Py_buffer *info, int flags): info.buf = self.myarray info.len = 5 * 5 * 5 info.ndim = 3 info.shape = self.shape info.strides = self.strides info.suboffsets = self.suboffsets info.itemsize = sizeof(int) info.readonly = 0 info.obj = self info.format = self.format @testcase def test_index_slicing_away_direct_indirect(): """ >>> test_index_slicing_away_direct_indirect() 20 20 20 20 20 20 20 20 All dimensions preceding dimension 1 must be indexed and not sliced """ cdef int[:, ::view.indirect, :] a = TestIndexSlicingDirectIndirectDims() a_obj = a print a[1][2][3] print a[1, 2, 3] print a[1, 2][3] print a[..., 3][1, 2] print print a_obj[1][2][3] print a_obj[1, 2, 3] print a_obj[1, 2][3] print a_obj[..., 3][1, 2] try: print a_obj[1:, 2][3] except IndexError, e: print e.args[0] @testcase def test_direct_slicing(arg): """ Fused types would be convenient to test this stuff! Test simple slicing >>> test_direct_slicing(IntMockBuffer("A", range(8 * 14 * 11), shape=(8, 14, 11))) acquired A 3 9 2 308 -11 1 -1 -1 -1 released A Test direct slicing, negative slice oob in dim 2 >>> test_direct_slicing(IntMockBuffer("A", range(1 * 2 * 3), shape=(1, 2, 3))) acquired A 0 0 2 12 -3 1 -1 -1 -1 released A """ cdef int[:, :, ::1] a = arg cdef int[:, :, :] b = a[2:8:2, -4:1:-1, 1:3] print b.shape[0], b.shape[1], b.shape[2] print_int_offsets(b.strides[0], b.strides[1], b.strides[2]) print_int_offsets(b.suboffsets[0], b.suboffsets[1], b.suboffsets[2]) cdef int i, j, k for i in range(b.shape[0]): for j in range(b.shape[1]): for k in range(b.shape[2]): itemA = a[2 + 2 * i, -4 - j, 1 + k] itemB = b[i, j, k] assert itemA == itemB, (i, j, k, itemA, itemB) @testcase def test_slicing_and_indexing(arg): """ >>> a = IntStridedMockBuffer("A", range(10 * 3 * 5), shape=(10, 3, 5)) >>> test_slicing_and_indexing(a) acquired A 5 2 15 2 126 113 [111] released A """ cdef int[:, :, :] a = arg cdef int[:, :] b = a[-5:, 1, 1::2] cdef int[:, :] c = b[4:1:-1, ::-1] cdef int[:] d = c[2, 1:2] print b.shape[0], b.shape[1] print_int_offsets(b.strides[0], b.strides[1]) cdef int i, j for i in range(b.shape[0]): for j in range(b.shape[1]): itemA = a[-5 + i, 1, 1 + 2 * j] itemB = b[i, j] assert itemA == itemB, (i, j, itemA, itemB) print c[1, 1], c[2, 0] print [d[i] for i in range(d.shape[0])] @testcase def test_oob(): """ >>> test_oob() Traceback (most recent call last): ... IndexError: Index out of bounds (axis 1) """ cdef int[:, :] a = IntMockBuffer("A", range(4 * 9), shape=(4, 9)) print a[:, 20] cdef int nogil_oob(int[:, :] a) nogil except 0: a[100, 9:] return 1 @testcase def test_nogil_oob1(): """ A is acquired at the beginning of the function and released at the end. B is acquired as a temporary and as such is immediately released in the except clause. >>> test_nogil_oob1() acquired A acquired B released B Index out of bounds (axis 0) Index out of bounds (axis 0) released A """ cdef int[:, :] a = IntMockBuffer("A", range(4 * 9), shape=(4, 9)) try: nogil_oob(IntMockBuffer("B", range(4 * 9), shape=(4, 9))) except IndexError, e: print e.args[0] try: with nogil: nogil_oob(a) except IndexError, e: print e.args[0] @testcase def test_nogil_oob2(): """ >>> test_nogil_oob2() Traceback (most recent call last): ... IndexError: Index out of bounds (axis 0) """ cdef int[:, :] a = IntMockBuffer("A", range(4 * 9), shape=(4, 9)) with nogil: a[100, 9:] @cython.boundscheck(False) cdef int cdef_nogil(int[:, :] a) nogil except 0: cdef int i, j cdef int[:, :] b = a[::-1, 3:10:2] for i in range(b.shape[0]): for j in range(b.shape[1]): b[i, j] = -b[i, j] return 1 @testcase def test_nogil(): """ >>> test_nogil() acquired A released A acquired A -25 released A """ _a = IntMockBuffer("A", range(4 * 9), shape=(4, 9)) cdef_nogil(_a) cdef int[:, :] a = _a print a[2, 7] @testcase def test_convert_slicenode_to_indexnode(): """ When indexing with a[i:j] a SliceNode gets created instead of an IndexNode, which forces coercion to object and back. This would not only be inefficient, but it would also not compile in nogil mode. So instead we mutate it into an IndexNode. >>> test_convert_slicenode_to_indexnode() acquired A 2 released A """ cdef int[:] a = IntMockBuffer("A", range(10), shape=(10,)) with nogil: a = a[2:4] print a[0] @testcase @cython.boundscheck(False) @cython.wraparound(False) def test_memslice_prange(arg): """ >>> test_memslice_prange(IntMockBuffer("A", range(400), shape=(20, 4, 5))) acquired A released A >>> test_memslice_prange(IntMockBuffer("A", range(200), shape=(100, 2, 1))) acquired A released A """ cdef int[:, :, :] src, dst src = arg dst = array(( src).shape, sizeof(int), format="i") cdef int i, j, k for i in prange(src.shape[0], nogil=True): for j in range(src.shape[1]): for k in range(src.shape[2]): dst[i, j, k] = src[i, j, k] for i in range(src.shape[0]): for j in range(src.shape[1]): for k in range(src.shape[2]): assert src[i, j, k] == dst[i, j, k], (src[i, j, k] == dst[i, j, k]) @testcase def test_clean_temps_prange(int[:, :] buf): """ Try to access a buffer out of bounds in a parallel section, and make sure any temps used by the slicing processes are correctly counted. >>> A = IntMockBuffer("A", range(100), (10, 10)) >>> test_clean_temps_prange(A) acquired A released A """ cdef int i try: for i in prange(buf.shape[0], nogil=True): buf[1:10, 20] = 0 except IndexError: pass @testcase def test_clean_temps_parallel(int[:, :] buf): """ Try to access a buffer out of bounds in a parallel section, and make sure any temps used by the slicing processes are correctly counted. >>> A = IntMockBuffer("A", range(100), (10, 10)) >>> test_clean_temps_parallel(A) acquired A released A """ cdef int i try: with nogil, parallel(): try: with gil: pass for i in prange(buf.shape[0]): buf[1:10, 20] = 0 finally: buf[1:10, 20] = 0 except IndexError: pass # Test arrays in structs cdef struct ArrayStruct: int ints[10] char chars[3] cdef packed struct PackedArrayStruct: int ints[10] char chars[3] cdef fused FusedStruct: ArrayStruct PackedArrayStruct @testcase def test_memslice_struct_with_arrays(): """ >>> test_memslice_struct_with_arrays() abc abc """ cdef ArrayStruct[10] a1 cdef PackedArrayStruct[10] a2 test_structs_with_arr(a1) test_structs_with_arr(a2) cdef test_structs_with_arr(FusedStruct array[10]): cdef FusedStruct[:] myslice1, myslice2, myslice3, myslice4 cdef int i, j myslice1 = array for i in range(10): for j in range(10): myslice1[i].ints[j] = i for j in range(3): myslice1[i].chars[j] = 97 + j if (2, 7) <= sys.version_info[:2] < (3, 3): size1 = sizeof(FusedStruct) size2 = len(builtins.memoryview(myslice1)[0]) assert size1 == size2, (size1, size2, builtins.memoryview(myslice1).format) myslice2 = builtins.memoryview(myslice1) for i in range(10): assert myslice2[i].ints[i] == myslice1[i].ints[i] assert myslice2[i].chars[i] == myslice1[i].chars[i] myslice3 = myslice1 myslice4 = myslice1 for i in range(10): for j in range(10): assert myslice3[i].ints[j] == myslice4[i].ints[j] == myslice1[i].ints[j] for j in range(3): assert myslice3[i].chars[j] == myslice4[i].chars[j] == myslice1[i].chars[j] print myslice1[0].chars[:3].decode('ascii') cdef struct TestAttrs: int int_attrib char char_attrib @testcase def test_struct_attributes_format(): """ >>> test_struct_attributes_format() T{i:int_attrib:c:char_attrib:} """ cdef TestAttrs[10] array cdef TestAttrs[:] struct_memview = array if sys.version_info[:2] >= (2, 7): print builtins.memoryview(struct_memview).format else: print "T{i:int_attrib:c:char_attrib:}" # Test padding at the end of structs in the buffer support cdef struct PaddedAtEnd: int a[3] char b[3] cdef struct AlignedNested: PaddedAtEnd a char chars[1] cdef struct PaddedAtEndNormal: int a char b char c char d cdef struct AlignedNestedNormal: PaddedAtEndNormal a char chars # Test nested structs in a struct, make sure we compute padding each time # accordingly. If the first struct member is a struct, align on the first # member of that struct (recursively) cdef struct A: double d char c cdef struct B: char c1 A a char c2 cdef struct C: A a char c1 cdef struct D: B b C cstruct int a[2] char c cdef fused FusedPadded: ArrayStruct PackedArrayStruct AlignedNested AlignedNestedNormal A B C D @testcase def test_padded_structs(): """ >>> test_padded_structs() """ cdef ArrayStruct[10] a1 cdef PackedArrayStruct[10] a2 cdef AlignedNested[10] a3 cdef AlignedNestedNormal[10] a4 cdef A[10] a5 cdef B[10] a6 cdef C[10] a7 cdef D[10] a8 _test_padded(a1) _test_padded(a2) _test_padded(a3) _test_padded(a4) _test_padded(a5) _test_padded(a6) _test_padded(a7) # There is a pre-existing bug that doesn't parse the format for this # struct properly -- fix this #_test_padded(a8) cdef _test_padded(FusedPadded myarray[10]): # test that the buffer format parser accepts our format string... cdef FusedPadded[:] myslice = myarray obj = myslice cdef FusedPadded[:] myotherslice = obj @testcase def test_object_indices(): """ >>> test_object_indices() 0 1 2 """ cdef int[3] array cdef int[:] myslice = array cdef int j for i in range(3): myslice[i] = i for j in range(3): print myslice[j] cdef fused slice_1d: object int[:] cdef fused slice_2d: object int[:, :] @testcase def test_ellipsis_expr(): """ >>> test_ellipsis_expr() 8 8 """ cdef int[10] a cdef int[:] m = a _test_ellipsis_expr(m) _test_ellipsis_expr( m) cdef _test_ellipsis_expr(slice_1d m): m[4] = 8 m[...] = m[...] print m[4] @testcase def test_slice_assignment(): """ >>> test_slice_assignment() """ cdef int[10][100] carray cdef int i, j for i in range(10): for j in range(100): carray[i][j] = i * 100 + j cdef int[:, :] m = carray cdef int[:, :] copy = m[-6:-1, 60:65].copy() _test_slice_assignment(m, copy) _test_slice_assignment( m, copy) cdef _test_slice_assignment(slice_2d m, slice_2d copy): cdef int i, j m[...] = m[::-1, ::-1] m[:, :] = m[::-1, ::-1] m[-5:, -5:] = m[-6:-1, 60:65] for i in range(5): for j in range(5): assert copy[i, j] == m[-5 + i, -5 + j], (copy[i, j], m[-5 + i, -5 + j]) @testcase def test_slice_assignment_broadcast_leading(): """ >>> test_slice_assignment_broadcast_leading() """ cdef int[1][10] array1 cdef int[10] array2 cdef int i for i in range(10): array1[0][i] = i cdef int[:, :] a = array1 cdef int[:] b = array2 _test_slice_assignment_broadcast_leading(a, b) for i in range(10): array1[0][i] = i _test_slice_assignment_broadcast_leading( a, b) cdef _test_slice_assignment_broadcast_leading(slice_2d a, slice_1d b): cdef int i b[:] = a[:, :] b = b[::-1] a[:, :] = b[:] for i in range(10): assert a[0, i] == b[i] == 10 - 1 - i, (a[0, i], b[i], 10 - 1 - i) @testcase def test_slice_assignment_broadcast_strides(): """ >>> test_slice_assignment_broadcast_strides() """ cdef int[10] src_array cdef int[10][5] dst_array cdef int i, j for i in range(10): src_array[i] = 10 - 1 - i cdef int[:] src = src_array cdef int[:, :] dst = dst_array cdef int[:, :] dst_f = dst.copy_fortran() _test_slice_assignment_broadcast_strides(src, dst, dst_f) _test_slice_assignment_broadcast_strides( src, dst, dst_f) cdef _test_slice_assignment_broadcast_strides(slice_1d src, slice_2d dst, slice_2d dst_f): cdef int i, j dst[1:] = src[-1:-6:-1] dst_f[1:] = src[-1:-6:-1] for i in range(1, 10): for j in range(1, 5): assert dst[i, j] == dst_f[i, j] == j, (dst[i, j], dst_f[i, j], j) # test overlapping memory with broadcasting dst[:, 1:4] = dst[1, :3] dst_f[:, 1:4] = dst[1, 1:4] for i in range(10): for j in range(1, 3): assert dst[i, j] == dst_f[i, j] == j - 1, (dst[i, j], dst_f[i, j], j - 1) @testcase def test_borrowed_slice(): """ Test the difference between borrowed an non-borrowed slices. If you delete or assign to a slice in a cdef function, it is not borrowed. >>> test_borrowed_slice() 5 5 5 """ cdef int i cdef int[10] carray carray[:] = range(10) _borrowed(carray) _not_borrowed(carray) _not_borrowed2(carray) cdef _borrowed(int[:] m): print m[5] cdef _not_borrowed(int[:] m): print m[5] if object(): del m cdef _not_borrowed2(int[:] m): cdef int[10] carray print m[5] if object(): m = carray class SingleObject(object): def __init__(self, value): self.value = value def __str__(self): return str(self.value) def __eq__(self, other): return self.value == getattr(other, 'value', None) or self.value == other cdef _get_empty_object_slice(fill=None): cdef array a = array((10,), sizeof(PyObject *), 'O') assert a.dtype_is_object return a @testcase def test_object_dtype_copying(): """ >>> test_object_dtype_copying() 0 1 2 3 4 5 6 7 8 9 2 5 1 5 """ cdef int i unique = object() unique_refcount = get_refcount(unique) cdef object[:] m1 = _get_empty_object_slice() cdef object[:] m2 = _get_empty_object_slice() for i in range(10): m1[i] = SingleObject(i) m2[...] = m1 del m1 for i in range(10): print m2[i] obj = m2[5] print get_refcount(obj), obj del m2 print get_refcount(obj), obj assert unique_refcount == get_refcount(unique), (unique_refcount, get_refcount(unique)) @testcase def test_scalar_slice_assignment(): """ >>> test_scalar_slice_assignment() 0 1 6 3 6 5 6 7 6 9 0 1 6 3 6 5 6 7 6 9 """ cdef int[10] a cdef int[:] m = a cdef int[5][10] a2 cdef int[:, ::1] m2 = a2 _test_scalar_slice_assignment(m, m2) print _test_scalar_slice_assignment( m, m2) cdef _test_scalar_slice_assignment(slice_1d m, slice_2d m2): cdef int i, j for i in range(10): m[i] = i m[-2:0:-2] = 6 for i in range(10): print m[i] for i in range(m2.shape[0]): for j in range(m2.shape[1]): m2[i, j] = i * m2.shape[1] + j cdef int x = 2, y = -2 cdef long value = 1 m2[::2, ::-1] = value m2[-2::-2, ::-1] = 2 m2[::2, -2::-2] = 0 m2[-2::-2, -2::-2] = 0 cdef int[:, :] s = m2[..., 1::2] for i in range(s.shape[0]): for j in range(s.shape[1]): assert s[i, j] == i % 2 + 1, (s[i, j], i) s = m2[::2, 1::2] for i in range(s.shape[0]): for j in range(s.shape[1]): assert s[i, j] == 1, s[i, j] s = m2[1::2, ::2] for i in range(s.shape[0]): for j in range(s.shape[1]): assert s[i, j] == 0, s[i, j] m2[...] = 3 for i in range(m2.shape[0]): for j in range(m2.shape[1]): assert m2[i, j] == 3, s[i, j] @testcase def test_contig_scalar_to_slice_assignment(): """ >>> test_contig_scalar_to_slice_assignment() 14 14 14 14 20 20 20 20 """ cdef int[5][10] a cdef int[:, ::1] m = a m[...] = 14 print m[0, 0], m[-1, -1], m[3, 2], m[4, 9] m[:, :] = 20 print m[0, 0], m[-1, -1], m[3, 2], m[4, 9] @testcase def test_dtype_object_scalar_assignment(): """ >>> test_dtype_object_scalar_assignment() """ cdef object[:] m = array((10,), sizeof(PyObject *), 'O') m[:] = SingleObject(2) assert m[0] == m[4] == m[-1] == 2 ( m)[:] = SingleObject(3) assert m[0] == m[4] == m[-1] == 3 # ### Test slices that are set to None # # for none memoryview slice attribute testing, slicing, indexing, etc, see # nonecheck.pyx @testcase def test_coerce_to_from_None(double[:] m1, double[:] m2 = None): """ >>> test_coerce_to_from_None(None) (None, None) >>> test_coerce_to_from_None(None, None) (None, None) """ return m1, m2 @testcase def test_noneslice_compare(double[:] m): """ >>> test_noneslice_compare(None) (True, True) """ with cython.nonecheck(True): result = m is None return result, m is None cdef class NoneSliceAttr(object): cdef double[:] m @testcase def test_noneslice_ext_attr(): """ >>> test_noneslice_ext_attr() AttributeError Memoryview is not initialized None """ cdef NoneSliceAttr obj = NoneSliceAttr() with cython.nonecheck(True): try: print obj.m except Exception, e: print type(e).__name__, e.args[0] obj.m = None print obj.m @testcase def test_noneslice_del(): """ >>> test_noneslice_del() Traceback (most recent call last): ... UnboundLocalError: local variable 'm' referenced before assignment """ cdef int[10] a cdef int[:] m = a with cython.nonecheck(True): m = None del m print m @testcase def test_noneslice_nogil_check_none(double[:] m): """ >>> test_noneslice_nogil_check_none(None) (True, False) """ cdef bint is_none = False cdef bint not_none = True with nogil: is_none = m is None and None is m and m == None and None == m not_none = m is not None and None is not m and m != None and None != m return is_none, not_none @testcase def test_noneslice_not_none(double[:] m not None): """ >>> test_noneslice_not_none(None) Traceback (most recent call last): TypeError: Argument 'm' must not be None """ def get_int(): return 10 @testcase def test_inplace_assignment(): """ >>> test_inplace_assignment() 10 """ cdef int[10] a cdef int[:] m = a m[0] = get_int() print m[0] @testcase def test_newaxis(int[:] one_D): """ >>> A = IntMockBuffer("A", range(6)) >>> test_newaxis(A) acquired A 3 3 3 3 released A """ cdef int[:, :] two_D_1 = one_D[None] cdef int[:, :] two_D_2 = one_D[None, :] cdef int[:, :] two_D_3 = one_D[:, None] cdef int[:, :] two_D_4 = one_D[..., None] print two_D_1[0, 3] print two_D_2[0, 3] print two_D_3[3, 0] print two_D_4[3, 0] @testcase def test_newaxis2(int[:, :] two_D): """ >>> A = IntMockBuffer("A", range(6), shape=(3, 2)) >>> test_newaxis2(A) acquired A shape: 3 1 1 strides: 2 0 0 suboffsets: -1 -1 -1 shape: 1 2 1 strides: 0 1 0 suboffsets: -1 -1 -1 shape: 3 1 1 1 strides: 2 0 1 0 suboffsets: -1 -1 -1 -1 shape: 1 2 2 1 strides: 0 2 1 0 suboffsets: -1 -1 -1 -1 released A """ cdef int[:, :, :] a = two_D[..., None, 1, None] cdef int[:, :, :] b = two_D[None, 1, ..., None] cdef int[:, :, :, :] c = two_D[..., None, 1:, None] cdef int[:, :, :, :] d = two_D[None, 1:, ..., None] _print_attributes(a) print _print_attributes(b) print _print_attributes(c) print _print_attributes(d) Cython-0.23.4/tests/memoryview/memoryviewattrs.pyx0000644000175600017570000001655512606202452023610 0ustar jenkinsjenkins00000000000000# mode: run # tag: numpy __test__ = {} def testcase(func): __test__[func.__name__] = func.__doc__ return func cimport cython from cython.view cimport array import numpy as np cimport numpy as np @testcase def test_shape_stride_suboffset(): u''' >>> test_shape_stride_suboffset() 5 7 11 77 11 1 -1 -1 -1 5 7 11 1 5 35 -1 -1 -1 5 7 11 77 11 1 -1 -1 -1 ''' cdef char[:,:,:] larr = array((5,7,11), 1, 'c') print larr.shape[0], larr.shape[1], larr.shape[2] print larr.strides[0], larr.strides[1], larr.strides[2] print larr.suboffsets[0], larr.suboffsets[1], larr.suboffsets[2] print larr = array((5,7,11), 1, 'c', mode='fortran') print larr.shape[0], larr.shape[1], larr.shape[2] print larr.strides[0], larr.strides[1], larr.strides[2] print larr.suboffsets[0], larr.suboffsets[1], larr.suboffsets[2] print cdef char[:,:,:] c_contig = larr.copy() print c_contig.shape[0], c_contig.shape[1], c_contig.shape[2] print c_contig.strides[0], c_contig.strides[1], c_contig.strides[2] print c_contig.suboffsets[0], c_contig.suboffsets[1], c_contig.suboffsets[2] @testcase def test_copy_to(): u''' >>> test_copy_to() 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 ''' cdef int[:, :, :] from_mvs, to_mvs from_mvs = np.arange(8, dtype=np.int32).reshape(2,2,2) cdef int *from_data = from_mvs._data print ' '.join(str(from_data[i]) for i in range(2*2*2)) to_mvs = array((2,2,2), sizeof(int), 'i') to_mvs[...] = from_mvs cdef int *to_data = to_mvs._data print ' '.join(str(from_data[i]) for i in range(2*2*2)) print ' '.join(str(to_data[i]) for i in range(2*2*2)) @testcase def test_overlapping_copy(): """ >>> test_overlapping_copy() """ cdef int i, array[10] for i in range(10): array[i] = i cdef int[:] slice = array slice[...] = slice[::-1] for i in range(10): assert slice[i] == 10 - 1 - i @testcase def test_partly_overlapping(): """ >>> test_partly_overlapping() """ cdef int i, array[10] for i in range(10): array[i] = i cdef int[:] slice = array cdef int[:] slice2 = slice[:5] slice2[...] = slice[4:9] for i in range(5): assert slice2[i] == i + 4 @testcase @cython.nonecheck(True) def test_nonecheck1(): u''' >>> test_nonecheck1() Traceback (most recent call last): ... UnboundLocalError: local variable 'uninitialized' referenced before assignment ''' cdef int[:,:,:] uninitialized print uninitialized.is_c_contig() @testcase @cython.nonecheck(True) def test_nonecheck2(): u''' >>> test_nonecheck2() Traceback (most recent call last): ... UnboundLocalError: local variable 'uninitialized' referenced before assignment ''' cdef int[:,:,:] uninitialized print uninitialized.is_f_contig() @testcase @cython.nonecheck(True) def test_nonecheck3(): u''' >>> test_nonecheck3() Traceback (most recent call last): ... UnboundLocalError: local variable 'uninitialized' referenced before assignment ''' cdef int[:,:,:] uninitialized uninitialized.copy() @testcase @cython.nonecheck(True) def test_nonecheck4(): u''' >>> test_nonecheck4() Traceback (most recent call last): ... UnboundLocalError: local variable 'uninitialized' referenced before assignment ''' cdef int[:,:,:] uninitialized uninitialized.copy_fortran() @testcase @cython.nonecheck(True) def test_nonecheck5(): u''' >>> test_nonecheck5() Traceback (most recent call last): ... UnboundLocalError: local variable 'uninitialized' referenced before assignment ''' cdef int[:,:,:] uninitialized uninitialized._data @testcase def test_copy_mismatch(): u''' >>> test_copy_mismatch() Traceback (most recent call last): ... ValueError: got differing extents in dimension 0 (got 2 and 3) ''' cdef int[:,:,::1] mv1 = array((2,2,3), sizeof(int), 'i') cdef int[:,:,::1] mv2 = array((3,2,3), sizeof(int), 'i') mv1[...] = mv2 @testcase def test_is_contiguous(): u''' >>> test_is_contiguous() True True False True True False True False False True True False ''' cdef int[::1, :, :] fort_contig = array((1,1,1), sizeof(int), 'i', mode='fortran') print fort_contig.is_c_contig() , fort_contig.is_f_contig() fort_contig = array((200,100,100), sizeof(int), 'i', mode='fortran') print fort_contig.is_c_contig(), fort_contig.is_f_contig() fort_contig = fort_contig.copy() print fort_contig.is_c_contig(), fort_contig.is_f_contig() cdef int[:,:,:] strided = fort_contig print strided.is_c_contig(), strided.is_f_contig() print fort_contig = fort_contig.copy_fortran() print fort_contig.is_c_contig(), fort_contig.is_f_contig() print strided.is_c_contig(), strided.is_f_contig() @testcase def call(): u''' >>> call() 1000 2000 3000 1000 2000 3000 3000 1 1 1000 ''' cdef int[::1] mv1, mv2, mv3 cdef array arr = array((3,), sizeof(int), 'i') mv1 = arr cdef int *data data = arr.data data[0] = 1000 data[1] = 2000 data[2] = 3000 print (mv1._data)[0] , (mv1._data)[1] , (mv1._data)[2] mv2 = mv1.copy() print (mv2._data)[0] print (mv2._data)[1] , (mv2._data)[2] mv3 = mv2 cdef int *mv3_data = mv3._data print (mv1._data)[2] mv3_data[0] = 1 print (mv3._data)[0] , (mv2._data)[0] , (mv1._data)[0] @testcase def two_dee(): u''' >>> two_dee() 1 2 3 4 -4 -4 1 2 3 -4 1 2 3 -4 ''' cdef long[:,::1] mv1, mv2, mv3 cdef array arr = array((2,2), sizeof(long), 'l') cdef long *arr_data arr_data = arr.data mv1 = arr arr_data[0] = 1 arr_data[1] = 2 arr_data[2] = 3 arr_data[3] = 4 print (mv1._data)[0] , (mv1._data)[1] , (mv1._data)[2] , (mv1._data)[3] mv2 = mv1 arr_data = mv2._data arr_data[3] = -4 print (mv2._data)[3] , (mv1._data)[3] mv3 = mv2.copy() print (mv2._data)[0] , (mv2._data)[1] , (mv2._data)[2] , (mv2._data)[3] print (mv3._data)[0] , (mv3._data)[1] , (mv3._data)[2] , (mv3._data)[3] @testcase def fort_two_dee(): u''' >>> fort_two_dee() 1 2 3 4 -4 -4 1 2 3 -4 1 3 2 -4 1 2 3 -4 ''' cdef array arr = array((2,2), sizeof(long), 'l', mode='fortran') cdef long[::1,:] mv1, mv2, mv3 cdef long *arr_data arr_data = arr.data mv1 = arr arr_data[0] = 1 arr_data[1] = 2 arr_data[2] = 3 arr_data[3] = 4 print (mv1._data)[0], (mv1._data)[1], (mv1._data)[2], (mv1._data)[3] mv2 = mv1 arr_data = mv2._data arr_data[3] = -4 print (mv2._data)[3], (mv1._data)[3] mv3 = mv2.copy() print (mv2._data)[0], (mv2._data)[1], (mv2._data)[2], (mv2._data)[3] print (mv3._data)[0], (mv3._data)[1], (mv3._data)[2], (mv3._data)[3] mv3 = mv3.copy_fortran() print (mv3._data)[0], (mv3._data)[1], (mv3._data)[2], (mv3._data)[3] Cython-0.23.4/tests/memoryview/memoryview_inplace_division.pyx0000644000175600017570000000104412606202452026114 0ustar jenkinsjenkins00000000000000# mode: run # tag: memoryview, cdivision, array cimport cython from cpython.array cimport array # make Cython aware of the array type def div_memoryview(int[:] A): """ >>> from array import array >>> x = array('i', [6]) >>> div_memoryview(x) >>> x[0] 3 """ with cython.cdivision(True): A[0] /= 2 def div_buffer(object[int, ndim=1] A): """ >>> from array import array >>> x = array('i', [6]) >>> div_buffer(x) >>> x[0] 3 """ with cython.cdivision(True): A[0] /= 2 Cython-0.23.4/tests/memoryview/memoryview_in_subclasses.pyx0000644000175600017570000000212712606202452025435 0ustar jenkinsjenkins00000000000000""" Test for memory leaks when adding more memory view attributes in subtypes. """ import gc from cython.view cimport array def count_memoryviews(): gc.collect() return sum([1 if 'memoryview' in str(type(o)) else 0 for o in gc.get_objects()]) def run_test(cls, num_iters): orig_count = count_memoryviews() def f(): x = cls(1024) for i in range(num_iters): f() return count_memoryviews() - orig_count cdef class BaseType: """ >>> run_test(BaseType, 10) 0 """ cdef double[:] buffer def __cinit__(self, n): self.buffer = array((n,), sizeof(double), 'd') cdef class Subtype(BaseType): """ >>> run_test(Subtype, 10) 0 """ cdef double[:] buffer2 def __cinit__(self, n): self.buffer2 = array((n,), sizeof(double), 'd') cdef class SubtypeWithUserDealloc(BaseType): """ >>> run_test(SubtypeWithUserDealloc, 10) 0 """ cdef double[:] buffer2 def __cinit__(self, n): self.buffer2 = array((n,), sizeof(double), 'd') def __dealloc__(self): pass Cython-0.23.4/tests/memoryview/memoryview_compare_type_pointers.srctree0000644000175600017570000000306312606202452030041 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import test_compare_type_pointers" ######## setup.py ######## from Cython.Build import cythonize from distutils.core import setup setup( ext_modules = cythonize("*.pyx"), ) ######## test_compare_type_pointers.pyx ######## include "types.pxi" import other_module def test_foo_view(Foo[:] m): return m[0].f assert test_foo_view(other_module.fooview_obj) == 5.0 assert test_foo_view(other_module.otherfooview_obj) == 4.0 # Test for type comparison where the memoryview instance check succeeds cdef OtherFoo[10] otherfooarray cdef OtherFoo[:] otherfooview = otherfooarray otherfooview_obj = otherfooview otherfooview[0].f = 4.0 assert test_foo_view(otherfooview_obj) == 4.0 # Test a simple dtype now def test_double_view(double[:] m): return m[0] assert test_double_view(other_module.doubleview_obj) == 6.0 ######## other_module.pyx ######## include "types.pxi" cdef Foo[10] fooarray cdef Foo[:] fooview = fooarray fooview_obj = fooview fooview[0].f = 5.0 cdef OtherFoo[10] otherfooarray cdef OtherFoo[:] otherfooview = otherfooarray otherfooview_obj = otherfooview otherfooview[0].f = 4.0 cdef double[10] doublearray cdef double[:] doubleview = doublearray doubleview_obj = doubleview doubleview[0] = 6.0 ######## types.pxi ######## ctypedef packed struct Baz: double d ctypedef struct Bar: int i ctypedef struct Foo: float f double complex dc char c int i Bar b char s[20] ctypedef struct OtherFoo: float f double complex dc char c int i Bar b char s[20] Cython-0.23.4/tests/memoryview/memoryview_acq_count.srctree0000644000175600017570000000171312606202452025403 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import counting_atomic" PYTHON -c "import counting_locked" ######## setup.py ######## from distutils.core import setup from Cython.Distutils import build_ext from Cython.Distutils.extension import Extension setup( ext_modules = [ Extension("counting_atomic", ["counting_atomic.pyx"]), Extension("counting_locked", ["counting_locked.pyx"], define_macros=[('CYTHON_ATOMICS', '0')]) ], cmdclass={'build_ext': build_ext}, ) ######## counting_atomic.pyx ######## include "counting.pxi" ######## counting_locked.pyx ######## include "counting.pxi" ######## counting.pxi ######## cimport cython from cython.parallel cimport prange cdef int[100] a cdef int[:] m = a cdef Py_ssize_t i for i in prange(1000000, nogil=True, num_threads=16): use_slice(m[::2]) cdef int use_slice(int[:] m) nogil except -1: cdef int[:] m2 = m[1:] m = m2[:-1] del m, m2 return 0 Cython-0.23.4/tests/memoryview/memoryview.pyx0000644000175600017570000006013412606202452022522 0ustar jenkinsjenkins00000000000000# mode: run u''' >>> f() >>> g() >>> call() >>> assignmvs() ''' from cython.view cimport memoryview, array from cython cimport view from cpython.object cimport PyObject from cpython.ref cimport Py_INCREF, Py_DECREF cimport cython cdef extern from "Python.h": cdef int PyBUF_C_CONTIGUOUS include "../buffers/mockbuffers.pxi" # ### Test for some coercions # def init_obj(): return 3 cdef passmvs(float[:,::1] mvs, object foo): mvs = array((10,10), itemsize=sizeof(float), format='f') foo = init_obj() cdef object returnobj(): cdef obj = object() return obj cdef float[::1] returnmvs_inner(): return array((10,), itemsize=sizeof(float), format='f') cdef float[::1] returnmvs(): cdef float[::1] mvs = returnmvs_inner() return mvs def f(): cdef array arr = array(shape=(10,10), itemsize=sizeof(int), format='i') cdef memoryview mv = memoryview(arr, PyBUF_C_CONTIGUOUS) def g(): cdef object obj = init_obj() cdef int[::1] mview = array((10,), itemsize=sizeof(int), format='i') obj = init_obj() mview = array((10,), itemsize=sizeof(int), format='i') cdef class ExtClass(object): cdef int[::1] mview def __init__(self): self.mview = array((10,), itemsize=sizeof(int), format='i') self.mview = array((10,), itemsize=sizeof(int), format='i') class PyClass(object): def __init__(self): self.mview = array((10,), itemsize=sizeof(long), format='l') cdef cdg(): cdef double[::1] dmv = array((10,), itemsize=sizeof(double), format='d') dmv = array((10,), itemsize=sizeof(double), format='d') cdef class TestExcClassExternalDtype(object): cdef ext_dtype[:, :] arr_float cdef td_h_double[:, :] arr_double def __init__(self): self.arr_float = array((10, 10), itemsize=sizeof(ext_dtype), format='f') self.arr_float[:] = 0.0 self.arr_float[4, 4] = 2.0 self.arr_double = array((10, 10), itemsize=sizeof(td_h_double), format='d') self.arr_double[:] = 0.0 self.arr_double[4, 4] = 2.0 def test_external_dtype(): """ >>> test_external_dtype() 2.0 2.0 """ cdef TestExcClassExternalDtype obj = TestExcClassExternalDtype() print obj.arr_float[4, 4] print obj.arr_double[4, 4] cdef class ExtClassMockedAttr(object): cdef int[:, :] arr def __init__(self): self.arr = IntMockBuffer("self.arr", range(100), (10, 8)) self.arr[:] = 0 self.arr[4, 4] = 2 cdef int[:, :] _coerce_to_temp(): cdef ExtClassMockedAttr obj = ExtClassMockedAttr() return obj.arr def test_coerce_to_temp(): """ >>> test_coerce_to_temp() acquired self.arr released self.arr acquired self.arr released self.arr acquired self.arr released self.arr 2 acquired self.arr released self.arr 2 acquired self.arr released self.arr 2 """ _coerce_to_temp()[:] = 0 print _coerce_to_temp()[...] = 0 print print _coerce_to_temp()[4, 4] print print _coerce_to_temp()[..., 4][4] print print _coerce_to_temp()[4][4] def test_extclass_attribute_dealloc(): """ >>> test_extclass_attribute_dealloc() acquired self.arr 2 released self.arr """ cdef ExtClassMockedAttr obj = ExtClassMockedAttr() print obj.arr[4, 4] cdef float[:,::1] global_mv = array((10,10), itemsize=sizeof(float), format='f') global_mv = array((10,10), itemsize=sizeof(float), format='f') cdef object global_obj def assignmvs(): cdef int[::1] mv1, mv2 cdef int[:] mv3 mv1 = array((10,), itemsize=sizeof(int), format='i') mv2 = mv1 mv1 = mv2 mv3 = mv2 def call(): global global_mv passmvs(global_mv, global_obj) global_mv = array((3,3), itemsize=sizeof(float), format='f') cdef float[::1] getmvs = returnmvs() returnmvs() cdef object obj = returnobj() cdg() f = ExtClass() pf = PyClass() cdef ExtClass get_ext_obj(): print 'get_ext_obj called' return ExtClass.__new__(ExtClass) def test_cdef_attribute(): """ >>> test_cdef_attribute() Memoryview is not initialized local variable 'myview' referenced before assignment local variable 'myview' referenced before assignment get_ext_obj called Memoryview is not initialized """ cdef ExtClass extobj = ExtClass.__new__(ExtClass) try: print extobj.mview except AttributeError, e: print e.args[0] else: print "No AttributeError was raised" cdef int[:] myview try: print myview except UnboundLocalError, e: print e.args[0] else: print "No UnboundLocalError was raised" cdef int[:] otherview try: otherview = myview except UnboundLocalError, e: print e.args[0] try: print get_ext_obj().mview except AttributeError, e: print e.args[0] else: print "No AttributeError was raised" print ExtClass().mview @cython.boundscheck(False) def test_nogil_unbound_localerror(): """ >>> test_nogil_unbound_localerror() Traceback (most recent call last): ... UnboundLocalError: local variable 'm' referenced before assignment """ cdef int[:] m with nogil: m[0] = 10 def test_nogil_oob(): """ >>> test_nogil_oob() Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) """ cdef int[5] a cdef int[:] m = a with nogil: m[5] = 1 def basic_struct(MyStruct[:] mslice): """ See also buffmt.pyx >>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)])) [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] >>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="ccqii")) [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] """ buf = mslice print sorted([(k, int(v)) for k, v in buf[0].items()]) def nested_struct(NestedStruct[:] mslice): """ See also buffmt.pyx >>> nested_struct(NestedStructMockBuffer(None, [(1, 2, 3, 4, 5)])) 1 2 3 4 5 >>> nested_struct(NestedStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="T{ii}T{2i}i")) 1 2 3 4 5 """ buf = mslice d = buf[0] print d['x']['a'], d['x']['b'], d['y']['a'], d['y']['b'], d['z'] def packed_struct(PackedStruct[:] mslice): """ See also buffmt.pyx >>> packed_struct(PackedStructMockBuffer(None, [(1, 2)])) 1 2 >>> packed_struct(PackedStructMockBuffer(None, [(1, 2)], format="T{c^i}")) 1 2 >>> packed_struct(PackedStructMockBuffer(None, [(1, 2)], format="T{c=i}")) 1 2 """ buf = mslice print buf[0]['a'], buf[0]['b'] def nested_packed_struct(NestedPackedStruct[:] mslice): """ See also buffmt.pyx >>> nested_packed_struct(NestedPackedStructMockBuffer(None, [(1, 2, 3, 4, 5)])) 1 2 3 4 5 >>> nested_packed_struct(NestedPackedStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="ci^ci@i")) 1 2 3 4 5 >>> nested_packed_struct(NestedPackedStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="^c@i^ci@i")) 1 2 3 4 5 """ buf = mslice d = buf[0] print d['a'], d['b'], d['sub']['a'], d['sub']['b'], d['c'] def complex_dtype(long double complex[:] mslice): """ >>> complex_dtype(LongComplexMockBuffer(None, [(0, -1)])) -1j """ buf = mslice print buf[0] def complex_inplace(long double complex[:] mslice): """ >>> complex_inplace(LongComplexMockBuffer(None, [(0, -1)])) (1+1j) """ buf = mslice buf[0] = buf[0] + 1 + 2j print buf[0] def complex_struct_dtype(LongComplex[:] mslice): """ Note that the format string is "Zg" rather than "2g", yet a struct is accessed. >>> complex_struct_dtype(LongComplexMockBuffer(None, [(0, -1)])) 0.0 -1.0 """ buf = mslice print buf[0]['real'], buf[0]['imag'] # # Getting items and index bounds checking # def get_int_2d(int[:, :] mslice, int i, int j): """ >>> C = IntMockBuffer("C", range(6), (2,3)) >>> get_int_2d(C, 1, 1) acquired C released C 4 Check negative indexing: >>> get_int_2d(C, -1, 0) acquired C released C 3 >>> get_int_2d(C, -1, -2) acquired C released C 4 >>> get_int_2d(C, -2, -3) acquired C released C 0 Out-of-bounds errors: >>> get_int_2d(C, 2, 0) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) >>> get_int_2d(C, 0, -4) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 1) """ buf = mslice return buf[i, j] def set_int_2d(int[:, :] mslice, int i, int j, int value): """ Uses get_int_2d to read back the value afterwards. For pure unit test, one should support reading in MockBuffer instead. >>> C = IntMockBuffer("C", range(6), (2,3)) >>> set_int_2d(C, 1, 1, 10) acquired C released C >>> get_int_2d(C, 1, 1) acquired C released C 10 Check negative indexing: >>> set_int_2d(C, -1, 0, 3) acquired C released C >>> get_int_2d(C, -1, 0) acquired C released C 3 >>> set_int_2d(C, -1, -2, 8) acquired C released C >>> get_int_2d(C, -1, -2) acquired C released C 8 >>> set_int_2d(C, -2, -3, 9) acquired C released C >>> get_int_2d(C, -2, -3) acquired C released C 9 Out-of-bounds errors: >>> set_int_2d(C, 2, 0, 19) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) >>> set_int_2d(C, 0, -4, 19) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 1) """ buf = mslice buf[i, j] = value # # Test all kinds of indexing and flags # def writable(unsigned short int[:, :, :] mslice): """ >>> R = UnsignedShortMockBuffer("R", range(27), shape=(3, 3, 3)) >>> writable(R) acquired R released R >>> [str(x) for x in R.recieved_flags] # Py2/3 ['FORMAT', 'ND', 'STRIDES', 'WRITABLE'] """ buf = mslice buf[2, 2, 1] = 23 def strided(int[:] mslice): """ >>> A = IntMockBuffer("A", range(4)) >>> strided(A) acquired A released A 2 Check that the suboffsets were patched back prior to release. >>> A.release_ok True """ buf = mslice return buf[2] def c_contig(int[::1] mslice): """ >>> A = IntMockBuffer(None, range(4)) >>> c_contig(A) 2 """ buf = mslice return buf[2] def c_contig_2d(int[:, ::1] mslice): """ Multi-dim has seperate implementation >>> A = IntMockBuffer(None, range(12), shape=(3,4)) >>> c_contig_2d(A) 7 """ buf = mslice return buf[1, 3] def f_contig(int[::1, :] mslice): """ >>> A = IntMockBuffer(None, range(4), shape=(2, 2), strides=(1, 2)) >>> f_contig(A) 2 """ buf = mslice return buf[0, 1] def f_contig_2d(int[::1, :] mslice): """ Must set up strides manually to ensure Fortran ordering. >>> A = IntMockBuffer(None, range(12), shape=(4,3), strides=(1, 4)) >>> f_contig_2d(A) 7 """ buf = mslice return buf[3, 1] def generic(int[::view.generic, ::view.generic] mslice1, int[::view.generic, ::view.generic] mslice2): """ >>> A = IntMockBuffer("A", [[0,1,2], [3,4,5], [6,7,8]]) >>> B = IntMockBuffer("B", [[0,1,2], [3,4,5], [6,7,8]], shape=(3, 3), strides=(1, 3)) >>> generic(A, B) acquired A acquired B 4 4 10 11 released A released B """ buf1, buf2 = mslice1, mslice2 print buf1[1, 1] print buf2[1, 1] buf1[2, -1] = 10 buf2[2, -1] = 11 print buf1[2, 2] print buf2[2, 2] #def generic_contig(int[::view.generic_contiguous, :] mslice1, # int[::view.generic_contiguous, :] mslice2): # """ # >>> A = IntMockBuffer("A", [[0,1,2], [3,4,5], [6,7,8]]) # >>> B = IntMockBuffer("B", [[0,1,2], [3,4,5], [6,7,8]], shape=(3, 3), strides=(1, 3)) # >>> generic_contig(A, B) # acquired A # acquired B # 4 # 4 # 10 # 11 # released A # released B # """ # buf1, buf2 = mslice1, mslice2 # # print buf1[1, 1] # print buf2[1, 1] # # buf1[2, -1] = 10 # buf2[2, -1] = 11 # # print buf1[2, 2] # print buf2[2, 2] ctypedef int td_cy_int cdef extern from "bufaccess.h": ctypedef td_cy_int td_h_short # Defined as short, but Cython doesn't know this! ctypedef float td_h_double # Defined as double ctypedef unsigned int td_h_ushort # Defined as unsigned short ctypedef td_h_short td_h_cy_short def printbuf_td_cy_int(td_cy_int[:] mslice, shape): """ >>> printbuf_td_cy_int(IntMockBuffer(None, range(3)), (3,)) 0 1 2 END >>> printbuf_td_cy_int(ShortMockBuffer(None, range(3)), (3,)) Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'td_cy_int' but got 'short' """ buf = mslice cdef int i for i in range(shape[0]): print buf[i], print 'END' def printbuf_td_h_short(td_h_short[:] mslice, shape): """ >>> printbuf_td_h_short(ShortMockBuffer(None, range(3)), (3,)) 0 1 2 END >>> printbuf_td_h_short(IntMockBuffer(None, range(3)), (3,)) Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'td_h_short' but got 'int' """ buf = mslice cdef int i for i in range(shape[0]): print buf[i], print 'END' def printbuf_td_h_cy_short(td_h_cy_short[:] mslice, shape): """ >>> printbuf_td_h_cy_short(ShortMockBuffer(None, range(3)), (3,)) 0 1 2 END >>> printbuf_td_h_cy_short(IntMockBuffer(None, range(3)), (3,)) Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'td_h_cy_short' but got 'int' """ buf = mslice cdef int i for i in range(shape[0]): print buf[i], print 'END' def printbuf_td_h_ushort(td_h_ushort[:] mslice, shape): """ >>> printbuf_td_h_ushort(UnsignedShortMockBuffer(None, range(3)), (3,)) 0 1 2 END >>> printbuf_td_h_ushort(ShortMockBuffer(None, range(3)), (3,)) Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'td_h_ushort' but got 'short' """ buf = mslice cdef int i for i in range(shape[0]): print buf[i], print 'END' def printbuf_td_h_double(td_h_double[:] mslice, shape): """ >>> printbuf_td_h_double(DoubleMockBuffer(None, [0.25, 1, 3.125]), (3,)) 0.25 1.0 3.125 END >>> printbuf_td_h_double(FloatMockBuffer(None, [0.25, 1, 3.125]), (3,)) Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'td_h_double' but got 'float' """ buf = mslice cdef int i for i in range(shape[0]): print buf[i], print 'END' # # Object access # def addref(*args): for item in args: Py_INCREF(item) def decref(*args): for item in args: Py_DECREF(item) def get_refcount(x): return (x).ob_refcnt def printbuf_object(object[:] mslice, shape): """ Only play with unique objects, interned numbers etc. will have unpredictable refcounts. ObjectMockBuffer doesn't do anything about increfing/decrefing, we to the "buffer implementor" refcounting directly in the testcase. >>> a, b, c = "globally_unique_string_23234123", {4:23}, [34,3] >>> get_refcount(a), get_refcount(b), get_refcount(c) (2, 2, 2) >>> A = ObjectMockBuffer(None, [a, b, c]) >>> printbuf_object(A, (3,)) 'globally_unique_string_23234123' 2 {4: 23} 2 [34, 3] 2 """ buf = mslice cdef int i for i in range(shape[0]): print repr(buf[i]), (buf[i]).ob_refcnt def assign_to_object(object[:] mslice, int idx, obj): """ See comments on printbuf_object above. >>> a, b = [1, 2, 3], [4, 5, 6] >>> get_refcount(a), get_refcount(b) (2, 2) >>> addref(a) >>> A = ObjectMockBuffer(None, [1, a]) # 1, ...,otherwise it thinks nested lists... >>> get_refcount(a), get_refcount(b) (3, 2) >>> assign_to_object(A, 1, b) >>> get_refcount(a), get_refcount(b) (2, 3) >>> decref(b) """ buf = mslice buf[idx] = obj def assign_temporary_to_object(object[:] mslice): """ See comments on printbuf_object above. >>> a, b = [1, 2, 3], {4:23} >>> get_refcount(a) 2 >>> addref(a) >>> A = ObjectMockBuffer(None, [b, a]) >>> get_refcount(a) 3 >>> assign_temporary_to_object(A) >>> get_refcount(a) 2 >>> printbuf_object(A, (2,)) {4: 23} 2 {1: 8} 2 To avoid leaking a reference in our testcase we need to replace the temporary with something we can manually decref :-) >>> assign_to_object(A, 1, a) >>> decref(a) """ buf = mslice buf[1] = {3-2: 2+(2*4)-2} def test_generic_slicing(arg, indirect=False): """ Test simple slicing >>> test_generic_slicing(IntMockBuffer("A", range(8 * 14 * 11), shape=(8, 14, 11))) acquired A (3, 9, 2) 308 -11 1 -1 -1 -1 released A Test direct slicing, negative slice oob in dim 2 >>> test_generic_slicing(IntMockBuffer("A", range(1 * 2 * 3), shape=(1, 2, 3))) acquired A (0, 0, 2) 12 -3 1 -1 -1 -1 released A Test indirect slicing >>> test_generic_slicing(IntMockBuffer("A", shape_5_3_4_list, shape=(5, 3, 4)), indirect=True) acquired A (2, 0, 2) 0 1 -1 released A >>> stride1 = 21 * 14 >>> stride2 = 21 >>> test_generic_slicing(IntMockBuffer("A", shape_9_14_21_list, shape=(9, 14, 21)), indirect=True) acquired A (3, 9, 2) 10 1 -1 released A """ cdef int[::view.generic, ::view.generic, :] _a = arg a = _a b = a[2:8:2, -4:1:-1, 1:3] print b.shape if indirect: print b.suboffsets[0] // sizeof(int *), print b.suboffsets[1] // sizeof(int), print b.suboffsets[2] else: print_int_offsets(b.strides[0], b.strides[1], b.strides[2]) print_int_offsets(b.suboffsets[0], b.suboffsets[1], b.suboffsets[2]) cdef int i, j, k for i in range(b.shape[0]): for j in range(b.shape[1]): for k in range(b.shape[2]): itemA = a[2 + 2 * i, -4 - j, 1 + k] itemB = b[i, j, k] assert itemA == itemB, (i, j, k, itemA, itemB) def test_indirect_slicing(arg): """ Test indirect slicing >>> test_indirect_slicing(IntMockBuffer("A", shape_5_3_4_list, shape=(5, 3, 4))) acquired A (5, 3, 2) 0 0 -1 58 56 58 58 58 58 released A >>> test_indirect_slicing(IntMockBuffer("A", shape_9_14_21_list, shape=(9, 14, 21))) acquired A (5, 14, 3) 0 16 -1 2412 2410 2412 2412 2412 2412 released A """ cdef int[::view.indirect, ::view.indirect, :] _a = arg a = _a b = a[-5:, ..., -5:100:2] print b.shape print_int_offsets(*b.suboffsets) print b[4, 2, 1] print b[..., 0][4, 2] print b[..., 1][4, 2] print b[..., 1][4][2] print b[4][2][1] print b[4, 2][1] def test_direct_slicing(arg): """ Fused types would be convenient to test this stuff! Test simple slicing >>> test_direct_slicing(IntMockBuffer("A", range(8 * 14 * 11), shape=(8, 14, 11))) acquired A (3, 9, 2) 308 -11 1 -1 -1 -1 released A Test direct slicing, negative slice oob in dim 2 >>> test_direct_slicing(IntMockBuffer("A", range(1 * 2 * 3), shape=(1, 2, 3))) acquired A (0, 0, 2) 12 -3 1 -1 -1 -1 released A """ cdef int[:, :, :] _a = arg a = _a b = a[2:8:2, -4:1:-1, 1:3] print b.shape print_int_offsets(*b.strides) print_int_offsets(*b.suboffsets) cdef int i, j, k for i in range(b.shape[0]): for j in range(b.shape[1]): for k in range(b.shape[2]): itemA = a[2 + 2 * i, -4 - j, 1 + k] itemB = b[i, j, k] assert itemA == itemB, (i, j, k, itemA, itemB) def test_slicing_and_indexing(arg): """ >>> a = IntStridedMockBuffer("A", range(10 * 3 * 5), shape=(10, 3, 5)) >>> test_slicing_and_indexing(a) acquired A (5, 2) 15 2 126 113 [111] released A """ cdef int[:, :, :] _a = arg a = _a b = a[-5:, 1, 1::2] c = b[4:1:-1, ::-1] d = c[2, 1:2] print b.shape print_int_offsets(*b.strides) cdef int i, j for i in range(b.shape[0]): for j in range(b.shape[1]): itemA = a[-5 + i, 1, 1 + 2 * j] itemB = b[i, j] assert itemA == itemB, (i, j, itemA, itemB) print c[1, 1], c[2, 0] print [d[i] for i in range(d.shape[0])] def test_oob(): """ >>> test_oob() Traceback (most recent call last): ... IndexError: Index out of bounds (axis 1) """ cdef int[:, :] a = IntMockBuffer("A", range(4 * 9), shape=(4, 9)) print a[:, 20] def test_acquire_memoryview(): """ Segfaulting in 3.2? >> test_acquire_memoryview() acquired A 22 22 22 released A """ cdef int[:, :] a = IntMockBuffer("A", range(4 * 9), shape=(4, 9)) cdef object b = a print a[2, 4] # Make sure we don't have to keep this around del a print b cdef int[:, :] c = b print b[2, 4] print c[2, 4] def test_acquire_memoryview_slice(): """ >>> test_acquire_memoryview_slice() acquired A 31 31 31 released A """ cdef int[:, :] a = IntMockBuffer("A", range(4 * 9), shape=(4, 9)) a = a[1:, :6] cdef object b = a print a[2, 4] # Make sure we don't have to keep this around del a print b cdef int[:, :] c = b print b[2, 4] print c[2, 4] class SingleObject(object): def __init__(self, value): self.value = value def __str__(self): return str(self.value) def __eq__(self, other): return self.value == getattr(other, 'value', None) or self.value == other def test_assign_scalar(int[:, :] m): """ >>> A = IntMockBuffer("A", [0] * 100, shape=(10, 10)) >>> test_assign_scalar(A) acquired A 1 1 1 4 1 6 1 1 1 1 2 2 2 4 2 6 2 2 2 2 3 3 3 4 3 6 3 3 3 3 1 1 1 4 1 6 1 1 1 1 5 5 5 5 5 6 5 5 5 5 1 1 1 4 1 6 1 1 1 1 released A """ m[:, :] = 1 m[1, :] = 2 m[2, :] = 3 m[:, 3] = 4 m[4, ...] = 5 m[..., 5] = 6 for i in range(6): print " ".join([str(m[i, j]) for j in range(m.shape[1])]) def test_contig_scalar_to_slice_assignment(): """ >>> test_contig_scalar_to_slice_assignment() 14 14 14 14 20 20 20 20 """ cdef int[5][10] a cdef int[:, ::1] _m = a m = _m m[...] = 14 print m[0, 0], m[-1, -1], m[3, 2], m[4, 9] m[:, :] = 20 print m[0, 0], m[-1, -1], m[3, 2], m[4, 9] def test_dtype_object_scalar_assignment(): """ >>> test_dtype_object_scalar_assignment() """ cdef object[:] m = array((10,), sizeof(PyObject *), 'O') m[:] = SingleObject(2) assert m[0] == m[4] == m[-1] == 2 ( m)[:] = SingleObject(3) assert m[0] == m[4] == m[-1] == 3 def test_assignment_in_conditional_expression(bint left): """ >>> test_assignment_in_conditional_expression(True) 1.0 2.0 1.0 2.0 >>> test_assignment_in_conditional_expression(False) 3.0 4.0 3.0 4.0 """ cdef double a[2] cdef double b[2] a[:] = [1, 2] b[:] = [3, 4] cdef double[:] A = a cdef double[:] B = b cdef double[:] C, c # assign new memoryview references C = A if left else B for i in range(C.shape[0]): print C[i] # create new memoryviews c = a if left else b for i in range(c.shape[0]): print c[i] def test_cpython_offbyone_issue_23349(): """ >>> print(test_cpython_offbyone_issue_23349()) testing """ cdef unsigned char[:] v = bytearray(b"testing") # the following returns 'estingt' without the workaround return bytearray(v).decode('ascii') cdef int min_max_tree_restructuring(): """ >>> min_max_tree_restructuring() """ cdef char a[5] a = [1, 2, 3, 4, 5] cdef char[:] aview = a return max(1, aview[0]) Cython-0.23.4/tests/memoryview/memoryview.pxd0000644000175600017570000000013112606202452022464 0ustar jenkinsjenkins00000000000000ctypedef float ext_dtype cdef extern from "bufaccess.h": ctypedef float td_h_double Cython-0.23.4/tests/memoryview/extension_type_memoryview.pyx0000644000175600017570000000120012606202452025644 0ustar jenkinsjenkins00000000000000# mode: run # tag: numpy cimport numpy as np import numpy as np cdef class ExtensionType(object): cdef public int dummy def __init__(self, n): self.dummy = n items = [ExtensionType(1), ExtensionType(2)] cdef ExtensionType[:] view = np.array(items, dtype=ExtensionType) def test_getitem(): """ >>> test_getitem() 1 2 """ for i in range(view.shape[0]): item = view[i] print item.dummy def test_getitem_typed(): """ >>> test_getitem_typed() 1 2 """ cdef ExtensionType item for i in range(view.shape[0]): item = view[i] print item.dummy Cython-0.23.4/tests/memoryview/error_declarations.pyx0000644000175600017570000000617112606202452024201 0ustar jenkinsjenkins00000000000000# mode: error cimport cython from cython cimport view cdef signed short[::1, ::1] both cdef signed short[::1, :, :, ::1] both2 cdef signed char[::2] err0 cdef signed char[::-100] err1 cdef signed char[::-1] err2 cdef long long[01::1, 0x01:, '0' :, False:] fort_contig0 cdef signed char[1::] bad_start cdef unsigned long[:,:1] bad_stop cdef unsigned long[:,::1,:] neither_c_or_f cdef signed char[::1-1+1] expr_spec cdef signed char[::blargh] bad_name cdef double[::alist[0]['view'].full] expr_attribute cdef object[::1, :] unconformable1 = object() cdef object[:, ::1] unconformable2 = unconformable1 cdef int[::1, :] dtype_unconformable = object() unconformable1 = dtype_unconformable # These are INVALID cdef int[::view.contiguous, ::1] a1 #cdef int[::view.generic_contiguous, ::1] a2 #cdef int[::view.contiguous, ::view.generic_contiguous] a3 #cdef int[::view.generic_contiguous, ::view.generic_contiguous] a4 cdef int[::view.contiguous, ::view.contiguous] a5 cdef int[:, ::view.contiguous, ::view.indirect_contiguous] a6 #cdef int[::view.generic_contiguous, ::view.contiguous] a7 #cdef int[::view.contiguous, ::view.generic_contiguous] a8 ctypedef int *intp cdef intp[:, :] myarray cdef int[:] a10 = object() cdef int[:] a11 = 1 cdef struct Valid: int array[1][2][3][4][5][6][7][8] cdef struct Invalid: int array[1][2][3][4][5][6][7][8][9] cdef Valid[:] validslice cdef Invalid[:] invalidslice cdef int[:, :, :, :] four_D four_D[None, None, None, None] four_D[None, None, None, None, None] cdef int[:, :, :, :, :, :, :, :] eight_D = object() cdef double[:] m print &m # These are VALID cdef int[::view.indirect_contiguous, ::view.contiguous] a9 four_D[None, None, None] _ERRORS = u''' 11:25: Cannot specify an array that is both C and Fortran contiguous. 12:31: Cannot specify an array that is both C and Fortran contiguous. 13:19: Step must be omitted, 1, or a valid specifier. 14:20: Step must be omitted, 1, or a valid specifier. 15:20: Step must be omitted, 1, or a valid specifier. 16:17: Start must not be given. 17:18: Start must not be given. 18:22: Axis specification only allowed in the 'step' slot. 19:19: Fortran contiguous specifier must follow an indirect dimension 20:22: Invalid axis specification. 21:25: Invalid axis specification. 22:22: no expressions allowed in axis spec, only names and literals. 25:51: Memoryview 'object[::1, :]' not conformable to memoryview 'object[:, ::1]'. 28:36: Different base types for memoryviews (int, Python object) 31:9: Dimension may not be contiguous 37:9: Only one direct contiguous axis may be specified. 38:9:Only dimensions 3 and 2 may be contiguous and direct 44:10: Invalid base type for memoryview slice: intp 46:35: Can only create cython.array from pointer or array 47:24: Cannot assign type 'double' to 'Py_ssize_t' 55:13: Invalid base type for memoryview slice: Invalid 58:6: More dimensions than the maximum number of buffer dimensions were used. 59:6: More dimensions than the maximum number of buffer dimensions were used. 61:9: More dimensions than the maximum number of buffer dimensions were used. 64:13: Cannot take address of memoryview slice ''' Cython-0.23.4/tests/memoryview/cythonarray.pyx0000644000175600017570000001131012606202452022652 0ustar jenkinsjenkins00000000000000# mode: run from __future__ import unicode_literals from cython.view cimport array from cython cimport view as v cimport cython as cy include "cythonarrayutil.pxi" def contiguity(): ''' >>> contiguity() 12 4 2 3 2 4 8 2 3 2 ''' cdef v.array cvarray = v.array(shape=(2,3), itemsize=sizeof(int), format="i", mode='c') assert cvarray.len == 2*3*sizeof(int), (cvarray.len, 2*3*sizeof(int)) assert cvarray.itemsize == sizeof(int) print cvarray.strides[0], cvarray.strides[1] print cvarray.shape[0], cvarray.shape[1] print cvarray.ndim print cdef v.array farray = v.array(shape=(2,3), itemsize=sizeof(int), format="i", mode='fortran') assert farray.len == 2*3*sizeof(int) assert farray.itemsize == sizeof(int) print farray.strides[0], farray.strides[1] print farray.shape[0], farray.shape[1] print farray.ndim def acquire(): ''' >>> acquire() ''' cdef object[int, ndim=1, mode="c"] buf1d = \ array(shape=(10,), itemsize=sizeof(int), format='i', mode='c') cdef object[int, ndim=2, mode="c"] buf2d = \ array(shape=(10,10), itemsize=sizeof(int), format='i') cdef object[unsigned long, ndim=3, mode='fortran'] buf3d = \ array(shape=(1,2,3), itemsize=sizeof(unsigned long), format='L', mode='fortran') cdef object[long double, ndim=3, mode='fortran'] bufld = \ array(shape=(1,2,3), itemsize=sizeof(long double), format='g', mode='fortran') def full_or_strided(): ''' >>> full_or_strided() ''' cdef object[float, ndim=2, mode='full'] fullbuf = \ array(shape=(10,10), itemsize=sizeof(float), format='f', mode='c') cdef object[long long int, ndim=3, mode='strided'] stridedbuf = \ array(shape=(1,2,3), itemsize=sizeof(long long int), format='q', mode='fortran') def dont_allocate_buffer(): """ >>> dont_allocate_buffer() callback called """ cdef array result = array((10, 10), itemsize=sizeof(int), format='i', allocate_buffer=False) assert result.data == NULL result.callback_free_data = callback result = None def test_cython_array_getbuffer(): """ >>> test_cython_array_getbuffer() 98 61 98 61 """ cdef int[:, ::1] cslice = create_array((14, 10), 'c') cdef int[::1, :] fslice = create_array((14, 10), 'fortran') print cslice[9, 8] print cslice[6, 1] print fslice[9, 8] print fslice[6, 1] def test_cython_array_index(): """ >>> test_cython_array_index() 98 61 98 61 """ c_array = create_array((14, 10), 'c') f_array = create_array((14, 10), 'fortran') print c_array[9, 8] print c_array[6, 1] print f_array[9, 8] print f_array[6, 1] cdef int *getp(int dim1=10, int dim2=10, dim3=1) except NULL: print "getp()" cdef int *p = malloc(dim1 * dim2 * dim3 * sizeof(int)) if p == NULL: raise MemoryError for i in range(dim1 * dim2 * dim3): p[i] = i return p cdef void callback_free_data(void *p): print 'callback free data called' free(p) def test_array_from_pointer(): """ >>> test_array_from_pointer() getp() 69 c getp() callback free data called fortran getp() 56 getp() 56 getp() 119 callback free data called """ cdef int *p = getp() cdef array c_arr = p c_arr.callback_free_data = callback_free_data print c_arr[6, 9] print c_arr.mode c_arr = ( getp()) print c_arr.mode c_arr.callback_free_data = free c_arr = getp() c_arr.callback_free_data = free cdef int[:, ::1] mslice = c_arr print mslice[5, 6] c_arr = getp(12, 10) c_arr.callback_free_data = free print c_arr[5, 6] cdef int m = 12 cdef int n = 10 c_arr = getp(m, n) c_arr.callback_free_data = callback_free_data print c_arr[m - 1, n - 1] def test_array_from_pointer_3d(): """ >>> test_array_from_pointer_3d() getp() 3 3 True True """ cdef int *p = getp(2, 2, 2) cdef array c_arr = p cdef array f_arr = p cdef int[:, :, ::1] m1 = c_arr cdef int[::1, :, :] m2 = f_arr print m1[0, 1, 1], m2[1, 1, 0] print m1.is_c_contig(), m2.is_f_contig() def test_cyarray_from_carray(): """ >>> test_cyarray_from_carray() 0 8 21 0 8 21 """ cdef int[7][8] a for i in range(7): for j in range(8): a[i][j] = i * 8 + j cdef int[:, :] mslice = a print mslice[0, 0], mslice[1, 0], mslice[2, 5] mslice = a print mslice[0, 0], mslice[1, 0], mslice[2, 5] Cython-0.23.4/tests/memoryview/compile_declarations.pyx0000644000175600017570000000441312606202452024475 0ustar jenkinsjenkins00000000000000# mode: compile cimport cython # from cython.view cimport contig as foo, full as bar #, follow from cython cimport view from cython.view cimport (generic, strided, indirect, contiguous, indirect_contiguous) cdef char[:] one_dim cdef char[:,:,:] three_dim cdef unsigned int[::1, :] view1 cdef unsigned int[:, ::1] view2 cdef long long[::1, :, :, :] fort_contig cdef unsigned long[:, :, :, ::1] c_contig cdef unsigned short int[::1] c_and_fort cdef unsigned long[:, :, :, ::0x0001] c_contig0 cdef int[::generic, ::generic] a1 cdef int[::strided, ::generic] a2 cdef int[::indirect, ::generic] a3 cdef int[::generic, ::strided] a4 cdef int[::strided, ::strided] a5 cdef int[::indirect, ::strided] a6 cdef int[::generic, ::indirect] a7 cdef int[::strided, ::indirect] a8 cdef int[::indirect, ::indirect] a9 cdef int[::generic, ::contiguous] a13 cdef int[::strided, ::contiguous] a14 cdef int[::indirect, ::contiguous] a15 cdef int[::generic, ::indirect_contiguous] a16 cdef int[::strided, ::indirect_contiguous] a17 cdef int[::indirect, ::indirect_contiguous] a18 cdef int[::generic, ::] a19 cdef int[::strided, :] a20 cdef int[::indirect, :] a21 cdef int[::contiguous, :] a23 cdef int[::indirect_contiguous, :] a24 cdef int[::indirect_contiguous, ::1] a25 cdef int[::indirect_contiguous, ::1, :] a26 cdef int[::indirect_contiguous, :, ::1] a27 cdef int[::indirect_contiguous, ::1, :] a28 cdef int[::indirect_contiguous, ::view.contiguous, :] a29 cdef int[::indirect_contiguous, :, ::view.contiguous] a30 cdef int[::indirect, ::1] a31 cdef int[::indirect, ::1, :] a32 = object() cdef int[::indirect, :, ::1] a33 = object() cdef int[::indirect, ::1, :] a34 cdef int[::indirect, ::view.contiguous, :] a35 cdef int[::indirect, :, ::view.contiguous] a36 cdef int[::1, :] my_f_contig = a32[0] cdef int[:, ::1] my_c_contig = a33[0] my_f_contig = a32[0, :, :] my_c_contig = a33[0, :, :] my_f_contig = a32[0, ...] my_c_contig = a33[0, ...] # Test casting to cython.view.array cdef double[:, :] m1 = NULL cdef double[:, :] m2 = NULL cdef double[:, :] m3 = NULL cdef double[:, :, :] m4 = NULL cdef double[:, :, :] m5 = NULL cdef double[:, :, :] m6 = NULL Cython-0.23.4/tests/memoryview/bufaccess.h0000644000175600017570000000016312606202452021660 0ustar jenkinsjenkins00000000000000/* See bufaccess.pyx */ typedef short td_h_short; typedef double td_h_double; typedef unsigned short td_h_ushort; Cython-0.23.4/tests/errors/0000755000175600017570000000000012606202455016665 5ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/errors/wraparound_warnings.pyx0000644000175600017570000000406412606202452023522 0ustar jenkinsjenkins00000000000000# mode: error # tag: werror cimport cython s = "abc" l = [1, 2, 3] def normal_wraparound(int i, bytes B not None, list L not None): a = s[:] a = s[1:2] a = s[-2:-1] a = "abc"[-2:-1] a = "abc"[-2:i] a = B[-2:-1] a = B[:-1] a = B[-2:] b = l[1:2] b = l[:2] b = l[1:] b = l[-2:-1] b = [1, 2, 3][-2:-1] b = [1, 2, 3][-2:i] b = L[-2:-1] @cython.wraparound(False) def no_wraparound(int i, bytes B not None, list L not None): a = s[:] a = s[1:2] a = s[-2:-1] a = "abc"[-2:-1] # evaluated at compile time a = "abc"[-2:i] a = B[:] a = B[-2:-1] a = B[:-1] a = B[-2:] b = l[1:2] b = l[:2] b = l[1:] b = l[-2:-1] b = [1, 2, 3][-2:i] b = L[-2:-1] _ERRORS = """ 31:11: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined 31:14: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined 33:15: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined 35:11: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined 35:14: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined 36:12: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined 37:11: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined 42:11: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined 42:14: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined 43:19: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined 44:11: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined 44:14: the result of using negative indices inside of code sections marked as 'wraparound=False' is undefined """ Cython-0.23.4/tests/errors/w_unused.pyx0000644000175600017570000000216112606202452021255 0ustar jenkinsjenkins00000000000000# cython: warn.unused=True, warn.unused_arg=True, warn.unused_result=True # mode: error # tag: werror def unused_variable(): a = 1 def unused_cascade(arg): a, b = arg.split() return a def unused_arg(arg): pass def unused_result(): r = 1 + 1 r = 2 return r def unused_nested(): def _unused_one(): pass def unused_class(): class Unused: pass # this should not generate warning def used(x, y): x.y = 1 y[0] = 1 lambda x: x def unused_and_unassigned(): cdef object foo cdef int i def unused_generic(*args, **kwargs): pass def unused_in_closure(a,b,c): x = 1 def inner(): nonlocal c c = 1 y = 2 return a+b return inner() _ERRORS = """ 6:6: Unused entry 'a' 9:9: Unused entry 'b' 12:15: Unused argument 'arg' 16:6: Unused result in 'r' 21:4: Unused entry '_unused_one' 25:4: Unused entry 'Unused' 35:16: Unused entry 'foo' 36:13: Unused entry 'i' 38:20: Unused argument 'args' 38:28: Unused argument 'kwargs' 41:26: Unused argument 'c' 41:26: Unused entry 'c' 42:6: Unused entry 'x' 46:10: Unused entry 'y' """ Cython-0.23.4/tests/errors/w_unreachable_cf.pyx0000644000175600017570000000122212606202452022670 0ustar jenkinsjenkins00000000000000# mode: error # tag: werror, unreachable, control-flow def try_finally(): try: return finally: return print 'oops' def try_return(): try: return except: return print 'oops' def for_return(a): for i in a: return else: return print 'oops' def while_return(a): while a: return else: return print 'oops' def forfrom_return(a): for i from 0 <= i <= a: return else: return print 'oops' _ERRORS = """ 9:4: Unreachable code 16:4: Unreachable code 23:4: Unreachable code 30:4: Unreachable code 37:4: Unreachable code """ Cython-0.23.4/tests/errors/w_unreachable.pyx0000644000175600017570000000115612606202452022226 0ustar jenkinsjenkins00000000000000# mode: error # tag: werror def simple_return(): return print 'Where am I?' def simple_loops(*args): for i in args: continue print 'Never be here' while True: break print 'Never be here' def conditional(a, b): if a: return 1 elif b: return 2 else: return 3 print 'oops' def try_except(): try: raise TypeError except ValueError: pass else: print 'unreachable' _ERRORS = """ 6:4: Unreachable code 11:8: Unreachable code 15:8: Unreachable code 24:4: Unreachable code 32:8: Unreachable code """ Cython-0.23.4/tests/errors/w_uninitialized_with.pyx0000644000175600017570000000103512606202452023654 0ustar jenkinsjenkins00000000000000# cython: warn.maybe_uninitialized=True # mode: error # tag: werror def with_no_target(m): with m: print a a = 1 def unbound_manager(m1): with m2: pass m2 = m1 def with_target(m): with m as f: print(f) def with_mgr(m): try: with m() as f: pass except: print f _ERRORS = """ 7:15: local variable 'a' referenced before assignment 11:11: local variable 'm2' referenced before assignment 24:15: local variable 'f' might be referenced before assignment """ Cython-0.23.4/tests/errors/w_uninitialized_while.pyx0000644000175600017570000000217412606202452024016 0ustar jenkinsjenkins00000000000000# cython: warn.maybe_uninitialized=True # mode: error # tag: werror def simple_while(n): while n > 0: n -= 1 a = 0 return a def simple_while_break(n): while n > 0: n -= 1 break else: a = 1 return a def simple_while_pos(n): while n > 0: n -= 1 a = 0 else: a = 1 return a def while_finally_continue(p, f): while p(): try: x = f() finally: print x continue def while_finally_break(p, f): while p(): try: x = f() finally: print x break def while_finally_outer(p, f): x = 1 try: while p(): print x x = f() if x > 0: continue if x < 0: break finally: del x _ERRORS = """ 9:12: local variable 'a' might be referenced before assignment 17:12: local variable 'a' might be referenced before assignment 32:19: local variable 'x' might be referenced before assignment 40:19: local variable 'x' might be referenced before assignment """ Cython-0.23.4/tests/errors/w_uninitialized_py3.pyx0000644000175600017570000000061412606202452023416 0ustar jenkinsjenkins00000000000000# cython: language_level=3, warn.maybe_uninitialized=True # mode: error # tag: werror def ref(obj): pass def list_comp(a): r = [i for i in a] ref(i) i = 0 return r def dict_comp(a): r = {i: j for i, j in a} ref(i) i = 0 return r _ERRORS = """ 10:9: local variable 'i' referenced before assignment 16:9: local variable 'i' referenced before assignment """ Cython-0.23.4/tests/errors/w_uninitialized_py2.pyx0000644000175600017570000000113112606202452023410 0ustar jenkinsjenkins00000000000000# cython: language_level=2, warn.maybe_uninitialized=True # mode: error # tag: werror def list_comp(a): r = [i for i in a] return i # dict comp is py3 feuture and don't leak here def dict_comp(a): r = {i: j for i, j in a} return i, j def dict_comp2(a): r = {i: j for i, j in a} print i, j i, j = 0, 0 _ERRORS = """ 7:12: local variable 'i' might be referenced before assignment 12:12: undeclared name not builtin: i 12:15: undeclared name not builtin: j 16:11: local variable 'i' referenced before assignment 16:14: local variable 'j' referenced before assignment """ Cython-0.23.4/tests/errors/w_uninitialized_generators.pyx0000644000175600017570000000036112606202452025053 0ustar jenkinsjenkins00000000000000# cython: warn.maybe_uninitialized=True # mode: error # tag: werror def unbound_inside_generator(*args): for i in args: yield x x = i + i _ERRORS = """ 7:15: local variable 'x' might be referenced before assignment """ Cython-0.23.4/tests/errors/w_uninitialized_for.pyx0000644000175600017570000000343712606202452023477 0ustar jenkinsjenkins00000000000000# cython: warn.maybe_uninitialized=True # mode: error # tag: werror def simple_for(n): for i in n: a = 1 return a def simple_for_break(n): for i in n: a = 1 break return a def simple_for_pos(n): for i in n: a = 1 else: a = 0 return a def simple_target(n): for i in n: pass return i def simple_target_f(n): for i in n: i *= i return i def simple_for_from(n): for i from 0 <= i <= n: x = i else: return x def for_continue(l): for i in l: if i > 0: continue x = i print x def for_break(l): for i in l: if i > 0: break x = i print x def for_finally_continue(f): for i in f: try: x = i() finally: print x continue def for_finally_break(f): for i in f: try: x = i() finally: print x break def for_finally_outer(p, f): x = 1 try: for i in f: print x x = i() if x > 0: continue if x < 0: break finally: del x _ERRORS = """ 8:12: local variable 'a' might be referenced before assignment 14:12: local variable 'a' might be referenced before assignment 26:12: local variable 'i' might be referenced before assignment 31:12: local variable 'i' might be referenced before assignment 37:16: local variable 'x' might be referenced before assignment 44:11: local variable 'x' might be referenced before assignment 51:11: local variable 'x' might be referenced before assignment 58:19: local variable 'x' might be referenced before assignment 66:19: local variable 'x' might be referenced before assignment """ Cython-0.23.4/tests/errors/w_uninitialized_exc.pyx0000644000175600017570000000434212606202452023464 0ustar jenkinsjenkins00000000000000# cython: warn.maybe_uninitialized=True # mode: error # tag: werror def exc_target(): try: {}['foo'] except KeyError, e: pass except IndexError, i: pass return e, i def exc_body(): try: a = 1 except Exception: pass return a def exc_else_pos(): try: pass except Exception, e: pass else: e = 1 return e def exc_body_pos(d): try: a = d['foo'] except KeyError: a = None return a def exc_pos(): try: a = 1 except Exception: a = 1 return a def exc_finally(): try: a = 1 finally: pass return a def exc_finally2(): try: pass finally: a = 1 return a def exc_assmt_except(a): try: x = a except: return x def exc_assmt_finaly(a): try: x = a except: return x def raise_stat(a): try: if a < 0: raise IndexError except IndexError: oops = 1 print oops def try_loop(args): try: x = 0 for i in args: if i is 0: continue elif i is None: break elif i is False: return i() except ValueError: x = 1 finally: return x def try_finally(a): try: for i in a: if i > 0: x = 1 finally: return x def try_finally_nested(m): try: try: try: f = m() except: pass finally: pass except: print f _ERRORS = """ 12:12: local variable 'e' might be referenced before assignment 12:15: local variable 'i' might be referenced before assignment 19:12: local variable 'a' might be referenced before assignment 63:16: local variable 'x' might be referenced before assignment 69:16: local variable 'x' might be referenced before assignment 77:14: local variable 'oops' might be referenced before assignment 93:16: local variable 'x' might be referenced before assignment 101:16: local variable 'x' might be referenced before assignment 113:15: local variable 'f' might be referenced before assignment """ Cython-0.23.4/tests/errors/w_uninitialized_del.pyx0000644000175600017570000000040112606202452023441 0ustar jenkinsjenkins00000000000000# cython: warn.maybe_uninitialized=True # mode: error # tag: werror def foo(x): a = 1 del a, b b = 2 return a, b _ERRORS = """ 7:12: local variable 'b' referenced before assignment 9:12: local variable 'a' referenced before assignment """ Cython-0.23.4/tests/errors/w_uninitialized.pyx0000644000175600017570000000525012606202452022624 0ustar jenkinsjenkins00000000000000# cython: warn.maybe_uninitialized=True # mode: error # tag: werror def simple(): print a a = 0 def simple2(arg): if arg > 0: a = 1 return a def simple_pos(arg): if arg > 0: a = 1 else: a = 0 return a def ifelif(c1, c2): if c1 == 1: if c2: a = 1 else: a = 2 elif c1 == 2: a = 3 return a def nowimpossible(a): if a: b = 1 if a: print b def fromclosure(): def bar(): print a a = 1 return bar # Should work ok in both py2 and py3 def list_comp(a): return [i for i in a] def set_comp(a): return set(i for i in a) def dict_comp(a): return {i: j for i, j in a} # args and kwargs def generic_args_call(*args, **kwargs): return args, kwargs def cascaded(x): print a, b a = b = x def from_import(): print bar from foo import bar def regular_import(): print foo import foo def raise_stat(): try: raise exc, msg except: pass exc = ValueError msg = 'dummy' def defnode_decorator(): @decorator def foo(): pass def decorator(): pass def defnode_default(): def foo(arg=default()): pass def default(): pass def class_bases(): class foo(bar): pass class bar(object): pass def class_decorators(): @decorator class foo(object): pass def decorator(cls): return cls def class_py3k_metaclass(): class foo(metaclass=Meta): pass class Meta(object): pass def class_py3k_args(): class foo(*args, **kwargs): pass args = [] kwargs = {} _ERRORS = """ 6:11: local variable 'a' referenced before assignment 12:12: local variable 'a' might be referenced before assignment 29:12: local variable 'a' might be referenced before assignment 35:15: local variable 'b' might be referenced before assignment 58:11: local variable 'a' referenced before assignment 58:14: local variable 'b' referenced before assignment 62:13: local variable 'bar' referenced before assignment 66:13: local variable 'foo' referenced before assignment 71:17: local variable 'exc' referenced before assignment 71:22: local variable 'msg' referenced before assignment 78:4: local variable 'decorator' referenced before assignment 85:23: local variable 'default' referenced before assignment 91:17: local variable 'bar' referenced before assignment 97:4: local variable 'decorator' referenced before assignment 104:28: local variable 'Meta' referenced before assignment 110:19: local variable 'args' referenced before assignment 110:29: local variable 'kwargs' referenced before assignment """ Cython-0.23.4/tests/errors/w_python_list_as_cppset_ref.pyx0000644000175600017570000000066312606202452025230 0ustar jenkinsjenkins00000000000000# mode: error # tag: cpp, werror from libcpp.set cimport set cdef extern from *: void cpp_function_set1(set[int] arg) void cpp_function_set2(set[int]& arg) def pass_py_obj_as_cpp_cont_ref(): cdef list ordered_set = [0, 0, 0, 0, 0] cpp_function_set1(ordered_set) cpp_function_set2(ordered_set) _ERRORS = """ 14:33: Cannot pass Python object as C++ data structure reference (set[int] &), will pass by copy. """ Cython-0.23.4/tests/errors/w_numpy_arr_as_cppvec_ref.pyx0000644000175600017570000000175512606202452024655 0ustar jenkinsjenkins00000000000000# mode: error # tag: cpp, werror, numpy import numpy as np cimport numpy as np from libcpp.vector cimport vector cdef extern from *: void cpp_function_vector1(vector[int]) void cpp_function_vector2(vector[int] &) void cpp_function_2_vec_refs(vector[int] &, vector[int] &) def main(): cdef np.ndarray[int, ndim=1, mode="c"] arr = np.zeros(10, dtype='intc') cpp_function_vector1(arr) cpp_function_vector2(arr) cpp_function_vector2(arr) cpp_function_2_vec_refs(arr, arr) cdef vector[int] vec vec.push_back(0) cpp_function_vector2(vec) _ERRORS = """ 17:28: Cannot pass Python object as C++ data structure reference (vector[int] &), will pass by copy. 18:28: Cannot pass Python object as C++ data structure reference (vector[int] &), will pass by copy. 19:31: Cannot pass Python object as C++ data structure reference (vector[int] &), will pass by copy. 19:36: Cannot pass Python object as C++ data structure reference (vector[int] &), will pass by copy. """ Cython-0.23.4/tests/errors/w_cdef_override.pyx0000644000175600017570000000023612606202452022553 0ustar jenkinsjenkins00000000000000# mode: error # tag: werror cdef foo(): pass def foo(): pass _ERRORS = u""" 7:0: 'foo' redeclared 7:0: Overriding cdef method with def method. """ Cython-0.23.4/tests/errors/void_as_arg.pyx0000644000175600017570000000023212606202452021676 0ustar jenkinsjenkins00000000000000# mode: error cdef extern from *: void foo(void) _ERRORS = u""" 4:13:Use spam() rather than spam(void) to declare a function with no arguments. """ Cython-0.23.4/tests/errors/uninitialized_lhs.pyx0000644000175600017570000000050212606202452023137 0ustar jenkinsjenkins00000000000000# cython: warn.maybe_uninitialized=True # mode: error # tag: werror # ticket: 739 def index_lhs(a): cdef object idx a[idx] = 1 def slice_lhs(a): cdef object idx a[:idx] = 1 _ERRORS = """ 8:9: local variable 'idx' referenced before assignment 12:10: local variable 'idx' referenced before assignment """ Cython-0.23.4/tests/errors/undefinedname.pyx0000644000175600017570000000041212606202452022223 0ustar jenkinsjenkins00000000000000# mode: error i = _this_global_name_does_not_exist_ def test(i): return _this_local_name_does_not_exist_ _ERRORS = u""" 3:37:undeclared name not builtin: _this_global_name_does_not_exist_ 6:43:undeclared name not builtin: _this_local_name_does_not_exist_ """ Cython-0.23.4/tests/errors/typoT304.pyx0000644000175600017570000000023712606202452020774 0ustar jenkinsjenkins00000000000000# ticket: 304 # mode: error def f(): print assert sizeof(int) == sizof(short) == sizeof(long) _ERRORS = u""" 5:10: Expected an identifier or literal """ Cython-0.23.4/tests/errors/tree_assert.pyx0000644000175600017570000000106112606202452021742 0ustar jenkinsjenkins00000000000000# mode: error cimport cython @cython.test_fail_if_path_exists("//SimpleCallNode", "//NameNode") @cython.test_assert_path_exists("//ComprehensionNode", "//ComprehensionNode//FuncDefNode") def test(): object() _ERRORS = u""" 9:0: Expected path '//ComprehensionNode' not found in result tree 9:0: Expected path '//ComprehensionNode//FuncDefNode' not found in result tree 9:0: Unexpected path '//NameNode' found in result tree 9:0: Unexpected path '//SimpleCallNode' found in result tree """ Cython-0.23.4/tests/errors/syntax_warnings.pyx0000644000175600017570000000032612606202452022663 0ustar jenkinsjenkins00000000000000# mode: error # tag: werror cdef useless_semicolon(): cdef int i; pass; ctypedef int x; _ERRORS=""" 5:14: useless trailing semicolon 6:8: useless trailing semicolon 8:14: useless trailing semicolon """ Cython-0.23.4/tests/errors/subtyping_final_class.pyx0000644000175600017570000000030212606202452024001 0ustar jenkinsjenkins00000000000000# mode: error cimport cython @cython.final cdef class FinalClass: pass cdef class SubType(FinalClass): pass _ERRORS = """ 9:5: Base class 'FinalClass' of type 'SubType' is final """ Cython-0.23.4/tests/errors/string_assignments.pyx0000644000175600017570000000702312606202452023347 0ustar jenkinsjenkins00000000000000# mode: error # coding: ASCII # tag: py_unicode_strings # ok: cdef char* c1 = "abc" cdef str s1 = "abc" cdef unicode u1 = u"abc" cdef Py_UNICODE* cu1 = u1 cdef bytes b1 = b"abc" cdef char* c2 = b"abc" cdef bytes b2 = c1 cdef char* c3 = b1 cdef basestring bs1 = "abc" cdef basestring bs2 = u"abc" cdef object o1 = "abc" cdef object o2 = b"abc" cdef object o3 = u"abc" o4 = c1 o5 = b1 o6 = s1 o7 = u1 o8 = cu1 o9 = bs1 u1 = bs1 s1 = bs1 # errors: cdef char* c_f1 = u"abc" cdef char* c_f2 = u1 cdef char* c_f3 = s1 cdef Py_UNICODE* cu_f1 = c1 cdef Py_UNICODE* cu_f2 = b1 cdef Py_UNICODE* cu_f3 = s1 cdef Py_UNICODE* cu_f4 = b"abc" cdef bytes b_f1 = u"abc" cdef bytes b_f2 = u1 cdef bytes b_f3 = s1 cdef bytes b_f4 = bs1 cdef str s_f1 = b"abc" cdef str s_f2 = b1 cdef str s_f3 = u"abc" cdef str s_f4 = u1 cdef unicode u_f1 = "abc" cdef unicode u_f2 = s1 cdef unicode u_f3 = b"abc" cdef unicode u_f4 = b1 cdef unicode u_f5 = c1 cdef basestring bs_f1 = b"abc" cdef basestring bs_f2 = b1 cdef tuple t_f1 = "abc" cdef tuple t_f2 = u"abc" cdef tuple t_f3 = b"abc" cdef list l_f1 = s1 cdef list l_f2 = b1 cdef list l_f3 = u1 print c1 print c1[1:2] print c1 print c1[1:2] _ERRORS = u""" 36:20: Unicode literals do not support coercion to C types other than Py_UNICODE/Py_UCS4 (for characters) or Py_UNICODE* (for strings). 37:22: Unicode objects only support coercion to Py_UNICODE*. 38:22: 'str' objects do not support coercion to C types (use 'bytes'?). 40:27: Cannot assign type 'char *' to 'Py_UNICODE *' 41:27: Cannot convert 'bytes' object to Py_UNICODE*, use 'unicode'. 42:27: 'str' objects do not support coercion to C types (use 'unicode'?). 43:25: Cannot convert 'bytes' object to Py_UNICODE*, use 'unicode'. 45:20: Cannot convert Unicode string to 'bytes' implicitly, encoding required. 46:22: Cannot convert Unicode string to 'bytes' implicitly, encoding required. 47:22: Cannot convert 'str' to 'bytes' implicitly. This is not portable. 48:23: Cannot convert 'basestring' object to bytes implicitly. This is not portable. 50:17: Cannot convert 'bytes' object to str implicitly. This is not portable to Py3. 51:19: Cannot convert 'bytes' object to str implicitly. This is not portable to Py3. 52:17: Cannot convert Unicode string to 'str' implicitly. This is not portable and requires explicit encoding. 53:19: Cannot convert Unicode string to 'str' implicitly. This is not portable and requires explicit encoding. 55:20: str objects do not support coercion to unicode, use a unicode string literal instead (u'') 56:22: str objects do not support coercion to unicode, use a unicode string literal instead (u'') 57:20: Cannot convert 'bytes' object to unicode implicitly, decoding required 58:22: Cannot convert 'bytes' object to unicode implicitly, decoding required 59:22: Cannot convert 'char*' to unicode implicitly, decoding required 61:24: Cannot convert 'bytes' object to basestring implicitly. This is not portable to Py3. 62:26: Cannot convert 'bytes' object to basestring implicitly. This is not portable to Py3. 64:19: Cannot assign type 'str object' to 'tuple object' 65:18: Cannot assign type 'unicode object' to 'tuple object' 66:18: Cannot assign type 'bytes object' to 'tuple object' 72:13: default encoding required for conversion from 'char *' to 'str object' 73:13: default encoding required for conversion from 'char *' to 'str object' 74:17: Cannot convert 'char*' to unicode implicitly, decoding required 75:17: default encoding required for conversion from 'char *' to 'unicode object' """ Cython-0.23.4/tests/errors/se_multass.pyx0000644000175600017570000000030412606202452021600 0ustar jenkinsjenkins00000000000000# mode: error def f(obj1a, obj2a, obj3a, obj1b, obj2b, obj3b, obj4b): obj1a, (obj2a, obj3a) = obj1b, (obj2b, obj3b, obj4b) _ERRORS = u""" 4:9: too many values to unpack (expected 2, got 3) """ Cython-0.23.4/tests/errors/se_mixtabspace.pyx0000644000175600017570000000015712606202452022416 0ustar jenkinsjenkins00000000000000# mode: error def f(): a = b # space space c = d # tab _ERRORS = u""" 5:0: Mixed use of tabs and spaces """ Cython-0.23.4/tests/errors/se_badindent2.pyx0000644000175600017570000000021012606202452022116 0ustar jenkinsjenkins00000000000000# mode: error def f(): a = b c = d _ERRORS = u""" 5:0: Possible inconsistent indentation 5:0: Expected an identifier or literal """ Cython-0.23.4/tests/errors/se_badindent.pyx0000644000175600017570000000016712606202452022047 0ustar jenkinsjenkins00000000000000# mode: error def f(): a = b # space space c = d # space tab _ERRORS = u""" 5:0: Mixed use of tabs and spaces """ Cython-0.23.4/tests/errors/reversed_literal_pyobjs.pyx0000644000175600017570000000137512606202452024353 0ustar jenkinsjenkins00000000000000# mode: error # tag: reversed cdef int i, j for i in reversed(range([], j, 2)): pass for i in reversed(range([], j, -2)): pass for i in reversed(range(j, [], 2)): pass for i in reversed(range(j, [], -2)): pass for i in reversed(range({}, j, 2)): pass for i in reversed(range({}, j, -2)): pass for i in reversed(range(j, {}, 2)): pass for i in reversed(range(j, {}, -2)): pass _ERRORS = """ 5:24: Cannot coerce list to type 'long' 7:24: Cannot coerce list to type 'long' 9:27: Cannot coerce list to type 'long' 11:27: Cannot coerce list to type 'long' 13:24: Cannot interpret dict as type 'long' 15:24: Cannot interpret dict as type 'long' 17:27: Cannot interpret dict as type 'long' 19:27: Cannot interpret dict as type 'long' """ Cython-0.23.4/tests/errors/return_outside_function_T135.pyx0000644000175600017570000000134012606202452025116 0ustar jenkinsjenkins00000000000000# cython: remove_unreachable=False # ticket: 135 # mode: error def _runtime_True(): return True return 'bar' class A: return None cdef class B: return None try: return None except: pass try: return None finally: pass for i in (1,2): return None while True: return None if _runtime_True(): return None else: return None _ERRORS = u''' 8:0: Return not inside a function body 11:4: Return not inside a function body 14:4: Return not inside a function body 16:5: Return not inside a function body 19:5: Return not inside a function body 23:4: Return not inside a function body 26:4: Return not inside a function body 29:4: Return not inside a function body 31:4: Return not inside a function body ''' Cython-0.23.4/tests/errors/pyobjcastdisallow_T313.pyx0000644000175600017570000000027612606202452023700 0ustar jenkinsjenkins00000000000000# ticket: 313 # mode: error a = 3 cdef void* allowed = a cdef double* disallowed = a _ERRORS = u""" 7:26: Python objects cannot be cast to pointers of primitive types """ Cython-0.23.4/tests/errors/py_unicode_type_errors.pyx0000644000175600017570000000141612606202452024221 0ustar jenkinsjenkins00000000000000# mode: error # -*- coding: iso-8859-1 -*- cdef Py_UNICODE char_ASCII = u'A' cdef Py_UNICODE char_KLINGON = u'\uF8D2' def char_too_long_ASCII(): cdef Py_UNICODE c = u'AB' def char_too_long_Unicode(): cdef Py_UNICODE c = u'A\uF8D2' def char_too_long_bytes(): cdef Py_UNICODE c = b'AB' def char_too_long_latin1(): cdef Py_UNICODE char_bytes_latin1 = b'\xf6' _ERRORS = """ 8:24: Only single-character Unicode string literals or surrogate pairs can be coerced into Py_UCS4/Py_UNICODE. 11:24: Only single-character Unicode string literals or surrogate pairs can be coerced into Py_UCS4/Py_UNICODE. 14:24: Only single-character string literals can be coerced into ints. 17:40: Bytes literals cannot coerce to Py_UNICODE/Py_UCS4, use a unicode literal instead. """ Cython-0.23.4/tests/errors/py_ucs4_type_errors.pyx0000644000175600017570000000137412606202452023454 0ustar jenkinsjenkins00000000000000# mode: error # -*- coding: iso-8859-1 -*- cdef Py_UCS4 char_ASCII = u'A' cdef Py_UCS4 char_KLINGON = u'\uF8D2' def char_too_long_ASCII(): cdef Py_UCS4 c = u'AB' def char_too_long_Unicode(): cdef Py_UCS4 c = u'A\uF8D2' def char_too_long_bytes(): cdef Py_UCS4 c = b'AB' def char_too_long_latin1(): cdef Py_UCS4 char_bytes_latin1 = b'\xf6' _ERRORS = """ 8:21: Only single-character Unicode string literals or surrogate pairs can be coerced into Py_UCS4/Py_UNICODE. 11:21: Only single-character Unicode string literals or surrogate pairs can be coerced into Py_UCS4/Py_UNICODE. 14:21: Only single-character string literals can be coerced into ints. 17:37: Bytes literals cannot coerce to Py_UNICODE/Py_UCS4, use a unicode literal instead. """ Cython-0.23.4/tests/errors/pxd_signature_mismatch.pyx0000644000175600017570000000162212606202452024166 0ustar jenkinsjenkins00000000000000# mode: error # tag: pxd cdef int wrong_args(int x, int y): return 2 cdef int wrong_return_type(int x, int y): return 2 cdef int wrong_exception_check(int x, int y) except? 0: return 2 cdef int wrong_exception_value(int x, int y) except 1: return 2 cdef int wrong_exception_value_check(int x, int y) except? 1: return 2 cdef int inherit_exception_value(int x, int y): return 2 cdef int inherit_exception_check(int x, int y): return 2 _ERRORS = """ 4:5: Function signature does not match previous declaration 7:5: Function signature does not match previous declaration 10:5: Function signature does not match previous declaration 13:5: Function signature does not match previous declaration 16:5: Function signature does not match previous declaration 19:5: Function signature does not match previous declaration 22:5: Function signature does not match previous declaration """ Cython-0.23.4/tests/errors/pxd_signature_mismatch.pxd0000644000175600017570000000055412606202452024144 0ustar jenkinsjenkins00000000000000 cdef int wrong_args(int x, long y) cdef long wrong_return_type(int x, int y) cdef int wrong_exception_check(int x, int y) except 0 cdef int wrong_exception_value(int x, int y) except 0 cdef int wrong_exception_value_check(int x, int y) except 0 cdef int inherit_exception_value(int x, int y) except 0 cdef int inherit_exception_check(int x, int y) except * Cython-0.23.4/tests/errors/pxd_cdef_class_declaration_T286.pyx0000644000175600017570000000016512606202452025457 0ustar jenkinsjenkins00000000000000# ticket: 286 # mode: error cdef class A: pass _ERRORS = u""" 1:5: C class 'A' is declared but not defined """ Cython-0.23.4/tests/errors/pxd_cdef_class_declaration_T286.pxd0000644000175600017570000000001512606202452025424 0ustar jenkinsjenkins00000000000000cdef class A Cython-0.23.4/tests/errors/pep492_badsyntax_async9.pyx0000644000175600017570000000017112606202452024011 0ustar jenkinsjenkins00000000000000# mode: error # tag: pep492, async async def foo(): await _ERRORS = """ 5:9: Expected an identifier or literal """ Cython-0.23.4/tests/errors/pep492_badsyntax_async8.pyx0000644000175600017570000000020412606202452024005 0ustar jenkinsjenkins00000000000000# mode: error # tag: pep492, async async def foo(): await await fut _ERRORS = """ 5:10: Expected an identifier or literal """ Cython-0.23.4/tests/errors/pep492_badsyntax_async7.pyx0000644000175600017570000000027212606202452024011 0ustar jenkinsjenkins00000000000000# mode: error # tag: pep492, async async def foo(): yield from [] _ERRORS = """ 5:4: 'yield from' not supported here 5:4: 'yield' not allowed in async coroutines (use 'await') """ Cython-0.23.4/tests/errors/pep492_badsyntax_async6.pyx0000644000175600017570000000025512606202452024011 0ustar jenkinsjenkins00000000000000# mode: error # tag: pep492, async async def foo(): yield _ERRORS = """ 5:4: 'yield' not allowed in async coroutines (use 'await') 5:4: 'yield' not supported here """ Cython-0.23.4/tests/errors/pep492_badsyntax_async5.pyx0000644000175600017570000000017712606202452024013 0ustar jenkinsjenkins00000000000000# mode: error # tag: pep492, async def foo(): await list() _ERRORS = """ 5:10: Syntax error in simple statement list """ Cython-0.23.4/tests/errors/pep492_badsyntax_async4.pyx0000644000175600017570000000023312606202452024003 0ustar jenkinsjenkins00000000000000# mode: error # tag: pep492, async async def foo(): async def foo(): await list() _ERRORS = """ # ??? - this fails in CPython, not sure why ... """ Cython-0.23.4/tests/errors/pep492_badsyntax_async3.pyx0000644000175600017570000000020412606202452024000 0ustar jenkinsjenkins00000000000000# mode: error # tag: pep492, async async def foo(): [i async for i in els] _ERRORS = """ 5:7: Expected ']', found 'async' """ Cython-0.23.4/tests/errors/pep492_badsyntax_async2.pyx0000644000175600017570000000026412606202452024005 0ustar jenkinsjenkins00000000000000# mode: error # tag: pep492, async async def foo(): def foo(a:await list()): pass _ERRORS = """ 5:14: 'await' not supported here 5:14: 'await' not supported here """ Cython-0.23.4/tests/errors/pep492_badsyntax_async10.pyx0000644000175600017570000000066112606202452024065 0ustar jenkinsjenkins00000000000000# mode: error # tag: pep492, async async def genexpr(it): return (await x for x in it) async def listcomp(it): return [await x for x in it] async def setcomp(it): return {await x for x in it} async def dictcomp(it): return {await x:x+1 for x in it} # NOTE: CPython doesn't allow comprehensions either _ERRORS = """ 5:12: 'await' not allowed in generators (use 'yield') 5:12: 'await' not supported here """ Cython-0.23.4/tests/errors/pep492_badsyntax_async1.pyx0000644000175600017570000000022312606202452023777 0ustar jenkinsjenkins00000000000000# mode: error # tag: pep492, async async def foo(): def foo(a=await list()): pass _ERRORS = """ 5:14: 'await' not supported here """ Cython-0.23.4/tests/errors/pep448_syntax_3.pyx0000644000175600017570000000020412606202452022274 0ustar jenkinsjenkins00000000000000# mode: error # tag: pep448 def unpack_mix_in_set(): {*1, **2} _ERRORS = """ 5:9: unexpected **item found in set literal """ Cython-0.23.4/tests/errors/pep448_syntax_2.pyx0000644000175600017570000000017412606202452022301 0ustar jenkinsjenkins00000000000000# mode: error # tag: pep448 def unpack_wrong_stars(): [**1] _ERRORS = """ 5:5: Expected an identifier or literal """ Cython-0.23.4/tests/errors/pep448_syntax_1.pyx0000644000175600017570000000017012606202452022274 0ustar jenkinsjenkins00000000000000# mode: error # tag: pep448 def unpack_mix(): [*1, **1] _ERRORS = """ 5:9: Expected an identifier or literal """ Cython-0.23.4/tests/errors/parsed_directive.pyx0000644000175600017570000000067012606202452022743 0ustar jenkinsjenkins00000000000000# mode: error cimport cython cdef class TestClass: def foo(self): with cython.c_string_encoding("ascii"): return ### FIXME: way to many errors for my taste... _ERRORS = """ 7:13: The c_string_encoding compiler directive is not allowed in with statement scope 7:19: 'c_string_encoding' not a valid cython language construct 7:19: 'c_string_encoding' not a valid cython attribute or is being used incorrectly """ Cython-0.23.4/tests/errors/notcimportedT418.pyx0000644000175600017570000000022512606202452022513 0ustar jenkinsjenkins00000000000000# ticket: 418 # mode: error import somemod.child cdef somemod.child.something x _ERRORS = u""" 6:5: 'somemod.child' is not a cimported module """ Cython-0.23.4/tests/errors/nonconst_def_tuple.pyx0000644000175600017570000000042012606202452023310 0ustar jenkinsjenkins00000000000000# mode: error DEF t = (1,2,3) DEF t_const = (1,t,2) DEF t_non_const = (1,[1,2,3],3,t[4]) x = t_non_const _ERRORS = u""" 5:32: Error in compile-time expression: IndexError: tuple index out of range 7:15: Invalid type for compile-time constant: [1, 2, 3] (type list) """ Cython-0.23.4/tests/errors/nonconst_def.pyx0000644000175600017570000000031512606202452022102 0ustar jenkinsjenkins00000000000000# mode: error import os DEF ospath = os.path _ERRORS = u""" 4:15: Compile-time name 'os' not defined 4:15: Error in compile-time expression: AttributeError: 'NoneType' object has no attribute 'path' """ Cython-0.23.4/tests/errors/nogilfunctype.pyx0000644000175600017570000000034512606202452022314 0ustar jenkinsjenkins00000000000000# mode: error cdef extern from *: cdef void f() cdef void (*fp)() nogil cdef void g() nogil cdef void (*gp)() gp = g fp = f _ERRORS = u""" 12:6: Cannot assign type 'void (void)' to 'void (*)(void) nogil' """ Cython-0.23.4/tests/errors/nogilcmeth.pyx0000644000175600017570000000026012606202452021553 0ustar jenkinsjenkins00000000000000# mode: error cdef class C: cdef void f(self): pass _ERRORS = u""" 2:15: Previous declaration is here 4:9: Signature not compatible with previous declaration """ Cython-0.23.4/tests/errors/nogilcmeth.pxd0000644000175600017570000000005212606202452021525 0ustar jenkinsjenkins00000000000000cdef class C: cdef void f(self) nogil Cython-0.23.4/tests/errors/nogil_buffer_acquisition.pyx0000644000175600017570000000033412606202452024475 0ustar jenkinsjenkins00000000000000# mode: error cimport numpy as np cdef void func(np.ndarray[np.double_t, ndim=1] myarray) nogil: pass _ERRORS = u""" 5:15: Buffer may not be acquired without the GIL. Consider using memoryview slices instead. """ Cython-0.23.4/tests/errors/nogil.pyx0000644000175600017570000001261712606202452020543 0ustar jenkinsjenkins00000000000000# cython: remove_unreachable=False # mode: error cdef object f(object x) nogil: pass cdef void g(int x) nogil: cdef object z z = None cdef void h(int x) nogil: p() cdef object p() nogil: pass cdef void r() nogil: q() cdef object m(): cdef object x, y = 0, obj cdef int i, j, k global fred q() with nogil: r() q() i = 42 obj = None 17L 7j help xxx = `"Hello"` import fred from fred import obj for x in obj: pass obj[i] obj[i:j] obj[i:j:k] obj.fred (x, y) [x, y] {x: y} {x, y} obj and x t(obj) # f(42) # Cython handles this internally x + obj -obj x = y = obj x, y = y, x obj[i] = x obj.fred = x print obj del fred return obj raise obj if obj: pass while obj: pass for x <= obj <= y: pass try: pass except: pass try: pass finally: pass cdef void q(): pass cdef class C: pass cdef void t(C c) nogil: pass def ticket_338(): cdef object obj with nogil: for obj from 0 <= obj < 4: pass def bare_pyvar_name(object x): with nogil: x # For m(), the important thing is that there are errors on all lines in the range 23-69 # except these: 29, 34, 44, 56, 58, 60, 62-64 _ERRORS = u""" 4:5: Function with Python return type cannot be declared nogil 7:5: Function declared nogil has Python locals or temporaries 9:6: Assignment of Python object not allowed without gil 12:5: Discarding owned Python object not allowed without gil 14:5: Function with Python return type cannot be declared nogil 18:5: Calling gil-requiring function not allowed without gil 27:9: Calling gil-requiring function not allowed without gil 29:12: Assignment of Python object not allowed without gil 31:16: Constructing complex number not allowed without gil 33:12: Assignment of Python object not allowed without gil 33:14: Backquote expression not allowed without gil 33:15: Operation not allowed without gil 34:15: Assignment of Python object not allowed without gil 34:15: Operation not allowed without gil 34:15: Python import not allowed without gil 35:8: Operation not allowed without gil 35:13: Python import not allowed without gil 35:25: Constructing Python list not allowed without gil 35:25: Operation not allowed without gil 36:17: Iterating over Python object not allowed without gil 38:11: Discarding owned Python object not allowed without gil 38:11: Indexing Python object not allowed without gil 39:11: Discarding owned Python object not allowed without gil 39:11: Slicing Python object not allowed without gil 40:11: Constructing Python slice object not allowed without gil 40:11: Discarding owned Python object not allowed without gil 40:11: Indexing Python object not allowed without gil 40:13: Converting to Python object not allowed without gil 40:15: Converting to Python object not allowed without gil 40:17: Converting to Python object not allowed without gil 41:11: Accessing Python attribute not allowed without gil 41:11: Discarding owned Python object not allowed without gil 42:9: Constructing Python tuple not allowed without gil 42:9: Discarding owned Python object not allowed without gil 43:8: Constructing Python list not allowed without gil 43:8: Discarding owned Python object not allowed without gil 44:10: Constructing Python dict not allowed without gil 44:10: Discarding owned Python object not allowed without gil 45:10: Constructing Python set not allowed without gil 45:10: Discarding owned Python object not allowed without gil 46:12: Discarding owned Python object not allowed without gil 46:12: Truth-testing Python object not allowed without gil 47:13: Python type test not allowed without gil 49:10: Discarding owned Python object not allowed without gil 49:10: Operation not allowed without gil 50:8: Discarding owned Python object not allowed without gil 50:8: Operation not allowed without gil 51:10: Assignment of Python object not allowed without gil 51:14: Assignment of Python object not allowed without gil 52:9: Assignment of Python object not allowed without gil 52:13: Assignment of Python object not allowed without gil 52:16: Creating temporary Python reference not allowed without gil 52:19: Creating temporary Python reference not allowed without gil 53:11: Assignment of Python object not allowed without gil 53:11: Indexing Python object not allowed without gil 54:11: Accessing Python attribute not allowed without gil 54:11: Assignment of Python object not allowed without gil 55:8: Constructing Python tuple not allowed without gil 55:8: Python print statement not allowed without gil 56:8: Deleting Python object not allowed without gil 57:8: Returning Python object not allowed without gil 58:8: Raising exception not allowed without gil 59:14: Truth-testing Python object not allowed without gil 61:17: Truth-testing Python object not allowed without gil 63:8: For-loop using object bounds or target not allowed without gil 63:14: Coercion from Python not allowed without the GIL 63:25: Coercion from Python not allowed without the GIL 65:8: Try-except statement not allowed without gil 86:8: For-loop using object bounds or target not allowed without gil """ Cython-0.23.4/tests/errors/mod_errors.pyx0000644000175600017570000000022412606202452021575 0ustar jenkinsjenkins00000000000000# mode: error def mod_complex(): x = (1.1+2.0j) % 4 return x _ERRORS = """ 4:19: mod operator not supported for type 'double complex' """ Cython-0.23.4/tests/errors/missing_self_in_cpdef_method_T165.pyx0000644000175600017570000000026012606202452026012 0ustar jenkinsjenkins00000000000000# ticket: 165 # mode: error cdef class A: cpdef a(int not_self): pass _ERRORS = u""" 5:10: Self argument (int) of C method 'a' does not match parent type (A) """ Cython-0.23.4/tests/errors/missing_self_in_cpdef_method_T156.pyx0000644000175600017570000000017712606202452026021 0ustar jenkinsjenkins00000000000000# ticket: 156 # mode: error cdef class B: cpdef b(): pass _ERRORS = u""" 5:10: C method has no self argument """ Cython-0.23.4/tests/errors/missing_baseclass_in_predecl_T262.pyx0000644000175600017570000000033312606202452026015 0ustar jenkinsjenkins00000000000000# ticket: 262 # mode: error cdef class Album cdef class SessionStruct: cdef Album _create_album(self, void* album, bint take_owner): pass cdef class Album(SessionStruct): pass _ERROR = u""" """ Cython-0.23.4/tests/errors/literal_lists.pyx0000644000175600017570000000030712606202452022276 0ustar jenkinsjenkins00000000000000# mode: error def f(): cdef int* p if false(): p = [1, 2, 3] def false(): return False _ERRORS = u""" 6:10: Literal list must be assigned to pointer at time of declaration """ Cython-0.23.4/tests/errors/invalid_uescapeN.pyx0000644000175600017570000000014712606202452022677 0ustar jenkinsjenkins00000000000000# mode: error u'\N{GIBBET NICH}' _ERRORS = ''' 3:2: Unknown Unicode character name 'GIBBET NICH' ''' Cython-0.23.4/tests/errors/invalid_uescape2.pyx0000644000175600017570000000011312606202452022634 0ustar jenkinsjenkins00000000000000# mode: error u'\u12' _ERRORS = ''' 3:2: Invalid unicode escape '\u' ''' Cython-0.23.4/tests/errors/invalid_uescape0.pyx0000644000175600017570000000011112606202452022630 0ustar jenkinsjenkins00000000000000# mode: error u'\u' _ERRORS = ''' 3:2: Invalid unicode escape '\u' ''' Cython-0.23.4/tests/errors/invalid_uescape.pyx0000644000175600017570000000011412606202452022553 0ustar jenkinsjenkins00000000000000# mode: error u'\uXYZ' _ERRORS = ''' 3:2: Invalid unicode escape '\u' ''' Cython-0.23.4/tests/errors/invalid_hex_escape1.pyx0000644000175600017570000000010512606202452023313 0ustar jenkinsjenkins00000000000000# mode: error '\x1' _ERRORS = ''' 3:1: Invalid hex escape '\x' ''' Cython-0.23.4/tests/errors/invalid_hex_escape0.pyx0000644000175600017570000000010412606202452023311 0ustar jenkinsjenkins00000000000000# mode: error '\x' _ERRORS = ''' 3:1: Invalid hex escape '\x' ''' Cython-0.23.4/tests/errors/invalid_cast.pyx0000644000175600017570000000014412606202452022063 0ustar jenkinsjenkins00000000000000# mode: error def f(): a = True _ERRORS = u""" 4:9: 'foao' is not a type identifier """ Cython-0.23.4/tests/errors/incorrectly_nested_gil_blocks.pyx0000644000175600017570000000121112606202452025506 0ustar jenkinsjenkins00000000000000# mode: error with gil: pass with nogil: with nogil: pass cdef void without_gil() nogil: # This is not an error, as 'func' *may* be called without the GIL, but it # may also be held. with nogil: pass cdef void with_gil() with gil: # This is an error, as the GIL is acquired already with gil: pass def func(): with gil: pass _ERRORS = u''' 3:5: Trying to acquire the GIL while it is already held. 7:9: Trying to release the GIL while it was previously released. 18:9: Trying to acquire the GIL while it is already held. 22:9: Trying to acquire the GIL while it is already held. ''' Cython-0.23.4/tests/errors/futurebraces.pyx0000644000175600017570000000012412606202452022113 0ustar jenkinsjenkins00000000000000# mode: error from __future__ import braces _ERRORS = u""" 3:23: not a chance """ Cython-0.23.4/tests/errors/fused_types.pyx0000644000175600017570000000354712606202452021767 0ustar jenkinsjenkins00000000000000# mode: error cimport cython from cython import fused_type # This is all invalid # ctypedef foo(int) dtype1 # ctypedef foo.bar(float) dtype2 # ctypedef fused_type(foo) dtype3 dtype4 = cython.fused_type(int, long, kw=None) # ctypedef public cython.fused_type(int, long) dtype7 # ctypedef api cython.fused_type(int, long) dtype8 int_t = cython.fused_type(short, short, int) int2_t = cython.fused_type(int, long) dtype9 = cython.fused_type(int2_t, int) floating = cython.fused_type(float, double) cdef func(floating x, int2_t y): print x, y cdef float x = 10.0 cdef int y = 10 func[float](x, y) func[float][int](x, y) func[float, int](x) func[float, int](x, y, y) func(x, y=y) ctypedef fused memslice_dtype_t: cython.p_int # invalid dtype cython.long def f(memslice_dtype_t[:, :] a): pass lambda cython.integral i: i cdef cython.floating x cdef class Foo(object): cdef cython.floating attr def outer(cython.floating f): def inner(): cdef cython.floating g # This is all valid dtype5 = fused_type(int, long, float) dtype6 = cython.fused_type(int, long) func[float, int](x, y) cdef fused fused1: int long long ctypedef fused fused2: int long long func(x, y) _ERRORS = u""" 10:15: fused_type does not take keyword arguments 15:38: Type specified multiple times 26:4: Invalid use of fused types, type cannot be specialized 26:4: Not enough types specified to specialize the function, int2_t is still fused 27:4: Invalid use of fused types, type cannot be specialized 27:4: Not enough types specified to specialize the function, int2_t is still fused 28:16: Call with wrong number of arguments (expected 2, got 1) 29:16: Call with wrong number of arguments (expected 2, got 3) 36:6: Invalid base type for memoryview slice: int * 39:0: Fused lambdas not allowed 42:5: Fused types not allowed here 45:9: Fused types not allowed here """ Cython-0.23.4/tests/errors/fused_syntax_ctypedef.pyx0000644000175600017570000000024512606202452024024 0ustar jenkinsjenkins00000000000000# mode: error cimport cython ctypedef cython.fused_type(int, float) fused_t _ERRORS = u""" fused_syntax_ctypedef.pyx:5:39: Syntax error in ctypedef statement """ Cython-0.23.4/tests/errors/fused_syntax.pyx0000644000175600017570000000016512606202452022142 0ustar jenkinsjenkins00000000000000# mode: error cdef fused my_fused_type: int a; char b _ERRORS = u""" fused_syntax.pyx:3:26: Expected a newline """ Cython-0.23.4/tests/errors/final_methods.pyx0000644000175600017570000000057312606202452022245 0ustar jenkinsjenkins00000000000000# mode: error cimport cython cdef class BaseClass: @cython.final cdef cdef_method(self): pass @cython.final cpdef cpdef_method(self): pass cdef class SubType(BaseClass): cdef cdef_method(self): pass _ERRORS = """ 11:10: Only final types can have final Python (def/cpdef) methods 16:9: Overriding final methods is not allowed """ Cython-0.23.4/tests/errors/extended_unpacking_parser2.pyx0000644000175600017570000000033212606202452024717 0ustar jenkinsjenkins00000000000000# mode: error # invalid syntax (as handled by the parser) def syntax(): *a, *b = 1,2,3,4,5 _ERRORS = u""" 6:4: more than 1 starred expression in assignment 6:8: more than 1 starred expression in assignment """ Cython-0.23.4/tests/errors/extended_unpacking_parser.pyx0000644000175600017570000000112412606202452024635 0ustar jenkinsjenkins00000000000000# mode: error # wrong size RHS (as handled by the parser) def length1(): a, b = [1,2,3] def length2(): a, b = [1] def length3(): a, b = [] def length4(): a, *b = [] def length5(): a, *b, c = [] a, *b, c = [1] def length_recursive(): *(a, b), c = (1,2) _ERRORS = u""" 6:4: too many values to unpack (expected 2, got 3) 9:4: need more than 1 value to unpack 12:4: need more than 0 values to unpack 15:4: need more than 0 values to unpack 18:4: need more than 0 values to unpack 19:4: need more than 1 value to unpack 22:6: need more than 1 value to unpack """ Cython-0.23.4/tests/errors/extended_unpacking_notuple.pyx0000644000175600017570000000040512606202452025030 0ustar jenkinsjenkins00000000000000# mode: error # very common mistake for new users (handled early by the parser) def no_tuple_assignment(): *a = [1] _ERRORS = u""" 6:4: a starred assignment target must be in a list or tuple - maybe you meant to use an index assignment: var[0] = ... """ Cython-0.23.4/tests/errors/extended_unpacking.pyx0000644000175600017570000000154112606202452023264 0ustar jenkinsjenkins00000000000000# mode: error # invalid syntax (not handled by the parser) def syntax1(): a = b = c = d = e = f = g = h = i = 1 # prevent undefined names *a *1 *"abc" *a*b [*a, *b] (a, b, *c, d, e, f, *g, h, i) [a, b, *c, d, e, f, *g, h, i] {a, b, *c, d, e, f, *g, h, i} def syntax2(): list_of_sequences = [[1,2], [3,4]] for *a,*b in list_of_sequences: pass def types(l): cdef int a,b a, *b = (1,2,3,4) a, *b = l _ERRORS = u""" # syntax1() 8: 4: starred expression is not allowed here 10: 4: starred expression is not allowed here 12: 4: starred expression is not allowed here 14: 4: starred expression is not allowed here # syntax2() 26:11: more than 1 starred expression in assignment # types() 32:15: Cannot coerce list to type 'int' 33:10: starred target must have Python object (list) type """ Cython-0.23.4/tests/errors/extclassattrsetting.pyx0000644000175600017570000000051612606202452023545 0ustar jenkinsjenkins00000000000000# mode: error __doc__ = u""" >>> e = ExtClass() >>> e.get() 5 """ cdef class ExtClass: cdef int _attribute = 2 def get(self): return self._attribute _attribute = 5 # FIXME: this is not currently handled!!! _ERRORS = u""" 10:13: Cannot assign default value to fields in cdef classes, structs or unions """ Cython-0.23.4/tests/errors/exec_errors.pyx0000644000175600017570000000215412606202452021746 0ustar jenkinsjenkins00000000000000# mode: error # tag: exec def test_exec_tuples(): exec() exec(1,) exec(1,2,3,4) def test_exec_tuples_with_in(d1, d2): exec(1,2) in d1 exec(1,2,3) in d1 exec(1,2) in d1, d2 exec(1,2,3) in d1, d2 exec() in d1, d2 exec(1,) in d1, d2 exec(1,2,3,4) in d1, d2 _ERRORS = """ 5:4: expected tuple of length 2 or 3, got length 0 6:4: expected tuple of length 2 or 3, got length 1 7:4: expected tuple of length 2 or 3, got length 4 10:14: tuple variant of exec does not support additional 'in' arguments 11:16: tuple variant of exec does not support additional 'in' arguments 12:14: tuple variant of exec does not support additional 'in' arguments 13:16: tuple variant of exec does not support additional 'in' arguments 14:4: expected tuple of length 2 or 3, got length 0 14:11: tuple variant of exec does not support additional 'in' arguments 15:4: expected tuple of length 2 or 3, got length 1 15:13: tuple variant of exec does not support additional 'in' arguments 16:4: expected tuple of length 2 or 3, got length 4 16:18: tuple variant of exec does not support additional 'in' arguments """ Cython-0.23.4/tests/errors/encoding.pyx0000644000175600017570000000033012606202452021206 0ustar jenkinsjenkins00000000000000# coding=ASCII # mode: error """ Trs bien. """ _ERRORS = u""" 5:3: Decoding error, missing or incorrect coding= at top of source (cannot decode with encoding 'ascii': ordinal not in range(128)) """ Cython-0.23.4/tests/errors/empty.pyx0000644000175600017570000000005312606202452020560 0ustar jenkinsjenkins00000000000000# cython: autotestdict=False # mode: error Cython-0.23.4/tests/errors/e_while.pyx0000644000175600017570000000031412606202452021036 0ustar jenkinsjenkins00000000000000# cython: remove_unreachable=False # mode: error def f(a, b): cdef int i break # error continue # error _ERRORS = u""" 6:1: break statement not inside loop 7:1: continue statement not inside loop """ Cython-0.23.4/tests/errors/e_unop.pyx0000644000175600017570000000031512606202452020710 0ustar jenkinsjenkins00000000000000# mode: error def f(): cdef int int1 cdef char *str2 int1 = -str2 # error int1 = ~str2 # error _ERRORS = u""" 6:8: Invalid operand type for '-' (char *) 7:8: Invalid operand type for '~' (char *) """ Cython-0.23.4/tests/errors/e_undefexttype.pyx0000644000175600017570000000026212606202452022454 0ustar jenkinsjenkins00000000000000# mode: error cdef class Spam cdef extern class external.Eggs _ERRORS = u""" 3:5: C class 'Spam' is declared but not defined 4:5: C class 'Eggs' is declared but not defined """ Cython-0.23.4/tests/errors/e_tuple_args_T692.py0000644000175600017570000000027212606202452022432 0ustar jenkinsjenkins00000000000000# ticket: 692 # mode: error def func((a, b)): return a + b _ERRORS = u""" 4:9: Missing argument name 5:13: undeclared name not builtin: a 5:16: undeclared name not builtin: b """ Cython-0.23.4/tests/errors/e_tempcast.pyx0000644000175600017570000000043412606202452021551 0ustar jenkinsjenkins00000000000000# mode: error cdef object blarg def foo(obj): cdef void *p p = blarg # ok p = (obj + blarg) # error - temporary _ERRORS = u""" 8:5: Casting temporary Python object to non-numeric non-Python type 8:5: Storing unsafe C derivative of temporary Python reference """ Cython-0.23.4/tests/errors/e_switch_transform.pyx0000644000175600017570000000032412606202452023323 0ustar jenkinsjenkins00000000000000# cython: optimize.use_switch=True # mode: error # tag: cerror import cython cdef extern from *: enum: ONE "1" ONE_AGAIN "1+0" def is_not_one(int i): return i != ONE and i != ONE_AGAIN Cython-0.23.4/tests/errors/e_switch.pyx0000644000175600017570000000027112606202452021231 0ustar jenkinsjenkins00000000000000# mode: error cdef int x = 3 if x == NONEXISTING: print 2 elif x == 2: print 2342 elif x == 4: print 34 _ERRORS = u""" 5:19: undeclared name not builtin: NONEXISTING """ Cython-0.23.4/tests/errors/e_subop.pyx0000644000175600017570000000036412606202452021063 0ustar jenkinsjenkins00000000000000# mode: error def f(): cdef int int2 cdef char *ptr1, *ptr2, *ptr3 ptr1 = int2 - ptr3 # error ptr1 = ptr2 - ptr3 # error _ERRORS = u""" 6:13: Invalid operand types for '-' (int; char *) 7:13: Cannot assign type 'ptrdiff_t' to 'char *' """ Cython-0.23.4/tests/errors/e_strcoerce.pyx0000644000175600017570000000115112606202452021717 0ustar jenkinsjenkins00000000000000# mode: error cdef int c1 = "t" # works cdef int c2 = "te" # fails cdef int cx = "test" # fails cdef int x1 = "\xFF" # works cdef int x2 = "\u0FFF" # fails cdef Py_UNICODE u1 = u"\xFF" # works cdef int u3 = u"\xFF" # fails _ERRORS = """ 4:14: Only single-character string literals can be coerced into ints. 5:14: Only single-character string literals can be coerced into ints. 8:15: Only single-character string literals can be coerced into ints. 11:14: Unicode literals do not support coercion to C types other than Py_UNICODE/Py_UCS4 (for characters) or Py_UNICODE* (for strings). """ Cython-0.23.4/tests/errors/e_slice.pyx0000644000175600017570000000111412606202452021024 0ustar jenkinsjenkins00000000000000# mode: error def f(obj2): cdef int *ptr1 obj1 = obj2[ptr1::] # error obj1 = obj2[:ptr1:] # error obj1 = obj2[::ptr1] # error cdef int a cdef int* int_ptr for a in int_ptr: pass for a in int_ptr[2:]: pass for a in int_ptr[2:2:a]: pass _ERRORS = u""" 5:20: Cannot convert 'int *' to Python object 6:21: Cannot convert 'int *' to Python object 7:22: Cannot convert 'int *' to Python object 12:16: C array iteration requires known end index 14:16: C array iteration requires known end index 16:22: C array iteration requires known step size and end index """ Cython-0.23.4/tests/errors/e_sizeofincomplete.pyx0000644000175600017570000000021512606202452023305 0ustar jenkinsjenkins00000000000000# mode: error cdef struct unbekannt cdef int n n = sizeof(unbekannt) _ERRORS = u""" 5:4: Cannot take sizeof incomplete type 'unbekannt' """ Cython-0.23.4/tests/errors/e_return.pyx0000644000175600017570000000044012606202452021245 0ustar jenkinsjenkins00000000000000# cython: remove_unreachable=False # mode: error cdef void g(): cdef int i return i # error cdef int h(): cdef int *p return # error return p # error _ERRORS = u""" 6:17: Return with value in void function 10:1: Return value required 11:17: Cannot assign type 'int *' to 'int' """ Cython-0.23.4/tests/errors/e_relative_cimport.pyx0000644000175600017570000000065112606202452023302 0ustar jenkinsjenkins00000000000000# mode: error # tag: cimport from ..relative_cimport cimport some_name from .e_relative_cimport cimport some_name from ..cython cimport declare from . cimport e_relative_cimport _ERRORS=""" 4:0: relative cimport beyond main package is not allowed 5:0: relative cimport beyond main package is not allowed 6:0: relative cimport beyond main package is not allowed 7:0: relative cimport beyond main package is not allowed """ Cython-0.23.4/tests/errors/e_pyobinstruct.pyx0000644000175600017570000000025412606202452022476 0ustar jenkinsjenkins00000000000000# mode: error cdef object x cdef struct spam: object parrot def f(): cdef spam s s.parrot = x _ERRORS = u""" 6:8: C struct/union member cannot be a Python object """ Cython-0.23.4/tests/errors/e_pxdimpl_imported.pxd0000644000175600017570000000105612606202452023265 0ustar jenkinsjenkins00000000000000 cdef class A: cdef int test(self) # Should give error: def somefunc(self): pass # While this should *not* be an error...: def __getbuffer__(self, Py_buffer* info, int flags): pass # This neither: def __releasebuffer__(self, Py_buffer* info): pass # Terminate with an error to be sure the compiler is # not terminating prior to previous errors def terminate(self): pass cdef extern from "foo.h": cdef class pxdimpl.B [object MyB]: def otherfunc(self): pass Cython-0.23.4/tests/errors/e_pxdimpl.pyx0000644000175600017570000000041512606202452021405 0ustar jenkinsjenkins00000000000000# mode: error cimport e_pxdimpl_imported _ERRORS = u""" 6:4: function definition in pxd file must be declared 'cdef inline' 18:4: function definition in pxd file must be declared 'cdef inline' 23:8: function definition in pxd file must be declared 'cdef inline' """ Cython-0.23.4/tests/errors/e_public_cdef_private_types.pyx0000644000175600017570000000226512606202452025152 0ustar jenkinsjenkins00000000000000# mode: error ctypedef char *string_t ctypedef public char *public_string_t ctypedef api char *api_string_t # This should all fail cdef public pub_func1(string_t x): pass cdef api api_func1(string_t x): pass cdef public string_t pub_func2(): pass cdef api string_t api_func2(): pass cdef public opt_pub_func(x = None): pass cdef api opt_api_func(x = None): pass # This should all work cdef public pub_func3(public_string_t x, api_string_t y): pass cdef api api_func3(public_string_t x, api_string_t y): pass cdef opt_func(x = None): pass _ERRORS = u""" e_public_cdef_private_types.pyx:8:22: Function declared public or api may not have private types e_public_cdef_private_types.pyx:11:19: Function declared public or api may not have private types e_public_cdef_private_types.pyx:14:5: Function declared public or api may not have private types e_public_cdef_private_types.pyx:17:5: Function declared public or api may not have private types e_public_cdef_private_types.pyx:20:25: Function with optional arguments may not be declared public or api e_public_cdef_private_types.pyx:23:22: Function with optional arguments may not be declared public or api """ Cython-0.23.4/tests/errors/e_powop.pyx0000644000175600017570000000037612606202452021102 0ustar jenkinsjenkins00000000000000# mode: error def f(): cdef char *str1 cdef float flt1, flt2, flt3 flt1 = str1 ** flt3 # error flt1 = flt2 ** str1 # error _ERRORS = u""" 6:13: Invalid operand types for '**' (char *; float) 7:13: Invalid operand types for '**' (float; char *) """ Cython-0.23.4/tests/errors/e_numop.pyx0000644000175600017570000000023312606202452021064 0ustar jenkinsjenkins00000000000000# mode: error def f(): cdef int int1, int2 cdef int *ptr int1 = int2 * ptr # error _ERRORS = u""" 6:13: Invalid operand types for '*' (int; int *) """ Cython-0.23.4/tests/errors/e_notnone2.pyx0000644000175600017570000000027612606202452021477 0ustar jenkinsjenkins00000000000000# mode: error def eggs(int x not None, char* y not None): pass _ERRORS = u""" 3: 9: Only Python type arguments can have 'not None' 3:25: Only Python type arguments can have 'not None' """ Cython-0.23.4/tests/errors/e_notnone.pyx0000644000175600017570000000024412606202452021410 0ustar jenkinsjenkins00000000000000# mode: error cdef extern class Grail.Shrubbery cdef void spam(Shrubbery sh not None): pass _ERRORS = u""" 5:15: 'not None' only allowed in Python functions """ Cython-0.23.4/tests/errors/e_nosignword.pyx0000644000175600017570000000072412606202452022124 0ustar jenkinsjenkins00000000000000# mode: error cdef signed float e cdef unsigned float f cdef signed double g cdef unsigned double h cdef signed long double i cdef unsigned long double j _ERRORS = u""" 3:5: Unrecognised type modifier combination 4:5: Unrecognised type modifier combination 5:5: Unrecognised type modifier combination 6:5: Unrecognised type modifier combination 7:5: Unrecognised type modifier combination 8:5: Unrecognised type modifier combination """ Cython-0.23.4/tests/errors/e_nonlocal_T490.pyx0000644000175600017570000000115412606202452022256 0ustar jenkinsjenkins00000000000000# mode: error def test_non_existant(): nonlocal no_such_name no_such_name = 1 def redef(): x = 1 def f(): x = 2 nonlocal x global_name = 5 def ref_to_global(): nonlocal global_name global_name = 6 def global_in_class_scope(): class Test(): nonlocal global_name global_name = 6 def redef_in_class_scope(): x = 1 class Test(): x = 2 nonlocal x _ERRORS = u""" 4:4: no binding for nonlocal 'no_such_name' found 11:8: 'x' redeclared as nonlocal 16:4: no binding for nonlocal 'global_name' found 28:8: 'x' redeclared as nonlocal """ Cython-0.23.4/tests/errors/e_nogilfunctype.pyx0000644000175600017570000000024612606202452022620 0ustar jenkinsjenkins00000000000000# mode: error cdef extern from *: cdef void f() cdef void (*fp)() nogil fp = f _ERRORS = u""" 7:6: Cannot assign type 'void (void)' to 'void (*)(void) nogil' """ Cython-0.23.4/tests/errors/e_nogilcmeth.pyx0000644000175600017570000000025612606202452022064 0ustar jenkinsjenkins00000000000000# mode: error cdef class C: cdef void f(self) nogil: pass _ERRORS = u""" 2:12: Previous declaration is here 4: 6: Signature not compatible with previous declaration """ Cython-0.23.4/tests/errors/e_nogilcmeth.pxd0000644000175600017570000000004112606202452022027 0ustar jenkinsjenkins00000000000000cdef class C: cdef void f(self) Cython-0.23.4/tests/errors/e_nargs.pyx0000644000175600017570000000111112606202452021034 0ustar jenkinsjenkins00000000000000# mode: error cdef extern grail(char *s, int i) cdef extern spam(char *s, int i,...) cdef f(): grail() # too few args grail("foo") # too few args grail("foo", 42, 17) # too many args spam() # too few args spam("blarg") # too few args _ERRORS = u""" 7:6: Call with wrong number of arguments (expected 2, got 0) 8:6: Call with wrong number of arguments (expected 2, got 1) 9:6: Call with wrong number of arguments (expected 2, got 3) 10:5: Call with wrong number of arguments (expected at least 2, got 0) 11:5: Call with wrong number of arguments (expected at least 2, got 1) """ Cython-0.23.4/tests/errors/e_multass.pyx0000644000175600017570000000027312606202452021422 0ustar jenkinsjenkins00000000000000# mode: error def f(obj1a, obj1b): cdef int int1, int2, int3 cdef int *ptr2 int1, int3, obj1a = int2, ptr2, obj1b # error _ERRORS = u""" 6:31: Cannot assign type 'int *' to 'int' """ Cython-0.23.4/tests/errors/e_invalid_num_threads.pyx0000644000175600017570000000136212606202452023751 0ustar jenkinsjenkins00000000000000# mode: error from cython.parallel cimport parallel, prange cdef int i # valid with nogil, parallel(num_threads=None): pass # invalid with nogil, parallel(num_threads=0): pass with nogil, parallel(num_threads=i): pass with nogil, parallel(num_threads=2): for i in prange(10, num_threads=2): pass with nogil, parallel(): for i in prange(10, num_threads=2): pass # this one is valid for i in prange(10, nogil=True, num_threads=2): pass _ERRORS = u""" e_invalid_num_threads.pyx:12:20: argument to num_threads must be greater than 0 e_invalid_num_threads.pyx:19:19: num_threads already declared in outer section e_invalid_num_threads.pyx:23:19: num_threads must be declared in the parent parallel section """ Cython-0.23.4/tests/errors/e_int_literals_py3.py0000644000175600017570000000072512606202452023030 0ustar jenkinsjenkins00000000000000# mode: error # cython: language_level=3 def int_literals(): a = 1L b = 10000000000000L c = 1UL d = 10000000000000UL e = 10000000000000LL _ERRORS = """ 5:8: illegal integer literal syntax in Python source file 6:8: illegal integer literal syntax in Python source file 7:8: illegal integer literal syntax in Python source file 8:8: illegal integer literal syntax in Python source file 9:8: illegal integer literal syntax in Python source file """ Cython-0.23.4/tests/errors/e_int_literals_py2.py0000644000175600017570000000055412606202452023027 0ustar jenkinsjenkins00000000000000# mode: error # cython: language_level=2 def int_literals(): a = 1L # ok b = 10000000000000L # ok c = 1UL d = 10000000000000UL e = 10000000000000LL _ERRORS = """ 7:8: illegal integer literal syntax in Python source file 8:8: illegal integer literal syntax in Python source file 9:8: illegal integer literal syntax in Python source file """ Cython-0.23.4/tests/errors/e_index.pyx0000644000175600017570000000062112606202452021036 0ustar jenkinsjenkins00000000000000# mode: error def f(obj1, obj2): cdef int int1, int2, int3 cdef float flt1, *ptr1 cdef int array1[42] int1 = array1[flt1] # error int1 = array1[ptr1] # error int1 = int2[int3] # error obj1 = obj2[ptr1] # error _ERRORS = u""" 7:14: Invalid index type 'float' 8:14: Invalid index type 'float *' 9:12: Attempting to index non-array type 'int' 10:17: Cannot convert 'float *' to Python object """ Cython-0.23.4/tests/errors/e_generators.pyx0000644000175600017570000000042512606202452022102 0ustar jenkinsjenkins00000000000000# mode: error def foo(): yield return 0 def bar(a): return 0 yield yield class Foo: yield _ERRORS = u""" #5:4: 'return' with argument inside generator #9:4: 'yield' outside function 11:0: 'yield' not supported here 14:4: 'yield' not supported here """ Cython-0.23.4/tests/errors/e_fused_closure.pyx0000644000175600017570000000106012606202452022567 0ustar jenkinsjenkins00000000000000# mode: error cimport cython def closure(cython.integral i): def inner(cython.floating f): pass def closure2(cython.integral i): return lambda cython.integral i: i def closure3(cython.integral i): def inner(): return lambda cython.floating f: f def generator(cython.integral i): yield i _ERRORS = u""" e_fused_closure.pyx:6:4: Cannot nest fused functions e_fused_closure.pyx:10:11: Fused lambdas not allowed e_fused_closure.pyx:14:15: Fused lambdas not allowed e_fused_closure.pyx:16:0: Fused generators not supported """ Cython-0.23.4/tests/errors/e_func_in_pxd_support.pxd0000644000175600017570000000015012606202452023767 0ustar jenkinsjenkins00000000000000cdef foo(): return 1 cdef public inline foo2(): return 1 cdef api inline foo3(): return 1 Cython-0.23.4/tests/errors/e_func_in_pxd.pyx0000644000175600017570000000040012606202452022216 0ustar jenkinsjenkins00000000000000# mode: error cimport e_func_in_pxd_support _ERRORS = u""" 1:5: function definition in pxd file must be declared 'cdef inline' 4:5: inline function definition in pxd file cannot be 'public' 7:5: inline function definition in pxd file cannot be 'api' """ Cython-0.23.4/tests/errors/e_extweakref.pyx0000644000175600017570000000126212606202452022076 0ustar jenkinsjenkins00000000000000# mode: error cdef class C: cdef object __weakref__ cdef class D: cdef public object __weakref__ cdef class E: cdef readonly object __weakref__ cdef void f(): cdef C c = C() cdef object x x = c.__weakref__ c.__weakref__ = x _ERRORS = u""" 7:20: Illegal use of special attribute __weakref__ 7:20: Illegal use of special attribute __weakref__ 7:20: Illegal use of special attribute __weakref__ 7:20: Special attribute __weakref__ cannot be exposed to Python 10:22: Illegal use of special attribute __weakref__ 10:22: Special attribute __weakref__ cannot be exposed to Python 15:6: Illegal use of special attribute __weakref__ 16:2: Illegal use of special attribute __weakref__ """ Cython-0.23.4/tests/errors/e_exttype_freelist.pyx0000644000175600017570000000057212606202452023333 0ustar jenkinsjenkins00000000000000# mode: error # tag: freelist, werror cimport cython @cython.freelist(8) cdef class ExtType: pass @cython.freelist(8) cdef class ExtTypeObject(object): pass cdef class ExtSubTypeOk(ExtType): pass @cython.freelist(8) cdef class ExtSubTypeFail(ExtType): pass _ERRORS = """ 18:5: freelists cannot be used on subtypes, only the base class can manage them """ Cython-0.23.4/tests/errors/e_excvalfunctype.pyx0000644000175600017570000000050412606202452022767 0ustar jenkinsjenkins00000000000000# mode: error ctypedef int (*spamfunc)(int, char *) except 42 ctypedef int (*grailfunc)(int, char *) cdef grailfunc grail cdef spamfunc spam grail = spam # type mismatch spam = grail # type mismatch _ERRORS = u""" 9:28: Cannot assign type 'spamfunc' to 'grailfunc' 10:28: Cannot assign type 'grailfunc' to 'spamfunc' """ Cython-0.23.4/tests/errors/e_exceptclause.pyx0000644000175600017570000000034012606202452022412 0ustar jenkinsjenkins00000000000000# mode: error try: raise KeyError except KeyError: pass except: pass except: pass except AttributeError: pass _ERRORS = u""" 9:0: default 'except:' must be last 11:0: default 'except:' must be last """ Cython-0.23.4/tests/errors/e_directives.pyx0000644000175600017570000000052312606202452022071 0ustar jenkinsjenkins00000000000000# mode: error # cython: nonexistant = True # cython: boundscheck = true # cython: boundscheck = 9 print 3 # Options should not be interpreted any longer: # cython: boundscheck = true _ERRORS = u""" 4:0: boundscheck directive must be set to True or False, got 'true' 5:0: boundscheck directive must be set to True or False, got '9' """ Cython-0.23.4/tests/errors/e_del.pyx0000644000175600017570000000130512606202452020473 0ustar jenkinsjenkins00000000000000# mode: error cdef struct S: int m def f(a): cdef int i, x[2] cdef S s global j del f() # error del i # error: deletion of non-Python object del j # error: deletion of non-Python object del x[i] # error: deletion of non-Python object del s.m # error: deletion of non-Python object def outer(a): def inner(): print a del a return inner() cdef object g del g _ERRORS = u""" 10:9: Cannot assign to or delete this 11:48: Deletion of non-Python, non-C++ object 13:9: Deletion of non-Python, non-C++ object 14:9: Deletion of non-Python, non-C++ object 19:9: can not delete variable 'a' referenced in nested scope 23:5: Deletion of global C variable """ Cython-0.23.4/tests/errors/e_decorators.pyx0000644000175600017570000000016712606202452022101 0ustar jenkinsjenkins00000000000000# mode: error _ERRORS = u""" 4:4 Expected a newline after decorator """ class A: pass @A().a def f(): pass Cython-0.23.4/tests/errors/e_declarations.pyx0000644000175600017570000000065112606202452022402 0ustar jenkinsjenkins00000000000000# mode: error cdef extern void fa[5]() cdef extern int af()[5] cdef extern int ff()() cdef void f(): cdef void *p cdef int (*h)() h = f # this is an error h = f # this is OK _ERRORS = u""" 3:20: Template arguments must be a list of names 3:20: Template parameter not a type 5:18: Function cannot return a function 10:10: Function cannot return a function 10:5: Cannot cast to a function type """ Cython-0.23.4/tests/errors/e_cython_parallel.pyx0000644000175600017570000001215712606202452023116 0ustar jenkinsjenkins00000000000000# mode: error cimport cython.parallel.parallel as p from cython.parallel cimport something import cython.parallel.parallel as p from cython.parallel import something from cython.parallel cimport prange import cython.parallel prange(1, 2, 3, schedule='dynamic') cdef int i with nogil, cython.parallel.parallel(): for i in prange(10, schedule='invalid_schedule'): pass with cython.parallel.parallel(): print "hello world!" cdef int *x = NULL with nogil, cython.parallel.parallel(): for j in prange(10): pass for x[1] in prange(10): pass for x in prange(10): pass with cython.parallel.parallel(): pass with nogil, cython.parallel.parallel: pass cdef int y for i in prange(10, nogil=True): i = y * 4 y = i for i in prange(10, nogil=True): y = i i = y * 4 y = i with nogil, cython.parallel.parallel(): i = y y = i for i in prange(10, nogil=True): y += i y *= i with nogil, cython.parallel.parallel("invalid"): pass with nogil, cython.parallel.parallel(invalid=True): pass def f(x): cdef int i with nogil, cython.parallel.parallel(): with gil: yield x for i in prange(10): with gil: yield x # Disabled nesting: for i in prange(10, nogil=True): for y in prange(10): pass with nogil, cython.parallel.parallel(): for i in prange(10): for i in prange(10): pass # Assign to private from parallel block in prange: cdef int myprivate1, myprivate2 with nogil, cython.parallel.parallel(): myprivate1 = 1 for i in prange(10): myprivate1 = 3 myprivate2 = 4 myprivate2 = 2 # Disallow parallel with block reductions: i = 0 with nogil, cython.parallel.parallel(): i += 1 # Use of privates after the parallel with block with nogil, cython.parallel.parallel(): i = 1 print i i = 2 print i # Reading of reduction variables in the prange block cdef int sum = 0 for i in prange(10, nogil=True): sum += i with gil: print sum for pyobj in prange("hello"): pass from cython import parallel with nogil, parallel.parallel(): for i in parallel.prange(10): pass cdef int[:] dst, src = object() for i in prange(10, nogil=True): dst = src for i in prange(10, nogil=True, chunksize=20): pass for i in prange(10, nogil=True, schedule='static', chunksize=-1): pass for i in prange(10, nogil=True, schedule='runtime', chunksize=10): pass cdef int chunksize(): return 10 for i in prange(10, nogil=True, schedule='static', chunksize=chunksize()): pass with nogil, cython.parallel.parallel(): with cython.parallel.parallel(): pass _ERRORS = u""" e_cython_parallel.pyx:3:8: cython.parallel.parallel is not a module e_cython_parallel.pyx:4:0: No such directive: cython.parallel.something e_cython_parallel.pyx:6:7: cython.parallel.parallel is not a module e_cython_parallel.pyx:7:0: No such directive: cython.parallel.something e_cython_parallel.pyx:13:6: prange() can only be used as part of a for loop e_cython_parallel.pyx:13:6: prange() can only be used without the GIL e_cython_parallel.pyx:18:19: Invalid schedule argument to prange: invalid_schedule c_cython_parallel.pyx:21:29: The parallel section may only be used without the GIL e_cython_parallel.pyx:27:10: target may not be a Python object as we don't have the GIL e_cython_parallel.pyx:30:9: Can only iterate over an iteration variable e_cython_parallel.pyx:33:10: Must be of numeric type, not int * e_cython_parallel.pyx:36:33: Nested parallel with blocks are disallowed e_cython_parallel.pyx:39:12: The parallel directive must be called e_cython_parallel.pyx:45:10: local variable 'y' referenced before assignment e_cython_parallel.pyx:55:9: local variable 'y' referenced before assignment e_cython_parallel.pyx:60:6: Reduction operator '*' is inconsistent with previous reduction operator '+' e_cython_parallel.pyx:62:36: cython.parallel.parallel() does not take positional arguments e_cython_parallel.pyx:65:36: Invalid keyword argument: invalid e_cython_parallel.pyx:73:12: Yield not allowed in parallel sections e_cython_parallel.pyx:77:16: Yield not allowed in parallel sections e_cython_parallel.pyx:97:19: Cannot assign to private of outer parallel block e_cython_parallel.pyx:98:19: Cannot assign to private of outer parallel block e_cython_parallel.pyx:104:6: Reductions not allowed for parallel blocks e_cython_parallel.pyx:110:7: local variable 'i' referenced before assignment e_cython_parallel.pyx:119:17: Cannot read reduction variable in loop body e_cython_parallel.pyx:121:20: stop argument must be numeric e_cython_parallel.pyx:121:19: prange() can only be used without the GIL e_cython_parallel.pyx:131:8: Memoryview slices can only be shared in parallel sections e_cython_parallel.pyx:133:42: Must provide schedule with chunksize e_cython_parallel.pyx:136:62: Chunksize must not be negative e_cython_parallel.pyx:139:62: Chunksize not valid for the schedule runtime e_cython_parallel.pyx:145:70: Calling gil-requiring function not allowed without gil e_cython_parallel.pyx:149:33: Nested parallel with blocks are disallowed """ Cython-0.23.4/tests/errors/e_cunion.pyx0000644000175600017570000000053712606202452021230 0ustar jenkinsjenkins00000000000000# mode: error cdef union AllCharptr: char *s1 char *s2 char *s3 def convert_ok(): cdef AllCharptr u u.s1 = b"abc" return u cdef union IllegalMix: char *s1 char *s2 int i def convert_nok(): cdef IllegalMix u u.i = 5 return u _ERRORS = """ 24:12: Cannot convert 'IllegalMix' to Python object """ Cython-0.23.4/tests/errors/e_ctypedefornot.pyx0000644000175600017570000000037312606202452022620 0ustar jenkinsjenkins00000000000000# mode: error cdef struct Foo ctypedef struct Foo: int i ctypedef struct Blarg: char c cdef struct Blarg cdef Foo f cdef Blarg b _ERRORS = u""" 5:0: 'Foo' previously declared using 'cdef' 11:5: 'Blarg' previously declared using 'ctypedef' """ Cython-0.23.4/tests/errors/e_cstruct.pyx0000644000175600017570000000157012606202452021422 0ustar jenkinsjenkins00000000000000# mode: error cdef struct Spam: int i char c float[42] *p obj # error - py object #cdef struct Spam: # error - redefined (not an error in Cython, should it be?) # int j cdef struct Grail cdef void eggs(Spam s): cdef int j cdef Grail *gp j = s.k # error - undef attribute j = s.p # type error s.p = j # type error j = j.i # no error - coercion to Python object j.i = j # no error - coercion to Python object j = gp.x # error - incomplete type gp.x = j # error - incomplete type _ERRORS = u""" 7:39: C struct/union member cannot be a Python object 17:9: Object of type 'Spam' has no attribute 'k' 18:9: Cannot assign type 'float (*)[42]' to 'int' 19:24: Cannot assign type 'int' to 'float (*)[42]' 22:10: Cannot select attribute of incomplete type 'Grail' 23:6: Cannot select attribute of incomplete type 'Grail' """ Cython-0.23.4/tests/errors/e_cmp.pyx0000644000175600017570000000064512606202452020514 0ustar jenkinsjenkins00000000000000# mode: error cdef void foo(): cdef int bool, int1 cdef char *ptr2 cdef int *ptr3 cdef object i = 5 bool = i == ptr2 # evaluated in Python space bool = ptr3 == i # error bool = int1 == ptr2 # error bool = ptr2 == ptr3 # error bool = 1 in 2 in 3 _ERRORS = u""" 10:13: Invalid types for '==' (int *, Python object) 11:13: Invalid types for '==' (int, char *) 12:13: Invalid types for '==' (char *, int *) """ Cython-0.23.4/tests/errors/e_cmethbasematch.pyx0000644000175600017570000000033112606202452022675 0ustar jenkinsjenkins00000000000000# mode: error cdef class C: cdef void f(self): pass cdef class D(C): cdef void f(self, int x): pass _ERRORS = u""" 8:6: Signature not compatible with previous declaration 4:6: Previous declaration is here """ Cython-0.23.4/tests/errors/e_cenum.pyx0000644000175600017570000000024012606202452021033 0ustar jenkinsjenkins00000000000000# mode: error cdef enum Spam: a, b, c cdef void f(): global a a = 42 # assignment to non-lvalue _ERRORS = u""" 8:3: Assignment to non-lvalue 'a' """ Cython-0.23.4/tests/errors/e_cdefemptysue.pyx0000644000175600017570000000054012606202452022424 0ustar jenkinsjenkins00000000000000# mode: error cdef struct spam: pass ctypedef union eggs: pass cdef enum ham: pass _ERRORS = u""" 3:5: Empty struct or union definition not allowed outside a 'cdef extern from' block 6:0: Empty struct or union definition not allowed outside a 'cdef extern from' block 9:5: Empty enum definition not allowed outside a 'cdef extern from' block """ Cython-0.23.4/tests/errors/e_cdefassign.pyx0000644000175600017570000000044412606202452022040 0ustar jenkinsjenkins00000000000000# mode: error cdef class A: cdef int value = 3 cdef extern from *: cdef struct B: int value = 3 _ERRORS = u""" 4:13: Cannot assign default value to fields in cdef classes, structs or unions 8:12: Cannot assign default value to fields in cdef classes, structs or unions """ Cython-0.23.4/tests/errors/e_cdef_yield.pyx0000644000175600017570000000024012606202452022013 0ustar jenkinsjenkins00000000000000# mode: error cdef cdef_yield(): yield cpdef cpdef_yield(): yield _ERRORS = u""" 4:4: 'yield' not supported here 7:4: 'yield' not supported here """ Cython-0.23.4/tests/errors/e_cdef_missing_declarator.pyx0000644000175600017570000000014312606202452024560 0ustar jenkinsjenkins00000000000000# mode: error cdef int cdef extern from *: void f(int) _ERRORS = u""" 3:8: Empty declarator """ Cython-0.23.4/tests/errors/e_cdef_keywords_T241.pyx0000644000175600017570000000452612606202452023301 0ustar jenkinsjenkins00000000000000# ticket: 241 # mode: error cdef some_function(x, y): pass cdef class A: cdef some_method(self, x, y=1): pass from libc.string cimport strcmp cdef extern from "string.h": char *strstr(char*, char*) # ok some_function(1, 2) some_function(1, y=2) # nok some_function(1, x=1) some_function(1, x=2, y=2) some_function(1, y=2, z=3) some_function(1, z=3) some_function(1, 2, z=3) some_function(x=1, y=2, z=3) some_function(x=1, y=2, x=1) some_function(x=1, y=2, x=1, z=3) cdef A a = A() # ok a.some_method(1) a.some_method(1, 2) a.some_method(1, y=2) a.some_method(x=1, y=2) # nok a.some_method(1, x=1) a.some_method(1, 2, x=1) a.some_method(1, 2, y=2) a.some_method(1, 2, x=1, y=2) a.some_method(1, 2, y=2, x=1) a.some_method(1, y=2, x=1) a.some_method(1, 2, z=3) a.some_method(1, y=2, z=3) a.some_method(x=1, x=1) a.some_method(x=1, x=1, y=2) a.some_method(x=1, y=2, x=1) # ok strcmp("abc", "cde") strcmp("abc", s2="cde") strcmp(s1="abc", s2="cde") strcmp(s2="cde", s1="abc") # nok strcmp("abc", s1="cde") strcmp("abc", s2="cde", s1="cde") strcmp(s1="abc", s2="cde", s1="cde") strcmp(s2="cde", s1="abc", s2="cde") # ok strstr("abc", "abcdef") # nok strstr("abc", char="abcdef") strstr("abc", "abcdef", char="xyz") _ERRORS = u""" 22:18: argument 'x' passed twice 23:18: argument 'x' passed twice 24:23: C function got unexpected keyword argument 'z' 25:18: C function got unexpected keyword argument 'z' 26:21: C function got unexpected keyword argument 'z' 27:25: C function got unexpected keyword argument 'z' 28:25: argument 'x' passed twice 29:25: argument 'x' passed twice 29:30: C function got unexpected keyword argument 'z' 39:18: argument 'x' passed twice 40:21: argument 'x' passed twice 41:21: argument 'y' passed twice 42:21: argument 'x' passed twice 42:26: argument 'y' passed twice 43:21: argument 'y' passed twice 43:26: argument 'x' passed twice 44:23: argument 'x' passed twice 45:21: C function got unexpected keyword argument 'z' 46:23: C function got unexpected keyword argument 'z' 47:20: argument 'x' passed twice 48:20: argument 'x' passed twice 49:25: argument 'x' passed twice 58:16: argument 's1' passed twice 59:26: argument 's1' passed twice 60:29: argument 's1' passed twice 61:29: argument 's2' passed twice 67:18: C function got unexpected keyword argument 'char' 68:28: C function got unexpected keyword argument 'char' """ Cython-0.23.4/tests/errors/e_cdef_closure.pyx0000644000175600017570000000021512606202452022363 0ustar jenkinsjenkins00000000000000# mode: error cpdef cpdef_yield(): def inner(): pass _ERRORS = u""" 3:6: closures inside cpdef functions not yet supported """ Cython-0.23.4/tests/errors/e_callspec.pyx0000644000175600017570000000404012606202452021514 0ustar jenkinsjenkins00000000000000# mode: error cimport cython ctypedef int USERTYPE # Functions @cython.callspec("") cdef void h1(): pass @cython.callspec("__cdecl") cdef void __cdecl h2(): pass @cython.callspec("__stdcall") cdef void __stdcall h3(): pass @cython.callspec("__fastcall") cdef void __fastcall h4(): pass cdef USERTYPE h5(): return 0 cdef USERTYPE __cdecl h6(): return 0 cdef USERTYPE __stdcall h7(): return 0 cdef USERTYPE __fastcall h8(): return 0 @cython.callspec("__cdecl") cdef void __stdcall herr1(): pass # fail @cython.callspec("__cdecl") cdef void __fastcall herr2(): pass # fail # Pointer typedefs ctypedef void (*PT1)() ctypedef void (__cdecl *PT2)() ctypedef void (__stdcall *PT3)() ctypedef void (__fastcall *PT4)() ctypedef USERTYPE (*PT5)() ctypedef USERTYPE (__cdecl *PT6)() ctypedef USERTYPE (__stdcall *PT7)() ctypedef USERTYPE (__fastcall *PT8)() # Pointers cdef void (*p1)() cdef void (__cdecl *p2)() cdef void (__stdcall *p3)() cdef void (__fastcall *p4)() cdef USERTYPE (*p5)() cdef USERTYPE (__cdecl *p6)() cdef USERTYPE (__stdcall *p7)() cdef USERTYPE (__fastcall *p8)() cdef PT1 pt1 cdef PT2 pt2 cdef PT3 pt3 cdef PT4 pt4 cdef PT5 pt5 cdef PT6 pt6 cdef PT7 pt7 cdef PT8 pt8 # Assignments p1 = pt1 = p2 = pt2 = h1 p1 = pt1 = p2 = pt2 = h2 p3 = pt3 = h3 p4 = pt4 = h4 p5 = pt5 = p6 = pt6 = h5 p5 = pt5 = p6 = pt6 = h6 p7 = pt7 = h7 p8 = pt8 = h8 #p1 = h2 # fail #p1 = h3 # fail #p1 = h4 # fail #p2 = h1 # fail #p2 = h3 # fail #p2 = h4 # fail _ERRORS = u""" 30:25: cannot have both '__stdcall' and '__cdecl' calling conventions 33:26: cannot have both '__fastcall' and '__cdecl' calling conventions """ #31:14: Cannot assign type 'void (__cdecl )(void)' to 'void (*)(void)' #32:14: Cannot assign type 'void (__stdcall )(void)' to 'void (*)(void)' #33:14: Cannot assign type 'void (__fastcall )(void)' to 'void (*)(void)' #35:14: Cannot assign type 'void (void)' to 'void (__cdecl *)(void)' #36:14: Cannot assign type 'void (__stdcall )(void)' to 'void (__cdecl *)(void)' #37:14: Cannot assign type 'void (__fastcall )(void)' to 'void (__cdecl *)(void)' Cython-0.23.4/tests/errors/e_callnonfunction.pyx0000644000175600017570000000045012606202452023123 0ustar jenkinsjenkins00000000000000# mode: error cdef int i i() cdef float f f() ctypedef struct s: # FIXME: this might be worth an error ... int x s() cdef int x(): return 0 x()() _ERRORS = u""" 4:1: Calling non-function type 'int' 7:1: Calling non-function type 'float' 16:3: Calling non-function type 'int' """ Cython-0.23.4/tests/errors/e_bufaccess_pxd.pxd0000644000175600017570000000005312606202452022512 0ustar jenkinsjenkins00000000000000# See e_bufaccess2.pyx ctypedef nothing T Cython-0.23.4/tests/errors/e_bufaccess2.pyx0000644000175600017570000000156612606202452021760 0ustar jenkinsjenkins00000000000000# mode: error cimport e_bufaccess_pxd # was needed to provoke a bug involving ErrorType import cython def f(): cdef object[e_bufaccess_pxd.T] buf def withnogil_access_fail(): cdef object[int] buf = None with nogil: buf[2] = 2 @cython.boundscheck(False) def withnogil_access_ok(): cdef object[int] buf = None with nogil: buf[2] = 2 # No error should be triggered here @cython.boundscheck(False) def withnogil_access_fail_2(): cdef object[object] buf = None with nogil: buf[2] = 2 # Not OK as dtype is object def withnogil_acquire(x): cdef object[int] buf with nogil: buf = x _ERRORS = u""" 3: 9: 'nothing' is not a type identifier 24:11: Cannot access buffer with object dtype without gil 24:11: Assignment of Python object not allowed without gil 29:12: Assignment of Python object not allowed without gil """ Cython-0.23.4/tests/errors/e_bufaccess.pyx0000644000175600017570000000153312606202452021670 0ustar jenkinsjenkins00000000000000# mode: error cdef object[int] buf cdef class A: cdef object[int] buf def f(): cdef object[fakeoption=True] buf1 cdef object[int, -1] buf1b cdef object[ndim=-1] buf2 cdef object[int, 'a'] buf3 cdef object[int,2,3,4,5,6] buf4 cdef object[int, 2, 'foo'] buf5 cdef object[int, 2, well] buf6 cdef object[x, 1] buf0 _ERRORS = u""" 3:17: Buffer types only allowed as function local variables 5:21: Buffer types only allowed as function local variables 8:31: "fakeoption" is not a buffer option """ #TODO: #7:22: "ndim" must be non-negative #8:15: "dtype" missing #9:21: "ndim" must be an integer #10:15: Too many buffer options #11:24: Only allowed buffer modes are "full" or "strided" (as a compile-time string) #12:28: Only allowed buffer modes are "full" or "strided" (as a compile-time string) #13:17: Invalid type. #""" Cython-0.23.4/tests/errors/e_boolcoerce.pyx0000644000175600017570000000203612606202452022045 0ustar jenkinsjenkins00000000000000# mode: error 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""" 7:26: 'struct_type_not_boolean' is not a constant, variable or function identifier 7:26: Type 'struct_type_not_boolean' not acceptable as a boolean 14:21: 'struct_not_boolean' is not a constant, variable or function identifier 14:21: Type 'struct_not_boolean' not acceptable as a boolean 21:25: 'union_type_not_boolean' is not a constant, variable or function identifier 21:25: Type 'union_type_not_boolean' not acceptable as a boolean 28:20: 'union_not_boolean' is not a constant, variable or function identifier 28:20: Type 'union_not_boolean' not acceptable as a boolean """ Cython-0.23.4/tests/errors/e_bitop.pyx0000644000175600017570000000023512606202452021045 0ustar jenkinsjenkins00000000000000# mode: error def f(): cdef int int1, int2 cdef char *ptr int1 = int2 | ptr # error _ERRORS = u""" 6:13: Invalid operand types for '|' (int; char *) """ Cython-0.23.4/tests/errors/e_badtypeuse.pyx0000644000175600017570000000263712606202452022105 0ustar jenkinsjenkins00000000000000# mode: error cdef struct Grail cdef extern object xobj # Python object cannot be extern cdef object aobj[42] # array element cannot be Python object cdef object *pobj # pointer base type cannot be Python object cdef int spam[] # incomplete variable type cdef Grail g # incomplete variable type cdef void nada # incomplete variable type cdef int a_spam[17][] # incomplete element type cdef Grail a_g[42] # incomplete element type cdef void a_nada[88] # incomplete element type cdef struct Eggs: int spam[] cdef f(Grail g, # incomplete argument type void v, # incomplete argument type int a[]): pass cdef NoSuchType* ptr ptr = None # This should not produce another error _ERRORS = u""" 5:19: Python object cannot be declared extern 6:16: Array element cannot be a Python object 7:12: Pointer base type cannot be a Python object 9:13: Variable type 'int []' is incomplete 10:11: Variable type 'Grail' is incomplete 11:10: Variable type 'void' is incomplete 13:15: Array element type 'int []' is incomplete 14:14: Array element type 'Grail' is incomplete 15:16: Array element type 'void' is incomplete 18:9: Variable type 'int []' is incomplete #19:1: Function argument cannot be void 21:1: Use spam() rather than spam(void) to declare a function with no arguments. 20:7: Argument type 'Grail' is incomplete 21:1: Invalid use of 'void' 25:5: 'NoSuchType' is not a type identifier """ Cython-0.23.4/tests/errors/e_badpyparam.pyx0000644000175600017570000000020312606202452022043 0ustar jenkinsjenkins00000000000000# mode: error cdef struct Foo def f(Foo *p): pass _ERRORS = u""" 5:6: Cannot convert Python object argument to type 'Foo *' """ Cython-0.23.4/tests/errors/e_badfuncargtype.pyx0000644000175600017570000000071512606202452022731 0ustar jenkinsjenkins00000000000000# mode: error cdef struct Spam cdef extern int spam(void) # function argument cannot be void cdef extern int grail(int i, void v) # function argument cannot be void cdef int tomato(Spam s): # incomplete type pass _ERRORS = u""" 5:21: Use spam() rather than spam(void) to declare a function with no arguments. 6:29: Use spam() rather than spam(void) to declare a function with no arguments. 7:16: Argument type 'Spam' is incomplete """ Cython-0.23.4/tests/errors/e_badexcvaltype.pyx0000644000175600017570000000025712606202452022567 0ustar jenkinsjenkins00000000000000# mode: error cdef char *spam() except -1: pass _ERRORS = u""" 3:26: Cannot assign type 'long' to 'char *' 3:26: Exception value incompatible with function return type """ Cython-0.23.4/tests/errors/e_autotestdict.pyx0000644000175600017570000000025512606202452022446 0ustar jenkinsjenkins00000000000000# mode: error cimport cython @cython.autotestdict(False) def foo(): pass _ERRORS = u""" 6:0: The autotestdict compiler directive is not allowed in function scope """ Cython-0.23.4/tests/errors/e_assnone.pyx0000644000175600017570000000014412606202452021375 0ustar jenkinsjenkins00000000000000# mode: error cdef void spam(): None = 42 _ERRORS = u""" 4:1: Cannot assign to or delete this """ Cython-0.23.4/tests/errors/e_ass.pyx0000644000175600017570000000046212606202452020520 0ustar jenkinsjenkins00000000000000# mode: error cdef void foo(obj): cdef int i1 cdef char *p1 cdef int *p2 i1 = p1 # error p2 = obj # error obj = p2 # error _ERRORS = u""" 7:19: Cannot assign type 'char *' to 'int' 8:20: Cannot convert Python object to 'int *' 10:20: Cannot convert 'int *' to Python object """ Cython-0.23.4/tests/errors/e_arrayassign.pyx0000644000175600017570000000107012606202452022251 0ustar jenkinsjenkins00000000000000# mode: error ctypedef int[1] int_array ctypedef int[2] int_array2 cdef int_array x, y x = y # not an error cdef int_array *x_ptr = &x x_ptr[0] = y # not an error cdef class A: cdef int_array value def __init__(self): self.value = x # not an error cdef int_array2 z z = x # error x = z # error cdef enum: SIZE = 2 ctypedef int[SIZE] int_array_dyn cdef int_array_dyn d d = z # not an error _ERRORS = u""" 20:2: Assignment to slice of wrong length, expected 2, got 1 21:2: Assignment to slice of wrong length, expected 1, got 2 """ Cython-0.23.4/tests/errors/e_argdefault.pyx0000644000175600017570000000072012606202452022045 0ustar jenkinsjenkins00000000000000# mode: error cdef spam(int i, char *s = "blarg", float f): # can't have default value pass def swallow(x, y = 42, z): # non-default after default pass cdef class Grail: def __add__(x, y = 42): # can't have default value pass _ERRORS = u""" 3:10: Non-default argument follows default argument 3:36: Non-default argument following default argument 6:23: Non-default argument following default argument 11:16: This argument cannot have a default value """ Cython-0.23.4/tests/errors/e_addop.pyx0000644000175600017570000000025612606202452021022 0ustar jenkinsjenkins00000000000000# mode: error def f(): cdef int int1, int3 cdef int *ptr1, *ptr2, *ptr3 ptr1 = ptr2 + ptr3 # error _ERRORS = u""" 6:13: Invalid operand types for '+' (int *; int *) """ Cython-0.23.4/tests/errors/e2_packedstruct_T290.pyx0000644000175600017570000000016012606202452023221 0ustar jenkinsjenkins00000000000000# ticket: 290 # mode: error cdef packed foo: pass _ERRORS = u""" 4:12: Expected 'struct', found 'foo' """ Cython-0.23.4/tests/errors/def_nogil.pyx0000644000175600017570000000015312606202452021351 0ustar jenkinsjenkins00000000000000# mode: error def test() nogil: pass _ERRORS = """ 3:0: Python function cannot be declared nogil """ Cython-0.23.4/tests/errors/declareafteruse_T158.pyx0000644000175600017570000000340012606202452023300 0ustar jenkinsjenkins00000000000000# ticket: 158 # mode: error def mult_decl_test(): print "%s" % vv print "%s" % s cdef str s, vv = "Test" def def_test(): cdef int j = 10 i[0] = j cdef int *i = NULL # pointer variables are special case cdef cdef_test(): cdef int j = 10 i[0] = j print "%d" % i[0] cdef int *i = NULL cpdef cpdef_test(): cdef int j = 10 i[0] = j print "%d" % i[0] cdef int *i = NULL s.upper() cdef str s = "Test" class Foo(object): def bar(self, x, y): cdef unsigned long w = 20 z = w + t cdef int t = 10 cdef class Foo2(object): print '%s' % r # check error inside class scope cdef str r def bar(self, x, y): cdef unsigned long w = 20 self.r = c'r' print self.r z = w + g(t) cdef int t = 10 def g(x): return x cdef int d = 20 baz[0] = d cdef int *baz print var[0][0] cdef unsigned long long[100][100] var # in 0.11.1 these are warnings FUTURE_ERRORS = u""" 6:13: cdef variable 's' declared after it is used 6:16: cdef variable 'vv' declared after it is used 11:14: cdef variable 'i' declared after it is used 17:14: cdef variable 'i' declared after it is used 23:14: cdef variable 'i' declared after it is used 26:9: cdef variable 's' declared after it is used 32:17: cdef variable 't' declared after it is used 36:13: cdef variable 'r' declared after it is used 42:17: cdef variable 't' declared after it is used 49:10: cdef variable 'baz' declared after it is used 52:24: cdef variable 'var' declared after it is used """ syntax error _ERRORS = u""" 42:17: cdef variable 't' declared after it is used 49:10: cdef variable 'baz' declared after it is used 52:24: cdef variable 'var' declared after it is used 70:7: Syntax error in simple statement list """ Cython-0.23.4/tests/errors/cython3_bytes.pyx0000644000175600017570000000031412606202452022217 0ustar jenkinsjenkins00000000000000# mode: error # -*- coding: utf-8 -*- # cython: language_level=3 escaped = b'abc\xc3\xbc\xc3\xb6\xc3\xa4' invalid = b'abcüöä' _ERRORS = """ 6:10: bytes can only contain ASCII literal characters. """ Cython-0.23.4/tests/errors/cpp_object_template.pyx0000644000175600017570000000053712606202452023434 0ustar jenkinsjenkins00000000000000# mode: error from libcpp.vector cimport vector cdef class A: pass def main(): cdef vector[object] vo vo.push_back(object()) cdef vector[A] va va.push_back(A()) _ERRORS = u""" 9:16: Python object type 'Python object' cannot be used as a template argument 11:16: Python object type 'A' cannot be used as a template argument """ Cython-0.23.4/tests/errors/cpp_no_constructor.pyx0000644000175600017570000000030412606202452023344 0ustar jenkinsjenkins00000000000000# tag: cpp # mode: error cdef extern from *: cdef cppclass Foo: Foo() Foo(int) new Foo(1, 2) _ERRORS = u""" 9:7: Call with wrong number of arguments (expected 1, got 2) """ Cython-0.23.4/tests/errors/cpp_no_auto_conversion.pyx0000644000175600017570000000121112606202452024172 0ustar jenkinsjenkins00000000000000# mode: error # tag: cpp # cpp will convert function arguments to a type if it has suitable constructor # we do not want that when calling from cython cdef extern from "no_such_file.cpp" nogil: cppclass wrapped_int: long long val wrapped_int() wrapped_int(long long val) wrapped_int& operator=(const wrapped_int &other) wrapped_int& operator=(const long long other) long long constructor_overload(const wrapped_int& x) long long constructor_overload(const wrapped_int x) cdef long long e = constructor_overload(17) _ERRORS = u""" 18:40: Cannot assign type 'long' to 'const wrapped_int' """ Cython-0.23.4/tests/errors/cpp_comparison.pyx0000644000175600017570000000045212606202452022441 0ustar jenkinsjenkins00000000000000# mode: error # tag: cpp from libcpp.vector cimport vector def vector_is_none(vector[int] iv): # TODO: this isn't strictly wrong, so it might be allowed as a 'feature' at some point if iv is None: pass _ERRORS = """ 8:10: Invalid types for 'is' (vector[int], Python object) """ Cython-0.23.4/tests/errors/cpdef_syntax.pyx0000644000175600017570000000031212606202452022107 0ustar jenkinsjenkins00000000000000# mode: error cpdef nogil: pass cpdef nogil class test: pass _ERRORS = u""" 3: 6: cdef blocks cannot be declared cpdef 4: 6: cdef blocks cannot be declared cpdef 4:12: Expected ':', found 'class' """ Cython-0.23.4/tests/errors/continue_outside_loop.pyx0000644000175600017570000000111112606202452024027 0ustar jenkinsjenkins00000000000000# cython: remove_unreachable=False # mode: error continue class A: continue cdef class B: continue def test(): continue try: continue except: pass try: continue finally: pass if bool_result(): continue else: continue def bool_result(): return True _ERRORS = u''' 4:0: continue statement not inside loop 7:4: continue statement not inside loop 10:4: continue statement not inside loop 13:4: continue statement not inside loop 18:5: continue statement not inside loop 22:4: continue statement not inside loop 24:4: continue statement not inside loop ''' Cython-0.23.4/tests/errors/const_decl_errors.pyx0000644000175600017570000000140312606202452023133 0ustar jenkinsjenkins00000000000000# mode: error cdef const object o # TODO: This requires making the assignment at declaration time. # (We could fake this case by dropping the const here in the C code, # as it's not needed for agreeing with external libraries. cdef const int x = 10 cdef struct S: int member cdef func(const int a, const int* b, const (int*) c, const S s, int *const d, const S *const t): a = 10 c = NULL b[0] = 100 s.member = 1000 d = NULL t = &s _ERRORS = """ 3:5: Const base type cannot be a Python object 8:5: Assignment to const 'x' 15:6: Assignment to const 'a' 16:6: Assignment to const 'c' 17:5: Assignment to const dereference 18:5: Assignment to const attribute 'member' 19:6: Assignment to const 'd' 20:6: Assignment to const 't' """ Cython-0.23.4/tests/errors/compile_time_unraisable_T370.pyx0000644000175600017570000000024112606202452025011 0ustar jenkinsjenkins00000000000000# ticket: 370 # mode: error cdef int raiseit(): raise IndexError try: raiseit() except: pass _ERRORS = u""" FIXME: provide a good error message here. """ Cython-0.23.4/tests/errors/cmethbasematch.pyx0000644000175600017570000000035612606202452022400 0ustar jenkinsjenkins00000000000000# mode: error cdef class C: cdef void f(self): pass cdef class D(C): cdef void f(self, int x): pass _ERRORS = u""" 8: 9: Signature not compatible with previous declaration 4: 9: Previous declaration is here """ Cython-0.23.4/tests/errors/charptr_from_temp.pyx0000644000175600017570000000275112606202452023144 0ustar jenkinsjenkins00000000000000# mode: error # tag: werror, charptr, conversion, temp, py_unicode_strings cdef bytes c_s = b"abc" s = b"abc" cdef char* cptr # constant => ok cptr = b"xyz" # global cdef variable => ok cptr = c_s # pyglobal => warning cptr = s # temp => error cptr = s + b"cba" # indexing => error (but not clear enough to make it a compiler error) cptr = s[0] cdef char* x = s[0] # slicing => error cptr = s[:2] cdef unicode c_u = u"abc" u = u"abc" cdef Py_UNICODE* cuptr # constant => ok cuptr = u"xyz" # global cdef variable => ok cuptr = c_u # pyglobal => warning cuptr = u # temp => error cuptr = u + u"cba" # coercion in conditional expression => ok boolval = list(u) cptr = c_s if boolval else c_s # temp in conditional expression => error cptr = s + b'x' if boolval else s + b'y' _ERRORS = """ 16:8: Obtaining 'char *' from externally modifiable global Python value 19:9: Storing unsafe C derivative of temporary Python reference #22:8: Storing unsafe C derivative of temporary Python reference #23:5: Storing unsafe C derivative of temporary Python reference #23:15: Casting temporary Python object to non-numeric non-Python type 26:8: Storing unsafe C derivative of temporary Python reference 41:9: Obtaining 'Py_UNICODE *' from externally modifiable global Python value 44:10: Storing unsafe C derivative of temporary Python reference 52:7: Storing unsafe C derivative of temporary Python reference 52:7: Unsafe C derivative of temporary Python reference used in conditional expression """ Cython-0.23.4/tests/errors/cfunc_directive_in_pyclass.pyx0000644000175600017570000000024312606202452025003 0ustar jenkinsjenkins00000000000000# mode: error import cython class Pyclass(object): @cython.cfunc def bad(self): pass _ERRORS = """ 6:4: cfunc directive is not allowed here """ Cython-0.23.4/tests/errors/cdefspecial.pyx0000644000175600017570000000037312606202452021671 0ustar jenkinsjenkins00000000000000# mode: error cdef class Test: cdef __cinit__(self): pass cdef __len__(self): pass _ERRORS = u""" 4:9: Special methods must be declared with 'def', not 'cdef' 7:9: Special methods must be declared with 'def', not 'cdef' """ Cython-0.23.4/tests/errors/cdefoptargs.pyx0000644000175600017570000000024712606202452021730 0ustar jenkinsjenkins00000000000000# mode: error def call5(): b(1,2,3,4,5) cdef b(a, b, c=1, d=2): pass _ERRORS = u""" 4:5:Call with wrong number of arguments (expected at most 4, got 5) """ Cython-0.23.4/tests/errors/cdefkwargs.pyx0000644000175600017570000000055312606202452021547 0ustar jenkinsjenkins00000000000000# mode: error __doc__ = u""" >>> call2() >>> call3() >>> call4() """ import sys, re if sys.version_info >= (2,6): __doc__ = re.sub(u"Error: (.*)exactly(.*)", u"Error: \\1at most\\2", __doc__) # the calls: def call2(): b(1,2) def call3(): b(1,2,3) def call4(): b(1,2,3,4) # the called function: cdef b(a, b, c=1, d=2): pass Cython-0.23.4/tests/errors/cdef_syntax.pyx0000644000175600017570000000026712606202452021740 0ustar jenkinsjenkins00000000000000# mode: error cdef pass cdef void cdef nogil class test: pass _ERRORS = u""" 3: 5: Expected an identifier, found 'pass' 4: 9: Empty declarator 5:11: Expected ':', found 'class' """ Cython-0.23.4/tests/errors/cdef_members_T517.pyx0000644000175600017570000000110412606202452022553 0ustar jenkinsjenkins00000000000000# ticket: 517 # mode: error ctypedef void* VoidP cdef class Spam: cdef VoidP vp0 cdef readonly VoidP vp2 cdef public VoidP vp1 ctypedef struct Foo: int i cdef class Bar: cdef Foo foo0 cdef readonly Foo foo2 cdef public Foo foo1 pass _ERRORS = u""" 8:24: C attribute of type 'VoidP' cannot be accessed from Python 8:24: Cannot convert 'VoidP' to Python object 9:24: C attribute of type 'VoidP' cannot be accessed from Python 9:24: Cannot convert 'VoidP' to Python object 9:24: Cannot convert Python object to 'VoidP' """ Cython-0.23.4/tests/errors/cdef_in_pyclass.pyx0000644000175600017570000000020012606202452022541 0ustar jenkinsjenkins00000000000000# mode: error class Pyclass(object): cdef bad(self): pass _ERRORS = """ 4:9: cdef statement not allowed here """ Cython-0.23.4/tests/errors/callingnonexisting_T307.pyx0000644000175600017570000000017612606202452024044 0ustar jenkinsjenkins00000000000000# ticket: 307 # mode: error nonexisting(3, with_kw_arg=4) _ERRORS = u""" 4:11: undeclared name not builtin: nonexisting """ Cython-0.23.4/tests/errors/callargs.pyx0000644000175600017570000000102512606202452021212 0ustar jenkinsjenkins00000000000000# mode: error def f(*args, **kwargs): pass args = (1,2,3) kwargs = {u"test" : "toast"} def test(): # ok f(1, 2, c=3, *args, d=5, **kwargs, **kwargs) f(1, 2, c=3, *args, d=5, **kwargs, x=6) f(1, 2, **kwargs, c=3) f(1, 2, c=3, *args, *args, **kwargs) f(*args, 1, 2, 3) # errors f(**kwargs, 1, 2, c=3) f(*args, **kwargs, *args) f(1, 2, c=3, *args, **kwargs, *args) f(1=2) # too bad we don't get more errors here ... _ERRORS = u""" 17:16: Non-keyword arg following keyword arg """ Cython-0.23.4/tests/errors/builtin_type_inheritance.pyx0000644000175600017570000000077312606202452024513 0ustar jenkinsjenkins00000000000000# mode: error # current restriction: cannot inherit from PyVarObject (see ticket #152) cdef class MyTuple(tuple): pass cdef class MyBytes(bytes): pass cdef class MyStr(str): # only in Py2, but can't know that during compilation pass _ERRORS = """ 5:5: inheritance from PyVarObject types like 'tuple' is not currently supported 8:5: inheritance from PyVarObject types like 'bytes' is not currently supported 11:5: inheritance from PyVarObject types like 'str' is not currently supported """ Cython-0.23.4/tests/errors/buffertypedef_T117.pyx0000644000175600017570000000027112606202452022772 0ustar jenkinsjenkins00000000000000# ticket: 117 # mode: error ctypedef object[float] mybuffer _ERRORS = u""" 1:0: Buffer vars not allowed in module scope 4:0: Buffer types only allowed as function local variables """ Cython-0.23.4/tests/errors/bufaccess_noassignT444.pyx0000644000175600017570000000030212606202452023636 0ustar jenkinsjenkins00000000000000# ticket: 444 # mode: error def test(): cdef object[int] not_assigned_to not_assigned_to[2] = 3 _ERRORS = """ 6:20: local variable 'not_assigned_to' referenced before assignment """ Cython-0.23.4/tests/errors/break_outside_loop.pyx0000644000175600017570000000103512606202452023274 0ustar jenkinsjenkins00000000000000# cython: remove_unreachable=False # mode: error break class A: break cdef class B: break def test(): break try: break except: pass try: break finally: pass if bool_result(): break else: break def bool_result(): return True _ERRORS = u''' 4:0: break statement not inside loop 7:4: break statement not inside loop 10:4: break statement not inside loop 13:4: break statement not inside loop 18:5: break statement not inside loop 22:4: break statement not inside loop 24:4: break statement not inside loop ''' Cython-0.23.4/tests/compile/0000755000175600017570000000000012606202455017001 5ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/compile/withgil.pyx0000644000175600017570000000015312606202452021206 0ustar jenkinsjenkins00000000000000# mode: compile cdef void f() with gil: x = 42 cdef int g(void* x) with gil: pass f() g("test") Cython-0.23.4/tests/compile/while.pyx0000644000175600017570000000045312606202452020652 0ustar jenkinsjenkins00000000000000# mode: compile def f(a, b): cdef int i = 5 while a: x = 1 while a+b: x = 1 while i: x = 1 else: x = 2 while i: x = 1 break x = 2 else: x = 3 while i: x = 1 continue x = 2 Cython-0.23.4/tests/compile/weakref_T276.pyx0000644000175600017570000000035512606202452021711 0ustar jenkinsjenkins00000000000000# ticket: 276 # mode: compile __doc__ = u""" """ cdef class A: cdef __weakref__ ctypedef public class B [type B_Type, object BObject]: cdef __weakref__ cdef public class C [type C_Type, object CObject]: cdef __weakref__ Cython-0.23.4/tests/compile/watts2.pyx0000644000175600017570000000005312606202452020762 0ustar jenkinsjenkins00000000000000# mode: compile cdef int x x = 0xFFFFFFFF Cython-0.23.4/tests/compile/utf8bom.pyx0000644000175600017570000000023412606202452021123 0ustar jenkinsjenkins00000000000000# coding: utf-8 # mode: compile # this file starts with a UTF-8 encoded BOM # the only thing we test is that it properly compiles def test(): pass Cython-0.23.4/tests/compile/types_and_names.pyx0000644000175600017570000000100212606202452022702 0ustar jenkinsjenkins00000000000000# mode: compile print sizeof(point*) cdef foo(int i0, int i, list L0, list L, point p0, point p, point* ps): pass cdef class A: cdef list cdef list L # Possibly empty declarators cdef point(self, int, int i, list, list L, point, point p, point* ps): pass cdef class B(A): cdef point(self, o, int i, oo, list L, ooo, point p, point* ps): pass cdef point P cdef point *Ps cdef A a foo(2, 3, [], [], P, P, &P) a.point("something", 3, "anything", [], "an object", P, &P) Cython-0.23.4/tests/compile/types_and_names.pxd0000644000175600017570000000021412606202452022661 0ustar jenkinsjenkins00000000000000cdef struct point: double x double y double z cdef foo(int, int i, list, list L, point, point p, point* ps) Cython-0.23.4/tests/compile/typecast.pyx0000644000175600017570000000023612606202452021375 0ustar jenkinsjenkins00000000000000# mode: compile cdef void f(obj): cdef size_t i=0 cdef char *p p = i p = &i obj = p p = obj f(None) Cython-0.23.4/tests/compile/tryfinally.pyx0000644000175600017570000000041212606202452021732 0ustar jenkinsjenkins00000000000000# mode: compile def f(a, b, c, x): cdef int i a = b + c try: return raise a finally: c = a - b for a in b: try: continue break c = a * b finally: i = 42 Cython-0.23.4/tests/compile/tryexcept.pyx0000644000175600017570000000204212606202452021565 0ustar jenkinsjenkins00000000000000# mode: compile def f(a, b, c, x): cdef int i a = b + c try: i = 1 raise x i = 2 except a: i = 3 try: i = 1 except a: i = 2 except b: i = 3 try: i = 1 except a, b: i = 2 try: i = 1 except a: i = 2 except: i = 3 try: i = 1 except (a, b), c[42]: i = 2 for a in b: try: c = x * 42 except: i = 17 try: i = 1 except: raise def g(a, b, c, x): cdef int i a = b + c try: i = 1 raise x i = 2 except a: i = 3 try: i = 1 except a: i = 2 except b: i = 3 try: i = 1 except a as b: i = 2 try: i = 1 except a: i = 2 except: i = 3 try: i = 1 except (a, b) as c: i = 2 except (b, a) as c: i = 3 except: i = 4 else: i = 5 Cython-0.23.4/tests/compile/traceback.pyx0000644000175600017570000000021012606202452021450 0ustar jenkinsjenkins00000000000000# mode: compile def spam(): raise Exception cdef int grail() except -1: raise Exception def tomato(): spam() grail() Cython-0.23.4/tests/compile/templates.h0000644000175600017570000000067412606202452021154 0ustar jenkinsjenkins00000000000000#ifndef _TEMPLATES_H_ #define _TEMPLATES_H_ template class TemplateTest1 { public: T value; int t; TemplateTest1() { } T getValue() { return value; } }; template class TemplateTest2 { public: T value1; U value2; TemplateTest2() { } T getValue1() { return value1; } U getValue2() { return value2; } }; template void template_function(TemplateTest1 &) { } #endif Cython-0.23.4/tests/compile/specmethextarg.pyx0000644000175600017570000000020612606202452022561 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: cdef int eggs def __iadd__(self, Spam other): self.eggs = self.eggs + other.eggs Cython-0.23.4/tests/compile/specmethdocstring.pyx0000644000175600017570000000146612606202452023274 0ustar jenkinsjenkins00000000000000# mode: compile cdef class C: def __cinit__(self): "This is an unusable docstring." def __init__(self): "This is an unusable docstring." def __dealloc__(self): "This is an unusable docstring." def __richcmp__(self, other, int op): "This is an unusable docstring." def __nonzero__(self): "This is an unusable docstring." return False def __contains__(self, other): "This is an unusable docstring." property foo: def __get__(self): "So is this." def __set__(self, x): "And here is another one." def __div__(self, other): "usable docstring" def __iter__(self): "usable docstring" return False def __next__(self): "usable docstring" return False Cython-0.23.4/tests/compile/specmethargdefault.pyx0000644000175600017570000000021312606202452023403 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Grail: def __cinit__(self, spam = None): pass def __init__(self, parrot = 42): pass Cython-0.23.4/tests/compile/specialfloatvals.pyx0000644000175600017570000000026212606202452023074 0ustar jenkinsjenkins00000000000000# mode: compile DEF nan = float('nan') DEF inf = float('inf') DEF minf = -float('inf') cdef int f() except -1: cdef float x, y, z x = nan y = inf z = minf f() Cython-0.23.4/tests/compile/slicex.pyx0000644000175600017570000000012612606202452021026 0ustar jenkinsjenkins00000000000000# mode: compile def f(a, b, c, d, e, f, g, h, i): a = b[c:d, e:f:g, ..., h, :i:] Cython-0.23.4/tests/compile/signedtypes.pyx0000644000175600017570000000046112606202452022077 0ustar jenkinsjenkins00000000000000# mode: compile cdef struct S: char c unsigned char uc signed char sc short s unsigned short us signed short ss int i unsigned int ui signed int si long l unsigned long ul signed long sl long long ll unsigned long long ull signed long long sll Cython-0.23.4/tests/compile/r_pernici1.pyx0000644000175600017570000000053512606202452021576 0ustar jenkinsjenkins00000000000000# mode: compile __doc__ = u""" >>> main() 3.14159265358979323846 3.14159265358979323846 3.14159265358979323846 """ cdef extern from "math.h": double M_PI #cdef unsigned long int n1 #n1 = 4293858116 cdef double pi pi = 3.14159265358979323846 def main(): #print n1 print "%.18f" % M_PI print "%.18f" % ( M_PI) print "%.18f" % pi Cython-0.23.4/tests/compile/pylong.pyx0000644000175600017570000000102612606202452021047 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern from "Python.h": ctypedef struct PyTypeObject: pass ctypedef struct PyObject: Py_ssize_t ob_refcnt PyTypeObject *ob_type cdef extern from "longintrepr.h": cdef struct _longobject: int ob_refcnt PyTypeObject *ob_type # int ob_size # not in Py3k unsigned int *ob_digit def test(temp = long(0)): cdef _longobject *l l = <_longobject *> temp #print sizeof(l.ob_size) # not in Py3k print sizeof(l.ob_digit[0]) Cython-0.23.4/tests/compile/pyclass.pyx0000644000175600017570000000007712606202452021222 0ustar jenkinsjenkins00000000000000# mode: compile class Spam: def eggs(self): pass Cython-0.23.4/tests/compile/pxd_override_T230.py0000644000175600017570000000016312606202452022552 0ustar jenkinsjenkins00000000000000# mode: compile class A: def foo(self): return "A" class B(A): def foo(self): return "B" Cython-0.23.4/tests/compile/pxd_override_T230.pxd0000644000175600017570000000011012606202452022705 0ustar jenkinsjenkins00000000000000cdef class A: cpdef foo(self) cdef class B(A): cpdef foo(self) Cython-0.23.4/tests/compile/publicapi_pxd_mix.pyx0000644000175600017570000000127312606202452023243 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Foo1: pass cdef class Foo2: pass cdef class Foo3: pass cdef class Bar1: pass cdef class Bar2: pass cdef class Bar3: pass cdef void bar0(): pass cdef public void bar1(): pass cdef api void bar2(): pass cdef public api void bar3(): pass cdef void* spam0(object o) except NULL: return NULL cdef public void* spam1(object o) except NULL: return NULL cdef api void* spam2(object o) nogil except NULL: return NULL cdef public api void* spam3(object o) except NULL with gil: return NULL cdef int i0 = 0 # XXX This should not be required! cdef public int i1 = 1 cdef api int i2 = 2 cdef public api int i3 = 3 Cython-0.23.4/tests/compile/publicapi_pxd_mix.pxd0000644000175600017570000000362712606202452023223 0ustar jenkinsjenkins00000000000000# -- ctypedef int Int0 ctypedef public int Int1 ctypedef api int Int2 ctypedef public api int Int3 ctypedef enum EnumA0: EA0 ctypedef public enum EnumA1: EA1 ctypedef api enum EnumA2: EA2 ctypedef public api enum EnumA3: EA3 cdef enum EnumB0: EB0=0 cdef public enum EnumB1: EB1=1 cdef api enum EnumB2: EB2=2 cdef public api enum EnumB3: EB3=3 # -- ctypedef struct StructA0: int SA0 ctypedef public struct StructA1: int SA1 ctypedef api struct StructA2: int SA2 ctypedef public api struct StructA3: int SA3 cdef struct StructB0: int SB0 cdef public struct StructB1: int SB1 cdef api struct StructB2: int SB2 cdef public api struct StructB3: int SB3 # -- ctypedef class Foo0: pass ctypedef public class Foo1 [type PyFoo1_Type, object PyFoo1_Object]: pass ctypedef api class Foo2 [type PyFoo2_Type, object PyFoo2_Object]: pass ctypedef public api class Foo3 [type PyFoo3_Type, object PyFoo3_Object]: pass cdef class Bar0: pass cdef public class Bar1 [type PyBar1_Type, object PyBar1_Object]: pass cdef api class Bar2 [type PyBar2_Type, object PyBar2_Object]: pass cdef public api class Bar3 [type PyBar3_Type, object PyBar3_Object]: pass # -- cdef extern from *: void foo() cdef inline void bar (): pass cdef void bar0() cdef public void bar1() cdef api void bar2() cdef public api void bar3() cdef inline void* spam (object o) except NULL: return NULL cdef void* spam0(object o) except NULL cdef public void* spam1(object o) except NULL cdef api void* spam2(object o) nogil except NULL cdef public api void* spam3(object o) except NULL with gil # -- cdef int i0 = 0 # XXX implement initialization!!! cdef public int i1 cdef api int i2 cdef public api int i3 # -- Cython-0.23.4/tests/compile/publicapi_pub.pyx0000644000175600017570000000227212606202452022361 0ustar jenkinsjenkins00000000000000# mode: compile # -- ctypedef int Int0 ctypedef public int Int1 ctypedef enum EnumA0: EA0 ctypedef public enum EnumA1: EA1 cdef enum EnumB0: EB0=0 cdef public enum EnumB1: EB1=1 cdef Int0 i0 = 0 cdef EnumA0 ea0 = EA0 cdef EnumB0 eb0 = EB0 cdef public Int1 i1 = 0 cdef public EnumA1 ea1 = EA1 cdef public EnumB1 eb1 = EB1 # -- ctypedef struct StructA0: int SA0 ctypedef public struct StructA1: int SA1 cdef struct StructB0: int SB0 cdef public struct StructB1: int SB1 cdef StructA0 sa0 = {'SA0':0} cdef StructB0 sb0 = {'SB0':2} cdef public StructA1 sa1 = {'SA1':1} cdef public StructB1 sb1 = {'SB1':3} # -- ctypedef class Foo0: pass ctypedef public class Foo1 [type PyFoo1_Type, object PyFoo1_Object]: pass cdef class Bar0: pass cdef public class Bar1 [type PyBar1_Type, object PyBar1_Object]: pass cdef Foo0 f0 = None cdef Bar0 b0 = None cdef public Foo1 f1 = None cdef public Bar1 b1 = None # -- cdef void bar0(): pass cdef public void bar1(): pass cdef void* spam0(object o) except NULL: return NULL cdef public void* spam1(object o) except NULL: return NULL bar0() bar1() spam0(None) spam1(None) # -- Cython-0.23.4/tests/compile/publicapi_mix.pyx0000644000175600017570000000375612606202452022400 0ustar jenkinsjenkins00000000000000# mode: compile # -- ctypedef int Int0 ctypedef public int Int1 ctypedef api int Int2 ctypedef public api int Int3 ctypedef enum EnumA0: EA0 ctypedef public enum EnumA1: EA1 ctypedef api enum EnumA2: EA2 ctypedef public api enum EnumA3: EA3 cdef enum EnumB0: EB0=0 cdef public enum EnumB1: EB1=1 cdef api enum EnumB2: EB2=2 cdef public api enum EnumB3: EB3=3 # -- ctypedef struct StructA0: int SA0 ctypedef public struct StructA1: int SA1 ctypedef api struct StructA2: int SA2 ctypedef public api struct StructA3: int SA3 cdef struct StructB0: int SB0 cdef public struct StructB1: int SB1 cdef api struct StructB2: int SB2 cdef public api struct StructB3: int SB3 # -- ctypedef class Foo0: pass ctypedef public class Foo1 [type PyFoo1_Type, object PyFoo1_Object]: pass ctypedef api class Foo2 [type PyFoo2_Type, object PyFoo2_Object]: pass ctypedef public api class Foo3 [type PyFoo3_Type, object PyFoo3_Object]: pass cdef class Bar0: pass cdef public class Bar1 [type PyBar1_Type, object PyBar1_Object]: pass cdef api class Bar2 [type PyBar2_Type, object PyBar2_Object]: pass cdef public api class Bar3 [type PyBar3_Type, object PyBar3_Object]: pass # -- cdef void bar0(): pass cdef public void bar1(): pass cdef api void bar2(): pass cdef public api void bar3(): pass cdef void* spam0(object o) except NULL: return NULL cdef public void* spam1(object o) except NULL: return NULL cdef api void* spam2(object o) except NULL: return NULL cdef public api void* spam3(object o) except NULL: return NULL bar0() spam0(None) # -- cdef double d0 = 0 cdef public double d1 = 1 cdef api double d2 = 2 cdef public api double d3 = 3 cdef object o0 = None cdef public object o1 = None cdef api object o2 = None cdef public api object o3 = None # -- Cython-0.23.4/tests/compile/publicapi_cimport.pyx0000644000175600017570000000023512606202452023245 0ustar jenkinsjenkins00000000000000# mode: compile from publicapi_pxd_mix cimport * bar0() bar1() bar2() bar3() spam0(None) spam1(None) spam2(None) spam3(None) i0 = 0 i1 = 1 i2 = 2 i3 = 3 Cython-0.23.4/tests/compile/publicapi_api.pyx0000644000175600017570000000215712606202452022346 0ustar jenkinsjenkins00000000000000# mode: compile # -- ctypedef int Int0 ctypedef api int Int1 ctypedef enum EnumA0: EA0 ctypedef api enum EnumA1: EA1 cdef enum EnumB0: EB0=0 cdef api enum EnumB1: EB1=1 cdef Int0 i0 = 0 cdef EnumA0 ea0 = EA0 cdef EnumB0 eb0 = EB0 cdef api Int1 i1 = 0 cdef api EnumA1 ea1 = EA1 cdef api EnumB1 eb1 = EB1 # -- ctypedef struct StructA0: int SA0 ctypedef api struct StructA1: int SA1 cdef struct StructB0: int SB0 cdef api struct StructB1: int SB1 cdef StructA0 sa0 = {'SA0':0} cdef StructB0 sb0 = {'SB0':2} cdef api StructA1 sa1 = {'SA1':1} cdef api StructB1 sb1 = {'SB1':3} # -- ctypedef class Foo0: pass ctypedef api class Foo1 [type PyFoo1_Type, object PyFoo1_Object]: pass cdef class Bar0: pass cdef api class Bar1 [type PyBar1_Type, object PyBar1_Object]: pass cdef Foo0 f0 = None cdef Bar0 b0 = None cdef api Foo1 f1 = None cdef api Bar1 b1 = None # -- cdef void bar0(): pass cdef api void bar1(): pass cdef void* spam0(object o) except NULL: return NULL cdef api void* spam1(object o) except NULL: return NULL bar0() bar1() spam0(None) spam1(None) # -- Cython-0.23.4/tests/compile/posix_pxds.pyx0000644000175600017570000000141512606202452021741 0ustar jenkinsjenkins00000000000000# tag: posix # mode: compile cimport posix cimport posix.unistd from posix cimport unistd from posix.unistd cimport * cimport posix.fcntl from posix cimport fcntl from posix.fcntl cimport * cimport posix.types from posix cimport types from posix.types cimport * cimport posix.signal from posix cimport signal from posix.signal cimport * cimport posix.stat from posix cimport stat from posix.stat cimport * cimport posix.stdlib from posix cimport stdlib from posix.stdlib cimport * cimport posix.time from posix cimport time from posix.time cimport * cimport posix.resource from posix cimport resource from posix.resource cimport * cimport posix.wait from posix cimport wait from posix.wait cimport * cimport posix.mman from posix cimport mman from posix.mman cimport * Cython-0.23.4/tests/compile/point.h0000644000175600017570000000022612606202452020300 0ustar jenkinsjenkins00000000000000#ifndef POINT_H #define POINT_H namespace geometry { struct Point { double x; double y; int color; }; } #endif Cython-0.23.4/tests/compile/pinard4.pyx0000644000175600017570000000014412606202452021100 0ustar jenkinsjenkins00000000000000# mode: compile __doc__ = u""" >>> fiches_CP [] """ fiches_CP = [1,2,3] fiches_CP[:] = [] Cython-0.23.4/tests/compile/parallel_compile_float_rank.pyx0000644000175600017570000000017212606202452025244 0ustar jenkinsjenkins00000000000000# mode: compile from cython.parallel import * cdef ssize_t i with nogil, parallel(): for i in range(10): pass Cython-0.23.4/tests/compile/operators.h0000644000175600017570000000216612606202452021172 0ustar jenkinsjenkins00000000000000#ifndef _OPERATORS_H_ #define _OPERATORS_H_ class Operators { public: int value; Operators() { } Operators(int value) { this->value = value; } virtual ~Operators() { } Operators operator+(Operators f) { return Operators(this->value + f.value); } Operators operator-(Operators f) { return Operators(this->value - f.value); } Operators operator*(Operators f) { return Operators(this->value * f.value); } Operators operator/(Operators f) { return Operators(this->value / f.value); } bool operator<(Operators f) { return this->value < f.value; } bool operator<=(Operators f) { return this->value <= f.value; } bool operator==(Operators f) { return this->value == f.value; } bool operator!=(Operators f) { return this->value != f.value; } bool operator>(Operators f) { return this->value > f.value; } bool operator>=(Operators f) { return this->value >= f.value; } Operators operator>>(int v) { return Operators(this->value >> v); } Operators operator<<(int v) { return Operators(this->value << v); } Operators operator%(int v) { return Operators(this->value % v); } }; #endif Cython-0.23.4/tests/compile/omittedargnames.pyx0000644000175600017570000000006512606202452022724 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern void spam(int, char *) Cython-0.23.4/tests/compile/nullptr.pyx0000644000175600017570000000015212606202452021236 0ustar jenkinsjenkins00000000000000# mode: compile cdef char *p1 cdef int *p2 cdef int x p1 = NULL p2 = NULL x = p1 == NULL x = NULL == p2 Cython-0.23.4/tests/compile/notnonearg.pyx0000644000175600017570000000024512606202452021713 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern class external.Spam [object Spam]: pass cdef extern class external.Eggs [object Eggs]: pass def ham(Spam s, Eggs e not None): pass Cython-0.23.4/tests/compile/none.pyx0000644000175600017570000000007312606202452020477 0ustar jenkinsjenkins00000000000000# mode: compile cdef void spam(): eggs = None spam() Cython-0.23.4/tests/compile/nonctypedefclass.pyx0000644000175600017570000000010212606202452023075 0ustar jenkinsjenkins00000000000000# mode: compile cdef class spam: pass cdef spam s s = None Cython-0.23.4/tests/compile/nogil.pyx0000644000175600017570000000060512606202452020651 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern object g(object x) nogil cdef extern void g2(object x) nogil cdef extern from "nogil.h": void e1() nogil int *e2() nogil cdef void f(int x) nogil: cdef int y y = 42 cdef void h(object x) nogil: cdef void *p=None g2(x) g2(p) p = x e1() e2() f(0) h(None) Cython-0.23.4/tests/compile/nogil.h0000644000175600017570000000065212606202452020262 0ustar jenkinsjenkins00000000000000#ifdef __cplusplus extern "C" { #endif extern DL_EXPORT(void) e1(void); extern DL_EXPORT(int*) e2(void); #ifdef __cplusplus } #endif void e1(void) {return;} int* e2(void) {return 0;} #ifdef __cplusplus extern "C" { #endif extern DL_EXPORT(PyObject *) g(PyObject*); extern DL_EXPORT(void) g2(PyObject*); #ifdef __cplusplus } #endif PyObject *g(PyObject* o) {if (o) {}; return 0;} void g2(PyObject* o) {if (o) {}; return;} Cython-0.23.4/tests/compile/msvc_strings.pyx0000644000175600017570000021454112606202452022270 0ustar jenkinsjenkins00000000000000# mode: compile """A long module docstring. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sit amet mauris mauris, sit amet venenatis nisl. Vivamus a est porta enim sollicitudin mollis. Proin fringilla massa vel ante gravida luctus. Nunc quis nunc id quam hendrerit posuere. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam porttitor interdum sollicitudin. Mauris malesuada tellus tellus. Mauris condimentum nunc et sapien pellentesque gravida. Suspendisse sed ipsum orci. Duis ut lacus dui. Integer ac gravida sem. Vivamus fermentum porttitor velit ac blandit. Maecenas pulvinar ullamcorper enim, vitae aliquet tortor scelerisque et. Vestibulum ante massa, sodales et bibendum dignissim, consectetur vitae metus. Quisque vel dui erat, vel commodo metus. Aliquam arcu dolor, viverra sit amet porttitor a, faucibus eu augue. Sed ornare, enim eget ultricies suscipit, nunc dui lacinia enim, vitae tempus nunc libero vitae ligula. Nam et commodo ligula. Pellentesque tincidunt lorem at elit aliquam at fringilla libero tempor. Donec molestie consectetur nibh, ac varius ante dictum id. Suspendisse lectus nibh, molestie vel dapibus eget, egestas ut eros. Mauris vel mauris turpis, vitae bibendum nunc. Vestibulum nulla enim, vestibulum vitae tincidunt et, gravida eu metus. Nulla sagittis, odio a placerat laoreet, arcu lectus vestibulum nunc, in hendrerit tortor quam sit amet turpis. In et purus vel dui pellentesque tincidunt. Donec dictum nibh sed quam luctus sit amet luctus justo dapibus. Integer nulla elit, lacinia aliquet euismod sed, tempus vitae lectus. Fusce non sapien dolor. Suspendisse ut est ut dui tempor ultricies id ut elit. Aenean adipiscing sollicitudin enim, nec porttitor est porttitor eget. Proin lobortis ante ut diam sodales volutpat. Donec urna diam, porttitor nec laoreet ut, rhoncus non diam. Ut sed mi vitae turpis semper semper. Integer sit amet lorem sapien. Aliquam risus diam, vulputate id sagittis et, molestie ut lectus. Aliquam erat volutpat. Morbi aliquet venenatis metus in posuere. Cras vitae purus nunc, ut vestibulum ipsum. Nullam vehicula dui in urna iaculis lobortis. Ut a est non est tincidunt iaculis. Vivamus rutrum velit non nunc malesuada sed bibendum mi iaculis. Sed id lacus in sem tempor vestibulum. Cras bibendum accumsan suscipit. Phasellus congue nisl consectetur turpis rhoncus aliquet posuere libero fringilla. Sed eros tellus, hendrerit nec imperdiet vitae, blandit ac dolor. Nulla facilisi. Morbi ullamcorper libero odio, at cursus tortor. Cras ultricies tellus eget justo cursus cursus. Donec at mi massa, auctor suscipit sem. Proin dolor purus, semper sed ultrices ut, iaculis at tortor. Donec risus enim, interdum et convallis nec, aliquam eget velit. Curabitur eget lectus dolor. Integer id turpis eu nulla euismod tincidunt. Fusce elit nibh, dapibus sit amet tempus ac, convallis eu libero. Donec dui justo, molestie sed euismod porta, ultricies id orci. Praesent a tellus et risus faucibus porttitor pellentesque in purus. Fusce blandit risus ac tortor viverra vitae molestie odio convallis. Donec rhoncus volutpat mauris, sit amet mattis libero dapibus id. Ut rhoncus venenatis nisi ac dictum. In non nulla eget massa convallis facilisis. Praesent nec odio id odio semper lobortis non eu erat. Proin quis gravida magna. Sed rhoncus lectus auctor arcu posuere a auctor dui pellentesque. Sed enim nulla, luctus quis sagittis sed, vestibulum eget metus. Mauris ornare pretium fringilla. Proin ligula eros, fermentum in placerat sit amet, placerat vel mauris. Nulla magna enim, luctus eget euismod ac, lacinia vel lorem. Duis mi leo, porttitor vitae dictum ac, ultrices iaculis metus. Quisque libero mi, aliquet quis vestibulum eget, porttitor non justo. Praesent ac metus felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec vel enim sit amet ante imperdiet commodo sed vel nisi. Praesent semper viverra nulla vehicula sollicitudin. Fusce lacinia aliquet ullamcorper. Donec vitae diam est. Integer volutpat hendrerit turpis ut bibendum. Integer et dui augue. Nunc ut nisl in felis feugiat semper nec sit amet purus. Proin convallis ultrices nisl ut vehicula. Pellentesque neque mi, elementum vel placerat nec, laoreet ac nulla. Pellentesque aliquam dui a metus iaculis posuere. Curabitur dapibus faucibus metus. Donec quis diam dui. Proin at mi nec augue cursus pulvinar eu vel metus. Curabitur eget turpis ac risus dignissim luctus sed id ligula. Etiam lectus neque, varius ut euismod nec, euismod quis nulla. Ut feugiat, quam id tempor luctus, metus eros lacinia diam, nec dapibus tellus dui quis diam. Nam interdum, orci id fringilla mattis, ipsum eros pellentesque turpis, hendrerit dignissim justo dui interdum ante. Curabitur aliquam nisi ut dui lacinia tempor. Nulla lobortis tellus non sapien dignissim ut dapibus dui aliquet. Nam scelerisque, urna a aliquam malesuada, mi tortor scelerisque libero, quis pellentesque erat eros ut justo. Phasellus nulla purus, suscipit vel gravida euismod, malesuada et odio. Vestibulum non libero eget lacus venenatis auctor quis a est. Nunc id leo est. Curabitur pulvinar viverra sapien at viverra. Cras pretium justo et lorem lobortis id tempor nisi accumsan. Cras egestas tortor in risus hendrerit eu varius purus suscipit. Nullam mauris eros, mattis at tempor vitae, mollis vitae velit. Etiam at adipiscing lectus. Quisque molestie, metus id posuere pharetra, lorem enim vehicula mauris, ut ultricies purus justo a lacus. Vivamus blandit euismod adipiscing. Nam eu ligula at elit ultricies tempus. Nunc ac sodales neque. Ut dui diam, porttitor a pulvinar vel, sodales sit amet turpis. Donec vitae eros at neque luctus scelerisque. In consequat elementum iaculis. Donec ullamcorper dolor eu quam volutpat rhoncus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras laoreet ante eget dolor sagittis imperdiet. Proin magna urna, porta id blandit nec, commodo eget lorem. Etiam imperdiet, orci sit amet rutrum consectetur, orci augue tempus lacus, id venenatis sapien nisl a est. Sed accumsan massa sed libero consectetur scelerisque. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed nunc risus, lobortis id egestas nec, suscipit id magna. Morbi at iaculis mauris. Proin felis sem, tempus non pellentesque congue, vehicula sit amet eros. Maecenas porttitor erat ac dolor pharetra iaculis. Cras tincidunt, nulla eget malesuada egestas, sem diam consequat quam, sed feugiat nulla orci at mauris. Quisque non arcu diam, ac lacinia felis. Nunc iaculis mollis egestas. Etiam imperdiet dolor consectetur eros feugiat fringilla sed in lacus. Nunc nec tincidunt dolor. Etiam sagittis tortor condimentum nunc fermentum vestibulum. Vivamus lobortis, magna sit amet scelerisque lobortis, sem eros molestie leo, eget aliquet ligula est in lectus. Duis placerat porta pulvinar. Sed sed adipiscing ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam accumsan iaculis augue, sed varius dui sagittis id. Etiam sit amet eleifend augue. Ut sit amet nibh sit amet justo tempor condimentum. Ut faucibus sagittis volutpat. Duis vestibulum feugiat sollicitudin. Aenean cursus luctus urna at consectetur. Nullam tincidunt, eros a iaculis sodales, tellus est imperdiet arcu, sit amet tincidunt orci felis et tortor. Mauris rutrum venenatis nunc ut rutrum. Phasellus nec erat magna, in tincidunt orci. Sed sit amet suscipit tellus. Mauris ut nisi turpis. Suspendisse augue turpis, condimentum ac bibendum in, vestibulum nec eros. Curabitur dapibus pulvinar vehicula. Fusce consequat, erat in malesuada hendrerit, tellus urna pharetra lacus, sed euismod nisi urna sed nisi. Etiam fermentum accumsan nunc, sed bibendum dui iaculis id. Etiam blandit fermentum ligula nec viverra. Vivamus venenatis arcu in nulla euismod euismod. Donec sit amet augue nec metus varius fringilla. Vivamus pulvinar elit ac mi rhoncus in luctus diam egestas. Curabitur a felis eget arcu pretium tempus eu sed mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris malesuada, nibh ac venenatis hendrerit, ligula dui condimentum tellus, sit amet pretium diam tortor vel risus. Suspendisse suscipit consequat eros id dignissim. Cras interdum lorem ac massa euismod non porta enim pretium. Aliquam ultrices nibh vitae ligula consectetur vel sollicitudin lacus volutpat. Phasellus vulputate iaculis sem nec laoreet. Nam leo sem, tempor eu condimentum id, imperdiet sed dolor. Donec pharetra velit non libero euismod tempor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed fermentum, libero a posuere posuere, enim elit imperdiet enim, a sollicitudin est felis non libero. Sed vel dolor ut arcu dapibus iaculis nec a mauris. Morbi ullamcorper ultrices venenatis. Fusce luctus ante sit amet lacus venenatis ut rutrum elit lobortis. Nulla fermentum tortor ac sapien fringilla quis iaculis quam egestas. Aliquam et tortor est, at elementum mauris. Morbi posuere erat nec leo vulputate in pellentesque tortor condimentum. Vestibulum at orci augue. Aenean pellentesque sapien id felis consequat varius. Suspendisse bibendum enim sit amet mi imperdiet vel suscipit nisi tristique. Curabitur velit massa, consectetur ac mattis vel, accumsan at nunc. Donec porta, nibh nec consequat convallis, urna neque auctor erat, eu convallis lorem leo convallis turpis. Morbi non mauris non metus ornare vulputate. Sed aliquet, dolor ut egestas fermentum, metus purus mollis elit, nec commodo odio quam quis nisl. Aliquam erat volutpat. Suspendisse sed faucibus urna. Integer suscipit rutrum condimentum. Praesent dignissim libero eget metus luctus consectetur. Vestibulum ac erat felis, vitae iaculis erat. Duis interdum lacinia arcu, non lacinia urna luctus in. Curabitur feugiat sapien sapien, in vestibulum diam. Phasellus lobortis massa ut metus pretium dignissim. Fusce quis sem odio. Integer pellentesque sodales augue id tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum lorem odio, semper vel scelerisque sit amet, sagittis ac libero. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam egestas ultricies dui at gravida. Duis tristique, eros id consectetur pellentesque, nulla arcu ultricies tortor, ut pulvinar sapien lacus in elit. Vivamus dolor massa, pulvinar at mollis vitae, euismod ut dolor. Vivamus a magna ante. Vestibulum vitae fringilla leo. Ut gravida magna in quam fringilla ultricies. Mauris rhoncus enim id sem interdum blandit. Pellentesque luctus leo sit amet felis viverra ac accumsan purus mollis. Aenean pretium fringilla quam nec laoreet. Nulla id mauris mauris. Nam varius bibendum tristique. Integer ante felis, volutpat sed dignissim vel, interdum molestie nisi. Etiam mollis accumsan elit, ut gravida eros molestie nec. Nullam quis velit ac purus imperdiet sodales. Donec semper placerat venenatis. Cras dolor risus, sodales sed scelerisque nec, sollicitudin pretium felis. Quisque pretium felis id turpis bibendum pulvinar ornare id nibh. Morbi lobortis leo non mi porttitor vulputate. Vestibulum nec odio tellus, ut blandit ligula. In pellentesque neque sit amet dui pulvinar sed laoreet dui vehicula. In hac habitasse platea dictumst. Etiam feugiat dictum blandit. Praesent lacinia tincidunt elit, quis consectetur tortor molestie commodo. Ut sit amet accumsan lorem. Cras quam nunc, malesuada tempor volutpat vitae, aliquam eu diam. Sed sem nibh, bibendum nec sollicitudin at, interdum et magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam vitae sem non elit pharetra vestibulum et condimentum libero. Nam egestas ultricies hendrerit. Nunc nec fringilla nulla. Aliquam risus tellus, hendrerit non dapibus a, tincidunt vel ante. Vivamus mollis, magna et lacinia tincidunt, dui massa porta odio, ac ornare felis massa nec lorem. Mauris sagittis lacus sed metus mollis ac egestas lectus porttitor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer vitae lacinia libero. Phasellus at neque enim, sit amet dictum mi. Ut risus nisi, vestibulum vel congue eget, egestas in ipsum. Duis faucibus tempus sodales. Duis convallis pellentesque arcu rhoncus congue. Nunc ac mauris eu purus vestibulum congue. Praesent convallis semper augue vel volutpat. Integer dictum varius placerat. Vestibulum convallis tortor non mi lacinia ac aliquet dui ultricies. Donec ultrices purus eros. Maecenas venenatis posuere massa, nec consectetur lacus cursus eget. Donec quam lacus, tempus id placerat et, posuere sed libero. Proin auctor diam ut arcu viverra ut imperdiet tellus dapibus. Morbi ac mauris quis tellus porttitor eleifend. Sed et ante magna, ut sodales sapien. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer mattis venenatis mi non ullamcorper. Vestibulum magna enim, aliquam non interdum ut, dignissim vitae ante. Praesent dignissim, est at pretium posuere, nisl ante varius felis, vitae posuere enim nulla et nunc. Morbi sagittis suscipit leo, eu accumsan ligula volutpat non. Donec ut tincidunt magna. Integer ac libero mi. Sed non eros dolor, in tincidunt enim. Curabitur iaculis erat quis felis iaculis ut volutpat augue malesuada. Pellentesque eget arcu ligula, ut volutpat purus. Suspendisse dictum lorem quis sapien lacinia pretium. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin sagittis egestas massa et tempor. Mauris et eros ante, id porta sem. Duis ac eros vitae ipsum ultrices malesuada eget a risus. Morbi imperdiet, est a hendrerit tristique, mi erat molestie lacus, ac tempor risus nulla id erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam congue, lacus quis ultricies consequat, diam metus convallis enim, ut volutpat enim urna vitae erat. In quam risus, molestie et dapibus id, elementum sit amet ligula. Nam faucibus lacus id dolor facilisis viverra. Nullam vehicula massa ac arcu consectetur vulputate. Praesent nec augue ac justo dapibus vehicula. Aliquam consectetur hendrerit dolor, et mollis nisl auctor ut. Ut sagittis risus at felis fringilla ultricies. Vestibulum non urna nibh, nec pretium dolor. Nulla imperdiet lobortis eros at pharetra. Vivamus cursus pellentesque ornare. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce arcu quam, pulvinar at rutrum vitae, ornare vitae leo. Maecenas vehicula magna sit amet nulla bibendum condimentum. Curabitur ultrices tempor fringilla. Vivamus pretium suscipit molestie. Donec arcu diam, ultricies ac pellentesque eu, venenatis et sapien. Nam dictum orci augue, vel eleifend leo. Nam at lacus sapien, nec pretium eros. In egestas, enim sed sagittis feugiat, purus odio tristique lectus, vel condimentum leo turpis ac odio. Nam iaculis mi quis odio posuere et venenatis velit ultricies. Nulla facilisi. Proin nec dolor ac quam euismod gravida quis et eros. Nam interdum condimentum mattis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent a nisi eu massa mollis posuere sed a nunc. Aenean tempus enim a justo rhoncus quis ultrices nisl commodo. Aenean imperdiet mauris a ipsum venenatis vel scelerisque lorem rutrum. Donec ut nunc eros, eget accumsan felis. Nullam ullamcorper porta dictum. Donec accumsan cursus vestibulum. Aenean in sapien velit. Vivamus nec massa mi. Fusce felis tortor, bibendum non volutpat a, fringilla quis nisi. Duis varius bibendum erat, quis fermentum sem accumsan eget. Maecenas massa felis, porta sed laoreet eu, luctus eu lectus. Cras id nibh vitae erat fringilla rutrum. Maecenas eget consequat est. Vivamus viverra, felis vel faucibus rhoncus, quam ipsum elementum libero, quis convallis urna purus ut mauris. Nam quis urna vitae enim consequat placerat. Vivamus congue augue sit amet lectus luctus tempor. Cras ut justo convallis est egestas pellentesque ac nec orci. Vivamus rutrum bibendum ante, at cursus erat pulvinar ornare. Proin imperdiet scelerisque ante eu vestibulum. Nullam ullamcorper metus nec purus auctor lobortis. Proin sed lacus et ipsum tempor tempus. Vivamus odio dolor, vulputate vitae semper sit amet, aliquet egestas orci. Nullam non quam eu quam sagittis porta. Nunc in velit id erat commodo viverra. Praesent nec est augue, nec sagittis erat. Cras sed turpis quis enim tempor sagittis. Donec in justo ac nisl porta condimentum id vestibulum nulla. Nam elementum ultricies nunc a bibendum. Aenean tincidunt nisl non augue pellentesque sit amet convallis neque semper. Cras placerat suscipit massa sed volutpat. Integer vulputate imperdiet enim, vitae vulputate sapien mattis feugiat. Vivamus pharetra facilisis mauris a gravida. Nulla non venenatis est. Duis lobortis consectetur sem ac aliquam. In eget sapien odio. Vivamus pulvinar ultricies magna, quis laoreet dui porta et. Integer tempus malesuada velit, et consequat odio ultrices sed. Aliquam malesuada commodo diam vel posuere. Morbi porttitor, elit vitae auctor gravida, lorem massa bibendum arcu, vel placerat nulla justo at augue. Aliquam libero quam, mattis blandit congue sit amet, fermentum ac augue. Aliquam malesuada molestie vulputate. Duis id porta augue. Vestibulum diam dolor, ultrices sit amet porttitor id, convallis id lectus. Etiam ac augue tincidunt nisi tempor molestie euismod id nisl. Nam et tortor ac arcu viverra pulvinar. Fusce pulvinar rhoncus leo, a faucibus enim interdum non. Aliquam vulputate mattis consectetur. Pellentesque sit amet quam sem. Cras eget arcu eu elit volutpat volutpat. Integer sed varius enim. Integer sit amet felis orci, id dignissim sapien. Sed vitae lorem sed libero facilisis fringilla. Pellentesque congue tristique purus, eleifend semper risus suscipit quis. Phasellus rutrum quam vitae arcu vulputate porta. Sed tristique arcu nec mi porttitor lacinia. Donec congue feugiat diam quis pretium. Vivamus at luctus nunc. Integer vulputate laoreet mauris quis auctor. Nunc at ultrices libero. Maecenas porta faucibus purus non vehicula. Sed sit amet metus vitae mi ultrices scelerisque nec quis risus. Phasellus pellentesque tincidunt massa id ultricies. Aliquam dictum arcu ac dolor interdum rutrum. Nulla facilisi. Duis nisi est, tincidunt a sagittis id, sollicitudin at odio. Curabitur sed est eu sapien faucibus dignissim in quis tortor. Nunc ac elit tortor, non lobortis massa. Proin posuere ante ut metus vehicula suscipit. Proin mattis mauris ac lectus consequat rutrum. Nam arcu lectus, commodo non pretium a, pharetra semper dolor. Fusce eleifend hendrerit adipiscing. Nunc et eleifend erat. Suspendisse tempus nisl ut arcu blandit ut adipiscing nisi tristique. Suspendisse molestie facilisis risus sed fermentum. Praesent tempor convallis ultricies. Integer et elit velit, at consectetur risus. Vestibulum mollis adipiscing sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris dictum molestie porta. Nam convallis nisl quis lacus vulputate in convallis risus sagittis. Vivamus accumsan faucibus cursus. Ut ultricies imperdiet ligula scelerisque blandit. In ornare egestas purus, at convallis velit egestas laoreet. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla quis imperdiet est. Nunc tempus magna quis lacus feugiat et posuere lacus vehicula. Cras lacinia aliquam est at vehicula. Aenean congue elit in ante dignissim vitae fermentum lectus aliquam. Mauris at odio magna, at interdum dui. Cras fringilla mi velit, nec varius neque. Fusce et volutpat lacus. Suspendisse id turpis et urna varius convallis in eu purus. Nulla facilisi. Etiam mauris nisl, ultrices ac porttitor sit amet, facilisis ut neque. Nullam ut velit quis velit tincidunt rhoncus. Praesent tristique porttitor euismod. Nulla non felis ante, feugiat commodo turpis. In nec venenatis mi. Duis tempus tempor purus, vitae consectetur mi ornare eu. Proin sed consequat erat. Quisque nec sem dui. Nam semper, ligula facilisis pretium interdum, diam lectus sollicitudin lorem, in elementum nisi lorem scelerisque justo. Nullam ac fringilla nunc. Maecenas malesuada ligula in massa sollicitudin sit amet auctor ipsum malesuada. Vestibulum ut augue in magna lobortis varius eget in ipsum. In hac habitasse platea dictumst. Cras vel sagittis mi. Aenean urna sapien, ultrices et tristique et, aliquam vel libero. Nullam in consequat ante. Suspendisse libero augue, pulvinar a dignissim vitae, fringilla malesuada dui. Phasellus augue ante, pulvinar eget tincidunt vel, venenatis sed arcu. Pellentesque ac purus orci, vel molestie turpis. Nulla consectetur sollicitudin dolor, sed ornare arcu accumsan fermentum. Fusce vestibulum nisi at leo interdum eu sollicitudin lacus dictum. Fusce malesuada consequat ipsum ut convallis. Maecenas in eros sit amet elit consectetur fringilla nec a nibh. Ut et velit vel ligula pharetra elementum. Nullam aliquam, tellus vel cursus lacinia, dui libero dictum turpis, nec lacinia dolor nunc vel diam. Pellentesque convallis dui quis lacus ornare at rutrum lorem pellentesque. Suspendisse potenti. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc ac nibh sed mauris ornare cursus. Praesent enim mauris, tincidunt vitae convallis ac, ultricies imperdiet sapien. Duis sodales ligula eget lorem suscipit sed consectetur metus pretium. Nam in magna augue, quis volutpat mauris. Quisque pretium lobortis orci quis laoreet. Nam ut nisi diam. Sed ultrices ultrices dapibus. Integer feugiat mauris id orci pulvinar eu tempus nibh viverra. Etiam venenatis bibendum massa a consequat. Fusce interdum velit ac mauris rhoncus non cursus neque consectetur. Vestibulum dictum eros ac metus fringilla venenatis. Phasellus auctor dui non nulla molestie id malesuada mauris euismod. Aenean id tortor ac justo eleifend mollis non vel arcu. Duis ac lorem tortor. Donec volutpat purus sed nunc luctus interdum hendrerit nulla ullamcorper. Sed consectetur interdum aliquet. Proin ullamcorper risus ut ante lacinia sagittis. Nunc varius eleifend purus, ac pellentesque urna viverra id. Praesent euismod, sapien accumsan gravida dictum, massa massa euismod sapien, ut auctor tellus arcu sed diam. Vivamus tincidunt dolor non lorem pellentesque at tempus elit adipiscing. Vestibulum tempor aliquam consectetur. Mauris nec dictum nisl. Donec scelerisque ornare condimentum. Phasellus laoreet justo nec nibh convallis convallis. Duis id orci sapien, eget pulvinar justo. Aenean id arcu felis, eu iaculis nibh. Aenean eleifend pretium rutrum. Aliquam molestie sem quis tellus aliquam eleifend. Mauris et purus orci. Nunc et accumsan tortor. Phasellus semper eleifend nisi, a faucibus risus vehicula id. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas in felis et est lacinia eleifend vel sed ipsum. Aliquam commodo molestie lorem id hendrerit. Nam sed tellus urna, sed dignissim eros. """ A_LONG_STRING = """A long string. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sit amet mauris mauris, sit amet venenatis nisl. Vivamus a est porta enim sollicitudin mollis. Proin fringilla massa vel ante gravida luctus. Nunc quis nunc id quam hendrerit posuere. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam porttitor interdum sollicitudin. Mauris malesuada tellus tellus. Mauris condimentum nunc et sapien pellentesque gravida. Suspendisse sed ipsum orci. Duis ut lacus dui. Integer ac gravida sem. Vivamus fermentum porttitor velit ac blandit. Maecenas pulvinar ullamcorper enim, vitae aliquet tortor scelerisque et. Vestibulum ante massa, sodales et bibendum dignissim, consectetur vitae metus. Quisque vel dui erat, vel commodo metus. Aliquam arcu dolor, viverra sit amet porttitor a, faucibus eu augue. Sed ornare, enim eget ultricies suscipit, nunc dui lacinia enim, vitae tempus nunc libero vitae ligula. Nam et commodo ligula. Pellentesque tincidunt lorem at elit aliquam at fringilla libero tempor. Donec molestie consectetur nibh, ac varius ante dictum id. Suspendisse lectus nibh, molestie vel dapibus eget, egestas ut eros. Mauris vel mauris turpis, vitae bibendum nunc. Vestibulum nulla enim, vestibulum vitae tincidunt et, gravida eu metus. Nulla sagittis, odio a placerat laoreet, arcu lectus vestibulum nunc, in hendrerit tortor quam sit amet turpis. In et purus vel dui pellentesque tincidunt. Donec dictum nibh sed quam luctus sit amet luctus justo dapibus. Integer nulla elit, lacinia aliquet euismod sed, tempus vitae lectus. Fusce non sapien dolor. Suspendisse ut est ut dui tempor ultricies id ut elit. Aenean adipiscing sollicitudin enim, nec porttitor est porttitor eget. Proin lobortis ante ut diam sodales volutpat. Donec urna diam, porttitor nec laoreet ut, rhoncus non diam. Ut sed mi vitae turpis semper semper. Integer sit amet lorem sapien. Aliquam risus diam, vulputate id sagittis et, molestie ut lectus. Aliquam erat volutpat. Morbi aliquet venenatis metus in posuere. Cras vitae purus nunc, ut vestibulum ipsum. Nullam vehicula dui in urna iaculis lobortis. Ut a est non est tincidunt iaculis. Vivamus rutrum velit non nunc malesuada sed bibendum mi iaculis. Sed id lacus in sem tempor vestibulum. Cras bibendum accumsan suscipit. Phasellus congue nisl consectetur turpis rhoncus aliquet posuere libero fringilla. Sed eros tellus, hendrerit nec imperdiet vitae, blandit ac dolor. Nulla facilisi. Morbi ullamcorper libero odio, at cursus tortor. Cras ultricies tellus eget justo cursus cursus. Donec at mi massa, auctor suscipit sem. Proin dolor purus, semper sed ultrices ut, iaculis at tortor. Donec risus enim, interdum et convallis nec, aliquam eget velit. Curabitur eget lectus dolor. Integer id turpis eu nulla euismod tincidunt. Fusce elit nibh, dapibus sit amet tempus ac, convallis eu libero. Donec dui justo, molestie sed euismod porta, ultricies id orci. Praesent a tellus et risus faucibus porttitor pellentesque in purus. Fusce blandit risus ac tortor viverra vitae molestie odio convallis. Donec rhoncus volutpat mauris, sit amet mattis libero dapibus id. Ut rhoncus venenatis nisi ac dictum. In non nulla eget massa convallis facilisis. Praesent nec odio id odio semper lobortis non eu erat. Proin quis gravida magna. Sed rhoncus lectus auctor arcu posuere a auctor dui pellentesque. Sed enim nulla, luctus quis sagittis sed, vestibulum eget metus. Mauris ornare pretium fringilla. Proin ligula eros, fermentum in placerat sit amet, placerat vel mauris. Nulla magna enim, luctus eget euismod ac, lacinia vel lorem. Duis mi leo, porttitor vitae dictum ac, ultrices iaculis metus. Quisque libero mi, aliquet quis vestibulum eget, porttitor non justo. Praesent ac metus felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec vel enim sit amet ante imperdiet commodo sed vel nisi. Praesent semper viverra nulla vehicula sollicitudin. Fusce lacinia aliquet ullamcorper. Donec vitae diam est. Integer volutpat hendrerit turpis ut bibendum. Integer et dui augue. Nunc ut nisl in felis feugiat semper nec sit amet purus. Proin convallis ultrices nisl ut vehicula. Pellentesque neque mi, elementum vel placerat nec, laoreet ac nulla. Pellentesque aliquam dui a metus iaculis posuere. Curabitur dapibus faucibus metus. Donec quis diam dui. Proin at mi nec augue cursus pulvinar eu vel metus. Curabitur eget turpis ac risus dignissim luctus sed id ligula. Etiam lectus neque, varius ut euismod nec, euismod quis nulla. Ut feugiat, quam id tempor luctus, metus eros lacinia diam, nec dapibus tellus dui quis diam. Nam interdum, orci id fringilla mattis, ipsum eros pellentesque turpis, hendrerit dignissim justo dui interdum ante. Curabitur aliquam nisi ut dui lacinia tempor. Nulla lobortis tellus non sapien dignissim ut dapibus dui aliquet. Nam scelerisque, urna a aliquam malesuada, mi tortor scelerisque libero, quis pellentesque erat eros ut justo. Phasellus nulla purus, suscipit vel gravida euismod, malesuada et odio. Vestibulum non libero eget lacus venenatis auctor quis a est. Nunc id leo est. Curabitur pulvinar viverra sapien at viverra. Cras pretium justo et lorem lobortis id tempor nisi accumsan. Cras egestas tortor in risus hendrerit eu varius purus suscipit. Nullam mauris eros, mattis at tempor vitae, mollis vitae velit. Etiam at adipiscing lectus. Quisque molestie, metus id posuere pharetra, lorem enim vehicula mauris, ut ultricies purus justo a lacus. Vivamus blandit euismod adipiscing. Nam eu ligula at elit ultricies tempus. Nunc ac sodales neque. Ut dui diam, porttitor a pulvinar vel, sodales sit amet turpis. Donec vitae eros at neque luctus scelerisque. In consequat elementum iaculis. Donec ullamcorper dolor eu quam volutpat rhoncus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras laoreet ante eget dolor sagittis imperdiet. Proin magna urna, porta id blandit nec, commodo eget lorem. Etiam imperdiet, orci sit amet rutrum consectetur, orci augue tempus lacus, id venenatis sapien nisl a est. Sed accumsan massa sed libero consectetur scelerisque. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed nunc risus, lobortis id egestas nec, suscipit id magna. Morbi at iaculis mauris. Proin felis sem, tempus non pellentesque congue, vehicula sit amet eros. Maecenas porttitor erat ac dolor pharetra iaculis. Cras tincidunt, nulla eget malesuada egestas, sem diam consequat quam, sed feugiat nulla orci at mauris. Quisque non arcu diam, ac lacinia felis. Nunc iaculis mollis egestas. Etiam imperdiet dolor consectetur eros feugiat fringilla sed in lacus. Nunc nec tincidunt dolor. Etiam sagittis tortor condimentum nunc fermentum vestibulum. Vivamus lobortis, magna sit amet scelerisque lobortis, sem eros molestie leo, eget aliquet ligula est in lectus. Duis placerat porta pulvinar. Sed sed adipiscing ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam accumsan iaculis augue, sed varius dui sagittis id. Etiam sit amet eleifend augue. Ut sit amet nibh sit amet justo tempor condimentum. Ut faucibus sagittis volutpat. Duis vestibulum feugiat sollicitudin. Aenean cursus luctus urna at consectetur. Nullam tincidunt, eros a iaculis sodales, tellus est imperdiet arcu, sit amet tincidunt orci felis et tortor. Mauris rutrum venenatis nunc ut rutrum. Phasellus nec erat magna, in tincidunt orci. Sed sit amet suscipit tellus. Mauris ut nisi turpis. Suspendisse augue turpis, condimentum ac bibendum in, vestibulum nec eros. Curabitur dapibus pulvinar vehicula. Fusce consequat, erat in malesuada hendrerit, tellus urna pharetra lacus, sed euismod nisi urna sed nisi. Etiam fermentum accumsan nunc, sed bibendum dui iaculis id. Etiam blandit fermentum ligula nec viverra. Vivamus venenatis arcu in nulla euismod euismod. Donec sit amet augue nec metus varius fringilla. Vivamus pulvinar elit ac mi rhoncus in luctus diam egestas. Curabitur a felis eget arcu pretium tempus eu sed mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris malesuada, nibh ac venenatis hendrerit, ligula dui condimentum tellus, sit amet pretium diam tortor vel risus. Suspendisse suscipit consequat eros id dignissim. Cras interdum lorem ac massa euismod non porta enim pretium. Aliquam ultrices nibh vitae ligula consectetur vel sollicitudin lacus volutpat. Phasellus vulputate iaculis sem nec laoreet. Nam leo sem, tempor eu condimentum id, imperdiet sed dolor. Donec pharetra velit non libero euismod tempor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed fermentum, libero a posuere posuere, enim elit imperdiet enim, a sollicitudin est felis non libero. Sed vel dolor ut arcu dapibus iaculis nec a mauris. Morbi ullamcorper ultrices venenatis. Fusce luctus ante sit amet lacus venenatis ut rutrum elit lobortis. Nulla fermentum tortor ac sapien fringilla quis iaculis quam egestas. Aliquam et tortor est, at elementum mauris. Morbi posuere erat nec leo vulputate in pellentesque tortor condimentum. Vestibulum at orci augue. Aenean pellentesque sapien id felis consequat varius. Suspendisse bibendum enim sit amet mi imperdiet vel suscipit nisi tristique. Curabitur velit massa, consectetur ac mattis vel, accumsan at nunc. Donec porta, nibh nec consequat convallis, urna neque auctor erat, eu convallis lorem leo convallis turpis. Morbi non mauris non metus ornare vulputate. Sed aliquet, dolor ut egestas fermentum, metus purus mollis elit, nec commodo odio quam quis nisl. Aliquam erat volutpat. Suspendisse sed faucibus urna. Integer suscipit rutrum condimentum. Praesent dignissim libero eget metus luctus consectetur. Vestibulum ac erat felis, vitae iaculis erat. Duis interdum lacinia arcu, non lacinia urna luctus in. Curabitur feugiat sapien sapien, in vestibulum diam. Phasellus lobortis massa ut metus pretium dignissim. Fusce quis sem odio. Integer pellentesque sodales augue id tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum lorem odio, semper vel scelerisque sit amet, sagittis ac libero. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam egestas ultricies dui at gravida. Duis tristique, eros id consectetur pellentesque, nulla arcu ultricies tortor, ut pulvinar sapien lacus in elit. Vivamus dolor massa, pulvinar at mollis vitae, euismod ut dolor. Vivamus a magna ante. Vestibulum vitae fringilla leo. Ut gravida magna in quam fringilla ultricies. Mauris rhoncus enim id sem interdum blandit. Pellentesque luctus leo sit amet felis viverra ac accumsan purus mollis. Aenean pretium fringilla quam nec laoreet. Nulla id mauris mauris. Nam varius bibendum tristique. Integer ante felis, volutpat sed dignissim vel, interdum molestie nisi. Etiam mollis accumsan elit, ut gravida eros molestie nec. Nullam quis velit ac purus imperdiet sodales. Donec semper placerat venenatis. Cras dolor risus, sodales sed scelerisque nec, sollicitudin pretium felis. Quisque pretium felis id turpis bibendum pulvinar ornare id nibh. Morbi lobortis leo non mi porttitor vulputate. Vestibulum nec odio tellus, ut blandit ligula. In pellentesque neque sit amet dui pulvinar sed laoreet dui vehicula. In hac habitasse platea dictumst. Etiam feugiat dictum blandit. Praesent lacinia tincidunt elit, quis consectetur tortor molestie commodo. Ut sit amet accumsan lorem. Cras quam nunc, malesuada tempor volutpat vitae, aliquam eu diam. Sed sem nibh, bibendum nec sollicitudin at, interdum et magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam vitae sem non elit pharetra vestibulum et condimentum libero. Nam egestas ultricies hendrerit. Nunc nec fringilla nulla. Aliquam risus tellus, hendrerit non dapibus a, tincidunt vel ante. Vivamus mollis, magna et lacinia tincidunt, dui massa porta odio, ac ornare felis massa nec lorem. Mauris sagittis lacus sed metus mollis ac egestas lectus porttitor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer vitae lacinia libero. Phasellus at neque enim, sit amet dictum mi. Ut risus nisi, vestibulum vel congue eget, egestas in ipsum. Duis faucibus tempus sodales. Duis convallis pellentesque arcu rhoncus congue. Nunc ac mauris eu purus vestibulum congue. Praesent convallis semper augue vel volutpat. Integer dictum varius placerat. Vestibulum convallis tortor non mi lacinia ac aliquet dui ultricies. Donec ultrices purus eros. Maecenas venenatis posuere massa, nec consectetur lacus cursus eget. Donec quam lacus, tempus id placerat et, posuere sed libero. Proin auctor diam ut arcu viverra ut imperdiet tellus dapibus. Morbi ac mauris quis tellus porttitor eleifend. Sed et ante magna, ut sodales sapien. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer mattis venenatis mi non ullamcorper. Vestibulum magna enim, aliquam non interdum ut, dignissim vitae ante. Praesent dignissim, est at pretium posuere, nisl ante varius felis, vitae posuere enim nulla et nunc. Morbi sagittis suscipit leo, eu accumsan ligula volutpat non. Donec ut tincidunt magna. Integer ac libero mi. Sed non eros dolor, in tincidunt enim. Curabitur iaculis erat quis felis iaculis ut volutpat augue malesuada. Pellentesque eget arcu ligula, ut volutpat purus. Suspendisse dictum lorem quis sapien lacinia pretium. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin sagittis egestas massa et tempor. Mauris et eros ante, id porta sem. Duis ac eros vitae ipsum ultrices malesuada eget a risus. Morbi imperdiet, est a hendrerit tristique, mi erat molestie lacus, ac tempor risus nulla id erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam congue, lacus quis ultricies consequat, diam metus convallis enim, ut volutpat enim urna vitae erat. In quam risus, molestie et dapibus id, elementum sit amet ligula. Nam faucibus lacus id dolor facilisis viverra. Nullam vehicula massa ac arcu consectetur vulputate. Praesent nec augue ac justo dapibus vehicula. Aliquam consectetur hendrerit dolor, et mollis nisl auctor ut. Ut sagittis risus at felis fringilla ultricies. Vestibulum non urna nibh, nec pretium dolor. Nulla imperdiet lobortis eros at pharetra. Vivamus cursus pellentesque ornare. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce arcu quam, pulvinar at rutrum vitae, ornare vitae leo. Maecenas vehicula magna sit amet nulla bibendum condimentum. Curabitur ultrices tempor fringilla. Vivamus pretium suscipit molestie. Donec arcu diam, ultricies ac pellentesque eu, venenatis et sapien. Nam dictum orci augue, vel eleifend leo. Nam at lacus sapien, nec pretium eros. In egestas, enim sed sagittis feugiat, purus odio tristique lectus, vel condimentum leo turpis ac odio. Nam iaculis mi quis odio posuere et venenatis velit ultricies. Nulla facilisi. Proin nec dolor ac quam euismod gravida quis et eros. Nam interdum condimentum mattis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent a nisi eu massa mollis posuere sed a nunc. Aenean tempus enim a justo rhoncus quis ultrices nisl commodo. Aenean imperdiet mauris a ipsum venenatis vel scelerisque lorem rutrum. Donec ut nunc eros, eget accumsan felis. Nullam ullamcorper porta dictum. Donec accumsan cursus vestibulum. Aenean in sapien velit. Vivamus nec massa mi. Fusce felis tortor, bibendum non volutpat a, fringilla quis nisi. Duis varius bibendum erat, quis fermentum sem accumsan eget. Maecenas massa felis, porta sed laoreet eu, luctus eu lectus. Cras id nibh vitae erat fringilla rutrum. Maecenas eget consequat est. Vivamus viverra, felis vel faucibus rhoncus, quam ipsum elementum libero, quis convallis urna purus ut mauris. Nam quis urna vitae enim consequat placerat. Vivamus congue augue sit amet lectus luctus tempor. Cras ut justo convallis est egestas pellentesque ac nec orci. Vivamus rutrum bibendum ante, at cursus erat pulvinar ornare. Proin imperdiet scelerisque ante eu vestibulum. Nullam ullamcorper metus nec purus auctor lobortis. Proin sed lacus et ipsum tempor tempus. Vivamus odio dolor, vulputate vitae semper sit amet, aliquet egestas orci. Nullam non quam eu quam sagittis porta. Nunc in velit id erat commodo viverra. Praesent nec est augue, nec sagittis erat. Cras sed turpis quis enim tempor sagittis. Donec in justo ac nisl porta condimentum id vestibulum nulla. Nam elementum ultricies nunc a bibendum. Aenean tincidunt nisl non augue pellentesque sit amet convallis neque semper. Cras placerat suscipit massa sed volutpat. Integer vulputate imperdiet enim, vitae vulputate sapien mattis feugiat. Vivamus pharetra facilisis mauris a gravida. Nulla non venenatis est. Duis lobortis consectetur sem ac aliquam. In eget sapien odio. Vivamus pulvinar ultricies magna, quis laoreet dui porta et. Integer tempus malesuada velit, et consequat odio ultrices sed. Aliquam malesuada commodo diam vel posuere. Morbi porttitor, elit vitae auctor gravida, lorem massa bibendum arcu, vel placerat nulla justo at augue. Aliquam libero quam, mattis blandit congue sit amet, fermentum ac augue. Aliquam malesuada molestie vulputate. Duis id porta augue. Vestibulum diam dolor, ultrices sit amet porttitor id, convallis id lectus. Etiam ac augue tincidunt nisi tempor molestie euismod id nisl. Nam et tortor ac arcu viverra pulvinar. Fusce pulvinar rhoncus leo, a faucibus enim interdum non. Aliquam vulputate mattis consectetur. Pellentesque sit amet quam sem. Cras eget arcu eu elit volutpat volutpat. Integer sed varius enim. Integer sit amet felis orci, id dignissim sapien. Sed vitae lorem sed libero facilisis fringilla. Pellentesque congue tristique purus, eleifend semper risus suscipit quis. Phasellus rutrum quam vitae arcu vulputate porta. Sed tristique arcu nec mi porttitor lacinia. Donec congue feugiat diam quis pretium. Vivamus at luctus nunc. Integer vulputate laoreet mauris quis auctor. Nunc at ultrices libero. Maecenas porta faucibus purus non vehicula. Sed sit amet metus vitae mi ultrices scelerisque nec quis risus. Phasellus pellentesque tincidunt massa id ultricies. Aliquam dictum arcu ac dolor interdum rutrum. Nulla facilisi. Duis nisi est, tincidunt a sagittis id, sollicitudin at odio. Curabitur sed est eu sapien faucibus dignissim in quis tortor. Nunc ac elit tortor, non lobortis massa. Proin posuere ante ut metus vehicula suscipit. Proin mattis mauris ac lectus consequat rutrum. Nam arcu lectus, commodo non pretium a, pharetra semper dolor. Fusce eleifend hendrerit adipiscing. Nunc et eleifend erat. Suspendisse tempus nisl ut arcu blandit ut adipiscing nisi tristique. Suspendisse molestie facilisis risus sed fermentum. Praesent tempor convallis ultricies. Integer et elit velit, at consectetur risus. Vestibulum mollis adipiscing sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris dictum molestie porta. Nam convallis nisl quis lacus vulputate in convallis risus sagittis. Vivamus accumsan faucibus cursus. Ut ultricies imperdiet ligula scelerisque blandit. In ornare egestas purus, at convallis velit egestas laoreet. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla quis imperdiet est. Nunc tempus magna quis lacus feugiat et posuere lacus vehicula. Cras lacinia aliquam est at vehicula. Aenean congue elit in ante dignissim vitae fermentum lectus aliquam. Mauris at odio magna, at interdum dui. Cras fringilla mi velit, nec varius neque. Fusce et volutpat lacus. Suspendisse id turpis et urna varius convallis in eu purus. Nulla facilisi. Etiam mauris nisl, ultrices ac porttitor sit amet, facilisis ut neque. Nullam ut velit quis velit tincidunt rhoncus. Praesent tristique porttitor euismod. Nulla non felis ante, feugiat commodo turpis. In nec venenatis mi. Duis tempus tempor purus, vitae consectetur mi ornare eu. Proin sed consequat erat. Quisque nec sem dui. Nam semper, ligula facilisis pretium interdum, diam lectus sollicitudin lorem, in elementum nisi lorem scelerisque justo. Nullam ac fringilla nunc. Maecenas malesuada ligula in massa sollicitudin sit amet auctor ipsum malesuada. Vestibulum ut augue in magna lobortis varius eget in ipsum. In hac habitasse platea dictumst. Cras vel sagittis mi. Aenean urna sapien, ultrices et tristique et, aliquam vel libero. Nullam in consequat ante. Suspendisse libero augue, pulvinar a dignissim vitae, fringilla malesuada dui. Phasellus augue ante, pulvinar eget tincidunt vel, venenatis sed arcu. Pellentesque ac purus orci, vel molestie turpis. Nulla consectetur sollicitudin dolor, sed ornare arcu accumsan fermentum. Fusce vestibulum nisi at leo interdum eu sollicitudin lacus dictum. Fusce malesuada consequat ipsum ut convallis. Maecenas in eros sit amet elit consectetur fringilla nec a nibh. Ut et velit vel ligula pharetra elementum. Nullam aliquam, tellus vel cursus lacinia, dui libero dictum turpis, nec lacinia dolor nunc vel diam. Pellentesque convallis dui quis lacus ornare at rutrum lorem pellentesque. Suspendisse potenti. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc ac nibh sed mauris ornare cursus. Praesent enim mauris, tincidunt vitae convallis ac, ultricies imperdiet sapien. Duis sodales ligula eget lorem suscipit sed consectetur metus pretium. Nam in magna augue, quis volutpat mauris. Quisque pretium lobortis orci quis laoreet. Nam ut nisi diam. Sed ultrices ultrices dapibus. Integer feugiat mauris id orci pulvinar eu tempus nibh viverra. Etiam venenatis bibendum massa a consequat. Fusce interdum velit ac mauris rhoncus non cursus neque consectetur. Vestibulum dictum eros ac metus fringilla venenatis. Phasellus auctor dui non nulla molestie id malesuada mauris euismod. Aenean id tortor ac justo eleifend mollis non vel arcu. Duis ac lorem tortor. Donec volutpat purus sed nunc luctus interdum hendrerit nulla ullamcorper. Sed consectetur interdum aliquet. Proin ullamcorper risus ut ante lacinia sagittis. Nunc varius eleifend purus, ac pellentesque urna viverra id. Praesent euismod, sapien accumsan gravida dictum, massa massa euismod sapien, ut auctor tellus arcu sed diam. Vivamus tincidunt dolor non lorem pellentesque at tempus elit adipiscing. Vestibulum tempor aliquam consectetur. Mauris nec dictum nisl. Donec scelerisque ornare condimentum. Phasellus laoreet justo nec nibh convallis convallis. Duis id orci sapien, eget pulvinar justo. Aenean id arcu felis, eu iaculis nibh. Aenean eleifend pretium rutrum. Aliquam molestie sem quis tellus aliquam eleifend. Mauris et purus orci. Nunc et accumsan tortor. Phasellus semper eleifend nisi, a faucibus risus vehicula id. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas in felis et est lacinia eleifend vel sed ipsum. Aliquam commodo molestie lorem id hendrerit. Nam sed tellus urna, sed dignissim eros. """ def a_function(): """A long function docstring. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sit amet mauris mauris, sit amet venenatis nisl. Vivamus a est porta enim sollicitudin mollis. Proin fringilla massa vel ante gravida luctus. Nunc quis nunc id quam hendrerit posuere. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam porttitor interdum sollicitudin. Mauris malesuada tellus tellus. Mauris condimentum nunc et sapien pellentesque gravida. Suspendisse sed ipsum orci. Duis ut lacus dui. Integer ac gravida sem. Vivamus fermentum porttitor velit ac blandit. Maecenas pulvinar ullamcorper enim, vitae aliquet tortor scelerisque et. Vestibulum ante massa, sodales et bibendum dignissim, consectetur vitae metus. Quisque vel dui erat, vel commodo metus. Aliquam arcu dolor, viverra sit amet porttitor a, faucibus eu augue. Sed ornare, enim eget ultricies suscipit, nunc dui lacinia enim, vitae tempus nunc libero vitae ligula. Nam et commodo ligula. Pellentesque tincidunt lorem at elit aliquam at fringilla libero tempor. Donec molestie consectetur nibh, ac varius ante dictum id. Suspendisse lectus nibh, molestie vel dapibus eget, egestas ut eros. Mauris vel mauris turpis, vitae bibendum nunc. Vestibulum nulla enim, vestibulum vitae tincidunt et, gravida eu metus. Nulla sagittis, odio a placerat laoreet, arcu lectus vestibulum nunc, in hendrerit tortor quam sit amet turpis. In et purus vel dui pellentesque tincidunt. Donec dictum nibh sed quam luctus sit amet luctus justo dapibus. Integer nulla elit, lacinia aliquet euismod sed, tempus vitae lectus. Fusce non sapien dolor. Suspendisse ut est ut dui tempor ultricies id ut elit. Aenean adipiscing sollicitudin enim, nec porttitor est porttitor eget. Proin lobortis ante ut diam sodales volutpat. Donec urna diam, porttitor nec laoreet ut, rhoncus non diam. Ut sed mi vitae turpis semper semper. Integer sit amet lorem sapien. Aliquam risus diam, vulputate id sagittis et, molestie ut lectus. Aliquam erat volutpat. Morbi aliquet venenatis metus in posuere. Cras vitae purus nunc, ut vestibulum ipsum. Nullam vehicula dui in urna iaculis lobortis. Ut a est non est tincidunt iaculis. Vivamus rutrum velit non nunc malesuada sed bibendum mi iaculis. Sed id lacus in sem tempor vestibulum. Cras bibendum accumsan suscipit. Phasellus congue nisl consectetur turpis rhoncus aliquet posuere libero fringilla. Sed eros tellus, hendrerit nec imperdiet vitae, blandit ac dolor. Nulla facilisi. Morbi ullamcorper libero odio, at cursus tortor. Cras ultricies tellus eget justo cursus cursus. Donec at mi massa, auctor suscipit sem. Proin dolor purus, semper sed ultrices ut, iaculis at tortor. Donec risus enim, interdum et convallis nec, aliquam eget velit. Curabitur eget lectus dolor. Integer id turpis eu nulla euismod tincidunt. Fusce elit nibh, dapibus sit amet tempus ac, convallis eu libero. Donec dui justo, molestie sed euismod porta, ultricies id orci. Praesent a tellus et risus faucibus porttitor pellentesque in purus. Fusce blandit risus ac tortor viverra vitae molestie odio convallis. Donec rhoncus volutpat mauris, sit amet mattis libero dapibus id. Ut rhoncus venenatis nisi ac dictum. In non nulla eget massa convallis facilisis. Praesent nec odio id odio semper lobortis non eu erat. Proin quis gravida magna. Sed rhoncus lectus auctor arcu posuere a auctor dui pellentesque. Sed enim nulla, luctus quis sagittis sed, vestibulum eget metus. Mauris ornare pretium fringilla. Proin ligula eros, fermentum in placerat sit amet, placerat vel mauris. Nulla magna enim, luctus eget euismod ac, lacinia vel lorem. Duis mi leo, porttitor vitae dictum ac, ultrices iaculis metus. Quisque libero mi, aliquet quis vestibulum eget, porttitor non justo. Praesent ac metus felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec vel enim sit amet ante imperdiet commodo sed vel nisi. Praesent semper viverra nulla vehicula sollicitudin. Fusce lacinia aliquet ullamcorper. Donec vitae diam est. Integer volutpat hendrerit turpis ut bibendum. Integer et dui augue. Nunc ut nisl in felis feugiat semper nec sit amet purus. Proin convallis ultrices nisl ut vehicula. Pellentesque neque mi, elementum vel placerat nec, laoreet ac nulla. Pellentesque aliquam dui a metus iaculis posuere. Curabitur dapibus faucibus metus. Donec quis diam dui. Proin at mi nec augue cursus pulvinar eu vel metus. Curabitur eget turpis ac risus dignissim luctus sed id ligula. Etiam lectus neque, varius ut euismod nec, euismod quis nulla. Ut feugiat, quam id tempor luctus, metus eros lacinia diam, nec dapibus tellus dui quis diam. Nam interdum, orci id fringilla mattis, ipsum eros pellentesque turpis, hendrerit dignissim justo dui interdum ante. Curabitur aliquam nisi ut dui lacinia tempor. Nulla lobortis tellus non sapien dignissim ut dapibus dui aliquet. Nam scelerisque, urna a aliquam malesuada, mi tortor scelerisque libero, quis pellentesque erat eros ut justo. Phasellus nulla purus, suscipit vel gravida euismod, malesuada et odio. Vestibulum non libero eget lacus venenatis auctor quis a est. Nunc id leo est. Curabitur pulvinar viverra sapien at viverra. Cras pretium justo et lorem lobortis id tempor nisi accumsan. Cras egestas tortor in risus hendrerit eu varius purus suscipit. Nullam mauris eros, mattis at tempor vitae, mollis vitae velit. Etiam at adipiscing lectus. Quisque molestie, metus id posuere pharetra, lorem enim vehicula mauris, ut ultricies purus justo a lacus. Vivamus blandit euismod adipiscing. Nam eu ligula at elit ultricies tempus. Nunc ac sodales neque. Ut dui diam, porttitor a pulvinar vel, sodales sit amet turpis. Donec vitae eros at neque luctus scelerisque. In consequat elementum iaculis. Donec ullamcorper dolor eu quam volutpat rhoncus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras laoreet ante eget dolor sagittis imperdiet. Proin magna urna, porta id blandit nec, commodo eget lorem. Etiam imperdiet, orci sit amet rutrum consectetur, orci augue tempus lacus, id venenatis sapien nisl a est. Sed accumsan massa sed libero consectetur scelerisque. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed nunc risus, lobortis id egestas nec, suscipit id magna. Morbi at iaculis mauris. Proin felis sem, tempus non pellentesque congue, vehicula sit amet eros. Maecenas porttitor erat ac dolor pharetra iaculis. Cras tincidunt, nulla eget malesuada egestas, sem diam consequat quam, sed feugiat nulla orci at mauris. Quisque non arcu diam, ac lacinia felis. Nunc iaculis mollis egestas. Etiam imperdiet dolor consectetur eros feugiat fringilla sed in lacus. Nunc nec tincidunt dolor. Etiam sagittis tortor condimentum nunc fermentum vestibulum. Vivamus lobortis, magna sit amet scelerisque lobortis, sem eros molestie leo, eget aliquet ligula est in lectus. Duis placerat porta pulvinar. Sed sed adipiscing ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam accumsan iaculis augue, sed varius dui sagittis id. Etiam sit amet eleifend augue. Ut sit amet nibh sit amet justo tempor condimentum. Ut faucibus sagittis volutpat. Duis vestibulum feugiat sollicitudin. Aenean cursus luctus urna at consectetur. Nullam tincidunt, eros a iaculis sodales, tellus est imperdiet arcu, sit amet tincidunt orci felis et tortor. Mauris rutrum venenatis nunc ut rutrum. Phasellus nec erat magna, in tincidunt orci. Sed sit amet suscipit tellus. Mauris ut nisi turpis. Suspendisse augue turpis, condimentum ac bibendum in, vestibulum nec eros. Curabitur dapibus pulvinar vehicula. Fusce consequat, erat in malesuada hendrerit, tellus urna pharetra lacus, sed euismod nisi urna sed nisi. Etiam fermentum accumsan nunc, sed bibendum dui iaculis id. Etiam blandit fermentum ligula nec viverra. Vivamus venenatis arcu in nulla euismod euismod. Donec sit amet augue nec metus varius fringilla. Vivamus pulvinar elit ac mi rhoncus in luctus diam egestas. Curabitur a felis eget arcu pretium tempus eu sed mauris. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris malesuada, nibh ac venenatis hendrerit, ligula dui condimentum tellus, sit amet pretium diam tortor vel risus. Suspendisse suscipit consequat eros id dignissim. Cras interdum lorem ac massa euismod non porta enim pretium. Aliquam ultrices nibh vitae ligula consectetur vel sollicitudin lacus volutpat. Phasellus vulputate iaculis sem nec laoreet. Nam leo sem, tempor eu condimentum id, imperdiet sed dolor. Donec pharetra velit non libero euismod tempor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed fermentum, libero a posuere posuere, enim elit imperdiet enim, a sollicitudin est felis non libero. Sed vel dolor ut arcu dapibus iaculis nec a mauris. Morbi ullamcorper ultrices venenatis. Fusce luctus ante sit amet lacus venenatis ut rutrum elit lobortis. Nulla fermentum tortor ac sapien fringilla quis iaculis quam egestas. Aliquam et tortor est, at elementum mauris. Morbi posuere erat nec leo vulputate in pellentesque tortor condimentum. Vestibulum at orci augue. Aenean pellentesque sapien id felis consequat varius. Suspendisse bibendum enim sit amet mi imperdiet vel suscipit nisi tristique. Curabitur velit massa, consectetur ac mattis vel, accumsan at nunc. Donec porta, nibh nec consequat convallis, urna neque auctor erat, eu convallis lorem leo convallis turpis. Morbi non mauris non metus ornare vulputate. Sed aliquet, dolor ut egestas fermentum, metus purus mollis elit, nec commodo odio quam quis nisl. Aliquam erat volutpat. Suspendisse sed faucibus urna. Integer suscipit rutrum condimentum. Praesent dignissim libero eget metus luctus consectetur. Vestibulum ac erat felis, vitae iaculis erat. Duis interdum lacinia arcu, non lacinia urna luctus in. Curabitur feugiat sapien sapien, in vestibulum diam. Phasellus lobortis massa ut metus pretium dignissim. Fusce quis sem odio. Integer pellentesque sodales augue id tincidunt. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum lorem odio, semper vel scelerisque sit amet, sagittis ac libero. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam egestas ultricies dui at gravida. Duis tristique, eros id consectetur pellentesque, nulla arcu ultricies tortor, ut pulvinar sapien lacus in elit. Vivamus dolor massa, pulvinar at mollis vitae, euismod ut dolor. Vivamus a magna ante. Vestibulum vitae fringilla leo. Ut gravida magna in quam fringilla ultricies. Mauris rhoncus enim id sem interdum blandit. Pellentesque luctus leo sit amet felis viverra ac accumsan purus mollis. Aenean pretium fringilla quam nec laoreet. Nulla id mauris mauris. Nam varius bibendum tristique. Integer ante felis, volutpat sed dignissim vel, interdum molestie nisi. Etiam mollis accumsan elit, ut gravida eros molestie nec. Nullam quis velit ac purus imperdiet sodales. Donec semper placerat venenatis. Cras dolor risus, sodales sed scelerisque nec, sollicitudin pretium felis. Quisque pretium felis id turpis bibendum pulvinar ornare id nibh. Morbi lobortis leo non mi porttitor vulputate. Vestibulum nec odio tellus, ut blandit ligula. In pellentesque neque sit amet dui pulvinar sed laoreet dui vehicula. In hac habitasse platea dictumst. Etiam feugiat dictum blandit. Praesent lacinia tincidunt elit, quis consectetur tortor molestie commodo. Ut sit amet accumsan lorem. Cras quam nunc, malesuada tempor volutpat vitae, aliquam eu diam. Sed sem nibh, bibendum nec sollicitudin at, interdum et magna. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam vitae sem non elit pharetra vestibulum et condimentum libero. Nam egestas ultricies hendrerit. Nunc nec fringilla nulla. Aliquam risus tellus, hendrerit non dapibus a, tincidunt vel ante. Vivamus mollis, magna et lacinia tincidunt, dui massa porta odio, ac ornare felis massa nec lorem. Mauris sagittis lacus sed metus mollis ac egestas lectus porttitor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer vitae lacinia libero. Phasellus at neque enim, sit amet dictum mi. Ut risus nisi, vestibulum vel congue eget, egestas in ipsum. Duis faucibus tempus sodales. Duis convallis pellentesque arcu rhoncus congue. Nunc ac mauris eu purus vestibulum congue. Praesent convallis semper augue vel volutpat. Integer dictum varius placerat. Vestibulum convallis tortor non mi lacinia ac aliquet dui ultricies. Donec ultrices purus eros. Maecenas venenatis posuere massa, nec consectetur lacus cursus eget. Donec quam lacus, tempus id placerat et, posuere sed libero. Proin auctor diam ut arcu viverra ut imperdiet tellus dapibus. Morbi ac mauris quis tellus porttitor eleifend. Sed et ante magna, ut sodales sapien. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Integer mattis venenatis mi non ullamcorper. Vestibulum magna enim, aliquam non interdum ut, dignissim vitae ante. Praesent dignissim, est at pretium posuere, nisl ante varius felis, vitae posuere enim nulla et nunc. Morbi sagittis suscipit leo, eu accumsan ligula volutpat non. Donec ut tincidunt magna. Integer ac libero mi. Sed non eros dolor, in tincidunt enim. Curabitur iaculis erat quis felis iaculis ut volutpat augue malesuada. Pellentesque eget arcu ligula, ut volutpat purus. Suspendisse dictum lorem quis sapien lacinia pretium. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin sagittis egestas massa et tempor. Mauris et eros ante, id porta sem. Duis ac eros vitae ipsum ultrices malesuada eget a risus. Morbi imperdiet, est a hendrerit tristique, mi erat molestie lacus, ac tempor risus nulla id erat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam congue, lacus quis ultricies consequat, diam metus convallis enim, ut volutpat enim urna vitae erat. In quam risus, molestie et dapibus id, elementum sit amet ligula. Nam faucibus lacus id dolor facilisis viverra. Nullam vehicula massa ac arcu consectetur vulputate. Praesent nec augue ac justo dapibus vehicula. Aliquam consectetur hendrerit dolor, et mollis nisl auctor ut. Ut sagittis risus at felis fringilla ultricies. Vestibulum non urna nibh, nec pretium dolor. Nulla imperdiet lobortis eros at pharetra. Vivamus cursus pellentesque ornare. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce arcu quam, pulvinar at rutrum vitae, ornare vitae leo. Maecenas vehicula magna sit amet nulla bibendum condimentum. Curabitur ultrices tempor fringilla. Vivamus pretium suscipit molestie. Donec arcu diam, ultricies ac pellentesque eu, venenatis et sapien. Nam dictum orci augue, vel eleifend leo. Nam at lacus sapien, nec pretium eros. In egestas, enim sed sagittis feugiat, purus odio tristique lectus, vel condimentum leo turpis ac odio. Nam iaculis mi quis odio posuere et venenatis velit ultricies. Nulla facilisi. Proin nec dolor ac quam euismod gravida quis et eros. Nam interdum condimentum mattis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent a nisi eu massa mollis posuere sed a nunc. Aenean tempus enim a justo rhoncus quis ultrices nisl commodo. Aenean imperdiet mauris a ipsum venenatis vel scelerisque lorem rutrum. Donec ut nunc eros, eget accumsan felis. Nullam ullamcorper porta dictum. Donec accumsan cursus vestibulum. Aenean in sapien velit. Vivamus nec massa mi. Fusce felis tortor, bibendum non volutpat a, fringilla quis nisi. Duis varius bibendum erat, quis fermentum sem accumsan eget. Maecenas massa felis, porta sed laoreet eu, luctus eu lectus. Cras id nibh vitae erat fringilla rutrum. Maecenas eget consequat est. Vivamus viverra, felis vel faucibus rhoncus, quam ipsum elementum libero, quis convallis urna purus ut mauris. Nam quis urna vitae enim consequat placerat. Vivamus congue augue sit amet lectus luctus tempor. Cras ut justo convallis est egestas pellentesque ac nec orci. Vivamus rutrum bibendum ante, at cursus erat pulvinar ornare. Proin imperdiet scelerisque ante eu vestibulum. Nullam ullamcorper metus nec purus auctor lobortis. Proin sed lacus et ipsum tempor tempus. Vivamus odio dolor, vulputate vitae semper sit amet, aliquet egestas orci. Nullam non quam eu quam sagittis porta. Nunc in velit id erat commodo viverra. Praesent nec est augue, nec sagittis erat. Cras sed turpis quis enim tempor sagittis. Donec in justo ac nisl porta condimentum id vestibulum nulla. Nam elementum ultricies nunc a bibendum. Aenean tincidunt nisl non augue pellentesque sit amet convallis neque semper. Cras placerat suscipit massa sed volutpat. Integer vulputate imperdiet enim, vitae vulputate sapien mattis feugiat. Vivamus pharetra facilisis mauris a gravida. Nulla non venenatis est. Duis lobortis consectetur sem ac aliquam. In eget sapien odio. Vivamus pulvinar ultricies magna, quis laoreet dui porta et. Integer tempus malesuada velit, et consequat odio ultrices sed. Aliquam malesuada commodo diam vel posuere. Morbi porttitor, elit vitae auctor gravida, lorem massa bibendum arcu, vel placerat nulla justo at augue. Aliquam libero quam, mattis blandit congue sit amet, fermentum ac augue. Aliquam malesuada molestie vulputate. Duis id porta augue. Vestibulum diam dolor, ultrices sit amet porttitor id, convallis id lectus. Etiam ac augue tincidunt nisi tempor molestie euismod id nisl. Nam et tortor ac arcu viverra pulvinar. Fusce pulvinar rhoncus leo, a faucibus enim interdum non. Aliquam vulputate mattis consectetur. Pellentesque sit amet quam sem. Cras eget arcu eu elit volutpat volutpat. Integer sed varius enim. Integer sit amet felis orci, id dignissim sapien. Sed vitae lorem sed libero facilisis fringilla. Pellentesque congue tristique purus, eleifend semper risus suscipit quis. Phasellus rutrum quam vitae arcu vulputate porta. Sed tristique arcu nec mi porttitor lacinia. Donec congue feugiat diam quis pretium. Vivamus at luctus nunc. Integer vulputate laoreet mauris quis auctor. Nunc at ultrices libero. Maecenas porta faucibus purus non vehicula. Sed sit amet metus vitae mi ultrices scelerisque nec quis risus. Phasellus pellentesque tincidunt massa id ultricies. Aliquam dictum arcu ac dolor interdum rutrum. Nulla facilisi. Duis nisi est, tincidunt a sagittis id, sollicitudin at odio. Curabitur sed est eu sapien faucibus dignissim in quis tortor. Nunc ac elit tortor, non lobortis massa. Proin posuere ante ut metus vehicula suscipit. Proin mattis mauris ac lectus consequat rutrum. Nam arcu lectus, commodo non pretium a, pharetra semper dolor. Fusce eleifend hendrerit adipiscing. Nunc et eleifend erat. Suspendisse tempus nisl ut arcu blandit ut adipiscing nisi tristique. Suspendisse molestie facilisis risus sed fermentum. Praesent tempor convallis ultricies. Integer et elit velit, at consectetur risus. Vestibulum mollis adipiscing sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris dictum molestie porta. Nam convallis nisl quis lacus vulputate in convallis risus sagittis. Vivamus accumsan faucibus cursus. Ut ultricies imperdiet ligula scelerisque blandit. In ornare egestas purus, at convallis velit egestas laoreet. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla quis imperdiet est. Nunc tempus magna quis lacus feugiat et posuere lacus vehicula. Cras lacinia aliquam est at vehicula. Aenean congue elit in ante dignissim vitae fermentum lectus aliquam. Mauris at odio magna, at interdum dui. Cras fringilla mi velit, nec varius neque. Fusce et volutpat lacus. Suspendisse id turpis et urna varius convallis in eu purus. Nulla facilisi. Etiam mauris nisl, ultrices ac porttitor sit amet, facilisis ut neque. Nullam ut velit quis velit tincidunt rhoncus. Praesent tristique porttitor euismod. Nulla non felis ante, feugiat commodo turpis. In nec venenatis mi. Duis tempus tempor purus, vitae consectetur mi ornare eu. Proin sed consequat erat. Quisque nec sem dui. Nam semper, ligula facilisis pretium interdum, diam lectus sollicitudin lorem, in elementum nisi lorem scelerisque justo. Nullam ac fringilla nunc. Maecenas malesuada ligula in massa sollicitudin sit amet auctor ipsum malesuada. Vestibulum ut augue in magna lobortis varius eget in ipsum. In hac habitasse platea dictumst. Cras vel sagittis mi. Aenean urna sapien, ultrices et tristique et, aliquam vel libero. Nullam in consequat ante. Suspendisse libero augue, pulvinar a dignissim vitae, fringilla malesuada dui. Phasellus augue ante, pulvinar eget tincidunt vel, venenatis sed arcu. Pellentesque ac purus orci, vel molestie turpis. Nulla consectetur sollicitudin dolor, sed ornare arcu accumsan fermentum. Fusce vestibulum nisi at leo interdum eu sollicitudin lacus dictum. Fusce malesuada consequat ipsum ut convallis. Maecenas in eros sit amet elit consectetur fringilla nec a nibh. Ut et velit vel ligula pharetra elementum. Nullam aliquam, tellus vel cursus lacinia, dui libero dictum turpis, nec lacinia dolor nunc vel diam. Pellentesque convallis dui quis lacus ornare at rutrum lorem pellentesque. Suspendisse potenti. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc ac nibh sed mauris ornare cursus. Praesent enim mauris, tincidunt vitae convallis ac, ultricies imperdiet sapien. Duis sodales ligula eget lorem suscipit sed consectetur metus pretium. Nam in magna augue, quis volutpat mauris. Quisque pretium lobortis orci quis laoreet. Nam ut nisi diam. Sed ultrices ultrices dapibus. Integer feugiat mauris id orci pulvinar eu tempus nibh viverra. Etiam venenatis bibendum massa a consequat. Fusce interdum velit ac mauris rhoncus non cursus neque consectetur. Vestibulum dictum eros ac metus fringilla venenatis. Phasellus auctor dui non nulla molestie id malesuada mauris euismod. Aenean id tortor ac justo eleifend mollis non vel arcu. Duis ac lorem tortor. Donec volutpat purus sed nunc luctus interdum hendrerit nulla ullamcorper. Sed consectetur interdum aliquet. Proin ullamcorper risus ut ante lacinia sagittis. Nunc varius eleifend purus, ac pellentesque urna viverra id. Praesent euismod, sapien accumsan gravida dictum, massa massa euismod sapien, ut auctor tellus arcu sed diam. Vivamus tincidunt dolor non lorem pellentesque at tempus elit adipiscing. Vestibulum tempor aliquam consectetur. Mauris nec dictum nisl. Donec scelerisque ornare condimentum. Phasellus laoreet justo nec nibh convallis convallis. Duis id orci sapien, eget pulvinar justo. Aenean id arcu felis, eu iaculis nibh. Aenean eleifend pretium rutrum. Aliquam molestie sem quis tellus aliquam eleifend. Mauris et purus orci. Nunc et accumsan tortor. Phasellus semper eleifend nisi, a faucibus risus vehicula id. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas in felis et est lacinia eleifend vel sed ipsum. Aliquam commodo molestie lorem id hendrerit. Nam sed tellus urna, sed dignissim eros. """ return A_LONG_STRING Cython-0.23.4/tests/compile/magcmp.pyx0000644000175600017570000000025112606202452021002 0ustar jenkinsjenkins00000000000000# mode: compile cdef void foo(): cdef int bool, int1=0, int2=0 bool = int1 < int2 bool = int1 > int2 bool = int1 <= int2 bool = int1 >= int2 foo() Cython-0.23.4/tests/compile/longunsigned.pyx0000644000175600017570000000011112606202452022225 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern unsigned long x cdef extern long unsigned y Cython-0.23.4/tests/compile/libc_stdio.pyx0000644000175600017570000000057512606202452021662 0ustar jenkinsjenkins00000000000000# mode: compile cimport libc from libc cimport stdio from libc.stdio cimport printf, puts, fputs, putchar, fputc, putc, stdout libc.stdio.printf("hello %s\n", b"world") stdio.printf("hello %s\n", b"world") printf("hello %s\n", b"world") printf("printf_output %d %d\n", 1, 2) puts("puts_output") fputs("fputs_output", stdout) putchar(b'z') fputc(b'x', stdout) putc(b'c', stdout) Cython-0.23.4/tests/compile/libc_signal.pyx0000644000175600017570000000053212606202452022006 0ustar jenkinsjenkins00000000000000# mode: compile from libc.signal cimport * cdef void sighdl(int signum) nogil: pass cdef sighandler_t h h = signal(SIGABRT, sighdl) if h == SIG_ERR: pass h = signal(SIGABRT, SIG_IGN) if h == SIG_ERR: pass h = signal(SIGABRT, SIG_DFL) if h == SIG_ERR: pass h = signal(SIGABRT, SIG_IGN) cdef int e = raise_(SIGABRT) h = signal(SIGABRT, h) Cython-0.23.4/tests/compile/libc_math.pyx0000644000175600017570000000114312606202452021461 0ustar jenkinsjenkins00000000000000from libc.math cimport (M_E, M_LOG2E, M_LOG10E, M_LN2, M_LN10, M_PI, M_PI_2, M_PI_4, M_1_PI, M_2_PI, M_2_SQRTPI, M_SQRT2, M_SQRT1_2) from libc.math cimport (acos, asin, atan, atan2, cos, sin, tan, cosh, sinh, tanh, acosh, asinh, atanh, exp, log, log10, pow, sqrt) def test_pi(): """ >>> import math >>> test_pi() == math.pi True """ return M_PI def test_sin(x): """ >>> test_sin(0) 0.0 >>> from math import sin >>> [sin(k) == test_sin(k) for k in range(10)] [True, True, True, True, True, True, True, True, True, True] """ return sin(x) Cython-0.23.4/tests/compile/libc_errno.pyx0000644000175600017570000000020612606202452021654 0ustar jenkinsjenkins00000000000000# mode: compile from libc.errno cimport * if errno == EDOM : pass if errno == EILSEQ : pass if errno == ERANGE : pass errno = 0 Cython-0.23.4/tests/compile/libc_all.pyx0000644000175600017570000000144312606202452021303 0ustar jenkinsjenkins00000000000000# mode: compile cimport libc cimport libc.stdio cimport libc.errno cimport libc.float cimport libc.limits cimport libc.locale cimport libc.signal cimport libc.stddef #cimport libc.stdint # XXX MSVC cimport libc.stdio cimport libc.stdlib cimport libc.string from libc cimport errno from libc cimport float from libc cimport limits from libc cimport locale from libc cimport signal from libc cimport stddef #from libc cimport stdint # XXX MSVC from libc cimport stdio from libc cimport stdlib from libc cimport string from libc.errno cimport * from libc.float cimport * from libc.limits cimport * from libc.locale cimport * from libc.signal cimport * from libc.stddef cimport * #from libc.stdint cimport * # XXX MSVC from libc.stdio cimport * from libc.stdlib cimport * from libc.string cimport * Cython-0.23.4/tests/compile/lepage_2.pyx0000644000175600017570000000010112606202452021206 0ustar jenkinsjenkins00000000000000# mode: compile ctypedef struct BB: void (*f) (void* state) Cython-0.23.4/tests/compile/kleckner1.pyx0000644000175600017570000000011212606202452021411 0ustar jenkinsjenkins00000000000000# mode: compile def f(x,): pass cdef void g(int x,): pass g(0) Cython-0.23.4/tests/compile/khavkine1.pyx0000644000175600017570000000020212606202452021413 0ustar jenkinsjenkins00000000000000# mode: compile cdef class T: cdef int[1] a cdef object b cdef void f(void *obj): ( obj).a[0] = 1 b = None f(NULL) Cython-0.23.4/tests/compile/johnson2.pyx0000644000175600017570000000012012606202452021271 0ustar jenkinsjenkins00000000000000# mode: compile cdef class C: cdef object foo cdef object __weakref__ Cython-0.23.4/tests/compile/johnson1.pyx0000644000175600017570000000016512606202452021301 0ustar jenkinsjenkins00000000000000# mode: compile ctypedef enum foo: FOO cdef void func(): cdef foo x map = [FOO] x = map[0] func() Cython-0.23.4/tests/compile/jiba6.pyx0000644000175600017570000000030112606202452020525 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern from "string.h": void memcpy(void* des, void* src, int size) cdef void f(): cdef float[3] f1 cdef float* f2 f2 = f1 + 1 memcpy(f1, f2, 1) f() Cython-0.23.4/tests/compile/jiba5.pyx0000644000175600017570000000013212606202452020526 0ustar jenkinsjenkins00000000000000# mode: compile def f(): cdef int i=0 global mylist del mylist[i] return Cython-0.23.4/tests/compile/jiba4.pyx0000644000175600017570000000005712606202452020533 0ustar jenkinsjenkins00000000000000# mode: compile cdef class A: cdef object x Cython-0.23.4/tests/compile/jiba3.pyx0000644000175600017570000000062712606202452020535 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Position cdef class Point(Position) cdef class Vector(Point) cdef class CoordSyst cdef void test(float* f): pass cdef class Position: cdef readonly CoordSyst parent cdef class Point(Position): cdef void bug(self): test(self.parent._matrix) cdef class Vector(Point): cdef void bug(self): test(self.parent._matrix) cdef class CoordSyst: cdef float* _matrix Cython-0.23.4/tests/compile/ishimoto4.pyx0000644000175600017570000000007012606202452021454 0ustar jenkinsjenkins00000000000000# mode: compile cdef void __stdcall f(): pass f() Cython-0.23.4/tests/compile/ishimoto1.pyx0000644000175600017570000000011312606202452021447 0ustar jenkinsjenkins00000000000000# mode: compile cdef class A: def __getitem__(self, x): pass Cython-0.23.4/tests/compile/inplace_ops.pyx0000644000175600017570000000036212606202452022035 0ustar jenkinsjenkins00000000000000# mode: compile def test(): cdef object a = 1, b = 2 cdef char *p = 'abc' a += b a -= b a *= b a /= b a %= b a **= b a <<= b a >>= b a &= b a ^= b a |= b p += 42 p -= 42 p += a Cython-0.23.4/tests/compile/inplace_lhs.pyx0000644000175600017570000000075312606202452022026 0ustar jenkinsjenkins00000000000000# mode: compile cdef struct S: int q def test(): cdef int i = 1, j = 2, k = 3 cdef float x = 1, y = 2, z = 3 cdef object a = 1, b = 2, c = 3, d = 4, e = 5 cdef int[3] m m[0] = 0 m[1] = 1 m[2] = 1 cdef S s = [1] global g i += j + k x += y + z x += i a += b + c g += a m[i] += j a[i] += b + c a[b + c] += d (a + b)[c] += d a[i : j] += b (a + b)[i : j] += c a.b += c + d (a + b).c += d s.q += i Cython-0.23.4/tests/compile/indices.pyx0000644000175600017570000000027112606202452021156 0ustar jenkinsjenkins00000000000000# mode: compile cdef int* a cdef object x cdef int f(int i): print i return i x[f(1)] = 3 a[f(1)] = 3 x[f(2)] += 4 a[f(2)] += 4 print x[1] print a[1] x[f(1)] = 15 Cython-0.23.4/tests/compile/index.pyx0000644000175600017570000000064612606202452020655 0ustar jenkinsjenkins00000000000000# mode: compile def f(obj1, obj2, obj3): cdef int int1, int2=0, int3=0 cdef float flt1, *ptr1=NULL cdef int[42] array1 array1[int2] = 0 int1 = array1[int2] flt1 = ptr1[int2] array1[int1] = int2 ptr1[int1] = int2 obj1 = obj2[obj3] int1 = array1[obj3] obj1 = obj2[int3] obj1[obj2] = obj3 array1[obj2] = int3 obj1[int2] = obj3 obj1[obj2] = 42 f(None, None, None) Cython-0.23.4/tests/compile/import.pyx0000644000175600017570000000016412606202452021053 0ustar jenkinsjenkins00000000000000# mode: compile def f(): import spam import spam.eggs import spam, eggs, ham import spam as tasty Cython-0.23.4/tests/compile/ia_cdefblock.pyx0000644000175600017570000000063412606202452022130 0ustar jenkinsjenkins00000000000000# mode: compile cdef: struct PrivFoo: int i int priv_i void priv_f(): global priv_i priv_i = 42 cdef public: struct PubFoo: int i int pub_v void pub_f(): pass class PubBlarg [object PubBlargObj, type PubBlargType]: pass cdef api: void api_f(): pass cdef public api: void pub_api_f(): pass priv_f() Cython-0.23.4/tests/compile/huss2.pyx0000644000175600017570000000030512606202452020602 0ustar jenkinsjenkins00000000000000# mode: compile cdef enum Color: red white blue cdef void f(): cdef Color e cdef int i i = red i = red + 1 i = red | 1 e = white i = e i = e + 1 f() Cython-0.23.4/tests/compile/hinsen2.pyx0000644000175600017570000000021512606202452021104 0ustar jenkinsjenkins00000000000000# mode: compile cdef class vector: def __div__(vector self, double factor): cdef object result = vector() return result Cython-0.23.4/tests/compile/hinsen1.pyx.BROKEN0000644000175600017570000000043512606202452022066 0ustar jenkinsjenkins00000000000000__doc__ = """ >>> test() 1 """ cdef extern from "hinsen1.h": ctypedef class spam.Spam [object PySpamObject]: pass cdef class SpamAndEggs(Spam): cdef cook(self): return 1 def test(): cdef SpamAndEggs s s = SpamAndEggs() return s.cook() Cython-0.23.4/tests/compile/hinsen1.h0000644000175600017570000000006012606202452020510 0ustar jenkinsjenkins00000000000000typedef struct { PyObject_HEAD } PySpamObject; Cython-0.23.4/tests/compile/gustafsson2.pyx0000644000175600017570000000031412606202452022014 0ustar jenkinsjenkins00000000000000# mode: compile ctypedef enum someenum_t: ENUMVALUE_1 ENUMVALUE_2 cdef somefunction(someenum_t val): if val == ENUMVALUE_1: pass somefunction(ENUMVALUE_1) somefunction(ENUMVALUE_2) Cython-0.23.4/tests/compile/globvardef.pyx0000644000175600017570000000017512606202452021656 0ustar jenkinsjenkins00000000000000# mode: compile cdef int a_global_int cdef a_global_pyobject a_global_int = 0 a_global_pyobject = None cdef object unused Cython-0.23.4/tests/compile/globalstmt.pyx0000644000175600017570000000010112606202452021700 0ustar jenkinsjenkins00000000000000# mode: compile def f(): global a,b,c,d a = b c = d Cython-0.23.4/tests/compile/globalonly.pyx0000644000175600017570000000006112606202452021677 0ustar jenkinsjenkins00000000000000# mode: compile global __name__ print __name__ Cython-0.23.4/tests/compile/getattr3ref.pyx.BROKEN0000644000175600017570000000012512606202452022747 0ustar jenkinsjenkins00000000000000__doc__ = """ >>> print f() """ def f(): g = getattr3 return g.__name__ Cython-0.23.4/tests/compile/gencall.pyx0000644000175600017570000000024312606202452021144 0ustar jenkinsjenkins00000000000000# mode: compile def f(x, y): x = y def z(a, b, c): f(x = 42, y = "spam") f(*a) f(**b) f(x = 42, **b) f(a, *b) f(a, x = 42, *b, **c) Cython-0.23.4/tests/compile/future_imports.pyx0000644000175600017570000000026012606202452022625 0ustar jenkinsjenkins00000000000000# mode: compile from __future__ import nested_scopes from __future__ import with_statement pass from __future__ import nested_scopes ; from __future__ import nested_scopes Cython-0.23.4/tests/compile/funcptr.pyx0000644000175600017570000000026512606202452021224 0ustar jenkinsjenkins00000000000000# mode: compile cdef int grail(): cdef int (*spam)() spam = &grail spam = grail spam() ctypedef int funcptr_t() cdef inline funcptr_t* dummy(): return &grail Cython-0.23.4/tests/compile/fromimport_star.pyx0000644000175600017570000000014012606202452022762 0ustar jenkinsjenkins00000000000000# mode: compile from spam import * from ...spam.foo import * from . import * from ... import * Cython-0.23.4/tests/compile/fromimport.pyx0000644000175600017570000000063112606202452021736 0ustar jenkinsjenkins00000000000000# mode: compile def f(): from spam import eggs from spam.morespam import bacon, eggs, ham from spam import eggs as ova from . import spam from ... import spam from .. import spam, foo from ... import spam, foobar from .spam import foo from ...spam import foo, bar from ...spam.foo import bar from ...spam.foo import foo, bar from ...spam.foo import (foo, bar) Cython-0.23.4/tests/compile/forward.pyx0000644000175600017570000000121612606202452021204 0ustar jenkinsjenkins00000000000000# mode: compile ctypedef enum MyEnum: Value1 Value2 Value3 = 100 cdef MyEnum my_enum = Value3 ctypedef struct StructA: StructA *a StructB *b cdef struct StructB: StructA *a StructB *b cdef class ClassA: cdef ClassA a cdef ClassB b ctypedef public class ClassB [ object ClassB, type TypeB ]: cdef ClassA a cdef ClassB b cdef StructA struct_a cdef StructB struct_b struct_a.a = &struct_a struct_a.b = &struct_b struct_b.a = &struct_a struct_b.b = &struct_b cdef ClassA class_a = ClassA() cdef ClassB class_b = ClassB() class_a.a = class_a class_a.b = class_b class_b.a = class_a class_b.b = class_b Cython-0.23.4/tests/compile/formfeed.pyx0000644000175600017570000000005712606202452021331 0ustar jenkinsjenkins00000000000000# mode: compile cdef int x x = 42 y = 88 Cython-0.23.4/tests/compile/forfromelse.pyx0000644000175600017570000000032312606202452022061 0ustar jenkinsjenkins00000000000000# mode: compile cdef void spam(): cdef int i, j=0, k=0 for i from 0 <= i < 10: j = k else: k = j # new syntax for 0 <= i < 10: j = i else: j = k spam() Cython-0.23.4/tests/compile/for.pyx0000644000175600017570000000046312606202452020331 0ustar jenkinsjenkins00000000000000# mode: compile def f(a, b, c): cdef int i for a in b: i = 1 continue i = 2 break i = 3 for i in b: i = 1 for a in "spam": i = 1 for a[b] in c: i = 1 for a,b in c: i = 1 for a in b,c: i = 1 Cython-0.23.4/tests/compile/food.h0000644000175600017570000000010612606202452020073 0ustar jenkinsjenkins00000000000000struct Tomato { PyObject_HEAD }; struct Bicycle{ PyObject_HEAD }; Cython-0.23.4/tests/compile/first_assignment.pyx0000644000175600017570000000146312606202452023123 0ustar jenkinsjenkins00000000000000# mode: compile cimport cython @cython.test_assert_path_exists( "//SingleAssignmentNode", "//SingleAssignmentNode[./NameNode[@name = 'a']]", "//SingleAssignmentNode[./NameNode[@name = 'a'] and @first = True]", ) def test_cdef(): cdef int a = 1 @cython.test_assert_path_exists( "//SingleAssignmentNode", "//SingleAssignmentNode[./NameNode[@name = 'a']]", # FIXME: currently not working # "//SingleAssignmentNode[./NameNode[@name = 'a'] and @first = True]", ) def test_py(): a = 1 @cython.test_assert_path_exists( "//SingleAssignmentNode", "//SingleAssignmentNode[./NameNode[@name = 'a']]", # FIXME: currently not working # "//SingleAssignmentNode[./NameNode[@name = 'a'] and @first = True]", ) def test_cond(): if True: a = 1 else: a = 2 Cython-0.23.4/tests/compile/find_pxd.srctree0000644000175600017570000000146512606202452022170 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace ######## setup.py ######## from Cython.Build import cythonize from Cython.Distutils.extension import Extension import sys sys.path.append("path") ext_modules = [ Extension("a", ["a.pyx"]), Extension("b", ["b.pyx"]), Extension("c", ["c.pyx"]), ] ext_modules = cythonize(ext_modules, include_path=["include"]) ######## a.pyx ######## # Implicit cimport looking in include_path cdef my_type foo ######## include/a.pxd ######## ctypedef int my_type ######## b.pyx ######## # Explicit cimport looking in sys.path from b cimport * cdef my_type foo ######## path/b.pxd ######## ctypedef int my_type ######## c.pyx ######## # Implicit cimport NOT looking in sys.path ######## path/c.pxd ######## +++syntax error just to show that this file is not actually cimported+++ Cython-0.23.4/tests/compile/extsetslice.pyx0000644000175600017570000000015312606202452022073 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: def __setslice__(self, Py_ssize_t i, Py_ssize_t j, x): pass Cython-0.23.4/tests/compile/extsetitem.pyx0000644000175600017570000000012112606202452021725 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: def __setitem__(self, i, x): pass Cython-0.23.4/tests/compile/extsetattr.pyx0000644000175600017570000000012112606202452021741 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: def __setattr__(self, n, x): pass Cython-0.23.4/tests/compile/extpymemberdef.pyx0000644000175600017570000000057012606202452022562 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: cdef public char c cdef public int i cdef public long l cdef public unsigned char uc cdef public unsigned int ui cdef public unsigned long ul cdef public float f cdef public double d cdef public char *s cdef readonly char[42] a cdef public object o cdef readonly int r cdef readonly Spam e Cython-0.23.4/tests/compile/extpropertyset.pyx0000644000175600017570000000014612606202452022662 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: property eggs: def __set__(self, x): pass Cython-0.23.4/tests/compile/extpropertyget.pyx0000644000175600017570000000014412606202452022644 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: property eggs: def __get__(self): pass Cython-0.23.4/tests/compile/extpropertydoc.pyx0000644000175600017570000000010512606202452022627 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: property eggs: "Ova" Cython-0.23.4/tests/compile/extpropertydel.pyx0000644000175600017570000000014312606202452022630 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: property eggs: def __del__(self): pass Cython-0.23.4/tests/compile/extpropertyall.pyx0000644000175600017570000000032012606202452022631 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: property eggs: "Ova" def __get__(self): pass def __set__(self, x): pass def __del__(self): pass Cython-0.23.4/tests/compile/extinheritset.pyx0000644000175600017570000000032512606202452022437 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Parrot: pass cdef class Norwegian(Parrot): def __setitem__(self, i, x): pass def __setattr__(self, n, x): pass def __set__(self, i, v): pass Cython-0.23.4/tests/compile/extinheritdel.pyx0000644000175600017570000000031712606202452022411 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Parrot: pass cdef class Norwegian(Parrot): def __delitem__(self, i): pass def __delattr__(self, n): pass def __delete__(self, i): pass Cython-0.23.4/tests/compile/extindex.pyx0000644000175600017570000000011612606202452021366 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: def __index__(self): return 42 Cython-0.23.4/tests/compile/extimportedsubtype.pyx0000644000175600017570000000020612606202452023516 0ustar jenkinsjenkins00000000000000# mode: compile from crunchytype cimport Crunchy cdef class Sub2(Crunchy): cdef char character cdef class Sub1(Sub2): pass Cython-0.23.4/tests/compile/extimported.pyx0000644000175600017570000000012512606202452022102 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern class Spam.Eggs.Ham: pass cdef Ham ham ham = None Cython-0.23.4/tests/compile/exthash.pyx0000644000175600017570000000011112606202452021175 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: def __hash__(self): pass Cython-0.23.4/tests/compile/extgetitem.pyx0000644000175600017570000000011712606202452021716 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: def __getitem__(self, x): pass Cython-0.23.4/tests/compile/extgetattr.pyx0000644000175600017570000000011612606202452021731 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: def __getattr__(self, x): pass Cython-0.23.4/tests/compile/extforward.pyx0000644000175600017570000000014312606202452021723 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam cdef class Grail: cdef Spam spam cdef class Spam: pass Cython-0.23.4/tests/compile/extexttype.pyx0000644000175600017570000000043612606202452021766 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern class external.Spam [object SpamObject]: pass ctypedef extern class external.Grail [object Grail]: pass cdef extern from "food.h": class external.Tomato [object Tomato]: pass class external.Bicycle [object Bicycle]: pass Cython-0.23.4/tests/compile/extern_packed_struct.pyx0000644000175600017570000000012512606202452023756 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern from *: cdef packed struct MyStruct: char a Cython-0.23.4/tests/compile/extern.pyx0000644000175600017570000000023612606202452021046 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern int i cdef extern char *s[] cdef extern void spam(char c) cdef extern int eggs(): pass cdef int grail(): pass grail() Cython-0.23.4/tests/compile/extdescrset.pyx0000644000175600017570000000011412606202452022071 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Foo: def __set__(self, i, v): pass Cython-0.23.4/tests/compile/extdescrget.pyx0000644000175600017570000000011412606202452022055 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Foo: def __get__(self, i, c): pass Cython-0.23.4/tests/compile/extdescrdel.pyx0000644000175600017570000000011412606202452022042 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Foo: def __delete__(self, i): pass Cython-0.23.4/tests/compile/extdelslice.pyx0000644000175600017570000000015012606202452022041 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: def __delslice__(self, Py_ssize_t i, Py_ssize_t j): pass Cython-0.23.4/tests/compile/extdelitem.pyx0000644000175600017570000000011612606202452021702 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: def __delitem__(self, i): pass Cython-0.23.4/tests/compile/extdelattr.pyx0000644000175600017570000000011612606202452021716 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: def __delattr__(self, n): pass Cython-0.23.4/tests/compile/extcoerce.pyx0000644000175600017570000000041412606202452021520 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Grail: def __add__(int x, float y): pass cdef class Swallow: pass def f(Grail g): cdef int i = 0 cdef Swallow s = Swallow() cdef object x = Grail() g = x x = g g = i i = g g = s s = g Cython-0.23.4/tests/compile/extcmethcall.pyx0000644000175600017570000000046512606202452022222 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: cdef int tons cdef void add_tons(self, int x): pass cdef class SuperSpam(Spam): pass cdef void tomato(): cdef Spam spam cdef SuperSpam superspam = SuperSpam() spam = superspam spam.add_tons(42) superspam.add_tons(1764) tomato() Cython-0.23.4/tests/compile/extargdefault.pyx0000644000175600017570000000021312606202452022373 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern class somewhere.Swallow: pass cdef Swallow swallow def spam(x = swallow, Swallow y = swallow): pass Cython-0.23.4/tests/compile/excvalreturn.pyx0000644000175600017570000000010212606202452022253 0ustar jenkinsjenkins00000000000000# mode: compile cdef int spam() except -1: eggs = 42 spam() Cython-0.23.4/tests/compile/excvaldecl.pyx0000644000175600017570000000045212606202452021653 0ustar jenkinsjenkins00000000000000# mode: compile cdef int spam() except 42: pass cdef float eggs() except 3.14: pass cdef char *grail() except NULL: pass cdef int tomato() except *: pass cdef int brian() except? 0: pass cdef int silly() except -1: pass spam() eggs() grail() tomato() brian() silly() Cython-0.23.4/tests/compile/excvalcheck.pyx0000644000175600017570000000041712606202452022022 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern from "excvalcheck.h": pass cdef extern int spam() except -1 cdef extern void grail() except * cdef extern char *tomato() except? NULL cdef void eggs(): cdef int i cdef char *p i = spam() grail() p = tomato() eggs() Cython-0.23.4/tests/compile/excvalcheck.h0000644000175600017570000000040512606202452021426 0ustar jenkinsjenkins00000000000000#ifdef __cplusplus extern "C" { #endif extern DL_EXPORT(int) spam(void); extern DL_EXPORT(void) grail(void); extern DL_EXPORT(char *)tomato(void); #ifdef __cplusplus } #endif int spam(void) {return 0;} void grail(void) {return;} char *tomato(void) {return 0;} Cython-0.23.4/tests/compile/ewing9.pyx0000644000175600017570000000005712606202452020744 0ustar jenkinsjenkins00000000000000# mode: compile cdef struct xmlDoc: int i Cython-0.23.4/tests/compile/ewing9.pxd0000644000175600017570000000002312606202452020710 0ustar jenkinsjenkins00000000000000cdef struct xmlDoc Cython-0.23.4/tests/compile/ewing8.pyx0000644000175600017570000000005412606202452020740 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Blarg: pass Cython-0.23.4/tests/compile/ewing8.pxd0000644000175600017570000000024412606202452020714 0ustar jenkinsjenkins00000000000000cdef struct Foo cdef class Blarg ctypedef Foo FooType ctypedef Blarg BlargType cdef struct Foo: FooType *f cdef class Blarg: cdef FooType *f cdef BlargType b Cython-0.23.4/tests/compile/ewing7.pyx0000644000175600017570000000027712606202452020746 0ustar jenkinsjenkins00000000000000# mode: compile cdef class A: cdef void f(self, x): pass cdef class B(A): cdef void f(self, object x): pass cdef extern void g(A a, b) cdef extern void g(A a, b) Cython-0.23.4/tests/compile/ewing6.pyx0000644000175600017570000000056312606202452020743 0ustar jenkinsjenkins00000000000000# mode: compile # Spurious gcc3.3 warnings about incompatible pointer # types passed to C method # Ordering of declarations in C code is important cdef class C cdef class D(C) cdef class E cdef class C: cdef void a(self): pass cdef class D(C): cdef void m(self, E e): pass cdef class E: pass cdef void f(D d, E e): d.m(e) f(D(),E()) Cython-0.23.4/tests/compile/ewing5.pyx0000644000175600017570000000007212606202452020735 0ustar jenkinsjenkins00000000000000# mode: compile cdef char *f(): raise Exception f() Cython-0.23.4/tests/compile/ewing4.pyx0000644000175600017570000000011012606202452020725 0ustar jenkinsjenkins00000000000000# mode: compile cdef void f(): "This is a pseudo doc string." f() Cython-0.23.4/tests/compile/ewing3.pyx0000644000175600017570000000007612606202452020737 0ustar jenkinsjenkins00000000000000# mode: compile cdef class C: cdef f(self): pass Cython-0.23.4/tests/compile/ewing1.pyx0000644000175600017570000000022012606202452020724 0ustar jenkinsjenkins00000000000000# mode: compile cdef int blarg(int i): pass cdef void foo(): cdef float f=0 cdef int i if blarg( f): pass foo() Cython-0.23.4/tests/compile/eqcmp.pyx0000644000175600017570000000052712606202452020651 0ustar jenkinsjenkins00000000000000# mode: compile cdef void foo(): cdef int bool, int1=0, int2=0 cdef float float1=0, float2=0 cdef char *ptr1=NULL, *ptr2=NULL cdef int *ptr3 bool = int1 == int2 bool = int1 != int2 bool = float1 == float2 bool = ptr1 == ptr2 bool = int1 == float2 bool = ptr1 is ptr2 bool = ptr1 is not ptr2 foo() Cython-0.23.4/tests/compile/enumintcompat.pyx0000644000175600017570000000061012606202452022420 0ustar jenkinsjenkins00000000000000# mode: compile cdef enum E: a cdef enum G: b cdef void f(): cdef E e=a cdef G g=b cdef int i, j=0 cdef float f, h=0 i = j | e i = e | j i = j ^ e i = j & e i = j << e i = j >> e i = j + e i = j - e i = j * e i = j / e i = j % e # f = j ** e # Cython prohibits this i = e + g f = h i = ~a i = -a f() Cython-0.23.4/tests/compile/emptytry.pyx0000644000175600017570000000012512606202452021433 0ustar jenkinsjenkins00000000000000# mode: compile cdef void f(): try: pass finally: pass f() Cython-0.23.4/tests/compile/ellipsis_T488.pyx0000644000175600017570000000015712606202452022116 0ustar jenkinsjenkins00000000000000# ticket: 488 # mode: compile #from ... import foo print ... def test(): x = ... assert x is Ellipsis Cython-0.23.4/tests/compile/drake1.pyx0000644000175600017570000000005412606202452020706 0ustar jenkinsjenkins00000000000000# mode: compile cdef char *s s = r'\"HT\"' Cython-0.23.4/tests/compile/dotted_cimport.pyx0000644000175600017570000000012612606202452022557 0ustar jenkinsjenkins00000000000000# mode: compile cimport dotted_cimport_submodule.a import dotted_cimport_submodule.b Cython-0.23.4/tests/compile/doda1.pyx0000644000175600017570000000026212606202452020530 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Spam: pass cdef Spam foo(): return blarg() #cdef Spam grail #grail = blarg() #return grail cdef object blarg(): pass foo() Cython-0.23.4/tests/compile/docstrings.pyx0000644000175600017570000000044012606202452021715 0ustar jenkinsjenkins00000000000000# mode: compile "Welcome to the parrot module. It is currently resting." def zap(polly, volts): "Wake up polly." class Parrot: "Standard Norwegian Blue." def admire_plumage(self): "Lovely, ain't it?" cdef class SuperParrot: "Special high-performance model." Cython-0.23.4/tests/compile/distutils_libraries_T845.srctree0000644000175600017570000000123712606202452025176 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace ######## setup.py ######## from Cython.Build import cythonize from Cython.Distutils.extension import Extension ext_modules = [ Extension("a", ["a.pyx"]), Extension("x", ["x.pyx"]), Extension("y", ["y.pyx"]), ] ext_modules = cythonize(ext_modules) assert len(ext_modules[0].libraries) == 2 assert ext_modules[1].libraries == ["lib_x"] assert ext_modules[2].libraries == ["lib_y"] ######## libx.pxd ######## # distutils: libraries = lib_x ######## liby.pxd ######## # distutils: libraries = lib_y ######## a.pyx ######## cimport libx , liby ######## x.pyx ######## cimport libx ######## y.pyx ######## cimport liby Cython-0.23.4/tests/compile/del.pyx0000644000175600017570000000016612606202452020307 0ustar jenkinsjenkins00000000000000# mode: compile def f(a, b): global g del g del a[b] del a[b][42] del a.spam del a.spam.eggs Cython-0.23.4/tests/compile/declarations.srctree0000644000175600017570000000433112606202452023040 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import declarations" ######## setup.py ######## from distutils.core import setup from Cython.Distutils import build_ext from Cython.Distutils.extension import Extension setup( ext_modules = [ Extension("declarations", ["declarations.pyx", "external_declarations.c"]), ], cmdclass={'build_ext': build_ext}, ) ######## declarations.pyx ######## # mode: compile cdef extern from "external_declarations.h": pass cdef extern char *cp cdef extern char *cpa[5] cdef extern int (*ifnpa[5])() cdef extern char *(*cpfnpa[5])() cdef extern int (*ifnp)() cdef extern int (*iap)[5] cdef extern int ifn() cdef extern char *cpfn() cdef extern int (*iapfn())[5] cdef extern char *(*cpapfn())[5] cdef extern int fnargfn(int ()) cdef extern int ia[] cdef extern int iaa[][3] cdef extern int a(int[][3], int[][3][5]) cdef void f(): cdef void *p=NULL global ifnp, cpa ifnp = p cdef char *g(): pass f() g() ######## external_declarations.h ######## #ifndef DL_IMPORT #define DL_IMPORT(t) t #endif #ifdef __cplusplus extern "C" { #endif extern DL_IMPORT(char) *cp; extern DL_IMPORT(char) *cpa[5]; extern DL_IMPORT(int) (*ifnpa[5])(void); extern DL_IMPORT(char) *(*cpfnpa[5])(void); extern DL_IMPORT(int) (*ifnp)(void); extern DL_IMPORT(int) (*iap)[5]; #ifdef __cplusplus } #endif #ifdef __cplusplus extern "C" { #endif extern DL_IMPORT(int) ifn(void); extern DL_IMPORT(char *) cpfn(void); extern DL_IMPORT(int) fnargfn(int (void)); extern DL_IMPORT(int) (*iapfn(void))[5]; extern DL_IMPORT(char *)(*cpapfn(void))[5]; extern DL_IMPORT(int) ia[]; extern DL_IMPORT(int) iaa[][3]; extern DL_IMPORT(int) a(int[][3], int[][3][5]); #ifdef __cplusplus } #endif ######## external_declarations.c ######## #include #ifndef DL_EXPORT #define DL_EXPORT(t) t #endif DL_EXPORT(char) *cp; DL_EXPORT(char) *cpa[5]; DL_EXPORT(int) (*ifnpa[5])(void); DL_EXPORT(char) *(*cpfnpa[5])(void); DL_EXPORT(int) (*ifnp)(void); DL_EXPORT(int) (*iap)[5]; DL_EXPORT(int) ifn(void) {return 0;} DL_EXPORT(char) *cpfn(void) {return 0;} DL_EXPORT(int) fnargfn(int f(void)) {return 0;} DL_EXPORT(int) ia[1]; DL_EXPORT(int) iaa[1][3]; DL_EXPORT(int) a(int a[][3], int b[][3][5]) {return 0;} Cython-0.23.4/tests/compile/declandimpl.pyx0000644000175600017570000000021112606202452022006 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Tomato: def eject(self): pass cdef extern Sandwich butty cdef Tomato supertom supertom = None Cython-0.23.4/tests/compile/declandimpl.pxd0000644000175600017570000000011512606202452021764 0ustar jenkinsjenkins00000000000000cdef struct Sandwich: int i char *s cdef class Tomato: cdef float danger Cython-0.23.4/tests/compile/cverylongtypes.pyx0000644000175600017570000000016412606202452022636 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern short int s cdef extern long int l cdef extern long long ll cdef extern long double ld Cython-0.23.4/tests/compile/cvardef.pyx0000644000175600017570000000244412606202452021156 0ustar jenkinsjenkins00000000000000# mode: compile # tag: cdef def f(): cdef char a_char cdef short a_short cdef int i1, i2 cdef long a_long cdef float a_float cdef double a_double cdef unsigned char an_unsigned_char cdef unsigned short an_unsigned_short cdef unsigned int an_unsigned_int cdef unsigned long an_unsigned_long cdef char *a_char_ptr, *another_char_ptr cdef char **a_char_ptr_ptr cdef char ***a_char_ptr_ptr_ptr cdef char[10] a_sized_char_array cdef char[10][20] a_2d_char_array cdef char *a_2d_char_ptr_array[10][20] cdef char **a_2d_char_ptr_ptr_array[10][20] cdef int (*a_0arg_function)() cdef int (*a_1arg_function)(int i) cdef int (*a_2arg_function)(int i, int j) cdef void (*a_void_function)() a_char = 0 a_short = 0 i1 = 0 i2 = 0 a_long = 0 a_float = 0 a_double = 0 an_unsigned_char = 0 an_unsigned_short = 0 an_unsigned_int = 0 an_unsigned_long = 0 a_char_ptr = NULL another_char_ptr = NULL a_char_ptr_ptr = NULL a_char_ptr_ptr_ptr = NULL a_sized_char_array[0] = 0 a_2d_char_array[0][0] = 0 a_2d_char_ptr_array[0][0] = NULL a_2d_char_ptr_ptr_array[0][0] = NULL a_0arg_function = NULL a_1arg_function = NULL a_2arg_function = NULL a_void_function = NULL Cython-0.23.4/tests/compile/cunsignedlong.pyx0000644000175600017570000000014612606202452022400 0ustar jenkinsjenkins00000000000000# mode: compile cdef void f(): cdef unsigned long x cdef object y=0 x = y y = x f() Cython-0.23.4/tests/compile/ctypedefunion.pyx0000644000175600017570000000015112606202452022411 0ustar jenkinsjenkins00000000000000# mode: compile ctypedef union pet: int cat float dog cdef pet sam sam.cat = 1 sam.dog = 2.7 Cython-0.23.4/tests/compile/ctypedefstruct.pyx0000644000175600017570000000025212606202452022607 0ustar jenkinsjenkins00000000000000# mode: compile ctypedef struct order: int spam int eggs cdef order order1 order1.spam = 7 order1.eggs = 2 ctypedef struct linked: int a linked *next Cython-0.23.4/tests/compile/ctypedefpubapi.pyx0000644000175600017570000000043112606202452022542 0ustar jenkinsjenkins00000000000000# mode: compile ctypedef public api class Foo [type PyFoo_Type, object PyFooObject]: pass cdef api: ctypedef public class Bar [type PyBar_Type, object PyBarObject]: pass cdef public api: ctypedef class Baz [type PyBaz_Type, object PyBazObject]: pass Cython-0.23.4/tests/compile/ctypedefenum.pyx0000644000175600017570000000016012606202452022225 0ustar jenkinsjenkins00000000000000# mode: compile ctypedef enum parrot_state: alive = 1 dead = 2 cdef parrot_state polly polly = dead Cython-0.23.4/tests/compile/ctypedefclass.pyx0000644000175600017570000000010612606202452022366 0ustar jenkinsjenkins00000000000000# mode: compile ctypedef class spam: pass cdef spam s s = None Cython-0.23.4/tests/compile/ctypedef_public_class_T355.pyx0000644000175600017570000000045312606202452024610 0ustar jenkinsjenkins00000000000000# ticket: 355 # mode: compile ctypedef public class Time [type MyTime_Type, object MyTimeObject]: def __init__(self, seconds): self.seconds = seconds ctypedef public class Event [type MyEvent_Type, object MyEventObject]: def __init__(self, Time time): self.time = time Cython-0.23.4/tests/compile/ctypedef_public_class_T355.pxd0000644000175600017570000000030712606202452024561 0ustar jenkinsjenkins00000000000000ctypedef public class Time [type MyTime_Type, object MyTimeObject]: cdef public double seconds ctypedef public class Event [type MyEvent_Type, object MyEventObject]: cdef public Time time Cython-0.23.4/tests/compile/ctypedef.pyx0000644000175600017570000000016312606202452021343 0ustar jenkinsjenkins00000000000000# mode: compile ctypedef int *IntPtr ctypedef unsigned long ULong cdef extern IntPtr spam cdef extern ULong grail Cython-0.23.4/tests/compile/cstructreturn.pyx0000644000175600017570000000022012606202452022461 0ustar jenkinsjenkins00000000000000# mode: compile ctypedef struct Foo: int blarg cdef Foo f(): blarg = 1 + 2 cdef Foo foo foo.blarg = blarg return foo f() Cython-0.23.4/tests/compile/crunchytype.pxd0000644000175600017570000000022012606202452022062 0ustar jenkinsjenkins00000000000000cdef extern from "crunchytype.h": cdef class crunchytype.Crunchy [ object CrunchyType ]: cdef int number cdef object string Cython-0.23.4/tests/compile/crunchytype.h0000644000175600017570000000007312606202452021524 0ustar jenkinsjenkins00000000000000 struct CrunchyType { int number; PyObject* string; }; Cython-0.23.4/tests/compile/cpp_templates.pyx0000644000175600017570000000221212606202452022375 0ustar jenkinsjenkins00000000000000# tag: cpp # mode: compile # ticket: 767 cdef extern from "templates.h": cdef cppclass TemplateTest1[T]: TemplateTest1() T value int t T getValue() cdef cppclass TemplateTest2[T, U]: TemplateTest2() T value1 U value2 T getValue1() U getValue2() void template_function[T](TemplateTest1[T] &) cdef TemplateTest1[int] a cdef TemplateTest1[int]* b = new TemplateTest1[int]() cdef int c = a.getValue() c = b.getValue() cdef TemplateTest2[int, char] d cdef TemplateTest2[int, char]* e = new TemplateTest2[int, char]() c = d.getValue1() c = e.getValue2() cdef char f = d.getValue2() f = e.getValue2() del b, e ctypedef TemplateTest1[int] TemplateTest1_int cdef TemplateTest1_int aa # Verify that T767 is fixed. cdef public int func(int arg): return arg # Regression test: the function call used to produce # template_function>(__pyx_v_t); # which is valid C++11, but not valid C++98 because the ">>" would be # parsed as a single token. cdef public void use_nested_templates(): cdef TemplateTest1[TemplateTest1[int]] t template_function(t) Cython-0.23.4/tests/compile/cpp_templated_ctypedef.pyx0000644000175600017570000000016412606202452024245 0ustar jenkinsjenkins00000000000000# tag: cpp # mode: compile cdef extern from *: cdef cppclass Foo[T]: pass ctypedef Foo[int] IntFoo Cython-0.23.4/tests/compile/cpp_structs.pyx0000644000175600017570000000031212606202452022105 0ustar jenkinsjenkins00000000000000# tag: cpp # mode: compile cdef extern from "point.h" namespace "geometry": cdef struct Point: double x double y int color cdef Point p = Point(0.0, 0.0, 0) the_point = p Cython-0.23.4/tests/compile/cpp_nogil.pyx0000644000175600017570000000066012606202452021514 0ustar jenkinsjenkins00000000000000# tag: cpp # mode: compile cdef extern from "cpp_nogil.h" nogil: cdef cppclass NoGilTest1: NoGilTest1() void doSomething() # This is declared in cpp_nogil.h, but here we're testing # that we can put nogil directly on the cppclass. cdef extern from *: cdef cppclass NoGilTest2 nogil: NoGilTest2() void doSomething() with nogil: NoGilTest1().doSomething() NoGilTest2().doSomething() Cython-0.23.4/tests/compile/cpp_nogil.h0000644000175600017570000000020712606202452021120 0ustar jenkinsjenkins00000000000000struct NoGilTest1 { NoGilTest1() { } void doSomething() { } }; struct NoGilTest2 { NoGilTest2() { } void doSomething() { } }; Cython-0.23.4/tests/compile/cpp_enums.pyx0000644000175600017570000000051312606202452021530 0ustar jenkinsjenkins00000000000000# tag: cpp # mode: compile cdef extern from "cpp_enums.h": cdef enum Enum1: Item1 Item2 a = Item1 b = Item2 cdef Enum1 x, y x = Item1 y = Item2 cdef extern from "cpp_enums.h" namespace "Namespace1": cdef enum Enum2: Item3 Item4 c = Item3 d = Item4 cdef Enum2 z, w z = Item3 w = Item4 Cython-0.23.4/tests/compile/cpp_enums.h0000644000175600017570000000014412606202452021137 0ustar jenkinsjenkins00000000000000enum Enum1 { Item1, Item2 }; namespace Namespace1 { enum Enum2 { Item3, Item4 }; } Cython-0.23.4/tests/compile/cpp_class_redefinition.pyx0000644000175600017570000000032012606202452024241 0ustar jenkinsjenkins00000000000000# tag: cpp # mode: compile cdef extern from "templates.h": cdef cppclass TemplateTest1[T]: TemplateTest1() T value int t T getValue() cdef cppclass TemplateTest1[T] Cython-0.23.4/tests/compile/cpdef.pyx0000644000175600017570000000013512606202452020620 0ustar jenkinsjenkins00000000000000# mode: compile cdef class A: cpdef a(self): ma(self) cpdef ma(x): print x Cython-0.23.4/tests/compile/coventry1.pyx0000644000175600017570000000005712606202452021474 0ustar jenkinsjenkins00000000000000# mode: compile cdef class Tst: cdef foo, Cython-0.23.4/tests/compile/constexpr.pyx0000644000175600017570000000016112606202452021563 0ustar jenkinsjenkins00000000000000# mode: compile cdef enum Grail: k = 42 cdef enum Spam: a = -1 b = 2 + 3 c = 42 > 17 d = k Cython-0.23.4/tests/compile/constcast.pyx0000644000175600017570000000024412606202452021541 0ustar jenkinsjenkins00000000000000# mode: compile from libc.stdlib cimport malloc, free cdef void f(): cdef const int **allocated = malloc(sizeof(int *)) free(allocated) f() Cython-0.23.4/tests/compile/const_decl.pyx0000644000175600017570000000052012606202452021652 0ustar jenkinsjenkins00000000000000# mode: compile cdef const_args(const int a, const int *b, const (int*) c, int *const d): print a print b[0] b = NULL # OK, the pointer itself is not const c[0] = 4 # OK, the value is not const d[0] = 7 # OK, the value is not const def call_const_args(x): cdef int k = x const_args(x, &k, &k, &k) Cython-0.23.4/tests/compile/const_T42.srctree0000644000175600017570000000121412606202452022144 0ustar jenkinsjenkins00000000000000# tag: cpp PYTHON setup.py build_ext --inplace PYTHON -c "import test" ######## test.pyx ######## # distutils: language = c++ cdef extern from "test.h": ctypedef struct c_Test "Test": const char *getString() except +RuntimeError cdef class Test: cdef c_Test *thisptr def getString(self): return self.thisptr.getString() ######## test.h ######## static const char *astring = "123"; class Test { public: const char *getString(void) { return astring; } }; ######## setup.py ######## from distutils.core import setup from Cython.Build.Dependencies import cythonize setup(name='test', ext_modules=cythonize('*.pyx')) Cython-0.23.4/tests/compile/complexbasetype.pyx0000644000175600017570000000016212606202452022743 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern (int *[42]) spam, grail, swallow cdef (int (*)()) brian(): return NULL brian() Cython-0.23.4/tests/compile/coercetovoidptr.pyx0000644000175600017570000000012612606202452022752 0ustar jenkinsjenkins00000000000000# mode: compile cdef void f(): cdef void *p cdef char *q=NULL p = q f() Cython-0.23.4/tests/compile/cnumop.pyx0000644000175600017570000000045312606202452021043 0ustar jenkinsjenkins00000000000000# mode: compile def f(): cdef int int1, int2=0, int3=1 cdef char char1=0 cdef long long1, long2=0 cdef float float1, float2=0 cdef double double1 int1 = int2 * int3 int1 = int2 / int3 long1 = long2 * char1 float1 = int1 * float2 double1 = float1 * int2 f() Cython-0.23.4/tests/compile/cnamespec.pyx0000644000175600017570000000067312606202452021504 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern from "cnamespec.h": int a "c_a", b "c_b" cdef struct foo "c_foo": int i "c_i" ctypedef enum blarg "c_blarg": x "c_x" y "c_y" = 42 cdef double spam "c_spam" (int i, float f): cdef double d "c_d" cdef foo *p global b d = spam(a, f) cdef foo q q.i = 7 p = &q b = p.i p.i = x p.i = y cdef inline double spam2 "c_spam2" (int i, float f): return spam(i,f) Cython-0.23.4/tests/compile/cnamespec.h0000644000175600017570000000001612606202452021102 0ustar jenkinsjenkins00000000000000int c_a, c_b; Cython-0.23.4/tests/compile/classmethargdefault.pyx0000644000175600017570000000061312606202452023562 0ustar jenkinsjenkins00000000000000# mode: compile __doc__ = u""" >>> s = Swallow() >>> s.spam(1) 1 42 'grail' True >>> s.spam(1, 2) 1 2 'grail' True >>> s.spam(1, z = 2) 1 42 'grail' 2 >>> s.spam(1, y = 2) 1 42 2 True >>> s.spam(1, x = 2, y = 'test') 1 2 'test' True """ swallow = True class Swallow: def spam(w, int x = 42, y = "grail", z = swallow): print w, x, y, z Cython-0.23.4/tests/compile/cimportfrom_T248.pyx0000644000175600017570000000032612606202452022623 0ustar jenkinsjenkins00000000000000# ticket: 248 # mode: compile from ewing8 cimport (Foo, Blarg) from declandimpl cimport (Sandwich , Tomato) cdef extern Foo yummy Cython-0.23.4/tests/compile/cimport_package_module_T4.pyx0000644000175600017570000000011212606202452024576 0ustar jenkinsjenkins00000000000000# ticket: 4 # mode: compile from a cimport b cdef int **t = b.foo(NULL) Cython-0.23.4/tests/compile/cheese.h0000644000175600017570000000000012606202452020371 0ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/compile/cforfromloop.pyx0000644000175600017570000000067612606202452022260 0ustar jenkinsjenkins00000000000000# mode: compile cdef int i, j, k cdef object a, b, x for i from 0 <= i < 10: pass for i from 0 < i <= 10: pass for i from 10 >= i > 0: pass for i from 10 > i >= 0: pass for x from 0 <= x <= 10: pass for i from a <= i <= b: pass for i from k <= i <= j: pass for i from k * 42 <= i <= j / 18: pass while j: for i from 0 <= i <= 10: continue break else: continue break Cython-0.23.4/tests/compile/cenum.pyx0000644000175600017570000000025312606202452020647 0ustar jenkinsjenkins00000000000000# mode: compile cdef enum Spam: a b, c, d, e, f g = 42 cdef void eggs(): cdef Spam s1, s2=a cdef int i s1 = s2 s1 = c i = s1 eggs() Cython-0.23.4/tests/compile/cdefexternfromstar.pyx0000644000175600017570000000006312606202452023444 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern from *: int spam Cython-0.23.4/tests/compile/cdefexternempty.pyx0000644000175600017570000000007012606202452022743 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern from "cheese.h": pass Cython-0.23.4/tests/compile/cdef_syntax.pyx0000644000175600017570000000025712606202452022053 0ustar jenkinsjenkins00000000000000# mode: compile # the following are valid syntax constructs and should not produce errors ctypedef int x; cdef no_semi(): cdef int i cdef with_semi(): cdef int i; Cython-0.23.4/tests/compile/casttoexttype.pyx0000644000175600017570000000027712606202452022466 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern class external.Spam: pass cdef void foo(object x): pass cdef void blarg(void *y, object z): foo(y) foo(z) blarg(None, None) Cython-0.23.4/tests/compile/cast_ctypedef_array_T518_helper.h0000644000175600017570000000030212606202452025235 0ustar jenkinsjenkins00000000000000struct __foo_struct { int i, j; }; typedef struct __foo_struct foo_t[1]; static void foo_init (foo_t v) { v[0].i = 0; v[0].j = 0; } static void foo_clear (foo_t v) { v[0].i = 0; v[0].j = 0; } Cython-0.23.4/tests/compile/cast_ctypedef_array_T518.pyx0000644000175600017570000000054412606202452024277 0ustar jenkinsjenkins00000000000000# ticket: 518 # mode: compile cdef extern from "cast_ctypedef_array_T518_helper.h": cdef struct __foo_struct: int i, j ctypedef __foo_struct foo_t[1] void foo_init(foo_t) void foo_clear(foo_t) cdef foo_t value foo_init(value) foo_clear(value) cdef void *pointer = value foo_init(pointer) foo_clear(pointer) Cython-0.23.4/tests/compile/cassign.pyx0000644000175600017570000000036412606202452021172 0ustar jenkinsjenkins00000000000000# mode: compile cdef void foo(): cdef int i1, i2=0 cdef char c1=0, c2 cdef char *p1, *p2=NULL cdef object obj1 i1 = i2 i1 = c1 p1 = p2 obj1 = i1 i1 = obj1 p1 = obj1 p1 = "spanish inquisition" foo() Cython-0.23.4/tests/compile/cascmp.pyx0000644000175600017570000000055412606202452021012 0ustar jenkinsjenkins00000000000000# mode: compile cdef void foo(): cdef int bool, int1=0, int2=0, int3=0, int4=0 cdef object obj1, obj2, obj3, obj4 obj1 = 1 obj2 = 2 obj3 = 3 obj4 = 4 bool = int1 < int2 < int3 bool = obj1 < obj2 < obj3 bool = int1 < int2 < obj3 bool = obj1 < 2 < 3 bool = obj1 < 2 < 3 < 4 bool = int1 < (int2 == int3) < int4 foo() Cython-0.23.4/tests/compile/carrdecl.pyx0000644000175600017570000000006312606202452021316 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern: cdef func(int[]) Cython-0.23.4/tests/compile/cargdef.pyx0000644000175600017570000000037312606202452021136 0ustar jenkinsjenkins00000000000000# mode: compile def f(obj, int i, double f, char *s1, char s2[]): pass cdef g(obj, int i, double f, char *s1, char s2[]): pass cdef do_g(object (*func)(object, int, double, char*, char*)): return func(1, 2, 3.14159, "a", "b") do_g(&g) Cython-0.23.4/tests/compile/callingconvention.srctree0000644000175600017570000000357612606202452024116 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import callingconvention" ######## setup.py ######## from distutils.core import setup from Cython.Distutils import build_ext from Cython.Distutils.extension import Extension setup( ext_modules = [ Extension("callingconvention", ["callingconvention.pyx", "external_callingconvention.c"]), ], cmdclass={'build_ext': build_ext}, ) ######## callingconvention.pyx ######## # mode: compile cdef extern from "external_callingconvention.h": pass cdef extern int f1() cdef extern int __cdecl f2() cdef extern int __stdcall f3() cdef extern int __fastcall f4() cdef extern int (*p1)() cdef extern int (__cdecl *p2)() cdef extern int (__stdcall *p3)() cdef extern int (__fastcall *p4)() p1 = f1 p2 = f2 p3 = f3 p4 = f4 ######## external_callingconvention.h ######## #ifndef DL_IMPORT #define DL_IMPORT(t) t #endif #ifdef __cplusplus extern "C" { #endif extern DL_IMPORT(int) f1(void); extern DL_IMPORT(int) __cdecl f2(void); extern DL_IMPORT(int) __stdcall f3(void); extern DL_IMPORT(int) __fastcall f4(void); extern DL_IMPORT(int) (*p1)(void); extern DL_IMPORT(int) (__cdecl *p2)(void); extern DL_IMPORT(int) (__stdcall *p3)(void); extern DL_IMPORT(int) (__fastcall *p4)(void); #ifdef __cplusplus } #endif ######## external_callingconvention.c ######## #include #ifndef DL_EXPORT #define DL_EXPORT(t) t #endif #if !defined(WIN32) && !defined(MS_WINDOWS) #ifndef __stdcall #define __stdcall #endif #ifndef __cdecl #define __cdecl #endif #ifndef __fastcall #define __fastcall #endif #endif DL_EXPORT(int) f1(void) {return 0;} DL_EXPORT(int) __cdecl f2(void) {return 0;} DL_EXPORT(int) __stdcall f3(void) {return 0;} DL_EXPORT(int) __fastcall f4(void) {return 0;} DL_EXPORT(int) (*p1)(void); DL_EXPORT(int) (__cdecl *p2)(void); DL_EXPORT(int) (__stdcall *p3)(void); DL_EXPORT(int) (__fastcall *p4)(void); Cython-0.23.4/tests/compile/c_directives.pyx0000644000175600017570000000155012606202452022204 0ustar jenkinsjenkins00000000000000# mode: compile # cython: boundscheck = False # cython: ignoreme = OK # cython: warn.undeclared = False # This testcase is most useful if you inspect the generated C file print 3 cimport cython as cy def e(object[int, ndim=2] buf): print buf[3, 2] # no bc @cy.boundscheck(False) def f(object[int, ndim=2] buf): print buf[3, 2] # no bc @cy.boundscheck(True) def g(object[int, ndim=2] buf): # The below line should have no meaning # cython: boundscheck = False # even if the above line doesn't follow indentation. print buf[3, 2] # bc def h(object[int, ndim=2] buf): print buf[3, 2] # no bc with cy.boundscheck(True): print buf[3,2] # bc from cython cimport boundscheck as bc def i(object[int] buf): with bc(True): print buf[3] # bs from cython cimport warn as my_warn @my_warn(undeclared=True) def j(): pass Cython-0.23.4/tests/compile/burton1.pyx.BROKEN0000644000175600017570000000011612606202452022107 0ustar jenkinsjenkins00000000000000cdef void f(): cdef void (*p)() p = 0 (p)() Cython-0.23.4/tests/compile/builtinlist.pyx0000644000175600017570000000044312606202452022103 0ustar jenkinsjenkins00000000000000# mode: compile cdef int f() except -1: cdef list l cdef object x = (), y = (1,), z z = list l = list(x) l = list(*y) z = l.insert l.insert(17, 42) l.append(88) l.sort() l.reverse() z = l.as_tuple() return z is not None def test(): f() Cython-0.23.4/tests/compile/builtinfuncs.pyx0000644000175600017570000000130212606202452022241 0ustar jenkinsjenkins00000000000000# mode: compile cdef int f() except -1: cdef object x, y = 0, z = 0, w = 0 cdef str sstring cdef basestring sustring cdef int i cdef long lng cdef Py_ssize_t s x = abs(y) delattr(x, 'spam') x = dir(y) x = divmod(y, z) x = getattr(y, 'spam') i = hasattr(y, 'spam') lng = hash(y) x = intern(y) i = isinstance(y, z) i = issubclass(y, z) x = iter(y) s = len(x) x = open(y, z) x = pow(y, z, w) x = pow(y, z) x = reload(y) x = repr(y) sstring = repr(x) sustring = repr(x) setattr(x, y, z) #i = typecheck(x, y) #i = issubtype(x, y) x = abs def not_called(): response = raw_input('xyz') f() Cython-0.23.4/tests/compile/builtin.pyx0000644000175600017570000000005612606202452021207 0ustar jenkinsjenkins00000000000000# mode: compile def f(): x = open("foo") Cython-0.23.4/tests/compile/belchenko2.pyx.BROKEN0000644000175600017570000000031112606202452022526 0ustar jenkinsjenkins00000000000000cdef extern from "belchenko2.h": void c_func(unsigned char pixel) def f(unsigned char pixel): c_func(pixel) def g(signed char pixel): c_func(pixel) def h(char pixel): c_func(pixel) Cython-0.23.4/tests/compile/belchenko2.h0000644000175600017570000000004212606202452021157 0ustar jenkinsjenkins00000000000000void c_func(unsigned char pixel); Cython-0.23.4/tests/compile/belchenko1.pyx0000644000175600017570000000025212606202452021552 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern from *: ctypedef int intptr_t cdef int _is_aligned(void *ptr): return ((ptr) & ((sizeof(int))-1)) == 0 _is_aligned(NULL) Cython-0.23.4/tests/compile/behnel4.pyx0000644000175600017570000000013312606202452021056 0ustar jenkinsjenkins00000000000000# mode: compile cdef enum E: spam, eggs cdef E f() except spam: return eggs f() Cython-0.23.4/tests/compile/assert2.pyx0000644000175600017570000000006012606202452021117 0ustar jenkinsjenkins00000000000000# mode: compile def f(a, b): assert a, a+b Cython-0.23.4/tests/compile/ass2longlong.pyx0000644000175600017570000000024312606202452022147 0ustar jenkinsjenkins00000000000000# mode: compile cdef void spam(): cdef long long L cdef unsigned long long U cdef object x = object() L = x x = L U = x x = U spam() Cython-0.23.4/tests/compile/arraytoptrarg.pyx0000644000175600017570000000015212606202452022437 0ustar jenkinsjenkins00000000000000# mode: compile cdef void f1(char *argv[]): f2(argv) cdef void f2(char *argv[]): pass f1(NULL) Cython-0.23.4/tests/compile/arrayptrcompat.pyx0000644000175600017570000000036412606202452022613 0ustar jenkinsjenkins00000000000000# mode: compile cdef enum E: z cdef void f(): cdef int *p cdef void *v cdef int[5] a cdef int i=0 cdef E e=z p = a v = a p = a + i p = a + e p = i + a p = e + a p = a - i p = a - e f() Cython-0.23.4/tests/compile/arrayargs.pyx0000644000175600017570000000062312606202452021534 0ustar jenkinsjenkins00000000000000# mode: compile cdef extern from *: cdef void foo(int[]) ctypedef int MyInt cdef void foo(MyInt[]) struct MyStruct: pass cdef void bar(MyStruct[]) ctypedef MyStruct* MyStructP cdef void baz(MyStructP[]) cdef struct OtherStruct: int a a = sizeof(int[23][34]) b = sizeof(OtherStruct[43]) DEF COUNT = 4 c = sizeof(int[COUNT]) d = sizeof(OtherStruct[COUNT]) Cython-0.23.4/tests/compile/argdefault.pyx0000644000175600017570000000013412606202452021654 0ustar jenkinsjenkins00000000000000# mode: compile cdef swallow def spam(w, int x = 42, y = "grail", z = swallow): pass Cython-0.23.4/tests/compile/altet1.pyx.BROKEN0000644000175600017570000000033112606202452021706 0ustar jenkinsjenkins00000000000000__doc__ = """ >>> flub(25) 25 >>> g() 0 """ cdef extern from "altet1.h": ctypedef int blarg cdef blarg globvar def flub(blarg bobble): print bobble globvar = 0 def g(): return globvar Cython-0.23.4/tests/compile/altet1.h0000644000175600017570000000002412606202452020335 0ustar jenkinsjenkins00000000000000typedef int blarg; Cython-0.23.4/tests/compile/a_capi.pyx0000644000175600017570000000072312606202452020756 0ustar jenkinsjenkins00000000000000# mode: compile cdef public struct Foo: int a, b ctypedef struct Blarg: int c, d ctypedef public Foo Zax cdef public class C[type C_Type, object C_Obj]: pass cdef public Zax *blarg cdef public C c_pub = C() cdef api C c_api = C() cdef public dict o_pub = C() cdef api list o_api = C() cdef api float f(Foo *x): pass cdef public void g(Blarg *x): pass cdef public api void h(Zax *x): pass cdef extern from "a_capi.h": pass Cython-0.23.4/tests/compile/dotted_cimport_submodule/0000755000175600017570000000000012606202455024100 5ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/compile/dotted_cimport_submodule/a.pxd0000644000175600017570000000000012606202452025020 0ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/compile/dotted_cimport_submodule/__init__.pyx0000644000175600017570000000001512606202452026372 0ustar jenkinsjenkins00000000000000# empty file Cython-0.23.4/tests/compile/a/0000755000175600017570000000000012606202455017221 5ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/compile/a/b.pxd0000644000175600017570000000002612606202452020152 0ustar jenkinsjenkins00000000000000cdef int **foo(void*) Cython-0.23.4/tests/compile/a/__init__.py0000644000175600017570000000001512606202452021323 0ustar jenkinsjenkins00000000000000# empty file Cython-0.23.4/tests/build/0000755000175600017570000000000012606202455016450 5ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/build/package_compilation.srctree0000644000175600017570000000226212606202452024031 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import toppkg; assert '.py' not in toppkg.__file__; assert toppkg.PACKAGE == 1" PYTHON -c "import toppkg.subpkg; assert '.py' not in toppkg.__file__; assert '.py' not in toppkg.subpkg.__file__; assert toppkg.subpkg.PACKAGE == 2" PYTHON -c "import toppkg.a; assert toppkg.a.MODULE == 'a'" PYTHON -c "from toppkg.subpkg import a; assert a.MODULE == 'subpkg.a'" ######## setup.py ######## from Cython.Build import cythonize from distutils.core import setup setup( ext_modules = cythonize("toppkg/**/*.py"), ) ######## toppkg/__init__.py ######## import sys assert 'toppkg' in sys.modules assert __path__ is not None, "__path__ is None" assert __path__, "__path__ is empty" assert 'toppkg' in __path__[0], "toppkg not in __path__[0]" assert 'toppkg' in __file__ from . import a assert a.MODULE == 'a' from . import b assert b.MODULE == 'b' PACKAGE = 1 ######## toppkg/a.py ######## MODULE = 'a' ######## toppkg/b.py ######## MODULE = 'b' ######## toppkg/subpkg/__init__.py ######## PACKAGE = 2 from . import a assert a.__name__ == 'toppkg.subpkg.a' assert a.MODULE == 'subpkg.a' ######## toppkg/subpkg/a.py ######## MODULE = 'subpkg.a' Cython-0.23.4/tests/build/module_api.srctree0000644000175600017570000000457112606202452022163 0ustar jenkinsjenkins00000000000000# tag: cpp PYTHON setup.py build_ext --inplace PYTHON test.py ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup exts = cythonize("*.pyx") for e in exts: if e.name == "d": e.sources.append("a.c") setup( ext_modules = exts, ) ######## a.pxd ######## ctypedef api float flt cdef int int0 cdef float flt0 cdef api int int1 cdef api float flt1 cdef public api int int2 cdef public api flt flt2 cdef class A0: pass ctypedef api class A1 [ type A1_Type, object A1Object ]: pass ctypedef public api class A2 [ type A2_Type, object A2Object ]: pass cdef A0 a0 cdef api A1 a1 cdef public api A2 a2 ######## a.pyx ######## cdef int int0 = 1, int1 = 1, int2 = 1 cdef float flt0 = 1, flt1 = 1, flt2 = 1 cdef api int int3 = 1 cdef api flt flt3 = 1 cdef public int int4 = 1 cdef public flt flt4 = 1 def get_int(): return (int0, int1, int2, int3, int4) def get_flt(): return (flt0, flt1, flt2, flt3, flt4) cdef class A0: pass cdef class A1: pass cdef class A2: pass cdef A0 a0 = A0() cdef api A1 a1 = A1() cdef public api A2 a2 = A2() ######## b.pyx ######## from a cimport * int0 = int1 = int2 = 7 flt0 = flt1 = flt2 = 7 ######## c.pyx ######## # distutils: language = c++ cdef extern from "a_api.h": int import_a() except -1 ctypedef float flt int int1, int2, int3 flt flt1, flt2, flt3 import_a() int1 = int2 = int3 = 5 flt1 = flt2 = flt3 = 5 ######## inita.h ######## #if PY_MAJOR_VERSION >= 3 void inita(void) { PyObject *sys_modules = NULL; PyObject *mod = NULL; sys_modules = PyImport_GetModuleDict(); if (!sys_modules) return; mod = PyInit_a(); if (!mod) return; PyDict_SetItemString(sys_modules, (char*)"a", mod); } #endif ######## d.pyx ######## cdef extern from "a.h": pass cdef extern from "inita.h": pass cdef extern from "a.h": void inita() except * ctypedef float flt int int2, int4 flt flt2, flt4 inita() int2 = int4 = 3 flt2 = flt4 = 3 ######## test.py ######## import a assert a.get_int() == (1,1,1,1,1) assert a.get_flt() == (1,1,1,1,1) import b assert a.get_int() == (7,7,7,1,1) assert a.get_flt() == (7,7,7,1,1) import c assert a.get_int() == (7,5,5,5,1) assert a.get_flt() == (7,5,5,5,1) import d import a assert a.get_int() == (1,1,3,1,3) assert a.get_flt() == (1,1,3,1,3) Cython-0.23.4/tests/build/inline_distutils.srctree0000644000175600017570000000122212606202452023415 0ustar jenkinsjenkins00000000000000# tag: cpp PYTHON setup.py build_ext --inplace PYTHON -c "import a" ######## setup.py ######## # TODO: Better interface... from Cython.Build.Dependencies import cythonize from distutils.core import setup import sys if sys.platform == 'win32': MATH_LIBS = [] else: MATH_LIBS = ['m'] setup( ext_modules = cythonize("*.pyx", aliases={'MATH_LIBS': MATH_LIBS}), ) ######## my_lib.pxd ######## # distutils: language = c++ # distutils: libraries = MATH_LIBS cdef extern from "my_lib_helper.cpp" namespace "A": int x ######## my_lib_helper.cpp ####### namespace A { int x = 100; }; ######## a.pyx ######## from my_lib cimport x print x Cython-0.23.4/tests/build/cythonize_script_package.srctree0000644000175600017570000000122612606202452025112 0ustar jenkinsjenkins00000000000000''' PYTHON -m Cython.Build.Cythonize -i pkg -j1 PYTHON package_test.py ''' ######## package_test.py ######## import sys if sys.version_info[0] < 3 or sys.version_info >= (3,3): # __init__.py compilation isn't supported in Py 3.[012] import pkg.sub.test assert pkg.sub.test.TEST == 'pkg.sub.test' assert '.py' not in pkg.sub.test.__file__ ######## test.py ######## TEST = 'test' ######## pkg/__init__.py ######## ######## pkg/test.py ######## TEST = 'pkg.test' ######## pkg/sub/__init__.py ######## ######## pkg/sub/test.py ######## # cython: language_level=3 TEST = 'pkg.sub.test' ustring = 'abc' assert isinstance(ustring, unicode) Cython-0.23.4/tests/build/cythonize_script_excludes.srctree0000644000175600017570000000223312606202452025332 0ustar jenkinsjenkins00000000000000PYTHON -m Cython.Build.Cythonize -i '**/*.pyx' -x '**/t/**/*.pyx' -x '**/m/**/*.pyx' PYTHON -c "import tests; assert tests.X.x == 2" ######## tests.py ######## import sys sys.path.append('src') import a.f.c.d.x as X assert X.x == 2 assert 'src/a/' in X.__file__ or 'src\\a\\' in X.__file__ try: import a.t.c.d.x except ImportError: pass else: assert False, "ImportError not raised - exclude of 't' package did not work" try: import a.m.c.d.x except ImportError: pass else: assert False, "ImportError not raised - exclude of 'm' package did not work" ######## src/a/__init__.py ######## ######## src/a/t/__init__.py ######## ######## src/a/t/c/__init__.py ######## ######## src/a/t/c/d/__init__.py ######## ######## src/a/t/c/d/x.pyx ######## x = 1 ######## src/a/__init__.py ######## ######## src/a/f/__init__.py ######## ######## src/a/f/c/__init__.py ######## ######## src/a/f/c/d/__init__.py ######## ######## src/a/f/c/d/x.pyx ######## x = 2 ######## src/a/__init__.py ######## ######## src/a/m/__init__.py ######## ######## src/a/m/c/__init__.py ######## ######## src/a/m/c/d/__init__.py ######## ######## src/a/m/c/d/x.pyx ######## x = 3 Cython-0.23.4/tests/build/cythonize_script.srctree0000644000175600017570000000151312606202452023436 0ustar jenkinsjenkins00000000000000''' PYTHON -m Cython.Build.Cythonize -i '**/*_test.py' PYTHON -c "import cy_test; assert cy_test.TEST == 'cy_test', cy_test.TEST; assert '.py' not in cy_test.__file__, cy_test.__file__" PYTHON -c "import pkg.cy_test; assert pkg.cy_test.TEST == 'pkg.cy_test', pkg.cy_test.TEST; assert '.py' not in pkg.cy_test.__file__, pkg.cy_test.__file__" PYTHON -c "import pkg.sub.cy_test; assert pkg.sub.cy_test.TEST == 'pkg.sub.cy_test', pkg.sub.cy_test.TEST; assert '.py' not in pkg.sub.cy_test.__file__, pkg.cy_test.__file__" ''' ######## cy_test.py ######## TEST = 'cy_test' ######## pkg/__init__.py ######## ######## pkg/cy_test.py ######## TEST = 'pkg.cy_test' ######## pkg/sub/__init__.py ######## ######## pkg/sub/cy_test.py ######## # cython: language_level=3 TEST = 'pkg.sub.cy_test' ustring = 'abc' assert isinstance(ustring, unicode) Cython-0.23.4/tests/build/cythonize_options.srctree0000644000175600017570000000076512606202452023635 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import a" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize("*.pyx", include_path=['subdir'], compiler_directives={'cdivision': True}), ) ######## a.pyx ######## cimport x include "y.pxi" # cdivision from setup.py def mod_int_c(int a, int b): return a % b assert mod_int_c(-1, 10) < 0 ######## subdir/x.pxd ######## ######## subdir/y.pxi ######## Cython-0.23.4/tests/build/cythonize_glob.srctree0000644000175600017570000000124312606202452023055 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import runner" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize("**/a*.pyx", include_path=['subdir'], compiler_directives={'cdivision': True}), ) ######## a.pyx ######## ######## p1/__init__.py ######## ######## p1/a.pyx ######## ######## p1/ab.pyx ######## ######## p1/b.pyx ######## ######## p1/p2/__init__.py ######## ######## p1/p2/a.pyx ######## ######## runner.py ######## import a import p1.a import p1.ab import p1.p2.a try: import p1.b assert False, "b should not be complied" except ImportError: pass Cython-0.23.4/tests/build/cythonize_additional_sources_ext.srctree0000644000175600017570000000120712606202452026665 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "from pkg import a; assert a.test() == 43" ######## setup.py ######## from Cython.Build import cythonize from distutils.core import setup, Extension extensions = [ Extension('pkg.a', sources=['pkg/a.pyx', 'pkg/alib.c'], include_dirs=['pkg']) ] setup( ext_modules = cythonize(extensions) ) ######## pkg/__init__.py ######## ######## pkg/a.pyx ######## cdef extern from "alib.h": int c_function(int x) def test(): return c_function(42) ######## pkg/alib.c ######## int c_function(int x) { return x + 1; } ######## pkg/alib.h ######## int c_function(int x); Cython-0.23.4/tests/build/cythonize_additional_sources.srctree0000644000175600017570000000077212606202452026013 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import a; assert a.test() == 43" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize("*.pyx"), ) ######## a.pyx ######## # distutils: sources=alib.c cdef extern from "alib.h": int c_function(int x) def test(): return c_function(42) ######## alib.c ######## int c_function(int x) { return x + 1; } ######## alib.h ######## int c_function(int x); Cython-0.23.4/tests/build/cpp_cythonize.srctree0000644000175600017570000000074412606202452022721 0ustar jenkinsjenkins00000000000000# tag: cpp PYTHON setup.py build_ext --inplace PYTHON -c "import a; a.use_vector([1,2,3])" ######## setup.py ######## from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize("*.pyx", language='c++'), ) ######## a.pyx ######## from libcpp.vector cimport vector def use_vector(L): try: v = new vector[int]() for a in L: v.push_back(a) return v.size() finally: del v Cython-0.23.4/tests/build/compile_env_distutils.srctree0000644000175600017570000000077112606202452024447 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import a; import sys; sys.exit(a.compile_env_test())" ######## setup.py ######## from distutils.core import setup from Cython.Distutils.extension import Extension from Cython.Distutils import build_ext setup( cmdclass = {'build_ext': build_ext}, ext_modules = [Extension( "a", ["a.pyx"], pyrex_compile_time_env = {'TEST': True}, )], ) ######## a.pyx ######## def compile_env_test(): IF TEST: return 0 ELSE: return 1 Cython-0.23.4/tests/build/common_include_dir.srctree0000644000175600017570000000361512606202452023674 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import runner" # Verify some files were created. # ls common/AddTraceback_impl*.h common/RaiseException_impl_*.h PYTHON -c "import glob; assert glob.glob('common/AddTraceback_impl*.h')" PYTHON -c "import glob; assert glob.glob('common/RaiseException_impl_*.h')" # Verify that they're used. PYTHON fake_grep.py -c '#include "common/AddTraceback_impl_.*h"' a.c PYTHON fake_grep.py -c '#include "common/AddTraceback_impl_.*h"' b.c PYTHON fake_grep.py -c '#include "common/AddTraceback_impl_.*h"' c.c ######## setup.py ######## import sys from Cython.Build.Dependencies import cythonize from distutils.core import setup # Test concurrent safety if multiprocessing is available. # (In particular, TravisCI does not support spawning processes from tests.) nthreads = 0 if not hasattr(sys, 'pypy_version_info'): try: import multiprocessing multiprocessing.Pool(2).close() nthreads = 2 except (ImportError, OSError): pass setup( ext_modules = cythonize("*.pyx", common_utility_include_dir='common', nthreads=nthreads), ) ######## a.pyx ######## def generator(n): for k in range(n): yield k assert list(generator(10)) == list(range(10)) ######## b.pyx ######## def generator(n): for k in range(n): yield k assert list(generator(10)) == list(range(10)) if __name__ == "__main__": print("here b") ######## c.pyx ######## if __name__ == "__main__": print("here c") ######## runner.py ######## import a, b, c ######## fake_grep.py ######## import re import sys if sys.platform == 'win32': opt, pattern, file = sys.argv[1:] assert opt == '-c' count = 0 regex = re.compile(pattern) for line in open(file): if regex.search(line): count += 1 print(count) sys.exit(count == 0) else: import subprocess sys.exit(subprocess.call(['grep'] + sys.argv[1:])) Cython-0.23.4/tests/build/build_dir.srctree0000644000175600017570000000357312606202452022003 0ustar jenkinsjenkins00000000000000PYTHON symlink_or_copy.py subdir fake PYTHON setup.py build_ext --inplace PYTHON -c "import a" PYTHON -c "import pkg.b" PYTHON check_paths.py ######## symlink_or_copy.py ######## import platform import sys if platform.system() == "Windows": import shutil shutil.copytree(sys.argv[1], sys.argv[2]) else: import os os.symlink(sys.argv[1], sys.argv[2]) ######## setup.py ######## # TODO: Better interface... from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = (cythonize("*.pyx", build_dir="scratchA") + cythonize("pkg/*.pyx", build_dir="scratchB")), ) ######## a.pyx ######## cdef extern from "helper.h": int value1 cdef extern from "subdir/helper.h": int value2 cdef extern from "pkg/pkg_helper.h": int value3 assert value1 == 100 assert value2 == 200 assert value3 == 300 ######## helper.h ######## int value1 = 100; ######## subdir/helper.h ######## int value2 = 200; ######## pkg/__init__.py ######## ######## pkg/b.pyx ######## cdef extern from "../fake/helper.h": int value2 cdef extern from "pkg_helper.h": int value3 cdef extern from "subdir/pkg_helper.h": int value4 assert value2 == 200 assert value3 == 300 assert value4 == 400 ######## pkg/pkg_helper.h ######## int value3 = 300; ######## pkg/subdir/pkg_helper.h ######## int value4 = 400; ######## check_paths.py ######## import os assert os.path.exists("scratchA/a.c") assert os.path.exists("scratchA/helper.h") assert os.path.exists("scratchA/subdir/helper.h") assert os.path.exists("scratchA/pkg/pkg_helper.h") assert not os.path.exists("a.c") assert os.path.exists("scratchB/pkg/b.c") assert os.path.exists("scratchB/pkg/pkg_helper.h") assert os.path.exists("scratchB/pkg/subdir/pkg_helper.h") assert os.path.exists("scratchB/fake/helper.h") assert not os.path.exists("b.c") assert not os.path.exists("pkg/b.c") Cython-0.23.4/tests/build/basic_distutils.srctree0000644000175600017570000000050012606202452023216 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import a" ######## setup.py ######## from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext setup( cmdclass = {'build_ext': build_ext}, ext_modules = [Extension("a", ["a.pyx"])], ) ######## a.pyx ######## Cython-0.23.4/tests/build/basic_cythonize.srctree0000644000175600017570000000041412606202452023212 0ustar jenkinsjenkins00000000000000PYTHON setup.py build_ext --inplace PYTHON -c "import a" ######## setup.py ######## # TODO: Better interface... from Cython.Build.Dependencies import cythonize from distutils.core import setup setup( ext_modules = cythonize("*.pyx"), ) ######## a.pyx ######## Cython-0.23.4/tests/buffers/0000755000175600017570000000000012606202455017005 5ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/buffers/mockbuffers.pxi0000644000175600017570000002551412606202452022041 0ustar jenkinsjenkins00000000000000from libc cimport stdlib from libc cimport stdio cimport cpython.buffer import sys available_flags = ( ('FORMAT', cpython.buffer.PyBUF_FORMAT), ('INDIRECT', cpython.buffer.PyBUF_INDIRECT), ('ND', cpython.buffer.PyBUF_ND), ('STRIDES', cpython.buffer.PyBUF_STRIDES), ('C_CONTIGUOUS', cpython.buffer.PyBUF_C_CONTIGUOUS), ('F_CONTIGUOUS', cpython.buffer.PyBUF_F_CONTIGUOUS), ('WRITABLE', cpython.buffer.PyBUF_WRITABLE) ) cdef class MockBuffer: cdef object format, offset cdef void* buffer cdef int len, itemsize, ndim cdef Py_ssize_t* strides cdef Py_ssize_t* shape cdef Py_ssize_t* suboffsets cdef object label, log cdef readonly object recieved_flags, release_ok cdef public object fail def __init__(self, label, data, shape=None, strides=None, format=None, offset=0): # It is important not to store references to data after the constructor # as refcounting is checked on object buffers. self.label = label self.release_ok = True self.log = "" self.offset = offset self.itemsize = self.get_itemsize() if format is None: format = self.get_default_format() if shape is None: shape = (len(data),) if strides is None: strides = [] cumprod = 1 rshape = list(shape) rshape.reverse() for s in rshape: strides.append(cumprod) cumprod *= s strides.reverse() strides = [x * self.itemsize for x in strides] suboffsets = [-1] * len(shape) datashape = [len(data)] p = data while True: p = p[0] if isinstance(p, list): datashape.append(len(p)) else: break if len(datashape) > 1: # indirect access self.ndim = len(datashape) shape = datashape self.buffer = self.create_indirect_buffer(data, shape) suboffsets = [0] * (self.ndim-1) + [-1] strides = [sizeof(void*)] * (self.ndim-1) + [self.itemsize] self.suboffsets = self.list_to_sizebuf(suboffsets) else: # strided and/or simple access self.buffer = self.create_buffer(data) self.ndim = len(shape) self.suboffsets = NULL try: format = format.encode('ASCII') except AttributeError: pass self.format = format self.len = len(data) * self.itemsize self.strides = self.list_to_sizebuf(strides) self.shape = self.list_to_sizebuf(shape) def __dealloc__(self): stdlib.free(self.strides) stdlib.free(self.shape) if self.suboffsets != NULL: stdlib.free(self.suboffsets) # must recursively free indirect... else: stdlib.free(self.buffer) cdef void* create_buffer(self, data) except NULL: cdef size_t n = (len(data) * self.itemsize) cdef char* buf = stdlib.malloc(n) if buf == NULL: raise MemoryError cdef char* it = buf for value in data: self.write(it, value) it += self.itemsize return buf cdef void* create_indirect_buffer(self, data, shape) except NULL: cdef size_t n = 0 cdef void** buf assert shape[0] == len(data), (shape[0], len(data)) if len(shape) == 1: return self.create_buffer(data) else: shape = shape[1:] n = len(data) * sizeof(void*) buf = stdlib.malloc(n) if buf == NULL: return NULL for idx, subdata in enumerate(data): buf[idx] = self.create_indirect_buffer(subdata, shape) return buf cdef Py_ssize_t* list_to_sizebuf(self, l): cdef size_t n = len(l) * sizeof(Py_ssize_t) cdef Py_ssize_t* buf = stdlib.malloc(n) for i, x in enumerate(l): buf[i] = x return buf def __getbuffer__(MockBuffer self, Py_buffer* buffer, int flags): if self.fail: raise ValueError("Failing on purpose") self.recieved_flags = [] cdef int value for name, value in available_flags: if (value & flags) == value: self.recieved_flags.append(name) buffer.buf = (self.buffer + (self.offset * self.itemsize)) buffer.obj = self buffer.len = self.len buffer.readonly = 0 buffer.format = self.format buffer.ndim = self.ndim buffer.shape = self.shape buffer.strides = self.strides buffer.suboffsets = self.suboffsets buffer.itemsize = self.itemsize buffer.internal = NULL if self.label: msg = "acquired %s" % self.label print msg self.log += msg + "\n" def __releasebuffer__(MockBuffer self, Py_buffer* buffer): if buffer.suboffsets != self.suboffsets: self.release_ok = False if self.label: msg = "released %s" % self.label print msg self.log += msg + "\n" def printlog(self): print self.log[:-1] def resetlog(self): self.log = "" cdef int write(self, char* buf, object value) except -1: raise Exception() cdef get_itemsize(self): print "ERROR, not subclassed", self.__class__ cdef get_default_format(self): print "ERROR, not subclassed", self.__class__ cdef class CharMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: (buf)[0] = value return 0 cdef get_itemsize(self): return sizeof(char) cdef get_default_format(self): return b"@b" cdef class IntMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: (buf)[0] = value return 0 cdef get_itemsize(self): return sizeof(int) cdef get_default_format(self): return b"@i" cdef class UnsignedIntMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: (buf)[0] = value return 0 cdef get_itemsize(self): return sizeof(unsigned int) cdef get_default_format(self): return b"@I" cdef class ShortMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: (buf)[0] = value return 0 cdef get_itemsize(self): return sizeof(short) cdef get_default_format(self): return b"h" # Try without endian specifier cdef class UnsignedShortMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: (buf)[0] = value return 0 cdef get_itemsize(self): return sizeof(unsigned short) cdef get_default_format(self): return b"@1H" # Try with repeat count cdef class FloatMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: (buf)[0] = (value) return 0 cdef get_itemsize(self): return sizeof(float) cdef get_default_format(self): return b"f" cdef class DoubleMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: (buf)[0] = value return 0 cdef get_itemsize(self): return sizeof(double) cdef get_default_format(self): return b"d" cdef extern from *: void* addr_of_pyobject "(void*)"(object) cdef class ObjectMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: (buf)[0] = addr_of_pyobject(value) return 0 cdef get_itemsize(self): return sizeof(void*) cdef get_default_format(self): return b"@O" cdef class IntStridedMockBuffer(IntMockBuffer): cdef __cythonbufferdefaults__ = {"mode" : "strided"} cdef class ErrorBuffer: cdef object label def __init__(self, label): self.label = label def __getbuffer__(ErrorBuffer self, Py_buffer* buffer, int flags): raise Exception("acquiring %s" % self.label) def __releasebuffer__(ErrorBuffer self, Py_buffer* buffer): raise Exception("releasing %s" % self.label) # # Structs # cdef struct MyStruct: signed char a signed char b long long int c int d int e cdef struct SmallStruct: int a int b cdef struct NestedStruct: SmallStruct x SmallStruct y int z cdef packed struct PackedStruct: signed char a int b cdef struct NestedPackedStruct: signed char a int b PackedStruct sub int c cdef class MyStructMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: cdef MyStruct* s s = buf s.a, s.b, s.c, s.d, s.e = value return 0 cdef get_itemsize(self): return sizeof(MyStruct) cdef get_default_format(self): return b"2cq2i" cdef class NestedStructMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: cdef NestedStruct* s s = buf s.x.a, s.x.b, s.y.a, s.y.b, s.z = value return 0 cdef get_itemsize(self): return sizeof(NestedStruct) cdef get_default_format(self): return b"2T{ii}i" cdef class PackedStructMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: cdef PackedStruct* s s = buf s.a, s.b = value return 0 cdef get_itemsize(self): return sizeof(PackedStruct) cdef get_default_format(self): return b"^ci" cdef class NestedPackedStructMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: cdef NestedPackedStruct* s s = buf s.a, s.b, s.sub.a, s.sub.b, s.c = value return 0 cdef get_itemsize(self): return sizeof(NestedPackedStruct) cdef get_default_format(self): return b"ci^ci@i" cdef struct LongComplex: long double real long double imag cdef class LongComplexMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: cdef LongComplex* s s = buf s.real, s.imag = value return 0 cdef get_itemsize(self): return sizeof(LongComplex) cdef get_default_format(self): return b"Zg" def print_offsets(*args, size, newline=True): sys.stdout.write(' '.join([str(item // size) for item in args])) if newline: sys.stdout.write('\n') def print_int_offsets(*args, newline=True): print_offsets(*args, size=sizeof(int), newline=newline) shape_5_3_4_list = [[list(range(k * 12 + j * 4, k * 12 + j * 4 + 4)) for j in range(3)] for k in range(5)] stride1 = 21 * 14 stride2 = 21 shape_9_14_21_list = [[list(range(k * stride1 + j * stride2, k * stride1 + j * stride2 + 21)) for j in range(14)] for k in range(9)] Cython-0.23.4/tests/buffers/buffmt.pyx0000644000175600017570000002327412606202452021037 0ustar jenkinsjenkins00000000000000from __future__ import unicode_literals # Tests buffer format string parsing. __test__ = {} def testcase(func): __test__[func.__name__] = func.__doc__ return func from libc cimport stdlib def little_endian(): cdef unsigned int n = 1 return (&n)[0] != 0 if little_endian(): current_endian = '<' other_endian = '>' else: current_endian = '>' other_endian = '<' cdef struct align_of_float_helper: char ch float d cdef struct align_of_int_helper: char ch int i float_align = sizeof(align_of_float_helper) - sizeof(float) int_align = sizeof(align_of_int_helper) - sizeof(int) if float_align != 4 or sizeof(float) != 4: raise RuntimeError("Alignment or size of float is %d on this system, please report to cython-dev for a testcase fix" % float_align) if int_align != 4 or sizeof(int) != 4: raise RuntimeError("Alignment or size of int is %d on this system, please report to cython-dev for a testcase fix" % int_align) cdef class MockBuffer: cdef Py_ssize_t zero cdef Py_ssize_t minusone cdef object format cdef object itemsize def __init__(self, format, itemsize): self.format = unicode(format).encode(u"ASCII") self.itemsize = itemsize self.zero = 0 self.minusone = -1 def __getbuffer__(self, Py_buffer* info, int flags): info.buf = NULL info.strides = &self.zero info.suboffsets = &self.minusone info.shape = &self.zero info.ndim = 1 info.format = self.format info.itemsize = self.itemsize @testcase def _int(fmt): """ >>> _int("i") >>> _int("b") Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'int' but got 'signed char' >>> _int("if") Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected end but got 'float' >>> _int("$$") Traceback (most recent call last): ... ValueError: Does not understand character buffer dtype format string ('$') """ cdef object[int] buf = MockBuffer(fmt, sizeof(int)) @testcase def _ulong(fmt): """ >>> _ulong("L") """ cdef object[unsigned long] buf = MockBuffer(fmt, sizeof(unsigned long)) @testcase def wrongsize(): """ >>> wrongsize() Traceback (most recent call last): ... ValueError: Item size of buffer (1 byte) does not match size of 'float' (4 bytes) """ cdef object[float] buf = MockBuffer("f", 1) @testcase def _obj(fmt): """ >>> _obj("O") >>> _obj("i") Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'Python object' but got 'int' """ cdef object[object] buf = MockBuffer(fmt, sizeof(void*)) cdef struct ComplexFloat: float real float imag ctypedef struct Char3Int: char a int b int c int d cdef struct CharIntCFloat: char a int b ComplexFloat c float d cdef struct UnpackedStruct1: char a int b ComplexFloat c float c2 Char3Int d ctypedef struct UnpackedStruct2: CharIntCFloat a Char3Int b ctypedef struct UnpackedStruct3: CharIntCFloat a char b int c, d, e cdef struct UnpackedStruct4: char a int b ComplexFloat c float c2 char d int e, f, g @testcase def char3int(fmt): """ >>> char3int("ciii") >>> char3int("c1i1i1i") >>> char3int("c3i") >>> char3int("ci2i") >>> char3int("c@i@2i") Extra pad bytes (assuming int size is 4 or more) >>> char3int("cxiii") >>> char3int("c3xiii") >>> char3int("cxxxiii") Standard alignment (assming int size is 4) >>> char3int("=c3xiii") >>> char3int("=ciii") Traceback (most recent call last): ... ValueError: Buffer dtype mismatch; next field is at offset 1 but 4 expected >>> char3int("=cxxx@iii") Error: >>> char3int("cii") Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'int' but got end in 'Char3Int.d' """ cdef object obj = MockBuffer(fmt, sizeof(Char3Int)) cdef object[Char3Int, ndim=1] buf = obj @testcase def unpacked_struct(fmt): """ Native formats: >>> unpacked_struct("ciZffciii") >>> unpacked_struct("@ci3fc3i") >>> unpacked_struct("@ciZffci2i") >>> unpacked_struct("ciZffT{ciii}") >>> unpacked_struct("cT{ifffc2i}i") >>> unpacked_struct("ciZffc3T{i}") >>> unpacked_struct("T{c}T{T{iZffT{ci}}}2T{T{i}}") """ assert (sizeof(UnpackedStruct1) == sizeof(UnpackedStruct2) == sizeof(UnpackedStruct3) == sizeof(UnpackedStruct4)) cdef object obj = MockBuffer(fmt, sizeof(UnpackedStruct1)) cdef object[UnpackedStruct1, ndim=1] buf1 = obj cdef object[UnpackedStruct2, ndim=1] buf2 = obj cdef object[UnpackedStruct3, ndim=1] buf3 = obj cdef object[UnpackedStruct4, ndim=1] buf4 = obj cdef struct ComplexTest: ComplexFloat a, b, c @testcase def complex_test(fmt): """ >>> complex_test("ZfZfZf") >>> complex_test("3Zf") >>> complex_test("6f") >>> complex_test("3T{Zf}") >>> complex_test("fZfZff") Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'float' but got 'complex float' in 'ComplexFloat.imag' """ cdef object obj = MockBuffer(fmt, sizeof(ComplexTest)) cdef object[ComplexTest] buf1 = obj @testcase def alignment_string(fmt, exc=None): """ >>> alignment_string("@i") >>> alignment_string("%si" % current_endian) >>> alignment_string("%si" % other_endian, "X-endian buffer not supported on X-endian compiler") >>> alignment_string("=i") """ cdef object[int] buf try: buf = MockBuffer(fmt, sizeof(int)) except ValueError, e: msg = unicode(e).replace("Big", "X").replace("Little", "X").replace("big", "X").replace("little", "X") if msg != exc: print msg print " is not equal to" print exc return if exc: print "fail" @testcase def int_and_long_are_same(): """ >>> int_and_long_are_same() """ cdef object[int] intarr cdef object[long] longarr if sizeof(int) == sizeof(long): intarr = MockBuffer("l", sizeof(int)) longarr = MockBuffer("i", sizeof(int)) cdef struct MixedComplex: double real float imag @testcase def mixed_complex_struct(): """ Triggering a specific execution path for this case. >>> mixed_complex_struct() Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'double' but got 'complex double' in 'MixedComplex.real' """ cdef object[MixedComplex] buf = MockBuffer("Zd", sizeof(MixedComplex)) cdef packed struct PackedSubStruct: char x int y cdef struct UnpackedSubStruct: char x int y cdef packed struct PackedStruct: char a int b PackedSubStruct sub cdef struct PartiallyPackedStruct: char a int b PackedSubStruct sub cdef packed struct PartiallyPackedStruct2: char a UnpackedSubStruct sub char b int c @testcase def packed_struct(fmt): """ Assuming int is four bytes: >>> packed_struct("^cici") >>> packed_struct("=cici") However aligned access won't work: >>> packed_struct("^c@i^ci") Traceback (most recent call last): ... ValueError: Buffer dtype mismatch; next field is at offset 4 but 1 expected >>> packed_struct("@cici") Traceback (most recent call last): ... ValueError: Buffer dtype mismatch; next field is at offset 4 but 1 expected """ cdef object[PackedStruct] buf = MockBuffer(fmt, sizeof(PackedStruct)) @testcase def partially_packed_struct(fmt): """ Assuming int is four bytes: >>> partially_packed_struct("^c@i^ci") >>> partially_packed_struct("@ci^ci") >>> partially_packed_struct("^c@i=ci") >>> partially_packed_struct("@ci=ci") >>> partially_packed_struct("ci^ci") >>> partially_packed_struct("ci=ci") Incorrectly aligned accesses won't work: >>> partially_packed_struct("^cici") Traceback (most recent call last): ... ValueError: Buffer dtype mismatch; next field is at offset 1 but 4 expected >>> partially_packed_struct("=cibi") Traceback (most recent call last): ... ValueError: Buffer dtype mismatch; next field is at offset 1 but 4 expected """ cdef object[PartiallyPackedStruct] buf = MockBuffer( fmt, sizeof(PartiallyPackedStruct)) @testcase def partially_packed_struct_2(fmt): """ Assuming int is four bytes: >>> partially_packed_struct_2("^ccxxxici") >>> partially_packed_struct_2("^ccxxxi^ci") >>> partially_packed_struct_2("c=cxxxi^ci") >>> partially_packed_struct_2("c^cxxxi^ci") >>> partially_packed_struct_2("c^cxxxi=ci") >>> partially_packed_struct_2("ccxxx^i@c^i") Incorrectly aligned accesses won't work: >>> partially_packed_struct_2("ccxxxici") Traceback (most recent call last): ... ValueError: Buffer dtype mismatch; next field is at offset 8 but 5 expected >>> partially_packed_struct_2("ccici") Traceback (most recent call last): ... ValueError: Buffer dtype mismatch; next field is at offset 4 but 5 expected """ cdef object[PartiallyPackedStruct2] buf = MockBuffer( fmt, sizeof(PartiallyPackedStruct2)) cdef packed struct PackedStructWithCharArrays: float a int b char[5] c char[3] d @testcase def packed_struct_with_strings(fmt): """ >>> packed_struct_with_strings("T{f:a:i:b:5s:c:3s:d:}") """ cdef object[PackedStructWithCharArrays] buf = MockBuffer( fmt, sizeof(PackedStructWithCharArrays)) # TODO: empty struct # TODO: Incomplete structs # TODO: mixed structs Cython-0.23.4/tests/buffers/buffer.pyx0000644000175600017570000000236512606202452021023 0ustar jenkinsjenkins00000000000000__doc__ = u""" >>> b1 = TestBuffer() >>> b2 = TestBufferRelease() """ import sys if sys.version_info[0] >= 3: __doc__ += u""" >>> ms = memoryview(s) >>> ms.tobytes() b'abcdefg' >>> m1 = memoryview(b1) __getbuffer__ called Semantics changed in python 3.3 >> m1.tobytes() __getbuffer__ called b'abcdefg' >>> m2 = memoryview(b2) __getbuffer__ called Semantics changed in python 3.3 >> m2.tobytes() __getbuffer__ called releasing! b'abcdefg' >>> del m1 >>> del m2 releasing! """ s = b"abcdefg" cdef class TestBuffer: def __getbuffer__(self, Py_buffer* buffer, int flags): print u"__getbuffer__ called" buffer.buf = s buffer.obj = self buffer.len = len(s) buffer.readonly = 0 buffer.format = "B" buffer.ndim = 0 buffer.shape = NULL buffer.strides = NULL buffer.suboffsets = NULL buffer.itemsize = 1 buffer.internal = NULL cdef class TestBufferRelease(TestBuffer): def __releasebuffer__(self, Py_buffer* buffer): print u"releasing!" cdef class TestCompileWithDocstring(object): def __getbuffer__(self, Py_buffer* buffer, int flags): "I am a docstring!" def __releasebuffer__(self, Py_buffer* buf): "I am a docstring!" Cython-0.23.4/tests/buffers/bufaccess.pyx0000644000175600017570000006520012606202452021505 0ustar jenkinsjenkins00000000000000# Tests the buffer access syntax functionality by constructing # mock buffer objects. # # Note that the buffers are mock objects created for testing # the buffer access behaviour -- for instance there is no flag # checking in the buffer objects (why test our test case?), rather # what we want to test is what is passed into the flags argument. # from __future__ import unicode_literals from cpython.object cimport PyObject from cpython.ref cimport Py_INCREF, Py_DECREF cimport cython __test__ = {} import sys #import re exclude = []#re.compile('object').search] if getattr(sys, 'pypy_version_info', None) is not None: # disable object-in-buffer tests in PyPy import re exclude.append(re.compile('object').search) def testcase(func): for e in exclude: if e(func.__name__): return func __test__[func.__name__] = func.__doc__ return func include "mockbuffers.pxi" # # Buffer acquire and release tests # def nousage(): """ The challenge here is just compilation. """ cdef object[int, ndim=2] buf @testcase def disabled_usage(obj): """ The challenge here is just compilation. >>> disabled_usage(None) """ cdef object[int, ndim=2] buf if False: buf = obj return obj @testcase def nousage_cleanup(x): """ >>> nousage_cleanup(False) >>> nousage_cleanup(True) Traceback (most recent call last): RuntimeError """ cdef object[int, ndim=2] buf if x: raise RuntimeError() @testcase def acquire_release(o1, o2): """ >>> A = IntMockBuffer("A", range(6)) >>> B = IntMockBuffer("B", range(6)) >>> acquire_release(A, B) acquired A released A acquired B released B >>> acquire_release(None, None) >>> acquire_release(None, B) acquired B released B """ cdef object[int] buf buf = o1 buf = o2 @testcase def acquire_raise(o): """ Apparently, doctest won't handle mixed exceptions and print stats, so need to circumvent this. >>> A = IntMockBuffer("A", range(6)) >>> A.resetlog() >>> acquire_raise(A) Traceback (most recent call last): ... Exception: on purpose >>> A.printlog() acquired A released A """ cdef object[int] buf buf = o raise Exception("on purpose") @testcase def acquire_failure1(): """ >>> acquire_failure1() acquired working 0 3 0 3 released working """ cdef object[int] buf buf = IntMockBuffer("working", range(4)) print buf[0], buf[3] try: buf = ErrorBuffer() assert False except Exception: print buf[0], buf[3] @testcase def acquire_failure2(): """ >>> acquire_failure2() acquired working 0 3 0 3 released working """ cdef object[int] buf = IntMockBuffer("working", range(4)) print buf[0], buf[3] try: buf = ErrorBuffer() assert False except Exception: print buf[0], buf[3] @testcase def acquire_failure3(): """ >>> acquire_failure3() acquired working 0 3 released working acquired working 0 3 released working """ cdef object[int] buf buf = IntMockBuffer("working", range(4)) print buf[0], buf[3] try: buf = 3 assert False except Exception: print buf[0], buf[3] @testcase def acquire_failure4(): """ >>> acquire_failure4() acquired working 0 3 released working acquired working 0 3 released working """ cdef object[int] buf = IntMockBuffer("working", range(4)) print buf[0], buf[3] try: buf = 2 assert False except Exception: print buf[0], buf[3] @testcase def acquire_failure5(): """ >>> acquire_failure5() Traceback (most recent call last): ... ValueError: Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too! """ cdef object[int] buf buf = IntMockBuffer("working", range(4)) buf.fail = True buf = 3 @testcase def acquire_nonbuffer1(first, second=None): """ >>> acquire_nonbuffer1(3) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError:... 'int'... >>> acquire_nonbuffer1(type) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError:... 'type'... >>> acquire_nonbuffer1(None, 2) # doctest: +ELLIPSIS Traceback (most recent call last): TypeError:... 'int'... """ cdef object[int] buf buf = first buf = second @testcase def acquire_nonbuffer2(): """ >>> acquire_nonbuffer2() acquired working 0 3 released working acquired working 0 3 released working """ cdef object[int] buf = IntMockBuffer("working", range(4)) print buf[0], buf[3] try: buf = ErrorBuffer assert False except Exception: print buf[0], buf[3] @testcase def as_argument(object[int] bufarg, int n): """ >>> A = IntMockBuffer("A", range(6)) >>> as_argument(A, 6) acquired A 0 1 2 3 4 5 END released A """ cdef int i for i in range(n): print bufarg[i], print 'END' @testcase def as_argument_not_none(object[int] bufarg not None): """ >>> A = IntMockBuffer("A", range(6)) >>> as_argument_not_none(A) acquired A ACCEPTED released A >>> as_argument_not_none(None) Traceback (most recent call last): TypeError: Argument 'bufarg' must not be None """ print 'ACCEPTED' @testcase def as_argument_defval(object[int] bufarg=IntMockBuffer('default', range(6)), int n=6): """ >>> as_argument_defval() acquired default 0 1 2 3 4 5 END released default >>> A = IntMockBuffer("A", range(6)) >>> as_argument_defval(A, 6) acquired A 0 1 2 3 4 5 END released A """ cdef int i for i in range(n): print bufarg[i], print 'END' @testcase def cdef_assignment(obj, n): """ >>> A = IntMockBuffer("A", range(6)) >>> cdef_assignment(A, 6) acquired A 0 1 2 3 4 5 END released A """ cdef object[int] buf = obj cdef int i for i in range(n): print buf[i], print 'END' @testcase def forin_assignment(objs, int pick): """ >>> A = IntMockBuffer("A", range(6)) >>> B = IntMockBuffer("B", range(6)) >>> forin_assignment([A, B, A, A], 2) acquired A 2 released A acquired B 2 released B acquired A 2 released A acquired A 2 released A """ cdef object[int] buf for buf in objs: print buf[pick] @testcase def cascaded_buffer_assignment(obj): """ >>> A = IntMockBuffer("A", range(6)) >>> cascaded_buffer_assignment(A) acquired A acquired A released A released A """ cdef object[int] a, b a = b = obj @testcase def tuple_buffer_assignment1(a, b): """ >>> A = IntMockBuffer("A", range(6)) >>> B = IntMockBuffer("B", range(6)) >>> tuple_buffer_assignment1(A, B) acquired A acquired B released A released B """ cdef object[int] x, y x, y = a, b @testcase def tuple_buffer_assignment2(tup): """ >>> A = IntMockBuffer("A", range(6)) >>> B = IntMockBuffer("B", range(6)) >>> tuple_buffer_assignment2((A, B)) acquired A acquired B released A released B """ cdef object[int] x, y x, y = tup @testcase def explicitly_release_buffer(): """ >>> explicitly_release_buffer() acquired A released A After release """ cdef object[int] x = IntMockBuffer("A", range(10)) x = None print "After release" # # Getting items and index bounds checking # @testcase def get_int_2d(object[int, ndim=2] buf, int i, int j): """ >>> C = IntMockBuffer("C", range(6), (2,3)) >>> get_int_2d(C, 1, 1) acquired C released C 4 Check negative indexing: >>> get_int_2d(C, -1, 0) acquired C released C 3 >>> get_int_2d(C, -1, -2) acquired C released C 4 >>> get_int_2d(C, -2, -3) acquired C released C 0 Out-of-bounds errors: >>> get_int_2d(C, 2, 0) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) >>> get_int_2d(C, 0, -4) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 1) """ return buf[i, j] @testcase def get_int_2d_uintindex(object[int, ndim=2] buf, unsigned int i, unsigned int j): """ Unsigned indexing: >>> C = IntMockBuffer("C", range(6), (2,3)) >>> get_int_2d_uintindex(C, 0, 0) acquired C released C 0 >>> get_int_2d_uintindex(C, 1, 2) acquired C released C 5 """ # This is most interesting with regards to the C code # generated. return buf[i, j] @testcase def set_int_2d(object[int, ndim=2] buf, int i, int j, int value): """ Uses get_int_2d to read back the value afterwards. For pure unit test, one should support reading in MockBuffer instead. >>> C = IntMockBuffer("C", range(6), (2,3)) >>> set_int_2d(C, 1, 1, 10) acquired C released C >>> get_int_2d(C, 1, 1) acquired C released C 10 Check negative indexing: >>> set_int_2d(C, -1, 0, 3) acquired C released C >>> get_int_2d(C, -1, 0) acquired C released C 3 >>> set_int_2d(C, -1, -2, 8) acquired C released C >>> get_int_2d(C, -1, -2) acquired C released C 8 >>> set_int_2d(C, -2, -3, 9) acquired C released C >>> get_int_2d(C, -2, -3) acquired C released C 9 Out-of-bounds errors: >>> set_int_2d(C, 2, 0, 19) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) >>> set_int_2d(C, 0, -4, 19) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 1) """ buf[i, j] = value @testcase def list_comprehension(object[int] buf, len): """ >>> list_comprehension(IntMockBuffer(None, [1,2,3]), 3) 1|2|3 """ cdef int i print u"|".join([unicode(buf[i]) for i in range(len)]) # # The negative_indices buffer option # @testcase def no_negative_indices(object[int, negative_indices=False] buf, int idx): """ The most interesting thing here is to inspect the C source and make sure optimal code is produced. >>> A = IntMockBuffer(None, range(6)) >>> no_negative_indices(A, 3) 3 >>> no_negative_indices(A, -1) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) """ return buf[idx] @testcase @cython.wraparound(False) def wraparound_directive(object[int] buf, int pos_idx, int neg_idx): """ Again, the most interesting thing here is to inspect the C source. >>> A = IntMockBuffer(None, range(4)) >>> wraparound_directive(A, 2, -1) 5 >>> wraparound_directive(A, -1, 2) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) """ cdef int byneg with cython.wraparound(True): byneg = buf[neg_idx] return buf[pos_idx] + byneg # # Test which flags are passed. # @testcase def readonly(obj): """ >>> R = UnsignedShortMockBuffer("R", range(27), shape=(3, 3, 3)) >>> readonly(R) acquired R 25 released R >>> [str(x) for x in R.recieved_flags] # Works in both py2 and py3 ['FORMAT', 'INDIRECT', 'ND', 'STRIDES'] """ cdef object[unsigned short int, ndim=3] buf = obj print buf[2, 2, 1] @testcase def writable(obj): """ >>> R = UnsignedShortMockBuffer("R", range(27), shape=(3, 3, 3)) >>> writable(R) acquired R released R >>> [str(x) for x in R.recieved_flags] # Py2/3 ['FORMAT', 'INDIRECT', 'ND', 'STRIDES', 'WRITABLE'] """ cdef object[unsigned short int, ndim=3] buf = obj buf[2, 2, 1] = 23 @testcase def strided(object[int, ndim=1, mode='strided'] buf): """ >>> A = IntMockBuffer("A", range(4)) >>> strided(A) acquired A released A 2 >>> [str(x) for x in A.recieved_flags] # Py2/3 ['FORMAT', 'ND', 'STRIDES'] Check that the suboffsets were patched back prior to release. >>> A.release_ok True """ return buf[2] @testcase def c_contig(object[int, ndim=1, mode='c'] buf): """ >>> A = IntMockBuffer(None, range(4)) >>> c_contig(A) 2 >>> [str(x) for x in A.recieved_flags] ['FORMAT', 'ND', 'STRIDES', 'C_CONTIGUOUS'] """ return buf[2] @testcase def c_contig_2d(object[int, ndim=2, mode='c'] buf): """ Multi-dim has seperate implementation >>> A = IntMockBuffer(None, range(12), shape=(3,4)) >>> c_contig_2d(A) 7 >>> [str(x) for x in A.recieved_flags] ['FORMAT', 'ND', 'STRIDES', 'C_CONTIGUOUS'] """ return buf[1, 3] @testcase def f_contig(object[int, ndim=1, mode='fortran'] buf): """ >>> A = IntMockBuffer(None, range(4)) >>> f_contig(A) 2 >>> [str(x) for x in A.recieved_flags] ['FORMAT', 'ND', 'STRIDES', 'F_CONTIGUOUS'] """ return buf[2] @testcase def f_contig_2d(object[int, ndim=2, mode='fortran'] buf): """ Must set up strides manually to ensure Fortran ordering. >>> A = IntMockBuffer(None, range(12), shape=(4,3), strides=(1, 4)) >>> f_contig_2d(A) 7 >>> [str(x) for x in A.recieved_flags] ['FORMAT', 'ND', 'STRIDES', 'F_CONTIGUOUS'] """ return buf[3, 1] # # Test compiler options for bounds checking. We create an array with a # safe "boundary" (memory # allocated outside of what it published) and then check whether we get back # what we stored in the memory or an error. @testcase def safe_get(object[int] buf, int idx): """ >>> A = IntMockBuffer(None, range(10), shape=(3,), offset=5) Validate our testing buffer... >>> safe_get(A, 0) 5 >>> safe_get(A, 2) 7 >>> safe_get(A, -3) 5 Access outside it. This is already done above for bounds check testing but we include it to tell the story right. >>> safe_get(A, -4) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) >>> safe_get(A, 3) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) """ return buf[idx] @testcase @cython.boundscheck(False) # outer decorators should take precedence @cython.boundscheck(True) def unsafe_get(object[int] buf, int idx): """ Access outside of the area the buffer publishes. >>> A = IntMockBuffer(None, range(10), shape=(3,), offset=5) >>> unsafe_get(A, -4) 4 >>> unsafe_get(A, -5) 3 >>> unsafe_get(A, 3) 8 """ return buf[idx] @testcase @cython.boundscheck(False) def unsafe_get_nonegative(object[int, negative_indices=False] buf, int idx): """ Also inspect the C source to see that it is optimal... >>> A = IntMockBuffer(None, range(10), shape=(3,), offset=5) >>> unsafe_get_nonegative(A, -2) 3 """ return buf[idx] @testcase def mixed_get(object[int] buf, int unsafe_idx, int safe_idx): """ >>> A = IntMockBuffer(None, range(10), shape=(3,), offset=5) >>> mixed_get(A, -4, 0) (4, 5) >>> mixed_get(A, 0, -4) Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) """ with cython.boundscheck(False): one = buf[unsafe_idx] with cython.boundscheck(True): two = buf[safe_idx] return (one, two) # # Coercions # ## @testcase ## def coercions(object[unsigned char] uc): ## """ ## TODO ## """ ## print type(uc[0]) ## uc[0] = -1 ## print uc[0] ## uc[0] = 3.14 ## print uc[0] ## cdef char* ch = b"asfd" ## cdef object[object] objbuf ## objbuf[3] = ch # # Testing that accessing data using various types of buffer access # all works. # def printbuf_int(object[int] buf, shape): # Utility func cdef int i for i in range(shape[0]): print buf[i], print 'END' @testcase def printbuf_int_2d(o, shape): """ Strided: >>> printbuf_int_2d(IntMockBuffer("A", range(6), (2,3)), (2,3)) acquired A 0 1 2 END 3 4 5 END released A >>> printbuf_int_2d(IntMockBuffer("A", range(100), (3,3), strides=(20,5)), (3,3)) acquired A 0 5 10 END 20 25 30 END 40 45 50 END released A Indirect: >>> printbuf_int_2d(IntMockBuffer("A", [[1,2],[3,4]]), (2,2)) acquired A 1 2 END 3 4 END released A """ # should make shape builtin cdef object[int, ndim=2] buf buf = o cdef int i, j for i in range(shape[0]): for j in range(shape[1]): print buf[i, j], print 'END' @testcase def printbuf_float(o, shape): """ >>> printbuf_float(FloatMockBuffer("F", [1.0, 1.25, 0.75, 1.0]), (4,)) acquired F 1.0 1.25 0.75 1.0 END released F """ # should make shape builtin cdef object[float] buf buf = o cdef int i, j for i in range(shape[0]): print buf[i], print "END" # # Test assignments # @testcase def inplace_operators(object[int] buf): """ >>> buf = IntMockBuffer(None, [2, 2]) >>> inplace_operators(buf) >>> printbuf_int(buf, (2,)) 0 3 END """ cdef int j = 0 buf[1] += 1 buf[j] *= 2 buf[0] -= 4 # # Typedefs # # Test three layers of typedefs going through a h file for plain int, and # simply a header file typedef for floats and unsigned. ctypedef int td_cy_int cdef extern from "bufaccess.h": ctypedef td_cy_int td_h_short # Defined as short, but Cython doesn't know this! ctypedef float td_h_double # Defined as double ctypedef unsigned int td_h_ushort # Defined as unsigned short ctypedef td_h_short td_h_cy_short @testcase def printbuf_td_cy_int(object[td_cy_int] buf, shape): """ >>> printbuf_td_cy_int(IntMockBuffer(None, range(3)), (3,)) 0 1 2 END >>> printbuf_td_cy_int(ShortMockBuffer(None, range(3)), (3,)) Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'td_cy_int' but got 'short' """ cdef int i for i in range(shape[0]): print buf[i], print 'END' @testcase def printbuf_td_h_short(object[td_h_short] buf, shape): """ >>> printbuf_td_h_short(ShortMockBuffer(None, range(3)), (3,)) 0 1 2 END >>> printbuf_td_h_short(IntMockBuffer(None, range(3)), (3,)) Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'td_h_short' but got 'int' """ cdef int i for i in range(shape[0]): print buf[i], print 'END' @testcase def printbuf_td_h_cy_short(object[td_h_cy_short] buf, shape): """ >>> printbuf_td_h_cy_short(ShortMockBuffer(None, range(3)), (3,)) 0 1 2 END >>> printbuf_td_h_cy_short(IntMockBuffer(None, range(3)), (3,)) Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'td_h_cy_short' but got 'int' """ cdef int i for i in range(shape[0]): print buf[i], print 'END' @testcase def printbuf_td_h_ushort(object[td_h_ushort] buf, shape): """ >>> printbuf_td_h_ushort(UnsignedShortMockBuffer(None, range(3)), (3,)) 0 1 2 END >>> printbuf_td_h_ushort(ShortMockBuffer(None, range(3)), (3,)) Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'td_h_ushort' but got 'short' """ cdef int i for i in range(shape[0]): print buf[i], print 'END' @testcase def printbuf_td_h_double(object[td_h_double] buf, shape): """ >>> printbuf_td_h_double(DoubleMockBuffer(None, [0.25, 1, 3.125]), (3,)) 0.25 1.0 3.125 END >>> printbuf_td_h_double(FloatMockBuffer(None, [0.25, 1, 3.125]), (3,)) Traceback (most recent call last): ... ValueError: Buffer dtype mismatch, expected 'td_h_double' but got 'float' """ cdef int i for i in range(shape[0]): print buf[i], print 'END' # # Object access # def addref(*args): for item in args: Py_INCREF(item) def decref(*args): for item in args: Py_DECREF(item) def get_refcount(x): return (x).ob_refcnt @testcase def printbuf_object(object[object] buf, shape): """ Only play with unique objects, interned numbers etc. will have unpredictable refcounts. ObjectMockBuffer doesn't do anything about increfing/decrefing, we to the "buffer implementor" refcounting directly in the testcase. >>> a, b, c = "globally_unique_string_23234123", {4:23}, [34,3] >>> get_refcount(a), get_refcount(b), get_refcount(c) (2, 2, 2) >>> A = ObjectMockBuffer(None, [a, b, c]) >>> printbuf_object(A, (3,)) 'globally_unique_string_23234123' 2 {4: 23} 2 [34, 3] 2 """ cdef int i for i in range(shape[0]): print repr(buf[i]), (buf[i]).ob_refcnt @testcase def assign_to_object(object[object] buf, int idx, obj): """ See comments on printbuf_object above. >>> a, b = [1, 2, 3], [4, 5, 6] >>> get_refcount(a), get_refcount(b) (2, 2) >>> addref(a) >>> A = ObjectMockBuffer(None, [1, a]) # 1, ...,otherwise it thinks nested lists... >>> get_refcount(a), get_refcount(b) (3, 2) >>> assign_to_object(A, 1, b) >>> get_refcount(a), get_refcount(b) (2, 3) >>> decref(b) """ buf[idx] = obj @testcase def assign_temporary_to_object(object[object] buf): """ See comments on printbuf_object above. >>> a, b = [1, 2, 3], {4:23} >>> get_refcount(a) 2 >>> addref(a) >>> A = ObjectMockBuffer(None, [b, a]) >>> get_refcount(a) 3 >>> assign_temporary_to_object(A) >>> get_refcount(a) 2 >>> printbuf_object(A, (2,)) {4: 23} 2 {1: 8} 2 To avoid leaking a reference in our testcase we need to replace the temporary with something we can manually decref :-) >>> assign_to_object(A, 1, a) >>> decref(a) """ buf[1] = {3-2: 2+(2*4)-2} # # cast option # @testcase def buffer_cast(object[unsigned int, cast=True] buf, int idx): """ Round-trip a signed int through unsigned int buffer access. >>> A = IntMockBuffer(None, [-100]) >>> buffer_cast(A, 0) -100 """ cdef unsigned int data = buf[idx] return data @testcase def buffer_cast_fails(object[char, cast=True] buf): """ Cannot cast between datatype of different sizes. >>> buffer_cast_fails(IntMockBuffer(None, [0])) Traceback (most recent call last): ... ValueError: Item size of buffer (4 bytes) does not match size of 'char' (1 byte) """ return buf[0] # # Typed buffers # @testcase def typedbuffer1(obj): """ >>> typedbuffer1(IntMockBuffer("A", range(10))) acquired A released A >>> typedbuffer1(None) >>> typedbuffer1(4) Traceback (most recent call last): ... TypeError: Cannot convert int to bufaccess.IntMockBuffer """ cdef IntMockBuffer[int, ndim=1] buf = obj @testcase def typedbuffer2(IntMockBuffer[int, ndim=1] obj): """ >>> typedbuffer2(IntMockBuffer("A", range(10))) acquired A released A >>> typedbuffer2(None) >>> typedbuffer2(4) Traceback (most recent call last): ... TypeError: Argument 'obj' has incorrect type (expected bufaccess.IntMockBuffer, got int) """ pass # # Test __cythonbufferdefaults__ # @testcase def bufdefaults1(IntStridedMockBuffer[int, ndim=1] buf): """ For IntStridedMockBuffer, mode should be "strided" by defaults which should show up in the flags. >>> A = IntStridedMockBuffer("A", range(10)) >>> bufdefaults1(A) acquired A released A >>> [str(x) for x in A.recieved_flags] ['FORMAT', 'ND', 'STRIDES'] """ pass @testcase def basic_struct(object[MyStruct] buf): """ See also buffmt.pyx >>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)])) 1 2 3 4 5 >>> basic_struct(MyStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="ccqii")) 1 2 3 4 5 """ print buf[0].a, buf[0].b, buf[0].c, buf[0].d, buf[0].e @testcase def nested_struct(object[NestedStruct] buf): """ See also buffmt.pyx >>> nested_struct(NestedStructMockBuffer(None, [(1, 2, 3, 4, 5)])) 1 2 3 4 5 >>> nested_struct(NestedStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="T{ii}T{2i}i")) 1 2 3 4 5 """ print buf[0].x.a, buf[0].x.b, buf[0].y.a, buf[0].y.b, buf[0].z @testcase def packed_struct(object[PackedStruct] buf): """ See also buffmt.pyx >>> packed_struct(PackedStructMockBuffer(None, [(1, 2)])) 1 2 >>> packed_struct(PackedStructMockBuffer(None, [(1, 2)], format="T{c^i}")) 1 2 >>> packed_struct(PackedStructMockBuffer(None, [(1, 2)], format="T{c=i}")) 1 2 """ print buf[0].a, buf[0].b @testcase def nested_packed_struct(object[NestedPackedStruct] buf): """ See also buffmt.pyx >>> nested_packed_struct(NestedPackedStructMockBuffer(None, [(1, 2, 3, 4, 5)])) 1 2 3 4 5 >>> nested_packed_struct(NestedPackedStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="ci^ci@i")) 1 2 3 4 5 >>> nested_packed_struct(NestedPackedStructMockBuffer(None, [(1, 2, 3, 4, 5)], format="^c@i^ci@i")) 1 2 3 4 5 """ print buf[0].a, buf[0].b, buf[0].sub.a, buf[0].sub.b, buf[0].c @testcase def complex_dtype(object[long double complex] buf): """ >>> complex_dtype(LongComplexMockBuffer(None, [(0, -1)])) -1j """ print buf[0] @testcase def complex_inplace(object[long double complex] buf): """ >>> complex_inplace(LongComplexMockBuffer(None, [(0, -1)])) (1+1j) """ buf[0] = buf[0] + 1 + 2j print buf[0] @testcase def complex_struct_dtype(object[LongComplex] buf): """ Note that the format string is "Zg" rather than "2g", yet a struct is accessed. >>> complex_struct_dtype(LongComplexMockBuffer(None, [(0, -1)])) 0.0 -1.0 """ print buf[0].real, buf[0].imag @testcase def complex_struct_inplace(object[LongComplex] buf): """ >>> complex_struct_inplace(LongComplexMockBuffer(None, [(0, -1)])) 1.0 1.0 """ buf[0].real += 1 buf[0].imag += 2 print buf[0].real, buf[0].imag # # Nogil # @testcase @cython.boundscheck(False) def buffer_nogil(): """ >>> buffer_nogil() 10 """ cdef object[int] buf = IntMockBuffer(None, [1,2,3]) with nogil: buf[1] = 10 return buf[1] @testcase def buffer_nogil_oob(): """ >>> buffer_nogil_oob() Traceback (most recent call last): ... IndexError: Out of bounds on buffer access (axis 0) """ cdef object[int] buf = IntMockBuffer(None, [1,2,3]) with nogil: buf[5] = 10 return buf[1] def get_int(): return 10 @testcase def test_inplace_assignment(): """ >>> test_inplace_assignment() 10 """ cdef object[int, ndim=1] buf = IntMockBuffer(None, [1, 2, 3]) buf[0] = get_int() print buf[0] Cython-0.23.4/tests/buffers/bufaccess.h0000644000175600017570000000016312606202452021111 0ustar jenkinsjenkins00000000000000/* See bufaccess.pyx */ typedef short td_h_short; typedef double td_h_double; typedef unsigned short td_h_ushort; Cython-0.23.4/tests/broken/0000755000175600017570000000000012606202455016631 5ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/broken/tslots.pyx0000644000175600017570000000006112606202452020715 0ustar jenkinsjenkins00000000000000cdef class Spam: pass def probe(): pass Cython-0.23.4/tests/broken/tryexceptelse.pyx0000644000175600017570000000044312606202452022271 0ustar jenkinsjenkins00000000000000def f(): cdef int i try: i = 1 raise x i = 2 else: i = 3 raise y i = 4 def g(): cdef int i try: i = 1 raise x i = 2 except a: i = 3 else: i = 4 raise y i = 5 Cython-0.23.4/tests/broken/test_include_options.pyx0000644000175600017570000000020212606202452023617 0ustar jenkinsjenkins00000000000000import sys from Pyrex.Compiler.Main import main sys.argv[1:] = "-I spam -Ieggs --include-dir ham".split() main(command_line = 1) Cython-0.23.4/tests/broken/retconvert.pyx0000644000175600017570000000010512606202452021557 0ustar jenkinsjenkins00000000000000def f(): return 42 cdef int g(): cdef object x return x Cython-0.23.4/tests/broken/raise.pyx0000644000175600017570000000021012606202452020464 0ustar jenkinsjenkins00000000000000def f(a, b, c): #raise raise a raise "spam" raise a, b raise "spam", 42 raise a, b, c raise "spam", 42, c() Cython-0.23.4/tests/broken/r_unpack.pyx0000644000175600017570000000021712606202452021172 0ustar jenkinsjenkins00000000000000seq = [1, [2, 3]] def f(): a, (b, c) = [1, [2, 3]] print a print b print c def g(): a, b, c = seq def h(): a, = seq Cython-0.23.4/tests/broken/r_traceback.pyx0000644000175600017570000000020112606202452021621 0ustar jenkinsjenkins00000000000000cdef int spam() except -1: raise Exception("Spam error") cdef int grail() except -1: spam() def tomato(): grail() Cython-0.23.4/tests/broken/r_tbfilename.pyx0000644000175600017570000000003712606202452022017 0ustar jenkinsjenkins00000000000000def foo(): raise Exception Cython-0.23.4/tests/broken/r_simpcall.pyx0000644000175600017570000000004012606202452021507 0ustar jenkinsjenkins00000000000000def f(): print "Spam!" f() Cython-0.23.4/tests/broken/r_newstyleclass.pyx0000644000175600017570000000017012606202452022607 0ustar jenkinsjenkins00000000000000class Inquisition(object): """Something that nobody expects.""" def __repr__(self): return "Surprise!" Cython-0.23.4/tests/broken/r_kwonlyargs.pyx0000644000175600017570000000131112606202452022105 0ustar jenkinsjenkins00000000000000def pd(d): l = [] i = d.items() i.sort() for kv in i: l.append("%r: %r" % kv) return "{%s}" % ", ".join(l) def c(a, b, c): print "a =", a, "b =", b, "c =", c def d(a, b, *, c = 88): print "a =", a, "b =", b, "c =", c def e(a, b, c = 88, **kwds): print "a =", a, "b =", b, "c =", c, "kwds =", pd(kwds) def f(a, b, *, c, d = 42): print "a =", a, "b =", b, "c =", c, "d =", d def g(a, b, *, c, d = 42, e = 17, f, **kwds): print "a =", a, "b =", b, "c =", c, "d =", d, "e =", e, "f =", f, "kwds =", pd(kwds) def h(a, b, *args, c, d = 42, e = 17, f, **kwds): print "a =", a, "b =", b, "args =", args, "c =", c, "d =", d, "e =", e, "f =", f, "kwds =", pd(kwds) Cython-0.23.4/tests/broken/r_inhcmethcall.pyx0000644000175600017570000000042712606202452022347 0ustar jenkinsjenkins00000000000000cdef class Parrot: cdef void describe(self): print "This parrot is resting." cdef class Norwegian(Parrot): cdef void describe(self): Parrot.describe(self) print "Lovely plumage!" cdef Parrot p1, p2 p1 = Parrot() p2 = Norwegian() p1.describe() p2.describe() Cython-0.23.4/tests/broken/r_import.pyx0000644000175600017570000000013612606202452021223 0ustar jenkinsjenkins00000000000000import spam print "Imported spam" print dir(spam) import sys print "Imported sys" print sys Cython-0.23.4/tests/broken/r_getattr3.pyx0000644000175600017570000000010012606202452021435 0ustar jenkinsjenkins00000000000000def test(obj, attr, dflt): return getattr3(obj, attr, dflt) Cython-0.23.4/tests/broken/r_extweakref.pyx0000644000175600017570000000011312606202452022051 0ustar jenkinsjenkins00000000000000cdef class Animal: cdef object __weakref__ cdef public object name Cython-0.23.4/tests/broken/r_extproperty.pyx0000644000175600017570000000057512606202452022325 0ustar jenkinsjenkins00000000000000cdef class CheeseShop: cdef object cheeses def __cinit__(self): self.cheeses = [] property cheese: "A senseless waste of a property." def __get__(self): return "We don't have: %s" % self.cheeses def __set__(self, value): self.cheeses.append(value) def __del__(self): del self.cheeses[:] Cython-0.23.4/tests/broken/r_extnumeric2.pyx0000644000175600017570000000112612606202452022156 0ustar jenkinsjenkins00000000000000cdef extern from "numeric.h": struct PyArray_Descr: int type_num, elsize char type ctypedef class Numeric.ArrayType [object PyArrayObject]: cdef char *data cdef int nd cdef int *dimensions, *strides cdef object base cdef PyArray_Descr *descr cdef int flags def ogle(ArrayType a): print "No. of dimensions:", a.nd print " Dim Value" for i in range(a.nd): print "%5d %5d" % (i, a.dimensions[i]) print "flags:", a.flags print "Type no.", a.descr.type_num print "Element size:", a.descr.elsize Cython-0.23.4/tests/broken/r_extmember.pyx0000644000175600017570000000047712606202452021711 0ustar jenkinsjenkins00000000000000cdef class Spam: cdef public int tons cdef readonly float tastiness cdef int temperature def __init__(self, tons, tastiness, temperature): self.tons = tons self.tastiness = tastiness self.temperature = temperature def get_temperature(self): return self.temperature Cython-0.23.4/tests/broken/r_extinherit.pyx0000644000175600017570000000042512606202452022075 0ustar jenkinsjenkins00000000000000cdef class Parrot: cdef object plumage def __init__(self): self.plumage = "yellow" def describe(self): print "This bird has lovely", self.plumage, "plumage." cdef class Norwegian(Parrot): def __init__(self): self.plumage = "blue" Cython-0.23.4/tests/broken/r_extimpinherit.pyx0000644000175600017570000000062212606202452022602 0ustar jenkinsjenkins00000000000000from b_extimpinherit cimport Parrot cdef class Norwegian(Parrot): cdef action(self): print "This parrot is resting." cdef plumage(self): print "Lovely plumage!" def main(): cdef Parrot p cdef Norwegian n p = Parrot() n = Norwegian() print "Parrot:" p.describe() p.action() print "Norwegian:" n.describe() n.action() n.plumage() Cython-0.23.4/tests/broken/r_excval.pyx0000644000175600017570000000060112606202452021170 0ustar jenkinsjenkins00000000000000cdef int tomato() except -1: print "Entering tomato" raise Exception("Eject! Eject! Eject!") print "Leaving tomato" cdef void sandwich(): print "Entering sandwich" tomato() print "Leaving sandwich" def snack(): print "Entering snack" tomato() print "Leaving snack" def lunch(): print "Entering lunch" sandwich() print "Leaving lunch" Cython-0.23.4/tests/broken/r_classmodname.pyx0000644000175600017570000000002512606202452022354 0ustar jenkinsjenkins00000000000000class Spam: pass Cython-0.23.4/tests/broken/r_classdoc.pyx0000644000175600017570000000005412606202452021503 0ustar jenkinsjenkins00000000000000class Spam: """Spam, glorious spam!""" Cython-0.23.4/tests/broken/r_cfuncimport.pyx0000644000175600017570000000013212606202452022236 0ustar jenkinsjenkins00000000000000cimport l_cfuncexport from l_cfuncexport cimport g print l_cfuncexport.f(42) print g(42) Cython-0.23.4/tests/broken/r_capi.pyx0000644000175600017570000000021012606202452020616 0ustar jenkinsjenkins00000000000000cdef extern from "l_capi_api.h": float f(float) int import_l_capi() except -1 def test(): print f(3.1415) import_l_capi() Cython-0.23.4/tests/broken/plex2.pyx0000644000175600017570000000016612606202452020425 0ustar jenkinsjenkins00000000000000cdef class Spam: pass cdef void foo(object blarg): pass cdef void xyzzy(): cdef Spam spam foo(spam) Cython-0.23.4/tests/broken/pkg.cimportfrom.pyx0000644000175600017570000000014412606202452022510 0ustar jenkinsjenkins00000000000000from spam cimport Spam from eggs cimport Eggs cdef extern Spam yummy cdef Eggs fried fried = None Cython-0.23.4/tests/broken/pkg.cimport.pyx0000644000175600017570000000012312606202452021621 0ustar jenkinsjenkins00000000000000cimport spam, eggs cdef extern spam.Spam yummy cdef eggs.Eggs fried fried = None Cython-0.23.4/tests/broken/naanou_1.pyx0000644000175600017570000000003412606202452021066 0ustar jenkinsjenkins00000000000000def f(a, *p, **n): pass Cython-0.23.4/tests/broken/l_cfuncexport.pyx0000644000175600017570000000011112606202452022234 0ustar jenkinsjenkins00000000000000cdef int f(int x): return x * x cdef int g(int x): return 5 * x Cython-0.23.4/tests/broken/l_capi.pyx0000644000175600017570000000006212606202452020615 0ustar jenkinsjenkins00000000000000cdef api float f(float x): return 0.5 * x * x Cython-0.23.4/tests/broken/invalid-module-name.pyx0000644000175600017570000000000012606202452023205 0ustar jenkinsjenkins00000000000000Cython-0.23.4/tests/broken/intindex.pyx0000644000175600017570000000025012606202452021207 0ustar jenkinsjenkins00000000000000cdef int f() except -1: cdef object x, y, z cdef int i cdef unsigned int ui z = x[y] z = x[i] x[y] = z x[i] = z z = x[ui] x[ui] = z Cython-0.23.4/tests/broken/includepublic.pyx0000644000175600017570000000003012606202452022203 0ustar jenkinsjenkins00000000000000include "i_public.pxi" Cython-0.23.4/tests/broken/i_public.pyx0000644000175600017570000000025612606202452021161 0ustar jenkinsjenkins00000000000000cdef public int grail cdef public spam(int servings): pass cdef public class sandwich [object sandwich, type sandwich_Type]: cdef int tomato cdef float lettuce Cython-0.23.4/tests/broken/getattr3ref.pyx0000644000175600017570000000005112606202452021616 0ustar jenkinsjenkins00000000000000cdef int f() except -1: g = getattr3 Cython-0.23.4/tests/broken/getattr.pyx0000644000175600017570000000016312606202452021042 0ustar jenkinsjenkins00000000000000cdef class Spam: cdef public object eggs def __getattr__(self, name): print "Spam getattr:", name Cython-0.23.4/tests/broken/fwddeclcclass.pyx0000644000175600017570000000015112606202452022166 0ustar jenkinsjenkins00000000000000cdef class Widget: pass cdef class Container: pass cdef Widget w cdef Container c w.parent = c Cython-0.23.4/tests/broken/externsue.pyx0000644000175600017570000000042312606202452021411 0ustar jenkinsjenkins00000000000000cdef extern from "externsue.h": enum Eggs: runny, firm, hard struct Spam: int i union Soviet: char c cdef extern Eggs e cdef extern Spam s cdef extern Soviet u cdef void tomato(): global e e = runny e = firm e = hard Cython-0.23.4/tests/broken/externfunc.pyx0000644000175600017570000000005212606202452021546 0ustar jenkinsjenkins00000000000000cdef extern from "foo.h": int fred() Cython-0.23.4/tests/broken/ctypedefextern.pyx0000644000175600017570000000025012606202452022416 0ustar jenkinsjenkins00000000000000cdef extern from "ctypedefextern.h": ctypedef int some_int ctypedef some_int *some_ptr cdef void spam(): cdef some_int i cdef some_ptr p p[0] = i Cython-0.23.4/tests/broken/cimportfunc.pyx0000644000175600017570000000003612606202452021720 0ustar jenkinsjenkins00000000000000from cexportfunc cimport f, g Cython-0.23.4/tests/broken/cimportfrompkgdir.pyx0000644000175600017570000000006212606202452023130 0ustar jenkinsjenkins00000000000000from package.inpackage cimport Spam cdef Spam s2 Cython-0.23.4/tests/broken/cimportfrom.pyx0000644000175600017570000000015612606202452021733 0ustar jenkinsjenkins00000000000000from spam cimport Spam from pkg.eggs cimport Eggs as ova cdef extern Spam yummy cdef ova fried fried = None Cython-0.23.4/tests/broken/cimport.pyx0000644000175600017570000000022612606202452021045 0ustar jenkinsjenkins00000000000000cimport spam cimport pkg.eggs cdef spam.Spam yummy cdef pkg.eggs.Eggs fried spam.eat(yummy) spam.tons = 3.14 ova = pkg.eggs fried = pkg.eggs.Eggs() Cython-0.23.4/tests/broken/cexportfunc.pyx0000644000175600017570000000007712606202452021734 0ustar jenkinsjenkins00000000000000cdef int f(): pass cdef char *g(int k, float z): pass Cython-0.23.4/tests/broken/cdefexternblock.pyx0000644000175600017570000000041612606202452022533 0ustar jenkinsjenkins00000000000000cdef extern from "cheese.h": ctypedef int camembert struct roquefort: int x char *swiss void cheddar() class external.runny [object runny_obj]: cdef int a def __init__(self): pass cdef runny r r = x r.a = 42 Cython-0.23.4/tests/broken/cdefemptysue.pyx0000644000175600017570000000031012606202452022057 0ustar jenkinsjenkins00000000000000cdef extern from "cdefemptysue.h": cdef struct spam: pass ctypedef union eggs: pass cdef enum ham: pass cdef extern spam s cdef extern eggs e cdef extern ham h Cython-0.23.4/tests/broken/cascadedass.pyx0000644000175600017570000000023112606202452021622 0ustar jenkinsjenkins00000000000000cdef void foo(): cdef int i, j, k i = j = k a = b = c i = j = c a = b = k (a, b), c = (d, e), f = (x, y), z # a, b = p, q = x, y Cython-0.23.4/tests/broken/builtindict.pyx0000644000175600017570000000041112606202452021676 0ustar jenkinsjenkins00000000000000cdef int f() except -1: cdef dict d cdef object x, z cdef int i z = dict d = dict(x) d = dict(*x) d.clear() z = d.copy() z = d.items() z = d.keys() z = d.values() d.merge(x, i) d.update(x) d.merge_pairs(x, i) Cython-0.23.4/tests/broken/builtinconst.pyx0000644000175600017570000000250712606202452022111 0ustar jenkinsjenkins00000000000000cdef int f() except -1: cdef type t cdef object x t = buffer t = enumerate t = file t = float t = int t = long t = open t = property t = str t = tuple t = xrange x = True x = False x = Ellipsis x = Exception x = StopIteration x = StandardError x = ArithmeticError x = LookupError x = AssertionError x = AssertionError x = EOFError x = FloatingPointError x = EnvironmentError x = IOError x = OSError x = ImportError x = IndexError x = KeyError x = KeyboardInterrupt x = MemoryError x = NameError x = OverflowError x = RuntimeError x = NotImplementedError x = SyntaxError x = IndentationError x = TabError x = ReferenceError x = SystemError x = SystemExit x = TypeError x = UnboundLocalError x = UnicodeError x = UnicodeEncodeError x = UnicodeDecodeError x = UnicodeTranslateError x = ValueError x = ZeroDivisionError x = MemoryErrorInst x = Warning x = UserWarning x = DeprecationWarning x = PendingDeprecationWarning x = SyntaxWarning #x = OverflowWarning # Does not seem to exist in 2.5 x = RuntimeWarning x = FutureWarning typecheck(x, Exception) try: pass except ValueError: pass Cython-0.23.4/tests/broken/big_t.pyx0000644000175600017570000000014012606202452020447 0ustar jenkinsjenkins00000000000000cdef extern from "foo.h": ctypedef long long big_t cdef void spam(big_t b) spam(grail) Cython-0.23.4/tests/broken/b_extimpinherit.pyx0000644000175600017570000000021612606202452022561 0ustar jenkinsjenkins00000000000000cdef class Parrot: cdef describe(self): print "This is a parrot." cdef action(self): print "Polly wants a cracker!" Cython-0.23.4/pyximport/0000755000175600017570000000000012606202455016262 5ustar jenkinsjenkins00000000000000Cython-0.23.4/pyximport/pyximport.py0000644000175600017570000005400512606202452020710 0ustar jenkinsjenkins00000000000000""" Import hooks; when installed with the install() function, these hooks allow importing .pyx files as if they were Python modules. If you want the hook installed every time you run Python you can add it to your Python version by adding these lines to sitecustomize.py (which you can create from scratch in site-packages if it doesn't exist there or somewhere else on your python path):: import pyximport pyximport.install() For instance on the Mac with a non-system Python 2.3, you could create sitecustomize.py with only those two lines at /usr/local/lib/python2.3/site-packages/sitecustomize.py . A custom distutils.core.Extension instance and setup() args (Distribution) for for the build can be defined by a .pyxbld file like: # examplemod.pyxbld def make_ext(modname, pyxfilename): from distutils.extension import Extension return Extension(name = modname, sources=[pyxfilename, 'hello.c'], include_dirs=['/myinclude'] ) def make_setup_args(): return dict(script_args=["--compiler=mingw32"]) Extra dependencies can be defined by a .pyxdep . See README. Since Cython 0.11, the :mod:`pyximport` module also has experimental compilation support for normal Python modules. This allows you to automatically run Cython on every .pyx and .py module that Python imports, including parts of the standard library and installed packages. Cython will still fail to compile a lot of Python modules, in which case the import mechanism will fall back to loading the Python source modules instead. The .py import mechanism is installed like this:: pyximport.install(pyimport = True) Running this module as a top-level script will run a test and then print the documentation. This code is based on the Py2.3+ import protocol as described in PEP 302. """ import sys import os import glob import imp mod_name = "pyximport" assert sys.hexversion >= 0x2030000, "need Python 2.3 or later" PYX_EXT = ".pyx" PYXDEP_EXT = ".pyxdep" PYXBLD_EXT = ".pyxbld" DEBUG_IMPORT = False def _print(message, args): if args: message = message % args print(message) def _debug(message, *args): if DEBUG_IMPORT: _print(message, args) def _info(message, *args): _print(message, args) # Performance problem: for every PYX file that is imported, we will # invoke the whole distutils infrastructure even if the module is # already built. It might be more efficient to only do it when the # mod time of the .pyx is newer than the mod time of the .so but # the question is how to get distutils to tell me the name of the .so # before it builds it. Maybe it is easy...but maybe the peformance # issue isn't real. def _load_pyrex(name, filename): "Load a pyrex file given a name and filename." def get_distutils_extension(modname, pyxfilename, language_level=None): # try: # import hashlib # except ImportError: # import md5 as hashlib # extra = "_" + hashlib.md5(open(pyxfilename).read()).hexdigest() # modname = modname + extra extension_mod,setup_args = handle_special_build(modname, pyxfilename) if not extension_mod: if not isinstance(pyxfilename, str): # distutils is stupid in Py2 and requires exactly 'str' # => encode accidentally coerced unicode strings back to str pyxfilename = pyxfilename.encode(sys.getfilesystemencoding()) from distutils.extension import Extension extension_mod = Extension(name = modname, sources=[pyxfilename]) if language_level is not None: extension_mod.cython_directives = {'language_level': language_level} return extension_mod,setup_args def handle_special_build(modname, pyxfilename): special_build = os.path.splitext(pyxfilename)[0] + PYXBLD_EXT ext = None setup_args={} if os.path.exists(special_build): # globls = {} # locs = {} # execfile(special_build, globls, locs) # ext = locs["make_ext"](modname, pyxfilename) mod = imp.load_source("XXXX", special_build, open(special_build)) make_ext = getattr(mod,'make_ext',None) if make_ext: ext = make_ext(modname, pyxfilename) assert ext and ext.sources, ("make_ext in %s did not return Extension" % special_build) make_setup_args = getattr(mod,'make_setup_args',None) if make_setup_args: setup_args = make_setup_args() assert isinstance(setup_args,dict), ("make_setup_args in %s did not return a dict" % special_build) assert set or setup_args, ("neither make_ext nor make_setup_args %s" % special_build) ext.sources = [os.path.join(os.path.dirname(special_build), source) for source in ext.sources] return ext, setup_args def handle_dependencies(pyxfilename): testing = '_test_files' in globals() dependfile = os.path.splitext(pyxfilename)[0] + PYXDEP_EXT # by default let distutils decide whether to rebuild on its own # (it has a better idea of what the output file will be) # but we know more about dependencies so force a rebuild if # some of the dependencies are newer than the pyxfile. if os.path.exists(dependfile): depends = open(dependfile).readlines() depends = [depend.strip() for depend in depends] # gather dependencies in the "files" variable # the dependency file is itself a dependency files = [dependfile] for depend in depends: fullpath = os.path.join(os.path.dirname(dependfile), depend) files.extend(glob.glob(fullpath)) # only for unit testing to see we did the right thing if testing: _test_files[:] = [] #$pycheck_no # if any file that the pyxfile depends upon is newer than # the pyx file, 'touch' the pyx file so that distutils will # be tricked into rebuilding it. for file in files: from distutils.dep_util import newer if newer(file, pyxfilename): _debug("Rebuilding %s because of %s", pyxfilename, file) filetime = os.path.getmtime(file) os.utime(pyxfilename, (filetime, filetime)) if testing: _test_files.append(file) def build_module(name, pyxfilename, pyxbuild_dir=None, inplace=False, language_level=None): assert os.path.exists(pyxfilename), ( "Path does not exist: %s" % pyxfilename) handle_dependencies(pyxfilename) extension_mod,setup_args = get_distutils_extension(name, pyxfilename, language_level) build_in_temp=pyxargs.build_in_temp sargs=pyxargs.setup_args.copy() sargs.update(setup_args) build_in_temp=sargs.pop('build_in_temp',build_in_temp) from . import pyxbuild so_path = pyxbuild.pyx_to_dll(pyxfilename, extension_mod, build_in_temp=build_in_temp, pyxbuild_dir=pyxbuild_dir, setup_args=sargs, inplace=inplace, reload_support=pyxargs.reload_support) assert os.path.exists(so_path), "Cannot find: %s" % so_path junkpath = os.path.join(os.path.dirname(so_path), name+"_*") #very dangerous with --inplace ? yes, indeed, trying to eat my files ;) junkstuff = glob.glob(junkpath) for path in junkstuff: if path!=so_path: try: os.remove(path) except IOError: _info("Couldn't remove %s", path) return so_path def load_module(name, pyxfilename, pyxbuild_dir=None, is_package=False, build_inplace=False, language_level=None, so_path=None): try: if so_path is None: if is_package: module_name = name + '.__init__' else: module_name = name so_path = build_module(module_name, pyxfilename, pyxbuild_dir, inplace=build_inplace, language_level=language_level) mod = imp.load_dynamic(name, so_path) if is_package and not hasattr(mod, '__path__'): mod.__path__ = [os.path.dirname(so_path)] assert mod.__file__ == so_path, (mod.__file__, so_path) except Exception: if pyxargs.load_py_module_on_import_failure and pyxfilename.endswith('.py'): # try to fall back to normal import mod = imp.load_source(name, pyxfilename) assert mod.__file__ in (pyxfilename, pyxfilename+'c', pyxfilename+'o'), (mod.__file__, pyxfilename) else: tb = sys.exc_info()[2] import traceback exc = ImportError("Building module %s failed: %s" % ( name, traceback.format_exception_only(*sys.exc_info()[:2]))) if sys.version_info[0] >= 3: raise exc.with_traceback(tb) else: exec("raise exc, None, tb", {'exc': exc, 'tb': tb}) return mod # import hooks class PyxImporter(object): """A meta-path importer for .pyx files. """ def __init__(self, extension=PYX_EXT, pyxbuild_dir=None, inplace=False, language_level=None): self.extension = extension self.pyxbuild_dir = pyxbuild_dir self.inplace = inplace self.language_level = language_level def find_module(self, fullname, package_path=None): if fullname in sys.modules and not pyxargs.reload_support: return None # only here when reload() try: fp, pathname, (ext,mode,ty) = imp.find_module(fullname,package_path) if fp: fp.close() # Python should offer a Default-Loader to avoid this double find/open! if pathname and ty == imp.PKG_DIRECTORY: pkg_file = os.path.join(pathname, '__init__'+self.extension) if os.path.isfile(pkg_file): return PyxLoader(fullname, pathname, init_path=pkg_file, pyxbuild_dir=self.pyxbuild_dir, inplace=self.inplace, language_level=self.language_level) if pathname and pathname.endswith(self.extension): return PyxLoader(fullname, pathname, pyxbuild_dir=self.pyxbuild_dir, inplace=self.inplace, language_level=self.language_level) if ty != imp.C_EXTENSION: # only when an extension, check if we have a .pyx next! return None # find .pyx fast, when .so/.pyd exist --inplace pyxpath = os.path.splitext(pathname)[0]+self.extension if os.path.isfile(pyxpath): return PyxLoader(fullname, pyxpath, pyxbuild_dir=self.pyxbuild_dir, inplace=self.inplace, language_level=self.language_level) # .so/.pyd's on PATH should not be remote from .pyx's # think no need to implement PyxArgs.importer_search_remote here? except ImportError: pass # searching sys.path ... #if DEBUG_IMPORT: print "SEARCHING", fullname, package_path if '.' in fullname: # only when package_path anyway? mod_parts = fullname.split('.') module_name = mod_parts[-1] else: module_name = fullname pyx_module_name = module_name + self.extension # this may work, but it returns the file content, not its path #import pkgutil #pyx_source = pkgutil.get_data(package, pyx_module_name) if package_path: paths = package_path else: paths = sys.path join_path = os.path.join is_file = os.path.isfile is_abs = os.path.isabs abspath = os.path.abspath #is_dir = os.path.isdir sep = os.path.sep for path in paths: if not path: path = os.getcwd() elif not is_abs(path): path = abspath(path) if is_file(path+sep+pyx_module_name): return PyxLoader(fullname, join_path(path, pyx_module_name), pyxbuild_dir=self.pyxbuild_dir, inplace=self.inplace, language_level=self.language_level) # not found, normal package, not a .pyx file, none of our business _debug("%s not found" % fullname) return None class PyImporter(PyxImporter): """A meta-path importer for normal .py files. """ def __init__(self, pyxbuild_dir=None, inplace=False, language_level=None): if language_level is None: language_level = sys.version_info[0] self.super = super(PyImporter, self) self.super.__init__(extension='.py', pyxbuild_dir=pyxbuild_dir, inplace=inplace, language_level=language_level) self.uncompilable_modules = {} self.blocked_modules = ['Cython', 'pyxbuild', 'pyximport.pyxbuild', 'distutils.extension', 'distutils.sysconfig'] def find_module(self, fullname, package_path=None): if fullname in sys.modules: return None if fullname.startswith('Cython.'): return None if fullname in self.blocked_modules: # prevent infinite recursion return None if _lib_loader.knows(fullname): return _lib_loader _debug("trying import of module '%s'", fullname) if fullname in self.uncompilable_modules: path, last_modified = self.uncompilable_modules[fullname] try: new_last_modified = os.stat(path).st_mtime if new_last_modified > last_modified: # import would fail again return None except OSError: # module is no longer where we found it, retry the import pass self.blocked_modules.append(fullname) try: importer = self.super.find_module(fullname, package_path) if importer is not None: if importer.init_path: path = importer.init_path real_name = fullname + '.__init__' else: path = importer.path real_name = fullname _debug("importer found path %s for module %s", path, real_name) try: so_path = build_module( real_name, path, pyxbuild_dir=self.pyxbuild_dir, language_level=self.language_level, inplace=self.inplace) _lib_loader.add_lib(fullname, path, so_path, is_package=bool(importer.init_path)) return _lib_loader except Exception: if DEBUG_IMPORT: import traceback traceback.print_exc() # build failed, not a compilable Python module try: last_modified = os.stat(path).st_mtime except OSError: last_modified = 0 self.uncompilable_modules[fullname] = (path, last_modified) importer = None finally: self.blocked_modules.pop() return importer class LibLoader(object): def __init__(self): self._libs = {} def load_module(self, fullname): try: source_path, so_path, is_package = self._libs[fullname] except KeyError: raise ValueError("invalid module %s" % fullname) _debug("Loading shared library module '%s' from %s", fullname, so_path) return load_module(fullname, source_path, so_path=so_path, is_package=is_package) def add_lib(self, fullname, path, so_path, is_package): self._libs[fullname] = (path, so_path, is_package) def knows(self, fullname): return fullname in self._libs _lib_loader = LibLoader() class PyxLoader(object): def __init__(self, fullname, path, init_path=None, pyxbuild_dir=None, inplace=False, language_level=None): _debug("PyxLoader created for loading %s from %s (init path: %s)", fullname, path, init_path) self.fullname = fullname self.path, self.init_path = path, init_path self.pyxbuild_dir = pyxbuild_dir self.inplace = inplace self.language_level = language_level def load_module(self, fullname): assert self.fullname == fullname, ( "invalid module, expected %s, got %s" % ( self.fullname, fullname)) if self.init_path: # package #print "PACKAGE", fullname module = load_module(fullname, self.init_path, self.pyxbuild_dir, is_package=True, build_inplace=self.inplace, language_level=self.language_level) module.__path__ = [self.path] else: #print "MODULE", fullname module = load_module(fullname, self.path, self.pyxbuild_dir, build_inplace=self.inplace, language_level=self.language_level) return module #install args class PyxArgs(object): build_dir=True build_in_temp=True setup_args={} #None ##pyxargs=None def _have_importers(): has_py_importer = False has_pyx_importer = False for importer in sys.meta_path: if isinstance(importer, PyxImporter): if isinstance(importer, PyImporter): has_py_importer = True else: has_pyx_importer = True return has_py_importer, has_pyx_importer def install(pyximport=True, pyimport=False, build_dir=None, build_in_temp=True, setup_args={}, reload_support=False, load_py_module_on_import_failure=False, inplace=False, language_level=None): """Main entry point. Call this to install the .pyx import hook in your meta-path for a single Python process. If you want it to be installed whenever you use Python, add it to your sitecustomize (as described above). You can pass ``pyimport=True`` to also install the .py import hook in your meta-path. Note, however, that it is highly experimental, will not work for most .py files, and will therefore only slow down your imports. Use at your own risk. By default, compiled modules will end up in a ``.pyxbld`` directory in the user's home directory. Passing a different path as ``build_dir`` will override this. ``build_in_temp=False`` will produce the C files locally. Working with complex dependencies and debugging becomes more easy. This can principally interfere with existing files of the same name. build_in_temp can be overriden by .pyxbld/make_setup_args() by a dict item of 'build_in_temp' ``setup_args``: dict of arguments for Distribution - see distutils.core.setup() . They are extended/overriden by those of .pyxbld/make_setup_args() ``reload_support``: Enables support for dynamic reload(), e.g. after a change in the Cython code. Additional files .reloadNN may arise on that account, when the previously loaded module file cannot be overwritten. ``load_py_module_on_import_failure``: If the compilation of a .py file succeeds, but the subsequent import fails for some reason, retry the import with the normal .py module instead of the compiled module. Note that this may lead to unpredictable results for modules that change the system state during their import, as the second import will rerun these modifications in whatever state the system was left after the import of the compiled module failed. ``inplace``: Install the compiled module next to the source file. ``language_level``: The source language level to use: 2 or 3. The default is to use the language level of the current Python runtime for .py files and Py2 for .pyx files. """ if not build_dir: build_dir = os.path.join(os.path.expanduser('~'), '.pyxbld') global pyxargs pyxargs = PyxArgs() #$pycheck_no pyxargs.build_dir = build_dir pyxargs.build_in_temp = build_in_temp pyxargs.setup_args = (setup_args or {}).copy() pyxargs.reload_support = reload_support pyxargs.load_py_module_on_import_failure = load_py_module_on_import_failure has_py_importer, has_pyx_importer = _have_importers() py_importer, pyx_importer = None, None if pyimport and not has_py_importer: py_importer = PyImporter(pyxbuild_dir=build_dir, inplace=inplace, language_level=language_level) # make sure we import Cython before we install the import hook import Cython.Compiler.Main, Cython.Compiler.Pipeline, Cython.Compiler.Optimize sys.meta_path.insert(0, py_importer) if pyximport and not has_pyx_importer: pyx_importer = PyxImporter(pyxbuild_dir=build_dir, inplace=inplace, language_level=language_level) sys.meta_path.append(pyx_importer) return py_importer, pyx_importer def uninstall(py_importer, pyx_importer): """ Uninstall an import hook. """ try: sys.meta_path.remove(py_importer) except ValueError: pass try: sys.meta_path.remove(pyx_importer) except ValueError: pass # MAIN def show_docs(): import __main__ __main__.__name__ = mod_name for name in dir(__main__): item = getattr(__main__, name) try: setattr(item, "__module__", mod_name) except (AttributeError, TypeError): pass help(__main__) if __name__ == '__main__': show_docs() Cython-0.23.4/pyximport/pyxbuild.py0000644000175600017570000001300612606202452020471 0ustar jenkinsjenkins00000000000000"""Build a Pyrex file from .pyx source to .so loadable module using the installed distutils infrastructure. Call: out_fname = pyx_to_dll("foo.pyx") """ import os import sys from distutils.errors import DistutilsArgError, DistutilsError, CCompilerError from distutils.extension import Extension from distutils.util import grok_environment_error try: from Cython.Distutils import build_ext HAS_CYTHON = True except ImportError: HAS_CYTHON = False DEBUG = 0 _reloads={} def pyx_to_dll(filename, ext = None, force_rebuild = 0, build_in_temp=False, pyxbuild_dir=None, setup_args={}, reload_support=False, inplace=False): """Compile a PYX file to a DLL and return the name of the generated .so or .dll .""" assert os.path.exists(filename), "Could not find %s" % os.path.abspath(filename) path, name = os.path.split(os.path.abspath(filename)) if not ext: modname, extension = os.path.splitext(name) assert extension in (".pyx", ".py"), extension if not HAS_CYTHON: filename = filename[:-len(extension)] + '.c' ext = Extension(name=modname, sources=[filename]) if not pyxbuild_dir: pyxbuild_dir = os.path.join(path, "_pyxbld") package_base_dir = path for package_name in ext.name.split('.')[-2::-1]: package_base_dir, pname = os.path.split(package_base_dir) if pname != package_name: # something is wrong - package path doesn't match file path package_base_dir = None break script_args=setup_args.get("script_args",[]) if DEBUG or "--verbose" in script_args: quiet = "--verbose" else: quiet = "--quiet" args = [quiet, "build_ext"] if force_rebuild: args.append("--force") if inplace and package_base_dir: args.extend(['--build-lib', package_base_dir]) if ext.name == '__init__' or ext.name.endswith('.__init__'): # package => provide __path__ early if not hasattr(ext, 'cython_directives'): ext.cython_directives = {'set_initial_path' : 'SOURCEFILE'} elif 'set_initial_path' not in ext.cython_directives: ext.cython_directives['set_initial_path'] = 'SOURCEFILE' if HAS_CYTHON and build_in_temp: args.append("--pyrex-c-in-temp") sargs = setup_args.copy() sargs.update({ "script_name": None, "script_args": args + script_args, }) # late import, in case setuptools replaced it from distutils.dist import Distribution dist = Distribution(sargs) if not dist.ext_modules: dist.ext_modules = [] dist.ext_modules.append(ext) if HAS_CYTHON: dist.cmdclass = {'build_ext': build_ext} build = dist.get_command_obj('build') build.build_base = pyxbuild_dir cfgfiles = dist.find_config_files() dist.parse_config_files(cfgfiles) try: ok = dist.parse_command_line() except DistutilsArgError: raise if DEBUG: print("options (after parsing command line):") dist.dump_option_dicts() assert ok try: obj_build_ext = dist.get_command_obj("build_ext") dist.run_commands() so_path = obj_build_ext.get_outputs()[0] if obj_build_ext.inplace: # Python distutils get_outputs()[ returns a wrong so_path # when --inplace ; see http://bugs.python.org/issue5977 # workaround: so_path = os.path.join(os.path.dirname(filename), os.path.basename(so_path)) if reload_support: org_path = so_path timestamp = os.path.getmtime(org_path) global _reloads last_timestamp, last_path, count = _reloads.get(org_path, (None,None,0) ) if last_timestamp == timestamp: so_path = last_path else: basename = os.path.basename(org_path) while count < 100: count += 1 r_path = os.path.join(obj_build_ext.build_lib, basename + '.reload%s'%count) try: import shutil # late import / reload_support is: debugging try: # Try to unlink first --- if the .so file # is mmapped by another process, # overwriting its contents corrupts the # loaded image (on Linux) and crashes the # other process. On Windows, unlinking an # open file just fails. if os.path.isfile(r_path): os.unlink(r_path) except OSError: continue shutil.copy2(org_path, r_path) so_path = r_path except IOError: continue break else: # used up all 100 slots raise ImportError("reload count for %s reached maximum"%org_path) _reloads[org_path]=(timestamp, so_path, count) return so_path except KeyboardInterrupt: sys.exit(1) except (IOError, os.error): exc = sys.exc_info()[1] error = grok_environment_error(exc) if DEBUG: sys.stderr.write(error + "\n") raise if __name__=="__main__": pyx_to_dll("dummy.pyx") from . import test Cython-0.23.4/pyximport/__init__.py0000644000175600017570000000011712606202452020367 0ustar jenkinsjenkins00000000000000from .pyximport import * # replicate docstring from .pyximport import __doc__ Cython-0.23.4/pyximport/README0000644000175600017570000000630512606202452017143 0ustar jenkinsjenkins00000000000000 == Pyximport == Download: pyx-import-1.0.tar.gz Pyrex is a compiler. Therefore it is natural that people tend to go through an edit/compile/test cycle with Pyrex modules. But my personal opinion is that one of the deep insights in Python's implementation is that a language can be compiled (Python modules are compiled to .pyc) files and hide that compilation process from the end-user so that they do not have to worry about it. Pyximport does this for Pyrex modules. For instance if you write a Pyrex module called "foo.pyx", with Pyximport you can import it in a regular Python module like this: import pyximport; pyximport.install() import foo Doing so will result in the compilation of foo.pyx (with appropriate exceptions if it has an error in it). If you would always like to import pyrex files without building them specially, you can also the first line above to your sitecustomize.py. That will install the hook every time you run Python. Then you can use Pyrex modules just with simple import statements. I like to test my Pyrex modules like this: python -c "import foo" See help(pyximport.install) to learn its options for controlling the default behavior of "import" and "reload". == Dependency Handling == In Pyximport 1.1 it is possible to declare that your module depends on multiple files, (likely ".h" and ".pxd" files). If your Pyrex module is named "foo" and thus has the filename "foo.pyx" then you should make another file in the same directory called "foo.pyxdep". The "modname.pyxdep" file can be a list of filenames or "globs" (like "*.pxd" or "include/*.h"). Each filename or glob must be on a separate line. Pyximport will check the file date for each of those files before deciding whether to rebuild the module. In order to keep track of the fact that the dependency has been handled, Pyximport updates the modification time of your ".pyx" source file. Future versions may do something more sophisticated like informing distutils of the dependencies directly. == Limitations == Pyximport does not give you any control over how your Pyrex file is compiled. Usually the defaults are fine. You might run into problems if you wanted to write your program in half-C, half-Pyrex and build them into a single library. Pyximport 1.2 will probably do this. Pyximport does not hide the Distutils/GCC warnings and errors generated by the import process. Arguably this will give you better feedback if something went wrong and why. And if nothing went wrong it will give you the warm fuzzy that pyximport really did rebuild your module as it was supposed to. == For further thought and discussion == "setup.py install" does not modify sitecustomize.py for you. Should it? Modifying Python's "standard interpreter" behaviour may be more than most people expect of a package they install.. Pyximport puts your ".c" file beside your ".pyx" file (analogous to ".pyc" beside ".py"). But it puts the platform-specific binary in a build directory as per normal for Distutils. If I could wave a magic wand and get Pyrex or distutils or whoever to put the build directory I might do it but not necessarily: having it at the top level is VERY HELPFUL for debugging Pyrex problems. Cython-0.23.4/pyximport/PKG-INFO0000644000175600017570000000046612606202452017362 0ustar jenkinsjenkins00000000000000Metadata-Version: 1.0 Name: pyximport Version: 1.0 Summary: Hooks to build and run Pyrex files as if they were simple Python files Home-page: http://www.prescod.net/pyximport Author: Paul Prescod Author-email: paul@prescod.net License: Python Description: UNKNOWN Keywords: pyrex import hook Platform: UNKNOWN Cython-0.23.4/pyximport/test/0000755000175600017570000000000012606202455017241 5ustar jenkinsjenkins00000000000000Cython-0.23.4/pyximport/test/test_reload.py0000644000175600017570000000163012606202452022115 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import, print_function import time, os, sys from . import test_pyximport if 1: from distutils import sysconfig try: sysconfig.set_python_build() except AttributeError: pass import pyxbuild print(pyxbuild.distutils.sysconfig == sysconfig) def test(): tempdir = test_pyximport.make_tempdir() sys.path.append(tempdir) hello_file = os.path.join(tempdir, "hello.pyx") open(hello_file, "w").write("x = 1; print x; before = 'before'\n") import hello assert hello.x == 1 time.sleep(1) # sleep to make sure that new "hello.pyx" has later # timestamp than object file. open(hello_file, "w").write("x = 2; print x; after = 'after'\n") reload(hello) assert hello.x == 2, "Reload should work on Python 2.3 but not 2.2" test_pyximport.remove_tempdir(tempdir) if __name__=="__main__": test() Cython-0.23.4/pyximport/test/test_pyximport.py0000644000175600017570000000402612606202452022724 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import, print_function from pyximport import pyximport; pyximport.install(reload_support=True) import os, sys import time, shutil import tempfile def make_tempdir(): tempdir = os.path.join(tempfile.gettempdir(), "pyrex_temp") if os.path.exists(tempdir): remove_tempdir(tempdir) os.mkdir(tempdir) return tempdir def remove_tempdir(tempdir): shutil.rmtree(tempdir, 0, on_remove_file_error) def on_remove_file_error(func, path, excinfo): print("Sorry! Could not remove a temp file:", path) print("Extra information.") print(func, excinfo) print("You may want to delete this yourself when you get a chance.") def test(): pyximport._test_files = [] tempdir = make_tempdir() sys.path.append(tempdir) filename = os.path.join(tempdir, "dummy.pyx") open(filename, "w").write("print 'Hello world from the Pyrex install hook'") import dummy reload(dummy) depend_filename = os.path.join(tempdir, "dummy.pyxdep") depend_file = open(depend_filename, "w") depend_file.write("*.txt\nfoo.bar") depend_file.close() build_filename = os.path.join(tempdir, "dummy.pyxbld") build_file = open(build_filename, "w") build_file.write(""" from distutils.extension import Extension def make_ext(name, filename): return Extension(name=name, sources=[filename]) """) build_file.close() open(os.path.join(tempdir, "foo.bar"), "w").write(" ") open(os.path.join(tempdir, "1.txt"), "w").write(" ") open(os.path.join(tempdir, "abc.txt"), "w").write(" ") reload(dummy) assert len(pyximport._test_files)==1, pyximport._test_files reload(dummy) time.sleep(1) # sleep a second to get safer mtimes open(os.path.join(tempdir, "abc.txt"), "w").write(" ") print("Here goes the reolad") reload(dummy) assert len(pyximport._test_files) == 1, pyximport._test_files reload(dummy) assert len(pyximport._test_files) == 0, pyximport._test_files remove_tempdir(tempdir) if __name__=="__main__": test() Cython-0.23.4/docs/0000755000175600017570000000000012606202455015137 5ustar jenkinsjenkins00000000000000Cython-0.23.4/docs/welcome.rst0000644000175600017570000000675612606202452017337 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _overview: ******** Welcome! ******** =============== What is Cython? =============== Cython is a programming language based on Python with extra syntax to provide static type declarations. ================ What Does It Do? ================ It takes advantage of the benefits of Python while allowing one to achieve the speed of C. ============================ How Exactly Does It Do That? ============================ The source code gets translated into optimized C/C++ code and compiled as Python extension modules. This allows for both very fast program execution and tight integration with external C libraries, while keeping up the high *programmer productivity* for which the Python language is well known. ============= Tell Me More! ============= The Python language is well known. The primary Python execution environment is commonly referred to as CPython, as it is written in C. Other major implementations use: :Java: Jython [#Jython]_ :C#: IronPython [#IronPython]_) :Python itself: PyPy [#PyPy]_ Written in C, CPython has been conducive to wrapping many external libraries that interface through the C language. It has, however, remained non trivial to write the necessary glue code in C, especially for programmers who are more fluent in a high-level language like Python than in a do-it-yourself language like C. Originally based on the well-known Pyrex [#Pyrex]_, the Cython project has approached this problem by means of a source code compiler that translates Python code to equivalent C code. This code is executed within the CPython runtime environment, but at the speed of compiled C and with the ability to call directly into C libraries. At the same time, it keeps the original interface of the Python source code, which makes it directly usable from Python code. These two-fold characteristics enable Cython’s two major use cases: #. Extending the CPython interpreter with fast binary modules, and #. Interfacing Python code with external C libraries. While Cython can compile (most) regular Python code, the generated C code usually gains major (and sometime impressive) speed improvements from optional static type declarations for both Python and C types. These allow Cython to assign C semantics to parts of the code, and to translate them into very efficient C code. Type declarations can therefore be used for two purposes: #. For moving code sections from dynamic Python semantics into static-and-fast C semantics, but also for.. #. Directly manipulating types defined in external libraries. Cython thus merges the two worlds into a very broadly applicable programming language. ================== Where Do I Get It? ================== Well.. at `cython.org `_.. of course! ====================== How Do I Report a Bug? ====================== ================================= I Want To Make A Feature Request! ================================= ============================================ Is There a Mail List? How Do I Contact You? ============================================ .. rubric:: Footnotes .. [#Jython] **Jython:** \J. Huginin, B. Warsaw, F. Bock, et al., Jython: Python for the Java platform, http://www.jython.org .. [#IronPython] **IronPython:** Jim Hugunin et al., http://www.codeplex.com/IronPython. .. [#PyPy] **PyPy:** The PyPy Group, PyPy: a Python implementation written in Python, http://pypy.org .. [#Pyrex] **Pyrex:** G. Ewing, Pyrex: C-Extensions for Python, http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/ Cython-0.23.4/docs/index.rst0000644000175600017570000000053412606202452016777 0ustar jenkinsjenkins00000000000000 Welcome to Cython's Documentation ================================= Also see the current `in-development version `_ of the documentation and the `Cython project homepage `_. .. toctree:: :maxdepth: 2 src/quickstart/index src/tutorial/index src/userguide/index src/reference/index Cython-0.23.4/docs/conf.py0000644000175600017570000003356212606202452016444 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- # # Cython documentation build configuration file, created by # sphinx-quickstart on Sun Jun 29 13:36:38 2014. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os, os.path, re import itertools import datetime YEAR = datetime.date.today().strftime('%Y') # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) sys.path.append(os.path.abspath('sphinxext')) # Import support for ipython console session syntax highlighting (lives # in the sphinxext directory defined above) import ipython_console_highlighting # -- General configuration ----------------------------------------------------- # Use cython as the default syntax highlighting language, as python is a subset # this does the right thing highlight_language = 'cython' # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ 'ipython_console_highlighting', 'cython_highlighting', 'sphinx.ext.pngmath', 'sphinx.ext.todo', 'sphinx.ext.intersphinx' ] try: import rst2pdf except ImportError: pass else: extensions.append('rst2pdf.pdfbuilder') # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = 'Cython' authors = 'Stefan Behnel, Robert Bradshaw, Dag Sverre Seljebotn, Greg Ewing, William Stein, Gabriel Gellner, et al.' copyright = '%s, %s' % (YEAR, authors) # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The full version, including alpha/beta/rc tags. release = '0.15' try: _match_version = re.compile(r'^\s*_*version\s*_*\s*=\s*["\']([^"\']+)["\'].*').match with open(os.path.join(os.path.dirname(__file__), '..', 'Cython', 'Shadow.py')) as _f: for line in itertools.islice(_f, 5): # assume version comes early enough _m = _match_version(line) if _m: release = _m.group(1) break else: print("FAILED TO PARSE PROJECT VERSION !") except: pass # The short X.Y version. version = re.sub('^([0-9]+[.][0-9]+).*', '\g<1>', release) # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['py*', 'build', 'BUILD'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # todo todo_include_todos = True # intersphinx for standard :keyword:s (def, for, etc.) intersphinx_mapping = {'python': ('http://docs.python.org/3/', None)} # If true, keep warnings as "system message" paragraphs in the built documents. #keep_warnings = False # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'default' try: import sphinx if os.path.isdir(os.path.join(os.path.dirname(sphinx.__file__), 'themes', 'nature')): html_theme = 'nature' except (ImportError, AttributeError): pass # use default theme # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. html_logo = "_static/cythonlogo.png" # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. html_favicon = "_static/favicon.ico" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. html_domain_indices = False # If false, no index is generated. html_use_index = False # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'Cythondoc' # -- Options for LaTeX output -------------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). _stdauthor = r'Stefan Behnel, Robert Bradshaw, William Stein\\ Gary Furnish, Dag Seljebotn, Greg Ewing\\ Gabriel Gellner, editor' latex_documents = [ ('src/reference/index', 'reference.tex', 'Cython Reference Guide', _stdauthor, 'manual'), ('src/tutorial/index', 'tutorial.tex', 'Cython Tutorial', _stdauthor, 'manual') ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'cython', u'Cython Documentation', [authors], 1) ] # If true, show URL addresses after external links. #man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'Cython', u'Cython Documentation', authors, 'Cython', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. #texinfo_appendices = [] # If false, no module index is generated. #texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. #texinfo_no_detailmenu = False # -- Options for Epub output --------------------------------------------------- # Bibliographic Dublin Core info. epub_title = u'Cython' epub_author = authors epub_publisher = u'' epub_copyright = copyright # The language of the text. It defaults to the language option # or en if the language is not set. #epub_language = '' # The scheme of the identifier. Typical schemes are ISBN or URL. #epub_scheme = '' # The unique identifier of the text. This can be a ISBN number # or the project homepage. #epub_identifier = '' # A unique identification for the text. #epub_uid = '' # A tuple containing the cover image and cover page html template filenames. #epub_cover = () # A sequence of (type, uri, title) tuples for the guide element of content.opf. #epub_guide = () # HTML files that should be inserted before the pages created by sphinx. # The format is a list of tuples containing the path and title. #epub_pre_files = [] # HTML files shat should be inserted after the pages created by sphinx. # The format is a list of tuples containing the path and title. #epub_post_files = [] # A list of files that should not be packed into the epub file. #epub_exclude_files = [] # The depth of the table of contents in toc.ncx. #epub_tocdepth = 3 # Allow duplicate toc entries. #epub_tocdup = True # Fix unsupported image types using the PIL. #epub_fix_images = False # Scale large images. #epub_max_image_width = 0 # If 'no', URL addresses will not be shown. #epub_show_urls = 'inline' # If false, no index is generated. #epub_use_index = True # -- Options for PDF output -------------------------------------------------- # Grouping the document tree into PDF files. List of tuples # (source start file, target name, title, author, options). # # If there is more than one author, separate them with \\. # For example: r'Guido van Rossum\\Fred L. Drake, Jr., editor' # # The options element is a dictionary that lets you override # this config per-document. # For example, # ('index', u'MyProject', u'My Project', u'Author Name', # dict(pdf_compressed = True)) # would mean that specific document would be compressed # regardless of the global pdf_compressed setting. pdf_documents = [ ('index', project, project, authors.replace(', ', '\\\\')), ] # A comma-separated list of custom stylesheets. Example: pdf_stylesheets = ['sphinx','kerning','a4'] # A list of folders to search for stylesheets. Example: pdf_style_path = ['.', '_styles'] # Create a compressed PDF # Use True/False or 1/0 # Example: compressed=True pdf_compressed = True # A colon-separated list of folders to search for fonts. Example: # pdf_font_path = ['/usr/share/fonts', '/usr/share/texmf-dist/fonts/'] # Language to be used for hyphenation support #pdf_language = "en_US" # Mode for literal blocks wider than the frame. Can be # overflow, shrink or truncate pdf_fit_mode = "shrink" # Section level that forces a break page. # For example: 1 means top-level sections start in a new page # 0 means disabled #pdf_break_level = 0 # When a section starts in a new page, force it to be 'even', 'odd', # or just use 'any' #pdf_breakside = 'any' # Insert footnotes where they are defined instead of # at the end. #pdf_inline_footnotes = True # verbosity level. 0 1 or 2 #pdf_verbosity = 0 # If false, no index is generated. pdf_use_index = False # If false, no modindex is generated. pdf_use_modindex = False # If false, no coverpage is generated. #pdf_use_coverpage = True # Name of the cover page template to use #pdf_cover_template = 'sphinxcover.tmpl' # Documents to append as an appendix to all manuals. #pdf_appendices = [] # Enable experimental feature to split table cells. Use it # if you get "DelayedTable too big" errors #pdf_splittables = False # Set the default DPI for images #pdf_default_dpi = 72 # Enable rst2pdf extension modules (default is only vectorpdf) # you need vectorpdf if you want to use sphinx's graphviz support #pdf_extensions = ['vectorpdf'] # Page template name for "regular" pages #pdf_page_template = 'cutePage' # Show Table Of Contents at the beginning? pdf_use_toc = False # How many levels deep should the table of contents be? pdf_toc_depth = 9999 # Add section number to section references pdf_use_numbered_links = False # Background images fitting mode pdf_fit_background_mode = 'scale' Cython-0.23.4/docs/TODO0000644000175600017570000000207312606202452015626 0ustar jenkinsjenkins00000000000000Background ---------- [brain dump] The "Old Cython Users Guide" is a derivative of the old Pyrex documentation. It underwent substantial editing by Peter Alexandar to become the Reference Guide, which is oriented around bullet points and lists rather than prose. This transition was incomplete. At nearly the same time, Robert, Dag, and Stefan wrote a tutorial as part of the SciPy proceedings. It was felt that the content there was cleaner and more up to date than anything else, and this became the basis for the "Getting Started" and "Tutorials" sections. However, it simply doesn't have as much content as the old documentation used to. Eventually, it seems all of the old users manual could be whittled down into independent tutorial topics. Much discussion of what we'd like to see is at http://www.mail-archive.com/cython-dev@codespeak.net/msg06945.html There is currently a huge amount of redundancy, but no one section has it all. Also, we should go through the wiki enhancement proposal list and make sure to transfer the (done) ones into the user manual. Cython-0.23.4/docs/README0000644000175600017570000000067412606202452016023 0ustar jenkinsjenkins00000000000000Cython's entire documentation suite is currently being overhauled. For the time being, I'll use this page to post notes. The previous Cython documentation files are hosted at http://hg.cython.org/cython-docs Notes ======= 1) Some css work should definitely be done. 2) Use local 'top-of-page' contents rather than the sidebar, imo. 3) Provide a link from each (sub)section to the TOC of the page. 4) Fix cython highlighter for cdef blocks Cython-0.23.4/docs/Makefile0000644000175600017570000001307712606202452016604 0ustar jenkinsjenkins00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = a4 BUILDDIR = build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean pdf html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* pdf: $(SPHINXBUILD) -b pdf $(ALLSPHINXOPTS) $(BUILDDIR)/pdf @echo @echo "Build finished. The PDF is in $(BUILDDIR)/pdf." html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Cython.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Cython.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/Cython" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Cython" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." Cython-0.23.4/docs/.hgignore0000644000175600017570000000007712606202452016743 0ustar jenkinsjenkins00000000000000syntax: glob *.pyc *~ .*.swp syntax: regexp ^build/ ^_build/ Cython-0.23.4/docs/src/0000755000175600017570000000000012606202455015726 5ustar jenkinsjenkins00000000000000Cython-0.23.4/docs/src/userguide/0000755000175600017570000000000012606202455017722 5ustar jenkinsjenkins00000000000000Cython-0.23.4/docs/src/userguide/wrapping_CPlusPlus.rst0000644000175600017570000004773412606202452024271 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _wrapping-cplusplus: ******************************** Using C++ in Cython ******************************** Overview ========= Cython v0.13 introduces native support for most of the C++ language. This means that the previous tricks that were used to wrap C++ classes (as described in http://wiki.cython.org/WrappingCPlusPlus_ForCython012AndLower) are no longer needed. Wrapping C++ classes with Cython is now much more straightforward. This document describe in details the new way of wrapping C++ code. What's new in Cython v0.13 about C++ --------------------------------------------------- For users of previous Cython versions, here is a brief overview of the main new features of Cython v0.13 regarding C++ support: * C++ objects can now be dynamically allocated with ``new`` and ``del`` keywords. * C++ objects can be stack-allocated. * C++ classes can be declared with the new keyword ``cppclass``. * Templated classes and functions are supported. * Overloaded functions are supported. * Overloading of C++ operators (such as operator+, operator[],...) is supported. Procedure Overview ------------------- The general procedure for wrapping a C++ file can now be described as follows: * Specify C++ language in :file:`setup.py` script or locally in a source file. * Create one or more .pxd files with ``cdef extern from`` blocks and (if existing) the C++ namespace name. In these blocks, * declare classes as ``cdef cppclass`` blocks * declare public names (variables, methods and constructors) * Write an extension modules, ``cimport`` from the .pxd file and use the declarations. A simple Tutorial ================== An example C++ API ------------------- Here is a tiny C++ API which we will use as an example throughout this document. Let's assume it will be in a header file called :file:`Rectangle.h`: .. sourcecode:: c++ namespace shapes { class Rectangle { public: int x0, y0, x1, y1; Rectangle(int x0, int y0, int x1, int y1); ~Rectangle(); int getLength(); int getHeight(); int getArea(); void move(int dx, int dy); }; } and the implementation in the file called :file:`Rectangle.cpp`: .. sourcecode:: c++ #include "Rectangle.h" namespace shapes { Rectangle::Rectangle(int X0, int Y0, int X1, int Y1) { x0 = X0; y0 = Y0; x1 = X1; y1 = Y1; } Rectangle::~Rectangle() { } int Rectangle::getLength() { return (x1 - x0); } int Rectangle::getHeight() { return (y1 - y0); } int Rectangle::getArea() { return (x1 - x0) * (y1 - y0); } void Rectangle::move(int dx, int dy) { x0 += dx; y0 += dy; x1 += dx; y1 += dy; } } This is pretty dumb, but should suffice to demonstrate the steps involved. Specify C++ language in setup.py --------------------------------- The best way to build Cython code from :file:`setup.py` scripts is the ``cythonize()`` function. To make Cython generate and compile C++ code with distutils, you just need to pass the option ``language="c++"``:: from distutils.core import setup from Cython.Build import cythonize setup(ext_modules = cythonize( "rect.pyx", # our Cython source sources=["Rectangle.cpp"], # additional source file(s) language="c++", # generate C++ code )) Cython will generate and compile the :file:`rect.cpp` file (from the :file:`rect.pyx`), then it will compile :file:`Rectangle.cpp` (implementation of the ``Rectangle`` class) and link both objects files together into :file:`rect.so`, which you can then import in Python using ``import rect`` (if you forget to link the :file:`Rectangle.o`, you will get missing symbols while importing the library in Python). Note that the ``language`` option has no effect on user provided Extension objects that are passed into ``cythonize()``. It is only used for modules found by file name (as in the example above). The ``cythonize()`` function in Cython versions up to 0.21 does not recognize the ``language`` option and it needs to be specified as an option to an :class:`Extension` that describes your extension and that is then handled by ``cythonize()`` as follows:: from distutils.core import setup, Extension from Cython.Build import cythonize setup(ext_modules = cythonize(Extension( "rect", # the extesion name sources=["rect.pyx", "Rectangle.cpp"], # the Cython source and # additional C++ source files language="c++", # generate and compile C++ code ))) The options can also be passed directly from the source file, which is often preferable (and overrides any global option). Starting with version 0.17, Cython also allows to pass external source files into the ``cythonize()`` command this way. Here is a simplified setup.py file:: from distutils.core import setup from Cython.Build import cythonize setup( name = "rectangleapp", ext_modules = cythonize('*.pyx'), ) And in the .pyx source file, write this into the first comment block, before any source code, to compile it in C++ mode and link it statically against the :file:`Rectange.cpp` code file:: # distutils: language = c++ # distutils: sources = Rectangle.cpp To compile manually (e.g. using ``make``), the ``cython`` command-line utility can be used to generate a C++ ``.cpp`` file, and then compile it into a python extension. C++ mode for the ``cython`` command is turned on with the ``--cplus`` option. Declaring a C++ class interface -------------------------------- The procedure for wrapping a C++ class is quite similar to that for wrapping normal C structs, with a couple of additions. Let's start here by creating the basic ``cdef extern from`` block:: cdef extern from "Rectangle.h" namespace "shapes": This will make the C++ class def for Rectangle available. Note the namespace declaration. Namespaces are simply used to make the fully qualified name of the object, and can be nested (e.g. ``"outer::inner"``) or even refer to classes (e.g. ``"namespace::MyClass`` to declare static members on MyClass). Declare class with cdef cppclass ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Now, let's add the Rectangle class to this extern from block - just copy the class name from Rectangle.h and adjust for Cython syntax, so now it becomes:: cdef extern from "Rectangle.h" namespace "shapes": cdef cppclass Rectangle: Add public attributes ^^^^^^^^^^^^^^^^^^^^^^ We now need to declare the attributes and methods for use on Cython:: cdef extern from "Rectangle.h" namespace "shapes": cdef cppclass Rectangle: Rectangle(int, int, int, int) except + int x0, y0, x1, y1 int getLength() int getHeight() int getArea() void move(int, int) Note that the constructor is declared as "except +". If the C++ code or the initial memory allocation raises an exception due to a failure, this will let Cython safely raise an appropriate Python exception instead (see below). Without this declaration, C++ exceptions originating from the constructor will not be handled by Cython. Declare a var with the wrapped C++ class ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Now, we use cdef to declare a var of the class with the C++ ``new`` statement:: cdef Rectangle *rec = new Rectangle(1, 2, 3, 4) try: recLength = rec.getLength() ... finally: del rec # delete heap allocated object It's also possible to declare a stack allocated object, as long as it has a "default" constructor:: cdef extern from "Foo.h": cdef cppclass Foo: Foo() def func(): cdef Foo foo ... Note that, like C++, if the class has only one constructor and it is a default one, it's not necessary to declare it. Create Cython wrapper class ---------------------------- At this point, we have exposed into our pyx file's namespace the interface of the C++ Rectangle type. Now, we need to make this accessible from external Python code (which is our whole point). Common programming practice is to create a Cython extension type which holds a C++ instance pointer as an attribute ``thisptr``, and create a bunch of forwarding methods. So we can implement the Python extension type as:: cdef class PyRectangle: cdef Rectangle *thisptr # hold a C++ instance which we're wrapping def __cinit__(self, int x0, int y0, int x1, int y1): self.thisptr = new Rectangle(x0, y0, x1, y1) def __dealloc__(self): del self.thisptr def getLength(self): return self.thisptr.getLength() def getHeight(self): return self.thisptr.getHeight() def getArea(self): return self.thisptr.getArea() def move(self, dx, dy): self.thisptr.move(dx, dy) And there we have it. From a Python perspective, this extension type will look and feel just like a natively defined Rectangle class. If you want to give attribute access, you could just implement some properties:: property x0: def __get__(self): return self.thisptr.x0 def __set__(self, x0): self.thisptr.x0 = x0 ... If you prefer giving the same name to the wrapper as the C++ class, see the section on :ref:`resolving naming conflicts `. Advanced C++ features ====================== We describe here all the C++ features that were not discussed in the above tutorial. Overloading ------------ Overloading is very simple. Just declare the method with different parameters and use any of them:: cdef extern from "Foo.h": cdef cppclass Foo: Foo(int) Foo(bool) Foo(int, bool) Foo(int, int) Overloading operators ---------------------- Cython uses C++ for overloading operators:: cdef extern from "foo.h": cdef cppclass Foo: Foo() Foo* operator+(Foo*) Foo* operator-(Foo) int operator*(Foo*) int operator/(int) cdef Foo* foo = new Foo() cdef int x cdef Foo* foo2 = foo[0] + foo foo2 = foo[0] - foo[0] x = foo[0] * foo2 x = foo[0] / 1 cdef Foo f foo = f + &f foo2 = f - f del foo, foo2 Nested class declarations -------------------------- C++ allows nested class declaration. Class declarations can also be nested in Cython:: cdef extern from "" namespace "std": cdef cppclass vector[T]: cppclass iterator: T operator*() iterator operator++() bint operator==(iterator) bint operator!=(iterator) vector() void push_back(T&) T& operator[](int) T& at(int) iterator begin() iterator end() cdef vector[int].iterator iter #iter is declared as being of type vector::iterator Note that the nested class is declared with a ``cppclass`` but without a ``cdef``. C++ operators not compatible with Python syntax ------------------------------------------------ Cython try to keep a syntax as close as possible to standard Python. Because of this, certain C++ operators, like the preincrement ``++foo`` or the dereferencing operator ``*foo`` cannot be used with the same syntax as C++. Cython provides functions replacing these operators in a special module ``cython.operator``. The functions provided are: * ``cython.operator.dereference`` for dereferencing. ``dereference(foo)`` will produce the C++ code ``*(foo)`` * ``cython.operator.preincrement`` for pre-incrementation. ``preincrement(foo)`` will produce the C++ code ``++(foo)`` * ... These functions need to be cimported. Of course, one can use a ``from ... cimport ... as`` to have shorter and more readable functions. For example: ``from cython.operator cimport dereference as deref``. Templates ---------- Cython uses a bracket syntax for templating. A simple example for wrapping C++ vector:: # import dereference and increment operators from cython.operator cimport dereference as deref, preincrement as inc cdef extern from "" namespace "std": cdef cppclass vector[T]: cppclass iterator: T operator*() iterator operator++() bint operator==(iterator) bint operator!=(iterator) vector() void push_back(T&) T& operator[](int) T& at(int) iterator begin() iterator end() cdef vector[int] *v = new vector[int]() cdef int i for i in range(10): v.push_back(i) cdef vector[int].iterator it = v.begin() while it != v.end(): print deref(it) inc(it) del v Multiple template parameters can be defined as a list, such as [T, U, V] or [int, bool, char]. Template functions are defined similarly, with the template parameter list following the function name:: cdef extern from "" namespace "std": T max[T](T a, T b) print max[long](3, 4) print max(1.5, 2.5) # simple template argument deduction Standard library ----------------- Most of the containers of the C++ Standard Library have been declared in pxd files located in ``/Cython/Includes/libcpp``. These containers are: deque, list, map, pair, queue, set, stack, vector. For example:: from libcpp.vector cimport vector cdef vector[int] vect cdef int i for i in range(10): vect.push_back(i) for i in range(10): print vect[i] The pxd files in ``/Cython/Includes/libcpp`` also work as good examples on how to declare C++ classes. Since Cython 0.17, the STL containers coerce from and to the corresponding Python builtin types. The conversion is triggered either by an assignment to a typed variable (including typed function arguments) or by an explicit cast, e.g.:: from libcpp.string cimport string from libcpp.vector cimport vector cdef string s = py_bytes_object print(s) cpp_string = py_unicode_object.encode('utf-8') cdef vector[int] vect = xrange(1, 10, 2) print(vect) # [1, 3, 5, 7, 9] cdef vector[string] cpp_strings = b'ab cd ef gh'.split() print(cpp_strings[1]) # b'cd' The following coercions are available: +------------------+----------------+-----------------+ | Python type => | *C++ type* | => Python type | +==================+================+=================+ | bytes | std::string | bytes | +------------------+----------------+-----------------+ | iterable | std::vector | list | +------------------+----------------+-----------------+ | iterable | std::list | list | +------------------+----------------+-----------------+ | iterable | std::set | set | +------------------+----------------+-----------------+ | iterable (len 2) | std::pair | tuple (len 2) | +------------------+----------------+-----------------+ All conversions create a new container and copy the data into it. The items in the containers are converted to a corresponding type automatically, which includes recursively converting containers inside of containers, e.g. a C++ vector of maps of strings. Simplified wrapping with default constructor -------------------------------------------- If your extension type instantiates a wrapped C++ class using the default constructor (not passing any arguments), you may be able to simplify the lifecycle handling by tying it directly to the lifetime of the Python wrapper object. Instead of a pointer attribute, you can declare an instance:: cdef class VectorStack: cdef vector[int] v def push(self, x): self.v.push_back(x) def pop(self): if self.v.empty(): raise IndexError() x = self.v.back() self.v.pop_back() return x Cython will automatically generate code that instantiates the C++ object instance when the Python object is created and deletes it when the Python object is garbage collected. Exceptions ----------- Cython cannot throw C++ exceptions, or catch them with a try-except statement, but it is possible to declare a function as potentially raising an C++ exception and converting it into a Python exception. For example, :: cdef extern from "some_file.h": cdef int foo() except + This will translate try and the C++ error into an appropriate Python exception. The translation is performed according to the following table (the ``std::`` prefix is omitted from the C++ identifiers): +-----------------------+---------------------+ | C++ | Python | +=======================+=====================+ | ``bad_alloc`` | ``MemoryError`` | +-----------------------+---------------------+ | ``bad_cast`` | ``TypeError`` | +-----------------------+---------------------+ | ``domain_error`` | ``ValueError`` | +-----------------------+---------------------+ | ``invalid_argument`` | ``ValueError`` | +-----------------------+---------------------+ | ``ios_base::failure`` | ``IOError`` | +-----------------------+---------------------+ | ``out_of_range`` | ``IndexError`` | +-----------------------+---------------------+ | ``overflow_error`` | ``OverflowError`` | +-----------------------+---------------------+ | ``range_error`` | ``ArithmeticError`` | +-----------------------+---------------------+ | ``underflow_error`` | ``ArithmeticError`` | +-----------------------+---------------------+ | (all others) | ``RuntimeError`` | +-----------------------+---------------------+ The ``what()`` message, if any, is preserved. Note that a C++ ``ios_base_failure`` can denote EOF, but does not carry enough information for Cython to discern that, so watch out with exception masks on IO streams. :: cdef int bar() except +MemoryError This will catch any C++ error and raise a Python MemoryError in its place. (Any Python exception is valid here.) :: cdef int raise_py_error() cdef int something_dangerous() except +raise_py_error If something_dangerous raises a C++ exception then raise_py_error will be called, which allows one to do custom C++ to Python error "translations." If raise_py_error does not actually raise an exception a RuntimeError will be raised. Static member method -------------------- If the Rectangle class has a static member: .. sourcecode:: c++ namespace shapes { class Rectangle { ... public: static void do_something(); }; } you can declare it using the Python @staticmethod decorator, i.e.:: cdef extern from "Rectangle.h" namespace "shapes": @staticmethod void do_something() Caveats and Limitations ======================== Access to C-only functions --------------------------- Whenever generating C++ code, Cython generates declarations of and calls to functions assuming these functions are C++ (ie, not declared as ``extern "C" {...}``. This is ok if the C functions have C++ entry points, but if they're C only, you will hit a roadblock. If you have a C++ Cython module needing to make calls to pure-C functions, you will need to write a small C++ shim module which: * includes the needed C headers in an extern "C" block * contains minimal forwarding functions in C++, each of which calls the respective pure-C function Declaring/Using References --------------------------- Question: How do you declare and call a function that takes a reference as an argument? C++ left-values ---------------- C++ allows functions returning a reference to be left-values. This is currently not supported in Cython. ``cython.operator.dereference(foo)`` is also not considered a left-value. Cython-0.23.4/docs/src/userguide/special_methods.rst0000644000175600017570000007500512606202452023623 0ustar jenkinsjenkins00000000000000.. _special-methods: Special Methods of Extension Types =================================== This page describes the special methods currently supported by Cython extension types. A complete list of all the special methods appears in the table at the bottom. Some of these methods behave differently from their Python counterparts or have no direct Python counterparts, and require special mention. .. Note: Everything said on this page applies only to extension types, defined with the :keyword:`cdef class` statement. It doesn't apply to classes defined with the Python :keyword:`class` statement, where the normal Python rules apply. Declaration ------------ Special methods of extension types must be declared with :keyword:`def`, not :keyword:`cdef`. This does not impact their performance--Python uses different calling conventions to invoke these special methods. Docstrings ----------- Currently, docstrings are not fully supported in some special methods of extension types. You can place a docstring in the source to serve as a comment, but it won't show up in the corresponding :attr:`__doc__` attribute at run time. (This seems to be is a Python limitation -- there's nowhere in the `PyTypeObject` data structure to put such docstrings.) Initialisation methods: :meth:`__cinit__` and :meth:`__init__` --------------------------------------------------------------- There are two methods concerned with initialising the object. The :meth:`__cinit__` method is where you should perform basic C-level initialisation of the object, including allocation of any C data structures that your object will own. You need to be careful what you do in the :meth:`__cinit__` method, because the object may not yet be fully valid Python object when it is called. Therefore, you should be careful invoking any Python operations which might touch the object; in particular, its methods. By the time your :meth:`__cinit__` method is called, memory has been allocated for the object and any C attributes it has have been initialised to 0 or null. (Any Python attributes have also been initialised to None, but you probably shouldn't rely on that.) Your :meth:`__cinit__` method is guaranteed to be called exactly once. If your extension type has a base type, the :meth:`__cinit__` method of the base type is automatically called before your :meth:`__cinit__` method is called; you cannot explicitly call the inherited :meth:`__cinit__` method. If you need to pass a modified argument list to the base type, you will have to do the relevant part of the initialisation in the :meth:`__init__` method instead (where the normal rules for calling inherited methods apply). Any initialisation which cannot safely be done in the :meth:`__cinit__` method should be done in the :meth:`__init__` method. By the time :meth:`__init__` is called, the object is a fully valid Python object and all operations are safe. Under some circumstances it is possible for :meth:`__init__` to be called more than once or not to be called at all, so your other methods should be designed to be robust in such situations. Any arguments passed to the constructor will be passed to both the :meth:`__cinit__` method and the :meth:`__init__` method. If you anticipate subclassing your extension type in Python, you may find it useful to give the :meth:`__cinit__` method `*` and `**` arguments so that it can accept and ignore extra arguments. Otherwise, any Python subclass which has an :meth:`__init__` with a different signature will have to override :meth:`__new__` [#]_ as well as :meth:`__init__`, which the writer of a Python class wouldn't expect to have to do. Alternatively, as a convenience, if you declare your :meth:`__cinit__`` method to take no arguments (other than self) it will simply ignore any extra arguments passed to the constructor without complaining about the signature mismatch. .. Note: Older Cython files may use :meth:`__new__` rather than :meth:`__cinit__`. The two are synonyms. The name change from :meth:`__new__` to :meth:`__cinit__` was to avoid confusion with Python :meth:`__new__` (which is an entirely different concept) and eventually the use of :meth:`__new__` in Cython will be disallowed to pave the way for supporting Python-style :meth:`__new__` .. [#] http://docs.python.org/reference/datamodel.html#object.__new__ Finalization method: :meth:`__dealloc__` ---------------------------------------- The counterpart to the :meth:`__cinit__` method is the :meth:`__dealloc__` method, which should perform the inverse of the :meth:`__cinit__` method. Any C data that you explicitly allocated (e.g. via malloc) in your :meth:`__cinit__` method should be freed in your :meth:`__dealloc__` method. You need to be careful what you do in a :meth:`__dealloc__` method. By the time your :meth:`__dealloc__` method is called, the object may already have been partially destroyed and may not be in a valid state as far as Python is concerned, so you should avoid invoking any Python operations which might touch the object. In particular, don't call any other methods of the object or do anything which might cause the object to be resurrected. It's best if you stick to just deallocating C data. You don't need to worry about deallocating Python attributes of your object, because that will be done for you by Cython after your :meth:`__dealloc__` method returns. When subclassing extension types, be aware that the :meth:`__dealloc__` method of the superclass will always be called, even if it is overridden. This is in contrast to typical Python behavior where superclass methods will not be executed unless they are explicitly called by the subclass. .. Note:: There is no :meth:`__del__` method for extension types. Arithmetic methods ------------------- Arithmetic operator methods, such as :meth:`__add__`, behave differently from their Python counterparts. There are no separate "reversed" versions of these methods (:meth:`__radd__`, etc.) Instead, if the first operand cannot perform the operation, the same method of the second operand is called, with the operands in the same order. This means that you can't rely on the first parameter of these methods being "self" or being the right type, and you should test the types of both operands before deciding what to do. If you can't handle the combination of types you've been given, you should return `NotImplemented`. This also applies to the in-place arithmetic method :meth:`__ipow__`. It doesn't apply to any of the other in-place methods (:meth:`__iadd__`, etc.) which always take `self` as the first argument. Rich comparisons ----------------- There are no separate methods for the individual rich comparison operations (:meth:`__eq__`, :meth:`__le__`, etc.) Instead there is a single method :meth:`__richcmp__` which takes an integer indicating which operation is to be performed, as follows: +-----+-----+ | < | 0 | +-----+-----+ | == | 2 | +-----+-----+ | > | 4 | +-----+-----+ | <= | 1 | +-----+-----+ | != | 3 | +-----+-----+ | >= | 5 | +-----+-----+ The :meth:`__next__` method ---------------------------- Extension types wishing to implement the iterator interface should define a method called :meth:`__next__`, not next. The Python system will automatically supply a next method which calls your :meth:`__next__`. Do *NOT* explicitly give your type a :meth:`next` method, or bad things could happen. Special Method Table --------------------- This table lists all of the special methods together with their parameter and return types. In the table below, a parameter name of self is used to indicate that the parameter has the type that the method belongs to. Other parameters with no type specified in the table are generic Python objects. You don't have to declare your method as taking these parameter types. If you declare different types, conversions will be performed as necessary. General ^^^^^^^ +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __cinit__ |self, ... | | Basic initialisation (no direct Python equivalent) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __init__ |self, ... | | Further initialisation | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __dealloc__ |self | | Basic deallocation (no direct Python equivalent) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __cmp__ |x, y | int | 3-way comparison | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __richcmp__ |x, y, int op | object | Rich comparison (no direct Python equivalent) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __str__ |self | object | str(self) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __repr__ |self | object | repr(self) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __hash__ |self | int | Hash function | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __call__ |self, ... | object | self(...) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __iter__ |self | object | Return iterator for sequence | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __getattr__ |self, name | object | Get attribute | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __getattribute__ |self, name | object | Get attribute, unconditionally | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __setattr__ |self, name, val | | Set attribute | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __delattr__ |self, name | | Delete attribute | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ Arithmetic operators ^^^^^^^^^^^^^^^^^^^^ +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __add__ | x, y | object | binary `+` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __sub__ | x, y | object | binary `-` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __mul__ | x, y | object | `*` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __div__ | x, y | object | `/` operator for old-style division | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __floordiv__ | x, y | object | `//` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __truediv__ | x, y | object | `/` operator for new-style division | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __mod__ | x, y | object | `%` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __divmod__ | x, y | object | combined div and mod | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __pow__ | x, y, z | object | `**` operator or pow(x, y, z) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __neg__ | self | object | unary `-` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __pos__ | self | object | unary `+` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __abs__ | self | object | absolute value | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __nonzero__ | self | int | convert to boolean | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __invert__ | self | object | `~` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __lshift__ | x, y | object | `<<` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __rshift__ | x, y | object | `>>` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __and__ | x, y | object | `&` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __or__ | x, y | object | `|` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __xor__ | x, y | object | `^` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ Numeric conversions ^^^^^^^^^^^^^^^^^^^ +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __int__ | self | object | Convert to integer | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __long__ | self | object | Convert to long integer | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __float__ | self | object | Convert to float | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __oct__ | self | object | Convert to octal | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __hex__ | self | object | Convert to hexadecimal | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __index__ (2.5+ only) | self | object | Convert to sequence index | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ In-place arithmetic operators ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __iadd__ | self, x | object | `+=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __isub__ | self, x | object | `-=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __imul__ | self, x | object | `*=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __idiv__ | self, x | object | `/=` operator for old-style division | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __ifloordiv__ | self, x | object | `//=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __itruediv__ | self, x | object | `/=` operator for new-style division | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __imod__ | self, x | object | `%=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __ipow__ | x, y, z | object | `**=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __ilshift__ | self, x | object | `<<=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __irshift__ | self, x | object | `>>=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __iand__ | self, x | object | `&=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __ior__ | self, x | object | `|=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __ixor__ | self, x | object | `^=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ Sequences and mappings ^^^^^^^^^^^^^^^^^^^^^^ +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __len__ | self int | | len(self) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __getitem__ | self, x | object | self[x] | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __setitem__ | self, x, y | | self[x] = y | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __delitem__ | self, x | | del self[x] | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __getslice__ | self, Py_ssize_t i, Py_ssize_t j | object | self[i:j] | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __setslice__ | self, Py_ssize_t i, Py_ssize_t j, x | | self[i:j] = x | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __delslice__ | self, Py_ssize_t i, Py_ssize_t j | | del self[i:j] | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __contains__ | self, x | int | x in self | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ Iterators ^^^^^^^^^ +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __next__ | self | object | Get next item (called next in Python) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ Buffer interface [PEP 3118] (no Python equivalents - see note 1) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __getbuffer__ | self, Py_buffer `*view`, int flags | | | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __releasebuffer__ | self, Py_buffer `*view` | | | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ Buffer interface [legacy] (no Python equivalents - see note 1) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __getreadbuffer__ | self, Py_ssize_t i, void `**p` | | | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __getwritebuffer__ | self, Py_ssize_t i, void `**p` | | | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __getsegcount__ | self, Py_ssize_t `*p` | | | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __getcharbuffer__ | self, Py_ssize_t i, char `**p` | | | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ Descriptor objects (see note 2) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __get__ | self, instance, class | object | Get value of attribute | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __set__ | self, instance, value | | Set value of attribute | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __delete__ | self, instance | | Delete attribute | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ .. note:: (1) The buffer interface was intended for use by C code and is not directly accessible from Python. It is described in the Python/C API Reference Manual of Python 2.x under sections 6.6 and 10.6. It was superseded by the new PEP 3118 buffer protocol in Python 2.6 and is no longer available in Python 3. For a how-to guide to the new API, see :ref:`buffer`. .. note:: (2) Descriptor objects are part of the support mechanism for new-style Python classes. See the discussion of descriptors in the Python documentation. See also PEP 252, "Making Types Look More Like Classes", and PEP 253, "Subtyping Built-In Types". Cython-0.23.4/docs/src/userguide/source_files_and_compilation.rst0000644000175600017570000001372112606202452026357 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _compilation: **************************** Source Files and Compilation **************************** .. note:: See :ref:`compilation-reference` reference section for more details Cython source file names consist of the name of the module followed by a ``.pyx`` extension, for example a module called primes would have a source file named :file:`primes.pyx`. Once you have written your ``.pyx`` file, there are a couple of ways of turning it into an extension module. One way is to compile it manually with the Cython compiler, e.g.: .. sourcecode:: text $ cython primes.pyx This will produce a file called :file:`primes.c`, which then needs to be compiled with the C compiler using whatever options are appropriate on your platform for generating an extension module. For these options look at the official Python documentation. The other, and probably better, way is to use the :mod:`distutils` extension provided with Cython. The benefit of this method is that it will give the platform specific compilation options, acting like a stripped down autotools. Basic setup.py =============== The distutils extension provided with Cython allows you to pass ``.pyx`` files directly to the ``Extension`` constructor in your setup file. If you have a single Cython file that you want to turn into a compiled extension, say with filename :file:`example.pyx` the associated :file:`setup.py` would be:: from distutils.core import setup from Cython.Build import cythonize setup( ext_modules = cythonize("example.pyx") ) To understand the :file:`setup.py` more fully look at the official :mod:`distutils` documentation. To compile the extension for use in the current directory use: .. sourcecode:: text $ python setup.py build_ext --inplace Multiple Cython Files in a Package =================================== To automatically compile multiple Cython files without listing all of them explicitly, you can use glob patterns:: setup( ext_modules = cythonize("package/*.pyx") ) You can also use glob patterns in :class:`Extension` objects if you pass them through :func:`cythonize`:: extensions = [Extension("*", ["*.pyx"])] setup( ext_modules = cythonize(extensions) ) .. _pyximport: Pyximport =========== .. TODO add some text about how this is Paul Prescods code. Also change the tone to be more universal (i.e. remove all the I statements) Cython is a compiler. Therefore it is natural that people tend to go through an edit/compile/test cycle with Cython modules. But my personal opinion is that one of the deep insights in Python's implementation is that a language can be compiled (Python modules are compiled to ``.pyc`` files) and hide that compilation process from the end-user so that they do not have to worry about it. Pyximport does this for Cython modules. For instance if you write a Cython module called :file:`foo.pyx`, with Pyximport you can import it in a regular Python module like this:: import pyximport; pyximport.install() import foo Doing so will result in the compilation of :file:`foo.pyx` (with appropriate exceptions if it has an error in it). If you would always like to import Cython files without building them specially, you can also the first line above to your :file:`sitecustomize.py`. That will install the hook every time you run Python. Then you can use Cython modules just with simple import statements. I like to test my Cython modules like this: .. sourcecode:: text $ python -c "import foo" Dependency Handling -------------------- In Pyximport 1.1 it is possible to declare that your module depends on multiple files, (likely ``.h`` and ``.pxd`` files). If your Cython module is named ``foo`` and thus has the filename :file:`foo.pyx` then you should make another file in the same directory called :file:`foo.pyxdep`. The :file:`modname.pyxdep` file can be a list of filenames or "globs" (like ``*.pxd`` or ``include/*.h``). Each filename or glob must be on a separate line. Pyximport will check the file date for each of those files before deciding whether to rebuild the module. In order to keep track of the fact that the dependency has been handled, Pyximport updates the modification time of your ".pyx" source file. Future versions may do something more sophisticated like informing distutils of the dependencies directly. Limitations ------------ Pyximport does not give you any control over how your Cython file is compiled. Usually the defaults are fine. You might run into problems if you wanted to write your program in half-C, half-Cython and build them into a single library. Pyximport 1.2 will probably do this. Pyximport does not hide the Distutils/GCC warnings and errors generated by the import process. Arguably this will give you better feedback if something went wrong and why. And if nothing went wrong it will give you the warm fuzzy that pyximport really did rebuild your module as it was supposed to. For further thought and discussion ------------------------------------ I don't think that Python's :func:`reload` will do anything for changed ``.so``'s on some (all?) platforms. It would require some (easy) experimentation that I haven't gotten around to. But reload is rarely used in applications outside of the Python interactive interpreter and certainly not used much for C extension modules. Info about Windows ``_ ``setup.py install`` does not modify :file:`sitecustomize.py` for you. Should it? Modifying Python's "standard interpreter" behaviour may be more than most people expect of a package they install.. Pyximport puts your ``.c`` file beside your ``.pyx`` file (analogous to ``.pyc`` beside ``.py``). But it puts the platform-specific binary in a build directory as per normal for Distutils. If I could wave a magic wand and get Cython or distutils or whoever to put the build directory I might do it but not necessarily: having it at the top level is *VERY* *HELPFUL* for debugging Cython problems. Cython-0.23.4/docs/src/userguide/sharing_declarations.rst0000644000175600017570000002153112606202452024636 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _sharing-declarations: ******************************************** Sharing Declarations Between Cython Modules ******************************************** This section describes how to make C declarations, functions and extension types in one Cython module available for use in another Cython module. These facilities are closely modeled on the Python import mechanism, and can be thought of as a compile-time version of it. Definition and Implementation files ==================================== A Cython module can be split into two parts: a definition file with a ``.pxd`` suffix, containing C declarations that are to be available to other Cython modules, and an implementation file with a ``.pyx`` suffix, containing everything else. When a module wants to use something declared in another module's definition file, it imports it using the :keyword:`cimport` statement. A ``.pxd`` file that consists solely of extern declarations does not need to correspond to an actual ``.pyx`` file or Python module. This can make it a convenient place to put common declarations, for example declarations of functions from an :ref:`external library ` that one wants to use in several modules. What a Definition File contains ================================ A definition file can contain: * Any kind of C type declaration. * extern C function or variable declarations. * Declarations of C functions defined in the module. * The definition part of an extension type (see below). It cannot contain the implementations of any C or Python functions, or any Python class definitions, or any executable statements. It is needed when one wants to access :keyword:`cdef` attributes and methods, or to inherit from :keyword:`cdef` classes defined in this module. .. note:: You don't need to (and shouldn't) declare anything in a declaration file public in order to make it available to other Cython modules; its mere presence in a definition file does that. You only need a public declaration if you want to make something available to external C code. What an Implementation File contains ====================================== An implementation file can contain any kind of Cython statement, although there are some restrictions on the implementation part of an extension type if the corresponding definition file also defines that type (see below). If one doesn't need to :keyword:`cimport` anything from this module, then this is the only file one needs. .. _cimport: The cimport statement ======================= The :keyword:`cimport` statement is used in a definition or implementation file to gain access to names declared in another definition file. Its syntax exactly parallels that of the normal Python import statement:: cimport module [, module...] from module cimport name [as name] [, name [as name] ...] Here is an example. :file:`dishes.pxd` is a definition file which exports a C data type. :file:`restaurant.pxd` an implementation file which imports and uses it. :file:`dishes.pxd`:: cdef enum otherstuff: sausage, eggs, lettuce cdef struct spamdish: int oz_of_spam otherstuff filler :file:`restaurant.pyx`:: cimport dishes from dishes cimport spamdish cdef void prepare(spamdish *d): d.oz_of_spam = 42 d.filler = dishes.sausage def serve(): cdef spamdish d prepare(&d) print "%d oz spam, filler no. %d" % (d.oz_of_spam, d.filler) It is important to understand that the :keyword:`cimport` statement can only be used to import C data types, C functions and variables, and extension types. It cannot be used to import any Python objects, and (with one exception) it doesn't imply any Python import at run time. If you want to refer to any Python names from a module that you have cimported, you will have to include a regular import statement for it as well. The exception is that when you use :keyword:`cimport` to import an extension type, its type object is imported at run time and made available by the name under which you imported it. Using :keyword:`cimport` to import extension types is covered in more detail below. If a ``.pxd`` file changes, any modules that :keyword:`cimport` from it may need to be recompiled. The ``Cython.Build.cythonize`` utility can take care of this for you. Search paths for definition files ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ When you :keyword:`cimport` a module called ``modulename``, the Cython compiler searches for a file called :file:`modulename.pxd`. It searches for this file along the path for include files (as specified by ``-I`` command line options or the ``include_path`` option to ``cythonize()``), as well as ``sys.path``. Also, whenever you compile a file :file:`modulename.pyx`, the corresponding definition file :file:`modulename.pxd` is first searched for along the include path (but not ``sys.path``), and if found, it is processed before processing the ``.pyx`` file. Using cimport to resolve naming conflicts ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The :keyword:`cimport` mechanism provides a clean and simple way to solve the problem of wrapping external C functions with Python functions of the same name. All you need to do is put the extern C declarations into a ``.pxd`` file for an imaginary module, and :keyword:`cimport` that module. You can then refer to the C functions by qualifying them with the name of the module. Here's an example: :file:`c_lunch.pxd`:: cdef extern from "lunch.h": void eject_tomato(float) :file:`lunch.pyx`:: cimport c_lunch def eject_tomato(float speed): c_lunch.eject_tomato(speed) You don't need any :file:`c_lunch.pyx` file, because the only things defined in :file:`c_lunch.pxd` are extern C entities. There won't be any actual ``c_lunch`` module at run time, but that doesn't matter; the :file:`c_lunch.pxd` file has done its job of providing an additional namespace at compile time. Sharing C Functions =================== C functions defined at the top level of a module can be made available via :keyword:`cimport` by putting headers for them in the ``.pxd`` file, for example: :file:`volume.pxd`:: cdef float cube(float) :file:`volume.pyx`:: cdef float cube(float x): return x * x * x :file:`spammery.pyx`:: from volume cimport cube def menu(description, size): print description, ":", cube(size), \ "cubic metres of spam" menu("Entree", 1) menu("Main course", 3) menu("Dessert", 2) .. note:: When a module exports a C function in this way, an object appears in the module dictionary under the function's name. However, you can't make use of this object from Python, nor can you use it from Cython using a normal import statement; you have to use :keyword:`cimport`. Sharing Extension Types ======================= An extension type can be made available via :keyword:`cimport` by splitting its definition into two parts, one in a definition file and the other in the corresponding implementation file. The definition part of the extension type can only declare C attributes and C methods, not Python methods, and it must declare all of that type's C attributes and C methods. The implementation part must implement all of the C methods declared in the definition part, and may not add any further C attributes. It may also define Python methods. Here is an example of a module which defines and exports an extension type, and another module which uses it: :file:`Shrubbing.pxd`:: cdef class Shrubbery: cdef int width cdef int length :file:`Shrubbing.pyx`:: cdef class Shrubbery: def __cinit__(self, int w, int l): self.width = w self.length = l def standard_shrubbery(): return Shrubbery(3, 7) :file:`Landscaping.pyx`:: cimport Shrubbing import Shrubbing cdef Shrubbing.Shrubbery sh sh = Shrubbing.standard_shrubbery() print "Shrubbery size is %d x %d" % (sh.width, sh.length) One would then need to compile both of these modules, e.g. using :file:`setup.py`:: from distutils.core import setup from Cython.Build import cythonize setup(ext_modules = cythonize(["Landscaping.pyx", "Shrubbing.pyx"])) Some things to note about this example: * There is a :keyword:`cdef` class Shrubbery declaration in both :file:`Shrubbing.pxd` and :file:`Shrubbing.pyx`. When the Shrubbing module is compiled, these two declarations are combined into one. * In Landscaping.pyx, the :keyword:`cimport` Shrubbing declaration allows us to refer to the Shrubbery type as :class:`Shrubbing.Shrubbery`. But it doesn't bind the name Shrubbing in Landscaping's module namespace at run time, so to access :func:`Shrubbing.standard_shrubbery` we also need to ``import Shrubbing``. Cython-0.23.4/docs/src/userguide/pyrex_differences.rst0000644000175600017570000002655412606202452024171 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _pyrex-differences: ************************************** Differences between Cython and Pyrex ************************************** .. warning:: Both Cython and Pyrex are moving targets. It has come to the point that an explicit list of all the differences between the two projects would be laborious to list and track, but hopefully this high-level list gives an idea of the differences that are present. It should be noted that both projects make an effort at mutual compatibility, but Cython's goal is to be as close to and complete as Python as reasonable. Python 3 Support ================ Cython creates ``.c`` files that can be built and used with both Python 2.x and Python 3.x. In fact, compiling your module with Cython may very well be the easiest way to port code to Python 3. We are also working to make the compiler run in both Python 2.x and 3.x. Many Python 3 constructs are already supported by Cython. List/Set/Dict Comprehensions ---------------------------- Cython supports the different comprehensions defined by Python 3 for lists, sets and dicts:: [expr(x) for x in A] # list {expr(x) for x in A} # set {key(x) : value(x) for x in A} # dict Looping is optimized if ``A`` is a list, tuple or dict. You can use the :keyword:`for` ... :keyword:`from` syntax, too, but it is generally preferred to use the usual :keyword:`for` ... :keyword:`in` ``range(...)`` syntax with a C run variable (e.g. ``cdef int i``). .. note:: see :ref:`automatic-range-conversion` Note that Cython also supports set literals starting from Python 2.4. Keyword-only arguments ---------------------- Python functions can have keyword-only arguments listed after the ``*`` parameter and before the ``**`` parameter if any, e.g.:: def f(a, b, *args, c, d = 42, e, **kwds): ... Here ``c``, ``d`` and ``e`` cannot be passed as position arguments and must be passed as keyword arguments. Furthermore, ``c`` and ``e`` are required keyword arguments, since they do not have a default value. If the parameter name after the ``*`` is omitted, the function will not accept any extra positional arguments, e.g.:: def g(a, b, *, c, d): ... takes exactly two positional parameters and has two required keyword parameters. Conditional expressions "x if b else y" ========================================= Conditional expressions as described in http://www.python.org/dev/peps/pep-0308/:: X if C else Y Only one of ``X`` and ``Y`` is evaluated (depending on the value of C). .. _inline: cdef inline ============= Module level functions can now be declared inline, with the :keyword:`inline` keyword passed on to the C compiler. These can be as fast as macros.:: cdef inline int something_fast(int a, int b): return a*a + b Note that class-level :keyword:`cdef` functions are handled via a virtual function table, so the compiler won't be able to inline them in almost all cases. Assignment on declaration (e.g. "cdef int spam = 5") ====================================================== In Pyrex, one must write:: cdef int i, j, k i = 2 j = 5 k = 7 Now, with cython, one can write:: cdef int i = 2, j = 5, k = 7 The expression on the right hand side can be arbitrarily complicated, e.g.:: cdef int n = python_call(foo(x,y), a + b + c) - 32 'by' expression in for loop (e.g. "for i from 0 <= i < 10 by 2") ================================================================== :: for i from 0 <= i < 10 by 2: print i yields:: 0 2 4 6 8 .. note:: Usage of this syntax is discouraged as it is redundant with the normal Python :keyword:`for` loop. See :ref:`automatic-range-conversion`. Boolean int type (e.g. it acts like a c int, but coerces to/from python as a boolean) ====================================================================================== In C, ints are used for truth values. In python, any object can be used as a truth value (using the :meth:`__nonzero__` method), but the canonical choices are the two boolean objects ``True`` and ``False``. The :c:type:`bint` (for "boolean int") type is compiled to a C int, but coerces to and from Python as booleans. The return type of comparisons and several builtins is a :c:type:`bint` as well. This reduces the need for wrapping things in :func:`bool()`. For example, one can write:: def is_equal(x): return x == y which would return ``1`` or ``0`` in Pyrex, but returns ``True`` or ``False`` in Cython. One can declare variables and return values for functions to be of the :c:type:`bint` type. For example:: cdef int i = x cdef bint b = x The first conversion would happen via ``x.__int__()`` whereas the second would happen via ``x.__bool__()`` (a.k.a. ``__nonzero__()``), with appropriate optimisations for known builtin types. Executable class bodies ======================= Including a working :func:`classmethod`:: cdef class Blah: def some_method(self): print self some_method = classmethod(some_method) a = 2*3 print "hi", a cpdef functions ================= Cython adds a third function type on top of the usual :keyword:`def` and :keyword:`cdef`. If a function is declared :keyword:`cpdef` it can be called from and overridden by both extension and normal python subclasses. You can essentially think of a :keyword:`cpdef` method as a :keyword:`cdef` method + some extras. (That's how it's implemented at least.) First, it creates a :keyword:`def` method that does nothing but call the underlying :keyword:`cdef` method (and does argument unpacking/coercion if needed). At the top of the :keyword:`cdef` method a little bit of code is added to see if it's overridden, similar to the following pseudocode:: if hasattr(type(self), '__dict__'): foo = self.foo if foo is not wrapper_foo: return foo(args) [cdef method body] To detect whether or not a type has a dictionary, it just checks the ``tp_dictoffset`` slot, which is ``NULL`` (by default) for extension types, but non- null for instance classes. If the dictionary exists, it does a single attribute lookup and can tell (by comparing pointers) whether or not the returned result is actually a new function. If, and only if, it is a new function, then the arguments packed into a tuple and the method called. This is all very fast. A flag is set so this lookup does not occur if one calls the method on the class directly, e.g.:: cdef class A: cpdef foo(self): pass x = A() x.foo() # will check to see if overridden A.foo(x) # will call A's implementation whether overridden or not See :ref:`early-binding-for-speed` for explanation and usage tips. .. _automatic-range-conversion: Automatic range conversion ============================ This will convert statements of the form ``for i in range(...)`` to ``for i from ...`` when ``i`` is any cdef'd integer type, and the direction (i.e. sign of step) can be determined. .. warning:: This may change the semantics if the range causes assignment to ``i`` to overflow. Specifically, if this option is set, an error will be raised before the loop is entered, whereas without this option the loop will execute until a overflowing value is encountered. If this effects you change ``Cython/Compiler/Options.py`` (eventually there will be a better way to set this). More friendly type casting =========================== In Pyrex, if one types ``x`` where ``x`` is a Python object, one will get the memory address of ``x``. Likewise, if one types ``i`` where ``i`` is a C int, one will get an "object" at location ``i`` in memory. This leads to confusing results and segfaults. In Cython ``x`` will try and do a coercion (as would happen on assignment of ``x`` to a variable of type type) if exactly one of the types is a python object. It does not stop one from casting where there is no conversion (though it will emit a warning). If one really wants the address, cast to a ``void *`` first. As in Pyrex ``x`` will cast ``x`` to type :c:type:`MyExtensionType` without any type checking. Cython supports the syntax ```` to do the cast with type checking (i.e. it will throw an error if ``x`` is not a (subclass of) :c:type:`MyExtensionType`. Optional arguments in cdef/cpdef functions ============================================ Cython now supports optional arguments for :keyword:`cdef` and :keyword:`cpdef` functions. The syntax in the ``.pyx`` file remains as in Python, but one declares such functions in the ``.pxd`` file by writing ``cdef foo(x=*)``. The number of arguments may increase on subclassing, but the argument types and order must remain the same. There is a slight performance penalty in some cases when a cdef/cpdef function without any optional is overridden with one that does have default argument values. For example, one can have the ``.pxd`` file:: cdef class A: cdef foo(self) cdef class B(A) cdef foo(self, x=*) cdef class C(B): cpdef foo(self, x=*, int k=*) with corresponding ``.pyx`` file:: cdef class A: cdef foo(self): print "A" cdef class B(A) cdef foo(self, x=None) print "B", x cdef class C(B): cpdef foo(self, x=True, int k=3) print "C", x, k .. note:: this also demonstrates how :keyword:`cpdef` functions can override :keyword:`cdef` functions. Function pointers in structs ============================= Functions declared in :keyword:`struct` are automatically converted to function pointers for convenience. C++ Exception handling ========================= :keyword:`cdef` functions can now be declared as:: cdef int foo(...) except + cdef int foo(...) except +TypeError cdef int foo(...) except +python_error_raising_function in which case a Python exception will be raised when a C++ error is caught. See :ref:`wrapping-cplusplus` for more details. Synonyms ========= ``cdef import from`` means the same thing as ``cdef extern from`` Source code encoding ====================== .. TODO: add the links to the relevant PEPs Cython supports PEP 3120 and PEP 263, i.e. you can start your Cython source file with an encoding comment and generally write your source code in UTF-8. This impacts the encoding of byte strings and the conversion of unicode string literals like ``u'abcd'`` to unicode objects. Automatic ``typecheck`` ======================== Rather than introducing a new keyword ``typecheck`` as explained in the `Pyrex docs `_, Cython emits a (non-spoofable and faster) typecheck whenever :func:`isinstance` is used with an extension type as the second parameter. From __future__ directives ========================== Cython supports several ``from __future__ import ...`` directives, namely ``absolute_import``, ``unicode_literals``, ``print_function`` and ``division``. With statements are always enabled. Pure Python mode ================ Cython has support for compiling ``.py`` files, and accepting type annotations using decorators and other valid Python syntax. This allows the same source to be interpreted as straight Python, or compiled for optimized results. See :ref:`pure-mode` for more details. Cython-0.23.4/docs/src/userguide/pypy.rst0000644000175600017570000001734512606202452021464 0ustar jenkinsjenkins00000000000000Porting Cython code to PyPy =========================== Since version 0.17, Cython has basic support for cpyext, the layer in `PyPy `_ that emulates CPython's C-API. This is achieved by making the generated C code adapt at C compile time, so the generated code will compile in both CPython and PyPy unchanged. However, beyond what Cython can cover and adapt internally, the cpyext C-API emulation involves some differences to the real C-API in CPython that have a visible impact on user code. This page lists major differences and ways to deal with them in order to write Cython code that works in both CPython and PyPy. Reference counts ---------------- A general design difference in PyPy is that the runtime does not use reference counting internally but always a garbage collector. Reference counting is only emulated at the cpyext layer by counting references being held in C space. This implies that the reference count in PyPy is generally different from that in CPython because it does not count any references held in Python space. Object lifetime --------------- As a direct consequence of the different garbage collection characteristics, objects may see the end of their lifetime at other points than in CPython. Special care therefore has to be taken when objects are expected to have died in CPython but may not in PyPy. Specifically, a deallocator method of an extension type (``__dealloc__()``) may get called at a much later point than in CPython, triggered rather by memory getting tighter than by objects dying. If the point in the code is known when an object is supposed to die (e.g. when it is tied to another object or to the execution time of a function), it is worth considering if it can be invalidated and cleaned up manually at that point, rather than relying on a deallocator. As a side effect, this can sometimes even lead to a better code design, e.g. when context managers can be used together with the ``with`` statement. Borrowed references and data pointers ------------------------------------- The memory management in PyPy is allowed to move objects around in memory. The C-API layer is only an indirect view on PyPy objects and often replicates data or state into C space that is then tied to the lifetime of a C-API object rather then the underlying PyPy object. It is important to understand that these two objects are separate things in cpyext. The effect can be that when data pointers or borrowed references are used, and the owning object is no longer directly referenced from C space, the reference or data pointer may become invalid at some point, even if the object itself is still alive. As opposed to CPython, it is not enough to keep the reference to the object alive in a list (or other Python container), because the contents of those is only managed in Python space and thus only references the PyPy object. A reference in a Python container will not keep the C-API view on it alive. Entries in a Python class dict will obviously not work either. One of the more visible places where this may happen is when accessing the :c:type:`char*` buffer of a byte string. In PyPy, this will only work as long as the Cython code holds a direct reference to the byte string object itself. Another point is when CPython C-API functions are used directly that return borrowed references, e.g. :c:func:`PyTuple_GET_ITEM()` and similar functions, but also some functions that return borrowed references to built-in modules or low-level objects of the runtime environment. The GIL in PyPy only guarantees that the borrowed reference stays valid up to the next call into PyPy (or its C-API), but not necessarily longer. When accessing the internals of Python objects or using borrowed references longer than up to the next call into PyPy, including reference counting or anything that frees the GIL, it is therefore required to additionally keep direct owned references to these objects alive in C space, e.g. in local variables in a function or in the attributes of an extension type. When in doubt, avoid using C-API functions that return borrowed references, or surround the usage of a borrowed reference explicitly by a pair of calls to :c:func:`Py_INCREF()` when getting the reference and :c:func:`Py_DECREF()` when done with it to convert it into an owned reference. Builtin types, slots and fields ------------------------------- The following builtin types are not currently available in cpyext in form of their C level representation: :c:type:`PyComplexObject`, :c:type:`PyFloatObject` and :c:type:`PyBoolObject`. Many of the type slot functions of builtin types are not initialised in cpyext and can therefore not be used directly. Similarly, almost none of the (implementation) specific struct fields of builtin types is exposed at the C level, such as the ``ob_digit`` field of :c:type:`PyLongObject` or the ``allocated`` field of the :c:type:`PyListObject` struct etc. Although the ``ob_size`` field of containers (used by the :c:func:`Py_SIZE()` macro) is available, it is not guaranteed to be accurate. It is best not to access any of these struct fields and slots and to use the normal Python types instead as well as the normal Python protocols for object operations. Cython will map them to an appropriate usage of the C-API in both CPython and cpyext. GIL handling ------------ Currently, the GIL handling function :c:func:`PyGILState_Ensure` is not re-entrant in PyPy and deadlocks when called twice. This means that code that tries to acquire the GIL "just in case", because it might be called with or without the GIL, will not work as expected in PyPy. See `PyGILState_Ensure should not deadlock if GIL already held `_. Efficiency ---------- Simple functions and especially macros that are used for speed in CPython may exhibit substantially different performance characteristics in cpyext. Functions returning borrowed references were already mentioned as requiring special care, but they also induce substantially more runtime overhead because they often create weak references in PyPy where they only return a plain pointer in CPython. A visible example is :c:func:`PyTuple_GET_ITEM()`. Some more high-level functions may also show entirely different performance characteristics, e.g. :c:func:`PyDict_Next()` for dict iteration. While being the fastest way to iterate over a dict in CPython, having linear time complexity and a low overhead, it currently has quadratic runtime in PyPy because it maps to normal dict iteration, which cannot keep track of the current position between two calls and thus needs to restart the iteration on each call. The general advice applies here even more than in CPython, that it is always best to rely on Cython generating appropriately adapted C-API handling code for you than to use the C-API directly - unless you really know what you are doing. And if you find a better way of doing something in PyPy and cpyext than Cython currently does, it's best to fix Cython for everyone's benefit. Known problems -------------- * As of PyPy 1.9, subtyping builtin types can result in infinite recursion on method calls in some rare cases. * Docstrings of special methods are not propagated to Python space. * The Python 3.x adaptations in pypy3 only slowly start to include the C-API, so more incompatibilities can be expected there. Bugs and crashes ---------------- The cpyext implementation in PyPy is much younger and substantially less mature than the well tested C-API and its underlying native implementation in CPython. This should be remembered when running into crashes, as the problem may not always be in your code or in Cython. Also, PyPy and its cpyext implementation are less easy to debug at the C level than CPython and Cython, simply because they were not designed for it. Cython-0.23.4/docs/src/userguide/pxd_package.rst0000644000175600017570000000304212606202452022716 0ustar jenkinsjenkins00000000000000I think this is a result of a recent change to Pyrex that has been merged into Cython. If a directory contains an :file:`__init__.py` or :file:`__init__.pyx` file, it's now assumed to be a package directory. So, for example, if you have a directory structure:: foo/ __init__.py shrubbing.pxd shrubbing.pyx then the shrubbing module is assumed to belong to a package called 'foo', and its fully qualified module name is 'foo.shrubbing'. So when Pyrex wants to find out whether there is a `.pxd` file for shrubbing, it looks for one corresponding to a module called `foo.shrubbing`. It does this by searching the include path for a top-level package directory called 'foo' containing a file called 'shrubbing.pxd'. However, if foo is the current directory you're running the compiler from, and you haven't added foo to the include path using a -I option, then it won't be on the include path, and the `.pxd` won't be found. What to do about this depends on whether you really intend the module to reside in a package. If you intend shrubbing to be a top-level module, you will have to move it somewhere else where there is no :file:`__init__.*` file. If you do intend it to reside in a package, then there are two alternatives: 1. cd to the directory containing foo and compile from there:: cd ..; cython foo/shrubbing.pyx 2. arrange for the directory containing foo to be passed as a -I option, e.g.:: cython -I .. shrubbing.pyx Arguably this behaviour is not very desirable, and I'll see if I can do something about it. Cython-0.23.4/docs/src/userguide/parallelism.rst0000644000175600017570000002122212606202452022755 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. py:module:: cython.parallel .. _parallel: ********************************** Using Parallelism ********************************** Cython supports native parallelism through the :py:mod:`cython.parallel` module. To use this kind of parallelism, the GIL must be released (see :ref:`Releasing the GIL `). It currently supports OpenMP, but later on more backends might be supported. .. NOTE:: Functionality in this module may only be used from the main thread or parallel regions due to OpenMP restrictions. .. function:: prange([start,] stop[, step][, nogil=False][, schedule=None[, chunksize=None]][, num_threads=None]) This function can be used for parallel loops. OpenMP automatically starts a thread pool and distributes the work according to the schedule used. ``step`` must not be 0. This function can only be used with the GIL released. If ``nogil`` is true, the loop will be wrapped in a nogil section. Thread-locality and reductions are automatically inferred for variables. If you assign to a variable in a prange block, it becomes lastprivate, meaning that the variable will contain the value from the last iteration. If you use an inplace operator on a variable, it becomes a reduction, meaning that the values from the thread-local copies of the variable will be reduced with the operator and assigned to the original variable after the loop. The index variable is always lastprivate. Variables assigned to in a parallel with block will be private and unusable after the block, as there is no concept of a sequentially last value. The ``schedule`` is passed to OpenMP and can be one of the following: static: If a chunksize is provided, iterations are distributed to all threads ahead of time in blocks of the given chunksize. If no chunksize is given, the iteration space is divided into chunks that are approximately equal in size, and at most one chunk is assigned to each thread in advance. This is most appropriate when the scheduling overhead matters and the problem can be cut down into equally sized chunks that are known to have approximately the same runtime. dynamic: The iterations are distributed to threads as they request them, with a default chunk size of 1. This is suitable when the runtime of each chunk differs and is not known in advance and therefore a larger number of smaller chunks is used in order to keep all threads busy. guided: As with dynamic scheduling, the iterations are distributed to threads as they request them, but with decreasing chunk size. The size of each chunk is proportional to the number of unassigned iterations divided by the number of participating threads, decreasing to 1 (or the chunksize if provided). This has an advantage over pure dynamic scheduling when it turns out that the last chunks take more time than expected or are otherwise being badly scheduled, so that most threads start running idle while the last chunks are being worked on by only a smaller number of threads. runtime: The schedule and chunk size are taken from the runtime scheduling variable, which can be set through the ``openmp.omp_set_schedule()`` function call, or the OMP_SCHEDULE environment variable. Note that this essentially disables any static compile time optimisations of the scheduling code itself and may therefore show a slightly worse performance than when the same scheduling policy is statically configured at compile time. .. auto The decision regarding scheduling is delegated to the .. compiler and/or runtime system. The programmer gives .. the implementation the freedom to choose any possible .. mapping of iterations to threads in the team. The default schedule is implementation defined. For more information consult the OpenMP specification [#]_. The ``num_threads`` argument indicates how many threads the team should consist of. If not given, OpenMP will decide how many threads to use. Typically this is the number of cores available on the machine. However, this may be controlled through the ``omp_set_num_threads()`` function, or through the ``OMP_NUM_THREADS`` environment variable. The ``chunksize`` argument indicates the chunksize to be used for dividing the iterations among threads. This is only valid for ``static``, ``dynamic`` and ``guided`` scheduling, and is optional. Different chunksizes may give substatially different performance results, depending on the schedule, the load balance it provides, the scheduling overhead and the amount of false sharing (if any). Example with a reduction:: from cython.parallel import prange cdef int i cdef int sum = 0 for i in prange(n, nogil=True): sum += i print sum Example with a typed memoryview (e.g. a NumPy array):: from cython.parallel import prange def func(double[:] x, double alpha): cdef Py_ssize_t i for i in prange(x.shape[0]): x[i] = alpha * x[i] .. function:: parallel(num_threads=None) This directive can be used as part of a ``with`` statement to execute code sequences in parallel. This is currently useful to setup thread-local buffers used by a prange. A contained prange will be a worksharing loop that is not parallel, so any variable assigned to in the parallel section is also private to the prange. Variables that are private in the parallel block are unavailable after the parallel block. Example with thread-local buffers:: from cython.parallel import parallel, prange from libc.stdlib cimport abort, malloc, free cdef Py_ssize_t idx, i, n = 100 cdef int * local_buf cdef size_t size = 10 with nogil, parallel(): local_buf = malloc(sizeof(int) * size) if local_buf == NULL: abort() # populate our local buffer in a sequential loop for i in xrange(size): local_buf[i] = i * 2 # share the work using the thread-local buffer(s) for i in prange(n, schedule='guided'): func(local_buf) free(local_buf) Later on sections might be supported in parallel blocks, to distribute code sections of work among threads. .. function:: threadid() Returns the id of the thread. For n threads, the ids will range from 0 to n-1. Compiling ========= To actually use the OpenMP support, you need to tell the C or C++ compiler to enable OpenMP. For gcc this can be done as follows in a setup.py:: from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext ext_module = Extension( "hello", ["hello.pyx"], extra_compile_args=['-fopenmp'], extra_link_args=['-fopenmp'], ) setup( name = 'Hello world app', cmdclass = {'build_ext': build_ext}, ext_modules = [ext_module], ) Breaking out of loops ===================== The parallel with and prange blocks support the statements break, continue and return in nogil mode. Additionally, it is valid to use a ``with gil`` block inside these blocks, and have exceptions propagate from them. However, because the blocks use OpenMP, they can not just be left, so the exiting procedure is best-effort. For prange() this means that the loop body is skipped after the first break, return or exception for any subsequent iteration in any thread. It is undefined which value shall be returned if multiple different values may be returned, as the iterations are in no particular order:: from cython.parallel import prange cdef int func(Py_ssize_t n): cdef Py_ssize_t i for i in prange(n, nogil=True): if i == 8: with gil: raise Exception() elif i == 4: break elif i == 2: return i In the example above it is undefined whether an exception shall be raised, whether it will simply break or whether it will return 2. Using OpenMP Functions ====================== OpenMP functions can be used by cimporting ``openmp``:: from cython.parallel cimport parallel cimport openmp cdef int num_threads openmp.omp_set_dynamic(1) with nogil, parallel(): num_threads = openmp.omp_get_num_threads() ... .. rubric:: References .. [#] http://www.openmp.org/mp-documents/spec30.pdf Cython-0.23.4/docs/src/userguide/numpy_tutorial.rst0000644000175600017570000005316612606202452023557 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _numpy_tutorial: ************************** Cython for NumPy users ************************** This tutorial is aimed at NumPy users who have no experience with Cython at all. If you have some knowledge of Cython you may want to skip to the ''Efficient indexing'' section which explains the new improvements made in summer 2008. The main scenario considered is NumPy end-use rather than NumPy/SciPy development. The reason is that Cython is not (yet) able to support functions that are generic with respect to datatype and the number of dimensions in a high-level fashion. This restriction is much more severe for SciPy development than more specific, "end-user" functions. See the last section for more information on this. The style of this tutorial will not fit everybody, so you can also consider: * Robert Bradshaw's `slides on cython for SciPy2008 `_ (a higher-level and quicker introduction) * Basic Cython documentation (see `Cython front page `_). * ``[:enhancements/buffer:Spec for the efficient indexing]`` .. Note:: The fast array access documented below is a completely new feature, and there may be bugs waiting to be discovered. It might be a good idea to do a manual sanity check on the C code Cython generates before using this for serious purposes, at least until some months have passed. Cython at a glance ==================== Cython is a compiler which compiles Python-like code files to C code. Still, ''Cython is not a Python to C translator''. That is, it doesn't take your full program and "turns it into C" -- rather, the result makes full use of the Python runtime environment. A way of looking at it may be that your code is still Python in that it runs within the Python runtime environment, but rather than compiling to interpreted Python bytecode one compiles to native machine code (but with the addition of extra syntax for easy embedding of faster C-like code). This has two important consequences: * Speed. How much depends very much on the program involved though. Typical Python numerical programs would tend to gain very little as most time is spent in lower-level C that is used in a high-level fashion. However for-loop-style programs can gain many orders of magnitude, when typing information is added (and is so made possible as a realistic alternative). * Easy calling into C code. One of Cython's purposes is to allow easy wrapping of C libraries. When writing code in Cython you can call into C code as easily as into Python code. Some Python constructs are not yet supported, though making Cython compile all Python code is a stated goal (among the more important omissions are inner functions and generator functions). Your Cython environment ======================== Using Cython consists of these steps: 1. Write a :file:`.pyx` source file 2. Run the Cython compiler to generate a C file 3. Run a C compiler to generate a compiled library 4. Run the Python interpreter and ask it to import the module However there are several options to automate these steps: 1. The `SAGE `_ mathematics software system provides excellent support for using Cython and NumPy from an interactive command line (like IPython) or through a notebook interface (like Maple/Mathematica). See `this documentation `_. 2. A version of `pyximport `_ is shipped with Cython, so that you can import pyx-files dynamically into Python and have them compiled automatically (See :ref:`pyximport`). 3. Cython supports distutils so that you can very easily create build scripts which automate the process, this is the preferred method for full programs. 4. Manual compilation (see below) .. Note:: If using another interactive command line environment than SAGE, like IPython or Python itself, it is important that you restart the process when you recompile the module. It is not enough to issue an "import" statement again. Installation ============= Unless you are used to some other automatic method: `download Cython `_ (0.9.8.1.1 or later), unpack it, and run the usual ```python setup.py install``. This will install a ``cython`` executable on your system. It is also possible to use Cython from the source directory without installing (simply launch :file:`cython.py` in the root directory). As of this writing SAGE comes with an older release of Cython than required for this tutorial. So if using SAGE you should download the newest Cython and then execute :: $ cd path/to/cython-distro $ path-to-sage/sage -python setup.py install This will install the newest Cython into SAGE. Manual compilation ==================== As it is always important to know what is going on, I'll describe the manual method here. First Cython is run:: $ cython yourmod.pyx This creates :file:`yourmod.c` which is the C source for a Python extension module. A useful additional switch is ``-a`` which will generate a document :file:`yourmod.html`) that shows which Cython code translates to which C code line by line. Then we compile the C file. This may vary according to your system, but the C file should be built like Python was built. Python documentation for writing extensions should have some details. On Linux this often means something like:: $ gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -I/usr/include/python2.7 -o yourmod.so yourmod.c ``gcc`` should have access to the NumPy C header files so if they are not installed at :file:`/usr/include/numpy` or similar you may need to pass another option for those. This creates :file:`yourmod.so` in the same directory, which is importable by Python by using a normal ``import yourmod`` statement. The first Cython program ========================== The code below does 2D discrete convolution of an image with a filter (and I'm sure you can do better!, let it serve for demonstration purposes). It is both valid Python and valid Cython code. I'll refer to it as both :file:`convolve_py.py` for the Python version and :file:`convolve1.pyx` for the Cython version -- Cython uses ".pyx" as its file suffix. .. code-block:: python from __future__ import division import numpy as np def naive_convolve(f, g): # f is an image and is indexed by (v, w) # g is a filter kernel and is indexed by (s, t), # it needs odd dimensions # h is the output image and is indexed by (x, y), # it is not cropped if g.shape[0] % 2 != 1 or g.shape[1] % 2 != 1: raise ValueError("Only odd dimensions on filter supported") # smid and tmid are number of pixels between the center pixel # and the edge, ie for a 5x5 filter they will be 2. # # The output size is calculated by adding smid, tmid to each # side of the dimensions of the input image. vmax = f.shape[0] wmax = f.shape[1] smax = g.shape[0] tmax = g.shape[1] smid = smax // 2 tmid = tmax // 2 xmax = vmax + 2*smid ymax = wmax + 2*tmid # Allocate result image. h = np.zeros([xmax, ymax], dtype=f.dtype) # Do convolution for x in range(xmax): for y in range(ymax): # Calculate pixel value for h at (x,y). Sum one component # for each pixel (s, t) of the filter g. s_from = max(smid - x, -smid) s_to = min((xmax - x) - smid, smid + 1) t_from = max(tmid - y, -tmid) t_to = min((ymax - y) - tmid, tmid + 1) value = 0 for s in range(s_from, s_to): for t in range(t_from, t_to): v = x - smid + s w = y - tmid + t value += g[smid - s, tmid - t] * f[v, w] h[x, y] = value return h This should be compiled to produce :file:`yourmod.so` (for Linux systems). We run a Python session to test both the Python version (imported from ``.py``-file) and the compiled Cython module. .. sourcecode:: ipython In [1]: import numpy as np In [2]: import convolve_py In [3]: convolve_py.naive_convolve(np.array([[1, 1, 1]], dtype=np.int), ... np.array([[1],[2],[1]], dtype=np.int)) Out [3]: array([[1, 1, 1], [2, 2, 2], [1, 1, 1]]) In [4]: import convolve1 In [4]: convolve1.naive_convolve(np.array([[1, 1, 1]], dtype=np.int), ... np.array([[1],[2],[1]], dtype=np.int)) Out [4]: array([[1, 1, 1], [2, 2, 2], [1, 1, 1]]) In [11]: N = 100 In [12]: f = np.arange(N*N, dtype=np.int).reshape((N,N)) In [13]: g = np.arange(81, dtype=np.int).reshape((9, 9)) In [19]: %timeit -n2 -r3 convolve_py.naive_convolve(f, g) 2 loops, best of 3: 1.86 s per loop In [20]: %timeit -n2 -r3 convolve1.naive_convolve(f, g) 2 loops, best of 3: 1.41 s per loop There's not such a huge difference yet; because the C code still does exactly what the Python interpreter does (meaning, for instance, that a new object is allocated for each number used). Look at the generated html file and see what is needed for even the simplest statements you get the point quickly. We need to give Cython more information; we need to add types. Adding types ============= To add types we use custom Cython syntax, so we are now breaking Python source compatibility. Here's :file:`convolve2.pyx`. *Read the comments!* :: from __future__ import division import numpy as np # "cimport" is used to import special compile-time information # about the numpy module (this is stored in a file numpy.pxd which is # currently part of the Cython distribution). cimport numpy as np # We now need to fix a datatype for our arrays. I've used the variable # DTYPE for this, which is assigned to the usual NumPy runtime # type info object. DTYPE = np.int # "ctypedef" assigns a corresponding compile-time type to DTYPE_t. For # every type in the numpy module there's a corresponding compile-time # type with a _t-suffix. ctypedef np.int_t DTYPE_t # The builtin min and max functions works with Python objects, and are # so very slow. So we create our own. # - "cdef" declares a function which has much less overhead than a normal # def function (but it is not Python-callable) # - "inline" is passed on to the C compiler which may inline the functions # - The C type "int" is chosen as return type and argument types # - Cython allows some newer Python constructs like "a if x else b", but # the resulting C file compiles with Python 2.3 through to Python 3.0 beta. cdef inline int int_max(int a, int b): return a if a >= b else b cdef inline int int_min(int a, int b): return a if a <= b else b # "def" can type its arguments but not have a return type. The type of the # arguments for a "def" function is checked at run-time when entering the # function. # # The arrays f, g and h is typed as "np.ndarray" instances. The only effect # this has is to a) insert checks that the function arguments really are # NumPy arrays, and b) make some attribute access like f.shape[0] much # more efficient. (In this example this doesn't matter though.) def naive_convolve(np.ndarray f, np.ndarray g): if g.shape[0] % 2 != 1 or g.shape[1] % 2 != 1: raise ValueError("Only odd dimensions on filter supported") assert f.dtype == DTYPE and g.dtype == DTYPE # The "cdef" keyword is also used within functions to type variables. It # can only be used at the top indendation level (there are non-trivial # problems with allowing them in other places, though we'd love to see # good and thought out proposals for it). # # For the indices, the "int" type is used. This corresponds to a C int, # other C types (like "unsigned int") could have been used instead. # Purists could use "Py_ssize_t" which is the proper Python type for # array indices. cdef int vmax = f.shape[0] cdef int wmax = f.shape[1] cdef int smax = g.shape[0] cdef int tmax = g.shape[1] cdef int smid = smax // 2 cdef int tmid = tmax // 2 cdef int xmax = vmax + 2*smid cdef int ymax = wmax + 2*tmid cdef np.ndarray h = np.zeros([xmax, ymax], dtype=DTYPE) cdef int x, y, s, t, v, w # It is very important to type ALL your variables. You do not get any # warnings if not, only much slower code (they are implicitly typed as # Python objects). cdef int s_from, s_to, t_from, t_to # For the value variable, we want to use the same data type as is # stored in the array, so we use "DTYPE_t" as defined above. # NB! An important side-effect of this is that if "value" overflows its # datatype size, it will simply wrap around like in C, rather than raise # an error like in Python. cdef DTYPE_t value for x in range(xmax): for y in range(ymax): s_from = int_max(smid - x, -smid) s_to = int_min((xmax - x) - smid, smid + 1) t_from = int_max(tmid - y, -tmid) t_to = int_min((ymax - y) - tmid, tmid + 1) value = 0 for s in range(s_from, s_to): for t in range(t_from, t_to): v = x - smid + s w = y - tmid + t value += g[smid - s, tmid - t] * f[v, w] h[x, y] = value return h At this point, have a look at the generated C code for :file:`convolve1.pyx` and :file:`convolve2.pyx`. Click on the lines to expand them and see corresponding C. (Note that this code annotation is currently experimental and especially "trailing" cleanup code for a block may stick to the last expression in the block and make it look worse than it is -- use some common sense). * .. literalinclude: convolve1.html * .. literalinclude: convolve2.html Especially have a look at the for loops: In :file:`convolve1.c`, these are ~20 lines of C code to set up while in :file:`convolve2.c` a normal C for loop is used. After building this and continuing my (very informal) benchmarks, I get: .. sourcecode:: ipython In [21]: import convolve2 In [22]: %timeit -n2 -r3 convolve2.naive_convolve(f, g) 2 loops, best of 3: 828 ms per loop Efficient indexing ==================== There's still a bottleneck killing performance, and that is the array lookups and assignments. The ``[]``-operator still uses full Python operations -- what we would like to do instead is to access the data buffer directly at C speed. What we need to do then is to type the contents of the :obj:`ndarray` objects. We do this with a special "buffer" syntax which must be told the datatype (first argument) and number of dimensions ("ndim" keyword-only argument, if not provided then one-dimensional is assumed). More information on this syntax [:enhancements/buffer:can be found here]. Showing the changes needed to produce :file:`convolve3.pyx` only:: ... def naive_convolve(np.ndarray[DTYPE_t, ndim=2] f, np.ndarray[DTYPE_t, ndim=2] g): ... cdef np.ndarray[DTYPE_t, ndim=2] h = ... Usage: .. sourcecode:: ipython In [18]: import convolve3 In [19]: %timeit -n3 -r100 convolve3.naive_convolve(f, g) 3 loops, best of 100: 11.6 ms per loop Note the importance of this change. *Gotcha*: This efficient indexing only affects certain index operations, namely those with exactly ``ndim`` number of typed integer indices. So if ``v`` for instance isn't typed, then the lookup ``f[v, w]`` isn't optimized. On the other hand this means that you can continue using Python objects for sophisticated dynamic slicing etc. just as when the array is not typed. Tuning indexing further ======================== The array lookups are still slowed down by two factors: 1. Bounds checking is performed. 2. Negative indices are checked for and handled correctly. The code above is explicitly coded so that it doesn't use negative indices, and it (hopefully) always access within bounds. We can add a decorator to disable bounds checking:: ... cimport cython @cython.boundscheck(False) # turn of bounds-checking for entire function def naive_convolve(np.ndarray[DTYPE_t, ndim=2] f, np.ndarray[DTYPE_t, ndim=2] g): ... Now bounds checking is not performed (and, as a side-effect, if you ''do'' happen to access out of bounds you will in the best case crash your program and in the worst case corrupt data). It is possible to switch bounds-checking mode in many ways, see :ref:`compiler-directives` for more information. Negative indices are dealt with by ensuring Cython that the indices will be positive, by casting the variables to unsigned integer types (if you do have negative values, then this casting will create a very large positive value instead and you will attempt to access out-of-bounds values). Casting is done with a special ``<>``-syntax. The code below is changed to use either unsigned ints or casting as appropriate:: ... cdef int s, t # changed cdef unsigned int x, y, v, w # changed cdef int s_from, s_to, t_from, t_to cdef DTYPE_t value for x in range(xmax): for y in range(ymax): s_from = max(smid - x, -smid) s_to = min((xmax - x) - smid, smid + 1) t_from = max(tmid - y, -tmid) t_to = min((ymax - y) - tmid, tmid + 1) value = 0 for s in range(s_from, s_to): for t in range(t_from, t_to): v = (x - smid + s) # changed w = (y - tmid + t) # changed value += g[(smid - s), (tmid - t)] * f[v, w] # changed h[x, y] = value ... (In the next Cython release we will likely add a compiler directive or argument to the ``np.ndarray[]``-type specifier to disable negative indexing so that casting so much isn't necessary; feedback on this is welcome.) The function call overhead now starts to play a role, so we compare the latter two examples with larger N: .. sourcecode:: ipython In [11]: %timeit -n3 -r100 convolve4.naive_convolve(f, g) 3 loops, best of 100: 5.97 ms per loop In [12]: N = 1000 In [13]: f = np.arange(N*N, dtype=np.int).reshape((N,N)) In [14]: g = np.arange(81, dtype=np.int).reshape((9, 9)) In [17]: %timeit -n1 -r10 convolve3.naive_convolve(f, g) 1 loops, best of 10: 1.16 s per loop In [18]: %timeit -n1 -r10 convolve4.naive_convolve(f, g) 1 loops, best of 10: 597 ms per loop (Also this is a mixed benchmark as the result array is allocated within the function call.) .. Warning:: Speed comes with some cost. Especially it can be dangerous to set typed objects (like ``f``, ``g`` and ``h`` in our sample code) to ``None``. Setting such objects to ``None`` is entirely legal, but all you can do with them is check whether they are None. All other use (attribute lookup or indexing) can potentially segfault or corrupt data (rather than raising exceptions as they would in Python). The actual rules are a bit more complicated but the main message is clear: Do not use typed objects without knowing that they are not set to ``None``. More generic code ================== It would be possible to do:: def naive_convolve(object[DTYPE_t, ndim=2] f, ...): i.e. use :obj:`object` rather than :obj:`np.ndarray`. Under Python 3.0 this can allow your algorithm to work with any libraries supporting the buffer interface; and support for e.g. the Python Imaging Library may easily be added if someone is interested also under Python 2.x. There is some speed penalty to this though (as one makes more assumptions compile-time if the type is set to :obj:`np.ndarray`, specifically it is assumed that the data is stored in pure strided more and not in indirect mode). [:enhancements/buffer:More information] The future ============ These are some points to consider for further development. All points listed here has gone through a lot of thinking and planning already; still they may or may not happen depending on available developer time and resources for Cython. 1. Support for efficient access to structs/records stored in arrays; currently only primitive types are allowed. 2. Support for efficient access to complex floating point types in arrays. The main obstacle here is getting support for efficient complex datatypes in Cython. 3. Calling NumPy/SciPy functions currently has a Python call overhead; it would be possible to take a short-cut from Cython directly to C. (This does however require some isolated and incremental changes to those libraries; mail the Cython mailing list for details). 4. Efficient code that is generic with respect to the number of dimensions. This can probably be done today by calling the NumPy C multi-dimensional iterator API directly; however it would be nice to have for-loops over :func:`enumerate` and :func:`ndenumerate` on NumPy arrays create efficient code. 5. A high-level construct for writing type-generic code, so that one can write functions that work simultaneously with many datatypes. Note however that a macro preprocessor language can help with doing this for now. Cython-0.23.4/docs/src/userguide/memoryviews.rst0000644000175600017570000005377112606202452023054 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _memoryviews: ***************** Typed Memoryviews ***************** Typed memoryviews allow efficient access to memory buffers, such as those underlying NumPy arrays, without incurring any Python overhead. Memoryviews are similar to the current NumPy array buffer support (``np.ndarray[np.float64_t, ndim=2]``), but they have more features and cleaner syntax. Memoryviews are more general than the old NumPy array buffer support, because they can handle a wider variety of sources of array data. For example, they can handle C arrays and the Cython array type (:ref:`view_cython_arrays`). A memoryview can be used in any context (function parameters, module-level, cdef class attribute, etc) and can be obtained from nearly any object that exposes writable buffer through the `PEP 3118`_ buffer interface. .. _view_quickstart: Quickstart ========== If you are used to working with NumPy, the following examples should get you started with Cython memory views. :: from cython.view cimport array as cvarray import numpy as np # Memoryview on a NumPy array narr = np.arange(27, dtype=np.dtype("i")).reshape((3, 3, 3)) cdef int [:, :, :] narr_view = narr # Memoryview on a C array cdef int carr[3][3][3] cdef int [:, :, :] carr_view = carr # Memoryview on a Cython array cyarr = cvarray(shape=(3, 3, 3), itemsize=sizeof(int), format="i") cdef int [:, :, :] cyarr_view = cyarr # Show the sum of all the arrays before altering it print("NumPy sum of the NumPy array before assignments: %s" % narr.sum()) # We can copy the values from one memoryview into another using a single # statement, by either indexing with ... or (NumPy-style) with a colon. carr_view[...] = narr_view cyarr_view[:] = narr_view # NumPy-style syntax for assigning a single value to all elements. narr_view[:, :, :] = 3 # Just to distinguish the arrays carr_view[0, 0, 0] = 100 cyarr_view[0, 0, 0] = 1000 # Assigning into the memoryview on the NumPy array alters the latter print("NumPy sum of NumPy array after assignments: %s" % narr.sum()) # A function using a memoryview does not usually need the GIL cpdef int sum3d(int[:, :, :] arr) nogil: cdef size_t i, j, k cdef int total = 0 I = arr.shape[0] J = arr.shape[1] K = arr.shape[2] for i in range(I): for j in range(J): for k in range(K): total += arr[i, j, k] return total # A function accepting a memoryview knows how to use a NumPy array, # a C array, a Cython array... print("Memoryview sum of NumPy array is %s" % sum3d(narr)) print("Memoryview sum of C array is %s" % sum3d(carr)) print("Memoryview sum of Cython array is %s" % sum3d(cyarr)) # ... and of course, a memoryview. print("Memoryview sum of C memoryview is %s" % sum3d(carr_view)) This code should give the following output:: NumPy sum of the NumPy array before assignments: 351 NumPy sum of NumPy array after assignments: 81 Memoryview sum of NumPy array is 81 Memoryview sum of C array is 451 Memoryview sum of Cython array is 1351 Memoryview sum of C memoryview is 451 Using memoryviews ================= Syntax ------ Memory views use Python slicing syntax in a similar way as NumPy. To create a complete view on a one-dimensional int buffer:: cdef int[:] view1D = exporting_object A complete 3D view:: cdef int[:,:,:] view3D = exporting_object A 2D view that restricts the first dimension of a buffer to 100 rows starting at the second (index 1) and then skips every second (odd) row:: cdef int[1:102:2,:] partial_view = exporting_object This also works conveniently as function arguments:: .. code-block:: cython def process_3d_buffer(int[1:102:2,:] view not None): ... The ``not None`` declaration for the argument automatically rejects None values as input, which would otherwise be allowed. The reason why None is allowed by default is that it is conveniently used for return arguments:: def process_buffer(int[:,:] input not None, int[:,:] output = None): if output is None: output = ... # e.g. numpy.empty_like(input) # process 'input' into 'output' return output Cython will reject incompatible buffers automatically, e.g. passing a three dimensional buffer into a function that requires a two dimensional buffer will raise a ``ValueError``. Indexing -------- In Cython, index access on memory views is automatically translated into memory addresses. The following code requests a two-dimensional memory view of C ``int`` typed items and indexes into it:: cdef int[:,:] buf = exporting_object print(buf[1,2]) Negative indices work as well, counting from the end of the respective dimension:: print(buf[-1,-2]) The following function loops over each dimension of a 2D array and adds 1 to each item:: def add_one(int[:,:] buf): for x in xrange(buf.shape[0]): for y in xrange(buf.shape[1]): buf[x,y] += 1 Indexing and slicing can be done with or without the GIL. It basically works like NumPy. If indices are specified for every dimension you will get an element of the base type (e.g. `int`). Otherwise, you will get a new view. An Ellipsis means you get consecutive slices for every unspecified dimension:: cdef int[:, :, :] my_view = exporting_object # These are all equivalent my_view[10] my_view[10, :, :] my_view[10, ...] Copying ------- Memory views can be copied in place:: cdef int[:, :, :] to_view, from_view ... # copy the elements in from_view to to_view to_view[...] = from_view # or to_view[:] = from_view # or to_view[:, :, :] = from_view They can also be copied with the ``copy()`` and ``copy_fortran()`` methods; see :ref:`view_copy_c_fortran`. .. _view_transposing: Transposing ----------- In most cases (see below), the memoryview can be transposed in the same way that NumPy slices can be transposed:: cdef int[:, ::1] c_contig = ... cdef int[::1, :] f_contig = c_contig.T This gives a new, transposed, view on the data. Transposing requires that all dimensions of the memoryview have a direct access memory layout (i.e., there are no indirections through pointers). See :ref:`view_general_layouts` for details. Newaxis ------- As for NumPy, new axes can be introduced by indexing an array with ``None`` :: cdef double[:] myslice = np.linspace(0, 10, num=50) # 2D array with shape (1, 50) myslice[None] # or myslice[None, :] # 2D array with shape (50, 1) myslice[:, None] One may mix new axis indexing with all other forms of indexing and slicing. See also an example_. Comparison to the old buffer support ==================================== You will probably prefer memoryviews to the older syntax because: * The syntax is cleaner * Memoryviews do not usually need the GIL (see :ref:`view_needs_gil`) * Memoryviews are considerably faster For example, this is the old syntax equivalent of the ``sum3d`` function above:: cpdef int old_sum3d(object[int, ndim=3, mode='strided'] arr): cdef int I, J, K, total = 0 I = arr.shape[0] J = arr.shape[1] K = arr.shape[2] for i in range(I): for j in range(J): for k in range(K): total += arr[i, j, k] return total Note that we can't use ``nogil`` for the buffer version of the function as we could for the memoryview version of ``sum3d`` above, because buffer objects are Python objects. However, even if we don't use ``nogil`` with the memoryview, it is significantly faster. This is a output from an IPython session after importing both versions:: In [2]: import numpy as np In [3]: arr = np.zeros((40, 40, 40), dtype=int) In [4]: timeit -r15 old_sum3d(arr) 1000 loops, best of 15: 298 us per loop In [5]: timeit -r15 sum3d(arr) 1000 loops, best of 15: 219 us per loop Python buffer support ===================== Cython memoryviews support nearly all objects exporting the interface of Python `new style buffers`_. This is the buffer interface described in `PEP 3118`_. NumPy arrays support this interface, as do :ref:`view_cython_arrays`. The "nearly all" is because the Python buffer interface allows the *elements* in the data array to themselves be pointers; Cython memoryviews do not yet support this. .. _view_memory_layout: Memory layout ============= The buffer interface allows objects to identify the underlying memory in a variety of ways. With the exception of pointers for data elements, Cython memoryviews support all Python new-type buffer layouts. It can be useful to know or specify memory layout if the memory has to be in a particular format for an external routine, or for code optimization. Background ---------- The concepts are as follows: there is data access and data packing. Data access means either direct (no pointer) or indirect (pointer). Data packing means your data may be contiguous or not contiguous in memory, and may use *strides* to identify the jumps in memory consecutive indices need to take for each dimension. NumPy arrays provide a good model of strided direct data access, so we'll use them for a refresher on the concepts of C and Fortran contiguous arrays, and data strides. Brief recap on C, Fortran and strided memory layouts ---------------------------------------------------- The simplest data layout might be a C contiguous array. This is the default layout in NumPy and Cython arrays. C contiguous means that the array data is continuous in memory (see below) and that neighboring elements in the first dimension of the array are furthest apart in memory, whereas neighboring elements in the last dimension are closest together. For example, in NumPy:: In [2]: arr = np.array([['0', '1', '2'], ['3', '4', '5']], dtype='S1') Here, ``arr[0, 0]`` and ``arr[0, 1]`` are one byte apart in memory, whereas ``arr[0, 0]`` and ``arr[1, 0]`` are 3 bytes apart. This leads us to the idea of *strides*. Each axis of the array has a stride length, which is the number of bytes needed to go from one element on this axis to the next element. In the case above, the strides for axes 0 and 1 will obviously be:: In [3]: arr.strides Out[4]: (3, 1) For a 3D C contiguous array:: In [5]: c_contig = np.arange(24, dtype=np.int8).reshape((2,3,4)) In [6] c_contig.strides Out[6]: (12, 4, 1) A Fortran contiguous array has the opposite memory ordering, with the elements on the first axis closest togther in memory:: In [7]: f_contig = np.array(c_contig, order='F') In [8]: np.all(f_contig == c_contig) Out[8]: True In [9]: f_contig.strides Out[9]: (1, 2, 6) A contiguous array is one for which a single continuous block of memory contains all the data for the elements of the array, and therefore the memory block length is the product of number of elements in the array and the size of the elements in bytes. In the example above, the memory block is 2 * 3 * 4 * 1 bytes long, where 1 is the length of an int8. An array can be contiguous without being C or Fortran order:: In [10]: c_contig.transpose((1, 0, 2)).strides Out[10]: (4, 12, 1) Slicing an NumPy array can easily make it not contiguous:: In [11]: sliced = c_contig[:,1,:] In [12]: sliced.strides Out[12]: (12, 1) In [13]: sliced.flags Out[13]: C_CONTIGUOUS : False F_CONTIGUOUS : False OWNDATA : False WRITEABLE : True ALIGNED : True UPDATEIFCOPY : False Default behavior for memoryview layouts --------------------------------------- As you'll see in :ref:`view_general_layouts`, you can specify memory layout for any dimension of an memoryview. For any dimension for which you don't specify a layout, then the data access is assumed to be direct, and the data packing assumed to be strided. For example, that will be the assumption for memoryviews like:: int [:, :, :] my_memoryview = obj C and Fortran contiguous memoryviews ------------------------------------ You can specify C and Fortran contiguous layouts for the memoryview by using the ``::1`` step syntax at definition. For example, if you know for sure your memoryview will be on top of a 3D C contiguous layout, you could write:: cdef int[:, :, ::1] c_contiguous = c_contig where ``c_contig`` could be a C contiguous NumPy array. The ``::1`` at the 3rd position means that the elements in this 3rd dimension will be one element apart in memory. If you know you will have a 3D Fortran contiguous array:: cdef int[::1, :, :] f_contiguous = f_contig If you pass a non-contiguous buffer, for example :: # This array is C contiguous c_contig = np.arange(24).reshape((2,3,4)) cdef int[:, :, ::1] c_contiguous = c_contig # But this isn't c_contiguous = np.array(c_contig, order='F') you will get a ``ValueError`` at runtime:: /Users/mb312/dev_trees/minimal-cython/mincy.pyx in init mincy (mincy.c:17267)() 69 70 # But this isn't ---> 71 c_contiguous = np.array(c_contig, order='F') 72 73 # Show the sum of all the arrays before altering it /Users/mb312/dev_trees/minimal-cython/stringsource in View.MemoryView.memoryview_cwrapper (mincy.c:9995)() /Users/mb312/dev_trees/minimal-cython/stringsource in View.MemoryView.memoryview.__cinit__ (mincy.c:6799)() ValueError: ndarray is not C-contiguous Thus the `::1` in the slice type specification indicates in which dimension the data is contiguous. It can only be used to specify full C or Fortran contiguity. .. _view_copy_c_fortran: C and Fortran contiguous copies ------------------------------- .. Mark : I could not make this work - should it? # This slice is C contiguous c_contig = np.arange(24).reshape((2,3,4)) f_contig = np.array(c_contig, order='F') cdef int [:, :, ::1] c_contig_view = c_contig cdef int [::1, :, :] f_contig_view = f_contig cdef int[:, :, ::1] f2c = f_contig_view.copy() cdef int[::1, :, :] c2f = c_contig_view.copy_fortran() Copies can be made C or Fortran contiguous using the ``.copy()`` and ``.copy_fortran()`` methods:: # This view is C contiguous cdef int[:, :, ::1] c_contiguous = myview.copy() # This view is Fortran contiguous cdef int[::1, :] f_contiguous_slice = myview.copy_fortran() .. _view_general_layouts: Specifying more general memory layouts -------------------------------------- Data layout can be specified using the previously seen ``::1`` slice syntax, or by using any of the constants in ``cython.view``. If no specifier is given in any dimension, then the data access is assumed to be direct, and the data packing assumed to be strided. If you don't know whether a dimension will be direct or indirect (because you're getting an object with a buffer interface from some library perhaps), then you can specify the `generic` flag, in which case it will be determined at runtime. The flags are as follows: * generic - strided and direct or indirect * strided - strided and direct (this is the default) * indirect - strided and indirect * contiguous - contiguous and direct * indirect_contiguous - the list of pointers is contiguous and they can be used like this:: from cython cimport view # direct access in both dimensions, strided in the first dimension, contiguous in the last cdef int[:, ::view.contiguous] a # contiguous list of pointers to contiguous lists of ints cdef int[::view.indirect_contiguous, ::1] b # direct or indirect in the first dimension, direct in the second dimension # strided in both dimensions cdef int[::view.generic, :] c Only the first, last or the dimension following an indirect dimension may be specified contiguous:: # INVALID cdef int[::view.contiguous, ::view.indirect, :] a cdef int[::1, ::view.indirect, :] b # VALID cdef int[::view.indirect, ::1, :] a cdef int[::view.indirect, :, ::1] b cdef int[::view.indirect_contiguous, ::1, :] The difference between the `contiguous` flag and the `::1` specifier is that the former specifies contiguity for only one dimension, whereas the latter specifies contiguity for all following (Fortran) or preceding (C) dimensions:: cdef int[:, ::1] c_contig = ... # VALID cdef int[:, ::view.contiguous] myslice = c_contig[::2] # INVALID cdef int[:, ::1] myslice = c_contig[::2] The former case is valid because the last dimension remains contiguous, but the first dimension does not "follow" the last one anymore (meaning, it was strided already, but it is not C or Fortran contiguous any longer), since it was sliced. .. _view_needs_gil: Memoryviews and the GIL ======================= As you will see from the :ref:`view_quickstart` section, memoryviews often do not need the GIL:: cpdef int sum3d(int[:, :, :] arr) nogil: ... In particular, you do not need the GIL for memoryview indexing, slicing or transposing. Memoryviews require the GIL for the copy methods (:ref:`view_copy_c_fortran`), or when the dtype is object and an object element is read or written. Memoryview Objects and Cython Arrays ==================================== These typed memoryviews can be converted to Python memoryview objects (`cython.view.memoryview`). These Python objects are indexable, slicable and transposable in the same way that the original memoryviews are. They can also be converted back to Cython-space memoryviews at any time. They have the following attributes: * ``shape``: size in each dimension, as a tuple. * ``strides``: stride along each dimension, in bytes. * ``suboffsets`` * ``ndim``: number of dimensions. * ``size``: total number of items in the view (product of the shape). * ``itemsize``: size, in bytes, of the items in the view. * ``nbytes``: equal to ``size`` times ``itemsize``. * ``base`` And of course the aforementioned ``T`` attribute (:ref:`view_transposing`). These attributes have the same semantics as in NumPy_. For instance, to retrieve the original object:: import numpy cimport numpy as cnp cdef cnp.int32_t[:] a = numpy.arange(10, dtype=numpy.int32) a = a[::2] print(a) print(numpy.asarray(a)) print(a.base) # this prints: # # [0 2 4 6 8] # [0 1 2 3 4 5 6 7 8 9] Note that this example returns the original object from which the view was obtained, and that the view was resliced in the meantime. .. _view_cython_arrays: Cython arrays ============= Whenever a Cython memoryview is copied (using any of the `copy` or `copy_fortran` methods), you get a new memoryview slice of a newly created ``cython.view.array`` object. This array can also be used manually, and will automatically allocate a block of data. It can later be assigned to a C or Fortran contiguous slice (or a strided slice). It can be used like:: from cython cimport view my_array = view.array(shape=(10, 2), itemsize=sizeof(int), format="i") cdef int[:, :] my_slice = my_array It also takes an optional argument `mode` ('c' or 'fortran') and a boolean `allocate_buffer`, that indicates whether a buffer should be allocated and freed when it goes out of scope:: cdef view.array my_array = view.array(..., mode="fortran", allocate_buffer=False) my_array.data = my_data_pointer # define a function that can deallocate the data (if needed) my_array.callback_free_data = free You can also cast pointers to array, or C arrays to arrays:: cdef view.array my_array = my_data_pointer cdef view.array my_array = my_c_array Of course, you can also immediately assign a cython.view.array to a typed memoryview slice. A C array may be assigned directly to a memoryview slice:: cdef int[:, ::1] myslice = my_2d_c_array The arrays are indexable and slicable from Python space just like memoryview objects, and have the same attributes as memoryview objects. CPython array module ==================== An alternative to ``cython.view.array`` is the ``array`` module in the Python standard library. In Python 3, the ``array.array`` type supports the buffer interface natively, so memoryviews work on top of it without additional setup. Starting with Cython 0.17, however, it is possible to use these arrays as buffer providers also in Python 2. This is done through explicitly cimporting the ``cpython.array`` module as follows:: cimport cpython.array def sum_array(int[:] view): """ >>> from array import array >>> sum_array( array('i', [1,2,3]) ) 6 """ cdef int total for i in range(view.shape[0]): total += view[i] return total Note that the cimport also enables the old buffer syntax for the array type. Therefore, the following also works:: from cpython cimport array def sum_array(array.array[int] arr): # using old buffer syntax ... Coercion to NumPy ================= Memoryview (and array) objects can be coerced to a NumPy ndarray, without having to copy the data. You can e.g. do:: cimport numpy as np import numpy as np numpy_array = np.asarray( my_pointer) Of course, you are not restricted to using NumPy's type (such as ``np.int32_t`` here), you can use any usable type. None Slices =========== Although memoryview slices are not objects they can be set to None and they can be be checked for being None as well:: def func(double[:] myarray = None): print(myarray is None) If the function requires real memory views as input, it is therefore best to reject None input straight away in the signature, which is supported in Cython 0.17 and later as follows:: def func(double[:] myarray not None): ... Unlike object attributes of extension classes, memoryview slices are not initialized to None. .. _GIL: http://docs.python.org/dev/glossary.html#term-global-interpreter-lock .. _new style buffers: http://docs.python.org/c-api/buffer.html .. _pep 3118: http://www.python.org/peps/pep-3118.html .. _NumPy: http://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html#memory-layout .. _example: http://www.scipy.org/Numpy_Example_List#newaxis Cython-0.23.4/docs/src/userguide/limitations.rst0000644000175600017570000000447012606202452023012 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _cython-limitations: ************* Limitations ************* This page used to list bugs in Cython that made the semantics of compiled code differ from that in Python. Most of the missing features have been fixed in Cython 0.15. The bug tracker has an up-to-date `list of remaining compatibility issues`_. Note that a future version 1.0 of Cython is planned to provide full Python language compatibility. .. _`list of remaining compatibility issues`: http://trac.cython.org/cython_trac/query?status=assigned&status=new&status=reopened&component=Python+Semantics&component=Python3+Semantics&order=priority&col=id&col=summary&col=component&col=status&col=type&col=priority&col=milestone Below is a list of differences that we will probably not be addressing. Most of these things that fall more into the implementation details rather than semantics, and we may decide not to fix (or require a --pedantic flag to get). Nested tuple argument unpacking =============================== :: def f((a,b), c): pass This was removed in Python 3. Inspect support =============== While it is quite possible to emulate the interface of functions in Cython's own function type, and recent Cython releases have seen several improvements here, the "inspect" module does not consider a Cython implemented function a "function", because it tests the object type explicitly instead of comparing an abstract interface or an abstract base class. This has a negative impact on code that uses inspect to inspect function objects, but would require a change to Python itself. Stack frames ============ Currently we generate fake tracebacks as part of exception propagation, but don't fill in locals and can't fill in co_code. To be fully compatible, we would have to generate these stack frame objects at function call time (with a potential performance penalty). We may have an option to enable this for debugging. Identity vs. equality for inferred literals =========================================== :: a = 1.0 # a inferred to be C type 'double' b = c = None # b and c inferred to be type 'object' if some_runtime_expression: b = a # creates a new Python float object c = a # creates a new Python float object print b is c # most likely not the same object Cython-0.23.4/docs/src/userguide/language_basics.rst0000644000175600017570000006247712606202452023600 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _language-basics: .. _struct: .. _union: .. _enum: .. _ctypedef: ***************** Language Basics ***************** C variable and type definitions =============================== The :keyword:`cdef` statement is used to declare C variables, either local or module-level:: cdef int i, j, k cdef float f, g[42], *h and C :keyword:`struct`, :keyword:`union` or :keyword:`enum` types:: cdef struct Grail: int age float volume cdef union Food: char *spam float *eggs cdef enum CheeseType: cheddar, edam, camembert cdef enum CheeseState: hard = 1 soft = 2 runny = 3 See also :ref:`struct-union-enum-styles` There is currently no special syntax for defining a constant, but you can use an anonymous :keyword:`enum` declaration for this purpose, for example,:: cdef enum: tons_of_spam = 3 .. note:: the words ``struct``, ``union`` and ``enum`` are used only when defining a type, not when referring to it. For example, to declare a variable pointing to a ``Grail`` you would write:: cdef Grail *gp and not:: cdef struct Grail *gp # WRONG There is also a ``ctypedef`` statement for giving names to types, e.g.:: ctypedef unsigned long ULong ctypedef int* IntPtr Types ----- Cython uses the normal C syntax for C types, including pointers. It provides all the standard C types, namely ``char``, ``short``, ``int``, ``long``, ``long long`` as well as their ``unsigned`` versions, e.g. ``unsigned int``. The special ``bint`` type is used for C boolean values (``int`` with 0/non-0 values for False/True) and ``Py_ssize_t`` for (signed) sizes of Python containers. Pointer types are constructed as in C, by appending a ``*`` to the base type they point to, e.g. ``int**`` for a pointer to a pointer to a C int. Arrays use the normal C array syntax, e.g. ``int[10]``. Note that Cython uses array access for pointer dereferencing, as ``*x`` is not valid Python syntax, whereas ``x[0]`` is. Also, the Python types ``list``, ``dict``, ``tuple``, etc. may be used for static typing, as well as any user defined extension types. The Python types int, long, and float are not available for static typing and instead interpreted as C ``int``, ``long``, and ``float`` respectively, as statically typing variables with these Python types has zero advantages. While these C types can be vastly faster, they have C semantics. Specifically, the integer types overflow and the C ``float`` type only has 32 bits of precision (as opposed to the 64-bit C ``double`` which Python floats wrap and is typically what one wants). If you want to use these numeric Python types simply omit the type declaration and let them be objects. Grouping multiple C declarations -------------------------------- If you have a series of declarations that all begin with :keyword:`cdef`, you can group them into a :keyword:`cdef` block like this:: cdef: struct Spam: int tons int i float f Spam *p void f(Spam *s): print s.tons, "Tons of spam" Python functions vs. C functions ================================== There are two kinds of function definition in Cython: Python functions are defined using the def statement, as in Python. They take Python objects as parameters and return Python objects. C functions are defined using the new :keyword:`cdef` statement. They take either Python objects or C values as parameters, and can return either Python objects or C values. Within a Cython module, Python functions and C functions can call each other freely, but only Python functions can be called from outside the module by interpreted Python code. So, any functions that you want to "export" from your Cython module must be declared as Python functions using def. There is also a hybrid function, called :keyword:`cpdef`. A :keyword:`cpdef` can be called from anywhere, but uses the faster C calling conventions when being called from other Cython code. A :keyword:`cpdef` can also be overridden by a Python method on a subclass or an instance attribute, even when called from Cython. If this happens, most performance gains are of course lost and even if it does not, there is a tiny overhead in calling a :keyword:`cpdef` method from Cython compared to calling a :keyword:`cdef` method. Parameters of either type of function can be declared to have C data types, using normal C declaration syntax. For example,:: def spam(int i, char *s): ... cdef int eggs(unsigned long l, float f): ... When a parameter of a Python function is declared to have a C data type, it is passed in as a Python object and automatically converted to a C value, if possible. In other words, the definition of ``spam`` above is equivalent to writing:: def spam(python_i, python_s): cdef int i = python_i cdef char* s = python_s ... Automatic conversion is currently only possible for numeric types, string types and structs (composed recursively of any of these types); attempting to use any other type for the parameter of a Python function will result in a compile-time error. Care must be taken with strings to ensure a reference if the pointer is to be used after the call. Structs can be obtained from Python mappings, and again care must be taken with string attributes if they are to be used after the function returns. C functions, on the other hand, can have parameters of any type, since they're passed in directly using a normal C function call. Functions declared using :keyword:`cdef`, like Python functions, will return a :keyword:`False` value when execution leaves the function body without an explicit return value. This is in contrast to C/C++, which leaves the return value undefined. A more complete comparison of the pros and cons of these different method types can be found at :ref:`early-binding-for-speed`. Python objects as parameters and return values ---------------------------------------------- If no type is specified for a parameter or return value, it is assumed to be a Python object. (Note that this is different from the C convention, where it would default to int.) For example, the following defines a C function that takes two Python objects as parameters and returns a Python object:: cdef spamobjs(x, y): ... Reference counting for these objects is performed automatically according to the standard Python/C API rules (i.e. borrowed references are taken as parameters and a new reference is returned). The name object can also be used to explicitly declare something as a Python object. This can be useful if the name being declared would otherwise be taken as the name of a type, for example,:: cdef ftang(object int): ... declares a parameter called int which is a Python object. You can also use object as the explicit return type of a function, e.g.:: cdef object ftang(object int): ... In the interests of clarity, it is probably a good idea to always be explicit about object parameters in C functions. Error return values ------------------- If you don't do anything special, a function declared with :keyword:`cdef` that does not return a Python object has no way of reporting Python exceptions to its caller. If an exception is detected in such a function, a warning message is printed and the exception is ignored. If you want a C function that does not return a Python object to be able to propagate exceptions to its caller, you need to declare an exception value for it. Here is an example:: cdef int spam() except -1: ... With this declaration, whenever an exception occurs inside spam, it will immediately return with the value ``-1``. Furthermore, whenever a call to spam returns ``-1``, an exception will be assumed to have occurred and will be propagated. When you declare an exception value for a function, you should never explicitly or implicitly return that value. In particular, if the exceptional return value is a ``False`` value, then you should ensure the function will never terminate via an implicit or empty return. If all possible return values are legal and you can't reserve one entirely for signalling errors, you can use an alternative form of exception value declaration:: cdef int spam() except? -1: ... The "?" indicates that the value ``-1`` only indicates a possible error. In this case, Cython generates a call to :c:func:`PyErr_Occurred` if the exception value is returned, to make sure it really is an error. There is also a third form of exception value declaration:: cdef int spam() except *: ... This form causes Cython to generate a call to :c:func:`PyErr_Occurred` after every call to spam, regardless of what value it returns. If you have a function returning void that needs to propagate errors, you will have to use this form, since there isn't any return value to test. Otherwise there is little use for this form. An external C++ function that may raise an exception can be declared with:: cdef int spam() except + See :ref:`wrapping-cplusplus` for more details. Some things to note: * Exception values can only declared for functions returning an integer, enum, float or pointer type, and the value must be a constant expression. Void functions can only use the ``except *`` form. * The exception value specification is part of the signature of the function. If you're passing a pointer to a function as a parameter or assigning it to a variable, the declared type of the parameter or variable must have the same exception value specification (or lack thereof). Here is an example of a pointer-to-function declaration with an exception value:: int (*grail)(int, char*) except -1 * You don't need to (and shouldn't) declare exception values for functions which return Python objects. Remember that a function with no declared return type implicitly returns a Python object. (Exceptions on such functions are implicitly propagated by returning NULL.) Checking return values of non-Cython functions ---------------------------------------------- It's important to understand that the except clause does not cause an error to be raised when the specified value is returned. For example, you can't write something like:: cdef extern FILE *fopen(char *filename, char *mode) except NULL # WRONG! and expect an exception to be automatically raised if a call to :func:`fopen` returns ``NULL``. The except clause doesn't work that way; its only purpose is for propagating Python exceptions that have already been raised, either by a Cython function or a C function that calls Python/C API routines. To get an exception from a non-Python-aware function such as :func:`fopen`, you will have to check the return value and raise it yourself, for example,:: cdef FILE* p p = fopen("spam.txt", "r") if p == NULL: raise SpamError("Couldn't open the spam file") Automatic type conversions ========================== In most situations, automatic conversions will be performed for the basic numeric and string types when a Python object is used in a context requiring a C value, or vice versa. The following table summarises the conversion possibilities. +----------------------------+--------------------+------------------+ | C types | From Python types | To Python types | +============================+====================+==================+ | [unsigned] char, | int, long | int | | [unsigned] short, | | | | int, long | | | +----------------------------+--------------------+------------------+ | unsigned int, | int, long | long | | unsigned long, | | | | [unsigned] long long | | | +----------------------------+--------------------+------------------+ | float, double, long double | int, long, float | float | +----------------------------+--------------------+------------------+ | char* | str/bytes | str/bytes [#]_ | +----------------------------+--------------------+------------------+ | struct, | | dict [#1]_ | | union | | | +----------------------------+--------------------+------------------+ .. [#] The conversion is to/from str for Python 2.x, and bytes for Python 3.x. .. [#1] The conversion from a C union type to a Python dict will add a value for each of the union fields. Cython 0.23 and later, however, will refuse to automatically convert a union with unsafe type combinations. An example is a union of an ``int`` and a ``char*``, in which case the pointer value may or be not be a valid pointer. Caveats when using a Python string in a C context ------------------------------------------------- You need to be careful when using a Python string in a context expecting a ``char*``. In this situation, a pointer to the contents of the Python string is used, which is only valid as long as the Python string exists. So you need to make sure that a reference to the original Python string is held for as long as the C string is needed. If you can't guarantee that the Python string will live long enough, you will need to copy the C string. Cython detects and prevents some mistakes of this kind. For instance, if you attempt something like:: cdef char *s s = pystring1 + pystring2 then Cython will produce the error message ``Obtaining char* from temporary Python value``. The reason is that concatenating the two Python strings produces a new Python string object that is referenced only by a temporary internal variable that Cython generates. As soon as the statement has finished, the temporary variable will be decrefed and the Python string deallocated, leaving ``s`` dangling. Since this code could not possibly work, Cython refuses to compile it. The solution is to assign the result of the concatenation to a Python variable, and then obtain the ``char*`` from that, i.e.:: cdef char *s p = pystring1 + pystring2 s = p It is then your responsibility to hold the reference p for as long as necessary. Keep in mind that the rules used to detect such errors are only heuristics. Sometimes Cython will complain unnecessarily, and sometimes it will fail to detect a problem that exists. Ultimately, you need to understand the issue and be careful what you do. Statements and expressions ========================== Control structures and expressions follow Python syntax for the most part. When applied to Python objects, they have the same semantics as in Python (unless otherwise noted). Most of the Python operators can also be applied to C values, with the obvious semantics. If Python objects and C values are mixed in an expression, conversions are performed automatically between Python objects and C numeric or string types. Reference counts are maintained automatically for all Python objects, and all Python operations are automatically checked for errors, with appropriate action taken. Differences between C and Cython expressions -------------------------------------------- There are some differences in syntax and semantics between C expressions and Cython expressions, particularly in the area of C constructs which have no direct equivalent in Python. * An integer literal is treated as a C constant, and will be truncated to whatever size your C compiler thinks appropriate. To get a Python integer (of arbitrary precision) cast immediately to an object (e.g. ``100000000000000000000``). The ``L``, ``LL``, and ``U`` suffixes have the same meaning as in C. * There is no ``->`` operator in Cython. Instead of ``p->x``, use ``p.x`` * There is no unary ``*`` operator in Cython. Instead of ``*p``, use ``p[0]`` * There is an ``&`` operator, with the same semantics as in C. * The null C pointer is called ``NULL``, not ``0`` (and ``NULL`` is a reserved word). * Type casts are written ``value`` , for example,:: cdef char* p, float* q p = q Scope rules ----------- Cython determines whether a variable belongs to a local scope, the module scope, or the built-in scope completely statically. As with Python, assigning to a variable which is not otherwise declared implicitly declares it to be a variable residing in the scope where it is assigned. The type of the variable depends on type inference, except for the global module scope, where it is always a Python object. Built-in Functions ------------------ Cython compiles calls to most built-in functions into direct calls to the corresponding Python/C API routines, making them particularly fast. Only direct function calls using these names are optimised. If you do something else with one of these names that assumes it's a Python object, such as assign it to a Python variable, and later call it, the call will be made as a Python function call. +------------------------------+-------------+----------------------------+ | Function and arguments | Return type | Python/C API Equivalent | +==============================+=============+============================+ | abs(obj) | object, | PyNumber_Absolute, fabs, | | | double, ... | fabsf, ... | +------------------------------+-------------+----------------------------+ | callable(obj) | bint | PyObject_Callable | +------------------------------+-------------+----------------------------+ | delattr(obj, name) | None | PyObject_DelAttr | +------------------------------+-------------+----------------------------+ | exec(code, [glob, [loc]]) | object | - | +------------------------------+-------------+----------------------------+ | dir(obj) | list | PyObject_Dir | +------------------------------+-------------+----------------------------+ | divmod(a, b) | tuple | PyNumber_Divmod | +------------------------------+-------------+----------------------------+ | getattr(obj, name, [default])| object | PyObject_GetAttr | | (Note 1) | | | +------------------------------+-------------+----------------------------+ | hasattr(obj, name) | bint | PyObject_HasAttr | +------------------------------+-------------+----------------------------+ | hash(obj) | int / long | PyObject_Hash | +------------------------------+-------------+----------------------------+ | intern(obj) | object | Py*_InternFromString | +------------------------------+-------------+----------------------------+ | isinstance(obj, type) | bint | PyObject_IsInstance | +------------------------------+-------------+----------------------------+ | issubclass(obj, type) | bint | PyObject_IsSubclass | +------------------------------+-------------+----------------------------+ | iter(obj, [sentinel]) | object | PyObject_GetIter | +------------------------------+-------------+----------------------------+ | len(obj) | Py_ssize_t | PyObject_Length | +------------------------------+-------------+----------------------------+ | pow(x, y, [z]) | object | PyNumber_Power | +------------------------------+-------------+----------------------------+ | reload(obj) | object | PyImport_ReloadModule | +------------------------------+-------------+----------------------------+ | repr(obj) | object | PyObject_Repr | +------------------------------+-------------+----------------------------+ | setattr(obj, name) | void | PyObject_SetAttr | +------------------------------+-------------+----------------------------+ Note 1: Pyrex originally provided a function :func:`getattr3(obj, name, default)` corresponding to the three-argument form of the Python builtin :func:`getattr()`. Cython still supports this function, but the usage is deprecated in favour of the normal builtin, which Cython can optimise in both forms. Operator Precedence ------------------- Keep in mind that there are some differences in operator precedence between Python and C, and that Cython uses the Python precedences, not the C ones. Integer for-loops ------------------ Cython recognises the usual Python for-in-range integer loop pattern:: for i in range(n): ... If ``i`` is declared as a :keyword:`cdef` integer type, it will optimise this into a pure C loop. This restriction is required as otherwise the generated code wouldn't be correct due to potential integer overflows on the target architecture. If you are worried that the loop is not being converted correctly, use the annotate feature of the cython commandline (``-a``) to easily see the generated C code. See :ref:`automatic-range-conversion` For backwards compatibility to Pyrex, Cython also supports a more verbose form of for-loop which you might find in legacy code:: for i from 0 <= i < n: ... or:: for i from 0 <= i < n by s: ... where ``s`` is some integer step size. .. note:: This syntax is deprecated and should not be used in new code. Use the normal Python for-loop instead. Some things to note about the for-from loop: * The target expression must be a plain variable name. * The name between the lower and upper bounds must be the same as the target name. * The direction of iteration is determined by the relations. If they are both from the set {``<``, ``<=``} then it is upwards; if they are both from the set {``>``, ``>=``} then it is downwards. (Any other combination is disallowed.) Like other Python looping statements, break and continue may be used in the body, and the loop may have an else clause. The include statement ===================== .. warning:: Historically the ``include`` statement was used for sharing declarations. Use :ref:`sharing-declarations` instead. A Cython source file can include material from other files using the include statement, for example,:: include "spamstuff.pxi" The contents of the named file are textually included at that point. The included file can contain any complete statements or declarations that are valid in the context where the include statement appears, including other include statements. The contents of the included file should begin at an indentation level of zero, and will be treated as though they were indented to the level of the include statement that is including the file. .. note:: There are other mechanisms available for splitting Cython code into separate parts that may be more appropriate in many cases. See :ref:`sharing-declarations`. Conditional Compilation ======================= Some features are available for conditional compilation and compile-time constants within a Cython source file. Compile-Time Definitions ------------------------ A compile-time constant can be defined using the DEF statement:: DEF FavouriteFood = "spam" DEF ArraySize = 42 DEF OtherArraySize = 2 * ArraySize + 17 The right-hand side of the ``DEF`` must be a valid compile-time expression. Such expressions are made up of literal values and names defined using ``DEF`` statements, combined using any of the Python expression syntax. The following compile-time names are predefined, corresponding to the values returned by :func:`os.uname`. UNAME_SYSNAME, UNAME_NODENAME, UNAME_RELEASE, UNAME_VERSION, UNAME_MACHINE The following selection of builtin constants and functions are also available: None, True, False, abs, bool, chr, cmp, complex, dict, divmod, enumerate, float, hash, hex, int, len, list, long, map, max, min, oct, ord, pow, range, reduce, repr, round, slice, str, sum, tuple, xrange, zip A name defined using ``DEF`` can be used anywhere an identifier can appear, and it is replaced with its compile-time value as though it were written into the source at that point as a literal. For this to work, the compile-time expression must evaluate to a Python value of type ``int``, ``long``, ``float`` or ``str``.:: cdef int a1[ArraySize] cdef int a2[OtherArraySize] print "I like", FavouriteFood Conditional Statements ---------------------- The ``IF`` statement can be used to conditionally include or exclude sections of code at compile time. It works in a similar way to the ``#if`` preprocessor directive in C.:: IF UNAME_SYSNAME == "Windows": include "icky_definitions.pxi" ELIF UNAME_SYSNAME == "Darwin": include "nice_definitions.pxi" ELIF UNAME_SYSNAME == "Linux": include "penguin_definitions.pxi" ELSE: include "other_definitions.pxi" The ``ELIF`` and ``ELSE`` clauses are optional. An ``IF`` statement can appear anywhere that a normal statement or declaration can appear, and it can contain any statements or declarations that would be valid in that context, including ``DEF`` statements and other ``IF`` statements. The expressions in the ``IF`` and ``ELIF`` clauses must be valid compile-time expressions as for the ``DEF`` statement, although they can evaluate to any Python value, and the truth of the result is determined in the usual Python way. Cython-0.23.4/docs/src/userguide/index.rst0000644000175600017570000000072112606202452021560 0ustar jenkinsjenkins00000000000000Users Guide =========== Contents: .. toctree:: :maxdepth: 2 language_basics extension_types special_methods sharing_declarations external_C_code source_files_and_compilation early_binding_for_speed wrapping_CPlusPlus fusedtypes pypy limitations pyrex_differences memoryviews buffer parallelism debugging Indices and tables ------------------ * :ref:`genindex` * :ref:`modindex` * :ref:`search` .. toctree:: Cython-0.23.4/docs/src/userguide/fusedtypes.rst0000644000175600017570000002150612606202452022650 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _fusedtypes: *********************** Fused Types (Templates) *********************** Fused types allow you to have one type definition that can refer to multiple types. This allows you to write a single static-typed cython algorithm that can operate on values of multiple types. Thus fused types allow `generic programming`_ and are akin to templates in C++ or generics in languages like Java / C#. .. _generic programming: http://en.wikipedia.org/wiki/Generic_programming .. Note:: Support is still somewhat experimental, there may be bugs! .. Note:: Fused types are not currently supported as attributes of extension types. Only variables and function/method arguments can be declared with fused types. Quickstart ========== :: cimport cython ctypedef fused char_or_float: cython.char cython.float cpdef char_or_float plus_one(char_or_float var): return var + 1 def show_me(): cdef: cython.char a = 127 cython.float b = 127 print 'char', plus_one(a) print 'float', plus_one(b) This gives:: >>> show_me() char -128 float 128.0 ``plus_one(a)`` "specializes" the fused type ``char_or_float`` as a ``char``, whereas ``plus_one(b)`` specializes ``char_or_float`` as a ``float``. Declaring Fused Types ===================== Fused types may be declared as follows:: cimport cython ctypedef fused my_fused_type: cython.int cython.double This declares a new type called ``my_fused_type`` which can be *either* an ``int`` *or* a ``double``. Alternatively, the declaration may be written as:: my_fused_type = cython.fused_type(cython.int, cython.float) Only names may be used for the constituent types, but they may be any (non-fused) type, including a typedef. i.e. one may write:: ctypedef double my_double my_fused_type = cython.fused_type(cython.int, my_double) Using Fused Types ================= Fused types can be used to declare parameters of functions or methods:: cdef cfunc(my_fused_type arg): return arg + 1 If the you use the same fused type more than once in an argument list, then each specialization of the fused type must be the same:: cdef cfunc(my_fused_type arg1, my_fused_type arg2): return cython.typeof(arg1) == cython.typeof(arg2) In this case, the type of both parameters is either an int, or a double (according to the previous examples). However, because these arguments use the same fused type ``my_fused_type``, both ``arg1`` and ``arg2`` are specialized to the same type. Therefore this function returns True for every possible valid invocation. You are allowed to mix fused types however:: def func(A x, B y): ... where ``A`` and ``B`` are different fused types. This will result in specialized code paths for all combinations of types contained in ``A`` and ``B``. Fused types and arrays ---------------------- Note that specializations of only numeric types may not be very useful, as one can usually rely on promotion of types. This is not true for arrays, pointers and typed views of memory however. Indeed, one may write:: def myfunc(A[:, :] x): ... # and cdef otherfunc(A *x): ... Note that in Cython 0.20.x and earlier, the compiler generated the full cross product of all type combinations when a fused type was used by more than one memory view in a type signature, e.g. :: def myfunc(A[:] a, A[:] b): # a and b had independent item types in Cython 0.20.x and earlier. ... This was unexpected for most users, unlikely to be desired, and also inconsistent with other structured type declarations like C arrays of fused types, which were considered the same type. It was thus changed in Cython 0.21 to use the same type for all memory views of a fused type. In order to get the original behaviour, it suffices to declare the same fused type under different names, and then use these in the declarations:: ctypedef fused A: int long ctypedef fused B: int long def myfunc(A[:] a, B[:] b): # a and b are independent types here and may have different item types ... To get only identical types also in older Cython versions (pre-0.21), a ``ctypedef`` can be used:: ctypedef A[:] A_1d def myfunc(A_1d a, A_1d b): # a and b have identical item types here, also in older Cython versions ... Selecting Specializations ========================= You can select a specialization (an instance of the function with specific or specialized (i.e., non-fused) argument types) in two ways: either by indexing or by calling. Indexing -------- You can index functions with types to get certain specializations, i.e.:: cfunc[cython.p_double](p1, p2) # From Cython space func[float, double](myfloat, mydouble) # From Python space func[cython.float, cython.double](myfloat, mydouble) If a fused type is used as a base type, this will mean that the base type is the fused type, so the base type is what needs to be specialized:: cdef myfunc(A *x): ... # Specialize using int, not int * myfunc[int](myint) Calling ------- A fused function can also be called with arguments, where the dispatch is figured out automatically:: cfunc(p1, p2) func(myfloat, mydouble) For a ``cdef`` or ``cpdef`` function called from Cython this means that the specialization is figured out at compile time. For ``def`` functions the arguments are typechecked at runtime, and a best-effort approach is performed to figure out which specialization is needed. This means that this may result in a runtime ``TypeError`` if no specialization was found. A ``cpdef`` function is treated the same way as a ``def`` function if the type of the function is unknown (e.g. if it is external and there is no cimport for it). The automatic dispatching rules are typically as follows, in order of preference: * try to find an exact match * choose the biggest corresponding numerical type (biggest float, biggest complex, biggest int) Built-in Fused Types ==================== There are some built-in fused types available for convenience, these are:: cython.integral # short, int, long cython.floating # float, double cython.numeric # short, int, long, float, double, float complex, double complex Casting Fused Functions ======================= Fused ``cdef`` and ``cpdef`` functions may be cast or assigned to C function pointers as follows:: cdef myfunc(cython.floating, cython.integral): ... # assign directly cdef object (*funcp)(float, int) funcp = myfunc funcp(f, i) # alternatively, cast it ( myfunc)(f, i) # This is also valid funcp = myfunc[float, int] funcp(f, i) Type Checking Specializations ============================= Decisions can be made based on the specializations of the fused parameters. False conditions are pruned to avoid invalid code. One may check with ``is``, ``is not`` and ``==`` and ``!=`` to see if a fused type is equal to a certain other non-fused type (to check the specialization), or use ``in`` and ``not in`` to figure out whether a specialization is part of another set of types (specified as a fused type). In example:: ctypedef fused bunch_of_types: ... ctypedef fused string_t: cython.p_char bytes unicode cdef cython.integral myfunc(cython.integral i, bunch_of_types s): cdef int *int_pointer cdef long *long_pointer # Only one of these branches will be compiled for each specialization! if cython.integral is int: int_pointer = &i else: long_pointer = &i if bunch_of_types in string_t: print "s is a string!" __signatures__ ============== Finally, function objects from ``def`` or ``cpdef`` functions have an attribute __signatures__, which maps the signature strings to the actual specialized functions. This may be useful for inspection. Listed signature strings may also be used as indices to the fused function, but the index format may change between Cython versions:: specialized_function = fused_function["MyExtensionClass|int|float"] It would usually be preferred to index like this, however:: specialized_function = fused_function[MyExtensionClass, int, float] Although the latter will select the biggest types for ``int`` and ``float`` from Python space, as they are not type identifiers but builtin types there. Passing ``cython.int`` and ``cython.float`` would resolve that, however. For memoryview indexing from python space we can do the following:: ctypedef fused my_fused_type: int[:, ::1] float[:, ::1] def func(my_fused_type array): ... my_fused_type[cython.int[:, ::1]](myarray) The same goes for when using e.g. ``cython.numeric[:, :]``. Cython-0.23.4/docs/src/userguide/external_C_code.rst0000644000175600017570000005757612606202452023553 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _external-C-code: ********************************** Interfacing with External C Code ********************************** One of the main uses of Cython is wrapping existing libraries of C code. This is achieved by using external declarations to declare the C functions and variables from the library that you want to use. You can also use public declarations to make C functions and variables defined in a Cython module available to external C code. The need for this is expected to be less frequent, but you might want to do it, for example, if you are `embedding Python`_ in another application as a scripting language. Just as a Cython module can be used as a bridge to allow Python code to call C code, it can also be used to allow C code to call Python code. .. _embedding Python: http://www.freenet.org.nz/python/embeddingpyrex/ External declarations ======================= By default, C functions and variables declared at the module level are local to the module (i.e. they have the C static storage class). They can also be declared extern to specify that they are defined elsewhere, for example,:: cdef extern int spam_counter cdef extern void order_spam(int tons) Referencing C header files --------------------------- When you use an extern definition on its own as in the examples above, Cython includes a declaration for it in the generated C file. This can cause problems if the declaration doesn't exactly match the declaration that will be seen by other C code. If you're wrapping an existing C library, for example, it's important that the generated C code is compiled with exactly the same declarations as the rest of the library. To achieve this, you can tell Cython that the declarations are to be found in a C header file, like this:: cdef extern from "spam.h": int spam_counter void order_spam(int tons) The ``cdef extern`` from clause does three things: 1. It directs Cython to place a ``#include`` statement for the named header file in the generated C code. 2. It prevents Cython from generating any C code for the declarations found in the associated block. 3. It treats all declarations within the block as though they started with ``cdef extern``. It's important to understand that Cython does not itself read the C header file, so you still need to provide Cython versions of any declarations from it that you use. However, the Cython declarations don't always have to exactly match the C ones, and in some cases they shouldn't or can't. In particular: #. Leave out any platform-specific extensions to C declarations such as ``__declspec()``. #. If the header file declares a big struct and you only want to use a few members, you only need to declare the members you're interested in. Leaving the rest out doesn't do any harm, because the C compiler will use the full definition from the header file. In some cases, you might not need any of the struct's members, in which case you can just put pass in the body of the struct declaration, e.g.:: cdef extern from "foo.h": struct spam: pass .. note:: you can only do this inside a ``cdef extern from`` block; struct declarations anywhere else must be non-empty. #. If the header file uses ``typedef`` names such as :c:type:`word` to refer to platform-dependent flavours of numeric types, you will need a corresponding :keyword:`ctypedef` statement, but you don't need to match the type exactly, just use something of the right general kind (int, float, etc). For example,:: ctypedef int word will work okay whatever the actual size of a :c:type:`word` is (provided the header file defines it correctly). Conversion to and from Python types, if any, will also be used for this new type. #. If the header file uses macros to define constants, translate them into a normal external variable declaration. You can also declare them as an :keyword:`enum` if they contain normal :c:type:`int` values. Note that Cython considers :keyword:`enum` to be equivalent to :c:type:`int`, so do not do this for non-int values. #. If the header file defines a function using a macro, declare it as though it were an ordinary function, with appropriate argument and result types. #. For archaic reasons C uses the keyword ``void`` to declare a function taking no parameters. In Cython as in Python, simply declare such functions as :meth:`foo()`. A few more tricks and tips: * If you want to include a C header because it's needed by another header, but don't want to use any declarations from it, put pass in the extern-from block:: cdef extern from "spam.h": pass * If you want to include some external declarations, but don't want to specify a header file (because it's included by some other header that you've already included) you can put ``*`` in place of the header file name:: cdef extern from *: ... Implementing functions in C --------------------------- When you want to call C code from a Cython module, usually that code will be in some external library that you link your extension against. However, you can also directly compile C (or C++) code as part of your Cython module. In the ``.pyx`` file, you can put something like:: cdef extern from "spam.c": void order_spam(int tons) Cython will assume that the function ``order_spam()`` is defined in the file ``spam.c``. If you also want to cimport this function from another module, it must be declared (not extern!) in the ``.pxd`` file:: cdef void order_spam(int tons) For this to work, the signature of ``order_spam()`` in ``spam.c`` must match the signature that Cython uses, in particular the function must be static: .. code-block:: c static void order_spam(int tons) { printf("Ordered %i tons of spam!\n", tons); } .. _struct-union-enum-styles: Styles of struct, union and enum declaration ---------------------------------------------- There are two main ways that structs, unions and enums can be declared in C header files: using a tag name, or using a typedef. There are also some variations based on various combinations of these. It's important to make the Cython declarations match the style used in the header file, so that Cython can emit the right sort of references to the type in the code it generates. To make this possible, Cython provides two different syntaxes for declaring a struct, union or enum type. The style introduced above corresponds to the use of a tag name. To get the other style, you prefix the declaration with :keyword:`ctypedef`, as illustrated below. The following table shows the various possible styles that can be found in a header file, and the corresponding Cython declaration that you should put in the ``cdef extern`` from block. Struct declarations are used as an example; the same applies equally to union and enum declarations. +-------------------------+---------------------------------------------+-----------------------------------------------------------------------+ | C code | Possibilities for corresponding Cython Code | Comments | +=========================+=============================================+=======================================================================+ | .. sourcecode:: c | :: | Cython will refer to the as ``struct Foo`` in the generated C code. | | | | | | struct Foo { | cdef struct Foo: | | | ... | ... | | | }; | | | +-------------------------+---------------------------------------------+-----------------------------------------------------------------------+ | .. sourcecode:: c | :: | Cython will refer to the type simply as ``Foo`` in | | | | the generated C code. | | typedef struct { | ctypedef struct Foo: | | | ... | ... | | | } Foo; | | | +-------------------------+---------------------------------------------+-----------------------------------------------------------------------+ | .. sourcecode:: c | :: | If the C header uses both a tag and a typedef with *different* | | | | names, you can use either form of declaration in Cython | | typedef struct foo { | cdef struct foo: | (although if you need to forward reference the type, | | ... | ... | you'll have to use the first form). | | } Foo; | ctypedef foo Foo #optional | | | | | | | | or:: | | | | | | | | ctypedef struct Foo: | | | | ... | | +-------------------------+---------------------------------------------+-----------------------------------------------------------------------+ | .. sourcecode:: c | :: | If the header uses the *same* name for the tag and typedef, you | | | | won't be able to include a :keyword:`ctypedef` for it -- but then, | | typedef struct Foo { | cdef struct Foo: | it's not necessary. | | ... | ... | | | } Foo; | | | +-------------------------+---------------------------------------------+-----------------------------------------------------------------------+ Note that in all the cases below, you refer to the type in Cython code simply as :c:type:`Foo`, not ``struct Foo``. Accessing Python/C API routines --------------------------------- One particular use of the ``cdef extern from`` statement is for gaining access to routines in the Python/C API. For example,:: cdef extern from "Python.h": object PyString_FromStringAndSize(char *s, Py_ssize_t len) will allow you to create Python strings containing null bytes. Special Types -------------- Cython predefines the name ``Py_ssize_t`` for use with Python/C API routines. To make your extensions compatible with 64-bit systems, you should always use this type where it is specified in the documentation of Python/C API routines. Windows Calling Conventions ---------------------------- The ``__stdcall`` and ``__cdecl`` calling convention specifiers can be used in Cython, with the same syntax as used by C compilers on Windows, for example,:: cdef extern int __stdcall FrobnicateWindow(long handle) cdef void (__stdcall *callback)(void *) If ``__stdcall`` is used, the function is only considered compatible with other ``__stdcall`` functions of the same signature. .. _resolve-conflicts: Resolving naming conflicts - C name specifications -------------------------------------------------- Each Cython module has a single module-level namespace for both Python and C names. This can be inconvenient if you want to wrap some external C functions and provide the Python user with Python functions of the same names. Cython provides a couple of different ways of solving this problem. The best way, especially if you have many C functions to wrap, is to put the extern C function declarations into a ``.pxd`` file and thus a different namespace, using the facilities described in :ref:`sharing declarations between Cython modules `. Writing them into a ``.pxd`` file allows their reuse across modules, avoids naming collisions in the normal Python way and even makes it easy to rename them on cimport. For example, if your ``decl.pxd`` file declared a C function ``eject_tomato``:: cdef extern from "myheader.h": void eject_tomato(float speed) then you can cimport and wrap it in a ``.pyx`` file as follows:: from decl cimport eject_tomato as c_eject_tomato def eject_tomato(speed): c_eject_tomato(speed) or simply cimport the ``.pxd`` file and use it as prefix:: cimport decl def eject_tomato(speed): decl.eject_tomato(speed) Note that this has no runtime lookup overhead, as it would in Python. Cython resolves the names in the ``.pxd`` file at compile time. For special cases where namespacing or renaming on import is not enough, e.g. when a name in C conflicts with a Python keyword, you can use a C name specification to give different Cython and C names to the C function at declaration time. Suppose, for example, that you want to wrap an external C function called :func:`yield`. If you declare it as:: cdef extern from "myheader.h": void c_yield "yield" (float speed) then its Cython visible name will be ``c_yield``, whereas its name in C will be ``yield``. You can then wrap it with:: def call_yield(speed): c_yield(speed) As for functions, C names can be specified for variables, structs, unions, enums, struct and union members, and enum values. For example:: cdef extern int one "eins", two "zwei" cdef extern float three "drei" cdef struct spam "SPAM": int i "eye" cdef enum surprise "inquisition": first "alpha" second "beta" = 3 Note that Cython will not do any validation or name mangling on the string you provide. It will inject the bare text into the C code unmodified, so you are entirely on your own with this feature. If you want to declare a name ``xyz`` and have Cython inject the text "make the C compiler fail here" into the C file for it, you can do this using a C name declaration. Consider this an advanced feature, only for the rare cases where everything else fails. Using Cython Declarations from C ================================ Cython provides two methods for making C declarations from a Cython module available for use by external C code---public declarations and C API declarations. .. note:: You do not need to use either of these to make declarations from one Cython module available to another Cython module – you should use the :keyword:`cimport` statement for that. Sharing Declarations Between Cython Modules. Public Declarations --------------------- You can make C types, variables and functions defined in a Cython module accessible to C code that is linked with the module, by declaring them with the public keyword:: cdef public struct Bunny: # public type declaration int vorpalness cdef public int spam # public variable declaration cdef public void grail(Bunny *): # public function declaration print "Ready the holy hand grenade" If there are any public declarations in a Cython module, a header file called :file:`modulename.h` file is generated containing equivalent C declarations for inclusion in other C code. Users who are embedding Python in C with Cython need to make sure to call Py_Initialize() and Py_Finalize(). For example, in the following snippet that includes :file:`modulename.h`:: #include #include "modulename.h" void grail() { Py_Initialize(); initmodulename(); Bunny b; grail(b); Py_Finalize(); } Any C code wanting to make use of these declarations will need to be linked, either statically or dynamically, with the extension module. If the Cython module resides within a package, then the name of the ``.h`` file consists of the full dotted name of the module, e.g. a module called :mod:`foo.spam` would have a header file called :file:`foo.spam.h`. .. _api: C API Declarations ------------------- The other way of making declarations available to C code is to declare them with the :keyword:`api` keyword. You can use this keyword with C functions and extension types. A header file called :file:`modulename_api.h` is produced containing declarations of the functions and extension types, and a function called :func:`import_modulename`. C code wanting to use these functions or extension types needs to include the header and call the :func:`import_modulename` function. The other functions can then be called and the extension types used as usual. If the C code wanting to use these functions is part of more than one shared library or executable, then :func:`import_modulename` function needs to be called in each of the shared libraries which use these functions. If you crash with a segmentation fault (SIGSEGV on linux) when calling into one of these api calls, this is likely an indication that the shared library which contains the api call which is generating the segmentation fault does not call the :func:`import_modulename` function before the api call which crashes. Any public C type or extension type declarations in the Cython module are also made available when you include :file:`modulename_api.h`.:: # delorean.pyx cdef public struct Vehicle: int speed float power cdef api void activate(Vehicle *v): if v.speed >= 88 and v.power >= 1.21: print "Time travel achieved" .. sourcecode:: c # marty.c #include "delorean_api.h" Vehicle car; int main(int argc, char *argv[]) { import_delorean(); car.speed = atoi(argv[1]); car.power = atof(argv[2]); activate(&car); } .. note:: Any types defined in the Cython module that are used as argument or return types of the exported functions will need to be declared public, otherwise they won't be included in the generated header file, and you will get errors when you try to compile a C file that uses the header. Using the :keyword:`api` method does not require the C code using the declarations to be linked with the extension module in any way, as the Python import machinery is used to make the connection dynamically. However, only functions can be accessed this way, not variables. You can use both :keyword:`public` and :keyword:`api` on the same function to make it available by both methods, e.g.:: cdef public api void belt_and_braces(): ... However, note that you should include either :file:`modulename.h` or :file:`modulename_api.h` in a given C file, not both, otherwise you may get conflicting dual definitions. If the Cython module resides within a package, then: * The name of the header file contains of the full dotted name of the module. * The name of the importing function contains the full name with dots replaced by double underscores. E.g. a module called :mod:`foo.spam` would have an API header file called :file:`foo.spam_api.h` and an importing function called :func:`import_foo__spam`. Multiple public and API declarations -------------------------------------- You can declare a whole group of items as :keyword:`public` and/or :keyword:`api` all at once by enclosing them in a :keyword:`cdef` block, for example,:: cdef public api: void order_spam(int tons) char *get_lunch(float tomato_size) This can be a useful thing to do in a ``.pxd`` file (see :ref:`sharing-declarations`) to make the module's public interface available by all three methods. Acquiring and Releasing the GIL --------------------------------- Cython provides facilities for acquiring and releasing the `Global Interpreter Lock (GIL) `_. This may be useful when calling from multi-threaded code into (external C) code that may block, or when wanting to use Python from a (native) C thread callback. Releasing the GIL should obviously only be done for thread-safe code or for code that uses other means of protection against race conditions and concurrency issues. Note that acquiring the GIL is a blocking thread-synchronising operation, and therefore potentially costly. It might not be worth releasing the GIL for minor calculations. Usually, I/O operations and substantial computations in parallel code will benefit from it. .. _nogil: Releasing the GIL ^^^^^^^^^^^^^^^^^ You can release the GIL around a section of code using the ``with nogil`` statement:: with nogil: Code in the body of the statement must not manipulate Python objects in any way, and must not call anything that manipulates Python objects without first re-acquiring the GIL. Cython currently does not check this. .. _gil: Acquiring the GIL ^^^^^^^^^^^^^^^^^ A C function that is to be used as a callback from C code that is executed without the GIL needs to acquire the GIL before it can manipulate Python objects. This can be done by specifying ``with gil`` in the function header:: cdef void my_callback(void *data) with gil: ... If the callback may be called from another non-Python thread, care must be taken to initialize the GIL first, through a call to `PyEval_InitThreads() `_. If you're already using :ref:`cython.parallel ` in your module, this will already have been taken care of. The GIL may also be acquired through the ``with gil`` statement:: with gil: Declaring a function as callable without the GIL -------------------------------------------------- You can specify :keyword:`nogil` in a C function header or function type to declare that it is safe to call without the GIL.:: cdef void my_gil_free_func(int spam) nogil: ... When you implement such a function in Cython, it cannot have any Python arguments or Python object return type. Furthermore, any operation that involves Python objects (including calling Python functions) must explicitly acquire the GIL first, e.g. by using a ``with gil`` block or by calling a function that has been defined ``with gil``. These restrictions are checked by Cython and you will get a compile error if it finds any Python interaction inside of a ``nogil`` code section. .. NOTE:: The ``nogil`` function annotation declares that it is safe to call the function without the GIL. It is perfectly allowed to execute it while holding the GIL. The function does not in itself release the GIL if it is held by the caller. Declaring a function ``with gil`` (i.e. as acquiring the GIL on entry) also implicitly makes its signature :keyword:`nogil`. Cython-0.23.4/docs/src/userguide/extension_types.rst0000644000175600017570000005621612606202452023723 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _extension-types: ****************** Extension Types ****************** Introduction ============== As well as creating normal user-defined classes with the Python class statement, Cython also lets you create new built-in Python types, known as extension types. You define an extension type using the :keyword:`cdef` class statement. Here's an example:: cdef class Shrubbery: cdef int width, height def __init__(self, w, h): self.width = w self.height = h def describe(self): print "This shrubbery is", self.width, \ "by", self.height, "cubits." As you can see, a Cython extension type definition looks a lot like a Python class definition. Within it, you use the def statement to define methods that can be called from Python code. You can even define many of the special methods such as :meth:`__init__` as you would in Python. The main difference is that you can use the :keyword:`cdef` statement to define attributes. The attributes may be Python objects (either generic or of a particular extension type), or they may be of any C data type. So you can use extension types to wrap arbitrary C data structures and provide a Python-like interface to them. .. _readonly: Attributes ============ Attributes of an extension type are stored directly in the object's C struct. The set of attributes is fixed at compile time; you can't add attributes to an extension type instance at run time simply by assigning to them, as you could with a Python class instance. (You can subclass the extension type in Python and add attributes to instances of the subclass, however.) There are two ways that attributes of an extension type can be accessed: by Python attribute lookup, or by direct access to the C struct from Cython code. Python code is only able to access attributes of an extension type by the first method, but Cython code can use either method. By default, extension type attributes are only accessible by direct access, not Python access, which means that they are not accessible from Python code. To make them accessible from Python code, you need to declare them as :keyword:`public` or :keyword:`readonly`. For example:: cdef class Shrubbery: cdef public int width, height cdef readonly float depth makes the width and height attributes readable and writable from Python code, and the depth attribute readable but not writable. .. note:: You can only expose simple C types, such as ints, floats, and strings, for Python access. You can also expose Python-valued attributes. .. note:: Also the :keyword:`public` and :keyword:`readonly` options apply only to Python access, not direct access. All the attributes of an extension type are always readable and writable by C-level access. Type declarations =================== Before you can directly access the attributes of an extension type, the Cython compiler must know that you have an instance of that type, and not just a generic Python object. It knows this already in the case of the ``self`` parameter of the methods of that type, but in other cases you will have to use a type declaration. For example, in the following function:: cdef widen_shrubbery(sh, extra_width): # BAD sh.width = sh.width + extra_width because the ``sh`` parameter hasn't been given a type, the width attribute will be accessed by a Python attribute lookup. If the attribute has been declared :keyword:`public` or :keyword:`readonly` then this will work, but it will be very inefficient. If the attribute is private, it will not work at all -- the code will compile, but an attribute error will be raised at run time. The solution is to declare ``sh`` as being of type :class:`Shrubbery`, as follows:: cdef widen_shrubbery(Shrubbery sh, extra_width): sh.width = sh.width + extra_width Now the Cython compiler knows that ``sh`` has a C attribute called :attr:`width` and will generate code to access it directly and efficiently. The same consideration applies to local variables, for example,:: cdef Shrubbery another_shrubbery(Shrubbery sh1): cdef Shrubbery sh2 sh2 = Shrubbery() sh2.width = sh1.width sh2.height = sh1.height return sh2 Type Testing and Casting ------------------------ Suppose I have a method :meth:`quest` which returns an object of type :class:`Shrubbery`. To access it's width I could write:: cdef Shrubbery sh = quest() print sh.width which requires the use of a local variable and performs a type test on assignment. If you *know* the return value of :meth:`quest` will be of type :class:`Shrubbery` you can use a cast to write:: print (quest()).width This may be dangerous if :meth:`quest()` is not actually a :class:`Shrubbery`, as it will try to access width as a C struct member which may not exist. At the C level, rather than raising an :class:`AttributeError`, either an nonsensical result will be returned (interpreting whatever data is at at that address as an int) or a segfault may result from trying to access invalid memory. Instead, one can write:: print (quest()).width which performs a type check (possibly raising a :class:`TypeError`) before making the cast and allowing the code to proceed. To explicitly test the type of an object, use the :meth:`isinstance` method. By default, in Python, the :meth:`isinstance` method checks the :class:`__class__` attribute of the first argument to determine if it is of the required type. However, this is potentially unsafe as the :class:`__class__` attribute can be spoofed or changed, but the C structure of an extension type must be correct to access its :keyword:`cdef` attributes and call its :keyword:`cdef` methods. Cython detects if the second argument is a known extension type and does a type check instead, analogous to Pyrex's :meth:`typecheck`. The old behavior is always available by passing a tuple as the second parameter:: print isinstance(sh, Shrubbery) # Check the type of sh print isinstance(sh, (Shrubbery,)) # Check sh.__class__ Extension types and None ========================= When you declare a parameter or C variable as being of an extension type, Cython will allow it to take on the value ``None`` as well as values of its declared type. This is analogous to the way a C pointer can take on the value ``NULL``, and you need to exercise the same caution because of it. There is no problem as long as you are performing Python operations on it, because full dynamic type checking will be applied. However, when you access C attributes of an extension type (as in the widen_shrubbery function above), it's up to you to make sure the reference you're using is not ``None`` -- in the interests of efficiency, Cython does not check this. You need to be particularly careful when exposing Python functions which take extension types as arguments. If we wanted to make :func:`widen_shrubbery` a Python function, for example, if we simply wrote:: def widen_shrubbery(Shrubbery sh, extra_width): # This is sh.width = sh.width + extra_width # dangerous! then users of our module could crash it by passing ``None`` for the ``sh`` parameter. One way to fix this would be:: def widen_shrubbery(Shrubbery sh, extra_width): if sh is None: raise TypeError sh.width = sh.width + extra_width but since this is anticipated to be such a frequent requirement, Cython provides a more convenient way. Parameters of a Python function declared as an extension type can have a ``not None`` clause:: def widen_shrubbery(Shrubbery sh not None, extra_width): sh.width = sh.width + extra_width Now the function will automatically check that ``sh`` is ``not None`` along with checking that it has the right type. .. note:: ``not None`` clause can only be used in Python functions (defined with :keyword:`def`) and not C functions (defined with :keyword:`cdef`). If you need to check whether a parameter to a C function is None, you will need to do it yourself. .. note:: Some more things: * The self parameter of a method of an extension type is guaranteed never to be ``None``. * When comparing a value with ``None``, keep in mind that, if ``x`` is a Python object, ``x is None`` and ``x is not None`` are very efficient because they translate directly to C pointer comparisons, whereas ``x == None`` and ``x != None``, or simply using ``x`` as a boolean value (as in ``if x: ...``) will invoke Python operations and therefore be much slower. Special methods ================ Although the principles are similar, there are substantial differences between many of the :meth:`__xxx__` special methods of extension types and their Python counterparts. There is a :ref:`separate page ` devoted to this subject, and you should read it carefully before attempting to use any special methods in your extension types. Properties ============ There is a special syntax for defining properties in an extension class:: cdef class Spam: property cheese: "A doc string can go here." def __get__(self): # This is called when the property is read. ... def __set__(self, value): # This is called when the property is written. ... def __del__(self): # This is called when the property is deleted. The :meth:`__get__`, :meth:`__set__` and :meth:`__del__` methods are all optional; if they are omitted, an exception will be raised when the corresponding operation is attempted. Here's a complete example. It defines a property which adds to a list each time it is written to, returns the list when it is read, and empties the list when it is deleted.:: # cheesy.pyx cdef class CheeseShop: cdef object cheeses def __cinit__(self): self.cheeses = [] property cheese: def __get__(self): return "We don't have: %s" % self.cheeses def __set__(self, value): self.cheeses.append(value) def __del__(self): del self.cheeses[:] # Test input from cheesy import CheeseShop shop = CheeseShop() print shop.cheese shop.cheese = "camembert" print shop.cheese shop.cheese = "cheddar" print shop.cheese del shop.cheese print shop.cheese .. sourcecode:: text # Test output We don't have: [] We don't have: ['camembert'] We don't have: ['camembert', 'cheddar'] We don't have: [] Subclassing ============= An extension type may inherit from a built-in type or another extension type:: cdef class Parrot: ... cdef class Norwegian(Parrot): ... A complete definition of the base type must be available to Cython, so if the base type is a built-in type, it must have been previously declared as an extern extension type. If the base type is defined in another Cython module, it must either be declared as an extern extension type or imported using the :keyword:`cimport` statement. An extension type can only have one base class (no multiple inheritance). Cython extension types can also be subclassed in Python. A Python class can inherit from multiple extension types provided that the usual Python rules for multiple inheritance are followed (i.e. the C layouts of all the base classes must be compatible). Since Cython 0.13.1, there is a way to prevent extension types from being subtyped in Python. This is done via the ``final`` directive, usually set on an extension type using a decorator:: cimport cython @cython.final cdef class Parrot: def done(self): pass Trying to create a Python subclass from this type will raise a :class:`TypeError` at runtime. Cython will also prevent subtyping a final type inside of the same module, i.e. creating an extension type that uses a final type as its base type will fail at compile time. Note, however, that this restriction does not currently propagate to other extension modules, so even final extension types can still be subtyped at the C level by foreign code. C methods ========= Extension types can have C methods as well as Python methods. Like C functions, C methods are declared using :keyword:`cdef` or :keyword:`cpdef` instead of :keyword:`def`. C methods are "virtual", and may be overridden in derived extension types. In addition, :keyword:`cpdef` methods can even be overridden by python methods when called as C method. This adds a little to their calling overhead compared to a :keyword:`cdef` method:: # pets.pyx cdef class Parrot: cdef void describe(self): print "This parrot is resting." cdef class Norwegian(Parrot): cdef void describe(self): Parrot.describe(self) print "Lovely plumage!" cdef Parrot p1, p2 p1 = Parrot() p2 = Norwegian() print "p1:" p1.describe() print "p2:" p2.describe() .. sourcecode:: text # Output p1: This parrot is resting. p2: This parrot is resting. Lovely plumage! The above example also illustrates that a C method can call an inherited C method using the usual Python technique, i.e.:: Parrot.describe(self) `cdef` methods can be declared static by using the @staticmethod decorator. This can be especially useful for constructing classes that take non-Python compatible types.:: cdef class OwnedPointer: cdef void* ptr cdef __dealloc__(self): if ptr != NULL: free(ptr) @staticmethod cdef create(void* ptr): p = OwnedPointer() p.ptr = ptr return ptr Forward-declaring extension types =================================== Extension types can be forward-declared, like :keyword:`struct` and :keyword:`union` types. This is usually not necessary and violates the DRY principle (Don't Repeat Yourself). If you are forward-declaring an extension type that has a base class, you must specify the base class in both the forward declaration and its subsequent definition, for example,:: cdef class A(B) ... cdef class A(B): # attributes and methods Fast instantiation =================== Cython provides two ways to speed up the instantiation of extension types. The first one is a direct call to the ``__new__()`` special static method, as known from Python. For an extension type ``Penguin``, you could use the following code:: cdef class Penguin: cdef object food def __cinit__(self, food): self.food = food def __init__(self, food): print("eating!") normal_penguin = Penguin('fish') fast_penguin = Penguin.__new__(Penguin, 'wheat') # note: not calling __init__() ! Note that the path through ``__new__()`` will *not* call the type's ``__init__()`` method (again, as known from Python). Thus, in the example above, the first instantiation will print ``eating!``, but the second will not. This is only one of the reasons why the ``__cinit__()`` method is safer and preferable over the normal ``__init__()`` method for extension types. The second performance improvement applies to types that are often created and deleted in a row, so that they can benefit from a freelist. Cython provides the decorator ``@cython.freelist(N)`` for this, which creates a statically sized freelist of ``N`` instances for a given type. Example:: cimport cython @cython.freelist(8) cdef class Penguin: cdef object food def __cinit__(self, food): self.food = food penguin = Penguin('fish 1') penguin = None penguin = Penguin('fish 2') # does not need to allocate memory! Making extension types weak-referenceable ========================================== By default, extension types do not support having weak references made to them. You can enable weak referencing by declaring a C attribute of type object called :attr:`__weakref__`. For example,:: cdef class ExplodingAnimal: """This animal will self-destruct when it is no longer strongly referenced.""" cdef object __weakref__ Controlling cyclic garbage collection in CPython ================================================ By default each extension type will support the cyclic garbage collector of CPython. If any Python objects can be referenced, Cython will automatically generate the ``tp_traverse`` and ``tp_clear`` slots. This is usually what you want. There is at least one reason why this might not be what you want: If you need to cleanup some external resources in the ``__dealloc__`` special function and your object happened to be in a reference cycle, the garbage collector may have triggered a call to ``tp_clear`` to drop references. This is the way that reference cycles are broken so that the garbage can actually be reclaimed. In that case any object references have vanished by the time when ``__dealloc__`` is called. Now your cleanup code lost access to the objects it has to clean up. In that case you can disable the cycle breaker ``tp_clear`` by using the ``no_gc_clear`` decorator :: @cython.no_gc_clear cdef class DBCursor: cdef DBConnection conn cdef DBAPI_Cursor *raw_cursor # ... def __dealloc__(self): DBAPI_close_cursor(self.conn.raw_conn, self.raw_cursor) This example tries to close a cursor via a database connection when the Python object is destroyed. The ``DBConnection`` object is kept alive by the reference from ``DBCursor``. But if a cursor happens to be in a reference cycle, the garbage collector may effectively "steal" the database connection reference, which makes it impossible to clean up the cursor. Using the ``no_gc_clear`` decorator this can not happen anymore because the references of a cursor object will not be cleared anymore. Public and external extension types ==================================== Extension types can be declared extern or public. An extern extension type declaration makes an extension type defined in external C code available to a Cython module. A public extension type declaration makes an extension type defined in a Cython module available to external C code. External extension types ------------------------ An extern extension type allows you to gain access to the internals of Python objects defined in the Python core or in a non-Cython extension module. .. note:: In previous versions of Pyrex, extern extension types were also used to reference extension types defined in another Pyrex module. While you can still do that, Cython provides a better mechanism for this. See :ref:`sharing-declarations`. Here is an example which will let you get at the C-level members of the built-in complex object.:: cdef extern from "complexobject.h": struct Py_complex: double real double imag ctypedef class __builtin__.complex [object PyComplexObject]: cdef Py_complex cval # A function which uses the above type def spam(complex c): print "Real:", c.cval.real print "Imag:", c.cval.imag .. note:: Some important things: 1. In this example, :keyword:`ctypedef` class has been used. This is because, in the Python header files, the ``PyComplexObject`` struct is declared with: .. sourcecode:: c typedef struct { ... } PyComplexObject; 2. As well as the name of the extension type, the module in which its type object can be found is also specified. See the implicit importing section below. 3. When declaring an external extension type, you don't declare any methods. Declaration of methods is not required in order to call them, because the calls are Python method calls. Also, as with :keyword:`struct` and :keyword:`union`, if your extension class declaration is inside a :keyword:`cdef` extern from block, you only need to declare those C members which you wish to access. Name specification clause ------------------------- The part of the class declaration in square brackets is a special feature only available for extern or public extension types. The full form of this clause is:: [object object_struct_name, type type_object_name ] where ``object_struct_name`` is the name to assume for the type's C struct, and type_object_name is the name to assume for the type's statically declared type object. (The object and type clauses can be written in either order.) If the extension type declaration is inside a :keyword:`cdef` extern from block, the object clause is required, because Cython must be able to generate code that is compatible with the declarations in the header file. Otherwise, for extern extension types, the object clause is optional. For public extension types, the object and type clauses are both required, because Cython must be able to generate code that is compatible with external C code. Implicit importing ------------------ Cython requires you to include a module name in an extern extension class declaration, for example,:: cdef extern class MyModule.Spam: ... The type object will be implicitly imported from the specified module and bound to the corresponding name in this module. In other words, in this example an implicit:: from MyModule import Spam statement will be executed at module load time. The module name can be a dotted name to refer to a module inside a package hierarchy, for example,:: cdef extern class My.Nested.Package.Spam: ... You can also specify an alternative name under which to import the type using an as clause, for example,:: cdef extern class My.Nested.Package.Spam as Yummy: ... which corresponds to the implicit import statement:: from My.Nested.Package import Spam as Yummy Type names vs. constructor names -------------------------------- Inside a Cython module, the name of an extension type serves two distinct purposes. When used in an expression, it refers to a module-level global variable holding the type's constructor (i.e. its type-object). However, it can also be used as a C type name to declare variables, arguments and return values of that type. When you declare:: cdef extern class MyModule.Spam: ... the name Spam serves both these roles. There may be other names by which you can refer to the constructor, but only Spam can be used as a type name. For example, if you were to explicity import MyModule, you could use ``MyModule.Spam()`` to create a Spam instance, but you wouldn't be able to use :class:`MyModule.Spam` as a type name. When an as clause is used, the name specified in the as clause also takes over both roles. So if you declare:: cdef extern class MyModule.Spam as Yummy: ... then Yummy becomes both the type name and a name for the constructor. Again, there are other ways that you could get hold of the constructor, but only Yummy is usable as a type name. Public extension types ====================== An extension type can be declared public, in which case a ``.h`` file is generated containing declarations for its object struct and type object. By including the ``.h`` file in external C code that you write, that code can access the attributes of the extension type. Cython-0.23.4/docs/src/userguide/early_binding_for_speed.rst0000644000175600017570000001145212606202452025310 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _early-binding-for-speed: ************************** Early Binding for Speed ************************** As a dynamic language, Python encourages a programming style of considering classes and objects in terms of their methods and attributes, more than where they fit into the class hierarchy. This can make Python a very relaxed and comfortable language for rapid development, but with a price - the 'red tape' of managing data types is dumped onto the interpreter. At run time, the interpreter does a lot of work searching namespaces, fetching attributes and parsing argument and keyword tuples. This run-time 'late binding' is a major cause of Python's relative slowness compared to 'early binding' languages such as C++. However with Cython it is possible to gain significant speed-ups through the use of 'early binding' programming techniques. For example, consider the following (silly) code example: .. sourcecode:: cython cdef class Rectangle: cdef int x0, y0 cdef int x1, y1 def __init__(self, int x0, int y0, int x1, int y1): self.x0 = x0; self.y0 = y0; self.x1 = x1; self.y1 = y1 def area(self): area = (self.x1 - self.x0) * (self.y1 - self.y0) if area < 0: area = -area return area def rectArea(x0, y0, x1, y1): rect = Rectangle(x0, y0, x1, y1) return rect.area() In the :func:`rectArea` method, the call to :meth:`rect.area` and the :meth:`.area` method contain a lot of Python overhead. However, in Cython, it is possible to eliminate a lot of this overhead in cases where calls occur within Cython code. For example: .. sourcecode:: cython cdef class Rectangle: cdef int x0, y0 cdef int x1, y1 def __init__(self, int x0, int y0, int x1, int y1): self.x0 = x0; self.y0 = y0; self.x1 = x1; self.y1 = y1 cdef int _area(self): cdef int area area = (self.x1 - self.x0) * (self.y1 - self.y0) if area < 0: area = -area return area def area(self): return self._area() def rectArea(x0, y0, x1, y1): cdef Rectangle rect rect = Rectangle(x0, y0, x1, y1) return rect._area() Here, in the Rectangle extension class, we have defined two different area calculation methods, the efficient :meth:`_area` C method, and the Python-callable :meth:`area` method which serves as a thin wrapper around :meth:`_area`. Note also in the function :func:`rectArea` how we 'early bind' by declaring the local variable ``rect`` which is explicitly given the type Rectangle. By using this declaration, instead of just dynamically assigning to ``rect``, we gain the ability to access the much more efficient C-callable :meth:`_rect` method. But Cython offers us more simplicity again, by allowing us to declare dual-access methods - methods that can be efficiently called at C level, but can also be accessed from pure Python code at the cost of the Python access overheads. Consider this code: .. sourcecode:: cython cdef class Rectangle: cdef int x0, y0 cdef int x1, y1 def __init__(self, int x0, int y0, int x1, int y1): self.x0 = x0; self.y0 = y0; self.x1 = x1; self.y1 = y1 cpdef int area(self): cdef int area area = (self.x1 - self.x0) * (self.y1 - self.y0) if area < 0: area = -area return area def rectArea(x0, y0, x1, y1): cdef Rectangle rect rect = Rectangle(x0, y0, x1, y1) return rect.area() .. note:: in earlier versions of Cython, the :keyword:`cpdef` keyword is ``rdef`` - but has the same effect). Here, we just have a single area method, declared as :keyword:`cpdef` to make it efficiently callable as a C function, but still accessible from pure Python (or late-binding Cython) code. If within Cython code, we have a variable already 'early-bound' (ie, declared explicitly as type Rectangle, (or cast to type Rectangle), then invoking its area method will use the efficient C code path and skip the Python overhead. But if in Pyrex or regular Python code we have a regular object variable storing a Rectangle object, then invoking the area method will require: * an attribute lookup for the area method * packing a tuple for arguments and a dict for keywords (both empty in this case) * using the Python API to call the method and within the area method itself: * parsing the tuple and keywords * executing the calculation code * converting the result to a python object and returning it So within Cython, it is possible to achieve massive optimisations by using strong typing in declaration and casting of variables. For tight loops which use method calls, and where these methods are pure C, the difference can be huge. Cython-0.23.4/docs/src/userguide/debugging.rst0000644000175600017570000002105712606202452022411 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _debugging: ********************************** Debugging your Cython program ********************************** Cython comes with an extension for the GNU Debugger that helps users debug Cython code. To use this functionality, you will need to install gdb 7.2 or higher, built with Python support (linked to Python 2.6 or higher). The debugger supports debuggees with versions 2.6 and higher. For Python 3, code should be built with Python 3 and the debugger should be run with Python 2 (or at least it should be able to find the Python 2 Cython installation). The debugger will need debug information that the Cython compiler can export. This can be achieved from within the setup script by passing ``gdb_debug=True`` to ``cythonize()``:: from distutils.code import setup from distutils.extension import Extension extensions = [Extension('source', ['source.pyx'])] setup(..., ext_modules=cythonize(extensions, gdb_debug=True)) For development it's often helpful to pass the ``--inplace`` flag to the ``setup.py`` script, which makes distutils build your project "in place", i.e., not in a separate `build` directory. When invoking Cython from the command line directly you can have it write debug information using the ``--gdb`` flag:: cython --gdb myfile.pyx Running the Debugger ===================== .. highlight:: bash To run the Cython debugger and have it import the debug information exported by Cython, run ``cygdb`` in the build directory:: $ python setup.py build_ext --inplace $ cygdb GNU gdb (GDB) 7.2 ... (gdb) When using the Cython debugger, it's preferable that you build and run your code with an interpreter that is compiled with debugging symbols (i.e. configured with ``--with-pydebug`` or compiled with the ``-g`` CFLAG). If your Python is installed and managed by your package manager you probably need to install debug support separately, e.g. for ubuntu:: $ sudo apt-get install python-dbg $ python-dbg setup.py build_ext --inplace Then you need to run your script with ``python-dbg`` also. You can also pass additional arguments to gdb:: $ cygdb /path/to/build/directory/ GDBARGS i.e.:: $ cygdb . --args python-dbg mainscript.py To tell cygdb not to import any debug information, supply ``--`` as the first argument:: $ cygdb -- Using the Debugger =================== The Cython debugger comes with a set of commands that support breakpoints, stack inspection, source code listing, stepping, stepping over, etc. Most of these commands are analogous to their respective gdb command. .. function:: cy break breakpoints... Break in a Python, Cython or C function. First it will look for a Cython function with that name, if cygdb doesn't know about a function (or method) with that name, it will set a (pending) C breakpoint. The ``-p`` option can be used to specify a Python breakpoint. Breakpoints can be set for either the function or method name, or they can be fully "qualified", which means that the entire "path" to a function is given:: (gdb) cy break cython_function_or_method (gdb) cy break packagename.cython_module.cython_function (gdb) cy break packagename.cython_module.ClassName.cython_method (gdb) cy break c_function You can also break on Cython line numbers:: (gdb) cy break :14 (gdb) cy break cython_module:14 (gdb) cy break packagename.cython_module:14 Python breakpoints currently support names of the module (not the entire package path) and the function or method:: (gdb) cy break -p python_module.python_function_or_method (gdb) cy break -p python_function_or_method .. note:: Python breakpoints only work in Python builds where the Python frame information can be read from the debugger. To ensure this, use a Python debug build or a non-stripped build compiled with debug support. .. function:: cy step Step through Python, Cython or C code. Python, Cython and C functions called directly from Cython code are considered relevant and will be stepped into. .. function:: cy next Step over Python, Cython or C code. .. function:: cy run Run the program. The default interpreter is the interpreter that was used to build your extensions with, or the interpreter ``cygdb`` is run with in case the "don't import debug information" option was in effect. The interpreter can be overridden using gdb's ``file`` command. .. function:: cy cont Continue the program. .. function:: cy up cy down Go up and down the stack to what is considered a relevant frame. .. function:: cy finish Execute until an upward relevant frame is met or something halts execution. .. function:: cy bt cy backtrace Print a traceback of all frames considered relevant. The ``-a`` option makes it print the full traceback (all C frames). .. function:: cy select Select a stack frame by number as listed by ``cy backtrace``. This command is introduced because ``cy backtrace`` prints a reversed stack trace, so frame numbers differ from gdb's ``bt``. .. function:: cy print varname Print a local or global Cython, Python or C variable (depending on the context). Variables may also be dereferenced:: (gdb) cy print x x = 1 (gdb) cy print *x *x = (PyObject) { _ob_next = 0x93efd8, _ob_prev = 0x93ef88, ob_refcnt = 65, ob_type = 0x83a3e0 } .. function:: cy set cython_variable = value Set a Cython variable on the Cython stack to value. .. function:: cy list List the source code surrounding the current line. .. function:: cy locals cy globals Print all the local and global variables and their values. .. function:: cy import FILE... Import debug information from files given as arguments. The easiest way to import debug information is to use the cygdb command line tool. .. function:: cy exec code Execute code in the current Python or Cython frame. This works like Python's interactive interpreter. For Python frames it uses the globals and locals from the Python frame, for Cython frames it uses the dict of globals used on the Cython module and a new dict filled with the local Cython variables. .. note:: ``cy exec`` modifies state and executes code in the debuggee and is therefore potentially dangerous. Example:: (gdb) cy exec x + 1 2 (gdb) cy exec import sys; print sys.version_info (2, 6, 5, 'final', 0) (gdb) cy exec >global foo > >foo = 'something' >end Convenience functions ===================== The following functions are gdb functions, which means they can be used in a gdb expression. .. function:: cy_cname(varname) Returns the C variable name of a Cython variable. For global variables this may not be actually valid. .. function:: cy_cvalue(varname) Returns the value of a Cython variable. .. function:: cy_eval(expression) Evaluates Python code in the nearest Python or Cython frame and returns the result of the expression as a gdb value. This gives a new reference if successful, NULL on error. .. function:: cy_lineno() Returns the current line number in the selected Cython frame. Example:: (gdb) print $cy_cname("x") $1 = "__pyx_v_x" (gdb) watch $cy_cvalue("x") Hardware watchpoint 13: $cy_cvalue("x") (gdb) cy set my_cython_variable = $cy_eval("{'spam': 'ham'}") (gdb) print $cy_lineno() $2 = 12 Configuring the Debugger ======================== A few aspects of the debugger are configurable with gdb parameters. For instance, colors can be disabled, the terminal background color and breakpoint autocompletion can be configured. .. c:macro:: cy_complete_unqualified Tells the Cython debugger whether ``cy break`` should also complete plain function names, i.e. not prefixed by their module name. E.g. if you have a function named ``spam``, in module ``M``, it tells whether to only complete ``M.spam`` or also just ``spam``. The default is true. .. c:macro:: cy_colorize_code Tells the debugger whether to colorize source code. The default is true. .. c:macro:: cy_terminal_background_color Tells the debugger about the terminal background color, which affects source code coloring. The default is "dark", another valid option is "light". This is how these parameters can be used:: (gdb) set cy_complete_unqualified off (gdb) set cy_terminal_background_color light (gdb) show cy_colorize_code Cython-0.23.4/docs/src/userguide/buffer.rst0000644000175600017570000001462512606202452021732 0ustar jenkinsjenkins00000000000000.. _buffer: Implementing the buffer protocol ================================ Cython objects can expose memory buffers to Python code by implementing the "buffer protocol". This chapter shows how to implement the protocol and make use of the memory managed by an extension type from NumPy. A matrix class -------------- The following Cython/C++ code implements a matrix of floats, where the number of columns is fixed at construction time but rows can be added dynamically. :: # matrix.pyx from libcpp.vector cimport vector cdef class Matrix: cdef unsigned ncols cdef vector[float] v def __cinit__(self, unsigned ncols): self.ncols = ncols def add_row(self): """Adds a row, initially zero-filled.""" self.v.extend(self.ncols) There are no members to do anything productive with the matrices' contents. We could implement custom ``__getitem__``, ``__setitem__``, etc. for this, but instead we'll use the buffer protocol to expose the matrix's data to Python so we can use NumPy to do useful work. Implementing the buffer protocol requires adding two methods, ``__getbuffer__`` and ``__releasebuffer__``, which Cython handles specially. :: from cpython cimport Py_buffer from libcpp.vector cimport vector cdef class Matrix: cdef Py_ssize_t ncols cdef Py_ssize_t shape[2] cdef Py_ssize_t strides[2] cdef vector[float] v def __cinit__(self, Py_ssize_t ncols): self.ncols = ncols def add_row(self): """Adds a row, initially zero-filled.""" self.v.resize(self.v.size() + self.ncols) def __getbuffer__(self, Py_buffer *buffer, int flags): cdef Py_ssize_t itemsize = sizeof(self.v[0]) self.shape[0] = self.v.size() / self.ncols self.shape[1] = self.ncols # Stride 1 is the distance, in bytes, between two items in a row; # this is the distance between two adjacent items in the vector. # Stride 0 is the distance between the first elements of adjacent rows. self.strides[1] = ( &(self.v[1]) - &(self.v[0])) self.strides[0] = self.ncols * self.strides[1] buffer.buf = &(self.v[0]) buffer.format = 'f' # float buffer.internal = NULL # see References buffer.itemsize = itemsize buffer.len = self.v.size() * itemsize # product(shape) * itemsize buffer.ndim = 2 buffer.obj = self buffer.readonly = 0 buffer.shape = self.shape buffer.strides = self.strides buffer.suboffsets = NULL # for pointer arrays only def __releasebuffer__(self, Py_buffer *buffer): pass The method ``Matrix.__getbuffer__`` fills a descriptor structure, called a ``Py_buffer``, that is defined by the Python C-API. It contains a pointer to the actual buffer in memory, as well as metadata about the shape of the array and the strides (step sizes to get from one element or row to the next). Its ``shape`` and ``strides`` members are pointers that must point to arrays of type and size ``Py_ssize_t[ndim]``. These arrays have to stay alive as long as any buffer views the data, so we store them on the ``Matrix`` object as members. The code is not yet complete, but we can already compile it and test the basic functionality. :: >>> from matrix import Matrix >>> import numpy as np >>> m = Matrix(10) >>> np.asarray(m) array([], shape=(0, 10), dtype=float32) >>> m.add_row() >>> a = np.asarray(m) >>> a[:] = 1 >>> m.add_row() >>> a = np.asarray(m) >>> a array([[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32) Now we can view the ``Matrix`` as a NumPy ``ndarray``, and modify its contents using standard NumPy operations. Memory safety and reference counting ------------------------------------ The ``Matrix`` class as implemented so far is unsafe. The ``add_row`` operation can move the underlying buffer, which invalidates any NumPy (or other) view on the data. If you try to access values after an ``add_row`` call, you'll get outdated values or a segfault. This is where ``__releasebuffer__`` comes in. We can add a reference count to each matrix, and lock it for mutation whenever a view exists. :: cdef class Matrix: # ... cdef int view_count def __cinit__(self, Py_ssize_t ncols): self.ncols = ncols self.view_count = 0 def add_row(self): if self.view_count > 0: raise ValueError("can't add row while being viewed") self.v.resize(self.v.size() + self.ncols) def __getbuffer__(self, Py_buffer *buffer, int flags): # ... as before self.view_count += 1 def __releasebuffer__(self, Py_buffer *buffer): self.view_count -= 1 Flags ----- We skipped some input validation in the code. The ``flags`` argument to ``__getbuffer__`` comes from ``np.asarray`` (and other clients) and is an OR of boolean flags that describe the kind of array that is requested. Strictly speaking, if the flags contain ``PyBUF_ND``, ``PyBUF_SIMPLE``, or ``PyBUF_F_CONTIGUOUS``, ``__getbuffer__`` must raise a ``BufferError``. These macros can be ``cimport``'d from ``cpython.buffer``. (The matrix-in-vector structure actually conforms to ``PyBUF_ND``, but that would prohibit ``__getbuffer__`` from filling in the strides. A single-row matrix is F-contiguous, but a larger matrix is not.) References ---------- The buffer interface used here is set out in `PEP 3118, Revising the buffer protocol `_ A tutorial for using this API from C is on Jake Vanderplas's blog, `An Introduction to the Python Buffer Protocol `_. Reference documentation is available for `Python 3 `_ and `Python 2 `_. The Py2 documentation also describes an older buffer protocol that is no longer in use; since Python 2.6, the PEP 3118 protocol has been implemented, and the older protocol is only relevant for legacy code. Cython-0.23.4/docs/src/tutorial/0000755000175600017570000000000012606202455017571 5ustar jenkinsjenkins00000000000000Cython-0.23.4/docs/src/tutorial/strings.rst0000644000175600017570000010411112606202452022007 0ustar jenkinsjenkins00000000000000.. highlight:: cython Unicode and passing strings =========================== Similar to the string semantics in Python 3, Cython strictly separates byte strings and unicode strings. Above all, this means that by default there is no automatic conversion between byte strings and unicode strings (except for what Python 2 does in string operations). All encoding and decoding must pass through an explicit encoding/decoding step. To ease conversion between Python and C strings in simple cases, the module-level ``c_string_type`` and ``c_string_encoding`` directives can be used to implicitly insert these encoding/decoding steps. Python string types in Cython code ---------------------------------- Cython supports four Python string types: :obj:`bytes`, :obj:`str`, :obj:`unicode` and :obj:`basestring`. The :obj:`bytes` and :obj:`unicode` types are the specific types known from normal Python 2.x (named :obj:`bytes` and :obj:`str` in Python 3). Additionally, Cython also supports the :obj:`bytearray` type starting with Python 2.6. It behaves like the :obj:`bytes` type, except that it is mutable. The :obj:`str` type is special in that it is the byte string in Python 2 and the Unicode string in Python 3 (for Cython code compiled with language level 2, i.e. the default). Meaning, it always corresponds exactly with the type that the Python runtime itself calls :obj:`str`. Thus, in Python 2, both :obj:`bytes` and :obj:`str` represent the byte string type, whereas in Python 3, both :obj:`str` and :obj:`unicode` represent the Python Unicode string type. The switch is made at C compile time, the Python version that is used to run Cython is not relevant. When compiling Cython code with language level 3, the :obj:`str` type is identified with exactly the Unicode string type at Cython compile time, i.e. it does not identify with :obj:`bytes` when running in Python 2. Note that the :obj:`str` type is not compatible with the :obj:`unicode` type in Python 2, i.e. you cannot assign a Unicode string to a variable or argument that is typed :obj:`str`. The attempt will result in either a compile time error (if detectable) or a :obj:`TypeError` exception at runtime. You should therefore be careful when you statically type a string variable in code that must be compatible with Python 2, as this Python version allows a mix of byte strings and unicode strings for data and users normally expect code to be able to work with both. Code that only targets Python 3 can safely type variables and arguments as either :obj:`bytes` or :obj:`unicode`. The :obj:`basestring` type represents both the types :obj:`str` and :obj:`unicode`, i.e. all Python text string types in Python 2 and Python 3. This can be used for typing text variables that normally contain Unicode text (at least in Python 3) but must additionally accept the :obj:`str` type in Python 2 for backwards compatibility reasons. It is not compatible with the :obj:`bytes` type. Its usage should be rare in normal Cython code as the generic :obj:`object` type (i.e. untyped code) will normally be good enough and has the additional advantage of supporting the assignment of string subtypes. Support for the :obj:`basestring` type is new in Cython 0.20. General notes about C strings ----------------------------- In many use cases, C strings (a.k.a. character pointers) are slow and cumbersome. For one, they usually require manual memory management in one way or another, which makes it more likely to introduce bugs into your code. Then, Python string objects cache their length, so requesting it (e.g. to validate the bounds of index access or when concatenating two strings into one) is an efficient constant time operation. In contrast, calling :c:func:`strlen()` to get this information from a C string takes linear time, which makes many operations on C strings rather costly. Regarding text processing, Python has built-in support for Unicode, which C lacks completely. If you are dealing with Unicode text, you are usually better off using Python Unicode string objects than trying to work with encoded data in C strings. Cython makes this quite easy and efficient. Generally speaking: unless you know what you are doing, avoid using C strings where possible and use Python string objects instead. The obvious exception to this is when passing them back and forth from and to external C code. Also, C++ strings remember their length as well, so they can provide a suitable alternative to Python bytes objects in some cases, e.g. when reference counting is not needed within a well defined context. Passing byte strings -------------------- It is very easy to pass byte strings between C code and Python. When receiving a byte string from a C library, you can let Cython convert it into a Python byte string by simply assigning it to a Python variable:: cdef char* c_string = c_call_returning_a_c_string() cdef bytes py_string = c_string A type cast to :obj:`object` or :obj:`bytes` will do the same thing:: py_string = c_string This creates a Python byte string object that holds a copy of the original C string. It can be safely passed around in Python code, and will be garbage collected when the last reference to it goes out of scope. It is important to remember that null bytes in the string act as terminator character, as generally known from C. The above will therefore only work correctly for C strings that do not contain null bytes. Besides not working for null bytes, the above is also very inefficient for long strings, since Cython has to call :c:func:`strlen()` on the C string first to find out the length by counting the bytes up to the terminating null byte. In many cases, the user code will know the length already, e.g. because a C function returned it. In this case, it is much more efficient to tell Cython the exact number of bytes by slicing the C string:: cdef char* c_string = NULL cdef Py_ssize_t length = 0 # get pointer and length from a C function get_a_c_string(&c_string, &length) py_bytes_string = c_string[:length] Here, no additional byte counting is required and ``length`` bytes from the ``c_string`` will be copied into the Python bytes object, including any null bytes. Keep in mind that the slice indices are assumed to be accurate in this case and no bounds checking is done, so incorrect slice indices will lead to data corruption and crashes. Note that the creation of the Python bytes string can fail with an exception, e.g. due to insufficient memory. If you need to :c:func:`free()` the string after the conversion, you should wrap the assignment in a try-finally construct:: from libc.stdlib cimport free cdef bytes py_string cdef char* c_string = c_call_creating_a_new_c_string() try: py_string = c_string finally: free(c_string) To convert the byte string back into a C :c:type:`char*`, use the opposite assignment:: cdef char* other_c_string = py_string This is a very fast operation after which ``other_c_string`` points to the byte string buffer of the Python string itself. It is tied to the life time of the Python string. When the Python string is garbage collected, the pointer becomes invalid. It is therefore important to keep a reference to the Python string as long as the :c:type:`char*` is in use. Often enough, this only spans the call to a C function that receives the pointer as parameter. Special care must be taken, however, when the C function stores the pointer for later use. Apart from keeping a Python reference to the string object, no manual memory management is required. Starting with Cython 0.20, the :obj:`bytearray` type is supported and coerces in the same way as the :obj:`bytes` type. However, when using it in a C context, special care must be taken not to grow or shrink the object buffer after converting it to a C string pointer. These modifications can change the internal buffer address, which will make the pointer invalid. Accepting strings from Python code ---------------------------------- The other side, receiving input from Python code, may appear simple at first sight, as it only deals with objects. However, getting this right without making the API too narrow or too unsafe may not be entirely obvious. In the case that the API only deals with byte strings, i.e. binary data or encoded text, it is best not to type the input argument as something like :obj:`bytes`, because that would restrict the allowed input to exactly that type and exclude both subtypes and other kinds of byte containers, e.g. :obj:`bytearray` objects or memory views. Depending on how (and where) the data is being processed, it may be a good idea to instead receive a 1-dimensional memory view, e.g. :: def process_byte_data(unsigned char[:] data): length = data.shape[0] first_byte = data[0] slice_view = data[1:-1] ... Cython's memory views are described in more detail in :doc:`../userguide/memoryviews`, but the above example already shows most of the relevant functionality for 1-dimensional byte views. They allow for efficient processing of arrays and accept anything that can unpack itself into a byte buffer, without intermediate copying. The processed content can finally be returned in the memory view itself (or a slice of it), but it is often better to copy the data back into a flat and simple :obj:`bytes` or :obj:`bytearray` object, especially when only a small slice is returned. Since memoryviews do not copy the data, they would otherwise keep the entire original buffer alive. The general idea here is to be liberal with input by accepting any kind of byte buffer, but strict with output by returning a simple, well adapted object. This can simply be done as follows:: def process_byte_data(unsigned char[:] data): # ... process the data if return_all: return bytes(data) else: # example for returning a slice return bytes(data[5:35]) If the byte input is actually encoded text, and the further processing should happen at the Unicode level, then the right thing to do is to decode the input straight away. This is almost only a problem in Python 2.x, where Python code expects that it can pass a byte string (:obj:`str`) with encoded text into a text API. Since this usually happens in more than one place in the module's API, a helper function is almost always the way to go, since it allows for easy adaptation of the input normalisation process later. This kind of input normalisation function will commonly look similar to the following:: from cpython.version cimport PY_MAJOR_VERSION cdef unicode _ustring(s): if type(s) is unicode: # fast path for most common case(s) return s elif PY_MAJOR_VERSION < 3 and isinstance(s, bytes): # only accept byte strings in Python 2.x, not in Py3 return (s).decode('ascii') elif isinstance(s, unicode): # an evil cast to might work here in some(!) cases, # depending on what the further processing does. to be safe, # we can always create a copy instead return unicode(s) else: raise TypeError(...) And should then be used like this:: def api_func(s): text = _ustring(s) ... Similarly, if the further processing happens at the byte level, but Unicode string input should be accepted, then the following might work, if you are using memory views:: # define a global name for whatever char type is used in the module ctypedef unsigned char char_type cdef char_type[:] _chars(s): if isinstance(s, unicode): # encode to the specific encoding used inside of the module s = (s).encode('utf8') return s In this case, you might want to additionally ensure that byte string input really uses the correct encoding, e.g. if you require pure ASCII input data, you can run over the buffer in a loop and check the highest bit of each byte. This should then also be done in the input normalisation function. Dealing with "const" -------------------- Many C libraries use the ``const`` modifier in their API to declare that they will not modify a string, or to require that users must not modify a string they return, for example: .. code-block:: c typedef const char specialChar; int process_string(const char* s); const unsigned char* look_up_cached_string(const unsigned char* key); Since version 0.18, Cython has support for the ``const`` modifier in the language, so you can declare the above functions straight away as follows:: cdef extern from "someheader.h": ctypedef const char specialChar int process_string(const char* s) const unsigned char* look_up_cached_string(const unsigned char* key) Previous versions required users to make the necessary declarations at a textual level. If you need to support older Cython versions, you can use the following approach. In general, for arguments of external C functions, the ``const`` modifier does not matter and can be left out in the Cython declaration (e.g. in a .pxd file). The C compiler will still do the right thing, even if you declare this to Cython:: cdef extern from "someheader.h": int process_string(char* s) # note: looses API information! However, in most other situations, such as for return values and variables that use specifically typedef-ed API types, it does matter and the C compiler will emit at least a warning if used incorrectly. To help with this, you can use the type definitions in the ``libc.string`` module, e.g.:: from libc.string cimport const_char, const_uchar cdef extern from "someheader.h": ctypedef const_char specialChar int process_string(const_char* s) const_uchar* look_up_cached_string(const_uchar* key) Note: even if the API only uses ``const`` for function arguments, it is still preferable to properly declare them using these provided :c:type:`const_char` types in order to simplify adaptations. In Cython 0.18, these standard declarations have been changed to use the correct ``const`` modifier, so your code will automatically benefit from the new ``const`` support if it uses them. Decoding bytes to text ---------------------- The initially presented way of passing and receiving C strings is sufficient if your code only deals with binary data in the strings. When we deal with encoded text, however, it is best practice to decode the C byte strings to Python Unicode strings on reception, and to encode Python Unicode strings to C byte strings on the way out. With a Python byte string object, you would normally just call the ``bytes.decode()`` method to decode it into a Unicode string:: ustring = byte_string.decode('UTF-8') Cython allows you to do the same for a C string, as long as it contains no null bytes:: cdef char* some_c_string = c_call_returning_a_c_string() ustring = some_c_string.decode('UTF-8') And, more efficiently, for strings where the length is known:: cdef char* c_string = NULL cdef Py_ssize_t length = 0 # get pointer and length from a C function get_a_c_string(&c_string, &length) ustring = c_string[:length].decode('UTF-8') The same should be used when the string contains null bytes, e.g. when it uses an encoding like UCS-4, where each character is encoded in four bytes most of which tend to be 0. Again, no bounds checking is done if slice indices are provided, so incorrect indices lead to data corruption and crashes. However, using negative indices is possible since Cython 0.17 and will inject a call to :c:func:`strlen()` in order to determine the string length. Obviously, this only works for 0-terminated strings without internal null bytes. Text encoded in UTF-8 or one of the ISO-8859 encodings is usually a good candidate. If in doubt, it's better to pass indices that are 'obviously' correct than to rely on the data to be as expected. It is common practice to wrap string conversions (and non-trivial type conversions in general) in dedicated functions, as this needs to be done in exactly the same way whenever receiving text from C. This could look as follows:: from libc.stdlib cimport free cdef unicode tounicode(char* s): return s.decode('UTF-8', 'strict') cdef unicode tounicode_with_length( char* s, size_t length): return s[:length].decode('UTF-8', 'strict') cdef unicode tounicode_with_length_and_free( char* s, size_t length): try: return s[:length].decode('UTF-8', 'strict') finally: free(s) Most likely, you will prefer shorter function names in your code based on the kind of string being handled. Different types of content often imply different ways of handling them on reception. To make the code more readable and to anticipate future changes, it is good practice to use separate conversion functions for different types of strings. Encoding text to bytes ---------------------- The reverse way, converting a Python unicode string to a C :c:type:`char*`, is pretty efficient by itself, assuming that what you actually want is a memory managed byte string:: py_byte_string = py_unicode_string.encode('UTF-8') cdef char* c_string = py_byte_string As noted before, this takes the pointer to the byte buffer of the Python byte string. Trying to do the same without keeping a reference to the Python byte string will fail with a compile error:: # this will not compile ! cdef char* c_string = py_unicode_string.encode('UTF-8') Here, the Cython compiler notices that the code takes a pointer to a temporary string result that will be garbage collected after the assignment. Later access to the invalidated pointer will read invalid memory and likely result in a segfault. Cython will therefore refuse to compile this code. C++ strings ----------- When wrapping a C++ library, strings will usually come in the form of the :c:type:`std::string` class. As with C strings, Python byte strings automatically coerce from and to C++ strings:: # distutils: language = c++ from libcpp.string cimport string cdef string s = py_bytes_object try: s.append('abc') py_bytes_object = s finally: del s The memory management situation is different than in C because the creation of a C++ string makes an independent copy of the string buffer which the string object then owns. It is therefore possible to convert temporarily created Python objects directly into C++ strings. A common way to make use of this is when encoding a Python unicode string into a C++ string:: cdef string cpp_string = py_unicode_string.encode('UTF-8') Note that this involves a bit of overhead because it first encodes the Unicode string into a temporarily created Python bytes object and then copies its buffer into a new C++ string. For the other direction, efficient decoding support is available in Cython 0.17 and later:: cdef string s = string(b'abcdefg') ustring1 = s.decode('UTF-8') ustring2 = s[2:-2].decode('UTF-8') For C++ strings, decoding slices will always take the proper length of the string into account and apply Python slicing semantics (e.g. return empty strings for out-of-bounds indices). Auto encoding and decoding -------------------------- Cython 0.19 comes with two new directives: ``c_string_type`` and ``c_string_encoding``. They can be used to change the Python string types that C/C++ strings coerce from and to. By default, they only coerce from and to the bytes type, and encoding or decoding must be done explicitly, as described above. There are two use cases where this is inconvenient. First, if all C strings that are being processed (or the large majority) contain text, automatic encoding and decoding from and to Python unicode objects can reduce the code overhead a little. In this case, you can set the ``c_string_type`` directive in your module to :obj:`unicode` and the ``c_string_encoding`` to the encoding that your C code uses, for example:: # cython: c_string_type=unicode, c_string_encoding=utf8 cdef char* c_string = 'abcdefg' # implicit decoding: cdef object py_unicode_object = c_string # explicit conversion to Python bytes: py_bytes_object = c_string The second use case is when all C strings that are being processed only contain ASCII encodable characters (e.g. numbers) and you want your code to use the native legacy string type in Python 2 for them, instead of always using Unicode. In this case, you can set the string type to :obj:`str`:: # cython: c_string_type=str, c_string_encoding=ascii cdef char* c_string = 'abcdefg' # implicit decoding in Py3, bytes conversion in Py2: cdef object py_str_object = c_string # explicit conversion to Python bytes: py_bytes_object = c_string # explicit conversion to Python unicode: py_bytes_object = c_string The other direction, i.e. automatic encoding to C strings, is only supported for the ASCII codec (and the "default encoding", which is runtime specific and may or may not be ASCII). This is because CPython handles the memory management in this case by keeping an encoded copy of the string alive together with the original unicode string. Otherwise, there would be no way to limit the lifetime of the encoded string in any sensible way, thus rendering any attempt to extract a C string pointer from it a dangerous endeavour. As long as you stick to the ASCII encoding for the ``c_string_encoding`` directive, though, the following will work:: # cython: c_string_type=unicode, c_string_encoding=ascii def func(): ustring = u'abc' cdef char* s = ustring return s[0] # returns u'a' (This example uses a function context in order to safely control the lifetime of the Unicode string. Global Python variables can be modified from the outside, which makes it dangerous to rely on the lifetime of their values.) Source code encoding -------------------- When string literals appear in the code, the source code encoding is important. It determines the byte sequence that Cython will store in the C code for bytes literals, and the Unicode code points that Cython builds for unicode literals when parsing the byte encoded source file. Following `PEP 263`_, Cython supports the explicit declaration of source file encodings. For example, putting the following comment at the top of an ``ISO-8859-15`` (Latin-9) encoded source file (into the first or second line) is required to enable ``ISO-8859-15`` decoding in the parser:: # -*- coding: ISO-8859-15 -*- When no explicit encoding declaration is provided, the source code is parsed as UTF-8 encoded text, as specified by `PEP 3120`_. `UTF-8`_ is a very common encoding that can represent the entire Unicode set of characters and is compatible with plain ASCII encoded text that it encodes efficiently. This makes it a very good choice for source code files which usually consist mostly of ASCII characters. .. _`PEP 263`: http://www.python.org/dev/peps/pep-0263/ .. _`PEP 3120`: http://www.python.org/dev/peps/pep-3120/ .. _`UTF-8`: http://en.wikipedia.org/wiki/UTF-8 As an example, putting the following line into a UTF-8 encoded source file will print ``5``, as UTF-8 encodes the letter ``'ö'`` in the two byte sequence ``'\xc3\xb6'``:: print( len(b'abcö') ) whereas the following ``ISO-8859-15`` encoded source file will print ``4``, as the encoding uses only 1 byte for this letter:: # -*- coding: ISO-8859-15 -*- print( len(b'abcö') ) Note that the unicode literal ``u'abcö'`` is a correctly decoded four character Unicode string in both cases, whereas the unprefixed Python :obj:`str` literal ``'abcö'`` will become a byte string in Python 2 (thus having length 4 or 5 in the examples above), and a 4 character Unicode string in Python 3. If you are not familiar with encodings, this may not appear obvious at first read. See `CEP 108`_ for details. As a rule of thumb, it is best to avoid unprefixed non-ASCII :obj:`str` literals and to use unicode string literals for all text. Cython also supports the ``__future__`` import ``unicode_literals`` that instructs the parser to read all unprefixed :obj:`str` literals in a source file as unicode string literals, just like Python 3. .. _`CEP 108`: http://wiki.cython.org/enhancements/stringliterals Single bytes and characters --------------------------- The Python C-API uses the normal C :c:type:`char` type to represent a byte value, but it has two special integer types for a Unicode code point value, i.e. a single Unicode character: :c:type:`Py_UNICODE` and :c:type:`Py_UCS4`. Since version 0.13, Cython supports the first natively, support for :c:type:`Py_UCS4` is new in Cython 0.15. :c:type:`Py_UNICODE` is either defined as an unsigned 2-byte or 4-byte integer, or as :c:type:`wchar_t`, depending on the platform. The exact type is a compile time option in the build of the CPython interpreter and extension modules inherit this definition at C compile time. The advantage of :c:type:`Py_UCS4` is that it is guaranteed to be large enough for any Unicode code point value, regardless of the platform. It is defined as a 32bit unsigned int or long. In Cython, the :c:type:`char` type behaves differently from the :c:type:`Py_UNICODE` and :c:type:`Py_UCS4` types when coercing to Python objects. Similar to the behaviour of the bytes type in Python 3, the :c:type:`char` type coerces to a Python integer value by default, so that the following prints 65 and not ``A``:: # -*- coding: ASCII -*- cdef char char_val = 'A' assert char_val == 65 # ASCII encoded byte value of 'A' print( char_val ) If you want a Python bytes string instead, you have to request it explicitly, and the following will print ``A`` (or ``b'A'`` in Python 3):: print( char_val ) The explicit coercion works for any C integer type. Values outside of the range of a :c:type:`char` or :c:type:`unsigned char` will raise an :obj:`OverflowError` at runtime. Coercion will also happen automatically when assigning to a typed variable, e.g.:: cdef bytes py_byte_string py_byte_string = char_val On the other hand, the :c:type:`Py_UNICODE` and :c:type:`Py_UCS4` types are rarely used outside of the context of a Python unicode string, so their default behaviour is to coerce to a Python unicode object. The following will therefore print the character ``A``, as would the same code with the :c:type:`Py_UNICODE` type:: cdef Py_UCS4 uchar_val = u'A' assert uchar_val == 65 # character point value of u'A' print( uchar_val ) Again, explicit casting will allow users to override this behaviour. The following will print 65:: cdef Py_UCS4 uchar_val = u'A' print( uchar_val ) Note that casting to a C :c:type:`long` (or :c:type:`unsigned long`) will work just fine, as the maximum code point value that a Unicode character can have is 1114111 (``0x10FFFF``). On platforms with 32bit or more, :c:type:`int` is just as good. Narrow Unicode builds ---------------------- In narrow Unicode builds of CPython before version 3.3, i.e. builds where ``sys.maxunicode`` is 65535 (such as all Windows builds, as opposed to 1114111 in wide builds), it is still possible to use Unicode character code points that do not fit into the 16 bit wide :c:type:`Py_UNICODE` type. For example, such a CPython build will accept the unicode literal ``u'\U00012345'``. However, the underlying system level encoding leaks into Python space in this case, so that the length of this literal becomes 2 instead of 1. This also shows when iterating over it or when indexing into it. The visible substrings are ``u'\uD808'`` and ``u'\uDF45'`` in this example. They form a so-called surrogate pair that represents the above character. For more information on this topic, it is worth reading the `Wikipedia article about the UTF-16 encoding`_. .. _`Wikipedia article about the UTF-16 encoding`: http://en.wikipedia.org/wiki/UTF-16/UCS-2 The same properties apply to Cython code that gets compiled for a narrow CPython runtime environment. In most cases, e.g. when searching for a substring, this difference can be ignored as both the text and the substring will contain the surrogates. So most Unicode processing code will work correctly also on narrow builds. Encoding, decoding and printing will work as expected, so that the above literal turns into exactly the same byte sequence on both narrow and wide Unicode platforms. However, programmers should be aware that a single :c:type:`Py_UNICODE` value (or single 'character' unicode string in CPython) may not be enough to represent a complete Unicode character on narrow platforms. For example, if an independent search for ``u'\uD808'`` and ``u'\uDF45'`` in a unicode string succeeds, this does not necessarily mean that the character ``u'\U00012345`` is part of that string. It may well be that two different characters are in the string that just happen to share a code unit with the surrogate pair of the character in question. Looking for substrings works correctly because the two code units in the surrogate pair use distinct value ranges, so the pair is always identifiable in a sequence of code points. As of version 0.15, Cython has extended support for surrogate pairs so that you can safely use an ``in`` test to search character values from the full :c:type:`Py_UCS4` range even on narrow platforms:: cdef Py_UCS4 uchar = 0x12345 print( uchar in some_unicode_string ) Similarly, it can coerce a one character string with a high Unicode code point value to a Py_UCS4 value on both narrow and wide Unicode platforms:: cdef Py_UCS4 uchar = u'\U00012345' assert uchar == 0x12345 In CPython 3.3 and later, the :c:type:`Py_UNICODE` type is an alias for the system specific :c:type:`wchar_t` type and is no longer tied to the internal representation of the Unicode string. Instead, any Unicode character can be represented on all platforms without resorting to surrogate pairs. This implies that narrow builds no longer exist from that version on, regardless of the size of :c:type:`Py_UNICODE`. See `PEP 393 `_ for details. Cython 0.16 and later handles this change internally and does the right thing also for single character values as long as either type inference is applied to untyped variables or the portable :c:type:`Py_UCS4` type is explicitly used in the source code instead of the platform specific :c:type:`Py_UNICODE` type. Optimisations that Cython applies to the Python unicode type will automatically adapt to PEP 393 at C compile time, as usual. Iteration --------- Cython 0.13 supports efficient iteration over :c:type:`char*`, bytes and unicode strings, as long as the loop variable is appropriately typed. So the following will generate the expected C code:: cdef char* c_string = ... cdef char c for c in c_string[:100]: if c == 'A': ... The same applies to bytes objects:: cdef bytes bytes_string = ... cdef char c for c in bytes_string: if c == 'A': ... For unicode objects, Cython will automatically infer the type of the loop variable as :c:type:`Py_UCS4`:: cdef unicode ustring = ... # NOTE: no typing required for 'uchar' ! for uchar in ustring: if uchar == u'A': ... The automatic type inference usually leads to much more efficient code here. However, note that some unicode operations still require the value to be a Python object, so Cython may end up generating redundant conversion code for the loop variable value inside of the loop. If this leads to a performance degradation for a specific piece of code, you can either type the loop variable as a Python object explicitly, or assign its value to a Python typed variable somewhere inside of the loop to enforce one-time coercion before running Python operations on it. There are also optimisations for ``in`` tests, so that the following code will run in plain C code, (actually using a switch statement):: cdef Py_UCS4 uchar_val = get_a_unicode_character() if uchar_val in u'abcABCxY': ... Combined with the looping optimisation above, this can result in very efficient character switching code, e.g. in unicode parsers. Windows and wide character APIs ------------------------------- Windows system APIs natively support Unicode in the form of zero-terminated UTF-16 encoded :c:type:`wchar_t*` strings, so called "wide strings". By default, Windows builds of CPython define :c:type:`Py_UNICODE` as a synonym for :c:type:`wchar_t`. This makes internal :obj:`unicode` representation compatible with UTF-16 and allows for efficient zero-copy conversions. This also means that Windows builds are always `Narrow Unicode builds`_ with all the caveats. To aid interoperation with Windows APIs, Cython 0.19 supports wide strings (in the form of :c:type:`Py_UNICODE*`) and implicitly converts them to and from :obj:`unicode` string objects. These conversions behave the same way as they do for :c:type:`char*` and :obj:`bytes` as described in `Passing byte strings`_. In addition to automatic conversion, unicode literals that appear in C context become C-level wide string literals and :py:func:`len` built-in function is specialized to compute the length of zero-terminated :c:type:`Py_UNICODE*` string or array. Here is an example of how one would call a Unicode API on Windows:: cdef extern from "Windows.h": ctypedef Py_UNICODE WCHAR ctypedef const WCHAR* LPCWSTR ctypedef void* HWND int MessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, int uType) title = u"Windows Interop Demo - Python %d.%d.%d" % sys.version_info[:3] MessageBoxW(NULL, u"Hello Cython \u263a", title, 0) .. Warning:: The use of :c:type:`Py_UNICODE*` strings outside of Windows is strongly discouraged. :c:type:`Py_UNICODE` is inherently not portable between different platforms and Python versions. CPython 3.3 has moved to a flexible internal representation of unicode strings (:pep:`393`), making all :c:type:`Py_UNICODE` related APIs deprecated and inefficient. One consequence of CPython 3.3 changes is that :py:func:`len` of :obj:`unicode` strings is always measured in *code points* ("characters"), while Windows API expect the number of UTF-16 *code units* (where each surrogate is counted individually). To always get the number of code units, call :c:func:`PyUnicode_GetSize` directly. Cython-0.23.4/docs/src/tutorial/related_work.rst0000644000175600017570000000523112606202452023003 0ustar jenkinsjenkins00000000000000Related work ============ Pyrex [Pyrex]_ is the compiler project that Cython was originally based on. Many features and the major design decisions of the Cython language were developed by Greg Ewing as part of that project. Today, Cython supersedes the capabilities of Pyrex by providing a substantially higher compatibility with Python code and Python semantics, as well as superior optimisations and better integration with scientific Python extensions like NumPy. ctypes [ctypes]_ is a foreign function interface (FFI) for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python code. Compared to Cython, it has the major advantage of being in the standard library and being usable directly from Python code, without any additional dependencies. The major drawback is its performance, which suffers from the Python call overhead as all operations must pass through Python code first. Cython, being a compiled language, can avoid much of this overhead by moving more functionality and long-running loops into fast C code. SWIG [SWIG]_ is a wrapper code generator. It makes it very easy to parse large API definitions in C/C++ header files, and to generate straight forward wrapper code for a large set of programming languages. As opposed to Cython, however, it is not a programming language itself. Thin wrappers are easy to generate, but the more functionality a wrapper needs to provide, the harder it gets to implement it with SWIG. Cython, on the other hand, makes it very easy to write very elaborate wrapper code specifically for the Python language, and to make it as thin or thick as needed at any given place. Also, there exists third party code for parsing C header files and using it to generate Cython definitions and module skeletons. ShedSkin [ShedSkin]_ is an experimental Python-to-C++ compiler. It uses a very powerful whole-module type inference engine to generate a C++ program from (restricted) Python source code. The main drawback is that it has no support for calling the Python/C API for operations it does not support natively, and supports very few of the standard Python modules. .. [ctypes] http://docs.python.org/library/ctypes.html. .. there's also the original ctypes home page: http://python.net/crew/theller/ctypes/ .. [Pyrex] G. Ewing, Pyrex: C-Extensions for Python, http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/ .. [ShedSkin] M. Dufour, J. Coughlan, ShedSkin, http://code.google.com/p/shedskin/ .. [SWIG] David M. Beazley et al., SWIG: An Easy to Use Tool for Integrating Scripting Languages with C and C++, http://www.swig.org. Cython-0.23.4/docs/src/tutorial/readings.rst0000644000175600017570000000253212606202452022116 0ustar jenkinsjenkins00000000000000Further reading =============== The main documentation is located at http://docs.cython.org/. Some recent features might not have documentation written yet, in such cases some notes can usually be found in the form of a Cython Enhancement Proposal (CEP) on http://wiki.cython.org/enhancements. [Seljebotn09]_ contains more information about Cython and NumPy arrays. If you intend to use Cython code in a multi-threaded setting, it is essential to read up on Cython's features for managing the Global Interpreter Lock (the GIL). The same paper contains an explanation of the GIL, and the main documentation explains the Cython features for managing it. Finally, don't hesitate to ask questions (or post reports on successes!) on the Cython users mailing list [UserList]_. The Cython developer mailing list, [DevList]_, is also open to everybody, but focusses on core development issues. Feel free to use it to report a clear bug, to ask for guidance if you have time to spare to develop Cython, or if you have suggestions for future development. .. [DevList] Cython developer mailing list: http://mail.python.org/mailman/listinfo/cython-devel .. [Seljebotn09] D. S. Seljebotn, Fast numerical computations with Cython, Proceedings of the 8th Python in Science Conference, 2009. .. [UserList] Cython users mailing list: http://groups.google.com/group/cython-users Cython-0.23.4/docs/src/tutorial/pxd_files.rst0000644000175600017570000000317212606202452022300 0ustar jenkinsjenkins00000000000000pxd files ========= In addition to the ``.pyx`` source files, Cython uses ``.pxd`` files which work like C header files -- they contain Cython declarations (and sometimes code sections) which are only meant for inclusion by Cython modules. A ``pxd`` file is imported into a ``pyx`` module by using the ``cimport`` keyword. ``pxd`` files have many use-cases: 1. They can be used for sharing external C declarations. 2. They can contain functions which are well suited for inlining by the C compiler. Such functions should be marked ``inline``, example: :: cdef inline int int_min(int a, int b): return b if b < a else a 3. When accompanying an equally named ``pyx`` file, they provide a Cython interface to the Cython module so that other Cython modules can communicate with it using a more efficient protocol than the Python one. In our integration example, we might break it up into ``pxd`` files like this: 1. Add a ``cmath.pxd`` function which defines the C functions available from the C ``math.h`` header file, like ``sin``. Then one would simply do ``from cmath cimport sin`` in ``integrate.pyx``. 2. Add a ``integrate.pxd`` so that other modules written in Cython can define fast custom functions to integrate. :: cdef class Function: cpdef evaluate(self, double x) cpdef integrate(Function f, double a, double b, int N) Note that if you have a cdef class with attributes, the attributes must be declared in the class declaration ``pxd`` file (if you use one), not the ``pyx`` file. The compiler will tell you about this. Cython-0.23.4/docs/src/tutorial/pure.rst0000644000175600017570000003016312606202452021276 0ustar jenkinsjenkins00000000000000 .. _pure-mode: Pure Python Mode ================ In some cases, it's desirable to speed up Python code without losing the ability to run it with the Python interpreter. While pure Python scripts can be compiled with Cython, it usually results only in a speed gain of about 20%-50%. To go beyond that, Cython provides language constructs to add static typing and cythonic functionalities to a Python module to make it run much faster when compiled, while still allowing it to be interpreted. This is accomplished either via an augmenting :file:`.pxd` file, or via special functions and decorators available after importing the magic ``cython`` module. Although it is not typically recommended over writing straight Cython code in a :file:`.pyx` file, there are legitimate reasons to do this - easier testing, collaboration with pure Python developers, etc. In pure mode, you are more or less restricted to code that can be expressed (or at least emulated) in Python, plus static type declarations. Anything beyond that can only be done in .pyx files with extended language syntax, because it depends on features of the Cython compiler. Augmenting .pxd --------------- Using an augmenting :file:`.pxd` allows to let the original :file:`.py` file completely untouched. On the other hand, one needs to maintain both the :file:`.pxd` and the :file:`.py` to keep them in sync. While declarations in a :file:`.pyx` file must correspond exactly with those of a :file:`.pxd` file with the same name (and any contradiction results in a compile time error, see :doc:`pxd_files`), the untyped definitions in a :file:`.py` file can be overridden and augmented with static types by the more specific ones present in a :file:`.pxd`. If a :file:`.pxd` file is found with the same name as the :file:`.py` file being compiled, it will be searched for :keyword:`cdef` classes and :keyword:`cdef`/:keyword:`cpdef` functions and methods. The compiler will then convert the corresponding classes/functions/methods in the :file:`.py` file to be of the declared type. Thus if one has a file :file:`A.py`:: def myfunction(x, y=2): a = x-y return a + x * y def _helper(a): return a + 1 class A: def __init__(self, b=0): self.a = 3 self.b = b def foo(self, x): print x + _helper(1.0) and adds :file:`A.pxd`:: cpdef int myfunction(int x, int y=*) cdef double _helper(double a) cdef class A: cdef public int a,b cpdef foo(self, double x) then Cython will compile the :file:`A.py` as if it had been written as follows:: cpdef int myfunction(int x, int y=2): a = x-y return a + x * y cdef double _helper(double a): return a + 1 cdef class A: cdef public int a,b def __init__(self, b=0): self.a = 3 self.b = b cpdef foo(self, double x): print x + _helper(1.0) Notice how in order to provide the Python wrappers to the definitions in the :file:`.pxd`, that is, to be accessible from Python, * Python visible function signatures must be declared as `cpdef` (with default arguments replaced by a `*` to avoid repetition):: cpdef int myfunction(int x, int y=*) * C function signatures of internal functions can be declared as `cdef`:: cdef double _helper(double a) * `cdef` classes (extension types) are declared as `cdef class`; * `cdef` class attributes must be declared as `cdef public` if read/write Python access is needed, `cdef readonly` for read-only Python access, or plain `cdef` for internal C level attributes; * `cdef` class methods must be declared as `cpdef` for Python visible methods or `cdef` for internal C methods. In the example above, the type of the local variable `a` in `myfunction()` is not fixed and will thus be a Python object. To statically type it, one can use Cython's ``@cython.locals`` decorator (see :ref:`magic_attributes`, and :ref:`magic_attributes_pxd`). Normal Python (:keyword:`def`) functions cannot be declared in :file:`.pxd` files. It is therefore currently impossible to override the types of plain Python functions in :file:`.pxd` files, e.g. to override types of their local variables. In most cases, declaring them as `cpdef` will work as expected. .. _magic_attributes: Magic Attributes ---------------- Special decorators are available from the magic ``cython`` module that can be used to add static typing within the Python file, while being ignored by the interpreter. This option adds the ``cython`` module dependency to the original code, but does not require to maintain a supplementary :file:`.pxd` file. Cython provides a fake version of this module as `Cython.Shadow`, which is available as `cython.py` when Cython is installed, but can be copied to be used by other modules when Cython is not installed. "Compiled" switch ^^^^^^^^^^^^^^^^^ * ``compiled`` is a special variable which is set to ``True`` when the compiler runs, and ``False`` in the interpreter. Thus, the code :: if cython.compiled: print("Yep, I'm compiled.") else: print("Just a lowly interpreted script.") will behave differently depending on whether or not the code is executed as a compiled extension (:file:`.so`/:file:`.pyd`) module or a plain :file:`.py` file. Static typing ^^^^^^^^^^^^^ * ``cython.declare`` declares a typed variable in the current scope, which can be used in place of the :samp:`cdef type var [= value]` construct. This has two forms, the first as an assignment (useful as it creates a declaration in interpreted mode as well):: x = cython.declare(cython.int) # cdef int x y = cython.declare(cython.double, 0.57721) # cdef double y = 0.57721 and the second mode as a simple function call:: cython.declare(x=cython.int, y=cython.double) # cdef int x; cdef double y It can also be used to type class constructors:: class A: cython.declare(a=cython.int, b=cython.int) def __init__(self, b=0): self.a = 3 self.b = b * ``@cython.locals`` is a decorator that is used to specify the types of local variables in the function body (including the arguments):: @cython.locals(a=cython.double, b=cython.double, n=cython.p_double) def foo(a, b, x, y): n = a*b ... * ``@cython.returns()`` specifies the function's return type. * Starting with Cython 0.21, Python signature annotations can be used to declare argument types. Cython recognises three ways to do this, as shown in the following example. Note that it currently needs to be enabled explicitly with the directive ``annotation_typing=True``. This might change in a later version. :: # cython: annotation_typing=True def func(plain_python_type: dict, named_python_type: 'dict', explicit_python_type: {'type': dict}, explicit_c_type: {'ctype': 'int'}): ... C types ^^^^^^^ There are numerous types built into the Cython module. It provides all the standard C types, namely ``char``, ``short``, ``int``, ``long``, ``longlong`` as well as their unsigned versions ``uchar``, ``ushort``, ``uint``, ``ulong``, ``ulonglong``. The special ``bint`` type is used for C boolean values and ``Py_ssize_t`` for (signed) sizes of Python containers. For each type, there are pointer types ``p_int``, ``pp_int``, etc., up to three levels deep in interpreted mode, and infinitely deep in compiled mode. Further pointer types can be constructed with ``cython.pointer(cython.int)``, and arrays as ``cython.int[10]``. A limited attempt is made to emulate these more complex types, but only so much can be done from the Python language. The Python types int, long and bool are interpreted as C ``int``, ``long`` and ``bint`` respectively. Also, the Python builtin types ``list``, ``dict``, ``tuple``, etc. may be used, as well as any user defined types. Extension types and cdef functions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * The class decorator ``@cython.cclass`` creates a ``cdef class``. * The function/method decorator ``@cython.cfunc`` creates a :keyword:`cdef` function. * ``@cython.ccall`` creates a :keyword:`cpdef` function, i.e. one that Cython code can call at the C level. * ``@cython.locals`` declares local variables (see above). It can also be used to declare types for arguments, i.e. the local variables that are used in the signature. * ``@cython.inline`` is the equivalent of the C ``inline`` modifier. Here is an example of a :keyword:`cdef` function:: @cython.cfunc @cython.returns(cython.bint) @cython.locals(a=cython.int, b=cython.int) def c_compare(a,b): return a == b Further Cython functions and declarations ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * ``address`` is used in place of the ``&`` operator:: cython.declare(x=cython.int, x_ptr=cython.p_int) x_ptr = cython.address(x) * ``sizeof`` emulates the `sizeof` operator. It can take both types and expressions. :: cython.declare(n=cython.longlong) print cython.sizeof(cython.longlong) print cython.sizeof(n) * ``struct`` can be used to create struct types.:: MyStruct = cython.struct(x=cython.int, y=cython.int, data=cython.double) a = cython.declare(MyStruct) is equivalent to the code:: cdef struct MyStruct: int x int y double data cdef MyStruct a * ``union`` creates union types with exactly the same syntax as ``struct``. * ``typedef`` defines a type under a given name:: T = cython.typedef(cython.p_int) # ctypedef int* T .. _magic_attributes_pxd: Magic Attributes within the .pxd ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The special `cython` module can also be imported and used within the augmenting :file:`.pxd` file. For example, the following Python file :file:`dostuff.py`:: def dostuff(n): t = 0 for i in range(n): t += i return t can be augmented with the following :file:`.pxd` file :file:`dostuff.pxd`:: import cython @cython.locals(t = cython.int, i = cython.int) cpdef int dostuff(int n) The :func:`cython.declare()` function can be used to specify types for global variables in the augmenting :file:`.pxd` file. Tips and Tricks --------------- Calling C functions ^^^^^^^^^^^^^^^^^^^ Normally, it isn't possible to call C functions in pure Python mode as there is no general way to support it in normal (uncompiled) Python. However, in cases where an equivalent Python function exists, this can be achieved by combining C function coercion with a conditional import as follows:: # in mymodule.pxd: # declare a C function as "cpdef" to export it to the module cdef extern from "math.h": cpdef double sin(double x) # in mymodule.py: import cython # override with Python import if not in compiled code if not cython.compiled: from math import sin # calls sin() from math.h when compiled with Cython and math.sin() in Python print(sin(0)) Note that the "sin" function will show up in the module namespace of "mymodule" here (i.e. there will be a ``mymodule.sin()`` function). You can mark it as an internal name according to Python conventions by renaming it to "_sin" in the ``.pxd`` file as follows:: cdef extern from "math.h": cpdef double _sin "sin" (double x) You would then also change the Python import to ``from math import sin as _sin`` to make the names match again. Using C arrays for fixed size lists ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Since Cython 0.22, C arrays can automatically coerce to Python lists or tuples. This can be exploited to replace fixed size Python lists in Python code by C arrays when compiled. An example:: import cython @cython.locals(counts=cython.int[10], digit=cython.int) def count_digits(digits): """ >>> digits = '01112222333334445667788899' >>> count_digits(map(int, digits)) [1, 3, 4, 5, 3, 1, 2, 2, 3, 2] """ counts = [0] * 10 for digit in digits: assert 0 <= digit <= 9 counts[digit] += 1 return counts In normal Python, this will use a Python list to collect the counts, whereas Cython will generate C code that uses a C array of C ints. Cython-0.23.4/docs/src/tutorial/profiling_tutorial.rst0000644000175600017570000003265212606202452024244 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _profiling: ********* Profiling ********* This part describes the profiling abilities of Cython. If you are familiar with profiling pure Python code, you can only read the first section (:ref:`profiling_basics`). If you are not familiar with Python profiling you should also read the tutorial (:ref:`profiling_tutorial`) which takes you through a complete example step by step. .. _profiling_basics: Cython Profiling Basics ======================= Profiling in Cython is controlled by a compiler directive. It can be set either for an entire file or on a per function basis via a Cython decorator. Enabling profiling for a complete source file --------------------------------------------- Profiling is enabled for a complete source file via a global directive to the Cython compiler at the top of a file:: # cython: profile=True Note that profiling gives a slight overhead to each function call therefore making your program a little slower (or a lot, if you call some small functions very often). Once enabled, your Cython code will behave just like Python code when called from the cProfile module. This means you can just profile your Cython code together with your Python code using the same tools as for Python code alone. Disabling profiling function wise --------------------------------- If your profiling is messed up because of the call overhead to some small functions that you rather do not want to see in your profile - either because you plan to inline them anyway or because you are sure that you can't make them any faster - you can use a special decorator to disable profiling for one function only:: cimport cython @cython.profile(False) def my_often_called_function(): pass Enabling line tracing --------------------- To get more detailed trace information (for tools that can make use of it), you can enable line tracing:: # cython: linetrace=True This will also enable profiling support, so the above ``profile=True`` option is not needed. Line tracing is needed for coverage analysis, for example. Note that even if line tracing is enabled via the compiler directive, it is not used by default. As the runtime slowdown can be substantial, it must additionally be compiled in by the C compiler by setting the C macro definition ``CYTHON_TRACE=1``. To include nogil functions in the trace, set ``CYTHON_TRACE_NOGIL=1`` (which implies ``CYTHON_TRACE=1``). C macros can be defined either in the extension definition of the ``setup.py`` script or by setting the respective distutils options in the source file with the following file header comment (if ``cythonize()`` is used for compilation):: # distutils: define_macros=CYTHON_TRACE_NOGIL=1 Enabling coverage analysis -------------------------- Since Cython 0.23, line tracing (see above) also enables support for coverage reporting with the `coverage.py `_ tool. To make the coverage analysis understand Cython modules, you also need to enable Cython's coverage plugin in your ``.coveragerc`` file as follows: .. code-block:: ini [run] plugins = Cython.Coverage With this plugin, your Cython source files should show up normally in the coverage reports. To include the coverage report in the Cython annotated HTML file, you need to first run the coverage.py tool to generate an XML result file. Pass this file into the ``cython`` command as follows: .. code-block:: bash $ cython --annotate-coverage coverage.xml package/mymodule.pyx This will recompile the Cython module and generate one HTML output file next to each Cython source file it processes, containing colour markers for lines that were contained in the coverage report. .. _profiling_tutorial: Profiling Tutorial ================== This will be a complete tutorial, start to finish, of profiling Python code, turning it into Cython code and keep profiling until it is fast enough. As a toy example, we would like to evaluate the summation of the reciprocals of squares up to a certain integer :math:`n` for evaluating :math:`\pi`. The relation we want to use has been proven by Euler in 1735 and is known as the `Basel problem `_. .. math:: \pi^2 = 6 \sum_{k=1}^{\infty} \frac{1}{k^2} = 6 \lim_{k \to \infty} \big( \frac{1}{1^2} + \frac{1}{2^2} + \dots + \frac{1}{k^2} \big) \approx 6 \big( \frac{1}{1^2} + \frac{1}{2^2} + \dots + \frac{1}{n^2} \big) A simple Python code for evaluating the truncated sum looks like this:: #!/usr/bin/env python # encoding: utf-8 # filename: calc_pi.py def recip_square(i): return 1./i**2 def approx_pi(n=10000000): val = 0. for k in range(1,n+1): val += recip_square(k) return (6 * val)**.5 On my box, this needs approximately 4 seconds to run the function with the default n. The higher we choose n, the better will be the approximation for :math:`\pi`. An experienced Python programmer will already see plenty of places to optimize this code. But remember the golden rule of optimization: Never optimize without having profiled. Let me repeat this: **Never** optimize without having profiled your code. Your thoughts about which part of your code takes too much time are wrong. At least, mine are always wrong. So let's write a short script to profile our code:: #!/usr/bin/env python # encoding: utf-8 # filename: profile.py import pstats, cProfile import calc_pi cProfile.runctx("calc_pi.approx_pi()", globals(), locals(), "Profile.prof") s = pstats.Stats("Profile.prof") s.strip_dirs().sort_stats("time").print_stats() Running this on my box gives the following output:: TODO: how to display this not as code but verbatimly? Sat Nov 7 17:40:54 2009 Profile.prof 10000004 function calls in 6.211 CPU seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 1 3.243 3.243 6.211 6.211 calc_pi.py:7(approx_pi) 10000000 2.526 0.000 2.526 0.000 calc_pi.py:4(recip_square) 1 0.442 0.442 0.442 0.442 {range} 1 0.000 0.000 6.211 6.211 :1() 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} This contains the information that the code runs in 6.2 CPU seconds. Note that the code got slower by 2 seconds because it ran inside the cProfile module. The table contains the real valuable information. You might want to check the Python `profiling documentation `_ for the nitty gritty details. The most important columns here are totime (total time spent in this function **not** counting functions that were called by this function) and cumtime (total time spent in this function **also** counting the functions called by this function). Looking at the tottime column, we see that approximately half the time is spent in approx_pi and the other half is spent in recip_square. Also half a second is spent in range ... of course we should have used xrange for such a big iteration. And in fact, just changing range to xrange makes the code run in 5.8 seconds. We could optimize a lot in the pure Python version, but since we are interested in Cython, let's move forward and bring this module to Cython. We would do this anyway at some time to get the loop run faster. Here is our first Cython version:: # encoding: utf-8 # cython: profile=True # filename: calc_pi.pyx def recip_square(int i): return 1./i**2 def approx_pi(int n=10000000): cdef double val = 0. cdef int k for k in xrange(1,n+1): val += recip_square(k) return (6 * val)**.5 Note the second line: We have to tell Cython that profiling should be enabled. This makes the Cython code slightly slower, but without this we would not get meaningful output from the cProfile module. The rest of the code is mostly unchanged, I only typed some variables which will likely speed things up a bit. We also need to modify our profiling script to import the Cython module directly. Here is the complete version adding the import of the pyximport module:: #!/usr/bin/env python # encoding: utf-8 # filename: profile.py import pstats, cProfile import pyximport pyximport.install() import calc_pi cProfile.runctx("calc_pi.approx_pi()", globals(), locals(), "Profile.prof") s = pstats.Stats("Profile.prof") s.strip_dirs().sort_stats("time").print_stats() We only added two lines, the rest stays completely the same. Alternatively, we could also manually compile our code into an extension; we wouldn't need to change the profile script then at all. The script now outputs the following:: Sat Nov 7 18:02:33 2009 Profile.prof 10000004 function calls in 4.406 CPU seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 1 3.305 3.305 4.406 4.406 calc_pi.pyx:7(approx_pi) 10000000 1.101 0.000 1.101 0.000 calc_pi.pyx:4(recip_square) 1 0.000 0.000 4.406 4.406 {calc_pi.approx_pi} 1 0.000 0.000 4.406 4.406 :1() 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} We gained 1.8 seconds. Not too shabby. Comparing the output to the previous, we see that recip_square function got faster while the approx_pi function has not changed a lot. Let's concentrate on the recip_square function a bit more. First note, that this function is not to be called from code outside of our module; so it would be wise to turn it into a cdef to reduce call overhead. We should also get rid of the power operator: it is turned into a pow(i,2) function call by Cython, but we could instead just write i*i which could be faster. The whole function is also a good candidate for inlining. Let's look at the necessary changes for these ideas:: # encoding: utf-8 # cython: profile=True # filename: calc_pi.pyx cdef inline double recip_square(int i): return 1./(i*i) def approx_pi(int n=10000000): cdef double val = 0. cdef int k for k in xrange(1,n+1): val += recip_square(k) return (6 * val)**.5 Now running the profile script yields:: Sat Nov 7 18:10:11 2009 Profile.prof 10000004 function calls in 2.622 CPU seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 1 1.782 1.782 2.622 2.622 calc_pi.pyx:7(approx_pi) 10000000 0.840 0.000 0.840 0.000 calc_pi.pyx:4(recip_square) 1 0.000 0.000 2.622 2.622 {calc_pi.approx_pi} 1 0.000 0.000 2.622 2.622 :1() 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} That bought us another 1.8 seconds. Not the dramatic change we could have expected. And why is recip_square still in this table; it is supposed to be inlined, isn't it? The reason for this is that Cython still generates profiling code even if the function call is eliminated. Let's tell it to not profile recip_square any more; we couldn't get the function to be much faster anyway:: # encoding: utf-8 # cython: profile=True # filename: calc_pi.pyx cimport cython @cython.profile(False) cdef inline double recip_square(int i): return 1./(i*i) def approx_pi(int n=10000000): cdef double val = 0. cdef int k for k in xrange(1,n+1): val += recip_square(k) return (6 * val)**.5 Running this shows an interesting result:: Sat Nov 7 18:15:02 2009 Profile.prof 4 function calls in 0.089 CPU seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 1 0.089 0.089 0.089 0.089 calc_pi.pyx:10(approx_pi) 1 0.000 0.000 0.089 0.089 {calc_pi.approx_pi} 1 0.000 0.000 0.089 0.089 :1() 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} First note the tremendous speed gain: this version only takes 1/50 of the time of our first Cython version. Also note that recip_square has vanished from the table like we wanted. But the most peculiar and import change is that approx_pi also got much faster. This is a problem with all profiling: calling a function in a profile run adds a certain overhead to the function call. This overhead is **not** added to the time spent in the called function, but to the time spent in the **calling** function. In this example, approx_pi didn't need 2.622 seconds in the last run; but it called recip_square 10000000 times, each time taking a little to set up profiling for it. This adds up to the massive time loss of around 2.6 seconds. Having disabled profiling for the often called function now reveals realistic timings for approx_pi; we could continue optimizing it now if needed. This concludes this profiling tutorial. There is still some room for improvement in this code. We could try to replace the power operator in approx_pi with a call to sqrt from the C stdlib; but this is not necessarily faster than calling pow(x,0.5). Even so, the result we achieved here is quite satisfactory: we came up with a solution that is much faster then our original Python version while retaining functionality and readability. Cython-0.23.4/docs/src/tutorial/numpy.rst0000644000175600017570000003205712606202452021477 0ustar jenkinsjenkins00000000000000======================= Working with NumPy ======================= You can use NumPy from Cython exactly the same as in regular Python, but by doing so you are losing potentially high speedups because Cython has support for fast access to NumPy arrays. Let's see how this works with a simple example. The code below does 2D discrete convolution of an image with a filter (and I'm sure you can do better!, let it serve for demonstration purposes). It is both valid Python and valid Cython code. I'll refer to it as both :file:`convolve_py.py` for the Python version and :file:`convolve1.pyx` for the Cython version -- Cython uses ".pyx" as its file suffix. .. code-block:: python from __future__ import division import numpy as np def naive_convolve(f, g): # f is an image and is indexed by (v, w) # g is a filter kernel and is indexed by (s, t), # it needs odd dimensions # h is the output image and is indexed by (x, y), # it is not cropped if g.shape[0] % 2 != 1 or g.shape[1] % 2 != 1: raise ValueError("Only odd dimensions on filter supported") # smid and tmid are number of pixels between the center pixel # and the edge, ie for a 5x5 filter they will be 2. # # The output size is calculated by adding smid, tmid to each # side of the dimensions of the input image. vmax = f.shape[0] wmax = f.shape[1] smax = g.shape[0] tmax = g.shape[1] smid = smax // 2 tmid = tmax // 2 xmax = vmax + 2*smid ymax = wmax + 2*tmid # Allocate result image. h = np.zeros([xmax, ymax], dtype=f.dtype) # Do convolution for x in range(xmax): for y in range(ymax): # Calculate pixel value for h at (x,y). Sum one component # for each pixel (s, t) of the filter g. s_from = max(smid - x, -smid) s_to = min((xmax - x) - smid, smid + 1) t_from = max(tmid - y, -tmid) t_to = min((ymax - y) - tmid, tmid + 1) value = 0 for s in range(s_from, s_to): for t in range(t_from, t_to): v = x - smid + s w = y - tmid + t value += g[smid - s, tmid - t] * f[v, w] h[x, y] = value return h This should be compiled to produce :file:`yourmod.so` (for Linux systems). We run a Python session to test both the Python version (imported from ``.py``-file) and the compiled Cython module. .. sourcecode:: ipython In [1]: import numpy as np In [2]: import convolve_py In [3]: convolve_py.naive_convolve(np.array([[1, 1, 1]], dtype=np.int), ... np.array([[1],[2],[1]], dtype=np.int)) Out [3]: array([[1, 1, 1], [2, 2, 2], [1, 1, 1]]) In [4]: import convolve1 In [4]: convolve1.naive_convolve(np.array([[1, 1, 1]], dtype=np.int), ... np.array([[1],[2],[1]], dtype=np.int)) Out [4]: array([[1, 1, 1], [2, 2, 2], [1, 1, 1]]) In [11]: N = 100 In [12]: f = np.arange(N*N, dtype=np.int).reshape((N,N)) In [13]: g = np.arange(81, dtype=np.int).reshape((9, 9)) In [19]: %timeit -n2 -r3 convolve_py.naive_convolve(f, g) 2 loops, best of 3: 1.86 s per loop In [20]: %timeit -n2 -r3 convolve1.naive_convolve(f, g) 2 loops, best of 3: 1.41 s per loop There's not such a huge difference yet; because the C code still does exactly what the Python interpreter does (meaning, for instance, that a new object is allocated for each number used). Look at the generated html file and see what is needed for even the simplest statements you get the point quickly. We need to give Cython more information; we need to add types. Adding types ============= To add types we use custom Cython syntax, so we are now breaking Python source compatibility. Consider this code (*read the comments!*) :: from __future__ import division import numpy as np # "cimport" is used to import special compile-time information # about the numpy module (this is stored in a file numpy.pxd which is # currently part of the Cython distribution). cimport numpy as np # We now need to fix a datatype for our arrays. I've used the variable # DTYPE for this, which is assigned to the usual NumPy runtime # type info object. DTYPE = np.int # "ctypedef" assigns a corresponding compile-time type to DTYPE_t. For # every type in the numpy module there's a corresponding compile-time # type with a _t-suffix. ctypedef np.int_t DTYPE_t # "def" can type its arguments but not have a return type. The type of the # arguments for a "def" function is checked at run-time when entering the # function. # # The arrays f, g and h is typed as "np.ndarray" instances. The only effect # this has is to a) insert checks that the function arguments really are # NumPy arrays, and b) make some attribute access like f.shape[0] much # more efficient. (In this example this doesn't matter though.) def naive_convolve(np.ndarray f, np.ndarray g): if g.shape[0] % 2 != 1 or g.shape[1] % 2 != 1: raise ValueError("Only odd dimensions on filter supported") assert f.dtype == DTYPE and g.dtype == DTYPE # The "cdef" keyword is also used within functions to type variables. It # can only be used at the top indendation level (there are non-trivial # problems with allowing them in other places, though we'd love to see # good and thought out proposals for it). # # For the indices, the "int" type is used. This corresponds to a C int, # other C types (like "unsigned int") could have been used instead. # Purists could use "Py_ssize_t" which is the proper Python type for # array indices. cdef int vmax = f.shape[0] cdef int wmax = f.shape[1] cdef int smax = g.shape[0] cdef int tmax = g.shape[1] cdef int smid = smax // 2 cdef int tmid = tmax // 2 cdef int xmax = vmax + 2*smid cdef int ymax = wmax + 2*tmid cdef np.ndarray h = np.zeros([xmax, ymax], dtype=DTYPE) cdef int x, y, s, t, v, w # It is very important to type ALL your variables. You do not get any # warnings if not, only much slower code (they are implicitly typed as # Python objects). cdef int s_from, s_to, t_from, t_to # For the value variable, we want to use the same data type as is # stored in the array, so we use "DTYPE_t" as defined above. # NB! An important side-effect of this is that if "value" overflows its # datatype size, it will simply wrap around like in C, rather than raise # an error like in Python. cdef DTYPE_t value for x in range(xmax): for y in range(ymax): s_from = max(smid - x, -smid) s_to = min((xmax - x) - smid, smid + 1) t_from = max(tmid - y, -tmid) t_to = min((ymax - y) - tmid, tmid + 1) value = 0 for s in range(s_from, s_to): for t in range(t_from, t_to): v = x - smid + s w = y - tmid + t value += g[smid - s, tmid - t] * f[v, w] h[x, y] = value return h After building this and continuing my (very informal) benchmarks, I get: .. sourcecode:: ipython In [21]: import convolve2 In [22]: %timeit -n2 -r3 convolve2.naive_convolve(f, g) 2 loops, best of 3: 828 ms per loop Efficient indexing ==================== There's still a bottleneck killing performance, and that is the array lookups and assignments. The ``[]``-operator still uses full Python operations -- what we would like to do instead is to access the data buffer directly at C speed. What we need to do then is to type the contents of the :obj:`ndarray` objects. We do this with a special "buffer" syntax which must be told the datatype (first argument) and number of dimensions ("ndim" keyword-only argument, if not provided then one-dimensional is assumed). These are the needed changes:: ... def naive_convolve(np.ndarray[DTYPE_t, ndim=2] f, np.ndarray[DTYPE_t, ndim=2] g): ... cdef np.ndarray[DTYPE_t, ndim=2] h = ... Usage: .. sourcecode:: ipython In [18]: import convolve3 In [19]: %timeit -n3 -r100 convolve3.naive_convolve(f, g) 3 loops, best of 100: 11.6 ms per loop Note the importance of this change. *Gotcha*: This efficient indexing only affects certain index operations, namely those with exactly ``ndim`` number of typed integer indices. So if ``v`` for instance isn't typed, then the lookup ``f[v, w]`` isn't optimized. On the other hand this means that you can continue using Python objects for sophisticated dynamic slicing etc. just as when the array is not typed. Tuning indexing further ======================== The array lookups are still slowed down by two factors: 1. Bounds checking is performed. 2. Negative indices are checked for and handled correctly. The code above is explicitly coded so that it doesn't use negative indices, and it (hopefully) always access within bounds. We can add a decorator to disable bounds checking:: ... cimport cython @cython.boundscheck(False) # turn of bounds-checking for entire function def naive_convolve(np.ndarray[DTYPE_t, ndim=2] f, np.ndarray[DTYPE_t, ndim=2] g): ... Now bounds checking is not performed (and, as a side-effect, if you ''do'' happen to access out of bounds you will in the best case crash your program and in the worst case corrupt data). It is possible to switch bounds-checking mode in many ways, see :ref:`compiler-directives` for more information. Negative indices are dealt with by ensuring Cython that the indices will be positive, by casting the variables to unsigned integer types (if you do have negative values, then this casting will create a very large positive value instead and you will attempt to access out-of-bounds values). Casting is done with a special ``<>``-syntax. The code below is changed to use either unsigned ints or casting as appropriate:: ... cdef int s, t # changed cdef unsigned int x, y, v, w # changed cdef int s_from, s_to, t_from, t_to cdef DTYPE_t value for x in range(xmax): for y in range(ymax): s_from = max(smid - x, -smid) s_to = min((xmax - x) - smid, smid + 1) t_from = max(tmid - y, -tmid) t_to = min((ymax - y) - tmid, tmid + 1) value = 0 for s in range(s_from, s_to): for t in range(t_from, t_to): v = (x - smid + s) # changed w = (y - tmid + t) # changed value += g[(smid - s), (tmid - t)] * f[v, w] # changed h[x, y] = value ... The function call overhead now starts to play a role, so we compare the latter two examples with larger N: .. sourcecode:: ipython In [11]: %timeit -n3 -r100 convolve4.naive_convolve(f, g) 3 loops, best of 100: 5.97 ms per loop In [12]: N = 1000 In [13]: f = np.arange(N*N, dtype=np.int).reshape((N,N)) In [14]: g = np.arange(81, dtype=np.int).reshape((9, 9)) In [17]: %timeit -n1 -r10 convolve3.naive_convolve(f, g) 1 loops, best of 10: 1.16 s per loop In [18]: %timeit -n1 -r10 convolve4.naive_convolve(f, g) 1 loops, best of 10: 597 ms per loop (Also this is a mixed benchmark as the result array is allocated within the function call.) .. Warning:: Speed comes with some cost. Especially it can be dangerous to set typed objects (like ``f``, ``g`` and ``h`` in our sample code) to ``None``. Setting such objects to ``None`` is entirely legal, but all you can do with them is check whether they are None. All other use (attribute lookup or indexing) can potentially segfault or corrupt data (rather than raising exceptions as they would in Python). The actual rules are a bit more complicated but the main message is clear: Do not use typed objects without knowing that they are not set to None. More generic code ================== It would be possible to do:: def naive_convolve(object[DTYPE_t, ndim=2] f, ...): i.e. use :obj:`object` rather than :obj:`np.ndarray`. Under Python 3.0 this can allow your algorithm to work with any libraries supporting the buffer interface; and support for e.g. the Python Imaging Library may easily be added if someone is interested also under Python 2.x. There is some speed penalty to this though (as one makes more assumptions compile-time if the type is set to :obj:`np.ndarray`, specifically it is assumed that the data is stored in pure strided mode and not in indirect mode). Cython-0.23.4/docs/src/tutorial/memory_allocation.rst0000644000175600017570000001022012606202452024030 0ustar jenkinsjenkins00000000000000.. _memory_allocation: ***************** Memory Allocation ***************** Dynamic memory allocation is mostly a non-issue in Python. Everything is an object, and the reference counting system and garbage collector automatically return memory to the system when it is no longer being used. When it comes to more low-level data buffers, Cython has special support for (multi-dimensional) arrays of simple types via NumPy, memory views or Python's stdlib array type. They are full featured, garbage collected and much easier to work with than bare pointers in C, while still retaining the speed and static typing benefits. See :ref:`array-array` and :ref:`memoryviews`. In some situations, however, these objects can still incur an unacceptable amount of overhead, which can then makes a case for doing manual memory management in C. Simple C values and structs (such as a local variable ``cdef double x``) are usually allocated on the stack and passed by value, but for larger and more complicated objects (e.g. a dynamically-sized list of doubles), the memory must be manually requested and released. C provides the functions :c:func:`malloc`, :c:func:`realloc`, and :c:func:`free` for this purpose, which can be imported in cython from ``clibc.stdlib``. Their signatures are: .. code-block:: c void* malloc(size_t size) void* realloc(void* ptr, size_t size) void free(void* ptr) A very simple example of malloc usage is the following:: import random from libc.stdlib cimport malloc, free def random_noise(int number=1): cdef int i # allocate number * sizeof(double) bytes of memory cdef double *my_array = malloc(number * sizeof(double)) if not my_array: raise MemoryError() try: ran = random.normalvariate for i in range(number): my_array[i] = ran(0,1) return [ my_array[i] for i in range(number) ] finally: # return the previously allocated memory to the system free(my_array) Note that the C-API functions for allocating memory on the Python heap are generally preferred over the low-level C functions above as the memory they provide is actually accounted for in Python's internal memory management system. They also have special optimisations for smaller memory blocks, which speeds up their allocation by avoiding costly operating system calls. The C-API functions can be found in the ``cpython.mem`` standard declarations file:: from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free Their interface and usage is identical to that of the corresponding low-level C functions. One important thing to remember is that blocks of memory obtained with :c:func:`malloc` or :c:func:`PyMem_Malloc` *must* be manually released with a corresponding call to :c:func:`free` or :c:func:`PyMem_Free` when they are no longer used (and *must* always use the matching type of free function). Otherwise, they won't be reclaimed until the python process exits. This is called a memory leak. If a chunk of memory needs a larger lifetime than can be managed by a ``try..finally`` block, another helpful idiom is to tie its lifetime to a Python object to leverage the Python runtime's memory management, e.g.:: cdef class SomeMemory: cdef double* data def __cinit__(self, size_t number): # allocate some memory (uninitialised, may contain arbitrary data) self.data = PyMem_Malloc(number * sizeof(double)) if not self.data: raise MemoryError() def resize(self, size_t new_number): # Allocates new_number * sizeof(double) bytes, # preserving the current content and making a best-effort to # re-use the original data location. mem = PyMem_Realloc(self.data, new_number * sizeof(double)) if not mem: raise MemoryError() # Only overwrite the pointer if the memory was really reallocated. # On error (mem is NULL), the originally memory has not been freed. self.data = mem def __dealloc__(self): PyMem_Free(self.data) # no-op if self.data is NULL Cython-0.23.4/docs/src/tutorial/index.rst0000644000175600017570000000040112606202452021422 0ustar jenkinsjenkins00000000000000Tutorials ========= .. toctree:: :maxdepth: 2 cython_tutorial external clibraries cdef_classes pxd_files caveats profiling_tutorial strings memory_allocation pure numpy array readings related_work appendix Cython-0.23.4/docs/src/tutorial/external.rst0000644000175600017570000001161612606202452022147 0ustar jenkinsjenkins00000000000000Calling C functions ==================== This tutorial describes shortly what you need to know in order to call C library functions from Cython code. For a longer and more comprehensive tutorial about using external C libraries, wrapping them and handling errors, see :doc:`clibraries`. For simplicity, let's start with a function from the standard C library. This does not add any dependencies to your code, and it has the additional advantage that Cython already defines many such functions for you. So you can just cimport and use them. For example, let's say you need a low-level way to parse a number from a ``char*`` value. You could use the ``atoi()`` function, as defined by the ``stdlib.h`` header file. This can be done as follows:: from libc.stdlib cimport atoi cdef parse_charptr_to_py_int(char* s): assert s is not NULL, "byte string value is NULL" return atoi(s) # note: atoi() has no error detection! You can find a complete list of these standard cimport files in Cython's source package `Cython/Includes/ `_. They are stored in ``.pxd`` files, the standard way to provide reusable Cython declarations that can be shared across modules (see :ref:`sharing-declarations`). Cython also has a complete set of declarations for CPython's C-API. For example, to test at C compilation time which CPython version your code is being compiled with, you can do this:: from cpython.version cimport PY_VERSION_HEX # Python version >= 3.2 final ? print PY_VERSION_HEX >= 0x030200F0 Cython also provides declarations for the C math library:: from libc.math cimport sin cdef double f(double x): return sin(x*x) Dynamic linking --------------- The libc math library is special in that it is not linked by default on some Unix-like systems, such as Linux. In addition to cimporting the declarations, you must configure your build system to link against the shared library ``m``. For distutils, it is enough to add it to the ``libraries`` parameter of the ``Extension()`` setup:: from distutils.core import setup from distutils.extension import Extension from Cython.Build import cythonize ext_modules=[ Extension("demo", sources=["demo.pyx"], libraries=["m"] # Unix-like specific ) ] setup( name = "Demos", ext_modules = cythonize(ext_modules) ) External declarations --------------------- If you want to access C code for which Cython does not provide a ready to use declaration, you must declare them yourself. For example, the above ``sin()`` function is defined as follows:: cdef extern from "math.h": double sin(double x) This declares the ``sin()`` function in a way that makes it available to Cython code and instructs Cython to generate C code that includes the ``math.h`` header file. The C compiler will see the original declaration in ``math.h`` at compile time, but Cython does not parse "math.h" and requires a separate definition. Just like the ``sin()`` function from the math library, it is possible to declare and call into any C library as long as the module that Cython generates is properly linked against the shared or static library. Note that you can easily export an external C function from your Cython module by declaring it as ``cpdef``. This generates a Python wrapper for it and adds it to the module dict. Here is a Cython module that provides direct access to the C ``sin()`` function for Python code:: """ >>> sin(0) 0.0 """ cdef extern from "math.h": cpdef double sin(double x) You get the same result when this declaration appears in the ``.pxd`` file that belongs to the Cython module (i.e. that has the same name, see :ref:`sharing-declarations`). This allows the C declaration to be reused in other Cython modules, while still providing an automatically generated Python wrapper in this specific module. Naming parameters ----------------- Both C and Cython support signature declarations without parameter names like this:: cdef extern from "string.h": char* strstr(const char*, const char*) However, this prevents Cython code from calling it with keyword arguments (supported since Cython 0.19). It is therefore preferable to write the declaration like this instead:: cdef extern from "string.h": char* strstr(const char *haystack, const char *needle) You can now make it clear which of the two arguments does what in your call, thus avoiding any ambiguities and often making your code more readable:: cdef char* data = "hfvcakdfagbcffvschvxcdfgccbcfhvgcsnfxjh" pos = strstr(needle='akd', haystack=data) print pos != NULL Note that changing existing parameter names later is a backwards incompatible API modification, just as for Python code. Thus, if you provide your own declarations for external C or C++ functions, it is usually worth the additional bit of effort to choose the names of their arguments well. Cython-0.23.4/docs/src/tutorial/data.py0000644000175600017570000000312012606202452021045 0ustar jenkinsjenkins00000000000000{ 'title': 'Cython Tutorial', 'paper_abstract': ''' Cython is a programming language based on Python with extra syntax to provide static type declarations. This takes advantage of the benefits of Python while allowing one to achieve the speed of C. In this paper we describe the Cython language and show how it can be used both to write optimized code and to interface with external C libraries. ''', 'authors': [ {'first_names': 'Stefan', 'surname': 'Behnel', 'address': '', 'country': 'Germany', 'email_address': 'stefan\_ml@behnel.de', 'institution': ''}, {'first_names': 'Robert W.', 'surname': 'Bradshaw', 'address': '', 'country': 'USA', 'email_address': 'robertwb@math.washington.edu', 'institution': '''University of Washington\\footnote{ Department of Mathematics, University of Washington, Seattle, WA, USA }'''}, {'first_names': 'Dag Sverre', 'surname': 'Seljebotn', 'address': '', 'country': 'Norway', 'email_address': 'dagss@student.matnat.uio.no', # I need three institutions w/ full address... leave it # all here until we get to editing stage 'institution': '''University of Oslo\\footnote{Institute of Theoretical Astrophysics, University of Oslo, P.O. Box 1029 Blindern, N-0315 Oslo, Norway}\\footnote{Department of Mathematics, University of Oslo, P.O. Box 1053 Blindern, N-0316 Oslo, Norway}\\footnote{Centre of Mathematics for Applications, University of Oslo, P.O. Box 1053 Blindern, N-0316 Oslo, Norway}'''} ], } Cython-0.23.4/docs/src/tutorial/cython_tutorial.rst0000644000175600017570000001426212606202452023554 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _tutorial: ************** Basic Tutorial ************** The Basics of Cython ==================== The fundamental nature of Cython can be summed up as follows: Cython is Python with C data types. Cython is Python: Almost any piece of Python code is also valid Cython code. (There are a few :ref:`cython-limitations`, but this approximation will serve for now.) The Cython compiler will convert it into C code which makes equivalent calls to the Python/C API. But Cython is much more than that, because parameters and variables can be declared to have C data types. Code which manipulates Python values and C values can be freely intermixed, with conversions occurring automatically wherever possible. Reference count maintenance and error checking of Python operations is also automatic, and the full power of Python's exception handling facilities, including the try-except and try-finally statements, is available to you -- even in the midst of manipulating C data. Cython Hello World =================== As Cython can accept almost any valid python source file, one of the hardest things in getting started is just figuring out how to compile your extension. So lets start with the canonical python hello world:: print "Hello World" Save this code in a file named :file:`helloworld.pyx`. Now we need to create the :file:`setup.py`, which is like a python Makefile (for more information see :ref:`compilation`). Your :file:`setup.py` should look like:: from distutils.core import setup from Cython.Build import cythonize setup( ext_modules = cythonize("helloworld.pyx") ) To use this to build your Cython file use the commandline options: .. sourcecode:: text $ python setup.py build_ext --inplace Which will leave a file in your local directory called :file:`helloworld.so` in unix or :file:`helloworld.pyd` in Windows. Now to use this file: start the python interpreter and simply import it as if it was a regular python module:: >>> import helloworld Hello World Congratulations! You now know how to build a Cython extension. But so far this example doesn't really give a feeling why one would ever want to use Cython, so lets create a more realistic example. :mod:`pyximport`: Cython Compilation the Easy Way ================================================== If your module doesn't require any extra C libraries or a special build setup, then you can use the pyximport module by Paul Prescod and Stefan Behnel to load .pyx files directly on import, without having to write a :file:`setup.py` file. It is shipped and installed with Cython and can be used like this:: >>> import pyximport; pyximport.install() >>> import helloworld Hello World Since Cython 0.11, the :mod:`pyximport` module also has experimental compilation support for normal Python modules. This allows you to automatically run Cython on every .pyx and .py module that Python imports, including the standard library and installed packages. Cython will still fail to compile a lot of Python modules, in which case the import mechanism will fall back to loading the Python source modules instead. The .py import mechanism is installed like this:: >>> pyximport.install(pyimport = True) Fibonacci Fun ============== From the official Python tutorial a simple fibonacci function is defined as: .. literalinclude:: ../../examples/tutorial/fib1/fib.pyx Now following the steps for the Hello World example we first rename the file to have a `.pyx` extension, lets say :file:`fib.pyx`, then we create the :file:`setup.py` file. Using the file created for the Hello World example, all that you need to change is the name of the Cython filename, and the resulting module name, doing this we have: .. literalinclude:: ../../examples/tutorial/fib1/setup.py Build the extension with the same command used for the helloworld.pyx: .. sourcecode:: text $ python setup.py build_ext --inplace And use the new extension with:: >>> import fib >>> fib.fib(2000) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 Primes ======= Here's a small example showing some of what can be done. It's a routine for finding prime numbers. You tell it how many primes you want, and it returns them as a Python list. :file:`primes.pyx`: .. literalinclude:: ../../examples/tutorial/primes/primes.pyx :linenos: You'll see that it starts out just like a normal Python function definition, except that the parameter ``kmax`` is declared to be of type ``int`` . This means that the object passed will be converted to a C integer (or a ``TypeError.`` will be raised if it can't be). Lines 2 and 3 use the ``cdef`` statement to define some local C variables. Line 4 creates a Python list which will be used to return the result. You'll notice that this is done exactly the same way it would be in Python. Because the variable result hasn't been given a type, it is assumed to hold a Python object. Lines 7-9 set up for a loop which will test candidate numbers for primeness until the required number of primes has been found. Lines 11-12, which try dividing a candidate by all the primes found so far, are of particular interest. Because no Python objects are referred to, the loop is translated entirely into C code, and thus runs very fast. When a prime is found, lines 14-15 add it to the p array for fast access by the testing loop, and line 16 adds it to the result list. Again, you'll notice that line 16 looks very much like a Python statement, and in fact it is, with the twist that the C parameter ``n`` is automatically converted to a Python object before being passed to the append method. Finally, at line 18, a normal Python return statement returns the result list. Compiling primes.pyx with the Cython compiler produces an extension module which we can try out in the interactive interpreter as follows:: >>> import primes >>> primes.primes(10) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] See, it works! And if you're curious about how much work Cython has saved you, take a look at the C code generated for this module. Language Details ================ For more about the Cython language, see :ref:`language-basics`. To dive right in to using Cython in a numerical computation context, see :ref:`numpy_tutorial`. Cython-0.23.4/docs/src/tutorial/clibraries.rst0000644000175600017570000005725612606202452022456 0ustar jenkinsjenkins00000000000000Using C libraries ================= Apart from writing fast code, one of the main use cases of Cython is to call external C libraries from Python code. As Cython code compiles down to C code itself, it is actually trivial to call C functions directly in the code. The following gives a complete example for using (and wrapping) an external C library in Cython code, including appropriate error handling and considerations about designing a suitable API for Python and Cython code. Imagine you need an efficient way to store integer values in a FIFO queue. Since memory really matters, and the values are actually coming from C code, you cannot afford to create and store Python ``int`` objects in a list or deque. So you look out for a queue implementation in C. After some web search, you find the C-algorithms library [CAlg]_ and decide to use its double ended queue implementation. To make the handling easier, however, you decide to wrap it in a Python extension type that can encapsulate all memory management. .. [CAlg] Simon Howard, C Algorithms library, http://c-algorithms.sourceforge.net/ Defining external declarations ------------------------------ The C API of the queue implementation, which is defined in the header file ``libcalg/queue.h``, essentially looks like this:: /* file: queue.h */ typedef struct _Queue Queue; typedef void *QueueValue; Queue *queue_new(void); void queue_free(Queue *queue); int queue_push_head(Queue *queue, QueueValue data); QueueValue queue_pop_head(Queue *queue); QueueValue queue_peek_head(Queue *queue); int queue_push_tail(Queue *queue, QueueValue data); QueueValue queue_pop_tail(Queue *queue); QueueValue queue_peek_tail(Queue *queue); int queue_is_empty(Queue *queue); To get started, the first step is to redefine the C API in a ``.pxd`` file, say, ``cqueue.pxd``:: # file: cqueue.pxd cdef extern from "libcalg/queue.h": ctypedef struct Queue: pass ctypedef void* QueueValue Queue* queue_new() void queue_free(Queue* queue) int queue_push_head(Queue* queue, QueueValue data) QueueValue queue_pop_head(Queue* queue) QueueValue queue_peek_head(Queue* queue) int queue_push_tail(Queue* queue, QueueValue data) QueueValue queue_pop_tail(Queue* queue) QueueValue queue_peek_tail(Queue* queue) bint queue_is_empty(Queue* queue) Note how these declarations are almost identical to the header file declarations, so you can often just copy them over. However, you do not need to provide *all* declarations as above, just those that you use in your code or in other declarations, so that Cython gets to see a sufficient and consistent subset of them. Then, consider adapting them somewhat to make them more comfortable to work with in Cython. Specifically, you should take care of choosing good argument names for the C functions, as Cython allows you to pass them as keyword arguments. Changing them later on is a backwards incompatible API modification. Choosing good names right away will make these functions more pleasant to work with from Cython code. One noteworthy difference to the header file that we use above is the declaration of the ``Queue`` struct in the first line. ``Queue`` is in this case used as an *opaque handle*; only the library that is called knows what is really inside. Since no Cython code needs to know the contents of the struct, we do not need to declare its contents, so we simply provide an empty definition (as we do not want to declare the ``_Queue`` type which is referenced in the C header) [#]_. .. [#] There's a subtle difference between ``cdef struct Queue: pass`` and ``ctypedef struct Queue: pass``. The former declares a type which is referenced in C code as ``struct Queue``, while the latter is referenced in C as ``Queue``. This is a C language quirk that Cython is not able to hide. Most modern C libraries use the ``ctypedef`` kind of struct. Another exception is the last line. The integer return value of the ``queue_is_empty()`` function is actually a C boolean value, i.e. the only interesting thing about it is whether it is non-zero or zero, indicating if the queue is empty or not. This is best expressed by Cython's ``bint`` type, which is a normal ``int`` type when used in C but maps to Python's boolean values ``True`` and ``False`` when converted to a Python object. This way of tightening declarations in a ``.pxd`` file can often simplify the code that uses them. It is good practice to define one ``.pxd`` file for each library that you use, and sometimes even for each header file (or functional group) if the API is large. That simplifies their reuse in other projects. Sometimes, you may need to use C functions from the standard C library, or want to call C-API functions from CPython directly. For common needs like this, Cython ships with a set of standard ``.pxd`` files that provide these declarations in a readily usable way that is adapted to their use in Cython. The main packages are ``cpython``, ``libc`` and ``libcpp``. The NumPy library also has a standard ``.pxd`` file ``numpy``, as it is often used in Cython code. See Cython's ``Cython/Includes/`` source package for a complete list of provided ``.pxd`` files. Writing a wrapper class ----------------------- After declaring our C library's API, we can start to design the Queue class that should wrap the C queue. It will live in a file called ``queue.pyx``. [#]_ .. [#] Note that the name of the ``.pyx`` file must be different from the ``cqueue.pxd`` file with declarations from the C library, as both do not describe the same code. A ``.pxd`` file next to a ``.pyx`` file with the same name defines exported declarations for code in the ``.pyx`` file. As the ``cqueue.pxd`` file contains declarations of a regular C library, there must not be a ``.pyx`` file with the same name that Cython associates with it. Here is a first start for the Queue class:: # file: queue.pyx cimport cqueue cdef class Queue: cdef cqueue.Queue* _c_queue def __cinit__(self): self._c_queue = cqueue.queue_new() Note that it says ``__cinit__`` rather than ``__init__``. While ``__init__`` is available as well, it is not guaranteed to be run (for instance, one could create a subclass and forget to call the ancestor's constructor). Because not initializing C pointers often leads to hard crashes of the Python interpreter, Cython provides ``__cinit__`` which is *always* called immediately on construction, before CPython even considers calling ``__init__``, and which therefore is the right place to initialise ``cdef`` fields of the new instance. However, as ``__cinit__`` is called during object construction, ``self`` is not fully constructed yet, and one must avoid doing anything with ``self`` but assigning to ``cdef`` fields. Note also that the above method takes no parameters, although subtypes may want to accept some. A no-arguments ``__cinit__()`` method is a special case here that simply does not receive any parameters that were passed to a constructor, so it does not prevent subclasses from adding parameters. If parameters are used in the signature of ``__cinit__()``, they must match those of any declared ``__init__`` method of classes in the class hierarchy that are used to instantiate the type. Memory management ----------------- Before we continue implementing the other methods, it is important to understand that the above implementation is not safe. In case anything goes wrong in the call to ``queue_new()``, this code will simply swallow the error, so we will likely run into a crash later on. According to the documentation of the ``queue_new()`` function, the only reason why the above can fail is due to insufficient memory. In that case, it will return ``NULL``, whereas it would normally return a pointer to the new queue. The Python way to get out of this is to raise a ``MemoryError`` [#]_. We can thus change the init function as follows:: cimport cqueue cdef class Queue: cdef cqueue.Queue* _c_queue def __cinit__(self): self._c_queue = cqueue.queue_new() if self._c_queue is NULL: raise MemoryError() .. [#] In the specific case of a ``MemoryError``, creating a new exception instance in order to raise it may actually fail because we are running out of memory. Luckily, CPython provides a C-API function ``PyErr_NoMemory()`` that safely raises the right exception for us. Since version 0.14.1, Cython automatically substitutes this C-API call whenever you write ``raise MemoryError`` or ``raise MemoryError()``. If you use an older version, you have to cimport the C-API function from the standard package ``cpython.exc`` and call it directly. The next thing to do is to clean up when the Queue instance is no longer used (i.e. all references to it have been deleted). To this end, CPython provides a callback that Cython makes available as a special method ``__dealloc__()``. In our case, all we have to do is to free the C Queue, but only if we succeeded in initialising it in the init method:: def __dealloc__(self): if self._c_queue is not NULL: cqueue.queue_free(self._c_queue) Compiling and linking --------------------- At this point, we have a working Cython module that we can test. To compile it, we need to configure a ``setup.py`` script for distutils. Here is the most basic script for compiling a Cython module:: from distutils.core import setup from distutils.extension import Extension from Cython.Build import cythonize setup( ext_modules = cythonize([Extension("queue", ["queue.pyx"])]) ) To build against the external C library, we must extend this script to include the necessary setup. Assuming the library is installed in the usual places (e.g. under ``/usr/lib`` and ``/usr/include`` on a Unix-like system), we could simply change the extension setup from :: ext_modules = cythonize([Extension("queue", ["queue.pyx"])]) to :: ext_modules = cythonize([ Extension("queue", ["queue.pyx"], libraries=["calg"]) ]) If it is not installed in a 'normal' location, users can provide the required parameters externally by passing appropriate C compiler flags, such as:: CFLAGS="-I/usr/local/otherdir/calg/include" \ LDFLAGS="-L/usr/local/otherdir/calg/lib" \ python setup.py build_ext -i Once we have compiled the module for the first time, we can now import it and instantiate a new Queue:: $ export PYTHONPATH=. $ python -c 'import queue.Queue as Q ; Q()' However, this is all our Queue class can do so far, so let's make it more usable. Mapping functionality --------------------- Before implementing the public interface of this class, it is good practice to look at what interfaces Python offers, e.g. in its ``list`` or ``collections.deque`` classes. Since we only need a FIFO queue, it's enough to provide the methods ``append()``, ``peek()`` and ``pop()``, and additionally an ``extend()`` method to add multiple values at once. Also, since we already know that all values will be coming from C, it's best to provide only ``cdef`` methods for now, and to give them a straight C interface. In C, it is common for data structures to store data as a ``void*`` to whatever data item type. Since we only want to store ``int`` values, which usually fit into the size of a pointer type, we can avoid additional memory allocations through a trick: we cast our ``int`` values to ``void*`` and vice versa, and store the value directly as the pointer value. Here is a simple implementation for the ``append()`` method:: cdef append(self, int value): cqueue.queue_push_tail(self._c_queue, value) Again, the same error handling considerations as for the ``__cinit__()`` method apply, so that we end up with this implementation instead:: cdef append(self, int value): if not cqueue.queue_push_tail(self._c_queue, value): raise MemoryError() Adding an ``extend()`` method should now be straight forward:: cdef extend(self, int* values, size_t count): """Append all ints to the queue. """ cdef size_t i for i in range(count): if not cqueue.queue_push_tail( self._c_queue, values[i]): raise MemoryError() This becomes handy when reading values from a NumPy array, for example. So far, we can only add data to the queue. The next step is to write the two methods to get the first element: ``peek()`` and ``pop()``, which provide read-only and destructive read access respectively:: cdef int peek(self): return cqueue.queue_peek_head(self._c_queue) cdef int pop(self): return cqueue.queue_pop_head(self._c_queue) Handling errors --------------- Now, what happens when the queue is empty? According to the documentation, the functions return a ``NULL`` pointer, which is typically not a valid value. Since we are simply casting to and from ints, we cannot distinguish anymore if the return value was ``NULL`` because the queue was empty or because the value stored in the queue was ``0``. However, in Cython code, we would expect the first case to raise an exception, whereas the second case should simply return ``0``. To deal with this, we need to special case this value, and check if the queue really is empty or not:: cdef int peek(self) except? -1: value = cqueue.queue_peek_head(self._c_queue) if value == 0: # this may mean that the queue is empty, or # that it happens to contain a 0 value if cqueue.queue_is_empty(self._c_queue): raise IndexError("Queue is empty") return value Note how we have effectively created a fast path through the method in the hopefully common cases that the return value is not ``0``. Only that specific case needs an additional check if the queue is empty. The ``except? -1`` declaration in the method signature falls into the same category. If the function was a Python function returning a Python object value, CPython would simply return ``NULL`` internally instead of a Python object to indicate an exception, which would immediately be propagated by the surrounding code. The problem is that the return type is ``int`` and any ``int`` value is a valid queue item value, so there is no way to explicitly signal an error to the calling code. In fact, without such a declaration, there is no obvious way for Cython to know what to return on exceptions and for calling code to even know that this method *may* exit with an exception. The only way calling code can deal with this situation is to call ``PyErr_Occurred()`` when returning from a function to check if an exception was raised, and if so, propagate the exception. This obviously has a performance penalty. Cython therefore allows you to declare which value it should implicitly return in the case of an exception, so that the surrounding code only needs to check for an exception when receiving this exact value. We chose to use ``-1`` as the exception return value as we expect it to be an unlikely value to be put into the queue. The question mark in the ``except? -1`` declaration indicates that the return value is ambiguous (there *may* be a ``-1`` value in the queue, after all) and that an additional exception check using ``PyErr_Occurred()`` is needed in calling code. Without it, Cython code that calls this method and receives the exception return value would silently (and sometimes incorrectly) assume that an exception has been raised. In any case, all other return values will be passed through almost without a penalty, thus again creating a fast path for 'normal' values. Now that the ``peek()`` method is implemented, the ``pop()`` method also needs adaptation. Since it removes a value from the queue, however, it is not enough to test if the queue is empty *after* the removal. Instead, we must test it on entry:: cdef int pop(self) except? -1: if cqueue.queue_is_empty(self._c_queue): raise IndexError("Queue is empty") return cqueue.queue_pop_head(self._c_queue) The return value for exception propagation is declared exactly as for ``peek()``. Lastly, we can provide the Queue with an emptiness indicator in the normal Python way by implementing the ``__bool__()`` special method (note that Python 2 calls this method ``__nonzero__``, whereas Cython code can use either name):: def __bool__(self): return not cqueue.queue_is_empty(self._c_queue) Note that this method returns either ``True`` or ``False`` as we declared the return type of the ``queue_is_empty()`` function as ``bint`` in ``cqueue.pxd``. Testing the result ------------------ Now that the implementation is complete, you may want to write some tests for it to make sure it works correctly. Especially doctests are very nice for this purpose, as they provide some documentation at the same time. To enable doctests, however, you need a Python API that you can call. C methods are not visible from Python code, and thus not callable from doctests. A quick way to provide a Python API for the class is to change the methods from ``cdef`` to ``cpdef``. This will let Cython generate two entry points, one that is callable from normal Python code using the Python call semantics and Python objects as arguments, and one that is callable from C code with fast C semantics and without requiring intermediate argument conversion from or to Python types. Note that ``cpdef`` methods ensure that they can be appropriately overridden by Python methods even when they are called from Cython. This adds a tiny overhead compared to ``cdef`` methods. The following listing shows the complete implementation that uses ``cpdef`` methods where possible:: cimport cqueue cdef class Queue: """A queue class for C integer values. >>> q = Queue() >>> q.append(5) >>> q.peek() 5 >>> q.pop() 5 """ cdef cqueue.Queue* _c_queue def __cinit__(self): self._c_queue = cqueue.queue_new() if self._c_queue is NULL: raise MemoryError() def __dealloc__(self): if self._c_queue is not NULL: cqueue.queue_free(self._c_queue) cpdef append(self, int value): if not cqueue.queue_push_tail(self._c_queue, value): raise MemoryError() cdef extend(self, int* values, size_t count): cdef size_t i for i in xrange(count): if not cqueue.queue_push_tail( self._c_queue, values[i]): raise MemoryError() cpdef int peek(self) except? -1: cdef int value = \ cqueue.queue_peek_head(self._c_queue) if value == 0: # this may mean that the queue is empty, # or that it happens to contain a 0 value if cqueue.queue_is_empty(self._c_queue): raise IndexError("Queue is empty") return value cpdef int pop(self) except? -1: if cqueue.queue_is_empty(self._c_queue): raise IndexError("Queue is empty") return cqueue.queue_pop_head(self._c_queue) def __bool__(self): return not cqueue.queue_is_empty(self._c_queue) The ``cpdef`` feature is obviously not available for the ``extend()`` method, as the method signature is incompatible with Python argument types. However, if wanted, we can rename the C-ish ``extend()`` method to e.g. ``c_extend()``, and write a new ``extend()`` method instead that accepts an arbitrary Python iterable:: cdef c_extend(self, int* values, size_t count): cdef size_t i for i in range(count): if not cqueue.queue_push_tail( self._c_queue, values[i]): raise MemoryError() cpdef extend(self, values): for value in values: self.append(value) As a quick test with 10000 numbers on the author's machine indicates, using this Queue from Cython code with C ``int`` values is about five times as fast as using it from Cython code with Python object values, almost eight times faster than using it from Python code in a Python loop, and still more than twice as fast as using Python's highly optimised ``collections.deque`` type from Cython code with Python integers. Callbacks --------- Let's say you want to provide a way for users to pop values from the queue up to a certain user defined event occurs. To this end, you want to allow them to pass a predicate function that determines when to stop, e.g.:: def pop_until(self, predicate): while not predicate(self.peek()): self.pop() Now, let us assume for the sake of argument that the C queue provides such a function that takes a C callback function as predicate. The API could look as follows:: /* C type of a predicate function that takes a queue value and returns * -1 for errors * 0 for reject * 1 for accept */ typedef int (*predicate_func)(void* user_context, QueueValue data); /* Pop values as long as the predicate evaluates to true for them, * returns -1 if the predicate failed with an error and 0 otherwise. */ int queue_pop_head_until(Queue *queue, predicate_func predicate, void* user_context); It is normal for C callback functions to have a generic :c:type:`void*` argument that allows passing any kind of context or state through the C-API into the callback function. We will use this to pass our Python predicate function. First, we have to define a callback function with the expected signature that we can pass into the C-API function:: cdef int evaluate_predicate(void* context, cqueue.QueueValue value): "Callback function that can be passed as predicate_func" try: # recover Python function object from void* argument func = context # call function, convert result into 0/1 for True/False return bool(func(value)) except: # catch any Python errors and return error indicator return -1 The main idea is to pass a pointer (a.k.a. borrowed reference) to the function object as the user context argument. We will call the C-API function as follows:: def pop_until(self, python_predicate_function): result = cqueue.queue_pop_head_until( self._c_queue, evaluate_predicate, python_predicate_function) if result == -1: raise RuntimeError("an error occurred") The usual pattern is to first cast the Python object reference into a :c:type:`void*` to pass it into the C-API function, and then cast it back into a Python object in the C predicate callback function. The cast to :c:type:`void*` creates a borrowed reference. On the cast to ````, Cython increments the reference count of the object and thus converts the borrowed reference back into an owned reference. At the end of the predicate function, the owned reference goes out of scope again and Cython discards it. The error handling in the code above is a bit simplistic. Specifically, any exceptions that the predicate function raises will essentially be discarded and only result in a plain ``RuntimeError()`` being raised after the fact. This can be improved by storing away the exception in an object passed through the context parameter and re-raising it after the C-API function has returned ``-1`` to indicate the error. Cython-0.23.4/docs/src/tutorial/cdef_classes.rst0000644000175600017570000001252512606202452022743 0ustar jenkinsjenkins00000000000000Extension types (aka. cdef classes) =================================== To support object-oriented programming, Cython supports writing normal Python classes exactly as in Python:: class MathFunction(object): def __init__(self, name, operator): self.name = name self.operator = operator def __call__(self, *operands): return self.operator(*operands) Based on what Python calls a "built-in type", however, Cython supports a second kind of class: *extension types*, sometimes referred to as "cdef classes" due to the keywords used for their declaration. They are somewhat restricted compared to Python classes, but are generally more memory efficient and faster than generic Python classes. The main difference is that they use a C struct to store their fields and methods instead of a Python dict. This allows them to store arbitrary C types in their fields without requiring a Python wrapper for them, and to access fields and methods directly at the C level without passing through a Python dictionary lookup. Normal Python classes can inherit from cdef classes, but not the other way around. Cython requires to know the complete inheritance hierarchy in order to lay out their C structs, and restricts it to single inheritance. Normal Python classes, on the other hand, can inherit from any number of Python classes and extension types, both in Cython code and pure Python code. So far our integration example has not been very useful as it only integrates a single hard-coded function. In order to remedy this, with hardly sacrificing speed, we will use a cdef class to represent a function on floating point numbers:: cdef class Function: cpdef double evaluate(self, double x) except *: return 0 The directive cpdef makes two versions of the method available; one fast for use from Cython and one slower for use from Python. Then:: cdef class SinOfSquareFunction(Function): cpdef double evaluate(self, double x) except *: return sin(x**2) This does slightly more than providing a python wrapper for a cdef method: unlike a cdef method, a cpdef method is fully overrideable by methods and instance attributes in Python subclasses. It adds a little calling overhead compared to a cdef method. Using this, we can now change our integration example:: def integrate(Function f, double a, double b, int N): cdef int i cdef double s, dx if f is None: raise ValueError("f cannot be None") s = 0 dx = (b-a)/N for i in range(N): s += f.evaluate(a+i*dx) return s * dx print(integrate(SinOfSquareFunction(), 0, 1, 10000)) This is almost as fast as the previous code, however it is much more flexible as the function to integrate can be changed. We can even pass in a new function defined in Python-space:: >>> import integrate >>> class MyPolynomial(integrate.Function): ... def evaluate(self, x): ... return 2*x*x + 3*x - 10 ... >>> integrate(MyPolynomial(), 0, 1, 10000) -7.8335833300000077 This is about 20 times slower, but still about 10 times faster than the original Python-only integration code. This shows how large the speed-ups can easily be when whole loops are moved from Python code into a Cython module. Some notes on our new implementation of ``evaluate``: - The fast method dispatch here only works because ``evaluate`` was declared in ``Function``. Had ``evaluate`` been introduced in ``SinOfSquareFunction``, the code would still work, but Cython would have used the slower Python method dispatch mechanism instead. - In the same way, had the argument ``f`` not been typed, but only been passed as a Python object, the slower Python dispatch would be used. - Since the argument is typed, we need to check whether it is ``None``. In Python, this would have resulted in an ``AttributeError`` when the ``evaluate`` method was looked up, but Cython would instead try to access the (incompatible) internal structure of ``None`` as if it were a ``Function``, leading to a crash or data corruption. There is a *compiler directive* ``nonecheck`` which turns on checks for this, at the cost of decreased speed. Here's how compiler directives are used to dynamically switch on or off ``nonecheck``:: #cython: nonecheck=True # ^^^ Turns on nonecheck globally import cython # Turn off nonecheck locally for the function @cython.nonecheck(False) def func(): cdef MyClass obj = None try: # Turn nonecheck on again for a block with cython.nonecheck(True): print obj.myfunc() # Raises exception except AttributeError: pass print obj.myfunc() # Hope for a crash! Attributes in cdef classes behave differently from attributes in regular classes: - All attributes must be pre-declared at compile-time - Attributes are by default only accessible from Cython (typed access) - Properties can be declared to expose dynamic attributes to Python-space :: cdef class WaveFunction(Function): # Not available in Python-space: cdef double offset # Available in Python-space: cdef public double freq # Available in Python-space: property period: def __get__(self): return 1.0 / self.freq def __set__(self, value): self.freq = 1.0 / value <...> Cython-0.23.4/docs/src/tutorial/caveats.rst0000644000175600017570000000172112606202452021747 0ustar jenkinsjenkins00000000000000Caveats ======= Since Cython mixes C and Python semantics, some things may be a bit surprising or unintuitive. Work always goes on to make Cython more natural for Python users, so this list may change in the future. - ``10**-2 == 0``, instead of ``0.01`` like in Python. - Given two typed ``int`` variables ``a`` and ``b``, ``a % b`` has the same sign as the second argument (following Python semantics) rather than having the same sign as the first (as in C). The C behavior can be obtained, at some speed gain, by enabling the cdivision directive (versions prior to Cython 0.12 always followed C semantics). - Care is needed with unsigned types. ``cdef unsigned n = 10; print(range(-n, n))`` will print an empty list, since ``-n`` wraps around to a large positive integer prior to being passed to the ``range`` function. - Python's ``float`` type actually wraps C ``double`` values, and the ``int`` type in Python 2.x wraps C ``long`` values. Cython-0.23.4/docs/src/tutorial/array.rst0000644000175600017570000001212712606202452021441 0ustar jenkinsjenkins00000000000000.. _array-array: ========================== Working with Python arrays ========================== Python has a builtin array module supporting dynamic 1-dimensional arrays of primitive types. It is possible to access the underlying C array of a Python array from within Cython. At the same time they are ordinary Python objects which can be stored in lists and serialized between processes when using :obj:`multiprocessing`. Compared to the manual approach with :c:func:`malloc` and :c:func:`free`, this gives the safe and automatic memory management of Python, and compared to a Numpy array there is no need to install a dependency, as the :obj:`array` module is built into both Python and Cython. Safe usage with memory views ---------------------------- :: from cpython cimport array import array cdef array.array a = array.array('i', [1, 2, 3]) cdef int[:] ca = a print ca[0] NB: the import brings the regular Python array object into the namespace while the cimport adds functions accessible from Cython. A Python array is constructed with a type signature and sequence of initial values. For the possible type signatures, refer to the Python documentation for the `array module `_. Notice that when a Python array is assigned to a variable typed as memory view, there will be a slight overhead to construct the memory view. However, from that point on the variable can be passed to other functions without overhead, so long as it is typed:: from cpython cimport array import array cdef array.array a = array.array('i', [1, 2, 3]) cdef int[:] ca = a cdef int overhead(object a): cdef int[:] ca = a return ca[0] cdef int no_overhead(int[:] ca): return ca[0] print overhead(a) # new memory view will be constructed, overhead print no_overhead(ca) # ca is already a memory view, so no overhead Zero-overhead, unsafe access to raw C pointer --------------------------------------------- To avoid any overhead and to be able to pass a C pointer to other functions, it is possible to access the underlying contiguous array as a pointer. There is no type or bounds checking, so be careful to use the right type and signedness. :: from cpython cimport array import array cdef array.array a = array.array('i', [1, 2, 3]) # access underlying pointer: print a.data.as_ints[0] from libc.string cimport memset memset(a.data.as_voidptr, 0, len(a) * sizeof(int)) Note that any length-changing operation on the array object may invalidate the pointer. Cloning, extending arrays ------------------------- To avoid having to use the array constructor from the Python module, it is possible to create a new array with the same type as a template, and preallocate a given number of elements. The array is initialized to zero when requested. :: from cpython cimport array import array cdef array.array int_array_template = array.array('i', []) cdef array.array newarray # create an array with 3 elements with same type as template newarray = array.clone(int_array_template, 3, zero=False) An array can also be extended and resized; this avoids repeated memory reallocation which would occur if elements would be appended or removed one by one. :: from cpython cimport array import array cdef array.array a = array.array('i', [1, 2, 3]) cdef array.array b = array.array('i', [4, 5, 6]) # extend a with b, resize as needed array.extend(a, b) # resize a, leaving just original three elements array.resize(a, len(a) - len(b)) API reference ------------- Data fields ~~~~~~~~~~~ :: data.as_voidptr data.as_chars data.as_schars data.as_uchars data.as_shorts data.as_ushorts data.as_ints data.as_uints data.as_longs data.as_ulongs data.as_floats data.as_doubles data.as_pyunicodes Direct access to the underlying contiguous C array, with given type; e.g., ``myarray.data.as_ints``. Functions ~~~~~~~~~ The following functions are available to Cython from the array module:: int resize(array self, Py_ssize_t n) except -1 Fast resize / realloc. Not suitable for repeated, small increments; resizes underlying array to exactly the requested amount. :: int resize_smart(array self, Py_ssize_t n) except -1 Efficient for small increments; uses growth pattern that delivers amortized linear-time appends. :: cdef inline array clone(array template, Py_ssize_t length, bint zero) Fast creation of a new array, given a template array. Type will be same as ``template``. If zero is ``True``, new array will be initialized with zeroes. :: cdef inline array copy(array self) Make a copy of an array. :: cdef inline int extend_buffer(array self, char* stuff, Py_ssize_t n) except -1 Efficient appending of new data of same type (e.g. of same array type) ``n``: number of elements (not number of bytes!) :: cdef inline int extend(array self, array other) except -1 Extend array with data from another array; types must match. :: cdef inline void zero(array self) Set all elements of array to zero. Cython-0.23.4/docs/src/tutorial/appendix.rst0000644000175600017570000000265612606202452022141 0ustar jenkinsjenkins00000000000000Appendix: Installing MinGW on Windows ===================================== 1. Download the MinGW installer from http://www.mingw.org/wiki/HOWTO_Install_the_MinGW_GCC_Compiler_Suite. (As of this writing, the download link is a bit difficult to find; it's under "About" in the menu on the left-hand side). You want the file entitled "Automated MinGW Installer" (currently version 5.1.4). 2. Run it and install MinGW. Only the basic package is strictly needed for Cython, although you might want to grab at least the C++ compiler as well. 3. You need to set up Windows' "PATH" environment variable so that includes e.g. "c:\\mingw\\bin" (if you installed MinGW to "c:\\mingw"). The following web-page describes the procedure in Windows XP (the Vista procedure is similar): http://support.microsoft.com/kb/310519 4. Finally, tell Python to use MinGW as the default compiler (otherwise it will try for Visual C). If Python is installed to "c:\\Python27", create a file named "c:\\Python27\\Lib\\distutils\\distutils.cfg" containing:: [build] compiler = mingw32 The [WinInst]_ wiki page contains updated information about this procedure. Any contributions towards making the Windows install process smoother is welcomed; it is an unfortunate fact that none of the regular Cython developers have convenient access to Windows. .. [WinInst] http://wiki.cython.org/InstallingOnWindows Cython-0.23.4/docs/src/tutorial/queue_example/0000755000175600017570000000000012606202455022430 5ustar jenkinsjenkins00000000000000Cython-0.23.4/docs/src/tutorial/queue_example/queue.pyx0000644000175600017570000000453312606202452024320 0ustar jenkinsjenkins00000000000000cimport cqueue cdef class Queue: cdef cqueue.Queue* _c_queue def __cinit__(self): self._c_queue = cqueue.queue_new() if self._c_queue is NULL: raise MemoryError() def __dealloc__(self): if self._c_queue is not NULL: cqueue.queue_free(self._c_queue) cpdef int append(self, int value) except -1: if not cqueue.queue_push_tail(self._c_queue, value): raise MemoryError() return 0 cdef int extend(self, int* values, Py_ssize_t count) except -1: cdef Py_ssize_t i for i in range(count): if not cqueue.queue_push_tail(self._c_queue, values[i]): raise MemoryError() return 0 cpdef int peek(self) except? 0: cdef int value = cqueue.queue_peek_head(self._c_queue) if value == 0: # this may mean that the queue is empty, or that it # happens to contain a 0 value if cqueue.queue_is_empty(self._c_queue): raise IndexError("Queue is empty") return value cpdef int pop(self) except? 0: cdef int value = cqueue.queue_pop_head(self._c_queue) if value == 0: # this may mean that the queue is empty, or that it # happens to contain a 0 value if cqueue.queue_is_empty(self._c_queue): raise IndexError("Queue is empty") return value def __bool__(self): # same as __nonzero__ in Python 2.x return not cqueue.queue_is_empty(self._c_queue) DEF repeat_count=10000 def test_cy(): cdef int i cdef Queue q = Queue() for i in range(repeat_count): q.append(i) for i in range(repeat_count): q.peek() while q: q.pop() def test_py(): cdef int i q = Queue() for i in range(repeat_count): q.append(i) for i in range(repeat_count): q.peek() while q: q.pop() from collections import deque def test_deque(): cdef int i q = deque() for i in range(repeat_count): q.appendleft(i) for i in range(repeat_count): q[-1] while q: q.pop() repeat = range(repeat_count) def test_py_exec(): q = Queue() d = dict(q=q, repeat=repeat) exec u"""\ for i in repeat: q.append(9) for i in repeat: q.peek() while q: q.pop() """ in d Cython-0.23.4/docs/src/tutorial/queue_example/cqueue.pxd0000644000175600017570000000104112606202452024425 0ustar jenkinsjenkins00000000000000cdef extern from "libcalg/queue.h": ctypedef struct Queue: pass ctypedef void* QueueValue Queue* queue_new() void queue_free(Queue* queue) int queue_push_head(Queue* queue, QueueValue data) QueueValue queue_pop_head(Queue* queue) QueueValue queue_peek_head(Queue* queue) int queue_push_tail(Queue* queue, QueueValue data) QueueValue queue_pop_tail(Queue* queue) QueueValue queue_peek_tail(Queue* queue) int queue_is_empty(Queue* queue) Cython-0.23.4/docs/src/reference/0000755000175600017570000000000012606202455017664 5ustar jenkinsjenkins00000000000000Cython-0.23.4/docs/src/reference/special_methods_table.rst0000644000175600017570000005433312606202452024735 0ustar jenkinsjenkins00000000000000.. _special_methods_table: Special Methods Table --------------------- This table lists all of the special methods together with their parameter and return types. In the table below, a parameter name of self is used to indicate that the parameter has the type that the method belongs to. Other parameters with no type specified in the table are generic Python objects. You don't have to declare your method as taking these parameter types. If you declare different types, conversions will be performed as necessary. General ^^^^^^^ +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __cinit__ |self, ... | | Basic initialisation (no direct Python equivalent) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __init__ |self, ... | | Further initialisation | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __dealloc__ |self | | Basic deallocation (no direct Python equivalent) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __cmp__ |x, y | int | 3-way comparison | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __richcmp__ |x, y, int op | object | Rich comparison (no direct Python equivalent) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __str__ |self | object | str(self) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __repr__ |self | object | repr(self) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __hash__ |self | int | Hash function | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __call__ |self, ... | object | self(...) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __iter__ |self | object | Return iterator for sequence | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __getattr__ |self, name | object | Get attribute | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __getattribute__ |self, name | object | Get attribute, unconditionally | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __setattr__ |self, name, val | | Set attribute | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __delattr__ |self, name | | Delete attribute | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ Arithmetic operators ^^^^^^^^^^^^^^^^^^^^ +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __add__ | x, y | object | binary `+` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __sub__ | x, y | object | binary `-` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __mul__ | x, y | object | `*` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __div__ | x, y | object | `/` operator for old-style division | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __floordiv__ | x, y | object | `//` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __truediv__ | x, y | object | `/` operator for new-style division | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __mod__ | x, y | object | `%` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __divmod__ | x, y | object | combined div and mod | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __pow__ | x, y, z | object | `**` operator or pow(x, y, z) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __neg__ | self | object | unary `-` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __pos__ | self | object | unary `+` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __abs__ | self | object | absolute value | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __nonzero__ | self | int | convert to boolean | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __invert__ | self | object | `~` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __lshift__ | x, y | object | `<<` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __rshift__ | x, y | object | `>>` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __and__ | x, y | object | `&` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __or__ | x, y | object | `|` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __xor__ | x, y | object | `^` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ Numeric conversions ^^^^^^^^^^^^^^^^^^^ +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __int__ | self | object | Convert to integer | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __long__ | self | object | Convert to long integer | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __float__ | self | object | Convert to float | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __oct__ | self | object | Convert to octal | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __hex__ | self | object | Convert to hexadecimal | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __index__ | self | object | Convert to sequence index | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ In-place arithmetic operators ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __iadd__ | self, x | object | `+=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __isub__ | self, x | object | `-=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __imul__ | self, x | object | `*=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __idiv__ | self, x | object | `/=` operator for old-style division | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __ifloordiv__ | self, x | object | `//=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __itruediv__ | self, x | object | `/=` operator for new-style division | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __imod__ | self, x | object | `%=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __ipow__ | x, y, z | object | `**=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __ilshift__ | self, x | object | `<<=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __irshift__ | self, x | object | `>>=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __iand__ | self, x | object | `&=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __ior__ | self, x | object | `|=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __ixor__ | self, x | object | `^=` operator | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ Sequences and mappings ^^^^^^^^^^^^^^^^^^^^^^ +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __len__ | self int | | len(self) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __getitem__ | self, x | object | self[x] | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __setitem__ | self, x, y | | self[x] = y | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __delitem__ | self, x | | del self[x] | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __getslice__ | self, Py_ssize_t i, Py_ssize_t j | object | self[i:j] | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __setslice__ | self, Py_ssize_t i, Py_ssize_t j, x | | self[i:j] = x | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __delslice__ | self, Py_ssize_t i, Py_ssize_t j | | del self[i:j] | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __contains__ | self, x | int | x in self | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ Iterators ^^^^^^^^^ +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __next__ | self | object | Get next item (called next in Python) | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ Buffer interface ^^^^^^^^^^^^^^^^ .. note:: The buffer interface is intended for use by C code and is not directly accessible from Python. It is described in the Python/C API Reference Manual under sections 6.6 and 10.6. +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __getreadbuffer__ | self, int i, void `**p` | | | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __getwritebuffer__ | self, int i, void `**p` | | | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __getsegcount__ | self, int `*p` | | | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __getcharbuffer__ | self, int i, char `**p` | | | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ Descriptor objects ^^^^^^^^^^^^^^^^^^ .. note:: Descriptor objects are part of the support mechanism for new-style Python classes. See the discussion of descriptors in the Python documentation. See also PEP 252, "Making Types Look More Like Classes", and PEP 253, "Subtyping Built-In Types". +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | Name | Parameters | Return type | Description | +=======================+=======================================+=============+=====================================================+ | __get__ | self, instance, class | object | Get value of attribute | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __set__ | self, instance, value | | Set value of attribute | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ | __delete__ | self, instance | | Delete attribute | +-----------------------+---------------------------------------+-------------+-----------------------------------------------------+ Cython-0.23.4/docs/src/reference/special_mention.rst0000644000175600017570000000013612606202452023564 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _special_mention: *************** Special Mention *************** Cython-0.23.4/docs/src/reference/limitations.rst0000644000175600017570000000011612606202452022745 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _limitations: *********** Limitations *********** Cython-0.23.4/docs/src/reference/language_basics.rst0000644000175600017570000006256412606202452023537 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _language_basics: *************** Language Basics *************** ================= Cython File Types ================= There are three file types in Cython: * Implementation files carry a ``.pyx`` suffix * Definition files carry a ``.pxd`` suffix * Include files which carry a ``.pxi`` suffix Implementation File =================== What can it contain? -------------------- * Basically anything Cythonic, but see below. What can't it contain? ---------------------- * There are some restrictions when it comes to **extension types**, if the extension type is already defined else where... **more on this later** Definition File =============== What can it contain? -------------------- * Any kind of C type declaration. * ``extern`` C function or variable declarations. * Declarations for module implementations. * The definition parts of **extension types**. * All declarations of functions, etc., for an **external library** What can't it contain? ---------------------- * Any non-extern C variable declaration. * Implementations of C or Python functions. * Python class definitions * Python executable statements. * Any declaration that is defined as **public** to make it accessible to other Cython modules. * This is not necessary, as it is automatic. * a **public** declaration is only needed to make it accessible to **external C code**. What else? ---------- cimport ``````` * Use the **cimport** statement, as you would Python's import statement, to access these files from other definition or implementation files. * **cimport** does not need to be called in ``.pyx`` file for for ``.pxd`` file that has the same name, as they are already in the same namespace. * For cimport to find the stated definition file, the path to the file must be appended to the ``-I`` option of the **Cython compile command**. compilation order ````````````````` * When a ``.pyx`` file is to be compiled, Cython first checks to see if a corresponding ``.pxd`` file exits and processes it first. Include File ============ What can it contain? -------------------- * Any Cythonic code really, because the entire file is textually embedded at the location you prescribe. How do I use it? ---------------- * Include the ``.pxi`` file with an ``include`` statement like: ``include "spamstuff.pxi`` * The ``include`` statement can appear anywhere in your Cython file and at any indentation level * The code in the ``.pxi`` file needs to be rooted at the "zero" indentation level. * The included code can itself contain other ``include`` statements. ==================== Declaring Data Types ==================== As a dynamic language, Python encourages a programming style of considering classes and objects in terms of their methods and attributes, more than where they fit into the class hierarchy. This can make Python a very relaxed and comfortable language for rapid development, but with a price - the 'red tape' of managing data types is dumped onto the interpreter. At run time, the interpreter does a lot of work searching namespaces, fetching attributes and parsing argument and keyword tuples. This run-time ‘late binding’ is a major cause of Python’s relative slowness compared to ‘early binding’ languages such as C++. However with Cython it is possible to gain significant speed-ups through the use of ‘early binding’ programming techniques. .. note:: Typing is not a necessity Providing static typing to parameters and variables is convenience to speed up your code, but it is not a necessity. Optimize where and when needed. The cdef Statement ================== The ``cdef`` statement is used to make C level declarations for: :Variables: :: cdef int i, j, k cdef float f, g[42], *h :Structs: :: cdef struct Grail: int age float volume ..note Structs can be declared as ``cdef packed struct``, which has the same effect as the C directive ``#pragma pack(1)``. :Unions: :: cdef union Food: char *spam float *eggs :Enums: :: cdef enum CheeseType: cheddar, edam, camembert cdef enum CheeseState: hard = 1 soft = 2 runny = 3 :Functions: :: cdef int eggs(unsigned long l, float f): ... :Extension Types: :: cdef class Spam: ... .. note:: Constants Constants can be defined by using an anonymous enum:: cdef enum: tons_of_spam = 3 Grouping cdef Declarations ========================== A series of declarations can grouped into a ``cdef`` block:: cdef: struct Spam: int tons int i float f Spam *p void f(Spam *s): print s.tons, "Tons of spam" .. note:: ctypedef statement The ``ctypedef`` statement is provided for naming types:: ctypedef unsigned long ULong ctypedef int *IntPtr Parameters ========== * Both C and Python **function** types can be declared to have parameters C data types. * Use normal C declaration syntax:: def spam(int i, char *s): ... cdef int eggs(unsigned long l, float f): ... * As these parameters are passed into a Python declared function, they are magically **converted** to the specified C type value. * This holds true for only numeric and string types * If no type is specified for a parameter or a return value, it is assumed to be a Python object * The following takes two Python objects as parameters and returns a Python object:: cdef spamobjs(x, y): ... .. note:: -- This is different then C language behavior, where it is an int by default. * Python object types have reference counting performed according to the standard Python C-API rules: * Borrowed references are taken as parameters * New references are returned .. todo:: link or label here the one ref count caveat for NumPy. * The name ``object`` can be used to explicitly declare something as a Python Object. * For sake of code clarity, it recommended to always use ``object`` explicitly in your code. * This is also useful for cases where the name being declared would otherwise be taken for a type:: cdef foo(object int): ... * As a return type:: cdef object foo(object int): ... .. todo:: Do a see also here ..?? Optional Arguments ------------------ * Are supported for ``cdef`` and ``cpdef`` functions * There differences though whether you declare them in a ``.pyx`` file or a ``.pxd`` file * When in a ``.pyx`` file, the signature is the same as it is in Python itself:: cdef class A: cdef foo(self): print "A" cdef class B(A) cdef foo(self, x=None) print "B", x cdef class C(B): cpdef foo(self, x=True, int k=3) print "C", x, k * When in a ``.pxd`` file, the signature is different like this example: ``cdef foo(x=*)``:: cdef class A: cdef foo(self) cdef class B(A) cdef foo(self, x=*) cdef class C(B): cpdef foo(self, x=*, int k=*) * The number of arguments may increase when subclassing, but the arg types and order must be the same. * There may be a slight performance penalty when the optional arg is overridden with one that does not have default values. Keyword-only Arguments ======================= * As in Python 3, ``def`` functions can have keyword-only arguments listed after a ``"*"`` parameter and before a ``"**"`` parameter if any:: def f(a, b, *args, c, d = 42, e, **kwds): ... * Shown above, the ``c``, ``d`` and ``e`` arguments can not be passed as positional arguments and must be passed as keyword arguments. * Furthermore, ``c`` and ``e`` are required keyword arguments since they do not have a default value. * If the parameter name after the ``"*"`` is omitted, the function will not accept any extra positional arguments:: def g(a, b, *, c, d): ... * Shown above, the signature takes exactly two positional parameters and has two required keyword parameters Automatic Type Conversion ========================= * For basic numeric and string types, in most situations, when a Python object is used in the context of a C value and vice versa. * The following table summarizes the conversion possibilities, assuming ``sizeof(int) == sizeof(long)``: +----------------------------+--------------------+------------------+ | C types | From Python types | To Python types | +============================+====================+==================+ | [unsigned] char | int, long | int | +----------------------------+ | | | [unsigned] short | | | +----------------------------+ | | | int, long | | | +----------------------------+--------------------+------------------+ | unsigned int | int, long | long | +----------------------------+ | | | unsigned long | | | +----------------------------+ | | | [unsigned] long long | | | +----------------------------+--------------------+------------------+ | float, double, long double | int, long, float | float | +----------------------------+--------------------+------------------+ | char * | str/bytes | str/bytes [#]_ | +----------------------------+--------------------+------------------+ | struct | | dict | +----------------------------+--------------------+------------------+ .. note:: **Python String in a C Context** * A Python string, passed to C context expecting a ``char*``, is only valid as long as the Python string exists. * A reference to the Python string must be kept around for as long as the C string is needed. * If this can't be guaranteed, then make a copy of the C string. * Cython may produce an error message: ``Obtaining char* from a temporary Python value`` and will not resume compiling in situations like this:: cdef char *s s = pystring1 + pystring2 * The reason is that concatenating to strings in Python produces a temporary variable. * The variable is decrefed, and the Python string deallocated as soon as the statement has finished, * Therefore the lvalue **``s``** is left dangling. * The solution is to assign the result of the concatenation to a Python variable, and then obtain the ``char*`` from that:: cdef char *s p = pystring1 + pystring2 s = p .. note:: **It is up to you to be aware of this, and not to depend on Cython's error message, as it is not guaranteed to be generated for every situation.** Type Casting ============= * The syntax used in type casting are ``"<"`` and ``">"`` .. note:: The syntax is different from C convention :: cdef char *p, float *q p = q * If one of the types is a python object for ``x``, Cython will try and do a coercion. .. note:: Cython will not stop a casting where there is no conversion, but it will emit a warning. * If the address is what is wanted, cast to a ``void*`` first. Type Checking ------------- * A cast like ``x`` will cast x to type ``MyExtensionType`` without type checking at all. * To have a cast type checked, use the syntax like: ``x``. * In this case, Cython will throw an error if ``"x"`` is not a (subclass) of ``MyExtensionType`` * Automatic type checking for extension types can be obtained whenever ``isinstance()`` is used as the second parameter Python Objects ============== ========================== Statements and Expressions ========================== * For the most part, control structures and expressions follow Python syntax. * When applied to Python objects, the semantics are the same unless otherwise noted. * Most Python operators can be applied to C values with the obvious semantics. * An expression with mixed Python and C values will have **conversions** performed automatically. * Python operations are automatically checked for errors, with the appropriate action taken. Differences Between Cython and C ================================ * Most notable are C constructs which have no direct equivalent in Python. * An integer literal is treated as a C constant * It will be truncated to whatever size your C compiler thinks appropriate. * Cast to a Python object like this:: 10000000000000000000 * The ``"L"``, ``"LL"`` and the ``"U"`` suffixes have the same meaning as in C * There is no ``->`` operator in Cython.. instead of ``p->x``, use ``p.x``. * There is no ``*`` operator in Cython.. instead of ``*p``, use ``p[0]``. * ``&`` is permissible and has the same semantics as in C. * ``NULL`` is the null C pointer. * Do NOT use 0. * ``NULL`` is a reserved word in Cython * Syntax for **Type casts** are ``value``. Scope Rules =========== * All determination of scoping (local, module, built-in) in Cython is determined statically. * As with Python, a variable assignment which is not declared explicitly is implicitly declared to be a Python variable residing in the scope where it was assigned. .. note:: * Module-level scope behaves the same way as a Python local scope if you refer to the variable before assigning to it. * Tricks, like the following will NOT work in Cython:: try: x = True except NameError: True = 1 * The above example will not work because ``True`` will always be looked up in the module-level scope. Do the following instead:: import __builtin__ try: True = __builtin__.True except AttributeError: True = 1 Built-in Constants ================== Predefined Python built-in constants: * None * True * False Operator Precedence =================== * Cython uses Python precedence order, not C For-loops ========== The "for ... in iterable" loop works as in Python, but is even more versatile in Cython as it can additionally be used on C types. * ``range()`` is C optimized when the index value has been declared by ``cdef``, for example:: cdef size_t i for i in range(n): ... * Iteration over C arrays and sliced pointers is supported and automatically infers the type of the loop variable, e.g.:: cdef double* data = ... for x in data[:10]: ... * Iterating over many builtin types such as lists and tuples is optimized. * There is also a more verbose C-style for-from syntax which, however, is deprecated in favour of the normal Python "for ... in range()" loop. You might still find it in legacy code that was written for Pyrex, though. * The target expression must be a plain variable name. * The name between the lower and upper bounds must be the same as the target name. for i from 0 <= i < n: ... * Or when using a step size:: for i from 0 <= i < n by s: ... * To reverse the direction, reverse the conditional operation:: for i from n > i >= 0: ... * The ``break`` and ``continue`` statements are permissible. * Can contain an else clause. ===================== Functions and Methods ===================== * There are three types of function declarations in Cython as the sub-sections show below. * Only "Python" functions can be called outside a Cython module from *Python interpreted code*. Callable from Python ===================== * Are declared with the ``def`` statement * Are called with Python objects * Return Python objects * See **Parameters** for special consideration .. _cdef: Callable from C ================ * Are declared with the ``cdef`` statement. * Are called with either Python objects or C values. * Can return either Python objects or C values. .. _cpdef: Callable from both Python and C ================================ * Are declared with the ``cpdef`` statement. * Can be called from anywhere, because it uses a little Cython magic. * Uses the faster C calling conventions when being called from other Cython code. Overriding ========== ``cpdef`` functions can override ``cdef`` functions:: cdef class A: cdef foo(self): print "A" cdef class B(A) cdef foo(self, x=None) print "B", x cdef class C(B): cpdef foo(self, x=True, int k=3) print "C", x, k Function Pointers ================= * Functions declared in a ``struct`` are automatically converted to function pointers. * see **using exceptions with function pointers** Python Built-ins ================ Cython compiles calls to most built-in functions into direct calls to the corresponding Python/C API routines, making them particularly fast. Only direct function calls using these names are optimised. If you do something else with one of these names that assumes it's a Python object, such as assign it to a Python variable, and later call it, the call will be made as a Python function call. +------------------------------+-------------+----------------------------+ | Function and arguments | Return type | Python/C API Equivalent | +==============================+=============+============================+ | abs(obj) | object, | PyNumber_Absolute, fabs, | | | double, ... | fabsf, ... | +------------------------------+-------------+----------------------------+ | callable(obj) | bint | PyObject_Callable | +------------------------------+-------------+----------------------------+ | delattr(obj, name) | None | PyObject_DelAttr | +------------------------------+-------------+----------------------------+ | exec(code, [glob, [loc]]) | object | - | +------------------------------+-------------+----------------------------+ | dir(obj) | list | PyObject_Dir | +------------------------------+-------------+----------------------------+ | divmod(a, b) | tuple | PyNumber_Divmod | +------------------------------+-------------+----------------------------+ | getattr(obj, name, [default])| object | PyObject_GetAttr | | (Note 1) | | | +------------------------------+-------------+----------------------------+ | hasattr(obj, name) | bint | PyObject_HasAttr | +------------------------------+-------------+----------------------------+ | hash(obj) | int / long | PyObject_Hash | +------------------------------+-------------+----------------------------+ | intern(obj) | object | Py*_InternFromString | +------------------------------+-------------+----------------------------+ | isinstance(obj, type) | bint | PyObject_IsInstance | +------------------------------+-------------+----------------------------+ | issubclass(obj, type) | bint | PyObject_IsSubclass | +------------------------------+-------------+----------------------------+ | iter(obj, [sentinel]) | object | PyObject_GetIter | +------------------------------+-------------+----------------------------+ | len(obj) | Py_ssize_t | PyObject_Length | +------------------------------+-------------+----------------------------+ | pow(x, y, [z]) | object | PyNumber_Power | +------------------------------+-------------+----------------------------+ | reload(obj) | object | PyImport_ReloadModule | +------------------------------+-------------+----------------------------+ | repr(obj) | object | PyObject_Repr | +------------------------------+-------------+----------------------------+ | setattr(obj, name) | void | PyObject_SetAttr | +------------------------------+-------------+----------------------------+ Note 1: Pyrex originally provided a function :func:`getattr3(obj, name, default)` corresponding to the three-argument form of the Python builtin :func:`getattr()`. Cython still supports this function, but the usage is deprecated in favour of the normal builtin, which Cython can optimise in both forms. ============================ Error and Exception Handling ============================ * A plain ``cdef`` declared function, that does not return a Python object... * Has no way of reporting a Python exception to it's caller. * Will only print a warning message and the exception is ignored. * In order to propagate exceptions like this to it's caller, you need to declare an exception value for it. * There are three forms of declaring an exception for a C compiled program. * First:: cdef int spam() except -1: ... * In the example above, if an error occurs inside spam, it will immediately return with the value of ``-1``, causing an exception to be propagated to it's caller. * Functions declared with an exception value, should explicitly prevent a return of that value. * Second:: cdef int spam() except? -1: ... * Used when a ``-1`` may possibly be returned and is not to be considered an error. * The ``"?"`` tells Cython that ``-1`` only indicates a *possible* error. * Now, each time ``-1`` is returned, Cython generates a call to ``PyErr_Occurred`` to verify it is an actual error. * Third:: cdef int spam() except * * A call to ``PyErr_Occurred`` happens *every* time the function gets called. .. note:: Returning ``void`` A need to propagate errors when returning ``void`` must use this version. * Exception values can only be declared for functions returning an.. * integer * enum * float * pointer type * Must be a constant expression .. note:: .. note:: Function pointers * Require the same exception value specification as it's user has declared. * Use cases here are when used as parameters and when assigned to a variable:: int (*grail)(int, char *) except -1 .. note:: Python Objects * Declared exception values are **not** need. * Remember that Cython assumes that a function function without a declared return value, returns a Python object. * Exceptions on such functions are implicitly propagated by returning ``NULL`` .. note:: C++ * For exceptions from C++ compiled programs, see **Wrapping C++ Classes** Checking return values for non-Cython functions.. ================================================= * Do not try to raise exceptions by returning the specified value.. Example:: cdef extern FILE *fopen(char *filename, char *mode) except NULL # WRONG! * The except clause does not work that way. * It's only purpose is to propagate Python exceptions that have already been raised by either... * A Cython function * A C function that calls Python/C API routines. * To propagate an exception for these circumstances you need to raise it yourself:: cdef FILE *p p = fopen("spam.txt", "r") if p == NULL: raise SpamError("Couldn't open the spam file") ======================= Conditional Compilation ======================= * The expressions in the following sub-sections must be valid compile-time expressions. * They can evaluate to any Python value. * The *truth* of the result is determined in the usual Python way. Compile-Time Definitions ========================= * Defined using the ``DEF`` statement:: DEF FavouriteFood = "spam" DEF ArraySize = 42 DEF OtherArraySize = 2 * ArraySize + 17 * The right hand side must be a valid compile-time expression made up of either: * Literal values * Names defined by other ``DEF`` statements * They can be combined using any of the Python expression syntax * Cython provides the following predefined names * Corresponding to the values returned by ``os.uname()`` * UNAME_SYSNAME * UNAME_NODENAME * UNAME_RELEASE * UNAME_VERSION * UNAME_MACHINE * A name defined by ``DEF`` can appear anywhere an identifier can appear. * Cython replaces the name with the literal value before compilation. * The compile-time expression, in this case, must evaluate to a Python value of ``int``, ``long``, ``float``, or ``str``:: cdef int a1[ArraySize] cdef int a2[OtherArraySize] print "I like", FavouriteFood Conditional Statements ======================= * Similar semantics of the C pre-processor * The following statements can be used to conditionally include or exclude sections of code to compile. * ``IF`` * ``ELIF`` * ``ELSE`` :: IF UNAME_SYSNAME == "Windows": include "icky_definitions.pxi" ELIF UNAME_SYSNAME == "Darwin": include "nice_definitions.pxi" ELIF UNAME_SYSNAME == "Linux": include "penguin_definitions.pxi" ELSE: include "other_definitions.pxi" * ``ELIF`` and ``ELSE`` are optional. * ``IF`` can appear anywhere that a normal statement or declaration can appear * It can contain any statements or declarations that would be valid in that context. * This includes other ``IF`` and ``DEF`` statements .. [#] The conversion is to/from str for Python 2.x, and bytes for Python 3.x. Cython-0.23.4/docs/src/reference/interfacing_with_other_code.rst0000644000175600017570000000032212606202452026127 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _interfacing_with_other_code: *************************** Interfacing with Other Code *************************** == C == === C++ === ======= Fortran ======= ===== NumPy ===== Cython-0.23.4/docs/src/reference/index.rst0000644000175600017570000000071612606202452021526 0ustar jenkinsjenkins00000000000000Reference Guide =============== .. note:: .. todo:: Most of the **boldface** is to be changed to refs or other markup later. Contents: .. toctree:: :maxdepth: 2 compilation language_basics extension_types interfacing_with_other_code special_mention limitations directives Indices and tables ------------------ .. toctree:: :maxdepth: 2 special_methods_table * :ref:`genindex` * :ref:`modindex` * :ref:`search` Cython-0.23.4/docs/src/reference/extension_types.rst0000644000175600017570000004115312606202452023657 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _extension_types: *************** Extension Types *************** * Normal Python as well as extension type classes can be defined. * Extension types: * Are considered by Python as "built-in" types. * Can be used to wrap arbitrary C-data structures, and provide a Python-like interface to them from Python. * Attributes and methods can be called from Python or Cython code * Are defined by the ``cdef class`` statement. :: cdef class Shrubbery: cdef int width, height def __init__(self, w, h): self.width = w self.height = h def describe(self): print "This shrubbery is", self.width, \ "by", self.height, "cubits." ========== Attributes ========== * Are stored directly in the object's C struct. * Are fixed at compile time. * You can't add attributes to an extension type instance at run time like in normal Python. * You can sub-class the extenstion type in Python to add attributes at run-time. * There are two ways to access extension type attributes: * By Python look-up. * Python code's only method of access. * By direct access to the C struct from Cython code. * Cython code can use either method of access, though. * By default, extension type attributes are: * Only accessible by direct access. * Not accessible from Python code. * To make attributes accessible to Python, they must be declared ``public`` or ``readonly``:: cdef class Shrubbery: cdef public int width, height cdef readonly float depth * The ``width`` and ``height`` attributes are readable and writable from Python code. * The ``depth`` attribute is readable but not writable. .. note:: .. note:: You can only expose simple C types, such as ints, floats, and strings, for Python access. You can also expose Python-valued attributes. .. note:: The ``public`` and ``readonly`` options apply only to Python access, not direct access. All the attributes of an extension type are always readable and writable by C-level access. ======= Methods ======= * ``self`` is used in extension type methods just like it normally is in Python. * See **Functions and Methods**; all of which applies here. ========== Properties ========== * Cython provides a special syntax:: cdef class Spam: property cheese: "A doc string can go here." def __get__(self): # This is called when the property is read. ... def __set__(self, value): # This is called when the property is written. ... def __del__(self): # This is called when the property is deleted. * The ``__get__()``, ``__set__()``, and ``__del__()`` methods are all optional. * If they are omitted, an exception is raised on attribute access. * Below, is a full example that defines a property which can.. * Add to a list each time it is written to (``"__set__"``). * Return the list when it is read (``"__get__"``). * Empty the list when it is deleted (``"__del__"``). :: # cheesy.pyx cdef class CheeseShop: cdef object cheeses def __cinit__(self): self.cheeses = [] property cheese: def __get__(self): return "We don't have: %s" % self.cheeses def __set__(self, value): self.cheeses.append(value) def __del__(self): del self.cheeses[:] # Test input from cheesy import CheeseShop shop = CheeseShop() print shop.cheese shop.cheese = "camembert" print shop.cheese shop.cheese = "cheddar" print shop.cheese del shop.cheese print shop.cheese :: # Test output We don't have: [] We don't have: ['camembert'] We don't have: ['camembert', 'cheddar'] We don't have: [] =============== Special Methods =============== .. note:: #. The semantics of Cython's special methods are similar in principle to that of Python's. #. There are substantial differences in some behavior. #. Some Cython special methods have no Python counter-part. * See the :ref:`special_methods_table` for the many that are available. Declaration =========== * Must be declared with ``def`` and cannot be declared with ``cdef``. * Performance is not affected by the ``def`` declaration because of special calling conventions Docstrings ========== * Docstrings are not supported yet for some special method types. * They can be included in the source, but may not appear in the corresponding ``__doc__`` attribute at run-time. * This a Python library limitation because the ``PyTypeObject`` data structure is limited Initialization: ``__cinit__()`` and ``__init__()`` ================================================== * Any arguments passed to the extension type's constructor will be passed to both initialization methods. * ``__cinit__()`` is where you should perform C-level initialization of the object * This includes any allocation of C data structures. * **Caution** is warranted as to what you do in this method. * The object may not be fully valid Python object when it is called. * Calling Python objects, including the extensions own methods, may be hazardous. * By the time ``__cinit__()`` is called... * Memory has been allocated for the object. * All C-level attributes have been initialized to 0 or null. * Python have been initialized to ``None``, but you can not rely on that for each occasion. * This initialization method is guaranteed to be called exactly once. * For Extensions types that inherit a base type: * The ``__cinit__()`` method of the base type is automatically called before this one. * The inherited ``__cinit__()`` method can not be called explicitly. * Passing modified argument lists to the base type must be done through ``__init__()``. * It may be wise to give the ``__cinit__()`` method both ``"*"`` and ``"**"`` arguments. * Allows the method to accept or ignore additional arguments. * Eliminates the need for a Python level sub-class, that changes the ``__init__()`` method's signature, to have to override both the ``__new__()`` and ``__init__()`` methods. * If ``__cinit__()`` is declared to take no arguments except ``self``, it will ignore any extra arguments passed to the constructor without complaining about a signature mis-match. * ``__init__()`` is for higher-level initialization and is safer for Python access. * By the time this method is called, the extension type is a fully valid Python object. * All operations are safe. * This method may sometimes be called more than once, or possibly not at all. * Take this into consideration to make sure the design of your other methods are robust of this fact. Note that all constructor arguments will be passed as Python objects. This implies that non-convertible C types such as pointers or C++ objects cannot be passed into the constructor from Cython code. If this is needed, use a factory function instead that handles the object initialisation. It often helps to directly call ``__new__()`` in this function to bypass the call to the ``__init__()`` constructor. Finalization: ``__dealloc__()`` =============================== * This method is the counter-part to ``__cinit__()``. * Any C-data that was explicitly allocated in the ``__cinit__()`` method should be freed here. * Use caution in this method: * The Python object to which this method belongs may not be completely intact at this point. * Avoid invoking any Python operations that may touch the object. * Don't call any of this object's methods. * It's best to just deallocate C-data structures here. * All Python attributes of your extension type object are deallocated by Cython after the ``__dealloc__()`` method returns. Arithmetic Methods ================== .. note:: Most of these methods behave differently than in Python * There are not "reversed" versions of these methods... there is no __radd__() for instance. * If the first operand cannot perform the operation, the same method of the second operand is called, with the operands in the same order. * Do not rely on the first parameter of these methods, being ``"self"`` or the right type. * The types of both operands should be tested before deciding what to do. * Return ``NotImplemented`` for unhandled, mis-matched operand types. * The previously mentioned points.. * Also apply to 'in-place' method ``__ipow__()``. * Do not apply to other 'in-place' methods like ``__iadd__()``, in that these always take ``self`` as the first argument. Rich Comparisons ================ .. note:: There are no separate methods for individual rich comparison operations. * A single special method called ``__richcmp__()`` replaces all the individual rich compare, special method types. * ``__richcmp__()`` takes an integer argument, indicating which operation is to be performed as shown in the table below. +-----+-----+ | < | 0 | +-----+-----+ | == | 2 | +-----+-----+ | > | 4 | +-----+-----+ | <= | 1 | +-----+-----+ | != | 3 | +-----+-----+ | >= | 5 | +-----+-----+ The ``__next__()`` Method ========================= * Extension types used to expose an iterator interface should define a ``__next__()`` method. * **Do not** explicitly supply a ``next()`` method, because Python does that for you automatically. =========== Subclassing =========== * An extension type may inherit from a built-in type or another extension type:: cdef class Parrot: ... cdef class Norwegian(Parrot): ... * A complete definition of the base type must be available to Cython * If the base type is a built-in type, it must have been previously declared as an ``extern`` extension type. * ``cimport`` can be used to import the base type, if the extern declared base type is in a ``.pxd`` definition file. * In Cython, multiple inheritance is not permitted.. singlular inheritance only * Cython extenstion types can also be sub-classed in Python. * Here multiple inhertance is permissible as is normal for Python. * Even multiple extension types may be inherited, but C-layout of all the base classes must be compatible. ==================== Forward Declarations ==================== * Extension types can be "forward-declared". * This is necessary when two extension types refer to each other:: cdef class Shrubbery # forward declaration cdef class Shrubber: cdef Shrubbery work_in_progress cdef class Shrubbery: cdef Shrubber creator * An extension type that has a base-class, requires that both forward-declarations be specified:: cdef class A(B) ... cdef class A(B): # attributes and methods ======================== Extension Types and None ======================== * Parameters and C-variables declared as an Extension type, may take the value of ``None``. * This is analogous to the way a C-pointer can take the value of ``NULL``. .. note:: #. Exercise caution when using ``None`` #. Read this section carefully. * There is no problem as long as you are performing Python operations on it. * This is because full dynamic type checking is applied * When accessing an extension type's C-attributes, **make sure** it is not ``None``. * Cython does not check this for reasons of efficiency. * Be very aware of exposing Python functions that take extension types as arguments:: def widen_shrubbery(Shrubbery sh, extra_width): # This is sh.width = sh.width + extra_width * Users could **crash** the program by passing ``None`` for the ``sh`` parameter. * This could be avoided by:: def widen_shrubbery(Shrubbery sh, extra_width): if sh is None: raise TypeError sh.width = sh.width + extra_width * Cython provides a more convenient way with a ``not None`` clause:: def widen_shrubbery(Shrubbery sh not None, extra_width): sh.width = sh.width + extra_width * Now this function automatically checks that ``sh`` is not ``None``, as well as that is the right type. * ``not None`` can only be used in Python functions (declared with ``def`` **not** ``cdef``). * For ``cdef`` functions, you will have to provide the check yourself. * The ``self`` parameter of an extension type is guaranteed to **never** be ``None``. * When comparing a value ``x`` with ``None``, and ``x`` is a Python object, note the following: * ``x is None`` and ``x is not None`` are very efficient. * They translate directly to C-pointer comparisons. * ``x == None`` and ``x != None`` or ``if x: ...`` (a boolean condition), will invoke Python operations and will therefore be much slower. ================ Weak Referencing ================ * By default, weak references are not supported. * It can be enabled by declaring a C attribute of the ``object`` type called ``__weakref__()``:: cdef class ExplodingAnimal: """This animal will self-destruct when it is no longer strongly referenced.""" cdef object __weakref__ ========================= External and Public Types ========================= Public ====== * When an extension type is declared ``public``, Cython will generate a C-header (".h") file. * The header file will contain the declarations for it's **object-struct** and it's **type-object**. * External C-code can now access the attributes of the extension type. External ======== * An ``extern`` extension type allows you to gain access to the internals of: * Python objects defined in the Python core. * Non-Cython extension modules * The following example lets you get at the C-level members of Python's built-in "complex" object:: cdef extern from "complexobject.h": struct Py_complex: double real double imag ctypedef class __builtin__.complex [object PyComplexObject]: cdef Py_complex cval # A function which uses the above type def spam(complex c): print "Real:", c.cval.real print "Imag:", c.cval.imag .. note:: Some important things in the example: #. ``ctypedef`` has been used because because Python's header file has the struct decalared with:: ctypedef struct { ... } PyComplexObject; #. The module of where this type object can be found is specified along side the name of the extension type. See **Implicit Importing**. #. When declaring an external extension type... * Don't declare any methods, because they are Python method class the are not needed. * Similar to **structs** and **unions**, extension classes declared inside a ``cdef extern from`` block only need to declare the C members which you will actually need to access in your module. Name Specification Clause ========================= .. note:: Only available to **public** and **extern** extension types. * Example:: [object object_struct_name, type type_object_name ] * ``object_struct_name`` is the name to assume for the type's C-struct. * ``type_object_name`` is the name to assume for the type's statically declared type-object. * The object and type clauses can be written in any order. * For ``cdef extern from`` declarations, This clause **is required**. * The object clause is required because Cython must generate code that is compatible with the declarations in the header file. * Otherwise the object clause is optional. * For public extension types, both the object and type clauses **are required** for Cython to generate code that is compatible with external C-code. ================================ Type Names vs. Constructor Names ================================ * In a Cython module, the name of an extension type serves two distinct purposes: #. When used in an expression, it refers to a "module-level" global variable holding the type's constructor (i.e. it's type-object) #. It can also be used as a C-type name to declare a "type" for variables, arguments, and return values. * Example:: cdef extern class MyModule.Spam: ... * The name "Spam" serves both of these roles. * Only "Spam" can be used as the type-name. * The constructor can be referred to by other names. * Upon an explicit import of "MyModule"... * ``MyModule.Spam()`` could be used as the constructor call. * ``MyModule.Spam`` could not be used as a type-name * When an "as" clause is used, the name specified takes over both roles:: cdef extern class MyModule.Spam as Yummy: ... * ``Yummy`` becomes both type-name and a name for the constructor. * There other ways of course, to get hold of the constructor, but ``Yummy`` is the only usable type-name. Cython-0.23.4/docs/src/reference/directives.rst0000644000175600017570000000014412606202452022553 0ustar jenkinsjenkins00000000000000Compiler Directives =================== See `Compilation `_. Cython-0.23.4/docs/src/reference/compilation.rst0000644000175600017570000004310112606202452022730 0ustar jenkinsjenkins00000000000000.. highlight:: cython .. _compilation-reference: ============= Compilation ============= Cython code, unlike Python, must be compiled. This happens in two stages: * A ``.pyx`` file is compiled by Cython to a ``.c`` file. * The ``.c`` file is compiled by a C compiler to a ``.so`` file (or a ``.pyd`` file on Windows) The following sub-sections describe several ways to build your extension modules, and how to pass directives to the Cython compiler. Compiling from the command line =============================== Run the Cython compiler command with your options and list of ``.pyx`` files to generate. For example:: $ cython -a yourmod.pyx This creates a ``yourmod.c`` file, and the ``-a`` switch produces an annotated html file of the source code. Pass the ``-h`` flag for a complete list of supported flags. Compiling your ``.c`` files will vary depending on your operating system. Python documentation for writing extension modules should have some details for your system. Here we give an example on a Linux system:: $ gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing \ -I/usr/include/python2.7 -o yourmod.so yourmod.c [``gcc`` will need to have paths to your included header files and paths to libraries you need to link with] A ``yourmod.so`` file is now in the same directory and your module, ``yourmod``, is available for you to import as you normally would. Compiling with ``distutils`` ============================ The ``distutils`` package is part of the standard library. It is the standard way of building Python packages, including native extension modules. The following example configures the build for a Cython file called *hello.pyx*. First, create a ``setup.py`` script:: from distutils.core import setup from Cython.Build import cythonize setup( name = "My hello app", ext_modules = cythonize('hello.pyx'), # accepts a glob pattern ) Now, run the command ``python setup.py build_ext --inplace`` in your system's command shell and you are done. Import your new extension module into your python shell or script as normal. The ``cythonize`` command also allows for multi-threaded compilation and dependency resolution. Recompilation will be skipped if the target file is up to date with its main source file and dependencies. Configuring the C-Build ------------------------ If you have include files in non-standard places you can pass an ``include_path`` parameter to ``cythonize``:: from distutils.core import setup from Cython.Build import cythonize setup( name = "My hello app", ext_modules = cythonize("src/*.pyx", include_path = [...]), ) Often, Python packages that offer a C-level API provide a way to find the necessary include files, e.g. for NumPy:: include_path = [numpy.get_include()] Note for Numpy users. Despite this, you will still get warnings like the following from the compiler, because Cython is using a deprecated Numpy API:: .../include/numpy/npy_1_7_deprecated_api.h:15:2: warning: #warning "Using deprecated NumPy API, disable it by " "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp] For the time being, it is just a warning that you can ignore. If you need to specify compiler options, libraries to link with or other linker options you will need to create ``Extension`` instances manually (note that glob syntax can still be used to specify multiple extensions in one line):: from distutils.core import setup from distutils.extension import Extension from Cython.Build import cythonize extensions = [ Extension("primes", ["primes.pyx"], include_dirs = [...], libraries = [...], library_dirs = [...]), # Everything but primes.pyx is included here. Extension("*", ["*.pyx"], include_dirs = [...], libraries = [...], library_dirs = [...]), ] setup( name = "My hello app", ext_modules = cythonize(extensions), ) If your options are static (for example you do not need to call a tool like ``pkg-config`` to determine them) you can also provide them directly in your .pyx source file using a special comment block at the start of the file:: # distutils: libraries = spam eggs # distutils: include_dirs = /opt/food/include If you have some C files that have been wrapped with Cython and you want to compile them into your extension, you can define the distutils ``sources`` parameter:: # distutils: sources = helper.c, another_helper.c Note that these sources are added to the list of sources of the current extension module. Spelling this out in the :file:`setup.py` file looks as follows:: from distutils.core import setup from Cython.Build import cythonize from distutils.extension import Extension sourcefiles = ['example.pyx', 'helper.c', 'another_helper.c'] extensions = [Extension("example", sourcefiles)] setup( ext_modules = cythonize(extensions) ) The :class:`Extension` class takes many options, and a fuller explanation can be found in the `distutils documentation`_. Some useful options to know about are ``include_dirs``, ``libraries``, and ``library_dirs`` which specify where to find the ``.h`` and library files when linking to external libraries. .. _distutils documentation: http://docs.python.org/extending/building.html Distributing Cython modules ---------------------------- It is strongly recommended that you distribute the generated ``.c`` files as well as your Cython sources, so that users can install your module without needing to have Cython available. It is also recommended that Cython compilation not be enabled by default in the version you distribute. Even if the user has Cython installed, he/she probably doesn't want to use it just to install your module. Also, the installed version may not be the same one you used, and may not compile your sources correctly. This simply means that the :file:`setup.py` file that you ship with will just be a normal distutils file on the generated `.c` files, for the basic example we would have instead:: from distutils.core import setup from distutils.extension import Extension setup( ext_modules = [Extension("example", ["example.c"])] ) This is easy to combine with :func:`cythonize` by changing the file extension of the extension module sources:: from distutils.core import setup from distutils.extension import Extension USE_CYTHON = ... # command line option, try-import, ... ext = '.pyx' if USE_CYTHON else '.c' extensions = [Extension("example", ["example"+ext])] if USE_CYTHON: from Cython.Build import cythonize extensions = cythonize(extensions) setup( ext_modules = extensions ) If you have many extensions and want to avoid the additional complexity in the declarations, you can declare them with their normal Cython sources and then call the following function instead of ``cythonize()`` to adapt the sources list in the Extensions when not using Cython:: import os.path def no_cythonize(extensions, **_ignore): for extension in extensions: sources = [] for sfile in extension.sources: path, ext = os.path.splitext(sfile) if ext in ('.pyx', '.py'): if extension.language == 'c++': ext = '.cpp' else: ext = '.c' sfile = path + ext sources.append(sfile) extension.sources[:] = sources return extensions Compiling with ``pyximport`` ============================= For generating Cython code right in your pure python module just type:: >>> import pyximport; pyximport.install() >>> import helloworld Hello World This allows you to automatically run Cython on every ``.pyx`` that Python is trying to import. You should use this for simple Cython builds only where no extra C libraries and no special building setup is needed. In the case that Cython fails to compile a Python module, *pyximport* will fall back to loading the source modules instead. It is also possible to compile new ``.py`` modules that are being imported (including the standard library and installed packages). For using this feature, just tell that to ``pyximport``:: >>> pyximport.install(pyimport = True) Compiling with ``cython.inline`` ================================= One can also compile Cython in a fashion similar to SciPy's ``weave.inline``. For example:: >>> import cython >>> def f(a): ... ret = cython.inline("return a+b", b=3) ... Unbound variables are automatically pulled from the surrounding local and global scopes, and the result of the compilation is cached for efficient re-use. Compiling with Sage =================== The Sage notebook allows transparently editing and compiling Cython code simply by typing ``%cython`` at the top of a cell and evaluate it. Variables and functions defined in a Cython cell are imported into the running session. Please check `Sage documentation `_ for details. You can tailor the behavior of the Cython compiler by specifying the directives below. .. _compiler-directives: Compiler directives ==================== Compiler directives are instructions which affect the behavior of Cython code. Here is the list of currently supported directives: ``boundscheck`` (True / False) If set to False, Cython is free to assume that indexing operations ([]-operator) in the code will not cause any IndexErrors to be raised. Lists, tuples, and strings are affected only if the index can be determined to be non-negative (or if ``wraparound`` is False). Conditions which would normally trigger an IndexError may instead cause segfaults or data corruption if this is set to False. Default is True. ``wraparound`` (True / False) In Python arrays can be indexed relative to the end. For example A[-1] indexes the last value of a list. In C negative indexing is not supported. If set to False, Cython will neither check for nor correctly handle negative indices, possibly causing segfaults or data corruption. Default is True. ``initializedcheck`` (True / False) If set to True, Cython checks that a memoryview is initialized whenever its elements are accessed or assigned to. Setting this to False disables these checks. Default is True. ``nonecheck`` (True / False) If set to False, Cython is free to assume that native field accesses on variables typed as an extension type, or buffer accesses on a buffer variable, never occurs when the variable is set to ``None``. Otherwise a check is inserted and the appropriate exception is raised. This is off by default for performance reasons. Default is False. ``overflowcheck`` (True / False) If set to True, raise errors on overflowing C integer arithmetic operations. Incurs a modest runtime penalty, but is much faster than using Python ints. Default is False. ``overflowcheck.fold`` (True / False) If set to True, and overflowcheck is True, check the overflow bit for nested, side-effect-free arithmetic expressions once rather than at every step. Depending on the compiler, architecture, and optimization settings, this may help or hurt performance. A simple suite of benchmarks can be found in ``Demos/overflow_perf.pyx``. Default is True. ``embedsignature`` (True / False) If set to True, Cython will embed a textual copy of the call signature in the docstring of all Python visible functions and classes. Tools like IPython and epydoc can thus display the signature, which cannot otherwise be retrieved after compilation. Default is False. ``cdivision`` (True / False) If set to False, Cython will adjust the remainder and quotient operators C types to match those of Python ints (which differ when the operands have opposite signs) and raise a ``ZeroDivisionError`` when the right operand is 0. This has up to a 35% speed penalty. If set to True, no checks are performed. See `CEP 516 `_. Default is False. ``cdivision_warnings`` (True / False) If set to True, Cython will emit a runtime warning whenever division is performed with negative operands. See `CEP 516 `_. Default is False. ``always_allow_keywords`` (True / False) Avoid the ``METH_NOARGS`` and ``METH_O`` when constructing functions/methods which take zero or one arguments. Has no effect on special methods and functions with more than one argument. The ``METH_NOARGS`` and ``METH_O`` signatures provide faster calling conventions but disallow the use of keywords. ``profile`` (True / False) Write hooks for Python profilers into the compiled C code. Default is False. ``linetrace`` (True / False) Write line tracing hooks for Python profilers or coverage reporting into the compiled C code. This also enables profiling. Default is False. Note that the generated module will not actually use line tracing, unless you additionally pass the C macro definition ``CYTHON_TRACE=1`` to the C compiler (e.g. using the distutils option ``define_macros``). Define ``CYTHON_TRACE_NOGIL=1`` to also include ``nogil`` functions and sections. ``infer_types`` (True / False) Infer types of untyped variables in function bodies. Default is None, indicating that only safe (semantically-unchanging) inferences are allowed. ``language_level`` (2/3) Globally set the Python language level to be used for module compilation. Default is compatibility with Python 2. To enable Python 3 source code semantics, set this to 3 at the start of a module or pass the "-3" command line option to the compiler. Note that cimported and included source files inherit this setting from the module being compiled, unless they explicitly set their own language level. ``c_string_type`` (bytes / str / unicode) Globally set the type of an implicit coercion from char* or std::string. ``c_string_encoding`` (ascii, default, utf-8, etc.) Globally set the encoding to use when implicitly coercing char* or std:string to a unicode object. Coercion from a unicode object to C type is only allowed when set to ``ascii`` or ``default``, the latter being utf-8 in Python 3 and nearly-always ascii in Python 2. ``type_version_tag`` (True / False) Enables the attribute cache for extension types in CPython by setting the type flag ``Py_TPFLAGS_HAVE_VERSION_TAG``. Default is True, meaning that the cache is enabled for Cython implemented types. To disable it explicitly in the rare cases where a type needs to juggle with its ``tp_dict`` internally without paying attention to cache consistency, this option can be set to False. ``unraisable_tracebacks`` (True / False) Whether to print tracebacks when suppressing unraisable exceptions. Configurable optimisations -------------------------- ``optimize.use_switch`` (True / False) Whether to expand chained if-else statements (including statements like ``if x == 1 or x == 2:``) into C switch statements. This can have performance benefits if there are lots of values but cause compiler errors if there are any duplicate values (which may not be detectable at Cython compile time for all C constants). Default is True. ``optimize.unpack_method_calls`` (True / False) Cython can generate code that optimistically checks for Python method objects at call time and unpacks the underlying function to call it directly. This can substantially speed up method calls, especially for bultins, but may also have a slight negative performance impact in some cases where the guess goes completely wrong. Disabling this option can also reduce the code size. Default is True. How to set directives --------------------- Globally ::::::::: One can set compiler directives through a special header comment at the top of the file, like this:: #!python #cython: language_level=3, boundscheck=False The comment must appear before any code (but can appear after other comments or whitespace). One can also pass a directive on the command line by using the -X switch:: $ cython -X boundscheck=True ... Directives passed on the command line will override directives set in header comments. Locally :::::::: For local blocks, you need to cimport the special builtin ``cython`` module:: #!python cimport cython Then you can use the directives either as decorators or in a with statement, like this:: #!python @cython.boundscheck(False) # turn off boundscheck for this function def f(): ... # turn it temporarily on again for this block with cython.boundscheck(True): ... .. Warning:: These two methods of setting directives are **not** affected by overriding the directive on the command-line using the -X option. In :file:`setup.py` ::::::::::::::::::: Compiler directives can also be set in the :file:`setup.py` file by passing a keyword argument to ``cythonize``:: from distutils.core import setup from Cython.Build import cythonize setup( name = "My hello app", ext_modules = cythonize('hello.pyx', compiler_directives={'embedsignature': True}), ) This will override the default directives as specified in the ``compiler_directives`` dictionary. Note that explicit per-file or local directives as explained above take precedence over the values passed to ``cythonize``. Cython-0.23.4/docs/src/reference/Makefile0000644000175600017570000000417012606202452021323 0ustar jenkinsjenkins00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html web htmlhelp latex changes linkcheck help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " web to make files usable by Sphinx.web" @echo " htmlhelp to make HTML files and a HTML help project" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " changes to make an overview over all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" clean: -rm -rf build/* html: mkdir -p build/html build/doctrees $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html @echo @echo "Build finished. The HTML pages are in build/html." web: mkdir -p build/web build/doctrees $(SPHINXBUILD) -b web $(ALLSPHINXOPTS) build/web @echo @echo "Build finished; now you can run" @echo " python -m sphinx.web build/web" @echo "to start the server." htmlhelp: mkdir -p build/htmlhelp build/doctrees $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in build/htmlhelp." latex: mkdir -p build/latex build/doctrees $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex @echo @echo "Build finished; the LaTeX files are in build/latex." @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ "run these through (pdf)latex." changes: mkdir -p build/changes build/doctrees $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes @echo @echo "The overview file is in build/changes." linkcheck: mkdir -p build/linkcheck build/doctrees $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in build/linkcheck/output.txt." Cython-0.23.4/docs/src/quickstart/0000755000175600017570000000000012606202455020120 5ustar jenkinsjenkins00000000000000Cython-0.23.4/docs/src/quickstart/sage.png0000644000175600017570000016142312606202452021551 0ustar jenkinsjenkins00000000000000‰PNG  IHDRÝ  ’€þsRGB®Îé pHYs  šœtIMEÙ  MxJÀbKGDÿÿÿ ½§“â“IDATxÚìX[ǯ­x¯­ØÝz¯Ý­((¶XØÝ!© ‚€‚„ Hww7¢Ò¡R‚4ß÷Âèܹ[Ì.K(ïÿù?ûœ9sfNÌ™™ßœ=;ûÇÿP( …B¡P(TSël …B¡P(ª‰¡D„Þ'D£Ñh4F£ÑèÆ÷3­Èåh4F£Ñh4r9F£Ñh4\Ž\ŽF£Ñh4FÿÚ\6rq?Gô/z›aWiÚ"ṃF£Ñhts°£Ã;gG[¾q9yƒoB.oЬ›ÁüÞ…\Ž= F£Ñè舰@s3³WFub®ð/€ÀèÛÅùÅåì[´p°—Ÿ@sÖ<Î;Gí2¹„½bùR:õÚ±c1Öñ;w&¸ç–Ôõ;¶5—wïÞý‘š*À´˜Øf–Ûîß·wá‚ùD+Í›'|`¿™ È,À¯†\uu´†F>ŠÀ®.œ?ËsaŸÇž1c:çp(|jij>>ÑP##áxº;C7=wö´íªU+ÈÅ)S&ÉFŒþâù3xЄ‡Š½{vmX¿–¹²ì²`Ù˜<÷UÞj]ÿbpî9ìNFj×"Î)0”óÐÁýx¹D£Ñh4ºAEg-/óË™ÙqÀ€þäÈ<°H¯^=ù5¿\PPüɪ£Ã;>r¹á ½I'‹£G2{mL§^šÿA¸˜ï\½z¥ÖõúÏWf®W¿~}¥n^Ìâ@f}úôqr°![ LæãåJ&ƒú*+݇$îÛWx·>îÚµ ù½»p(˜´ÔuXknfBÝP€7ùɰئMæ"A<–•e™ËÆä‹y¨5_ŠÁ¹ç°;©]‹<§ˆž€—K4F£È6ÖoE¨“È©Žxeb Éø6^ÌDåb"_ÆËaÏPb²è|ärð”)“ žëcÉ3gNg. ËzE„öïß@ù§Zÿ=ÂÔãåp,/^Ø­[·…HôgØ–¡•H„eHöDCmØÐ¡`ÝÚÕ7o\­Ï1 ô=uòøìY39€CÁ :‡%rhv‹¦Æ†Óþù»S§N 9=s,“çvà¡Ö|)çžÃîd¤v-–ÅC£Ñh4Ý@\ðÍüÆpB\$€ $ ÆÔøÃåýúõõöäÏ$ƒ©ãåN6üårÍÇæÏŸ á9³Ÿik2†]½âª*Mž4Âð ¼;kÖ þÒÃÚÄø(í§{÷îÅn¼œú­,²Û F£Ñè†0 K(§&àçüòsgO-\0ßÅÉ.>6âµ1̓/\~`¿ÄâÅ ü~Ì…eκK—¿Èoíy˜ë3jÔHÅû²cÇŒfYvõºpþ,Ð 1ä|ãú•¾}/^8Û@\¾vÍj;KÀè§ZÝ»wgYk ‰ÝäŒaxÒØ'±‡]@´){ïv=Ÿ‹Ïž9I¶»p.˜—ë°¡CÏŸ;Í—wëÚ„ »:ÛÃáÀåÌY°lLžÛ·Z׿œ{»NKm(âœ/^´žÓðЉF£ÑhtƒnÊ6Öoˆ×°Ž‹ wv´¥¾€?\ž è3`@ÿ¶mÛéüñk~9<^ˆlÜбcÇž={0¿ t( À󨹒‚\›6m”åYV]½¬ÞšÁVÄO ½ leiÞ@\®ª¢d YŒ9BWG‹e­á0‹‰nê\+G9‹GU† LNcàùuêÔiÞìô©ô¹ü±ÆÃ… Aú÷ïFœ¹œ! –Éóã¹Öõ,çžÃ®Ó²|Ë&‘ œŸàÑh4F×ßÄ{ߘ›ŒNüГ—÷$¢'/Y²HEYÛ¡%_dŽF£Ñht#ÛÄØø;,ÄŸ`tScCbôD˜—×ÿ?y,o Œê̱¹! K˜yïî­#†SßÚþûµØ/q,¨ë6ç?¥B£Ñh4Mð˜Ùkcs3â—~ ïOÄñò4J*4`ù.H4Ž—£Ñh4n|¿³¶°·cýÛHär4F£Ñh4ºé\ŽF£Ñh4F73.‡4F£Ñh4Ý$þÁå P( …B¡P¨¦ÕÿP( …B¡P(T“ ç—£Ñh4F£Ñø»O4F£Ñh4¹¹F£Ñh4F.G£Ñh4F£ÑÈåh4F£Ñh4r9F£Ñh4F.o¹GF£Ñè_Ú||-Þ.ÑMn>p¹½ûë†&ȨÈÐ_‚t㣘ÝÜŸÆP( …ú•ÿw…_7D¼]¢š¼?×—Ë­ íííš WžÔœqÜÚÉëè—K=³Qqäzùi;T××z gšÉ: ö—ÝõÅ‹û‡ 0¸ZòpJJŒùð>öcRܧ ÉŸÞ§&'¥¥~LOû”‘žœ™žR㌟NOÈŒ´dHÉ 1lÂæ°>Z P( U§àFÖ˜\ÞÈgx|[f®—[Øë:::êÙÐÔÁÁaá±þa!ÍÊÃÂÂŽHÌØõHú™¯¶M¬¥_Šu@š¡Ë{•×aâWM§lU~kët®cê°`Ÿ:o˜P~|bíCÛ"""˜?ÕÄWq…æ?¹ü”§|zÀ Ø•‘š•ž“ñ9'“Á «²2SÐ!q Íñ"‚B¡P(ärärTÓp¹É»Ç®®®òzçìì캃.:Ú?33sÍÙÑ¡ÁÍ Êc¢#fízxXÁpüŽQÔ~U?‘»n»ïPô>ó4DÃ&ážAà$1ŧÖZF6SÄ Y-Á#”Kˆ?ݵžù¸Esâ¨× –ˆO®…rYÙ*Ârr¤«ÁövÅ&&¥ææ%D$™ 6 asär …Bñ]eeeñµ*--m&\>dgÀëQô\Þ•ó9ÇÆÖú™ÞS•ŠÚ:šÖï,323øÏåo”?2¼[TTÔ8ãåOM”óòòÖžÒlÐ<1>ꌼÉa¹wvA†®u’ ]?=wþ l{Ó b¯Š¯¸‚÷=ÓhY£‰[”'mU•1.ðóŒ£?dNòÍAAAÃçÓík¨Ÿ>>>ðÉ-šGýcR\òÇ„Ô䤌ôä"—­zü¸ÂаÌÛ»èCRaVVAî×ü¼ÜüÂBøÌ“—¯®%õšd6IMùü1v‚ …BñWß¾}:OKKk>\ÎøðPYõ¥°4ãkqVÞ÷âÒ êªÀ^]Ë[¬ª««ýü}uõµ³²²JJ¿Ã³eqq1„_ê¹{¸UVVòËŸ™É”?4*((Ð2UhœñrÈ뉉\nnîšs£ƒýš—[9x.•|úÊãÓÝ碗К(ªü·¸êÚÓÏ%ïÛ=²Š¿¢¶KÙç†aÄýב²¯"Z'—»:ÛG†'ÄEråO÷n Tž3UWWWuþ?~*¾’øtrrºÖ¹sÍ£‹øÊÐÐPúhþ“Ëã“?%¦§~ÌÊLÚ–—¯/,ÈÏýZhbR®¦öcÈû,Dñmp¹eDX M.—ݵf¤||*Ïž À­uõ²¡¡¡ÊÜ©£%¶ÌÑÑQªO襤$é~}íííµÄ–× ùÖ4/CŸ>ħ$¿ÏHKÎÉJ'&®|ýZ˜Ÿ_heUN"øýûÕEEEJJÕ_>k?­ü_•“‘‘žœ’œ;A.G.o’"Ç£P¿«à¦ŸM„?תYq¹¡ca¿ùÆÒª¾éYÿα±rü2t峎#¯ä|-B.oѽ÷ë—§Úšeåå»än…ê¹|P·M¼o+©î+¡àò%·à…Ä^¸\ÕàŠ»»›Ò‹Kp¶È¾8'Ìc“{ùùùÆŒŸêÆwÒÒÒ–@Â@ù ­½,÷Ÿð ÷â$ä¨lX“ûú cüý|šË¬×Ÿx:t­Ü ù§úzÚ/ ôÌÍLÞY[ؾ{kmeaöÊèÜ­‡Ä”¤ CkÒ8ª$ó:¸ÜÆú }.ñâ…ö¡m~~~ê«„uuuÊ‹‹‹u•kÐ\x ´@yVVÖË—†€æ×: xxxhm^±˜m.¯™Ä’™‘ò9'h[Q¡*5µHG§@üåËnl\™ûõ;45«¾~)VTüÁë° l˜šòvBŸËây㪨¨¨aÆ1„›3—sØI||ü²eËjX$â«««/^¼Ø­[·îÝ»_¾|y‹o¸&âöH5g“eÈÍ̓vîÕ«—””T}ʉB¡b€îï™™™ÀŸ>}Љ‰!¿ë¯¨¨€EˆLMM… V5!—;ùô6“Rv B9¡œÜ’¢ïD˜\^XXhnn.##—÷›7ojkk“_& —7C¹º9§¥¥>0 Wxü>×/ዉw pùYÝГšʯC32Ó­ßYÖ‹ËåžöðpWxq.''ç¶þ81ˆÏ;ú222néí‡OiÝýéééÒÏöAðÝÞÞ>&&„f/>Ôö|WïHÍj÷Cì“Ì…ÌQîÅ)xn¹8Ž74iøü+AELù’‚½µƒ½µ—‡KP Oxh@dx|ú{9:ÚÌÜ¡´çžíɧÁ‡Ó ’2Ž.v§Ïå€×Ùš" }}}UfO('Ñœ„rø„0´¶¦ÈH©}P€žæe(ùcbZʇ¬ÌÔ/Ÿ³µõõËccŠ!`bRQ\T¬®^3‚^Pöó7 åÉŸŠ‰ð—ÏÙ°aZíóFær•Ç3„Q.Ÿ2e 0b^­®_¿>uêT"þÉ“'³fÍJ¯ž>}Ê[|Ã5·Gª©¸œ,ÃÖ­[÷ìÙóµV»vízöìÏåD¡P|à8Üâ¿×ª¼¼œaâ €8Dª’’H€ÎËK`ù~hˆç —Ÿ{”Ý}ú“:kDår®ŠÄpKÍÏÏ"wppÈÍÍ…v €§êE¹¼¹ÉÈØ°¸øÛ~E›àŒÔÏʼn…oÒ¤Œ#¥£ÞÄžÕô),,ÐÖÑäËoköôô{~N†ëÏvÀùpMg{JJÊUímÉÉÉWžŠÃçe­­ð,{IsëÇO©¯µ ÷¡  `;;»ëZ»/>Ùû¹¬Y³·ËO·Öîì r¬É÷YÍçýCÙÙÙ›.Oôñöäöµƒ^OO—Ê_¾¬®®ÎËýLŸË/+šx{{‚‡ûEG†ÄÇF@$áØè°ÃÒús÷k]ѽjNøŠA8p¹í»·Àî\Œ—÷ññÑ\?ÏÛÛ[eæ*šÃ± ¡ZH£¹aWãåµ\þ1+3íë—l@í¤÷E^^?&‘»º–ÖŒŽçåëëÿ;——¯.ÏÉ)„lÖ¼•… —?~üxðàÁíÚµô %"©ïÏgþ{ÈËË÷éÓG@@@BB‚ú|*±­^½ÚÌÌŒ!L&€«öºÔêàÁƒ°HÄÃ5ýÌ™3½zõêÖ­›¢¢"™””´nݺ?ÿü³C‡+W®$¿6¥‰¹"r±±±?~<$†Mˆë&s5©ûïØ±#YMØI§NˆðìÙ³‰0„……y‹gh"®êé544†Ú¾}{¨”§§§®®îÈ‘#‰Í¡§‘÷ËË—/÷îÝ ì[XXÈœ5»v†ºïÝ»·  àýû÷©ÍN'ë:µ ;ÜÕˆH@ó¹sç²ìQ(ªI7µœœ:)áüÍÈÈàÀåp£ß°~-C ;`àŠË«ÿ÷¿IbN‚s5¸âr®ŠÄpK555%/ïÌ‚˜W¯^ݨÕëׯÉçvñp+466¾zõê­[·\]]I'UUUp#“––†4,_†ƒâ,'j¥¥%{œõ]?XeX¦=²M¼û*úá»§gµü ¿ªœy¼>Ï>ÞwÙ³ëÞ¿Z½öóÑÚ„„„“WÃ3Ü®ûSCBB.ilçv¼€^\v\XXØ!•…°·SjkÓ‰ýŸQ_W“ããõðyîIMîç4× o¾: М>ý“T­¡¡NB¹¦¦&€Å·Â|®à@paê|FD„Ž\(œÁEï;;ÚÒÿÝçñòµs¼¼¼4×̆OåéãH4(‡«˜TïÞ¶¶¶ÄZâ“ëñòÔÙ?¹<5õÛýûÕäÌò„„’‚¢¢oE@áW¥¦~ÏÌ,ÎÏûÏyÊÊU°I6G.DKKK+**‚“úôétÆËaqÍš5ÙµTºxñ"sʲ²2ÀǼ¼<†0™àܹs°-ìZV¬Xqþüy".1Ë—/‡néOŸ>MDŽ7®wß¿ÏÏÏ?uêÔŽ;˜eEØåÜW@¸Á#åþýûÙ “1¢¢¢°[ÈJ%%%‹D<Ô«  €,g Þ⚈«º@úM›6ÁS1ô·{÷îýõ×_bbbäâ¬Y³ˆd·oß^¶l4,9@ö‘#G˜³f×ÎpG²^§6;¬ëá@œ)''´(OC¦Ñ\=‹ëñr —çåØÛ—©ªVikW™™U¤¤|‡–çå§¥}wp(:ÏÌ,Š-ªù…h]\èC„¡¨mÛ¶¥Éåð0F„áÙLHHˆ¹»»¹¹Íœ9“9Lîªÿþ°-Ž0`†½‘³·Y ÊÙ»wofàcYv¹ 8:Ü]8T“á3xð`â2 ôôt"¾uëÖäÍ mÚ´á-ž¡‰¸ª ¤ÿòå ™ža‘ÜŠG„¯™³f×ÎyÄ!kj³ÓɺÎÃD-<óìÛ·/·V,Ó P¨¦\C’’’˜ß"G\Ù>~üw@â÷3uÎ/ ö›ðÝ»œã!@^-áºÊÌå222äÀô·nÝÂnÉ­Ü=Ü>|xÿÂ1î¢NàÓh)£¨Öñ/Ü>½ ÊÐvH|d˜˜ockÍ —×ü{NLˆ‡»›Ø•)>|Ø«0388x˽1T˜‘éçç·ñæ__ßõׇûøøœVÞìàà@¼|®d/ ƒõׇÁ6Ü{¹9ÂßßSíþIX‡|·Ü èyQ]Rˆ(ÿQ¯¨P--Mx^,ÿð>–«m=|§l{`šiœa”nþÚóÓ²£ÚRªFa!þq1á°søûzúx¹zy¸€Í-mo©™Ð,'ÇËŸ¬˜îîîþdÅ4ʉ9åpa¢Î5Wþg‘ÆÃÃûùå?汘˜”|+,(úø±$<¼ÔÙ¹²øüùûÏ7—×¼›åËç"—‚Ë9Ïca¹X'—SèC’U×®]»~ý:s˜Ü )Ë@<ó›¶¼½½çÎÛ¹sg‚Œ[µjE³Àìrîºnݺž={6ÌÒÒ²N._ºté7Èùå°Èßñr–MD³.u,"é©ßÌ’mHÍš];3dM¿ŸÐóòò<*»–‡ÿ´§úcR\qñ7øäv†º£«W —‡dÓ ’Ô¼ù2â’†Óª æ¦>ÞnÄts0zlt0}Ï5ýµÇ5!†~›ãå5À½tê»wï¤z÷ú÷‡ž½{1ü Tyê77·'Ëþæ~~ùß}ª¨TffÄD“þVøï XÀjjU™Evv¥Üþî“>o‘£§ n©š1c´ s˜:^N‚…Eãå…±±1\òà \KøØåBö‡Œ$?\Þ¡CêürX$Âüš_β‰hÖ…&8å¿~P³f×ÎÔñr¸¼ðË©e JGGgûöíœÓ P¨&Qjj*ù+ªˆù\qy½åäÃä?gkÉ=õ¥/1íûøz½ç?é8þÙI‹ÿñï},pñdž_N/'crrr`±ÎxÎãå÷îÝã0mESaá¡oÌ ¿¾rO¼þ<ø’~ð­—!ÚÖ!p,ôôŸ]»qy÷Þ¡¡!*³žØ|û<©° öJq3ä¸öò“ŠÝÝÝ.¨Š×Êëóòr{7àrÕwAGŸR8÷,ôÁ›¨ñ›äTµ<Ý£"jÅ!ñ3Pti5ó!«eOÜ5dçv¼üñ’É×’’’H(·¶¶Vš<ŒDs­«—Ÿ={¦&<ÖÕÕ•«ñr†÷$‚ƒƒ¾ÇÄü "ÿœó„rˆ|ù²"-­è?ïI¬yy}.ïÖ­9çy’­[·.§Vk×®¥þ<œØCnnn×®]ËËËÂÔ,Μ9CNR_¹råÙ³gÉaQæùå=zôxóæ \î¡y·nÝJøØå"..ý¿¬¬ ŽQ¯^½XV“ºŸ©S§’ïc¹qãÆ?ÿüCÄ?~üP›x¿ ÈŸÞsÏ®‰hÖ…&ÃE|õêÕïß¿¯¨¨€ ÍÈœ5»v>þÕ¤è÷Âà @s;;;æ½Á'`úò³BAAA‡eÖ¸¸8ßzr¨iÿTȾf¼\õµOÊ¥çaguB%ø]{qá‰çD1¥×µõLl¼||=}üÌlÜä5ßÎÝûhòÖÓviÈ?6 ö#~$J'#8Ô¶,x¼`œ`Ò}iÊá¤z¼`<œ9J‡š”¿|ùRqü`ˆÑÚºÒÏÏOrtWžÿW[÷ýþýê·o˳³¼ÝȨâë—oN?þõ“»ÿ"ïÞ½û矲[¤¾eÏž=Ô!"Íëׯ ‰j˜š€×¾}ûþª`‘ˆ‡‹û©S§»wﮬ¬LD¢ 6¬M›6j>¤Ïåìr122=ztÛ¶mÇý™e5©û¾½hÑ¢NµZ¼x1yש®®†«d·Z]ºt‰úžrúñ욈f]hÂ1\»eddˆw¡L˜0ÁØØ˜9kví ‡x÷îÝPw8è ïc©?—3”î4ýû÷'ÞOø,{ …jZÁÓ;<äaÀИZ‘ã»p$ï Mû¿BÞa9]ÿ6è<ÕøÁ«´âÒ'‡|¨ì0Hñî#~Ž—ƒòòòLMMÎáò.%%ÀMþ(nm°êz­ @>Æpˆ‡ûñ>À†Ë—/3p9Ü>\\\ˆw¥+))………a·äYÀâîn&¯Œ4ž¨ºº9{yyJìߣ¤r_GW“@ó°°PÞ¹à»ìÄàÐÐÐ7„£¢¢„õlh4?|w@ù¾[5ÿp©¨w¡Éÿì“àò®UÌ£TÞÄ^{¾KÉç”VðÝMWÌçÔ·Yy‚˜Ê´sê.=oµæªýQÓ׿AÞq1á4¹ÜÕÂNµ­µh>ìÛ·o¯  kÌãääD|*M ç§ÂØÖÚº üøÄ>!Áþ4/C“â“?%¦§~ÌÊL•“­"Ð\Q±*&ºøë×o¹¹ßr²‹ÔÕ«"¿ÇÇä~Î)PU­}g¢llÂæ°~ý9Y¯¯–””TUUe£êl®–“5WeÀ^„B5+}üø±¬¬ ¸3==½¢¢¢²²2##(?}úD¾‰µi¹¼†• KõÌÂÅO9ÿ9I¿ãHƒK´…–éLØd öÔîSjÎÿ~…ÿûÌÎΖ••Å^×È !Ð\û™¦®þSÉ#êÅåàš±m!€ÅC·×ÚÙÙ54/<Ò/<<|çõùo7-”S¹üÖ‹À±"÷'mU¹ò,èœNˆ¸¼—ø}o ¿}*~{•ý¶ß÷¹ã±FÊuÕu— âNI©ÙÙXúÒ/g@sqhm¹µPNù|8cD ”oYNÊ)\—ü±f*KFz²,pùO4WV®òö*.,Ì/ÈÏÿúµ 9¹ÐѱÄÖ¶„)‡d6I­™\ž;i4.6lXtt4sUgsµœ¬¹*ö"ªY©ºº(<55µ¸¸˜ÿýûwˆR'¿$lr.'UU]ý½´´‚é2Í–Ë---¡=á GGG‡|?ªIÐ\^AæÒ•‹õårpXhÐâcý}}}g¼\ìâtûoT›ÊÉùå#×ËOSº~OYâŒü¸M ‡”Ý?Ú¡à-r×c­´ÛÊ®+®»,½ê¼à¼Íxqµy;å_è¹»:rõ>–£æ€àÌŸÜB9yÔ?¼ýø!>ùÓû´Ô²µ´-ûÍ««ÞX”8Ø“óˉx2YÍ›X>½‡Ía'Æå( …B5—ϱEßÍ–Ë===¥¥¥¯]»öòå˲²2ìKM¢°°PÉ#ʉ?Ú«/—ƒ#ƒíß8ã倿¯í´›”\îåë?g÷C-=S sÓ7榷•µÇlŸ³_{ã ÛÍ·E¼b/|ÒbòÝëeEÈhëhÚÛY‡ùq5XN8.&Üê¹&œ}HH©EóŒ´ä¬ŒÔì¬ôœìŒÏ9™ †HX••™š‘ž ‰aØ6OJŒm´/ÝP( …j*.oã-µÅöçzq98*"dÙ‰A ÝAÞ¹5(ÿñâÈØˆÈð @/?âÓüÍ›£×ÕgïT˜ "7t­ìè r3Åå6’‘QP1zùjÄLÿ…¨Pû 0PSxñâÅþa,?ŽüËÍÅÐR†ûÑ’'ŽzRb ‰æÉŸÞ§&'p§§}òÎLO©qÆO§§@$€;$€dÉ?¡6‡àE…B¡PÈåÈ娦äòÚç kèêîó®YA91dh &^RâïíébokenfblôÂÈPßÄØà¹©ƒ½µ—kxhýŸ{2 r,ü<»¾ý}=! o/7È+ÐßÛÕÙ>"<(8Ð76š‹—£ó÷Bƒ …B!—£Ñ<›?\Þb M5éÀßA>À;Þîð ¬ñÉÐ~šÊ̇F.G£ÑhtÓp¹šÚ÷g:v¶éAï£"ââbbâcc`mB\Œ¬lE³år¼'ý~íŸuýæ™ÂsÏ]¼A]‹'Ïž™9w®Ô-iÞ¸\Y¹@C=ËÄ8ÆÎÆÏÅÉÃÝÕ k=Ü\îÝ+C.G7š=ÝΜ;;cŽð‘Ç=Ü©«Ü]9G˜ìçÛvïÚµOˆœ€rxø$ûù¬ùó‘ËÑh4º™û°ä–H ñ¼p¹¼|yhpâc"q‚¿uŸåGEÆS\ i8Œ—7þ"—ÿ~\~îÂ@“§:š²r÷ž¿Ðݾs×Aè×’5PþÒØ@IEQïù3ñ;.]¹Ì-—ËÈ”8Øù¨ªæˆk¨gü­¡‘DNLq¤áŠËâyûú:ýû÷cÿÞ\®¤ ÷ÏßSÛ·oߥË_Ë—-±zkÖ<¹œ·æ¢³Õ‘ãÇwìÞCöóm;vî’Ø»ko ”“ý|ëŽí'ND.G£ÑèfîÄø¨ ë×2@9Ä@6 °G;v\³zUxh,²qC§N{õêyñÂYên©fYNæ\è´si̲¨Û·m•“½K¦‘•¹1œð–ô !!¡víÚ9ÂØè…¼Ü½!Cù¾³¶ “A­{öì- ºY$&*´á¸êuðÈ‘{÷jëx¨LÀÊácG¦žÓár5µÏ–oB ðX# Ð\Qñ„ÍÍÂMM¢ ×Óýhgã×ø\~òÄÑÖ1„o.Ÿ>íÅû²ŽöÖзED6£·4.÷psÜ-±oÇž=d?ß±c÷> ²ŸoÙ¾mïþý SÏ‘ËÑh4ºy:6:lö¬™$ïAbxœÇàŸôÎ:ƒÀî·o²âccäåËc£cµ4¿‘²²ÀåÑ‘qàË™ã÷ïÛ»pÁ| C?yó„ì— “bø1b÷ˆÃ_<pì·wÏ.xáËaÏÞž.‘áA§NŸ4qË­NŸ:1WxŽ—‡ `îæMwl' ¼téb(—a·d锓ºÈ¹˜K[gQ¡LŸ>í¡ª„¨*B8.&œsÁV,_êéî|îì©Î;¯Zµ‚\œ2e2™lÑÂPN0øÐÁý ú=0÷Ã’Û÷ìdQTº¯ÿ\¨Eõ¡’®ÀÊŽ:¡œ—Û¾ó7zG`·Á‹D7W™77µ‡_È9-5¿uö€3i?wÀà‰`tu4‰HRÌ‹D̑ǺwïÖ±c‡5«Wº:Û±D78{ïÝ•f“ \œl×­]ݹ³xýº5°HÄ»¹ØÃ³\×®]á¡îø±ÃD¤©±°ðìN:ÁƒÖÌ™ÓÉqhj‘˜+Â!švv´Y¹r9T³G÷îPe2;ÀÊ;¶uëÖ­C‡K/t°³bÞÖÉÁJˉ>ïË: žtñ‡¶}àfL„Þ ’É|¼\9£6 c=¸¦ @rmÚ´a¹‡ú;Ø[a`å^½za(¡«³=vv´¥î–Z`šå$9´ËÒÒ)*„…„„K€O×Y° o2ža‘ÚJPk" |ièù95h.)¹m×Nͧš Jò JrÚÏ´¶lßNÊÙq¹ƒõ¥+V–A€æ5ob¹[¦¤X`oëëhïíîê %rrß™¹ °ÒÂÌÄÉá6$(V‡‡&x{}äm s<õ=ì(™\456œöÏß:u"Æ®ˆI#Ür9Í‚QÉÈŒ Ìnsšå$¹m:EŸ8~b®\¾ÀsÁ˜[‰N9ùËåûInÙ±ý‘†š¬ü=¹;êÕÄwî”<Â;—…ëë}“+VUÉÓÒL·³ñû9ðìfo竀μ¬,ƒYÎc±±~CŽïB Ðärc£çDØøåó>½{3£Õ£‡ÊãÆe“»‚'.Ø–ê÷îÝ‹ÃÞ`‘´A9»uëÆÌå,+Â.š†ô¦Æ?jjôœÌá^èa þÝ»3l¨«£Ù¯__ÎéÓ§÷™Ó'îé´- µÔÍ«d$Ô‘ÈrÙ¹c|B˜åÌšÇ÷µ™Œa‘ÝVupùž½bÛ·QûùÖ;¨ohA.G£Ñèô>–çúy‰ñ5ï):ðKruN±0φ˜ÈðxòÍår²Q‘qoßdÕÉåpgŠ &ÂAÞÆËÉñWG‡w°È™ ¨*†û%ÆG……ø³Ûmý¹nÛÞž.Ìû²/§&£YNêx9Wí@§¨V–æCê 0äι-s+‘»‚u\¿Á üè6q%e©[7U(=x¨|ëÎMeU%ÑmÛ9ÂÃ<Í'žî5ï):·±ö77 ñü=Ä8;zÞ»[FÎcqqò0x‘XçürvÓµ™©ï¿#¹ê=»wìÙ½“9LîªuëÖ,wñ°È°·Ç'MšÐ±cGòŒfÙåBÓ ›“»e~z¤n¥ö@YP°–¦:ç?ÕҞݵK—þýûÉËÞåܶ²2· «–.]|úÔqr'{wÁ&ä„~ßúL⯅ò=›Å·2÷óÍââ»%öá<4nq\®¨Xïéñ‰úÿAÄsrQE¥4<4ÁìuN\>aÂøS'š2®\¹œŒïÒå/rÒXBb79_yþü¹û$öpæÂn]»>ÑP‹‰ 8^³zK¬¬s~9Ëx†‚;{já‚ù.Nv@~ï¬- /"J¸lé’@/0ÃürênÙ•“!2žÛvøÏ{KX52nÜØ¨ˆ`š șˡÖ?¦×/ZpðÀ>Îí_çq©ÊE¶l¹+sçòÕ‹r÷e7lÞ,"ºYAQîêõ˲r÷DÄÄ–äöwŸrrÅ€à–oB¨SYˆ)æä¢Âý"G/}½|äòÇtž³„7vÌ#5æðÆËþɆEãåÅ-év¶–žîNö¶VÌådW`v¹Ð4¤g9^Þ§Oo 3–›@9a+m- úÄ£p_¦GœÛ’ 6tû¶­ýúö…ÞNDê=Ó‚æ’¹{ ’‘[5-—P¾QLŒìçë7mÚ¸yÙÏ7ŠŠîÞ»—ùÑ ¹F£g.'ÈÛÙ1•Ds r uÊ!RG§ 4$ÎûX,ß¼lӦ̀ýá¾KÆŸ=sR@@€\XÝÔ¹V Ø‘>Öx8p ì¶ÿ~7o\å#—3,!.òü¹ÓÄ‹PFù@U‘œl½aúŽ;öìÙ€Ö²Ü-»r2äÂs;PͲ¨"7Ü»ûïî\»rIt³ÍäÌåäûX6‰l ¾7†ï\~úìYñë7¯ž:sBúŽÔZ‘’‡€Ô×mÚtûŽôù‹g¤oÝ\·IäÜÅ ÜÎc›½Š$шHýß™ß-ÓPÏv°÷¦ó>rñÏ?ÿ$çi0/B2aáÙĬë9sf,2ìÁöÝ›?;w&¦;SÃÔ,¶n%'RÏœ9]|«(9¸Î<¿žeen»:Û%/©}€¤ šìraØ„]ÒÏ›'üÎÊL_~èàþÙ³fš½¾Ô×Ó†"ñÇìcðB—‘/]²Èàù3€ìûò÷ºvíZgÛWžË—ÎÿœaòHxà‘—½;jägGšÍÂ|@ùÅå’GŽˆ“ý|ÍÆ;÷îR‡Oöóµ"ž8Ž\ŽF£Ñ-ŽËÁÞž½½>ÊÉV¼4üJr90ú3‚èÈ8ò_?±íí¬…„„ZV×iÄ{ÿtáyGOX¹xùªuëöîßèè³KbϪuk/]¾pöÜ)É#’3ç-àËÁ–oƒ­,ƒ͵Ÿ¦:9x‘ÀèêY®Îî/ž¿çŠËØGÌÚg¹H}gȪ•Ë©/9!Òܽ#4ü£„”05 €È5kV Ô $SÁó€8èÄñ#?fqÜ» ^­[·ê=}ê8}.g— M.wr°Y±|i‡ ²Àâð¬øó•#NðTE¼çdØÐ¡@Ìä¶ r´·fGŸÒR× O•C‡QR”«³mïÜ–@Ž4¯\¹ž*ɵÐVkV¯¤Ù,Ì”_\>mÎ\²Ÿ¯\»vÛÎð`fcýfëöm+×®!ûùŒ¹ø¿Bh4Ý"¹ÜËãSLTlltldx¼ªj‰›k²¯÷‡„¸àr%ŲÎå{w úz»/\0_Bb7ryùæ-éÅ+VHX²rŶ];ím­ÞY[X½5{kñj“˜ØÂ¥K÷ìݳ`é2éÛÒ^×ÏËÁ-߆‚»¹¸9;z**Z˜‡Y[z¸¹@¤¼|1K.o ÿ}ܰ~í©“Ç˜Ã¿´ tûõëÛ„ÿÐ9WxŽôÍkͼ•Î]¼°hùrèç‹W,ß¼e‹Á ]}=m]ÍgÚOÖmذ`Éèçó—,=ñ‚§»r9F·8.+(”ÙÚ¤×Αøñ2 ólbZ9éÛ|ׯ]îÞ½»€@ÍÛ#‘ËÈ@Û×n\«M<~ÔÉÁÆÚÊÂì•‘‰±Á+C sÓ=Ïœ}åúÕøØÞ¸,'÷ÝÄ(¦v.² ñ2–ÏßÓÊI7—÷ïßÏàù3æð¯è-b›mß½±|ójö¬™[·ˆ6 —{¸9]¼pvÈÁä«›­¶OŸ=ýÏla‰ýÆ/Ÿëë>Õzòè±úƒ'Õ´µ4¶nß6uƬSgN»»: —£Ñht årðýûåFF_ÈY+ÌÆvD7švGG†„‡xûz»ûx¹Â'„ÃBü£"‚amB\$oóXËÊ–èh§³V˜Ý8\þ;ùÔÉc]»víÔ©Ó²¥K8LJáÜ\Ìâªm!²_ß¾u¾à¥ù 9`·‹“­ƒ]Í—BðHóÆÜ>!lokåìhk9?` —£ÑhôïÆåhôïgf.G£?#—£Ñh4r9\ŽF#—£Ñh4¹¦Çåð‰F£Ñh4Ý ýƒËQ( …B¡P(¥(›¾+*Ê‘ËQ( …B¡P¨árš)ÿøãär …B¡P(ª¹œæT[är …B¡P( ¹…B¡P( …B.G.G¡P( …B¡Ë£"‚>T…Oär …B¡P(ªi¸<.&BAáþ…  …B¡P( ¹…B¡P( …B.G.G¡P( …B¡šË»ë4r9 …B¡P( Õ€\þm!—£P( …B¡P Åå4SòË322$%%ÇŽ;tèÐAƒ 2dذa#jĈÃk1cÆlÞ¼944´²²2$$dÞ¼y°ÕèÑ£ásܸq&L˜X+"0}úô+V;v,**ª¢¢‚9ßòòòׯ_/Z´ö 9B£F"v5~üøI“&Áþ—-[¶råÊ}ûöÀNŠŠŠ¤¤¤þþûoH<䧆þÔ0ŠˆÃao3fÌ8þ|p¯³œðØ@p¹††W\Þv+¹…B¡P( ¹¼‘¸ÜÇÇGHHØw×®] 4¹\II‰àrÎ\«\]]ûôéC ®Ïž=»]»v+V¬xùò%`:çì<<<:wîLryrròˆ#€ËÅÅÅirùéÓ§‰y,ÜrùŽÛqðiçŸËeË+ª™¥/91tKêå•Õ |OšÜðµÛçM×bFo$ê?ûpؽä‚âJ†Œ¾}¯<­–4j{àñ@ Ùø”ìRšùÒIÀPž€ØB( ÄÀVxú¡P( …B5 —<àuøðáG½wïž E÷(’••Õ××ÿúõ+À´ššà2.ÿ_í¯<zôèñçŸvèÐaܸq@ÉŸ>}ª¬ýüü`’Ëa“AƒÖ‹‰‰yzz³ÁÕ«W/_¾|鿺\«‹/;vlذaP5xðà–ËÓ¾Üì?S2´´¼Š%Ë–•W‰\‹f†oÑ1³ärh§£Ê‰Ì«ž /ü‰æDÌ™xj‚¿÷‡ä}« “o êâ–?lkÀ?C‡l<÷P( …B¡šŒËSRRDDDz÷îÝ••ºuëÖ¥Kâí+C‡555-))ÑÒÒ‚š\ÊÏÏ_»v-ìö)))I̯³lAAAT.ÿðáÀ`vell™À%$bæ§“/ý‚™¹¸Ù¸x5/Š[Áe Eý½«ÿ7~ ïWx˜°Û4;.'é°µ‚½ÔÕÕˆË utt.¯ówŸÿ«ý뢩S§víÚuõêÕÄ7Oœ8‘ššZç({xxx÷îÝYr9Aöu›¤¡ÿ§BT˜ÖµÉ‚ðÁû Ì=D,‹Kþ3§¨¤"‡n `Çå@ùÌ3LÈ7ÀP·*)ûwÏßK« r¤“/ý‚ ñ½=0(î^òPÈåXT¬>r9 v›æÂåuJCC€¸_¿~JJJ$—÷ìÙóÞ½{œ¹ |Ó¦M;v(óæÏܹsNž<™Í—£¢¢ýÉ÷—“\»¢9â΃¨0]YU½èd8,zFð…Ëa;.'S6—Ö>8ƒ…\ŽEÅê#—£ð0a·i .ÿöí°rzz:ñÉY?uîܹ֭[—«ªªÂž={\x}àÀ@䬬,€ì¬ŸÊ®<عsç &À†©©©ååå~~~C† à¾}ûvdddJJJZZs¾ pyïÞ½¸Š!,,ìââ2o•™™I”ÿ™ V•””Ðárgx ‘/8Îr ôì7žÿ™.Ò_¤fê£ÇÊó‘›ü½ÎÎóX8äK§`DÚÖ™ð)´ÉßÌý3^õPÈåXT¬>r9 v›ÆærYYÙAƒ ýW~ªÿþD€\5°V:ujÕªUß¾}•””€˜MLLÚµk1:t:tèèÑ£GÕjäÈ‘£~jøðáÝ»w|‡ÏóçÏZô¿ŸÓÍ!%ì᯿þ@â'³A ¥¥¥½½½©\žœœÎŒ\ÎÇvcXµjg`õ?ý=´.çÜàXÍê"SÿþßT‡©ñ¯œÜ±%.wvv>zôè¦M›Ö³Ò:ŠÖR´¦V»ví277/))IKKn'Vé™÷¶qãFHsåÊ___êëPÊË˹Ϟ=+**JdݹˆˆK7Ð]“¿w–¥mÐ*Ô¿¨à¾Sçoò{ú2…æ¯i8Ô…ºjÅö€†kú{ ¤§ñsóËOÝŒ=ß½÷D§ ‹=_ ñzæ¢2ÇÔÙàܯzŒw5×ý´TÌ·¢ÊÆ,_ž÷x;5x>Yšê0ñvRðýÊÉù¤häŽÍßú6,—WVVæççX§p¯ôôô‚‚â/îKKK³³³SSS9¤‡µ_¿~-++c(졨¨(++‹Ý†Ÿ? íÓ§p9à5p9”¼ªª ûL©‡`çPrú\º£—ÌüÈ,}ñéˆ!b5ßuó ’}AY_ËÈ'ŒÝDLh!ã=à ٧î´Ù6\x2üŠæÇ„oÔWžQK³3h¸xÀ^™øä¬RúùÖ™€¡.ßd1^áÿ µD.çû ƒzùcnÎ\ÎnŸMåuµªªnŠönŸlö»­’ؘ¨Ñ„\Þ„T´ù`È …„Ï_k¾öLøP´é@o$Ô´ŠNÖ–V…EB}^ˆü…¸¼>§Æ¯Âåõ¼RñýÊÉÛI\þ+)&&†àòµk×\Žà…jRQQS½uëÖ}ûö=xð <š’«ž?>|øðvíÚ7N__ŸÊåDXKKkèСíÛ·Ÿ8q¢µµõ•+Wú÷ïég̘ÎLóDøõë׳gÏîØ±cçΗ/_žÀ_.7~›1mµwŸINðib™A&xù&ãï^‚“k·|‚ò¨£>VQ³0·Éš±Æö©›Àî»BÓ\úÿí"z(ÄÅû ™¸  *8OÄ/<¦°Î Gò…Ü¡ ÄåC/¯¨†°¹-‡UÔ,l]sVlˆO*ª¨¬þò}ËáP£7¼Ü]èÜíØÕ‚H×ý´šŸ—WÉ©'A²#W¢~,>JZ³;ˆ·ÒÒ,*dDÂóZ†vÛz$4*¾æÿˈ*ظäpxšš½Þç­}6Üw¿U˜§Soxǯý¨¯ÌÃ÷Ë~[Í®‚Ô£ ¹C‚Ëyèf\åTA6ƒ8Y:ãå ϲm9Ô‚Ýaª?—šáJ³Žð<¥bèWœO™K÷âò ÊÃòY>o³,lÕÔ~™ ]ˆ·Sƒ!SÎ%¬ódáÜ&t® q¥¢ÙÙ5®ÊÃᤠfWçõœeŸ§sv×yÅÃñòÿ€ÛÍÍíöíÛ7oÞ”’’ºs玌ŒŒl­ä~ b¤¥¥oܸqõêÕsçÎŽ·«°Åû÷ïaˆh¨–,x4…s¾W¯^?nÀ³gÃb`àÓ@€™°áÄð÷ï߉ÅÄÄDb?­ZµjÓ¦ ;. !‹ŠŠ`‘LÉ._¶-À;0—\ô È%®¼ ñÑñßÈm9¬¢f·ŸÄÿþŽ%+§tñžïvœçdz«±-Y `#êbá·Š¾Sy+-çsuuÍäNwÆ/ë9ߥB£ ¨UXA©ó&BÓ\B(é© ÈŠ@úN©£‚ MÒ0ãå!`j•YRR{{e …ç­‚Ô£ ¹C‚ËyèfÜrùÞ3Éiß«ªª³?—]–‰Ûr8´Î#;t–Û‡”ï°jø7v1t…C-ئú7ìBQ?ËŸœCaC(P,C¿¢ʰkjI GÀ¯Üüò›Š üârÎ%¬ódáÜ&MÅå4KÅî¨qËåìN š½—fãp8R®xzr9 …¢«ˆˆˆþù§mÛ¶ƒ ÒÐÐ` d]]ÝaƵk׎øÛæÆåìfR_qE}!—¡EúÔå5/ÏZ,æYÐs‚S«²€ëµðF_Ø3\‚œÌùRÆÃÝŽæ¿u°¬C2΋\•–·?Ö›ÐÜÚ,l®yãÃûȼs‰7£AÛRßÒÀŒÛºæ¬ÞØwªó€j^À÷þc1Ï$æ<?(oo*ü_]?zã¡›ÑÏÝ3 wÏéðQsÝ{Mt=ßàk^9•XVü¡Î'¡i.ƒf¸j¿Leîñ™ÙÕ‚åaâK¿‚=C 2Îu„4!µ¯dèW4ORÌmE*6±ð ö3nQÍD–›ÓœzNçÒDóda×&\]âJE³TìŽýòp8)hö^úÃîìfwÅãÜ£ËQ(Ôï£ú'£´Ì¸ér»ª™þjgìftúR3oüúœ ñïxUüåNnËÃÇëyà ¹…BýÂ7 v£˜Mâ_«ð¿n;ÿêGЫܱaÑ-á0ýÆÝ¹…Bá@Nݲ°ÍZ°Ù¯Ï$§QóܯÉÇ—•WÑYÕœG¡~¡3ìf¿VãóëŒàoÕxæTö@ŽZ=ËÓ@×ó†S³àòñãÇgeeaÀbcv#eee–›s˜êZç,X–zòäI¯^½úõëghhˆg> ÕÒx¹«ß¿…÷+¬««Ë/.§–0$$dêÔ©mÚ´aH™=zôhìy( …B¡P¨fÇå #F|­ÕÈ‘#‰˜±cÇš£2„¤^}}}â_» Lýßor?Öµ"÷«¬¬¬€’™G©###‘+**øÈåd 'Mš¤ªªJþ?"¡êêê-[¶ØÛÛcÏC¡P( …B5G.?s挮®î³gÏΞ=KÄ´©U«Z‘Ô M„ gΜ9yòä/_¾P)6)++nÛ¶-¹Uuíÿ†1“ôÒ¥K!SüÍ—“%„3¾ÌõرcšššØíP( …B¡PÍ”Ë===×®]»fÍ///"fìØ±VVVÄØ3K†UsçÎ566þßÇËmll¬­­!À°3Iÿñ_ñ…ËÉ0<30Œ—S§Ñ£P( …B¡P͑˫ªª†ÔŠœš€>räH†d@jaaáÏŸ?SWYZZö®0}\ÎÌÓÌYpµŠš&88xÒ¤I­ZµbøwCB%%%ØùP( …B¡PÍŽËQ( …B¡P(ärär …B¡P( ¹…B¡P( …B.G.G¡P( …B¡ËQ( …B¡P(ärär …B¡P( ¹…B¡P( …B!—£P( …B¡PÈå( …B¡P( ¹…B¡P( …B.G¡P( …B¡PÈå( …B¡P(r9 …B¡P( …B.G¡P( …B¡ËQ( …B¡P(r9 …B¡P( …\Ψ?êý]åä䈉‰ñ½` ”¾>[ñ·¦|s‘x«Z‹6 …B¡P¨ßËMMM{÷îÍGÄi¶\Î÷šÖ_,‹„Љ\ŽB¡P(ª%ry“#N£qy3„9äKl7 …B¡P¿<—ó SË‘/‘ËQ( Uç…›¨6é¯Äå,ã©‘œGÙgϞݩS§?ÿüsÞ¼yoÞ¼a¹‡AƒA²+V°ÌÔÙÙyùòå={ölÓ¦ ìjÆŒ666 I‡ºÒ‹¹¹¹gΜò´oß~Ô¨QÊÊÊÕÕÕœkš““søðáþýû·k×nàÀ’’’Ô¼`Ÿ„òwîÜyãÆ©©©ìrgh ÎugW¤ú vÕg'u iÛ¶-ìsêÔ©•••S^^>iÒ$ˆxXËÕÁýøñãæÍ›ÿúë/H)//«<==………;vìØ¯_?mmmæMÖ­[›tíÚuïÞ½_¿~åÐCê<ˆ( ÕüU'[4• ¦iÎ%Ä&ú›¹¼FçÎc^{ûömæýi¥K—2gjkkÛºuk†ý@Œ……ECpùèÑ£òRPPàPSÙaÆ1¬0`@ff&‘ ´´À”º–šç¦à\wú\NÿX°«>KÕY÷K—.‘>„Å[·n‹W¯^åöà RÓÀã 45FWW—a!!!j8 p,X6QA¡P(är„Nl"äòæÎåìÒ8::’œ—T+øZµjåîîΰá?ÿüóéÓ§ÏŸ?‡……1ïaUVV.***..~ðà±â‚Ë'L˜Å(,,@{B¥ˆ8,›¨ÎŠ P(r9B'6rù¯Êåëׯ'"ÉùäH'Æ–––t C¨¼¼œXÛ±cGúNŸËIT†&b€&9d$MÎE EbqÊ”)DaaarŽ õe—;CSðVw†H®Ž‡ê3«Îºƒ<<<à"Û´iCŒ…{ÿŸ½3‹â¼ÿ¸„+ÆË}šVÏ*¨©¨5µ"¦šŠA#`+jmÿFã•hlŽšh¼ŒŠxð`ÅŠÓ¦Mcæ_Õ6@c//))á9¢pEJw³éÚµ+“ [·n¼’Ù¡P,™7šõؤk!Ð}EÔöáïÿ;õÿ÷šu°¢¢‚NëëëÙòòr^/ I<B¶Í„Pƒ•‘ÈŽ¼Ò‰!bÔZxyë{ymm­5d&G‰ºº:^FÅyMF¹TUZ\\LÆÆÌ¹Šÿš£Æ^Îýšc“zʃ¬v(TÙ'‹f}ç6éZt_µ}g¸ví•™™ÙÌ*6UUÅþš˜˜‘pG^/o!mÕÖéL—uïå©zyMM Â.VCkkk €ýŸ*RZà¬Y³ØEÉÉÉ-êåMMÓ©S'&°ªªJiE]»veƒª/ç …f}ç6éZˆyUˆï;ÃèÑ£Ù¢üýý›ÙAµ!ìéO?ýÄÚ?bii©4‹ÈŽ@[÷ò»·¯ûûÍêîädlllaÑõ¶?T¯¼\Ç-”9üÛLMM{ôpÙ´a]+Ú¤ø!bgŽ:wîÜ·oŸysÿvãúeý¹ñÐÃ!5/777gŸ={Æ„\½z•—˜ìäNµ¾õÖ[Là±cǘï¿ÿ^ÕšfáÆtéÒ…9%›–Ú–ör¥=8p w¹³"ŠëËÙåÝj» ¶ïJ›ÄK£ñµP;°jûNìÛ·IcooÏœ?^|›ã剄 ¡‘gBÆŒ£4‹˜Ž€x¹‡Ç¨™3}b/D?|pd.pë¦7Þ¦W^®ã:::¬ýòßI‰wNøþ­·þØV¼œ9HL¸õÃ÷Gý|ß³µµ½xVO¼\‡Ôp¼¼ÿþLø?ÿùÏòòòÄÄÄÁƒ«òf©Tš››ËFFF2}ûö•6BLHLLL“¼üW¿úszøðᢢ"ÞªíîÇ"æÛÓÅ‹3&L())ùî»ï˜ÓßýîwL‚ÀÀ@v¯º½IIIéÕ«—H/WÛw¥M╦ñµP;Œjû^\\L,(ÄÙÙùñãÇÌRûßüæ7•••Z¼¸ª³wïÞ>|úô©››²cÇ¥YÔv ÃËMMMïÅßTu1&zܸ±¯¼òŠ™™ÙèÑîÿ¹vùÖÍ«ôWúöÍkl ±²²¤’æùóæXZZ¾üòËž'$ܽ¡-éÔq )Aô™b$/ùþÝw¦þ¹cÇ—­­­V,_ª!Ïyáܵ‘Z÷röñÏÌûm/^lèž½{÷211qrrüò‹Ï˜À”ä„Ù³}iкvíòчËT ,[ÔªVØÛÛ Œ€þ©áxypp0oÅ­¢Sþþ÷¿çnfÇæ7ožâ‚ÝåË—«­”¾hÑ"^!ìÂŒ7nèÒË•ö”T›D“×Bzq³3¯ÕÕÕ¬2°3èj½\mß•6I±4Í®…ÚaTÛ÷ùóç3áááÜ—»ÿ V.®ªÁämI>bĹ\®4‹ÚŽ€axùðáoxMšx$âàý{·yQ½zý&<ì gV’¼=yÎð™¾lélš¥KÏö÷¥ƒEïÿŸû¨‘W.] ß%µš9ã]mI§Ž[H:KÞyòD”Ú†ÌùëïÇŽ!g½~õÉ«H‰lÑùröq)ö¼5/–ä;8h+¹/ÅN›öø÷ùsÝ݆åέëÌ@©X¦(º¥aɨýRÃñr"((¨wïÞt Õ½{÷¹sçfgg󧤤Œ;ÖÜܼk×®&LàæýöÛoÝÝÝ;vìHŠ3|øðC‡‰©”.“É>üðC懩%k×®MJúùniêÔ©ºôrU=-..^±bݱÐ(YXX3›ú±úùùuëÖbÿö·¿±kô©(á«í»Ò&©ú½Ï¦^ 1Ã(Ðw’Zæ7ƒ† Æ,³©««c~b‰ý½O­\\U—’lûwÞéÔ©¹þ‚ Ø­f”¢ö"€x9ÙØüysz÷îEŽŽ$aÜÉfö‘˜pÛÒÒ’¢Ïœ dÜ£czîîäD’GÇNNŽg£ž%©²¶¶Ò–tê²…«V®èÙ³ÇÇ«>´µ±9¾ ¼KF«˜ØÎÎ.æÜiæøÜÙ“zåå)É ôÁÊ‹up°ÿä_«HÁ¹)ɘ©ñ…³ËuõÊEµ# ÿCÚö¼è’ŠŠ F {ôèÑÐåM&´s/giï“ÑzOû˨‘#˜ï¾=8tˆ[ÇŽÙ¯2ácF{lÛº‘¶nÙ0ÙË“ ämcÅ&Öâf#:h¡­­í©ßÓÁ±¨#..ÎAÛ6ÓñgŸ®f á>¨@Æþ™}›/'æÅFJ"ÆÛ­[7gçî!;·+ö‚}¨X^EªF@ÿ‡^þó#—ÌoÉd²ÂÂÂeË–1!~~~x9èÞËÙÉQSSSvò’ìöîíë$ÄñwþêϾov»º¦ƒÁƒýðýQv.6îòlØ¢-ìØñev:ùZÜTÈ¿V¯ôÛÇI„'wÏŸ=ÅÖNrIüyuû¸VñòþcþŸÿ½{÷úä_«Øykz,ùàý±cF_8†Ê9y"ŠÒkK:uÙÂ)~ÛÍm0©<¥¹zåâû ÿùÒK/uìØ‘·öƒyÌùÛìqãÆÞ¸~ù?×.SÉlíô§Œä‘tðÖ[TtÇ®]»°+j´½Ëmj¼¿ß,î~,lì$ωgNýð )~wÈ×ì2’Ÿ§¸¾\ÕÀòôWÕèÿÂËÁÿ¨­­ òðð°²²2iÄÙÙyöìÙ=ÂàÀË@—^öÍÇÿÁ¢«±±±½½Ý´¿L%f¢v|èìÜÂþµz%׺¾üâ3²«}ßìfCRS—.YäääHj¯½Ö›YF¢éÔe ÉüfÏöup°§2mmlfÎx—lïߟò§?þA1qRâ’Η_~ÙÊÊ’»y9h¿~}©ªë³OW+J䋾òÊ+ÚÝ…YmBÅöíóúÜ€¿±;¨pëݺeï_}•F7-{CCØ•èäñ _w³èºê£ÂËk³ªÐÿ!…—@_÷©·¿vÙUgC /¼^/‡—^/‡—cHÛŠ—/^¼¸EKnjù-מ67€í-©˜¢pðrx9†Èà‡Ô ¼\wáfŸ½9’ôàÁƒõë×/]ºôË/¿¼}û¶nDPã¼ñññëÖ­£ÖnذááÇJCÄäzþüy`` …Ð3+ INNþâ‹/(dûöí¥¥¥Ü›”x1^ˆÒÖRQuÿþ}n wïÞeO/^¼¨˜WÇ^ðrH'†^/ײH}üñÇ7oÞ”ËåùùùÌO¾ë³—ïÛ·/;;›Z{íÚ5j¹Ò1¹ÂÂÂNœ8A!ôÌôZ1dõêÕIIIBÏäؤĪ:«*|÷îÝ{÷îݵk7%Ý0?üY[[KwðrÐ.¤zû` IŸ[ˆ!2Ô!mc^ÎÌz~úé§Ììæ™3gHû+ÀÍ›››»mÛ6f~Z*•RÈãÇéxÅŠÇg×±ð²‹ÉÅ’••Eê¶dÉz~úô)S`ttôG}ÄX871“‘‘Q]]-ÐH**¢ê(„ªVÛ< ?{öìÊ•+IXïÞ½{úôi:^µjÕ­[·KSUBdd$…(½EEEŸþ¹pˆ@.fV›žSWB’MLÏÔ ÞÍŒÚÄÜ ûÒUú"¾‚¯+hCt(Ð&çËIz=zôïÿ›ŽIk®]»&“ÉÄkË–-¤Vr¹<99yíÚµBvåÊ•šššK—.q×—s³‹ÉÅBQÈD‘š3E]¾|™öàÁžbþôÓOGŽ¡òÉ®XµR¬ŽJ`«£òÕ6[#¹5åâÖ®XšÒ¨=d¨ŠcH6¼iÓ&îJÅá\|ðã¬T>ÝÀ( IHH ‰_¾|yTTÂÒ¤Ä eee?üðÝ{{9¥‰Ѹö†ŽÙ”äè4DT)]Ðââb¥^ÎÒo¾ù†)*==n ëâ¾t•¾…¯ ðë †~yù?þøÙgŸ‘¢Ñ)=SÈíÛ··nÝJ‚{úôiUâEÒÆÎ43¹(„Qy²"U^.&71Å8"%`<ò…êU ÙÙÙì:Åêè@±LæñjäÕ®XšÒ”Jyff&©$3k«*Dm.1óå,t«ÀÈ«À|¹@bê2wú_ñBÐm ÷ÿ-«V­¢6%yöÑ£G÷ï߯4¯âÒ×æÍ›é """--›Xñ¥«ôE(|E¾®/oq/_¶lÙÇÉfî߿ϕ’§OŸR„•””ðò’*ݸqƒì‡ Y¿~}\\•såÊ®ôp³‹ÉÅ‹âÍ—«ÒÁÀ‘ÿݹsgåÊ•ªª£\luÌt¬póTÕÈvWšp ,×®][½zuJJŠ@ˆ˜\d·ìqÆtC^4Î(çææ®[·îüùóÜ›”˜¡²²òÔ©S[¶lè @HH{JǦLOO§v‘âk’7¤Ä‘#Gâãã·oßÎK¬øÒUõ"¸‚/4ý:àåZöòÓ§OÔÈ™3g¸ëÂ?þøãèèh:•H$Ë—/çù Ið×_MbÄ.ÎVº´——]L.–ÌÌLÒ¬%K–ÐsVV–°?ݾ}›Ê¡Äôœ ª‘Š+Â…›§Öêx¥ —ÀÍÎ¥ººZiˆÚ\ÅÅÅÌrvz¦cJ£Â$þä“Oèú²³Â bó¾„@]£R7_(ûþ{{“œœÌžÒ1ãñb¾å©8¤/ÏÐ ‰âÊoÅ—®ª!¼zíåí6d]DºC¯­­ÅP^/­vÉV¬X!ü]Xx9ðr¼x9^@ïùÊïðÐøÁÌ»ÎéÏCŸÛf 6˜Æ|wšÔYx9x9¼^/Gwàå"ø®=¾·Ï¾ãÒx9ðr4" /o^ÞF?oÊËJÅ?N:¡TÎÐwt¿½õ4“n <àåðr¨¼Ý—ÃËÕØÉG.oŸrfx}Ç¥ofß©˜¢€‹ó¼\ƒ(x9¼^/Gwàå†ïåj‡’d')gí³ï¸ôÍì;ÏËEhhÍÌ^¿ÝºC3òÂËáåP+x9¼^®^®?·3x9.½>x¹ÚcCòráE,z¸”n /Gƒ!²ðrôröc ^®7-ðrx9¼\÷oU‘ÎÝ5ŸðÞMyyNa9%˜»5š 9}SJ!1w3Ù¹[ÏRHUü­•G›£¶ºÌ¨ÅÂÅ닪ñN¯x¬xÚLµ~yhÑ{´è‚ª4§ÍÍìo“ÆíÛ˜Ä'yÏkäµõ/^Èäu%ÕY?•h«%:ör^JêTfÞsê V†]à] Åëh^.üÏèöàåëׯ766¦g½ýïAKô¹ÜFFF]»vì]cFO½¾ûГúz5yÿ4㆘*¨Ìæ{ù© tìòä§R É-*gC(–B®&=ki6 /×L[Ô˵è¦ðr1¼ÔðìÔõÔOö^\¹;f÷qBšÞ¦½œ9þ(ä| ä?ÏòþJD^~/ש—롉êLÎêêê^}õÕÀÀÀ_ÿú×tÜ®¼üçÂËËïܹ³páBGGG’'x9¼¼9“Ð÷îÝ6l{Z__ß«W¯øøx6ËoûÛ¨¨(zÕ•––}:}¦¶¢ ìÚµ‹7F!šÉÙ‰'ÜÜÜè€dâäÉ“l¸L&[¼x±µµu·nÝ6nÜÈ›uã NUUÕœ9sº6@§l‚;vy˜šš<øîÝ»úÓwÅë¾zõê÷Þ{9NOO÷òòêܹ³¹¹ù[o½•——§t”&k—þÔ©Sýû÷§ëBWg÷îÝÂÝ©¬¬ôõõ}å•Wììì¾úê+]¾)šßw{9áêêÊŠ8ó¸qã¸YŽ;ÆMLo???æxæÌ™Û¶mãÆ’¸Ó#sL¥¸¸˜"íf œ±ù^.2ÏžŸåV¿:<–¢Ç­„ç$ë6Ï3)™@n‚ø¤RJ`7(ÆcÊõ„äRnóø¿ÕI{ù;Ÿ#/,­bN?Þw™ÒËk&#> ¿ÊRlÃx®;ÁæZ±çÇÄŒüjY-=î?ΧSžÅz~,‰ŠK{^^M÷`Š I>üýýÿþ÷¿·îÄ!×Q¸vÒT/Ÿ8qâ7ß|C{÷î¥c6|åÊ•üã©¿¤‹-R:Vìé’%K(/i\nnîŸþô§¥K—² Hמ>}Z^^þÙgŸqç[½ïŠ×=33ÓÞÞž9îׯ_LL ùèóçÏßÿ}ò¥¹T%ÓÿKOw\G­®®¦^³ Tu‡®ïÛo¿ýS#$îº|S4¿ïº÷ò­[·²CAï ºõåf©¨¨à&ÎÉÉqpp`Žé¶‡N¹±ôîëÛ·/;_îááqöìY¹\ΫQ8£V¼|Ó¦$z0ì³°—?Í©b½œ‰]ñEJq‰ìfüs®ŽsüsU媪ªû2ðÑ9K\´2_Nôì†Fv_|@Ççï<¦ç#—R…7üÈ+áJ9©@BúOÞk~˜öïâÓj0ƒÿª9SãÎñ³7žÿ¡’™irî²J¹òÊo.3!)Y…ûIXÜ„UG©Ì/_¿'Íçf|˜Uô×Mg(v×É:}ð¤‰]²ë"™µÄçË“ÿɬÉù*â?bbu?_¾?ºá¾ôѳ¢5á?Ò#ýY‘þ¬cÙuüÝ¥g}yðò¿¾¹pãÁ3F¤˜ØCc² ËÖ-\JnX¤q¹áE’]PÊšbkÍ—ÿ|7þSɦˆ«Ô˜“×RéôI^‰˜' §×-uyMø¥‡5ÄÒ©°š‹oü¹[éÜ”%åÕ÷Òó¸… ·œçoKCOÞYz?Ä¥PlÜý'ܼ'®=ÜqõCqWPë×bë/çËþ ªÎËÙ¡~Ôx!ö¾+ìå48tOãCÇ$JsŠEŽ^;Z_®xУG””æ˜ì“>[ýúŒ£ðì¤Ir–žžnccÃLoÓ3K¥R&ª{÷î>öÔÑÑ155õçÏ•‡œœØ………Ì1鈉‰‰þô]ÑTd2™©©©bíÔrµ~ÃM¦ÿ—ÞÙÙ9((ˆ»ÔA ;tAé¥Â.™Ð团ù}×½—ÓÝ‹•• Éq=g‘µb’lö}AŠÛ/vìØ‘‰-**Z¸pá¯ýë.]º oÚ´‰n«ÄdÔØË§MS³ã KɸöLÝ-z.;û# Å>yV%°@…ŽÓ¤?ß´P öƒc´îåäß 7GoÒñ=iÃ÷IþØPrrf…l…ü#è##£V÷rÆQš³ÈxéÒ¥¼ÏòeË–1QÆÆÆŠÓrª¼œ×ÖÖ*z†ªôúÐw¥óåìÌe\\œ»»{§Nx—›—KU2ý¿ô7nÜðòò"}$Ïûᇄ»Ã»¾º|S4¿ïº÷rbòäÉ¡¡¡ôþÚ±c/KII‰ªùr{{ûÊÊJµõæççûí·#GŽœ:uªÈŒÍß¿œ;_Îó”]ø{Ÿ®ø5Pž—3ŸOJ£´âå+¿iø¦lô­Œ·V­–Õæ—TR`va¹¼¶nª£N±Ëwÿo¥ ¥¡ŠbNé€N)k±ã?<¢¨¶¤þÔ—‡YEìÊuæA!L*äѳâÈ+©ï~qœ›ñý\Úø!ÓLKx°Ö.«ûùr™¼am;ÇLúãå2¹²±ú¥è8×°²‚¤œYB ëË™ãW×(Æ ¸ÒX Ôîh³=êFôG•ãö¼¬JiË?üeË¿¿tëá³çåÕÜ÷~ý/{ý!§×"¯ ¶öc¡ºžä=ç­EQëå C]+f¾œIù¬ ôJbæ.‰½öîåÎÎÎOŸ>}ÑzhýËÌ9÷›ŽR©”>oê|yZZ;_N§:ðrm}ï“eõêÕ³fÍbgˆI}ž?^__O"¥jßLUÉôüÒÿïÏ_}ýÉ“'ÙÕ;ªºCTé|¹Þmî{Ÿ ‰ÄÍÍ­wïÞ¼U+”…×Bîúr:8}ú47öÒ¥KìrÊ›››û¿ÿ—”°3âÂ_èêw…„íYi¬€|·„—OZI žSXþÏà†i¹K‰ ß¹›IÇï}½ªFÎZ¸H/Wª¶ŒÒÝNËýó§QÜØ™ëNž¿“ɬbg®¨*MÑËßþ$Ji¿„cáåŠV÷ÉÞ‹O4®(©høÔÉë©-íåµ;.|´û¼â²fz¹ŠYÖ¬^Î>BO6lj$rAvFã\þ¹[éŸ6^‘çË_nZ"æ jýI•—+mpS½|Ý¡+wÒrJ+jزM ^{÷ò/¾øbâĉ=’Ëå÷îÝ›>}ºÒZnKc­ËÙÞ½{'MšÄK3a„}ûö5¼°V­R\_Þ­[7vÝ·ƒ‹/öôôÌkä­·ÞúàƒÔzy“­E½œÌéÎ;ï¿ÿ>w?KKËï¿ÿ¾ººš|”®5›˜7ª’i÷UÑÝ÷Ýw“’’jjjNœ8amm-ܺ þóŸóá®/xS´s/§¥Á\¹r¥bf?–²²²C‡q÷c¡ƒÁƒÓ¡×$Ý“jÓk’î”Ø¼4ø©©©µµµŸ~úéøñãÅd$lmmoݺE—)::º©Ë¸óåÜ)ó¶èåì’fAË®“ ܸ7bä•»–ü‹™u, ‚Î ¬cQª¶”¥¤ñSöÉO¥Üïn²ÉÿŠdö‡!ñãåñé ÍþxߥŽÕ½—ëó:fíõ¾3ñªrJþCNI’ôÅK¤ætÌv¤…̬” z¹Ì =Í/ãg­»Ž…÷X¹;†»°D¸åÌ=ÉÇ¡?‹ìö¨j½\ílQ/g–ë°æ½õèõæ¯caÿúæÂÁÆoÁм«iï^^WW÷å—_2[‹ 0€û™×F½|èС§Nâ¥ùᇘogÊd2RUr‹_ýêW›7ofb׬YÓ¹sgÅÁ©¬¬üë_ÿÚ¥:`ÿ¥®ç^Î,½  4hùòåÜÝTÈœ~ýë_»¸¸²­â€ªdúïå‡~ýõ×MLLú÷ïæÌáîí½÷Þ{;v$½#gWá ¼)ôÖËÅ RÊ“÷ìÙ3;;[194Ý3û—Óm0oÿrÒîwÞyÇ‚†”^–$îlÔùóçéîÈÊÊŠ.i÷üùó‹ŠŠÄd$œœœ^zé%ºXGŽisó寕>©LH.ýÍÈØfzù¾³÷ç³é1ë¼Û®ªiÙõ‹™ï}Þ}”ç½æ‡¿üû(~ïS•ÏÙ|†™/«¬Y¶;–‰½“–÷IXÜ;Ÿ{kåQfQÍýÇb¼üý¯/4n=Q6wëÙ?}tdÆÚë¿»A· bbéñ¼¼aê÷¯›ÎèÆËâ¾´úèYÑ¿Ã~d¿ý¦ÊHÊ«n`6E\Õ—}ì&¹ Y#ÕG»Ï¯=xù»‹÷YsZýÍf㿈ƥ ‡c~€BH˜Z®Á{Oß%Û#;ßþý >zÐÁ³‚R Ü«ì+ƒŠ!ÂÎ|ï“ùVhcl¡¿÷™SXvîVú®n}¾ÿÇBκ/öÌþy.iüâ¬Ú–?n¼£8~õ!©ùÖ#×òŠËÕÊ«ðli/gÖœPƒéöccDÜ“¼Ås‡šN÷ÿ÷BU×Òž†EÇÓ®Ü}þ›S Ó4,íÚËÛ ØÄ¿÷©ÝðàÁ«¯¾Ú†úÞ*DDD°k¢´²”«uؼœ«ÑÜ}ý[1–ÈKÀ; }Ü}è—7.î9”ÕL/ÿëŸÿÅO"ëù±„BH‘kþ»bu溓¼ô¿Ü'±àÃÐK“ÐÜ@ßõ§r‹*˜Ù¯Àïo3§üx/‹YM[TVs7ÓçËãb¼œ ‚Î]¹ÿ´¤¢†J+(©¤¼‹w^»5ò6û_rÝüÞçw“ ·íû©¸â;Õû$2{ž0Ë~^èjŸÄ ÈÿÜÏø©¢JFW¡¤¢únZÎÎn1QwR³ysÉÒÆÉf oÑoºq/=—^4bôx^V•žK}?àœ}ëöIÌ}ª½}i$IÍi0©j¢²ZFVzà\‚È–yðrÒãŸè HïGºan„^¨ûñ+ØÒ^¾áÛ¸Ô¬B¦ÁäèÔSÅÓøÓU ),­än£ªk»Žßº—žG÷{Ì>‰Ô/¹¾^9CßÑ}>‹-***ÊÉÉ™8qââÅ‹áåóèwïÞuss»uë–Áxy¢…~—§<š³zA~ nç7øîþï AÎÐwt_-[·nµ¶¶îܹóŒ3ÊÊÊàå^njjÊýMn”øu2ú÷}ôç/‡—ÃËÑxx9¼\/äìÔ©Œ|ˆy˜—·Û¾ãÒ7³ïóåxÀËÑ`x9¼^®ešd'&gí¹ï¸ôÍì;€—ã/GƒáåðrýõòöúÞ>ûŽKàåxÀËÑ`ˆ,¼¼ x9x9ðr4^/‡—€—ÃËáåh<º//Ç^ŽÃËáåÍôòï}ÕJË^ŽÙ 4fx9ðràå-îåëÖaô€—/‡—/^/^¼^¼x9¼=ôòoh㈗㠴]àåÀËáåÀË€—ÃË€—/oi/ôèш#ÌÌÌ<<<222t9¬Ô¼¶¼¼’òµk×–••Ñó˜1ctéßðr/ÿSSÓòòr: 5733ƒ—xy+xùðáÃ7nÜHj¾víÚ‘#G2••• lšÇûùù988¸4ˆ[Î!C¢££¹^¾|yàÀ¬yóàyy||ü”)SlllLLLœœœ–,YRUUÅ&¸pႇ‡Ç+Œ=:66V|^/oK^žššJjnjj:bĈôôôŠŠŠM›6‘X‡††²Rîââ\PPPSSsûöíiÓ¦±ÙwïÞý—¿ü…[à?þñuœJ_Η;;;ïß¿¿°°P.—ß¿ܸq .dbãâ⬬¬>\VVVZZzðàA:½~ýº˜¼^ÞÆ¼œ¥¼¼|Æ ƒ Ú¸q#Ù9îççG¦.ËÚÚ://9­­­uppÈÌÌéåQQQܺ1°³³cŽ'MšÂݱcÇäÉ“Åäðò¶çåeeeëÖ­ñ—Lí1bÄÞ½{™Óððp:¥@1•Ši3å?~üÁƒËËËsrr,XÀ†Sâýû÷Êåòû÷ï7náÂ…šI°Ò(¥õRóè.‚¹ ¥¥¥”€N¯_¿Îæ:Ù?~üÌ™3ts¥•—¾Ú’ÇŽK­ÊÎή­­ÍÊÊ¢û¥÷Þ{OLg›3’Úº Pv^®_^îçç·iÓ&Uez{{‡„„pC¶oßÎ ¿¿ÿš5k¸±Gõôôl¾—«-™\°W¯^III)))½{÷¦S‘•Ši3å T*sQQQÜôôt;;;-z¹Òz'MšÄ» ;vì˜>>{öìá†p×—Ïž=["‘´„—«-ùîÝ»}úôa¾ùúë¯ÇÇÇ󘘘ð¾ *¾ÍúæåžžžŠë˽¼¼Z×Ë;uêTXXÈMÿþûïóªVuà倗óÉÈÈèÞ½;³‹L&#Á%gcSRR\\\"""ÊËËÉ€ÃÃùû±deeõë×/444??_.—SQ$ñÇo¾3 —L:NRÎîxñâž}ûR ¹%P‚°°0Åe!bÚ¬o^~ùòeKKKf?âСCtÊ®ªo-/§;œwÞyG*•Ò0Òó|`eeÅ«ZÕU9’ªv“ÔÊU€ÊðrýòòûyÏš5ËÎÎÎÔÔtàÀäÜØÄÄD///Òq33377·ÈÈH®ÐdggÏŸ?ŸÜòÚØØx{{s·ÖnŽ& ”L­]´h71úúúrCŽ?NyŒŒkWÛf}órâܹs£FêØˆ»»{LLŒH{n9/¯ªªZºt)ÝÔ[[[“£Ó]¯jUW^x9ðr}órfÊP÷ÏÀË€—ÃË€—/‡—/^/D+[J ÒC›ë£T*577Ÿ7ožŒ$õ‚ú’‘‘?1€—·G/×n]:¯ï€ª«« `$©ýû÷÷óóßÀËáåm‰ììlSSÓK—.ÌHÆÆÆRrssñWðòÖäÞ½{^^^æææ®®®‰„kx.\ðððx¥‘Ñ£G“à ‹ ÷·â£¢¢†JÅvíÚÕÓÓ3!!A¼MJ¥R+++ÊN…DGG‹ìNMMͺuë† Ò¹sgcccoooê·FU«>(0>>~Ê”)666&&&NNNK–,©ªªâ¦Ù¼yóرc l$ÝÝÝñWðòV#99™ìóðáÃeee%%%aaad~¬áÅÅÅ‘Ï1±¥¥¥¤Óëׯ‹´I2TÊB)û¡C‡©:16™™™I‰×¯_ŸŸŸOZ|úôigggjŒ˜‘…/]º4==]&“UWW§¦¦†„„Œ1BL½Híß¿¿°°P.—ß¿ܸq .䦙0aBhh¨$ ѤI“ðWðòVƒ,–œŒ²}ûvÖðÈÕx±;vì˜oÞ<èK@@õ…·º^¼^¼x9¼x9ðrx9ðràåðràåÀËáåÀË€—ÃË€—/‡—/^/^¼^¼x9¼x9ðrx9ðràåðràåZ€šÒ¤ô‰ÄÉÉ©C#º¬WƒB:ph¡×“ðhH¥Rssóy󿵓ÑPCFFþi÷Šðòvíå...gÏž­««Ó/YHË9ðhøúú0 ºººŒ†*hú÷ïïç籆—ðr­ù‘‘Q}}}«kž˜¨Àhdgg›šš^ºt©ýŒ†±±±4¹¹¹íÜËß}÷Ýàà`™LFÙé9((ˆBðw¼Ü0½üñãÇ~~~fffƒ ⥼wïž———………¹¹¹«««D"áê…T*õññ±²²¢Ø¡C‡FGGóD„‡øQ®÷Â… ¯42zôhr8aûaé **ŠšJÅvíÚÕÓÓ3!!A¼B ÷W­– ÆæÍ›ÇŽÛF# €7îïï?wî\^2ww÷ÀÀÀ¦¾ßZ¥¶^á÷‚@É4D‘‘‘nnn/¿ü2]¦I“&%&&jåPSS³sçÎñãÇS.z¦c Áßeðrôr—ààà‚‚ú¼¿}ûö´iÓØØääd''§Ã‡—•••””„……‘½±V‘™™éèè¸~ýúüüüªªªÓ§O;;;ÇÅʼn´:„ë¥*ȘØÒÒÒƒÒéõë×Eš(ie¡Œ”ýСCÔªNL›EöW­«Šš0aBhhh{ z¥1bïÞ½Ìixx8*êfHH n“†W¸UÂõ ¿„Kæ$½Ý(öáÇÍ|#0mÞµkëåt¬ÔË[åk¼\›^îçç·iÓ&Uez{{“qC¶oßÎ~üûûû¯Y³†{ôèQOOÏæ{¹p½äj¼Ø;vLž}ú0ßU}ýõ×ãããÓPcšú½Oµ­¨Wø½ \²âHîÞ½›·\ÕÿC/o ##£{÷îÌ2™Œ4…,MIIqqq‰ˆˆ(//' çî’••Õ¯_?RÉüü|¹\NE‘>>¼ù^.\ïåË—---™H˜]Dè”]+¼`Á‚7ß|3))‰šTTTtàÀ=z(î@B©pfß ªŽ×€‘#GnÛ¶7Ó,²¿{¹ª} o4¨:’cv?Ç‹/öíÛ— XoS÷In•p½Âïá’y#IoFIÞÎ6TuXXXó`KÕë óñàåmÛË_4îÊ|87 ™hXX˜âr” ¼ùæ›III”±¨¨èÀ=zôЗ»¹¹mܸñÎ;åååµµµiiisæÌñõõÕ–—«Ú'‘tœ†"66–9½xñbß¾}© Í¿:T£‘‘ÑâÅ‹…“9û$^n˜^þ¢q‘ùó绸¸˜ššÚØØx{{³êÉpüøqŠ%qäRQQ±páBccckkë©S§&$$èÀ˯]»F"Þ³gO“N: 2dÆ ìjœÊhR½ª~WhÖ¬Y‹-â†Ð©âý€fWG)t³Ä¦‰‰‰Áï ^Þæ½4 ²íTWWëI{ªªªúöíËûU#x9¼ÜÀ‘J¥æææóæÍÓ“öP{x«ùàåðr/‡—Ж½œ´[í^àå-èåD/ðò–òò+—bD>àå^/^/ðrx9ðrx9€—ÃË€—Ã˼^¼^¼x9¼x9ðrx9ðràåðràåÀËáåÀË€—ÃË€—/‡—ÐÞ½¼C‡Mê¡D"qrrêÐHSGGƒ,ŒT*577Ÿ7ožnÆM¸Úô¨¶é±ÒÁàëøúRu={ö”ÉdªÚ@¯zdddàxy“?§]\\Ξ=[WW§K'ÐOYlf«|}} P]]­®i0÷Nmz¬ôÙË5ËH¹lmmCBBTE¯ÿþýûûùùá㼼ɷFFFõõõmQ¶ôªUÙÙÙ¦¦¦—.]2xׄ—·õ×y3½|ãÆ=zôàN™óŠŠ¥÷Bnn.>´//¿wïž———………¹¹¹«««D"á~FJ¥R+++Š:thtt4ï#–G“>žUe¡Àøøø)S¦ØØØ˜˜˜899-Y²¤ªªJd¥ÂmNNNžkìå”Ñ$'8~ü8µÊÈÈH1±p›ïß¿OýíÒ¥ ³ù¹sç^zé%1Ý©ªªZºti÷îÝ­­­É,I´Õª‚¿+$|¨ £FêØˆ»»{LL E÷ .tpp`Ú}ú´³³s\\œ¢éjÜ{öl‰D¢Ÿ^nbbRSS/€—· /ÏÈÈèÞ½;³‹L&‹'gcSRR\\\"""ÊËËKKKÃÃùû±deeõë×/444??_.—SQ$ñÇ×/ïÓ§OXX˜f?f/€—·R©tÖ¬Yvvv¦¦¦<|ø07611ÑËË‹tÜÌÌÌÍÍ-22’ë¬ÙÙÙóçÏ'w§¼666ÞÞÞ±±±ÍwÜÊh’—?~œZedd¤Ù¦éo/‡—/o‹^ÎLëþÀËáåÀËáå^/^/ðrx9ðrƒðò¦né-‘Hœœœš¿¸V¶.DÇÛ–öæèééé“'OîÒÈÛo¿‘‘¿b¼^Þš6éââröìYzS—^®cc6`/þü9]÷uëÖ­]»¶gÏž¥¥¥øCÀËáå­f“FFFõõõzb±ðrÝ@F>{ölnȬY³6n܈?d¼^®’Çûùù988˜™™ 4ˆ×Â{÷îyyyYXX˜››»ººJ$®MJ¥R+++Š:thtt4Ï;5þM{áz/\¸àááñJ#£GŽ–]6¢¢¢¨©Tl×®]===ijp5îQ@@]nbÿ¹sç6ÿâÖÔÔ"2¤sçÎÆÆÆt•½½½iôZúEEåüùóܳgÏŽ;Èx9¼\¥”»¸¸Ãݾ}{Ú´illrr²““ÓáÇËÊÊJJJÂÂÂÈeY›ÌÌÌttt\¿~}~~~UUÕéÓ§ãââD:®ÂõRdÆLliiéÁƒéôúõë"½œÌ˜²PFÊ~èÐ!êU'¦Í"û«AhäGŒ±wï^æ4<<œN)°ù×—,|éÒ¥ééé2™¬ºº:555$$„ oéו­­m^^7$77×ÎÎÈx9¼\9~~~›6m°:Ò8nÈöíÛY›ô÷÷_³f 7öèÑ£žžžÍ÷ráz'MšÄ‹Ý±cÇäÉ“Ez9%æå>}º˜6‹ì¯="²³³{õê•”””’’Ò»wo:ÕÊõ577§;ÍòvP˜¼¦¦¦r¹œFŽéîîNtc`ff†?d¼^®{{ûgÏž©Šµ±±ÉÍÍå†/²fFyyúXRRbiiÙ|/®×ÊÊŠ›““CYDz¹b^[[[1mÙ_ zÄçêê:lذ«W¯jëú2dâĉ'Ož,**ÒåëŠõòßýîw¤æðr^/Wƒ‰‰ ãOJ166®­­å†PbÖ&)¯âdª‘‘Qó½\¸^¥±Ô‘^.W¸Í"û«AXF7¢Åë›™™9sæLkkkªËÅÅe̘1«V­Ò£c /‡—7 áùrE»âÎò:::Êd2µUhàåÂõ*/'õdŽ·©¬¬ž/§AÓf‘ýÕ G AAAsæÌ Öú….//ß¹s§›››‡‡‡˜,ÍYÇ‚ï}ðrxyÓðõõؽÎÇÇgÏž=ÜîªèÙ³gK$’–ðráz===×—{yy±,•J¹±QQQ\/'7åÆîÚµkÆŒ¼(]–-²¿ôˆ¸{÷nŸ>}˜o²¾þúëäÐ-tÅ‹‹‹;vìØÒ¯+¥û$nذÈx9¼\9Ý»wgöc‘Éd¤ƒdllJJŠ‹‹KDDDyy9ùbxx8w‘¬¬¬~ýú…††æççËår*ŠÔsøðáÍ÷ráz/_¾liiÉìmÂì©B§ìšì ¼ùæ›IIIÔ¤¢¢¢ôèÑCq?ÊH…Óåpvv¦êx 9rä¶mÛxóî"û«A¨1$åìn/^ìÛ·/¥Tɦ¦››Ýwݹs‡J«­­MKK›3gÝŒµôëŠù]¡¯¾úª¸ü®/‡—«G*•Κ5ËÎÎÎÔÔtàÀä»ÜØÄÄD///’H333’¼ÈÈHÞ."óçÏ'£¼666ÞÞÞÜ­Ä5örµõž;wnÔ¨Qqww‰‰a£***.\èàà`lllmm=uêÔ„„®—K$WWW*– §*¨"ÅÚoÞ¼Ù«W/EÓ_ zDã¿hÑ"nb:åÙs]]¥W\ /̵k×HÄɉ)c§N† ²aÃWã4‰GQ;wîÜ¥K—·ß~›÷O ÀËáå MråÊòòåË—c(/78/gækuÿÜÞÐÆX-[¶ÌÅÅEqq ¼¼í{9h;¼öÚkÇŽÃ8^/^¼^¼xy;óòz³kŠT*577Ÿ7ožÎšGuQjS^¹reÔ¨QÜVõìÙ“·5x‡ö¹ÿ àåðrór__ßTWWë¬yTWÿþýýüüÔ¦ôòòânB­²µµ —^/7(/ÏÎÎ655½té’Ž›Kõæææ ¤INNîׯ_}}=·U7nìÑ£wÊ^x9¼\,÷îÝóòò²°°077wuu•H$¬MðfŽýýýçΫ›†mÞ¼yìØ±Jo¢¢¢†J îÚµ«§§gBB‚øbÏŸ??yòänݺ™™™õîÝ{ÕªU¼ùxÂÝÝ=00P Ù³g‡††òZUYYioo¿cÇx9àåðò¦‘œœìäätøðá²²²’’’°°02]Ö&kjjFŒ±wï^æ4<<œN)P7m›0aÏ}YÙ¥»ˆƒ–––R³:äèèHY,¹>õ7;;»¶¶6++‹î=Þ{ï=^šI“&©*áÙ³g={öä3h[¶lqvvf£à倗ÃËEáííÍ[½}ûv®M’¿öêÕ+)))%%¥wïÞt*²ä*ß6ºaHKKSZ2wNš ÓéÓ§k6döt+ ¤Î’^«Ê²lÙ²¯¾úJ±Uô\UUåàà@c/¼^Þlllx ©É¼y6çêê:lذ«W¯ê²m&&&Jçæ©y¼6çääØÚÚŠ)³¾¾>88ø7Þèܹ³ÀÝBuuµ©©©Òž?NÊ^RR¢ÔˉÀÀ@º£`ÖÆÀË/‡—‹ÂØØ¸¶¶–"—Ëmrt#:n›€—+¶™óÒ(uîåË—Ó Æ¹s犋‹™om*í¯€—¯[·Ž QÚ*6/y9³<^x9¼\¶¶¶yyyÜÅùò   €€€9sæ‹/Y+ëXRSS•–¬8_noo/¦LKKË'OžpC¨ ÅV©ZÇB÷ ={öTº˜‡[ÈöíÛ«ªªà倗ÃËEáãã³gÏno}ùÝ»wûôéSVVVZZúúë¯ÇÇÇë¬mßûܹs'7d×®]3fÌSf§N ¹!ï¿ÿ¾¢=SJ¿÷Icõ׿þUÕ}WßIë·lÙ/¼^.Š””—ˆˆˆòòr2ïððpî~,¤ã$å±±±ÌéÅ‹ûöíK)uÓ6}™ýX¨yÔR’`ꈘ2gÏžýÎ;ïH¥R¹\NÏ|ð•••¢=9RqŸÄúúú~ýú=xð@­—tç`oo/¼^.–ÄÄD///Òq33377·ÈÈHÖ&gÍšµhÑ"nb:õõõÕMÃ~WH"‘¸ººRƒ©ÙÔxê‚È2«ªª–.]Ú½{wccckkkrtzž=ÇÄÄ(ý]¡ï¿ÿ~òäɪJæ"“Ézöì /¼^nÐ=À€÷§å qïÛ·/ï×”FŽyåÊ\ÀËáåÚ†™ÍÕìY'H¥Rssóyóæé¬Æ€€ª‘êÅ[^øÿöî.ª:ÿÿ¸ÄM/ËEmS»ì*iEˆ¦åc ±‹»¨™·MÔµßÏÜ2ÿý¹›÷g¿.ºº)–×4¯Y –â /¤y©´TP V1¼ Ìpg. ¿Ž;çr„×óñyð˜9×ï|ÏÌ™÷Μärr9@.Èåär€\ËÉå¹¼Î$&&†„„4¹îN®×•Õ5¶_í±{ÕH鄎;êõzG=#ÓË\ÙÙÙìD¹ü.Èå¡¡¡;v쨨¨¸Ãë%—;Ïî¯,I'´nÝzñâÅŽzF¦ðÁíþR¹¼Þqss3™L<Ïê­ÜÜ\OOϽ{÷Ú~8™={v‡”‡Ì­>±¤¦¦Ê¼/^¤¹¼þæò&6”cwïÞÝ»wï{¯‹ŠŠ’„g;û¥K—†ÚªU«€€€¹sçVw½®´ÙG¾øâ‹!!!o¾ùfYYYµîèíܹsРA2ÜËË«sçÎÓ¦M³½®r½'Ož”y[´hÑ´iÓž={nÙ²EÙþ¬¬¬aÆùûû{{{?úè£Û·o·jÕœ9súöík·µ¥¥¥mÚ´ùøãår9oÞ<ö#€\^s¹£$'öïß/IqݺuEEE………kÖ¬‘»‡²šñ™gž‘QÅÅÅ.\˜8q¢ëëue^ؾ}ûO?ýôêÕ«ƒ!==½_¿~“&MªÖb="IÆÒ¹¹¹F£1'''..î•W^qf½?ÿü³Œ]±b…V«•Å®_¿^zÒÒþ³gÏðÁyyyå·nÝ*Kç+[õì³Ï.[¶ÌQ'ȇ™E§Ó9ê™Å‹8Pýs{@.¯§¹\’œÕ‰Ëüñ Aƒ¬ftå@ìíÈåIIIÊ!gΜ ªÖb|Dòq¥E‹άWâûG}d”-í=zôÌ™3•c¢££•CBBBNŸ>í¨$Í·mÛvÁ‚Žz&##C‚;¹ËïÊ\îïïouRò… ­f<þ|½ÊåVg­˜L&77·j-Öî#’åÄÇÇ÷êÕË×××ö´õõJ@·êI¹k™·M›6¹¹¹Ê±~~~Ê!–Ãáv;A>KHv7ŸWcÛ32ÜÓÓ“ý —ß•¹ÜÝÝÝh4*‡  ˆV3ºr—Û‘Ë]\‹£G4uêÔž={¦¤¤h4ówd¥7”¹\e½v{Ò2VºÔö,«ÏUærIÞ’ËÍGúÉå€\Þð—ÔV°®·¹Üîp??¿sçÎ)‡dff:™Ëƒ‚‚¬ŽˆKOZÆ[]€Ü–dnYzk,X ‹*++«îy,äòzË£££mÏ/‰‰iœ¹ÜÇÇçêÕ«Ê!¯¿þº“¹|øðáóçÏWŽZ´h‘eì˜1cÕ[¥þ½O3N'á{îܹ¶‘Õ©|ï€\^¯sù¾}ûüüüÌ×ck×®•»hœ¹\ÒóàÁƒ³²² ƒü}ã7”×TQ_ïéÓ§ƒƒƒ?ùä­V[RR"O’   ËØœœœnݺIìÎËË“…ggg/]ºôñÇW.Jå:‰Ê» .lÓ¦mc"""T¾ÌÊ÷>¹¼^çr‘’’òä“O6».22r×®]µ¬›ØS+óÞ¾\^VV6eÊ”víÚ¹»»HFÏÈÈp2—‹ôôô˜˜˜æÍ››¯_.{Ï=÷XÆæææN˜0!44ÔÓÓ300066ÖêRñ*¿+¤¼«×ë;vìh5P¶šúï ‘Ë¹TVVÖ}÷ÝW­YFŽùÐCY~ÉÈIòq",,lÔ¨Qô9 —“ËQ%Ï+W® †´´´þýûÏ™3§ºQÞÛÛ{üøñÕš+..Næ’yÙ€\N.GerròSO=e>#(<<|É’%ô —“Ër9@.'—är€\N.oCBB]™»f×6q†ú…À«u™v'§”G!%;;›Èåäòz'44tÇŽvÇÖìZàõ3—Ë£xðÁ¹B9 —“Ëë#777“Édw”£ßμ}†¯×ë%mËßùóçËÚÊå"55Uý=Èå 6—ëtº÷Þ{/<<Ü×××ÝݽmÛ¶±±±»wï®ó†5±a5Áœ9súöíkwÞ;w4¨U«V^^^;wž6mšóÇÔ­ÎÜW .|æ™gd¬ü•Û2D9ÁñãÇcbbZ¶léííݽ{÷ÄÄDËrââ⬎…=zܸqV«ˆŒŒœ7o{ @.ot¹\Rø”)SΜ9£×ë%¼fff.^¼ø‰'ž¨n†¾}éÜѨgŸ}vÙ²evGI^_·n]nn®ÑhÌÉÉ‘LüÊ+¯T«ÍŽrù¢E‹,¹\n+sùÉ“'CBBd½EEE+W®lÑ¢…e92¥ôêòåËÍwW­Z%w­b½Î8p { @.ot¹ÜÛÛ[räíHÏM¨­\.!øôéÓÎ,D Dd×sù!CæÏŸo9eÞ¼y2Dù GRµrú (—#Ÿ:uêtâĉŒŒŒÎ;Ë]ÛUȨöíÛ³§äòF—ËÃÃß{î¹äääüüüÚÍåµBeɶǛ…ÉdŠïÕ«—¯¯¯ÊçW¾Ùiwl`` Õ©á’¼­¦Ü¿÷îÝ{öìyàÀ»K.//÷ôôdOÈå.—Ÿ={vøðá’ CCCûôé3mÚ4'3ºë‡ÃoG.Ÿ:uªß””FcþΨÁ`°,ÇÉ6× —»»»Fååz-¢®s´dr9 —7Ò\nQ\\|ôèÑ… öèÑ£wïÞ®§ç;pKff¦íp??¿sçÎ)‡Èdµ{¼Ü®Ö­[_ºtI9ÄöxùüùóãââÆŽow!œÇÈå=—[h4šfÍšÕVzvQ ¾÷éããsõêUå×_ýäòaÆ-]ºT9Äêüòü±k×®EEE………<ð€| ²]È¢E‹øÞ' —7Æ\Þ£GÙ³gÿðÃÅÅÅF£ñôéÓcÇŽ9rdýÏ厮“8f̘Áƒgee ùûÆoøûûß\ž‘‘º~ýzéIIÞ«V­R^E⸄òÔÔTóÝ={ö„……É”V ‰ˆˆà:‰€\ÞsùÁƒ%ˆwìØÑÃÃÃÇÇ'<<|Ö¬Yz½¾ž4O%;ú]¡²²²)S¦´k×ÎÝÝ= @2º$f's¶‹'Þ¤¥¥ÅÄÄH÷òò’<6l°Ì>bĈɓ'+'–»VŸvíÚÅï ry#Íåw5ɵ=ôó¿TŸÉlj°°0«ß —“ËïYYYÞÞÞãǯû¦˜‹×ìïuqqqòXä±Y¹œ\r9¹ —“Ë@.'—ärr9ÈåärÔºÚúµ£Û÷«IärryÞärr9¹¼Î :4>>^¯×˃’¿óçÏ—!t¹üÎeëK—.ImÕªU@@Àܹs-£²²²† æïïïííýè£nß¾]9—ÊÏÎÛ¤¶ÓØ]¯ ?zôè‹/¾èááòæ›o–••9óXt:Ý{ï½îëëëîîÞ¶mÛØØØÝ»w;9ïÂ… Ÿyæi€ü•Û2Äùn<~üxLLLË–-¥¯ºw˜hy¼qqqV¿Ç9zôèqãÆñÂärrù-ùXbèš5kŠ‹‹/\¸0qâDóð³gÏðÁyyy‹·nÝÚ¾}ûýû÷W™¿Ïåv×+ÃeEŸ~úéÕ«W Czzz¿~ý&MšäÌc‘>eÊ”3gÎèõúòòòÌÌÌÅ‹?ñÄNæòE‹Yr¹Üv>—Ÿ?¬[·®¨¨¨  `åÊ•-Z´°<^YŽ´aùòåæ»«V­’»Õ ýäòF‘ËçÍ›g;|ôèÑ3gÎTIHHˆŽŽ®Å\nw½2<))I9DrvPP3ÅÛÛ[’qÍúaÈ!óçÏ·œÇ"m“!NÎ+Ÿä€rÈ‚ ”777·S§N'NœÈÈÈèܹ³ÜåU Èåärë|þüyÛámÚ´±Š~~~µ˜Ëí®W†[µb2™ÜÜÜœy,áááÏ=÷\rrr~~¾+RÝY/^¼¨"]gµœýû÷wïÞ½gÏžà% Èåär;1´¢¢Âv¸‡‡‡íIäVùØÅ\nw½ÎÌëÈÙ³g‡ Ó‡††öéÓgÚ´iÕÍè5ÈåîîîF£Q9Ä`0Ø.'ê:^Ï€\N.¯F Öëõ5›Wâ»ÉdR)--u满.ær‹âââ£G.\¸°G½{÷¾Ý}غuëK—.)‡Ø/Ÿ?~\\ÜØ±cãããyIr9¹ÜÙÈ;f̘ÄÄDõy=<<ì~QrjVV–rHRRÒÌå¦Y³f·»‡ ¶téRå«óËüñÇ®]»>ðÀò™W5 —“ËŠ¼999ݺu[¶lY^^žÁ`ÈÎΖèùøã+§‘¬¹råJÛÓQ&NœØ¿ÿ'NÈŒùùù«W¯îСÃÈå=zô˜={ö?üP\\l4OŸ>=vìØ‘#GÞî>ÌÈÈ ]¿~½¬W’÷ªU«”×c‘8.•ššj¾»gÏž°°0™’6 —“ËŠ¼¹¹¹&LÄééék —f›6m’±nnnV )))™4iRÛ¶mÝÝÝ^zé¥cÇŽÝ\~ðàA â;vôðððññ Ÿ5kV•gãÔŠ´´´˜˜‰ã^^^òñ`Æ –61bòäÉʉåîø´@.¿›r9@.ÇÝÏ|\¼fÈåär€\ËÉå¹ —“Ër9@.'—är€\N.y.îj !—¹ — —ärär€\~Ww\“&ù4õN=Gu=zx{ç·j¥yá…¢ÌÌ z²fÊÊLo¿]zÿýZ/¯ünÝ Ö®Õ±ä)ÔPŸí¼ºÙŽ–l)öH —“Ëijõ$&êCB´›7ëKJL……¦uëtaayy&z²ºL¦ÊŠ&N,9s¦B§«;wdÕ­Zi¼¼ò;wÖN›VZ^~sÞ“'2¶E ´­gÏÂ-[ôu¾ç’–””Ürt¼¨ÈQèäìÿúWŨQÅmÛ^ûßîo~S ™^9VeUÙ“5ÞF:<÷ËÂà |}5îîùÒ¶ØØbiI­l#•V X´w¯¡f[A½ÍÒ€ ô=zH“¤»dEiiF˼2—UçìÛgxøáóí¸¸Ù@ʱ£GWR+Û—ýFÃÞoðênÀ¯nõWŠò\Û3Rª|¥ËA.o˜¹¼}{í§Ÿê®^5 •ééÆ~ý 'Mº±ÇÙ¿ß {Ïuët" MkÖèäî¡C7÷tÉÉz)¹±i“~Û6½¼©X–|ölEp°öƒÊòòL²ÚºU/+’:Ó*Ù­Ëþ˼ނ“ìŒd¯Üûôí[(css+ŒÆÊœœ Ùo¾òÊýæÏ?WÈŠV¬Ðiµ¦âbÓúõ×Ú\ç{®fÍ4¥¥Ö¹\öÔN¾m‡†jãã˯\1É{Ï‘#Æ?üáæ›„ú6RïIW¶‘¼çM™RzæL…^_)oÉ™™‹—?ñD¡ëÛH½Uòpä{À€"y—’’È"O<'·‚z›¥ò†-(Ý(Ý%ñHÖûÓO7Þ¼—,)ÿýïoyo~íµÉ–L ËY¾üÆ»æªU:¹«s.]«o_ö {¿Á«»a¿ºÕ_)êÁZý•B.¹¼Áæò¤¤[v|²_ ÒZŽ^È®M9öãËå¼e^ÙÁÉž×r£ysòˆÂÌ™·œ§‘ ‹Ž.rrkµÞ ÊUö>²vyC2ß–·‡>ºe^YTï¹"" åH9DÞ<=jÕ¨QÅÿø‡Ã3^Ô·‘zOº²¼½¯mtç{Àùm¤Þ*/¯üûï¿–Eäýµ¤Ä$oZíÚi·lÑ»Þfi€tU«^~ùÆ»µ<½4—.ݘ]âHÛ¶Z –‰%£tê¤=q˜‘aìÜY+wìõíË~£aï7xu7ìW·ú+¥Ê\®òJ!—ƒ\Þ`s¹ò¿Ï•׿yãævãuîﯹxñ–Ð… –£¼æÝLo¹qÏ=7wmÚXï¼ L~~N!–UX­WeÙûÈŠâãË{õ*ôõÕØþPvyVóÊÝ:ßsÉ[K‡ÚmÛô¥¥7ŽÖ˜/8à̼ғ¿üâðm@}©÷¤+Û(<¼à¹çŠä3?ßÎ{¡+ÛH½UòaÆêý›7ë<#H½ÍÒÛVIc”‡Ð>øàF¤Ø¹óÚÙVKØ¿ßн{AÏž…TãñêÛ—ýFÃÞoðênدnõWJ•¹\å•B.¹¼Áær•îîùFã-£ †J|«Élo™Ìöä9«ý‘#v×kYøÔ©¥²sLIÑk4&“Éz¬ú¼uhëV}däóDûõ+ܳÇ¢ufFéIƒ¡z}eÙFê½áÊ6:{¶bøð koÌ¡¡Ú>} §M+µ¼#º²Ô[%k´:*VRbjÖLãz›e JOŠ´4c—.7O9]¸°ÜvQQ…RÕzb¨o_ö {¿Á«»a¿ºÕ_)ÎärG¯r9Èå1—Û=Z#;>göÁÁZ½¾†­jÝúæ¿mùùiλ¥U™™Ê£5VÇc¤ÍõpÏ•šj8Щÿ)×àˆše©÷¤+ÛÈ¢¸Øtô¨QÞÆzô(°dre©·*"¢°ÆïÜêm¶{DM:P9D>YɆ“æÉF¹zÕú°ÜüùåòŽ>vlI||ym1e¿Ñ°÷¼ºö«›\r9¹¼6ß_££íœÝSäÌ^c̘âÄľ- V¼t©Ãó&}|4V;Í×_/±Œ>¼Xv Ê±‹•×Ã=Wllñš5N}uhäÈâÙ³žª¾Ô{Ò•mdK£¹ùêÊ6RoÕôé¥VÿéNNÖ?þx¡ëm–X$[²¤|È[¾ ¶zµN¿e‹ÞrޝÅ?»v-0?ï $8ÙõíË~£aï7xu7ìW·3IÚÃ#ßî·HÌåÕý2@.¿‹ß_÷í3øùݸ€ÔÚµ:¹k9»N}¯‘“SÑ­[Á²eåyy×¾‡ž]!o!Nîa32Œ¡¡ÚõëuÅÅ×öƒ«VÝrÙ³\œ•U!‹•¿o¼Qªü¾ÿéÓ×¾ïÿÉ'×®PRbúüs]PÖöaªÿLš+cyùåâ'Œzýµ6OœXòôÓE&çö¥ÒuíÚݸbƒÌ.o ò~l«¾Ô{Ò•mÔ£Gä‰~0Ê’ÆkÝ>vl‰„ ×·‘z«._¾ö¾h~¼¥¥7®ç`õͪšµÙrÅóW¬¤U²ä“'oy./¯”m!Áè‹/ny#•YämÛr »={ aa²gž9êÛ—ýFÃÞoðênدngr¹,|åJ]EE syDDᇖ›Hæ —7†\.RRôO>Yج™F*2²p×.ƒó{ÜÜŠ JäÃÓ3?0Puñ]ii×®Ë+o3^^ù²ÃݰáæpËÊLS¦”ÊÔÝ=? @#ïòþ¤\uzúµy›7¿qõ\y¶_—¹ó¹|õj]—.òp~ýkí_ÿZjuÙDuòæ7bD±¼½IO>üðµ÷-åX•m¤Þ“®l£ƒ ò¶×±£ÖÃ#ßÇG^0kV™å?Ô.n#õV:uíêÈò.+¨{÷‚„g¯ö­Þfiž,ê·¿-ðöΗ.:vÌÎQ±·Þ*•U[}—K¶ÎäÉ·\ûLîZ2A•ÏõíË~£aï7xu7àW·3¹|Ó&½ô†›[¾£ó[Ôsù÷ß;uÒÖì] —£ÈÛÞ}÷ié¶Q ²¦­÷ß/“·6ÏIðê@.· †¢¨†Wì7(Šª?û €\ŽšHNÖ?õÔÿü†‡,YRNŸ°\?¢&´j¥¹ë¾£ öô$¯n€\~/¯Ÿm¾Ÿ®<"¶Ï+öl_z’­Ë9^Ër9¹h(¹¹ —¨¹œóËr9@.'—är€\N.È幜\Ër9¹¨—¹ü3à.×@r9Ÿp÷"—ärr9@.Èåär€\Ëïd.oÒ¤ Û"++ËÛÛ{üøñVÃÏœ93hРæ×=ÿüóÙÙÙµµÆÃ‡7Î×××«õª+++{ûí·ï¿ÿ~//¯nݺ­]»V9VzOú°› Èåäò»/лت‘#G>ôÐCåååÊZ­644ô½÷ÞÓh4ùùùï¾ûnÇŽ k¥Á’k§OŸžžžnÛòºZ¯:“É4`À€‰'ÊgNwìØ±¡C‡*'Þ{ðÁGÅNËïÄy, /—çææzzzîݻצ;ß3fŒrȈ#fÏž}»[^WëU·víZ« n+55UzòâÅ‹ìG¹¼ê‡ÑäßìŽ:zôè‹/¾èááòæ›o–••YÍèh YYYÆ ó÷÷÷öö~ôÑG·oß®{òäÉAƒµhÑ¢iÓ¦={öܲe‹Õäî¥K—$üµjÕ* `îܹ–Q;wî”ye¸——WçΧM›f9¶íb«Äœ9súöíkÛQQQ²^å;vزvóq]­W½¯hûÑÅVddä¼yóØr¹³ÃQ.oß¾ý§Ÿ~zõêUƒÁžžÞ¯_¿I“&U9£8{ölppð|——'Q~ëÖ­²¨ýû÷›ÇþüóÏrwÅŠZ­¶¸¸xýúõþlsù3Ï<³fÍ™àÂ… 'N´Œ’TºnݺÜÜ\£Ñ˜““÷Ê+¯¸Þ*³gŸ}vÙ²e¶ó¶nÝZ>'(‡\¼x1((èvçãºZ¯z_ɇ4Éå ð¹®wïÞÛ¶m³]ìâÅ‹%Á³ärWsyRR’rÈ™3g¬¡£}Úv^OOOùp"7""""##å†^¯÷òòºÝù¸®Ö«ÞWÒ€ûï¿_>–””$''·k×nË–-V ÉÈÈ4Ï~Ë]Íå–³VÌL&“›››3 ¸M›6¹¹¹Ê!~~~æÛî­N;–»¶¹üüùó¶K–6ÄÇÇ÷êÕË|»ç«Ô¬Uf:N%—?öØc‘ï|.¿ÃëUï+i•Õ“jóæÍææ)•——Ë”ìG¹ÜÕ\^å@G XÒ­í©Þ–Lïîîn4•ÓKô´]rEE…í’§NÚ³gÏ””F#ÝѼ5h•z.ol籨÷U@@@QQ‘rú’’’fÍš‘˹¼~åòàà`½^ïhu+­ŽÅ^¸pÁÉ%ûùù;wN9$33³VZe" ´Þؾ÷©ÞWÎärÎcäò;”Ë]3fLbb¢£Õ >|þüùÊ!‹-r2[ûøø\½zU9äõ×_¯•V™9úÞ§ÝëΚ5ëvçãºZ¯z_MŸ>ÝêI•œœüøã[M&›•ï}rùÈå]»v]¹r¥í '999ݺu“€›——g0²³³—.]jÉm§OŸþä“O´ZmII‰4>((ÈÉ\.yqðàÁYYY²XùûÆoØ^Ë¥f­2stDóïû¼ÿþûšëý¾£‹NÖ8×ÕzÕûêòåË<ðÀºu늊ŠJKKÍWk±ú–påõÃê\'Ë«ÎåMì©V.ß´i“¤F777Û‰sss'L˜ c===cccSSS-cÓÓÓcbbš7on¾~yJJÊ=÷ÜãL./++›2eJ»víÜÝÝ$£gddÔV«*ÿ®PåõË;J›}}}¥ÙÏ?ÿ¼|*°š@> È=<>šjår»óZM`·1@ÃÏå–3UÌÕ´éµÄ¼{·!2²Pn<úhÁÉ“7Î&ùúkC¯^…ÞÞ7'v>—;š×*—Ûm ÐðsyûöÚÂB“íŒÝº¬^­ëÝ»Ð2¤MmB‚®´Ô¤žÅï¹'_wíP{ååË&ËpGóÚ/·Û çòéÓK'M*ÑjMEE¦ü£,<üÆ©#óç—7k¦1ŸÍb¤]»VWRrmÊ+tŽrù¯­]³FWVfzç2ËpGó¶l©ÉʪøñG£¿¿F¥1@ÏåCå”)¥‹½½óûö-Ì̼qzwA)4Tkþö§YJŠþᇠ<<òCB´ –[NG±:5åóÏušÀ@MR’Þ2ÜѼï¾[æã£iÑB³`A¹Jc€žËryçrå—,ëgñD@ÃÏ幜\Ër9¹ — —äò:wæLñ Aß4o¾Aêùç¿ÉÎ.v~Þ&M>·*Ë¨Š Óܹ™<²ÝÛ;AJnÈ]hûý÷ù'¹ÿþ-žž ¿úÕÆ§ŸþúË/Q.¹¬ÌøöÛé2—WB·nÛÖ®=«²R)YŽ“K6ÓjõmÚ|¥l°3ó>œ?nÜa_ß V3þ{çôè‘"¶U«¤^ØŸ™Yä|?«/Y¥Ÿ÷íË1âÛöí7K›ýü6FGï“!Î?"õ6« —׉§¡¡›ß{ï”F£ÏÏ×½û“ ÎçrG£&Oþ1*jÏ·ß^•„]^^!±oß=þóQóØðð”?ÌLKÓ––^ûÝwWeb îæ±&Så€_K ”,«ÓU;¦:ô J3fÏþéå—9³d iÉÿø½Uû«œW>!LŸžžž^`ûÀχ„lÚ¼9·¤Ä(¸nݹ°°myyåNö³Ê’ÕûYFuê´eÅŠì+WtÒWß|“'IzãÆ_œyDêmV @.¯M’ÇŒùN9dĈo%溞˛7ßpáB™rˆÜmÑ"ÉÑô¿üRÚºõ—æÛkמUâJ&ɸ’8Y²ÙO?¶l™tþ|©JûÍëè÷êµS"¬rÈgŸ›1ãDuû¹º¹|ܸÃòÉG9äԩ®]·:óˆÔÛ¬>€\^›¢¢öìÜyI9dÇŽ‹}ûîq=—ûùm¼té–c«/–ùûoTÉ‹’•Í·Ü·wož“mذá|DÄ.õlmY²ÙsÏíûË_Ž«·ßѼŽxÓ¦‰%%·äã¢"ƒ¥aÎ÷sus¹-i†¯ïg‘z›ÕÇËkSëÖ_ڦ砠¯œÏå2±»û²œØØƒ'NXFÍœyòé§¿>r$¿¼¼BJnÈÝwÞ9i»I{»w_êÙs§å,—M’Ë øÚÇgƒTïÞ»·m»à¨ }úìùüó»£l—,¶n½ ´Z½zÞµ;¯JPnÖ,±´Ô:Å~YÝ~v”Ëõ³­uëÎýáœyDêmV @.¯Mžž õïbFD슌Ü-7ôú /¯'gé¥ý^‘Ø}õªnéÒ¬6m¾úáeì°a‡”_U”»¶qÓRÑÑûŒÆß •ÜÿÉ—……†’crrn»v›¶l±ÍÕ„†n6?g–,S†…m³œ`]å—,•óª§gé@IüÊ!Ÿ}vÎòmTçûÙn“ÔûY);»¸cÇd«/h:zDêmV @.¿-¹ü±ÇvšOQ¨V.·²jÕ¿ øúFßÍþ©K—­))KK’­·o¿(QÛîÕùù:‰à’5?ü0ÓÒ*‰€Êi6oε{Ř1ß½ÿ~†£öØ.ùŸÿ̼ï¾d®B%;šW==Ëdž6oÛvAoQ‘AÚo¾˜LuûÙ™SV”ýlÊ;uÚ²zõY'‘z›ÕÇËk“‹ç±X),4øøÜ8³YâáÃùʱß}wU:šwïÞ<ËØ€€/%*ÇJ²oÖ,Ñj–Ë—Ëýý7JÜTo•rÉ¿úÕF«K.:?o•éyëÖ ‘‘»ï½7Qª_¿Ô={.‡„lªn?;“Ë•ýlqì˜VV·pá™j="•6W9€\^k\üÞ§ Ó–¼èå• ×W(ÇêtjGâ•c#"v9“ËÿçNþéOGªl•rÉv¯}®…µÙ™ôœšzyàÀ}Õígg–¬ìg3IÌ~~׬9[­ÞPosuÇËkÎîõûfÍʨÙÒV¯>k9¿¢C‡ÍßËñr¹Û±c²£y÷ï¿Ò¥Ë«ûMŸžnuKrrîãßr‹„þM§NVÙ*å’«‚ÍëLzŽ=h ÊÎ÷³3KVö³X¿þœ·w¢EgœÙF*½aÕæêŽ —לù÷nÞ?C£ÑK9ú]!»•£¢öHJ;¾Ô`0åå•/^|¦mÛ›ßGœ;7³sç-æóË¥víºôÀ[çÍ;m±ë“O²³³‹eÞ‚ýÆ¿Èz×­»‘Å/_.—‰ånQ‘AæÝºõBûö›“’Î+×.«þÝïöÚ>"õ%«‡`ççµ›ž_~ùЉò!+«xâÄ#O?ýµÉT½~¶»dõ~ž3ç'7·Ïí^4Æ™G¤Òæ*ÇËkÓÏ?ÅÄ|ãë{ã÷á%Ù ‹¶yqӦܾþÕ¯6zx|!IqøðC·½^¶,«G”¦M¥äÆòåÙ–Q_}Y2_HÈ&™W– ËÙ±ã¢rÞS§  ú¦eË$/¯„îÝw$$X_ ±W¯v/žXå’UB°3󪜳zõÙ.]¶Jƒýëä¿þ5Íê"ƒUö³£%«÷³£3sÌ?ÌYå#Ro³úXr9@.'—är€\N.È幜\Ëryíærär€\€\ËËr9r9@.@.ÈåÈå¹\á3 ¹‹s9ŸŠÐ0Ër9¹ —ärr9@.Èåär€\ËÉå¹ —“Ër9@.'—är€\N.È幜\Ër9¹ —ärr9@.Èåär€\ËÉå¹ —“Ër9@.'— 7— ÆÝšËËr9r9@.@.ÈåÈå¹¹ — —ärär€\€\ËÉå¹ —“Ër9@.'— XPwÈåÀÍ\^o×K.¹¼¾çr'WÔ¤Ir9u.orÝíËå?gžP¯OH.ÀÝ—ËŸ|òIGñºW¯^–!½{÷VÉÜÊáär Ú¹ÜI·Ýºuûþûïåöwß}÷È#8 ÜärÀ¥\n9þ÷¿ÿÝßß_yD\n,Y²dôèÑr{È!«W¯VîÇ{,44tÕªU–…ˆ}ûö™ïΘ1ÃÇÇgêÔ©är ê\^ùïÃÛ£—/_n5¼¬¬¬C‡GŽéÔ©“Á`°=.Q^¹ËíÔÔÔ'NÜ{ï½·)—yh“[Ér9îú\¾aÆGyä·¿ýmJJŠrøŒ3Ú¶m¯ ßûÛßZ¶liup]¹@“ÉTisBK-æòŸNïßÿ)K(—Û2„\€»>—›íرC·rx^^ÞŸÿüçÒÒRå”Íš5;räHNNŽrÈ©S§ÌóÚ ë•µ}KÚ±#¿ù͵SÞå¯Üæ<4„\n>ðìçç7sæÌJÅ)ãÊÉ,C¦L™rï½÷N˜0Á2äµ×^“!Ó¦MSNfµ„Z?¿ü»Cû¢¢"å/ç—àîÎå:îž{î©“Ï®çr¾÷ €†Ë%¿6mÚôµ×^#—u–ËëázÉå —ß¹\bw•E.ÀÝ‘Ë늋¹¼‰ÓÈå@Í©f‰ÚÕªk¹Ü™£ëEQEQEݾº‘Ë›ÉíˆÁ5^¦Ìxsæ*¿+JQEQEQ ¦nG ®ñ2ÉåEQEQ¹œ\NQEQEQõ;—ÿpøÐù´rcß¾¯¿Úºå›] ‹~¼aÃärŠ¢(Š¢(Šºs¹üð÷{çŽIú2É2dì«cÿ{Ú“Ë)Š¢(Š¢(ꎞs’ôÕÆ­[“寙SGŸ~2â7ýMÿÿÓÿ:í¿?_¿æÎåró÷CÝÜÜ|}}úŽ÷êw‡ö±)Š¢(Š¢¨†ËO¤>“™f¾ýÖ̹'w­.Ù2­²âü’ÿ&³ôøâË/ÿƒÙw4—›o¤;üÕÆ„Q#_iݺuêžlHŠ¢(Š¢(ªçòë?Ü»ò­¯¿Ù»`Ùò¤ÿèU¹"ºòûÏ+µg++‹–ÿ%6((H¦Ù¿}µë¹\f©^.·Ô¼6áùçcþý1â‡Ø?üÞ÷º!±¿—»–¹þ>ãí`°°®›¾L4ÿéÔñ ãÇúùù5mÚ4ú¹gýøOŠ¢(Š¢(ª~žÇ2kÞ‚=‰Ëþ5£{åâgÿïK—Vü©òøºÊ‚¬ÊÊ˧÷o– ¾põ<óô5Ìå{Sw˜o¿úÇÑ}ûD}{pß¡{{÷~rì«c,sIìÞ¿owڱïOúG~È<|òëÿùdÄ7{wK"üÒ Ã_Ê‚¢(Š¢(Šª·ç—¬úýåÅ×¼½yrTéºW¯|:±òȺ½3ÌcwïÞéJ.7O\ó\žqò˜‡‡‡ùvëÖ­wîØb¾²#Ù|<ß<×áïüû˜#îîîæÛ!!Á;¶o6ß–(àÏ‚¢(Š¢(Šª‡¹|îÒO¿›3쬧&ùl\¯Êµ/ïœúÔá¿?_¹fpzÒì­;¶oÛòUͲ¾m(¯ùñòÖæÛ¸:uÜrŽŠ%[Íe¹+(nÔÍÍ'EQEQUßrù'«?ÿè/£‹æF »ph×Ê¿KüS¯Æÿ®rñsÛßxì­ÿýçŠ5k¿Z4éľõ5ËåV¡¼æç—¿ð Ëñò])[-ÇËå®z.oÛ¶Íþ}»yPEQEQõ3—ññ´¤Å›1kÞ™Äéïü˜Ž•=ºxx×ñƒŸËY82÷ygNü¿Ï ùöÇ#jËm”ÿ\Íë±ùjcÂèQ#”×c3fäS}û|{pŸTTTäÇŒRÏåo¾ñzß>Q»wnûéÔñäÍIÑÏ=Ë‚¢(Š¢(Šª?¹üøÑCI_})7¾ÿ¯ð¿öirñ°™Ñ†Æ9;«á'ÏïNXúõÞÝ®œ³nÊ«q~¹ù„“{ï½7¬ëãâ^•n›~üÈ~ÿ’ÏurCîªçòÌŒ´)oN6_§¥K—Îþs6OŠ¢(Š¢(ªž_~xœ÷Î7»ý­O“Žè™ÿÈCï\; ¼æ³õÞÎÊ5ßøÅ¢ªÁ2UB9¹œ¢(Š¢(Š"—Wƒÿßûñ+Ö|îâ2ÕC9¹œ¢(Š¢(Š"—«Åà¤äÍ{×½íâ2«óÎÌó<ï`a·óöö€€§—¿¯‘†2³¹…%3ö,ð@@Ú9øyß60ÐþÇv6Àþîáÿ{®ÿ1ìÿ½ƒÐÑÉÏ`|Ðî@G?O€°‘ƒ·¯?„/ Ìäï a8=„É}¡ BXè/vù«þÅöÿbóbLŒT ˜¿s! tpù{l`‘z9ºzN P+8<°sæA(†ÏÓóá_|a.ûÿ:Öå¿ð¿ó„"€ÞLDTL”Yõ®³»“¯§«?¿ƒ‡«½¯¿tšÿÏÍÓ#º>ÿ´¿WßÉËÔê% 0DQ@ Ú˜Uà. õî€à x®€?À8v€„í¡1;hÄ €¦èï ]PyèýÈ×Õå?óm(sN|ÌZ^|Ì"BÂ"Àßûào Oþ“_%ÎÆ5€R (þ3f.%L@©÷Ÿ1ö »5ݾÿž€Áz¡dÿ“—ÿ=‚€þÂ-08&ü5‚ш¡1ƒé„y„†‚C‹S€äCVâ*âváâÍâ»àŸDæñÕë/ø‘â’æ“É“ûSQTPšSTŸ©i`4?hèèèFé“t‘Œ]LñÌÚ,¸,=¬ lúììó…·8U¹(¹þp7ñäðòó‹ œ N 5‰õ»#.$A(±%Ù,•%ýPFU–Zv[®^>IÁF‘_¥Ôsûµ²³Š¨* Ú§–¥î¤!¬ÖìÖÊÔvÔÖuûôÞÜq×—3 0X4¬0Š5¾o"iJbº{·Ëì“ùS K+ «Ã{½ÖŸm¢î[ÛJÙ‘ÙíÚw:¼w sºë,ä‚tYyPïšáöÐ]ÓƒÅãÊsØ«èa”·•ˆ/®ï²_J€K |YÐvpã£W!n¡Šaäa[…§F8FJ>A>™}ú-*"Úàó³ç1Á±2±—q•ñÞ/¸^,$¤'j%Þ$}O¶K!MiIõOãH“.¾óê]†i&^fËëÇYÒYÙµ9o4s)s·Þ6ç¼KÌò>ª ãCÓ'‚Âä/úŤ%#ß^–•ÿè¯|Q¥YƒUÛVý[½ÙÔß’Ñf×!Ô…èžé­é33:<9™1]7{¸ ¿T°Ê³>µÕ¼suPvj ‚PþWaIp5øD†4Ææ#,*¬ l}ìmœh$²×w/Ÿ ¿–À”àˆ0 Ê|± ÉGR Òm²DrQò)Š'”|”Tϩũ×i²hõé°èèC¤.«™B˜•X,ݬÉl¦ìt싟nysÊrárMq—ð<åµàã'âßèü.”" b!*/Æ,Ž!¾&Ñ&Y õXÚT†KæR¶K.SÞQAHáF±])õ¶…2‹ò–J©j š¼:B½S#QÓP‹RkZ;OÇA—SwG¯ìN ¾¬`Ða˜ddjLo¼fòÝ4䮺™Ù’y©E¸¥®Õú½rëp­ûä÷l‹ìüíp†sœùO]~?xîzÇÊmÁ½Ðã¡§¤'èÕù0ÅÛ܇ÙgË·Ü/Ä_%?`<0/È-X4ý¨+äU¨]ØåãŽðW‘"OàO†ŸDDk<£|¶òükL@¬l,×õB%‘Д‘$—t™\™â›*˜º“öå¥Kú­ôõW…®™ü™Ç¯ë²žeå°åœ¿Ìýú69ïÑ;·|Ç÷®aÞ}œ.ÿÜXYrûðýwYÈñŠƒŸEÕŽµŒuS¿Ò ›ˆšZÓÚÍ:Yºv{ú2ü†ÌFTǤ'd¦4fçRF–V‹6ô·ywM®OÓþÉ+”iø2â);F;æ}Ì+¬LlAìN[œ d.;n=žÞ6þ‚RB-¢pbâ C’]Ò2>²>roèɯ¡¼O…MUNmCƒGSGëNÇH7DË ÀpÎXÎäÁÌͼʒÏjÍFÃ6ÆžÎaz‹îÖ*g)×nc^ï_-ÿk@A!!a<á‘*ÑçbFâTâi’ê’§RyÒÒ;2)²"²Ãr>òDòÅ j ‹Š”H”¾Ü¾}{RÙKC%[UHµ]ížÚ±zœ³Fµ¦æ¶V´6³v½Ž•εn®Þm½Í;iú ú;Ù††ÇFyÆÚÆg&ïLuLOïæ™i™™¿±P³Ø³Ì´R²Úº—j-c½j“x_º;âìDìæìcDæcÄ–œ“\ä\¶d¹j¹^¹•¸Ûxztx>öóÚ}øÙÛчÅgÉ·ÀÏÅŸßÿ, )0>È(˜:xöQ^ˆ}([èJXÁcûp–ð…ˆ·‘÷žÐ>™zú:Ê<š:zúÙ›ç÷cØcþÄVÄ…Çë¾ ±ŸÐ–ø.)2Ù)Å U%Má¥Jºé« Œ¯™è¬àÑ\ù<Í|ãËv…N_\‹Ý¿z~Xæó# 2¤*²&¶îå¯ü†ò¦®–Õv¬NþnëÞŒþé!ž‘ر³É²¹žÅ•²õËí7{½'$óÿ/?ÿåjˆßÞG€´i7À¨ç€zR ”ÀD €´0<X‘ÿò$€ !íBPB Éð@) ±ãÀb?à1ðÈ>U@0l×03L ¦ ³†ùÂbay°Ÿ°~Ø: „SÃEàzpx<^Ÿ„Ÿ"ÈÂ}„" ñ ÑØÃ ÂÆ0ÂðÇÈĨŘÃ0Ù050=0S0+1§1A,v,m,o¬ ¬z¬l$¶¶v8öGì>ìzUœtœzœU$>R i|†ü†œ@‚¸\¸†¸!¸¸=¸'xŒxxÞxYxÍx;øø øðSñëð× ¤ì ª–ñ%í«—‰‰dˆœ‰Òˆˆv çBØŸ8Ÿ¸Ÿø†„›ÄŒäI9É")!©©+i&ié1 ™>YYÙ$9¹¹=y ùoò Z MŠ@Š#”0JAJkÊ”5”›T”TªT¾TùTT(j>jKê8ê*èýJA£JãK“O3HÒ ÐÚÐ&Òþ¢Ý¡£§Ó¥ £+¡›¥' —§÷¢Ï£d€3ˆ281d2t3Ü0 2Ú3f0v3¢™D˜\˜r™†™q˜˜˜K˜WXhYŒXâYšY®YEY=X?².°Q³±%°u°ÃÙåكٰïsðr¸pp,Þb¸ey+óÖ'§!g2g>—WÝPÝn==W½š;8wÌï|¹s©¯¥Ÿ­ÿÇ@Î Ñ`ÞPÈð‰áˆ‡QQ—1±—q“ ™‰³I­)©­iÅ]œ»÷î–ša˜™›}5‡›ß5/¶€Yܵ(¶„YšY~µBXYX•Þúg}¯ÂÏÚÞºÖ†ÄÆÕ¦é>Í}Ÿûݶ¬¶¡¶£vüvÏíì¥í_Úï:h8ä;\;Þu,uÂsrvjrfpvurIpÙ| ú ÿÚÕʵÚÂÍ×mÐ]À=Á}ÛCÓã“'¦§£g‹«×¯¥‡·¾ó†yÛy7ù°úDù¬úªù~òÃñsõëñðOñ? 0 ¨¤ \R úLì<þHz»a„¸… „Їf‡ÁÂ\Âú‹=Î ‡‡»†EHE¼‹Ä‰ô‰œy¢ö¤ô)ýÓ¸§çQNQcÑjÑ•Ï8Ÿe=Çùü$Æ5f!Ö4¶7N5®>^<þû î˜r©Ó“H“R’ “SðSRñSÓÓR^’¼LO§LÏzE©&¶ŒÂL¾ÌÒ×â¯k³³Z³µ²rLr¦ßؾYÏõÈ=zô•õù.9Ÿˆ|¨ú(û±á“ò§¶BÍÂîϺŸû¿è,2(,Ö/î/Ñ-éúªþµù›ü·êï"ß‹KÙKsÊHËbËPå>åk?Ì~tVHUVRV>­Üûiñ³¹Š·*­ê¼ú^uC KÍ“šÅZùÚ¬Úã:ݺ‚ºËz½ú¼úý_ ¿^üÿÍüÛåwÉïƒáŸ†o ÛlÖƒM¸MªMáMUM‡Í¼ÍÎÍïš§[È[ô[âZZZЭҭ~­ßZ·ÚØÚlÚ²ÚFÛ‰ÚµÛŸµ7¶ßtHvøv|íØêdï´íÌéœè"íºÓßÕÖ ë–ï~Ô]Ñ}ÐÃ×ó çCÏb/}¯yozïPAŸVß³¾¦>t¿L`yÿþï€ËÀ‡ÅA†A‹ÁŒÁá!¢!¡Ø¡ÖaذüpÈðÏáãÁ‘Ï#k£,£6£Ù£cdcc c]ã˜ãÊãáãuãçbÞ%[““v“o'§§(§Œ¦’§z¦±§U¦#¦ë¦ÏgDgÎÏl̲ÍÚÌfÏŽÏ‘ÌéÍÅ͵Îó²óóeó» \  o¦Éõã[Á%™%ÿ¥ïK[ËlËÖ˯—‡WðWÔW"VjVŽWùVWóV'×HÖtÖ¢×ê×N×Ö×óÖ'6ˆ747"7ª7ö797ïoflömanÉmùm}ÙZܦÚÖÛŽÚ®Ý>øÃñÇêOêŸö?×;Â;Î;Ù;»»R»»ïvG÷pöd÷î½ßÛÇÙ—Ù÷ÜÏÛ:@ˆ8¼>è:¸:ä=´:L8¬?Ü9¢?Ò9 9*:š<Æ>–8vvWöBöU6;Ž<ŽyHXßzsk–“žÓš3—sž‹‰ËŽë=×*÷-îÜÅÜ{<Â<þî  ÏGE8FôDŠFæ§|þüùYŒKÌd¬vl}œ`ÜûxŠø¸xô ¿› 6 £‰Ú‰MIRI¥É\ÉïR¨SRSqS£SÑiÁiG/=^n¤Û§Ï½²x5šaÑ›©™ÙúZéõ/¨nò3[4»4‡/çË›[o r™ssßÒ¾ÍÌ#ÏKyGð.>+ÿi>ø>ôýYoÁÞ׫m>N}2þÔW¨QØøYúsÙî/ùE4EÉÅXÅaŇ%Î%3_õ! þ­ð;Í÷øïW¥n¥“eeå,å‰å?ìôVˆU¼©DTºVöÿùùêçy•yUu5Uu@õp@MlÍR­tmJízL]bÝ|½`}x}Ï/ª_ö¿Šÿ–þýøwc¼A¹!²¡¾á¼Q¨Ñ­ñCã|u“QSBS{3Ð,ÓÐü½y»…½å~KVËh+Q«vë³ÖÆÖë6‰6Ÿ¶’¶v¶v›ö¬ö±âÝŽØŽ–°S¶3¨óGç~o—KWA×B7]·Ywz÷`~Vϳž¦t¯LoPoEïAŸ[ß§¾•~æ~ëþ¬þñ²ƒÄîAìAÕÁ'ƒ¿¯‡¤††Ê‡ö‡ù†]‡ ‡WGXFlFrF&G)FGSFûÆpÇ4ƢǚÇÀq¹ñGã?Ç'„&<'Š&6 `?™79;E=e:•650?­5ý|ºyœ‘›y4S9s4+0ë>[8»:Çn¾}¾ ¿ðh¡ráp‘ñÁâ‡Å…%º¥»K©K}Ë8Ë*ËáË5ËÇ++®++ó«Ô«Æ«‰«k°5Ùµ€µïk›ë¬ëVëéëýØJ6Ê6¶7Ù6­6_nönalÉB* xky›vÛp;v»aûìÿ‡?Ùw°väv|w wævIw5vÃvËv×÷h÷îìEíýÜÛÞgÜ7ÜÞ¯Þß>`8Ð?xzPq°~Hu¨urX|8{Dp$äy”{ÔwtsÌwlu\}¼qBq¢râ}òö¤çäâ”ã ðåtì 8ã=»{ö䬸lì <ç:7<9/8ï9?¾ »P¾p»H¹¨º˜»D\r_Þ¹ô»|}Y¹x…qÅy¥}åy•|Uv5rurMq-~}÷:ðúÕuÅõÈõá Ñ ÿöËMôÍ»›ú›‰›#þ? Àå‡z*@Õ¡†Q[YS yÑJhS´+ú1:]€®Dw 'Ñ[è+¤¹AIP 4mAOðø L³Áà7° l;ÁpœWÀMˆÿÿáÿ+ðæÿâ€ùøŸ `Xn@” ê¸ppþ§d@)ðèfàª0„`Ê0SØX,öV „ê7p28/\n÷ƒ'Â?ÁáÓP%€Á‡ÐD8""¹ˆ:Ä$â ƒCªøb¤b”a aa’aŠašbafaÖaÎaXlXêX®X‰XeXcX—Ø ØÊØ.Ø ØeØãØ78,88ž8/qjp‘ØH~¤ 2ùÙ<Ä¥Á½û7·w ‰'‚g‰…W‚7†‡†˜ß?ÿ~?þA0Á{‚>‚KBvBÂPÂBÂQ"€ˆŸÈ’(†¨’h…˜„X‘Ø“8‡¸‹øœ„ƒÄ˜ä Éw’Y¨b.EêDú’´‘t—ŒŽL“,€ì=ÙŠœ‡ÜŒ<š¼Œ|žBŠÂ‰â%E#Å.%-¥&eeå %šŠÊ’*–ê'Õ5µ2µu>õ @#DcK“JÓLsBËAkFÕèØé,è’èZè.é…è] jÀ$ ƒÃs†f4£cc ã%“ Óc¦Ff f-ædæ1zG––SVEÖ8ÖQ6&6w¶jvLv#ö|öEŽdŽ…[·žÞåää åìçbã âêãfã~Ä=ÈÃÉÁ3Á+ÄÇ»Ì'Ç—ÉwȯÇÿYCÀVà— ­`à˜¨PªÐ¾ðá¯"ø""½¢¼¢ ¢;bºb_ŠĽÄ$„$R%Ž$%+¤(¤¥&¤¥¤³¤¯d,eêdédCegädå²å.åÍå«(ü¡ú¼âº’²Ò[¥ëÛæ·+•I•½•ûUøUTþ¨j«©áª¹«õªó«'©hiThRi†hÎiÝÖú ÔöÔÖ‘Ôy£ ×uÑí×Ó˹¿ãzgH_J?ßiàc0m¨bøÕˆÒ(ÒhÛØÔ¸Á„Çä•)ÌÔÃtò®*äÔéÍâÌÎÌÌ- —Nccyjåh5|ïö½Rk&ë$k”§Íì}Ýûõ¶|¶¹vvíöìïÛ8(9”9²:¦;a::m:[8÷¸È»|{Àü ÍÃ5ÐuÓÍÒ­Ç]Þý;´ÚðòãAž[^V^}–y³y§û`ùA•gKß^?y¿oþLÐú,À'`9Ð(°9H$è}0iðÓàÃG¶BBJBiCãBÏÂÆ+<.§ ?ˆ°ŠhŽÌ…Ö&ž,?Õú+Š7*;½ùÌâY÷sÙç%1Œ1©±±A±Ûq6qÃññõ/„_&Ð'¼LD&F&ž'y%­'['§ÜIiOUL­NN+zÉþ27*=õÞ«ç@FHÆiæÃÌí×N¯³,³Æ² ²{rÔsšÞȽù™+œ[òöÖÛü<º¼ŒwÄcä?Î?ïý~«À¾`úƒñ‡ž*k? ú\ÈTøê3ÞçÈϧ_̵ܾK•З$– ¿z}û¦û­î;×÷W¥ðROˆUÊJÊ)Ê—¯þÐþQZAQ\1S)_ù¶ýÓæg}MU@Õ`5OuTõLpMLÍL­@mdí`sW]m=V½AýëúÅ_¿Ü~}ýµ÷[à·Çï/¿WL^444AîÜ´ñycuãV]“.äÏK›–›É›Õ›ƒ›‹šg[[”Z|[>¶L´"[åZ½Zó[GÚ°Ú¤ÛÜÛÞ¶ µc´K¶»µç¶v :$:\;Þt t":%:];s;»0º$»Ü»Þv wcuKw{vçwöàôÈõxCn}²¿W©×¿÷sïlqŸj_pß×¾¥~Š~­þpȱ¯Ð èD Tì ² šÆA\}4Ä9to(e¨mèrX`Ø~8s¸wqy;22Š=*7ê3úqtzŒhLe,xìëØÒ8å¸ÎxÄxÅøÖÄÑDÌDÝÄÁ$û¤Ådâdóäùï”íTúT×jZdÚy:{z`1#5ã1ónfl9+?ë3ûqvzŽpNy.p®hn~žt^}>dþëüÒÅ‚ÖBØBéÂê"Õ¢ÎbøbùâÚõ’îRÄRùÒÚ2õ²ÄáeË«+T+Ú+a+ßW–WÉWÕW­¯Î­¯)¯ù¯}Z›XG®Ë®{®¿]Ü€mˆl8n¼Úhß8ßäڴ،۬Ýü³E·¥³¶U²5»¿-·í±³Ý³}õ‡çÅŸØ?UÖw(vT!FÏߨAíòíZîÆìVî®ìï)ì¹ï½ÞkÛ;ÚgÚ×ÙÞÿ°?¸sÀu`ryP|0~?ä?4;|zøõpâvÄ{dzqôåhøèú˜ãXï8ð8ï¸ãxÿ„úDñÄå$ùäçÉÜ)Æ)/ÄïÁ§oO[O·ÏˆÎÄÏ,Ï"Î>œužíž“œ‹Ÿ[œ‡¿;o9_¿À¹à½Ð»xx‘zQ~1zqzIy)qivt™yùórüòòú"W†W¯¯Š®:¯Ö®á׌ײ×f×~×I×_®[¯®/oÈ ¶×¸±½yt“vStÓ|3}sˆB¢˜P(]”=*•ˆzªBõ PÇh,4 š­ˆ6DÛ£ýÑÏÐèOèŸèvôz}Â@"â} P¼Z‚N 7 12øÌ‹ÀrÈû7AÜߎÓà"¸öû?OÀs*DüÇÿû9‹Šü[À«Ì <6ln@M€àu¢>AkÖÓÐxöïšÿßhFè›3hš…·­Ù0òŸãÿëçwY'EFü¿ržiTXtXML:com.adobe.xmp 1368 884 |Q a*ðIDATxÚì½{TÓwžÿOç²;3»ûÙ=óמÝ?öÌscÏVÀj[ÚNo;3™vÖÒ_·-ÓÖ 6ÖÚ¦S±bÚN¦Ò¢U­Äp"µj¨ ñ‚ (0¢H¸&ü^ïÏ;ùðÉ•p Ey>óžøÉûó¾'Íóù¾|"Æ0oˆ@óÀ<F0€Ì#`óÀ<FÀ×ÃßýÝß}ï{ßû{ø‡ø;þšÂïÿûßøÆ7Ö¬YC1N§x×ððpTTÔw¾óŠFq~ðƒððŸÿùŸÿó?ÿó÷¿ÿ}zzºÙl’ïÈȨôot4ÔSTŸ{Goë.pŽŒÒ_8RZæËÓW^SôЫE¥UM<»¹Ùuñ¡W‹^SøUm«X~Œ0“|÷»ß%©€o}ë[ßþö·¹022"5~ò“ŸP„»îº+н?üáß}÷].ÝçfÝyÁÎ6Ýܾïü¶²sùú†@qN™,ÛË/ìÔïî¼½, ÷kŠJ,ˆ^Y”w˜UpØ92‹ÊK¥þòBt’vÁŠÜƒ§®ÌYÏ#àö¦¥¥åìÙ³{÷î}ë­·¾ño¶ÿÑ~¤ÑhöïßâÄ “ÉÔÝÝí-Û†‡ö³ŸQÌo}ë[O=õÔŠ+–.]úÒK/=ýôÓÿõ_ÿEE;à•W^ñõzúë.ߣ^v¼9*!/:± ÿHãØÜ^°û)zeт廿<Ý2†Àᦦ¦æ›ßü&©÷{ï½w =<üóŸÿœbþíßþmSS“×[ƒá wÿæoþ†ÂǹpM2/:!ïHõE¯,\øÊÞÇ_/šp¦škÅM_­9H²6&Y»`™zaRQjö±±)­;p 9îÜ~±lÏý«òîI.JÎ8ì•/ðæâš{W—>ðJþ•ë=3Ûæ]½ƒ Väþá­=áS×·…À{ßËÀŠ`€™GØr?BêÝétVTTðm .¤+#~6_À¥¾Ñhä)H#Ûl¶»ï¾›¯/xþùçE#€K»CÕ-щ…½Vøæ4ûË=³½ì܄ӿ\“>Óò—üZºë¯g^J?°ð•² Ÿ“LãSHU:G&^Ïŧª¼.:©8zyÎÝËr¢WhŒ—nHSãþkᙘä’{“r[#ÀoI]‡Œ†zl/á‘3W®*yù½Sí»Ñ ¹I€¨„üü#y­'¼qjÙ¾ql“ `#Ì*\¥=zT4‚«=©pöìÙ1Ï…;vìà‡üô§?¥ø^b~a²öåôÓ,ö®î]{(m§alJ+ÜF@ýÂU¥¿z£˜þH“¯ý¤B*õE#`áª=÷&å^ñgø•¸\úÒçìOÈý£ü3‹Vë–¾?¹¦ð«>ÝkE?#`ÈáôkIL6;!·Ñ©•sjF6 #ÌQ#€ß{æÌ~XÀøÃ¾¾>©<|¦%:©øïî¦î™*æË†‚dJPDŠ?è¡{·í­[´æ 7Äyø®ÞÁ].=Ûºplß³÷e—ÕE%,LÔ\¸rKô,&4DµßÝ?xáJçé†ëç¯tŠg ŽÓ°;þ/m_L’–šÂ>ä”þ ؇&Ü+qíVí¥Õ×/_ëv ;}Õ²—PXq‘_ïaE½EE½lé eé§Ã:p®ù&Ýu©ÍJ¥ ^A±T‹–ë=g;j.Þh»Ù¼/‚<ÁÁ¡aÊºÏæ° ß¹G»>K!' ¾›ŒpçÎãgø5b#@Ì…¿¸råÊÏþógžyÆ·l_~ùå/~ñ‹ 6Œ¹ÿ³øÛ˼Œ_‘sòžÕå1+Ô[­cAW HW<º¦ðZgßoßÔ’àOÙV)*O.EüÉã?m«zdMaÔr5‰X {­è­ìª‹­]¾R™»ö西äžIúèðc¯.X–CTZºþþþgmÑC¯–h± |§?;`ÿÉ+ ¡òÜM·/Wß³R³$µl{Y}¿Í!­²h,X‘•w¨º…"¤«O=²†Ä¶úîeê{“òþ/MGå ><ŽÔ\MÎÐǾ’'d·{a‚æ©?ïý¤¸¶«×>æo¢žÀfwìÐv£ŽŠ·`™]rÞÒ÷•¿´ºðÿ6î3_ë¾½?rVƒ,6Nk²ûóLñ®£6cv|9àv0œ$^GFÌ#ó õ²ãÍLÃ'ì~à*OÞšÓg;,·ú¯Xz4‡L¼VD…ŒN**þêâ˜ç™‹¾¿û{:à Íó›tºæ«×{®ßê7^êøKîiæw¬,¢jRR^^@ïÀP܆²è•Å –©ÿ´µÒpþµmû; cë+=²`¹†ªðú§_IÏV€(©àt1Gj˜ @Ù=™RJÅ›hÏÅ,y³‰a6[ìL«Û­V—d·K#û\3k˜Ðט¥¯aÆW¼ÉNISVF“ÉâßÞæe±{Åä9A"`Š£ÀŽö€0¿Œññ.\ðPRRò½ï}ŸpàÀPŒŽÍfû×ý×üà·nÝâ1Á¿};¥³~ýz1¿FÀdk-®X˜\²x¥†Ono.2Æ$iïKν*h~ǰ#€çÕÝ?øØk…1+ ^ShºÒé•8]!Mïþú¢~»#@³>J)$½üÞþ‰:ˆåx´¶UØíŸŸúùqß8o« щy¤–wyÁåbmUvürtB~Ì uôÊBª¬×]g¯³™öļÿY[Øg’fWÝx4yLb~ü»ûIÛ{ÝXz¬9&!—²#I/:<¤6ŒN*&ÁŸ‘Æ·œ)Û«¢Y- ÷T5‰y¯H,ŒZ¡áFÀÐø‡ùZ€¤â%ë÷¶Þè ޝÓ°4±¾Ëøí&é[YÂ%iìX•ÉjÒ«T¥L¸)Si4*ŽFoõ6èéÍJ³‡î´Tr¯BÈ5â³L¼'I$Ra¾=Ä«§ob7eÉåJaze§SP2†™ñC„ž×Ùg¿]•¥Ýb2êôûUìV³QÄÒØ±ZLzÞêmK™ : å&kÈå±ê5Z£¤³¬f“¤,ÖÉ4Úö_l³F!W(²ŒÖ;¸Ž`€¹jˆ+***¬VkGGG{{{}}}^^^||ü7¿ùMîðgzíZdðblذn$ñ?æ^&{×]w™L&1© F€{ÝþÄZq|k@’vQâ̰Üxh5[‚þþîS‚eøØÓpŒ«V6ŸŸ]vŽÇ¤¬ù®`?ßWÇ#§ô‰‹üùãô(°?úZ!éó—Ò÷ó+<ä/¤EåµNúèõ—¯Þ°PK9œ”'ýñ-×{%jbV²-ô®“’Ç.×üF®òèä'+ŽŽr›cÃçÇc’ЬÈ=pêŠÐG.¡ýæÖJº“˜{FØdA‘y…XŒÕ›õ “‹&ìækõEDp7 ŸLÙ#´É¨Ó•Û(oð[=ö‡×0ûã™ eâˆ.#àK¶5àîeê c+/ •ÅIùTëg7îãK¾ÞµV½Â­¨ã•*•R'ªmA?Y4ŠxQ•1dÖ«Ä[t&R´‘þ‰”lp$ÿeJFÉï‰Ó˜Ä:·Ð§÷õ½FïVúz—èÕ(ãb#Ý9+(îÞà)5„šFÆÆF²4d¦éÈ ‹ŽR0‡¬Úô*wÝXÞlYÉH,2"R5M±cÒ±ÖÏ2ÍŒ “EF* !5€^§n®V£ÂméDÊ4ŠòÉe*zXžlRI­­ø‰ZN´½<·°ê#ùXü/¹.¤±`Ö²!9>\í*éG'NbÕ,zyD¬Æ>K£w–¾‡tÂç}|$ÛMô…¡5à #Ì–@‚ÿÿý¿ÿ÷OÿôOÿøÿøýïÿ»ßý®TÙÄÅÅÙívõÿAþÏË—/ÿÍßüMLL /Uccã]wÝõÐCI …™]\²8)WÜyþanuLrɃ«óIyò3 «®*ñZ ûX“T¼(q·ùZ7WÈҊпZ;ú¯ÔPœÕëýÀ68ÌW¼”¾ÂÒÞì¶ÝŸœ·0Y»nëÑ@qþ¿·ËbVÜ—”{ýÖ€XÁ²ã—IäG'¾µýؘç~®ùU·°åúIÚ¿hN‹wõÛܤxz}©oÛrm¿Ïp9ŠR^Y¸m/·Bؤá,WS9•ygÆ|;ä}š²­’š%zEŽIhs*ƒ¸"€Z#z¹ÚPßNÿ°z,6$9m·uZv¬\¥ÕüL¿˜›ös‘탈5…¨ÕU¬æ Én·0ñ/¶%)T?@¦~gD}¯j"§`LvÞ;¾™ôq¤fz*Í"XP2ƒÙj1jX?z.Fð-âd3¥h1fù‘Y¦IÔœR±#=»)‹ŠËµ´‘> ¡:v#œűE4ãŠ)ô e¾ÖCè++‚ŽÞ€ÃÎ ödFRÐØfª—JÒEÄô2FŒ€‰€Ÿþô§“Ç÷â{ßû¥°cÇß'ÜÀ¯<õÔS”ÎñãlüÆéõ®]»ÆÜ f܈¶˜ÜF@kGïý«òH\䚌b+’=Îr8#×’~âM-ŸW÷Å1ìüÝŸJ(Îÿ¼^4èpNÙàU;V×µ|wTbþ«›õúš«O]!ïõ÷̆²˜Äü… »ë/wJŒ€æ¨åRæ[öÔŽy?“½¾Øj½'awÌÊ"ÙÇGÄÁ@)» Šþ´µrÌç8@þφ–[ìÆ¤bùæMð…Ûöž£+Q+rK5{eça¾¬,ŠNÈ+þê÷#øu ;,°8z¹ºåzñbÇ¢¤‚¨„¼•ºÕcŸ.©q­ ¾•^ªØ¨‘y,¹wÏrõluk~Oy¢ñœá÷ÎJ0$‡òG ¸gAMÂÛ¾sûF¥ÇŒ«-Ö ‘P é¥ò•^v“85«ß'*^Žt«³Q¯QÚ^£Óé´þ=OÙ§2ŠjnäsßB‹ÅÊe|RXfe°åb®ñ*³ŸÂÄÆEFÄ»ššÍ*3akÕÇF²õÔV”2[xÀ^SÐqòñÕñv³F>> ¯w§nŽx äÚq…i¢a@%TºÚ&ÞåYz­Ðqîð¥fƒV©ÈÒO4—k5() Ñ÷±ƒJo TÓ 2 Üü*ê7ï ½Õj1[B^ŠÏx=ðbü ½ÜK¯Ú •B©ñe$k#UFÀ‚ ½™ c±†:„…O_¤t ½ßÑËûNpг/2R%ŒÓÀ£—Š-n̉TéÍ¢&0’ÏšŸLíZY$[q«·Ž™µ¬±î*ý(ÅgéÇçýu‚©§Ìb¹K?›ü+‹Àa7øŠ€oûÛK—.]¿~ýºuëRSSßÿý/¾ø¢¾¾>ÐíâÃÙ}™Œ^ÿøÇ?þÁ~ÐÝÝí©'ƒ^óó¡‹ÜF/á¦/NÐÅGÖvt±©õÌ"£×aÝ}ƒ±«òHäÿñ]]¼^~ïŹ/9·«wpÊF/Ré1vøÔòœË5”¦ß?ö˜Àú;eº&¸Ühâóö9/}çmItXîOÎJ, Eþѳm –©Ù2Üê1÷./nXmtctbáÒ÷ˆ]ðþîÓ “K,Ë©:׿«ÞùÒª&**ì}uB‘\FÀ˜ä=­.ØÒüØZ¶+!&1F˘û°†¯Ù0ñÉå„’È òX% Z«0‘©·Žù1T¦€F€°0Øè]¾ÀÓ˜H(5VùƒµUY#IC«IÉìóZXäî©W«IçZ·l7j²â…Õ q2!W[Ó.´°‡†´˜LÒE2Áb111¤4r§€ÕP©·²ÉS^{Ö;va™F|–Îl±uJ~:ƒ(&³ŒfaÕF¼Ö`¥U+–JÈ5F£‘ 9A˜ZÙF‚H…Ñlµ[Í:eܸ§›MZy„Çl¹Õ$$#3˜-&}ê¬,¥<Ž ®žt`Ïr‰Æ :… riÁ1¡PÓà™NÒxJEèFÀ¸ŸéåÙ‘îã3$½®ã“ðfõ[b•úÊbgÛ â=÷Gø½V“Ì=b­f£,‚_8zl³N,¥b·[y³Ë/ÀÊ|¹YHFOF´<üej7³ }f[À̾(â)};ÿžQ v”Õl`…v …¾ÈÒMF=ß<ãiŸ0 #Vc`€°âa---þå«Ó9#@¼÷ßÿýßÿíßþ­ªªŠrY¶lÙ˜çCøf|E€—ÐÜÞ½8)7&©øS-ÓY%µ1«öÜ—”'7ºHÞG¯,XúþÁ Y$üåKRà÷'ç]ó9ZF€PÎ}#›E_¾ûÁWò#×þêâ_˵Ò?ºò«×]çšnˆâ™­XÁt~îá†1ïç²òÜê±3S#±€. nÎ_°L\üׂ3c>û<’µoðWò¢V¾ðNù¨ûñ›¾0P9£–çœ8Ïæ+GǼŽ`ÿ,?a^°|÷ÂU%Ÿjk¹Ë žÀOjä+2Xò}­¸¹Ýê5¾,z¾ ßâ£7¬V«—àáwYY2ɾ}#`ê+„¹k…÷u½ DzK8Œ»Ùhä“ó¤j¸ÌŒˆôÐØB™å e–pøáx¾!o š%ÎïêoAeñw¹Å$–ÕÈtt¼B¥ÊÊÊRñ¹ÛH£ÝÎt’L'é7•{ÎV<|ÁC©š4±qZiãGfù´¿ÄÁa¢=R¢W}–Í SÖ®t­J×i‘¼âI}“N%“ÉµÆ Ì%VBéFw»9žM[×4X¦¡v‹ÉuD IåxÉ ˆI\ëz?«.K!“KM-»6Îu4ÛG ׉ÓÿbY¬¡Î~³^ðÒÆGïøPg'Œ¾£Wpaä’‘aÌr`áú\ËäJáC Ñ›‚fÊ?¡‚±(X$:˘«Öô)V±Q­Ò[ehä{eʶNx­ÖÆvœKÀá5ÄÃkjjèŸCCCÃü9‚5mF/Ì{ï½Gé?öØcVVVNÊhjëîêøç_#À­gÇÞÊ>¶0y õ!‡3çà…{V•.NÒˆF@ïÀP,iàÄ‚ç6•ò (¡?¾«£8÷¯Êíî ¸"€dsh+š£WäF Þ„}h¸Ï6D¡¿?'ý¹ 7(—]„ƒ†WõZgÿ}IÌ)x9ý€xñX}{Ôr¶"à=õ)_Ÿ…ǹÞÕ_r^ÌÊ¢„¿|)Z åU/L.¹{iN…±Õ÷F^¤â£©H1IŪòz^$Þjá°Àèå꨻?)6æn`kòãRËxŽŽ~½»˜®ÖöŽÏFZMúxï£þ„_óÊñ¥Àz«_ÅËÎ_ô«gKÄÝrÈgEÀ˜)NzFߤ@JÀ0nJ˜õ¼tn@‚ EJwe³ÞlžmVUê,V»}Ì®WŒkc‹Q¯×i™&çËãÝ>Ÿçes7×ÞQY"îùU»Ùõš/üÖèÝ #{ä"›–ëý×(6">Kà “ñÆæ½eãñuñ‚ÀúÈãGUäÄFÀ¸˜”6*ðv}&µM.u£|\…[õÂÊpkàšÍ4d#@Š¨Ï§`¸g¿ý^h·˜=l)(^)þܶC>ËhŸ°$qÞën^Ö¹ ×Â#ÀÏèVTJršZÅ'öij5ìC `'#F IüÈð¤Ø³D²"#â]†ŽAɶ¤ƒÚì©ëFb±DcqL`¶Œ€³gÏŽ…<[⊦N¯]ûáHYü÷ÿ·oâ~®9w8¿XVòû”=7¬¶)b: W»îIÌ¥·J«š÷šïYU*ÝàùÃ[¥Ñ+ _[dö›þàóWo°'þþO%CþV¶Û]+ C9#ÀP-J8„O‘s2än“œðך1ÏEþ¼ùë.ߌYAš¿hí§GÅìšÛ»%²ýÿ¯}RáÏã`áÙ¦tã¤â? Çò_ì?OÍBê½°â"d€Ç`6Ñèg¥gù9{ù9’ìÞ¹š/]?”3‹k¢ ¢ó_ù«Þéñ@>¶\.0Ÿ¯º¦ìüÎÛó„ø)ÿ‘q2¹,Þó‰ƒVL\ÇÖÚÛ2ŸåÙ†,÷ùìñr¥R)wÝâÞ`Oz#Î3“$‘"h·Û­f’'r=[ÿlµ“èŽt¯Y˜„6±µøFm¬¸H[P&r-—&v6g/Y/lõבÚe'ªd25ˆõ ,ZБ2Òwo1³°Mò®b –‡ðZÐà ž©Ýn2hdñl¶•œ‘¥g…´˜„mé\±ÛÍt§ŠéJ¡ýåZ‹p_a!×̳A£VUX]ÛÅe3Ét»Ý¨•‹&[ÂÖ~GF*øqv1qŸ^ËÝ“óv#ûk«Y§RÈU>'áOx¼¿0œ"•Âcùìfaš˜Í$¬i°Lä`µ gX*ͬB.;èכXýǬ&v\¥l¢ÿ…Q£'!«7Ÿiç§TFÈÔ¾&L.©¬ûc¯1{¤BéXÌ:’ÄãÛìIc„²ØM:…ôÄ„àNV¤‡`ôòà â5Âeûó#E³ÏßèÕË]7 ‡ThÅýÂN 9÷uìÂ"~î@ LÇܧcJ8p{K+Pol¥˜ÜYX·µ2šyé‚âüº7‘K©FªZ£÷÷dzsœäÈ@?*9LÐó Ñ¥s’½ÐLyºNô~„›Iïñl7&FÆ…WÔÒD ±“xܘY'ó=”ŸdfҊǤÅÉù‚g6)mQxF¢Óìzeܸ“¡ >“kÕHÚWÎ7·»[€ÍÓZ\«!øœ­g3Ž'nÒŽ'VÆt=ÜNóâ¶b‚Í·ÇÊ.3%2Kg;iüŒ·ˆH _á6q¤½g´»NpvØ]{¸ÅÍvsÖ¸g$“l`Ï N4†2ðâ#üœÑ详Á3õÛêzÏ qùm•ް¸¬ ·å{÷Q|ñ^ãTºÇ&•wñÄ'ºç½­FéJ,½9”+Å‘YÒ¤Œ^êU­×ƒ=Ýóí~G¯U+¥2{CˆÞ£â:{ÐLÇ­ƒ ìÆñ“yßqwÉ$.3ŠtyÞâC{4##°Ýø_د×ë¿ùÍoÞu×] .t8|¿ß¥þÓ7¢“Šƒ#‚’¦bPú­­­¾*Z4­9èµ" øèÅ_+}.­|ÂÝAŒÖ6ÝŒIÈ‹^±ûùMålê;a77øÆVaÉ}Á¦/ ü"á‚çH¸2›_~â²_;äpþn]ItRÑS){\~t<iùë7™$.ŒNÈÕ ŽÑœ#®ø~ò7ÆW$äE-W?ðJ> lž œq8&±pÁrµá|»´%?.¬a»ýWä–Xvw…²±/¼£[˜TDMwõz¯ØG”ø3o—‘ÎxM¡gv#Ü)hn³.Nbç,¾œ~@,³øø@aE€æà©+ü"¥908üGÅ~vPbBÞî//Ì/`ŒÏ [ÇgNý i¹û¼À éØ'ùH1ßü<}pêï¯ÔüJGùÙ'‘¼u2ÍøQ†!¥bÖÄFªÌaë£ `RIÛý:ûL´zà¾6Ògd4Mn¸O"¾°„Gg i¸k-¿ïøv{€î<ˆØ`yPJFx®D¤ëÀS€$=_pï½÷N ¡§g©q­³²²’ÒöÙgÇüÍ¥ó ÙûüŸÐow ;'.O#@Ì4Yy(feÑ‚e9 –©ïIt­çÞ_JßOÂuQRÞþ“Þ*âËÓ-Lî&<³¡lÈß³9+>ø2&©pÑʼ3׃•—ê•Î{VæF¯`çç«k÷F’»ºáúåk®iv·`ŽNÈY±;:IûçmU^~Á¶@Câ6ìvzÔýÚ;eù1‰¿~C{±µË+¯ÍEÆË)Íâw¾8!öˆû,ÀËl=ÿŠÜÕ›õ$ã¥wuõÚ_TˆJ`;ÿ¿’" 1Š(Yj½1× á0‚[ý¿‘k£ò¢rõ5WÇ<Å`N ,£·[]‹ù5xš×œÇnv=î1>>NÒ<3¸ºW!=âÅϱˆŒŒ}ûö©ÕêO>ùD¡P¼ð ßø—ù—õë×øá‡ÙÙÙæÂ… ÞzÞéüÅ/~ño|ã;ßùιsçÆB>ÅmĽ"`á*f؇†N ŇÃñtÌfóÏ~ö3*‰Ñhó>&pÄ6è°“ºÞZzîÞµ.#` ÇÈ9ÝFÀÂU%‹“Æ ”õÄ…k VhbV¨£–«­”,Ns{÷C¯²Óþ,Ë!]f¸|¬®mŸáòúìcQËs¢WÜ›œ_w¹Óoñxúš/M1É%1 š_½Q¬>d:^ßn8íPuËÎ7´tIoä/س ¢ó£–©IfSáK*› +.n/«Û 2<º—xÙñf¸·Ĭ,¤ þþO% “÷,}ï %r¬®ýËê–M_œˆžG¸`Ee-êyIŸÀ쌇VçgäŸ!}N7RvÉGX³$i—ÇøIkÇ_®Ï®ŠIfÒý¹Måêƒ*ϵ=Û¦ÒÕÿá­½Q ù1î“Äûœn# &©(j…hŒ—¤îòÍû_) ©Á›Ú¬sõóäñ„³?øsPC™ØâÙcâµz“íqÇY½þŽŸ)·ôX F˜T»‡ÀòåËÇ<8<<üãÿ˜¿[[[;6ÉOµây×C²ü_®Î@Vø|Ú>Ò„—.]úÿøŸþô§ßúÖ·(å¿üå/Ê\x±¹¨&vµö‘W Iš.^©YøÊ^RàcÓx|`ö¾º…²}w/˹på–W:<ëå$­µ"÷îej³¥[”¯<4µÜzf£Ž4̪=$q,W3¡»jOtbáÖïãóüA<ŠA‡óÕÍG¢WÓ]Ñ+Ùú|Ê…òZüÚ!µkü¨—w@:ÿWo–’8gBr óV.\µ'fUiLòž˜Ä¼Ê³m<²ëqUM ee¿ZpýV¿<ë+zMÑX9Ù¾†bº}Qr~¾q,À~þ}Ç›}]“TÌN^X‘ÇV¬,*›—ð—C×»|+Å÷ü¿·ûôÂÄ8²ìýƒ ùÒr«ß·:}ƒ;tç_L?xo’fÁ²œû’sÿ¨8°­¬Î*R0aÁHïÐ]xnÓþÅI¹t{ô õ£k “2*j›nøšüŸ$é·–ž{)ýà²|vàÿŠÝÊòþø®îýݧN]°ˆÛ"Äò¿ø¾þ£¼3übaÅÅßûraÂî¨åê‡×¼¾¥*ˆ[ÁS¸bé&Uÿ¿oí¡»–å<´:ÿ•+J]–Ú%~©:×¶î³ã¯-¢¼¢—«-/^Ÿ}ü”ɨ/¾¬nyé½C/¥8mºîeLðѧ>xaéû‡ÿ¨8øqá|x€€ÛÀ<F0€Ì#`óÀ<F0€Ì#"êÁ´©8wîÜYs k\µA½r"zÀôèîî¶Z­Ô”p•`nB’„É7hX"¢LÞÞ^L4ªFÌIH²‘p#ù KDØÀôèïïïéésÙ áFò –ˆÓc`` ··—FÕ€9 I6n$ß a‰˜v»½¿¿FÌe#€„É7hX" ¦ÇÐÐÍf£QE¯ix!Dˆ!B„"Dˆ!¹’d#áFò –ˆ€34Mø¢n˜ƒdãË a‰uuÇ(«B Oe–zMž’¥­>[±ÍÕÜM=ç Sä)ŠÍÛ”)®Þipé5wîB5gÅïl*¦i¢ª _[ôT7èœlï԰˶í6ÿ–È©ïį%„"DˆðŽu²²²øOÒó$õýÆÿä“OÞ{ï=¿élß¾=--Ró}FŒ€°4ÚèÅì„ÝHD§i´ZR ªêŽ[--ÝvÝÞÙÖÜPÉÖýÞò¾ËmˆWjw‘`K+¯ïpŒ9š lVr[U[XKÞ#)öŽêŽîö–çðàÍÓì×½B]]_4ÍèÊÓ˜@ñ¥Õq¥ã¸Z´=3MÐH[ˆÌ-yÇúÃÜÚÃu”ãvƒ…^›+H“ììd}>48dokn®.Íd{ÄøÕ¬Y³+;lGos¾‚µëµþ¦­Tâ­•·û.6^°_©d³£GÍ}á-\ÜŠãÁÑYWÊdcF^CG{åN*ì–6!f5tF¹mlÌÖQ¿“­Í>Çâß<í[66Ôº›«‹¹üÌȯ¬­.ß¹³ü¦càTÑ…Ð=iîî¹ÜÎÚuŸ¥Á³ÓØãp×®§¥áJ7uO§†9JÙõ¶1G—•;¥²uü^.5´U׬|Š{ŠÒ\:8£²}„ÙLA>•Žî¶æÒL¡½S2+kk+ów–ÖÝt8;Ë…‹jCC{s%ë軅 ½æÎÝ5$fë›J¾]«¯¨¨ÐïÝA…ªéœlï8;ëxÕ3óh¤U2¯P®¬³ÎÞ÷-B„"Dˆ0Ü¡Ýn÷r½^(þ† >ÿüs¿ïîÙ³‡îµZ­¾ï€®­³öiኺèè¾-)lR‚é`×ì¹ö<¿¿òû¹ ^¹¾#EÐß¹9*•*W½…}Úvœ kɽ‹ítR©ë I³lí¥¢ŒŽÖ2 š×#ÄbÏùÌ“j³!6ËÝTœ&OÉ9ŽŒ8ÂÝæ§t|ZÉà`_NŠ<½üʰë]ÖÞƒ&Rkê^w|ˉ¬Y·¨Y³æðÙñ”“=NV挣¶î*a´Ízj‹<µxÐéÿhñV}Ãv5quiOçHŠw†i*‡)Êš¢ÜœµmGŽZ_Ùp“â_?é¯:ŸUÝDÿR×vQ]72<84"t‰¼†QW÷8á¬]jyÞ…ñ +×°cðæ ¦Ó·äæPÁsÔ[R…Ñ=îŽq©9a[…µ_¸*ÈÚúî >•T¯KÔAiù]cîævÓUS^ª|kõÈûôœÞ*OÙq&X¯Íºß!|ä]®Ð–L…\ØÄ4ÙÞ¡![”*O+nv´1¶*gGu'~3!Dˆ!B„óÓ ðóÏ?ûí·¼Þýøã?øà¿wÁ€#€F0›Äž•°ÿ‚š¯±jo¾bux¾Û-(çï»#àÜ€x¥e;›\Ì;zü(Ç`0Ô_±†µäîbv´\·ßÚ«TèÍ}ô£_.ß~ËçBžËpß媎4vKJ^÷lµ6 ¯”’dÓ´û‡½ûB®îv_¹ö‰·”¼£GÇ›µºÞ:dw^?ÊVCä°%)Ší*…<£²uh6Êßã=¤#a N|Ýg6VV–ç©wîܹ=ƒI³m­ƒƒí~«ãO§Î9ì•c÷9jÔsý³Ò/ÒÙ.‘³Þ×Û¿JaÈå’Ñ]-ý¤\¤æÄmÎ~!q›¢n³å“®Uhû&úTž§2«MÏt.¸'Ï¥¯ƒõZ€ÏT˜B¾vÉí Ç”tO¡wX3޶º® ^¦OÑΚ[ƒ³ù €!B„" [XXX˜žž®P(DàÈ‘#Á直¨ h'Ožôº~ñâÅ7ß|³¸¸Øï]0`„kkÀl}Zúš¾"½°½Ábé´±µâuK«å¦¥a{Š|ËW 7-ËM«pÝJ×-Môã;å+º§Õbeñ‡f’XØRgé'eÞÝjÚ³=cKIcXKÞÀôÉv“åæõ]=ͬg:ûLÅlJTSÙzó¦É a¢)Û›ú(>¯N£PF^žŽõT6éˆz‹õf«iﮬͻ ánó¡án5ßÑœYér]ï»É ØÄöxoo´°Ps;˜à—oÙSÇšu°Ût¼H©ØržT±Ã•BiCm¦°Âût÷p¸GËÍVjÔ¦)òLa<ý>ØwE MllXÙkùWWèµug{:…Óä®Tn%mÚh·{UçXQU‡z§ÏêQ—,|H·•õݲuÙ°w—R©i _‡œ ì0Dù¶½Æ›Vk«É°ÔµÊ8èhe{1¶ì¹.”»Õt|»BQÒØMwY©!nZŽ £ÊÝiB[±Ë¬­\Ÿk_x{ÇÊ>§Ô1ÖAÇÈ­JV½)ȧ’ŠýÕ–”^æV‹;>ºH%zÖúÕvÖÓ}AzmpP¨fóñ3eí ëlgŸúÚ¹ÉZø’0ØZú&ß;ÝÂê‰Ô‚Ê:󥺂,ú ¥µ8ðË !B„"¼3·Þzk``€/éÅ °««ë£>Z·nÁ` {íçΣ¤6mÚtíÚ5¿wÁ€#Àf³Ñðš…ФwËä›õâõ>SÜ‹Ô]]6›µNãuY¡5ÑM#£Å™©ãq3¶Ÿní _É»Îíò.ž<¥üòÀàðHsy¶x%ÕUpc¯¿êX…Ôö+;SÇË]Zc Ë;® »ú‹ú]W¬iÞÜe¼awŒtÔ§J ½½ôtï KÁ\J’5£uxØÀžä˜ßçs™ûŒiÞÅ»i³uiÜgû]îºà:00UÓe<ºUú >ùÖò¦áA»Íáô­Nß½Nã™¶r|ÚöÊì4IüšÁ0Ötxd´¶xëxù2󛻇éòhGm¦¤BÛKͽÌÓ¤zušò‚¿¶¢Io{GìyÚîs4fêó™¡9gõÿ©ìõ.ÞÞ˽ÂgJãþ0_,UŽ÷r€^óM‡­Dã§æ’ûØCe¥Áý-”V`lïØ»óR©g·º¾øRÒ˺œÌ°ÏÚ·.B„"Dˆ0|!û1‘AÚ~ãÆGŽ ñ®ÎÎÎ>úˆîýóŸÿüÉ'ŸlذýÐHKkkk tŒáÚ0;Ÿ–aö¼:7£N·.µ“¢ö)ÝÈ¿ë£#l97)6–’ÍÖÛk®Ž:…ÅÃa*ùÓ·xc#î9X1’7†üUg§68Lw8x|¶ }Zž5–clÄ9ä¾2(íWù„’8„šöºëÃå(¤0<2ÔÕ;DMï¢÷Üu _(´’gkSA†ÜÍ:JM<:>N£V^jV¡à4Hx:ŽaïêPÉ^•—ŒC¡e¨­IüpÖtŸ®.w¹”¡mPxð¤Í]nv„ÁP6ïNe~‡O[Q:Ca,³Ø ¬}lîöd£Ëï§rÈéÛ•ÒÏE¿„^ößk¾éÐaì»Øª£Nñã/ä8¹Þ±õ±'_4ŽŽ á7B„"DxDŽ܄îð°««ëøñã999ééé;vì8zôè7‚ć# ,FÀÀÀ ¯Û.´ glÐGãk.‰}phhÐ>™»X±m¶Ùm+{Èñ]íêyÝNud¯‡msn}º:<„#åYnŸ¯Â¬•??³io ‡ÃÑÒÒröìÙj0PKR{R«â¿3 *†+`Žºô“Âb± ñIÑ)‡”¥CêÅWºÜv¹HÃááaúáÅ'{g6t:”òL•óki^…Û±ü¼ä3Û§”ì ¶ýÊÔÝÝÝÔ]]]48ñ%6#PKR{R«RÛ¢5f T W0À\„ôÆÅ‹Il(—7O9äâŠR£4¥k¤oÇ\ÄR€™Uì\éÍxʳÜ>¤ÉgÖ˘µQÄÆ]˜L“×ôÚµk^MA%'e&}Em‹‰ÖÃŒ0G!™QSSc·Û3¥FiRÊw@.Ü$uç áKyÖÚ'LUwùÃÔ­áHÓ·)ZZZºººðõ&¨m©…ÑÓÃŒ0Gá«£‡¸:š~ÈçÏéõ …‡CTw3›²T‹ÎxʳÖ>$Sy²·Wù‰p”<iò• Ò¦À,kXᳬh‡éƒŠá F˜»¿!Hc8f®…îŒ\†††l6[ˆ)_»v­YàêÕ«¡Äžrggg³?ÚÚÚæNû„Þ8sª'Õ­_{kx5?Ú„´0ší À˜Fé"ßÔlMMÑh”†.\ô_ I¸àw 455‘šš0ætr =$ìvûÀÀÀ„)S™×­[÷ÐC=/ðÈ#èõú Óu£ßwxàèèèç=¡,î¾ûî3gÎÌ…ö¡7Nˆñ©sCLyRåoii ½ÌƒýýýAJNåôùÒðܹsÓl þøƒîîîPÊ #Ê ÍÐÎ`€6@Bôå—_¾[àá‡NJJúÍo~óøã¿ôÒKƒñ+áƒB^ýõ_þò—”×}÷Ý÷Ê+¯>|xÂ[&•Ë7êëë'ƒÝn'­Þ××–8JüI•Á‚ëׯokk›©nŠŠº;(—/_žZkÔÕÕ-]ºtáÂ…”û™gž9vìXOOÏ»ï¾èc5#€¾à‚rýúõI*+‡-¤SÙõÖÌ­D¶¡]¿%k&»ž]Ü2{‡»ùÉÔÑnØš‘™oûÆrÔ¯u¸0@FI#¯xðÁIípÙC×áp>T«ÕÛ¶m{á…H´øÞÅÃ@.Pü'NÜ{ï½^B‹”×Ò3’Ë'Ÿ|rÏ=÷,^¼øW¿úUAA×»Dee¥Õjõ½>00 *F¿)s`Æ ÔJ|AzzzvvöÞ½{÷Pݤýƒ¨Pnj™©õI!§¥¥ñ\^ýu*aðø¼q‚Çá!õ&Ov×®]¡Ä½üb[Qÿfffúö£o‰ÞÞÞ@%ç.Lpššš¦ÐÅÅÅ111tûoûÛÕ«W?óÌ3<µ'žx"Pšâ¹!þîï7WmZºÄųkËê;Bû2è×®}6§±ž|õÑG2111dee«TgÈ9))ryz}0%ï¨-ÍW«w¦Êå;ë{%×;ÊéÛsg¦\žZk›¨|]Õé)®ìRSSøËìÊ)Hw™vÕReRvÖ­F@Yê³K•úq»j¨qí’µõýøÏòô‡+#„fØüAòãÁlnnæBeݺu¤I>ýôSRq$“¶mÛ¶lÙ2[üJ¸@‘ëëëE`ùòåííí©©©¢@ŠwFr¹ÿþûu:©ú²²²… VUU‰o?~\©TRH?µ½î¢ø¤„{zz‚¤¼aÆÇ{ŒšeÓ¦M)))|¶™^Sùe2™B€r÷{/×¢ÚßKy’hLOOï½÷žzê©§Ÿ~šÊ”IµXß7J3]»v-2È-Aªà…Ô%~èå÷j+ꎼ¼<ê¸ Õ Þ­¾ïטlk\ºti±5UÇápPXQQ±`Á‚ iú6EßýCm˜üߔӨÑaí0—eÊèŸeæPÔÕêÙ%ŸÍÖ××÷ /PËäææ†¢¬êÕiôå°µ¼ÁÖÛ^œAª<¥Râ®°“!ü ûü/#€Ó‚`«WËåiÅå•Å;ÓIÃç——ïL“§J¥»Ãÿ3ãÔþJ5a·NhªŸlkp‡K­V‹«裔œœø€O°{ÝHr‘"X­Ö [‰ï#à.Ào~óRt$×9"Z*\zÁµ¨ß”}µ¨B¡àê‘R&‰K}AZ·µµuúíÃkê×½*ªßƒTعs'ÝNÍÎwIˆFµ ß$ÿñÇO¿üAt{BB¹sç&Û­¡~Ö @¿ãiìQ¾â` Z­V-››K¥ ¥)‚üî'm•)N±zê.íZ&$6}öY*Û8ðlU“QL‹=›š“óßL b:¬¿ŒÅ\šù™°œàÙÏ:î¬/½ººº%Ö¯_\Y “ó*º½AÐͽµÌ È®ì°9½ÍùLSgwÌàhΗ§¨m,:å®v0éž–VÜ<ÖeHa ½¸¹«·«¥VPå™-l'A6[³P\ÝÑÛÛR[.\®t1„âR:µ µÅ[YôâáíŽjõÎâêæö®Ž†ì*·íÍÕ[S¸õ_[_Ÿ­®ír%U›Í7.¤ún—n¨ž]’#ØOK”UR# ¿QË:F¶é³ÌT6…wëUÂ]ºI¥RÒkËÌwü@Úp`€I}þàWœ·ä*—Kez—Â矾±±Ñï½~%œß˜”åB²J§Óñ ù\Ñëúúz®¸HÃO3^J³­­$heeåË/¿¼oß¾3g΢޼y3`¾wÑõžžž®®®à­$꺦¦¦{î¹'>>ž´ú¯ý몪*ißÛ¹ ”²¯ÀsÙ°aòeË(‹Ç{lùòåª<©öáŠx衇>úè#q eÁ_S+ù½1HˆƒòÛ£££×¬YÃ_Ëd2î………Ó/¿o[IyòÉ'-Ëd»uB#ÀïàÒÔq÷ßÿÃ?ì5øÈäŸ/¿ƒÐ·)‚üî_êóÞ ™µÂ×ô*SUÊ“f- ¨Mm<†õä³Â½BLÁ&s9ªÆy·\ÛÃhÈ'½ï«r»ªw²u[Õjúð¨ó5Rm›#@’;3Äè Å”ÍÖqÅk«&®®¿Á.gVŠ—{kwz˜~Œ€TyZ©øviš|ø¹çž3™L~ï $á|!‘CRMWôƒ›®HO õË…îtr!<¸hÑ¢ÄÄD¥RIõZµjUáwÞ¡ñùð²²2ß»º»»I1ŠF@ VK¨Õj©Àâ.t.ä¼âH¿)û5x£‰+Ø¥<Ùö¡ÔjjjH£RáKJJxŽÔ5|WÅÉ“'ùøIU• ™ŸŸï×à§ëº7ôòû¶ULL̇~HÇ8…n ŘTkPM333鯔”¯·:tóæÍžÀ„nDZ’z@rÁú)¤ÌzÁ5º¯²ÙKµÕ*6³* [¥ ¸„˜©Öþ~+û_ýɪú¶;j¢uòk­mÅl}Zy}; ØæêÒ4þ8€ŽJ¶¿TÐúŽÞCqFúV®”{»ØÂý)ò­•ÍôºËuðž­«£««¥2EžRÙÜE¯'\@c¦ÅM™4wõº"·³L3ò ]ʳ¥4Sx„.g2·ÂÀŽ.èm¯eËøÓŠm3u²S…ÂW·w´×–³mÙ†Ž±±æ J¼¼Áæ`ÕLe¦?kÀÑÛÕÌÊ!TÇ«àõj~¨@zóä·¸M«¶MlÕÿ¦g—ȸ Óº%}¿ñÙ%Kr}€œwú@êp`€E\ICú Êü¤ù”&— o¾ù¦hø½×¯„ó“DN{{;Ÿü竸5 Ÿ8åÇ¿Søüítr¡ð÷¿ÿý¶mÛøÑk/¼ð–-[øjmÒÿýë_/]ºtäÈ’¦^wu ܸq#H+Q!ûÛß>ñÄ>üðÃï¾û®(5¥-É7¥{¥@ò/HÊ^Ê“Ræ+Ä8Übð›òdÛ‡WhµZžãÎ;Åùê@½Àå´ß4Å”©Í½¼q-@ »&U~¯¶zýõ×/_¾ÌWà{µùrÞø~s§ÊNh\¸paR­AP¦4HèÞ7Þxƒ~ßÓÐ:þ´¯¶xëøåŒ|~Ùo¦¾³Ë]Oh(Ít_KËä{2+}âgJcØ\.Ü’–ß59*5hÐñé}]ŽXz ‘ UaTnêÎð2úçÁ@êp`€_H ‘Èlhh ÁÏE x~õq#€´ß{I¸@I½éCà¹Vœf.”ÅÒ¥K7nÜXZZºjÕªG}”„"—ë|w×®][¶lñº‘¤½+~S¦ðšFóÎ;ïˆjSÚ’Ò6¿)sÑèe„˜òd{A„²^9Nª Ò4ûûûE/€»Š=µþå)¿øâ‹gΜ᫂”<”n ŘlkÐ`>wîÜ“O>).[à/üñ“'O)pèFÑVE KdiŽÑ}@}ÙRqõgU\Õk7¹.=»Ô}X ÅÔŠ)¤æï¼ï½©=Íaëíêõ³ž-{qÌvØZš^ß%a Î$Òñóœ@ªg¯mr¥ ð<Á žàù¸Ê“™K¹@°lÓøP­æù%FÛØ²”=㎨ӮŒ0±@¢ˆK#iH²„¤þƒxÂ/’L%ï÷^¿ÎoL’îº~ý:éÏuëÖýîw¿{õÕWIQ_½z•~Ôò9ùiæBu9uêÔêÕ«é·Ô‡~ØÔÔÄõ?—+U~"Ÿ+ïí ²)?×<…âââõë×·´´\¹rÅl6ó°µµ•O{ÝÛÑѤÌ$žùó(ܳgOjjjè)O¡ÄÄêO<ñ«_ýŠÔiö—Êé Ó´²å»ýGŽÑét\¥OX’Iõ/õìþýûÅUÁSæËxãûC R <˜G}”Ú ­ÁímÛ¶%''ÿú׿NLLüä“OèsÄÏtפŒ!¶`ÚÚï;CJ½04äÙÏTj¿ß«w 'NœHHHô.”ÕŒ0­f uÞÙÃŒ^#À¾ò\|îº×ƒÐøE.›} $á‚À…4Øž¸¨[”mÓÏ…/} ï•r—¯»:;;I1ŠF@p¸`{ê©§žðôžß¶€@]À—”“J¬©©™TÊSë±­xs¹œàUðjéA}zùùXå@()Oحܶ°†g *º ü“5塎ßý3‚ßUÖhá¹b W0@¸E\y…\ñé\ßPT¾¡_ (1•’8g<þds =e1¼!píÚµPÊO!eÁ©WÈç{}ã[,–0¥<å^à‹ Bo+.§ClÏI…“*?®!¦Ì—ðÆ2Z|þÖtZClaqÕIðø0 `ÑŒí F˜y#€äî †$Üm— AÒN4&Œï¥ñ¤¾†ßø¢0ã)ÏZ/ðÆ™Ù4Ã]þööö/y˜ZF”š À3l("±1ƒ¡_ w;ær] ­­-å§kÑp¤Ù4yj¾MAtww“ ëPY3¨©¨=©U©mÑ3*†+`.2::êt:é÷ÄñãÇËËË÷NJÒ¡Ô(MJù¶ÎE¤´´´¤¤„ôØÞ0Ž”g¹}f¼ ³Sþ0uë̦¨)8‡£¥¥¥¶¶¶ÌÔ’Ôž˜\q0P1\Às× œ (¿¢åvÌE„?ïBñ1ò¶™€§ÃSžÙÏfû„£ ³SþïÖpth ¦F˜®022BzcxzP ”N Ñr{å"Åápø^™>AÒ¿Ú‡~«0kåŸñnñ ÞÌ]#`€;§„™’y\é;£[Ñ¡p"œ˜7D80oˆÀ¼!€yCDæ =˜7D`Þ1€yŒ`#˜GÀæ0€yŒ`#˜GÀæ0€yŒ`#˜GÀæ0€yŒ`#˜GÀæ0€yŒ`#˜GÀæ0€yŒ`#˜GÀæ0¸-°[Ì ;Z#€i)l³A••¥âÐ 1P<­g<ëlÒ˜!§1¡Ë0À׃•ORû`±†wÞÚnÒÉâãe eò±kb#<ˆTùMÕ¤‰óŒk´Ï^-ÄÜãT00À×ݤ‰Hœ)ŒV€]”äYÆÈF/÷ø¿‰Z¼ãM³Ž“«…hDf1ö0À×b¨±ÆY1T3ã7ØÍf³Q# n¸vé53n„V ‹^KèÍV =Œðõ8fF¥Ri”ñ‘¢6V Ûç5:Ѱ› zŽÁd±[Lš,…\FÈ5³o’VÒÙY ö¶\®Tª´z½F!‹Sz*åP%4e§×j”IKï °EÁ¯PiT2‰°uÍ™KâL¤ð=ôsl¼L6¾lAªÉgØð<7!V&—IJïŠ?‰Zø3â|‹gׯMQgž\_`05#€0²$ÒXa´Ú-FMd„÷ªx‰LÔº/ZZ®ßu®5îfe` )ÓIs·š´l‘¼Fgro0©‚¼?3+ƬZ¥B¡ÌÒÍîŠ㼕ö$j!¤`6zq¹„Oñ¬FI GÊ f«Ýn74‘>Dˆ}€ÀÔɦú{NÜÏöx³Î{±zlœ äõfïmýVU¬¸e ØÑy£>K!‹c+î#cãâEõN#€év½&KÉr—dë?ÔZ¸Û'`ñ$Ï5Œ—fa—*— Z_`0u#Àrö+>ƒ­oWyHåP´«Ux|ØŒ«Qò#'§ÀÏ®•:>`\ö»÷V„Ø„ÝC RÄÇù[7©´ú“КÚUzR`œBc0F]–,$# nÊF€ä¤ÀÈ8žek4èd‘šI>Å3f¹Šõ4$‡ÀÀ³gøl’?o\|ºTk¤F˜ü·Û­f£>kü¬½X£¿ƒÅcÿÜÏÌâ鯖—hcq©ü4WÄ:]oü­ˆ,ÉJ÷€¸@§ªEˆÅ“l ˆPèÍâ:ùø)³}}€€ElÑ ûà=Ÿƒ'\ˆŒW¹vo5z®÷Ó›ÍÏKJA»JÏÛWhøwv£F\õ®°H²6(Æ3‹‹”ž©ÏDµI²1@–¥ÑëuYr­±r-W½vŸßZЕØñc ªÈˆÈ@ñäZ“—+c¹j²<7(ÄJ'ÿ'¬¥¨WÆùfë¾§3ûy˜B¬L©ÑüÿìÝï‹ëØï{ý-óXò°Ðƒù zâ‹þ€[`.~ ‡gƒá*TC 5œˆ[çä*í¦ÂñÉŒð¹3WEÚž>LäMŸ ‡ÎÍí4h2XPÏdNö]ké‡å߮ڵ÷®Žß/úÌ©m[¿–dÇßÖZsë‡N>€]AÀ¡Ÿ£«nào¿&ˆcg×/دÿðÞ‘_¹3oß+ËJûðÚZ{ØÜ®ß3‡½ÝôÀ”úuåá†ö‘­š­9z;~;pãê® ¢ýs›œr‚…ÓÏ‚`WÅÖþ½î0[/5­(Mõ»Õ†§åþˆ÷ÕÎ^8ÛLðmàá8#øÖ(²Ø68+žÕª¼å´´¹í"¯žÉÄûÞ«Bdd»€ƒõj†1JŠg´*‘ø~\fÛŽãÎòúÁ"ólù˜;‰'ž#—µÝ Ç7´kUoÞdO>ê¸#ÏÑ·ÇUÞYè9åíz¹ iöõSE–$qØ—úq"ÍfÉj}"‘»TÝá·½DlæOˆdâ”ýdkõm³?‘«L‚¾<Ùî${ó&É&Rã¥BÈ} û¦a8õþ6‡X„rg;»}ìoŠd2²ê# âtu²dÓFŽ©žqF±à€I'nÕ9Þv}ßÓ¦U×—EMÂГ«"UL\³^bä—µº9Ê%»V%kóI¹.{ÆQ`¶ºÊgªJ¶ã4ËÒ™§ªû²†ÏúƦ°^¡ˆG²:ã$McO–ÑvXŽ¥iŽôÁIûdyªµt’0Å@ú[µ· Ò·ïP÷_Ðäiº*øu§ÃQ!„×+‘†Öf*±óØË×èöôf«Ù¤_÷€hw©X[ApjPÎÈ×&³Y<Òÿ(ûùy–$i:SSÞ;aœ¦Iš‰7«_ã3ƒ(žÅ¡^Â: õkºaF­€çàü#@ðÑðm8ûO> ¾äƒ < ‚ÎAg„ €3BÀ!àŒpF8#œ‚ÎAg„ €3BÀ!àŒpF8#œ‚ÎAg„ €3BÀ!àŒpF8#œ‚ÎAg„ €3BÀ!àŒàù)D¦ˆçºw¹Þ»â=oVo5+¸<àOLâ[†¦Ï°ì-³Ü;û}î]‘øÕVÃôX`„¾Tä_‘8Ãk¨È£0ðϹÞ‚Hã@_B¾ïGÉûk¼l6ñ«í‰ ò Às«³Ê{öµ¢Øñèc¿É¡]Ö¼F𠃀"­÷ÎNÞãÞ¥u£ØÁ‘ ª¥f½ÃýܸVòâØ‹ÄÛUzéÄwÇ w\‘艹׵õ§ï…ù[oué¶ó“÷þÎRü„ € Ï«à˜™ëµ¦9JT¿Qšá£¾Ë¯‚€çX ¬Êëƒæ±Â¬yeíÝõ\Ø:ãíâ»,DìíQ’ä; ÎÁ³P¤á{içui>ѧh_AGƒ§§“·/” % À³’M6+:'RõÃf<<î»|!ÒINÞg§ä‡I,÷.žeïw³y<‘âSfNY–g‰÷·0¬Ý:ÞÐ[ÁÄ&/~xÐê—±ïèÄ* 8» à­«h1é¿ÿ @½ó#×" À3-9’‰ßÔ€¦3Jôvy9«ÊÐiÝì-²$ö=·ßï»®7 Â8žx}Ûñ¢b³x›E±4SâYºÕÅ9Ogqi–Š"C_­´ß÷ÃÙŽºA½ (_ ·:SÕq½xòˆY÷Šjã³r÷’­½+Z{—y–ÇÜwÃ]©ÈùÝ&îhLâ8ôú–=Ú¨€äzâV£$i¾¿ŒÊäöåkg‰l:ûÊà"‰'#Ï-ùá$}lWò,‰ô@|¯9í¶;Rc¼ƒpÕ:E6ñûMyöä˜kŠÖa*Q$O¯^ÜÒ6~BÐê5àÄIŽ<}*¼I’í9¹‘<]ÞÈ—-ãÉëi½[»7Ë ‘Êsåêëy>fþÆ"¯¯”8Í…\w}¥ø³«“¯Ÿ¨-Ž|ùByÊ¢]§ìA€|CN¿º<2Û\ k®ž0)¯+yRbu]íÜ»4’ïD¹"$ÿoÍv_P'E³]}¢}þgiÎ'/A>°¦êhWB­ú¡)·Äþ[Âëýº‹ÔÚsWyß 6:£·o–‹$4Þˆž<°€[v¾£öö ÖönýX’ÀÙ÷ÊõÕn¸ØÙÏ¢ˆGûV¸V*ËfÙÙ†Ž¿ÍØIs1ì.A³æ²hâÈmΓ[ÝIäƒ"Ýä¦òú–e¶_lZ%Ó4GíÎU°ã*°ƒd=~šì¾BW¡Lqðb²Úwek‡ `muéÄÛ³wMŽ&Âþz›´ÅmœYº»/¸õŽHÃ}—“Äí$EDÞîÆEébm»êBÚ|CYÌ@€k÷íÇæ{|Ó£¸™î^•ž£öä `³ðÛè–|8hïIÇ<´Cúú°ó÷]k[$ÍXŽ„AßÞ·Ú­ ÀÞžy¡ˆú‡¶Û¬oãd±x ªxû‹a«&_Ûùسւ€ÍSÛ϶‚'ÌŽ4²3)¶7z0*²ðàYs³gaÏ„OÖª•²É¡Skôuݺœv¾¨uNŠõTδÌÝͲ?hæ(&Îá½ËpA€\4õß×lÀ“iP¿Ît›û«Édd®ª¬ÖJ³4IV7Ë·Ç'YÜ*d¬I’"雯_«OÜ0)Š"O'­b©§™@ï]äìŸÏ,›µJËK„ú-?sëõ­j֜ԊdRv˜6úK™ÜjÜ4еI°V,dz¸5p£U>­&c³½æõŠ$t›‰ÅS^ ;‚ãh2 ½öØ}D…<µÁª\,»™ˆÙhõ¢X¯:½ýIöfg ÏE‘FÖæ¹í–’—Š|U!Ò°o®uCÐg!h]yÞD^TùêeÖCçÅ,f¾ÝÚ»I^ÈÑßÌŒÄÌj7S’©½Ëf­½+»`d£ýb¶Êì|5q£Õoy6]Lo¶#°Üh6‹Co-¦)äÛºÚMw–©ÆËfíÎŽîàâQ¬IºjÃô#ùV' À·$È6ïV›–­zDñÞ_ ϶V²s»U…¶ãõEsÃÕtãfÉÕôõvX<õ7 àlÖ6»^ŸmvX°,ÛÕ’ío”}5gk6>«©ä[EZ´î›^…%Y•¯NPðȾק‡' Ìúë{’EîFÚÄÇıµÑzôÊÖ~¶:¡8aûb«{öV5£¹ÌšëgÕ›àáWT«'‚“n^5íæ’ ˜4£¬õ  Õ÷D¾ìAG±gn3æ𬂀V©ÌÍÑÚÕh³_օȓ٤¿Õïz=°ÖVPÞ¶vÍÐ/çhÿˆÀ» ìíâsk‡ëJÉ õ­N5b:‰ýV£$ÅþºñÐЀսÓÖëfhÀª¼;YkXõK‡#×qCñ.Ú¤½éZ~æ™Çß¡u,ÍŒò'*Ýfú?1xhh€azÙjVʼn¹5áÖeöD=¬°Øsñ´;Õ›Þjòÿ´Õ—ßYý<ÇêJk†9Ô?QYuwHÃí ;êmÇ¡ë8áêúiÆlò¡ö¼ëC oõSí߃Pƒ2t«uÚ£$iÏëá2>€ ^Úš<ÍtFá$\›ý++¶* ;œ¥j>±" ›¹âV!B6²ÍÒÚ­À’5*'Û¸_8ŠÓÖkeù—ƒËOœ•ýÔ²-W“ní]õˆ]–7"Yß;;β­Î6 ÿD“> Q7“6J!rE_“Új~ê‹ß÷ÕDÇÎP5Ÿö?2¯Ï„l‘춉>R}¾äÛ»“¥^Ÿ¾Š6}°YVk;¼w8 .œ2ß±,Ûé»ÞÈ÷Ýö}Í>÷Ÿã ‹C_ž©‘ç´;H¤Ô‹ApRY™î½1Îø9ž¯Ý³0˜íß±@¨,û;æ%ðbR€ç)ß=o‚¦´ @œœ‘Õžb9ÞéÉʳ $ÀÛ àŒpF8#œ‚ÎAg„ €3BÀ!àŒpF8#œ‚ÎAg„ €3BÀ!àŒà9)D–JYñØåßnñw¥<*Q<ÓVÏâ‘e²âOøÂÊF¶5Š3ÞaAYo§q$Åqùÿ¥Å“­704?9ºJ1›.RK-m%®¦IDg˜'Ô‡‘†ªÙ>ÈÞ%¡½‡¢Hmy„£„·.@€ÇÉ}Û2Ë’Ý4M{”=iÍ&«Òàx¶°ûe:J°ÓYTˆ ¶v+‘{>Û{îEž¦ù‡Ø¹B¶–¼Ó%0o]€ oQÃe¡aX» ö"™Œ¬*&°ƒ8]=ŽšüÀ Û·gEx¶eY¶NÔíóÃA€H“Y¬ n'ˆ“$™ÍfM[¤r¯Œ¾ç–]üÕÖåRQ¿Ú-£ïÇâ„ClÄrܾmö'™\MàX¶ãØ–­þ•Ƕi9ò7* !÷%ì«ýR»%÷+I›Ý²å1÷]G¯Îñã¢U„OFýºµÜ8åë=Ù¶ã<½„9ŠRÝæ‘Üœ]¦0¦íôašý¤:zNÕÀ†&¢u²’Q_5°DQàZ¦Yõ“3Ç4农~˜o4r2qÖþX]¤‘_7°åGeË‘+›J6—çbæ÷å¶,Óšd²µÔYtõY¬[+?|²²‰jÇyzÏLÇ_]&òrôœjÛ¶mšýæ©$pLuÆœ`–oÄ;Z¾ÚaÛʦtF§\*AÎ!Hw±gêZ7JSYø«ÙVPÖüùÈ”eU˜¤izÆê¹(ËǾu- Ѝ*ßVœ0mê8öU%Wí¡H|]2Iš%‘¯w1<\Ù&:¥sGž­kkuïºH&žÞ„«Ö\d#].ÊB½È&ÆÖ~UÇQ¤å&ñÄW{_'¹^—éG³4‰uk*àÅÄ5«z>Ž.èñ" õ®¸AXF£0tT §eœb©„%V-¯„zëy¬ƒg$‹Û*%ðâ²ñ‹<'ú4­§%».©ÝI—[4¬cÍ¥Ïb?ˆÓ,|§9)i”}\¼IõZm7”Ew6Ù:‹vµ‰}'«H'U£ŒÂ8R‘éWqRÊ´å¶³t¦÷wu8y‡a`7­T?¼§åߤ·ÜOm¤ÿœÇtxA€îßo ’OT f—/+DG“0”¥§×Ã…®ú&õŠÊôøÐ=‚Àß14@Õ=ܲC¾®×C»,Ý+z¯ÌC·zõ=|;\ugPug]vÆ®ºI_Þ»Wkvãf95ÞÞÜ ÖæÕ»%WU®¹<öÖ ùBÍeÉéÉW[µ‰z<¨J_3T[ôMÓ¯öSȹl`•bTÍžª•Žêc¾ÚÂzoüÍÎ…š4À^Uþ‰ZCP¼9Ò\òÄ× œëê¿Þh«æ¶Õ¤~»'H¡[kchÀ“µÖÚº©«ÔÇØŸ¥™r5OÃÆ¹ÝØÐ¡–“éäÍZAÊûÀf +1Yh•³ýµËøfA}¯Þê»n_•„ÕËÊ.[/)O ìÝs´öjõš²¶Üt`Ð~y{½cB±úG«;Æ3±–;lU§±E½·«ê7 6oÅ—å}Qˆ½u å$ª&o6¤Z^i¨ï÷›ŽëºŽmÊÅõš‹ÈY›'/i{2¬¿‚lüîÓáìhàUÿü")»Q´NôÞ2ûÀÉZ{ýZS‹d­ƒå­_›:ÐòÛ'‹ @SáÛkA€,/ÅÌÔòª¾R=ÀUÅ¥ þÕ­ò¼_×ZYÔ_+ÉvTà»+Ok×ËÖ÷JÕÏUÕS^r/Ê’¶(—¶º7A}[X?°>¡žê`تÜnu¨ªÓ½è›=©kK]f‹ÙHî­Ö*&²žÖ­´>Ãjq˜A³¡&‚);4]åßäQ³xª ë~“)¸›ä7OeÕ\íãÒôt8jÖ„ºß´¸PUºéômÝÉ_lÔçáV°÷d­½~UºËÃ…áLM<ç"K#{3ÈØÜЖ/[;H‹Ý{X¤~ßé»AÆpà¬äY: U)Î’T û†¥î3—·sÍ0N…I¬…÷£¢ºóï¨QÜI\΀çÊÒMev`˜ýX®iZÕÿ£Ã²3Gõ3³<›M|«*üŠ$T7†ÃDU­" ›U•w˽p– ‘«!ôj/£C3åëÊÐ0ü8Éó¬œÔÀhwk/Þo/ÈÔbÕ`uß­ê·÷¤ºwí„yQ÷¨7Ý8•û•Åzh½X!ÄÑ’­H!ÿ”ÍÞOT_¹¨£ù‡¬®‹²~öÕÀe3Zá,U3å‹YÕªýzŠ€:õ½nuu*y’¤œZ¿Àïèæ­×æNôy×["MÊYú™Šb}¯ÞÖG5ÒûÑTѺ‘m_·ÖÄ­Ç#ì=Y"Ñ TöäúUý$oú•X“$+ 5Eu2)C¹ýD¢ž•0LÕñfe ²§å«ÖîoŸ¬òüÖT0qpV2wGßízƾ"«&²«¦¥›T#ãó¸é=n»#WÝL¯nÛÊÒ«YÀqûºÀ¶Ž'ñhµi7P%oYÝé!/o,—ÓÔ©’°˜­Îã¦ÄG{ˆõÙI Ôê¼x«"ÎFÖÚVÞ´÷D”ÓÚé],w+Ÿµ6bx5¬ÄÉZ‹ü7㦭=§ló,rËqy»”+÷Gºën" }Ïu=5õ ÝôØqë§Š¤Ì>ªIõ½ÙÑ;àò¼÷Íö"jþÕ¨J> õ­È…b{ÕZ«©ûwž¬´n:[žŠ,¬›bRT]ýÛKøåþæñŽCLªywµ|«µõFìz#YµÃÕ3¢K€õ²°´óá 4Y›È ååË—dx'^½z%ßc|ÖxVd"«J6‚<½—/_ÒÀs#ëY­P²àé%IÂG €gHV+”l @‚ A@°å_~óïÿ߯ÿ]l>,–‹ÒR<Ù\dz™RŸ["×í”?×ý[^u/®¦Kþx¾dmY¼— àç?üãþìúïÏÿøíÚv16*ùS•íbqQ®ñzþ.>>æãë»å;ŽòùõõTlÖ>ª›goˆEWîÞÕœÿAAD$ñO¢HþÅ‘þ#NÞªV/¾Të™Lâ$ko%þÂ4^Æ ?›Kd7™¨HEñDAÀ~ògoþÛÿã׿ø_?ú³7ÿýÿ¶UCÎ/Œ‹ùS¸bÜ1.nï¢Þ•k5oÔüÅVƒ,nd;Ÿm?‡LõWü ð º=u­–5,«tõ‡äoµ¾Oäzlg4 Û}>ñƒ0ôåSÁVϾ­·î'OüûÿΛ}çý¨~ŸýêßÄï¾Ù(|·ƒ€l~{yQuÜLWâóù°×­žèç­žò‹éM¯{qqÑ»¾½§bqw]mĸ¸¾+_/îÝ‹®\Sošå÷×—Ýnï¢sq»"_Ì遼ŽaônæÒýý|‘¯êóùU¯ÜÈÅ`xÙé d…Ÿßß\ÈmôºÝÁ|ÍtØÓ[ìÞ.óå|>_ÊW_O«duË,ÆòÀ;ÃAOüåtˆùíUÝZÝ›iuàËÛ¡ÚÊàj¨w Ó»ÖK”([J‰Ñ½”ëSÏ^ŽçÕªÆWúµÄp<_ lÆWªåNOÕ:.ºWåH€ùM¯£§wsŸ=v€ € ;¤ÁÐô¿hô_xÖж?òF¾¥3‚QôÅiA@hÃtÏFì]A@ù”c¼°‚d«»BäûŸÄé¯:4à÷¿ù¿ýOõèùßwþ׿ ²é°,\ï‹éøJ’7eÉŸOå?{ãé\>3”5f·ºC>×ýÅåÕøfXV±Ýñ‘  \äRÖÍËÅݵª®{z‘Åô¦,^§¢X\ëU Æ‹\Ö՗Ɔî±ûóùýE¹÷·Ó»q¹c]y¤"›uš1¸U[\Nõ1v¯b¹µ c\WÏ‹q¯|Ùtªw¥Sm}:T…{ïún±P¥ºÞÞ\·ëmYÑw¯ÆÓ»›N=\B¶©~Ñ`|3PO÷®ÆêðËS]uÔª}õ«q¢ÜJw0¼TAÌp|/ªÔf:ßt7—=Ç`_°~ßUõ¿axa}ùÇð”1U°ó•Ebí ŠÄÞ|éê Â0?)üúWuð?þíOÿãŸ7žÞ „ªY/ïZ÷»Õðø›ªËùôv<ßê›àeWy5¸À¸¼]´KÐîáå˜v¹•J¦«ÿ«¼Ž"ÔÍ÷®ê{Ð]›k@Œ/04@ßÃï5‡¦¤ž !›ªíÝçE=WBÓíAÿsÇX ½¶a^½F®ª«š¤<ö»Õ,}sU’wË›ÿj‰Á´^ü¢ÉÆãZG]Õ°j¡N½E‘/§wºuõ^5»žyaXïb~¥6±¾{-sèØ‚‚ Þ¼ÉdIÿ"Îÿp¤†‡A@X:°Ãÿö·ßyó£ÿ½ Þü·ÿíŸýêߺ²]»·¬‹v]‘æú^¶Ñé]—ÝN”éÝ®æð;¡\‹ž±ír±*\˛ؗëóà«5Ÿ<û€¸»46Fõ‹ÖoLeô ÖÙ”ëM°cŽ€V%ß„å±ß´^-–Íâk{ÛZ\E-zœ€*ïoª?ʵ•Ó7^¨öÕC0Ê5‹å­lõûÖ9êlF-s䨂‚ tIïU%½.Ôß{ ž"øºü•š)ð'ñ¿þúÏßüèÏׇè*´UÉæª£üð~õ¼ªBk]§^”h™¬5ue+–wFëq¹@ïèнªÞí²U ¶ U1¿ÔqCWÈ7ÊÝñÉ=T7ƒaÖÞê¼u ºS€îv`LÛÛhîö¯[Ž»« @Uûú5ù}GµVÞj­ËºCÁÚÞ¶uÕãÅê¨^ý0AvÙêÐmõ¹XÞ ¶öp³eŽ;@@€#A@Ö.é¿…z˜¾~« @¯$ØùÜî àiôQ§þ%QAÀÏ~ñïŸý'5G@9:@¨©ñÔÀöެPïåóÅR´ºW¹1O³<_.îô­ûÁRÔÕûõt¹¬F°áýB>“_wôo멹î‡åYÀª;E9P^n7ÏóÅüNÚ¿\"[Lõ@ýîRzô~ï¦îm nUÆp½{p;¸82M€¾‘®öx¾Ì–s=©Áz÷ørà½1œn/u=]dËÅíõ ž& ×S\êÉÅ\O(8žgõtÆSu ó©žÕ X‘Ïõå0ÿÕâ²Õzv@‘«njf]çç¹®Þ{SyxÕÞʳp_þ@9¥‚qÑ«¦ÿk‚Ù`ê,ÞëiÇ yú\;v€ € Òë,ýiš¨ú¡ü#M³ª4?2dñŸ|©'íSÜpV<2[IÒ™ZI?üÒô Qüá”9ú#@ùÝüõwªÉÿú§(+ þ5Ugrq?´æä»ª@Ü_÷V^:MEšÏõt.]ýÄÍá;Ðb9¾ì4ét‡²”®æÐî2ùŠjsM§w±œ6/èôj‘ƒòùø¢µ YV¯=«3‡éæ:Äôjµ‘òGÊ!ºÈŸÊ–«ŸÖ·ÜånVéoóõæíŽ—ºA™|ò_ë׎çºz7z‹|1(gd̦«ö\•íØô­PéË`0¼OUÜP Ȧƒ­ÕS‡  @Ukÿ²µÇ?ÊÞ¼­êÙ0+lm%Øè\°;x=Q“¾0Ýè1A€òo¿þõ¿ÿzã·ê•XâAâË”K=ÁF„ꉿ6áI‡ù”Gò¨-‹ùõÎé ßín8uhÀÇ&8»çx#ß?›#kòùõÕUõ;|Ýëå·¤Lžß\^t{—娀ÖÏ:x>AÀ'†,éF“S/ú|:¶ºóoù~Ÿ<· @O›·ÛÍ·NdÓúáƒÁp8¼¼¼ú¶Ì¡·˜Þ ”«ñ”Áþ  À3M¾Œ'R'Ù©Kd'ˆ&?IEñmÔl„{ä²Að–€ € @@‚  À·Úb±øýïÏG €gEÖ)²Z¡d#ÀÓ{õêÕ×_ͧ €g嫯¾’Õ %AžÞ7ß|³X,¾þúkúxdmòÕW_É:EV+”lxWYÀ«W¯äÛ,€MÖ&²B! GpF8#œ‚ÎAg„ €3BÀ!àŒpF8#œ‚ÎAg„ €3BÀ!àŒpF8#xZE–JYñw"¶M'~Û½(åÃÎ[ú0Äs=†,Yö詚¸(òòœåEñí¼êð>Zþi¯ºwxhúÝ›‰ç¼£Õ[îý¿ãAÞÿ7ï$ªÄqýW"¿V©eHVòA¿i(wbôv;Q®D3“oÉW\‘„A”mG`ªcðŸë1¤¡ºdždï²È3føXLFAZ¼Ã«îÑ[ÂkÈ÷ãâ¹­êï÷ƒ[«nßN%Qèöû®çO¢IžÐ»v8 Ô~š~òŒÿÇ üÌÞ; ð4Å›þzjÙ–®1ÕÍÁ" ÃN?ø—Ó§º‹V$Ö‡Î5RTË;ÁŸíÝOuC1Š+äÑ›þL­ª(ÞÍíIUóì¯Å‹w|ïöðÖŸê#ß¿æ“lä Wõˆ÷û‘­?ÙU·såÙH2º~à{ŽqZ6ºg‡Ug…éóþàQo=+xæ; ðÖ_û&Nõµ/ ,Óoþ(ƒuw®ï¹e×?^};iÔ·ªûµ}?Õwæ‰mY¶ãŽÊo̦¥âèd³Ð)CSÅýÕe8ru¶ã¸³ú{~yòUr+r Ó–»æèí„B?%_íú“Ià•»±¹uu¿«ý%^­_®Ý¶ìIöæMÛ¦åÈGܨØ_x–YõC3Ç4åvÂDÔOμúHä.šÎ¤h6ùukY~tìKv!’dö媜8‘f³¤®)ŠÔ–kﻎ^³v×QD~¿ÞHÿpËYdëv4õÎz#}ŠÍ~}("¬Ä0V¨LF}Ùº–DQàZ¦9Š3½„j u®úa¾¾-‘Lʽ5,ÇíÛfr¸Œ’¯äU'/¿:ûÛÙò·¾çªKU1«Èk8 ú­Ñ4™Wæ8£‘k×9WCìþtr6NA‘…:Ê“I¹‚‰þìˆõg‡=ŠÄ¡Ö'K½,”ï^³Uoï;ïÍgšZ$RƒŽvÚßûŽ+ß¼F?JTPQîHÙ*å”%ÏxàÕR~$úCÅ•—JšDNûƒà[ŸäYÙ·  ‘eyÑõ­OÝ)]ëÕß"eñ\ITQf–/ËÔsn^}‹›ì`ÿæÕjûá,Ë…U‚ü^ŸlÜuRIA»$ËÂj?e£¿Iò›¯¾SV¨ïææ¨¾7XLúꋳØè¯à®ZD4_ÓÝøXƒ­­DîƒY}›×øeM£$Oã`’6I‡üú]·V®+öÑÑ[k©^u±+7ñêS"·X~e¯únDõ9‰j ovh™\$¨N™ª-úfÙ°ªÈtQ¦ª,U*–ͯG‘4{.|c«Ÿs¶qÆ‹²ÐlHÔ‚J Õ?y«çü¾–ßwÕܺ½ÿëÆUWžÜ¨uã>hêÕ_óû¶^¾ZCèw–}pm{®ºÖÎìèÇ.¯8Rgw¢v}­¸:ƒ†;I·ö7|Èt!j¯œH6I&×ßW—kj6Ÿ$òÜ©«ÓÝs\›ï÷ã[϶Û<Óoå¼¹­*Ù šO*ˆ˜Gb©âÐŽ\v”kKUŒæ‰#;¬/H¯ú„Qï¦rë‡ÎûÚ‡’þL8œ£í½æuµïf­‹­:õåÖ›3.f–N–ôæÔG×DþÏCõ¡¢®yoF¯ð§¥ 6¾7÷¢ë/èÕ}­Í»^úÎpû«êiEQ‘„k·Ð¼"dë»x½ŸÍ÷{U4–A€z¤Ušf* h}ßȯóå·ÛµÔãHmЬdUc¼Ñ=®ÍÖØ^T¦)ÎŽÖê­wé_k¢)†[³!¶o4ꄯ‹"U!4Zu «^î®ë:ª‹xyç°P÷G«’I+8x³ûŒ«»£özXpÚ€UInÕÉ{[~ÏUwpëÅŽ‚sïU§‹¥µ‚¹µøÃ¯ùÝ[×gdíÁ";¾¶ÝWÝ)’ò‚tú®ÛW=/ì ݾ*v§ß V5¤=ÉÊËRָɨ!5oØSkïÃ[ßñìÖÛ¤ÚÜT߉úޮŠÌj·Õ|nåíåbÇâûä¡fE!r)‹T·ØÞ§Ív[û¤­²¿)ËnÒ­»aª¿në&˜¾¥¼½?êÆža«‚÷xw€ªÆ˜Õ#ZwÅ‹YÌÊ#yª.ÁúõŽH\·Ö›“f¿KCk×íÊvk¬‚òÛ|™Å¬ÎÉ‘ãä÷ýfCí† ÌVäQâ®–ß{Õܺ.xôS³‰oÕÅÏΫ®A 7Œeûfi9^ÚÕÐïù½[//SnV^*I5Ò>:^øí¸êÊ Y§qšgéD øWv™ù±:½zÃrC}ŒEVAW¾Eš3x`UPG'jgò²ÝË×ëš™>¹z#iëNôž–?°õ}W]ù6éo¿MÞˆrÒNËifÀ ] Ê1úIùNÔ'¾Íäå¨z/Î׳‰]-¿¾'úJqôe³ÿ¼ Ý}£n_iû?7v_óe¢æbUWpRH¤gßг¼¨éEd[zÕ;m¹^¿ê+íÕýãt{0ÃZ úÆjìîQ«± v5]{Ðt”h÷¡m¦ô/²°¿ê¾­¦)?eöí"Yk-ÜÞD,Ê¡éú0ËS’ÍZ)gßÿëÍ™rÂDϬæÈb0rËcÉËR¤\¹?*ç¯ ?‘†¾çº^ÇÝôȶÏUýT‘„^ûØgÇînŸ¬¦ßòΖ?xÕÚzV'«n®W]y7´,8›ù(±Þ’§_óû·®.×jõóŸ»Pö_uúÙxÔ4fýKEæÛ««¤š4Ï‹Íw¢a­õÚµªÃoU_öóêÆ²“í>¹­¾ {[~ßÖ÷]u«6‘tó6){åèY'}×uGaGo°ëZ?iµ±éL’µ/ÖŸ[ÁÏŽNƒê‘~,t/†êÝ{à¼7Íeë#9eÈÏk>Ÿµ/{5‹Hš›}·|¿Wó_ÌÚOô´Fž”ïF7ÊøßPpNª‰éž`5O´²²탿•ê›~§O„¶:öí4Ëãð¡Ë<Í)9iË…¯F¤ïóRyL‹Ùú£Ú·(žð-ô¶ÍuðªÛ×b<Ї-Uˆz,ŒŇ9õG£ 3(N<!v½«Õä~"žòÝûto“]«:òÄÃß?ü!ÀUNj­~ÜÎúI°v%0 ä‹Ë›nþi‹œ}+ÏÓrúUÏê Ãñ-“Že;}G_ÁýÉ#ßõ"™ŒF~y÷Ü^ë…@¼Ï/øqÐw]Ïuû}Ç O¹S]ÌWÖ´r!Ïí&)mxB›¥lb×ùaB €oá#y{#5OÂã?mf£~wA}v¸£ˆŸÔà} àŒpF8#œ‚ÎAg„ €3BÀ!àŒpF8#œ‚ÎAg„ €3B€“|óÍ7¯^½zùòeš¬Md…"ëŠ5‚¼«à‹/¾øúë¯_¿~]À‡&kY¡¼|ù’,€ ïÄ«W¯ä{ŒÏÏŠ¬SdµBÉF€§÷òåKúxnd"«J6‚<½$Iøˆð Éj…’ @‚ A‚‚€ AA€ € ÏJ!~ç¿.Š?ñ @äËÅb±Ì|Až!‘Ä?‰"ù_Gú8y«R½øR­g2‰“¬õ`ê;/ £ú/˜ekKd7™¨HEñTA@vchÝ«éZE.–7½NùÌtù¶µz>ßÜ-7\Ü\ȵw®ç|ð x†·éS×zaYCS—èê;Èßj}ŸÈõØÎh®.ú"ù/òÁ0ù²(~öå†þ¢ä³°oë­ûÉùµa e¡ŸÏ»†qÛ*øÅüJ>³b>îÝ»·|c/ÆøيÄMǸ/øà@ð|¥ÁÐô¿hô_xÖж?òF¾¥3‚QôÅiA@(+ítóÑ<¯ÛIÁV¯ƒÔ1^XA²Õ]!òýOâô× ĵa\ŽçÙbÚ5.¦y;PÏÌ—Ëéu·3\ë,Ïo{º¯ÀEopÙí\ÞÊgç7—Ý^¯{1¸]EvÕ•ÿê^\ y>Ÿß/;†Ñ›Î¥ûûù¢^›w £s9Ыëô®ííß^•1:Ý›iˆ»\owpuUvVè]Ms>5‚‚¼û  }™æ·ìÉï…q¨ÛøÃSÆ TAÀÞWŠPÝüÿ/bs±ÄÞ|é–£ ÌOŠ Èw—UÁm¨âº3®‹ñüîêÒh¹Ñez~­#€Áít:võßj‘l~«ÿaܪ—‰éUG7¸Ë–·Æ¦^]ðë @½l<½½– \ÜT½¦Cµxïún±˜¯Ô‹.nÔ‚Åí \Åp<½»Q»w=gŠ€ € ï5xó&“%ý‹8ÿCY¨[Æ‹ oüa6ª1ÛëÙ䥃;|h òÅxØ+s€ë»vU-Óqyã½sy=¯: ˆñ…,Ü›° ˜«qþUŸÿl*«ôNy~1–ë6·ër±ÎŽ¡jmÃiõ¹*)b.¾lÍ)0¿éÊ­êø`)ÿL³fñ&;@@€÷è’Þ«Jz]¨¿]ð‡$ðdUïFé®Åvê !ò‡Ï îÉw/{õ½úÎÍ}VÇcY{WÓª~û7ú‰å¥ÊÖjo±ªï—ê~ýð^õ«r½ Æ;ƒ€¦’o±¸i: T¯[ʹÐ] Ôšë§‚‚| k—ô_ØêNþëÇE6óþuºÃûåZ!>UÕùZw½Ð²þ =Ì@ÿ Àâ¦\·q9Íuç­ìn ÿ=h0ºÃÛ¼ &êÇÆK±W‹ë> ð̃…?xÂÐg÷oäûçás<–(m?®æù»žçûzŠ­  À·0øÄ%½óÑhrêEŸÏBGý¦à Ëðû䉃€-ùüöêêzÐÕ¿x=¥x@@€$àËx"…q’ºDöwrhò“TÏ-Èîoz½ËÁ`0Ww9fð½ë @ ‚‚ A>l ²—‹ÅÏ‹ÏùoO^æ—ËÅgóù©‹ˆéM¯{ó§ñCB|µã8ÄWyöe.~·õÄk‘ÿc–ýãžCÿÈ¿âç@‚¼Ï à·sCý^¡ú¯óñ⤪þûÍ"Æ‹› Y1ÊW^ŸZòþÓüúÏ/5ø×åÍÿÕ5¾kß½˜ÿëÚã×׆~\ýwó³¬y&ÿûqó¸ñ½ëåï¶šåzkmAð®{Ì£éíÇ—²ªïž¼^tUý9ý|¹øìþþóì¤müb±øÅ©¥½øùñ¢³xnIÀWóëÞŒØ5¾Û]´Jwñ÷W²Î¶ÿšÿ³,ìË×ÕSË¿^~r—ýF”‰ÀàoÖÚ*ÿìZgkk@€· įæ×ßëv^t:/º—׽Πãúgy|zÕózƒ›ñøkA@þùÝà£ò¶ÿÅå&Ï~vw}3èèǯ??½?Z­çñMçÅE÷£ÞàãûÖ>-†Ã‹®×Þ /ÔÚ:WYnZ,?›O?U;sýÓùügóûxž} WuqÑíö†Wà Cê\Ý3Äâ~ºé~~Ròð?eI±Vºÿ.ozþ‹¸1¾ÛÙu‡?~׸øQkÇ^//¿k ïn{ßíÒ# ÀÓ¿švª>üúãâã¹,Zo?2Z=ü&È¢aùúÞõ [=u­“1~±¹ÈüØâ—óÛOÇWÞÆ ‚üöº£×Ðÿtzó=ù÷…Z•,·61þùá =¿tT`tÇÓéÍ¥üûâHM/]c[ï”>b±´žÏ0¾{•¯?8ÿ«ñð{zÀoV. ã»cñ»ÅC@‚r÷¥:!rm¯ù߀ Oˆ5KŸ1øéjtzör™‹²Ø6 ¯*Η?®‡üvÞݺ'o´ªtY ÷Z žhñéÅF w [ìBÍ;°,Nÿ Yœ­U ļ³£G@gþ=桚GpðWËÝ‹½Î®?2ŒëÛr º;€qõ£ñø“ü£û½ËUF€ oÓ#`ú}Õ¿óýi]Èæ÷?¾ÿRˆÏot…?,g¶»¿¹¨{dC]ù£¥ºMþ[‘¿œ0^Šb->,P=ÖÑ].ª‚]O@Ø ГvOŸ,P¨õª Œ,,òå¶ü” ŠrŽ€µùÿÅTÍ h\ýN~·{Áù'ã»Õàˆå_ ;]\|tÑýžJ: ¿á@‚ÿÙýýg~-ëúÞ­hË‹n·7¼^Rçên±¾Ä½Zb¼à  Nò+UŸoþ7þ\Ô÷ð7ÿ»úL=uûQýÈpÜTï‹O»[¯ï-D!>»Ú^Ïü·­½XÞÉZ8mw.Èo•Ýñtzs)ÿ¾˜¯…bÜ“ÏèðÏó®¾{?ý…ªð§ß¿P…úGÕÍùùÇem?˜ÿJˆ_.¦Ñ<¯ù‹Ò zãVyžß U‘?øËeýwWü¿ÍæÑí¥îpýãéô§Ói¼6D › £3Ýd°Tƒ¦Y¹±Å…aܬ+XŒ»†Ñ3Q@@< ‹^«ž?ëûü7å?Ÿöä?¯?G,*;ŒÞt(èÖwþËö»& ,Kúéô¬õƒbÑÝ òùõŽøAAp<xq1ýe«GÀ÷¦E+¸ù|0ÜܬF4å}ùÏ‹ûÒ5üËùýg«Ný‹›]A€êpQ?¨‚€ñú+²éÐ0:÷AAðð @ý×iæø¹(^/‡ÃN=¤¿#Ÿê}\ýR`þ³5­à‹N½”üc ‹ôå_ê×n?mþꉛ.ºÃêE=M@~µuo_Ìõã¹Ê ò¹&ЯÐý. zßëÉj¿3¼¼û\Wäb9XŸÞïâ¦ê&GÛ“ÿ]ª àÇ« `üñeówy#_¼¼»X½¾{ýÓÖ4™š,ðònÙÞ«®Qê- 1¾¨þÑú}Ár²À+:À‚ñË{5çßð:ïãÞºø­ÿm?¬Jý‹ñö@ÿ|àZv€ € 8ˆÏoÖîùºøPo{=5àæ,̯:†1Ìø¼€ôøÕüêz0üþPþ7¸Nþ!Ü/ï®Ç§Ný'¦×Wӌ邂à¡sAA€ € @@€o‰ÅbñûßÿžÏЬSdµBÉF€§÷êÕ«¯¿þšOÏÊW_}%«J6‚<½o¾ùf±X|ýõ×ô ðÈÚ䫯¾’uЬV(Ù𮲀W¯^É·Yš¬Md…B @Ž àŒpF8#œ‚ÎAg„ €3BÀ!À[*DQìzTäù®gŠB=!ŠÝë’‹m x~@»¶iHfP¬?á;F#˜åÍ3IØo·ýx³â/Rg{m‚<"Œ‚pd†¶K÷"Ér>L²¢ºðw³ú™ÈëûQRE2qå±X[aâ[*!X_€ ÏHÚ†¹^º"¯{þi`f²]Ù‹X…ië‰,2 kùô‚<_ihm­H ´e½?Z»ñ_äQèÛz€h¿Ò”¤EAà[ÌFÖæmI$ŽYÎàeõ3yìF?{£:ìx®A@¨»þn”í^,ŸY†áLÊg‹P%N8 }OM9à8£Œ0ð í˜#àMô€X×ù{~(Ð7 ÓOÊ¿#×¶l˲lÛR½,wBx^ ‘¥iZþ.@,ÿʪ!ÿYäêžÿnœÌâ(u}9Y`‘††a‡q’‹,Ôb£™ØX£þ57ÉÉ€ ÏLªg\©~ö¯ˆúæÚã†SÍP¤žµz´Ì6Êý4¨Ÿ¶˜/ð'¡(„TPèAx×8#œ‚ÎAg„ €3BÀ!àŒpF8#ÿ?{o×ã8’ßéòøì…?uµ—D^ìýî Ýh¡0Cº< èB %Ph¸…ÑÙ‚\´óh4Û°ZpcdHÓ>§’.¯K,ëˆå©1{Ûc°fËØh ‡c·§ëDI‰Rê-³³ª«ºžg„%_"‚A¿øGà#à#à#à#à#à#à#à#à#Þ]¾ÉùÐ.™¦Œø@.#ÐÃ\8F¼s$ñR'ÉÖEr{'ÔÑ÷°Õ³fßÑîo.OÕŸ–ÑæuËgÝYôýh”wëŽË{È2wÔü³r©:‹’7^î(-ömë1wxÕo³ÁfÝj¹;KvÜt·ºïñnØë™äÿþ𣠀wø”µœM§Ó™üÏlí;äÌP”z‹­ÃlÇà½}Dãî`y£Ò‹E¯7ûÞ?’FÓ¶±¢4LÞVgÔêl‘Üeše™dwñý¸[ß©;n9,ç=änÊ“,‡º­ÞäÅ%Q»´îÚÇoþ]÷{²¼Ÿ¿{iÿé%×êYœÝNi'7þ ½íÏÂÙ##îZZ”³jY*°á†[ÎÕòÙÙYµ77µ –³¶ÞÑ ‡jÇ›x Ãv5º+in2m–ÏÊåf·›î«vgÙŽh, T®6»íªö4ªÓ¥X?䎻™ÛQ*f««X\ͤà5ªƒÙb±¸ºº*ŸîÎ=Z,fúSgÈS…pU1íÕ³3Îê…Ü÷?ÝÆ‹n=+W¹9ÈÏHfírIVº¼4±_u‚Ýè¶Ð‹a÷,»’R{x|`\ÈÊê¶Ughv½^·;XäÊ,^Œóò–šƒY^Þ¨}&Ë«Âïåiy¯…_“cWì~Kgå³R=ïxéød½ÝLCz³u‡Ü‘{<«Ê6—]±[ë°$‘Rè*má©>-–5;”`–d9Î{ŠêC¥Bîy.Ín7ïMí#&f]]ZUÁª§½ÄUêq Ƴé0½³²vßÓQÜq7ïu¯__IÙUíÊòʺÑå2‘œ_±¬ùºV²ðHÚ6’xÜÖݹ®ú@Íôõ–•`ÛßîJNÇC½±¨*5€/uø2Ž–CìÑ(ôý5ÈªRÖ³ØUî÷×ËauýkS˜>“6V©>X,£Å´§[ôH—Xh!|ÖÌfÓ´æÊiwÝý!ÒVÇšem†{ÕôçnÕˆÊÅëe–h7Î=Y¿ª[í ߸nˆ…î\MÕµSVú3(ô¿ F½7´«[ÕrW}~uJWö‰,“,÷[ôyŒ€]¢L=¹V#­iÖOá*RT>É/‹Orúñ4QÊ©¾’yú¡ðXD@G[Äé s’D×ö¬å#- †Rež†ƒ"ù´Øœe·Rʬ4ž62šñZOj ™^È4Z?v+a˜§¦ãZ{»ž#÷䞥¼=t–ŽcKõ™"z¸ðêÐÓ¿ª¸fTh† ½ªõOs|bŒ|"®Õã*¾Zî›eWÒ6N âUS6LÛ}š¬Ë;(¦)]TŸøDž6ÊðJö‘)ׯ Q¬É<ÌC¦Ÿò÷æ®{o=ÎZ¿.Ï[JñUŸs“¤´1«%Ñ=e–+ºU¤½žA½j5qU:Ic$Ñb¦ëWl»ôHruÕô…è)9{;êÞ;î½.í )ÇTy‡×»\~cmÄ{îBÛF€–°M¥@¯ÒÝUUÙâp»¯ª§¼eèYèë¥>#ž ‡Çb.ŽtÔבüóÆåÎû=oǶX2ý‰Ð]ËhæM’èF,Š HÍ‘ud„.¿öGöÿDÈÖ)-³&;S_–½¬ t#v³VTž—¶NÖÙ«Ûdç¼’kF@ºÄXþdKUcûJè;ÎXÝéâªwôWåæ}>½öµûyÕË~„oÙç0®?nŒ×§«çïñzè/ÉÔ”~t«Ž£ãO–…,zÆuzIæAl“.– ¸•ªÍf³ªñ²¤M‰²aÝÚH/äÚãÙÊ(ïzŠÝ›{Ñb¸f\ 080*®5çÆÐ\RÔ«»ÄÕ!]mìªÇBÁÎêÍf]G°ŸhH5²áèvßX$b³ê–ƒ³Rïô©ýÉb¸ÑíÚãåŽê]eq wýe¸ŒÒUô¦QÔÓre«ªÏ¶Œ€ÝÝFwתIõÛÞ‘êé@m©ª*Xõ”#F€¾Ý6Igªïí¨bïwó^§*>^ÕåUéåA±æË×ï‹£]hg_g*rç*y­fg´·Ý rt+}1¬÷3ÊG̦cõfwÖžû}ç¯Íbm\‹#ØU’DãkcÚIrø'"íë²åµÑˆy—>+,òZ,ö1# º£s #½t_=ÚS½wÓç}í…ž¼úѾMŸÀØùܬfxΖé[ *ιt¥B¬§›Q¸Q5¶RO–¥õìɸz|4Z\Íf³+ù¿ì3[¤;“HïÈ·ë=é2^ƒR!l8žžÅ‹ÏZÑ —×- ýਈõ¸nQF*’÷¬h+\õ={qôoK eûÙ dÇ"»êÊru ‚uã‘ý†r%YÌRÒjTõ¸Ôõ¨–[¥×o°©E×(Œ–ëz,öñ°'k+±$šªàlêǺáò¶Ö­s ÷Tf”K¥j»®Ö*(º6×;ÉÁn£åG>öžÞGª+(YÅÐË¢[ÆOë¨õ•Ä" yÞ×Q÷Þq·èué¢k«ú™U ÞSÑ [×üñ.´§¯FÊ (+¯!ß9Ôî«ê)oÞI|Õ.äeé3½òÑÉG:êÍ€÷ûÞ_›×»n’ãÎE¡Šô;u\ÔþŸ%Úu À0[YS²´2 ¨;UqÈ]{÷ϵN3Ùê¨é˜üF犦õ‰FÆ·ïóú¦.õÄz{58Òç“å´©ÖA˜a FÀgP1Ós¬Ç‹8WìC=/s*¡§·ª©˜ËåUº€˜QJu¹P§F]›Ã|ÇâŽWúNŸ§{‹(Jg2+és¥´­Ð%¬õƒ¨XÔu©ôc³Ð#Xõt9¯tàq¨®+£+ ¥4b1ë¥QIÑàèéIËc~ªôáÞÜ_ç#xé¤å±š½¯‚uü³qÖÖ!Ìq6¡·:=(0†z.ñP!N5ÐNÒ…½¯ÔŠpÍ«år¹X|›UÔõ#xU6•¼’´­šÃ«Ã ªWƒ/Ôxn]/‘°XdÏøi¨ps8Så]¦s†›º¼êêÃfIîÓå]/¯ÖÏjA?w,f*¤>Ó‘.këªnë½¹+5¡ç7g"-\ E©¨ª÷ªyÓU]¶tÁt¡GÅ멚Øè6Ùl|㬞-lv’P•ý'ÊæÏ«0僯UOûî]qÞ(¥Â`òŽŽº÷Ž»M¯¤KßÉ‘&u&[-ºæ«ºæ£íšßß…TO‘õ;Îúêb³¯¦sõ7àÞvW³‡t[éÅ;uÇÓ¥Ê Ü/ôKuÆæ¼}~oWÙ¸³TÏ>áÍô»ï÷n³ÑiÓôöðJ5‰ZaDfz(#íìèF‰ã(ëE½ÅþŸùUÕ’ÌNä²_YWu” ˜—ÓÙÕ,ÓÏBt[éûTµæú>•÷»ªy•fi¨ë%¯yýoA[çgÝ[y Z½«õu{åÿ2,î¶Ï‹E7_jay•-+`è÷ùU€ïŒ€cª`ýØ”½Å=×?bÑÌÿ.Õ›éjðƒô!xµã¬ªã¡w¿YðÛÏÖ³š½nšûp)†gëhÛ(Ã­Ž£uÈhyœèqÅtžCª¬×VË¿‹ãѬ»Ž0Uër'ûsÏÆÿfÝUøïzMò$º*†0—ó¤]ãÕð¬óœ¥'Ë­àâ³Þíë6‰gÕu‘ºi+n½b§Ž*’ÏI´ˆZ%×ÍË»¬Û;t°}%)¥7·K}˜¬jG—îÎ=uÔ°§j‡e1Š>NߪKÙÏWXÖ}h+ºX,g½v³ÙìMgJC  H®zë îöÒµÚÊG–N[Ú½T–²z%˜ötÔ½wÜ{]¶¼âºCdÖɺæ«Q¡æÕðýÞ.”»oq=ѼÔjÍ‘ö,>Þî¯_ïh«lˆ{°>‹ŽûL»»Êµ;K ÈÔâŽû}]*åJ¬’M-äjP˜þPªfGï±Ùîë™;~"ÖWQ¿ÒŽ€Ü,tôŠìéÍØÌ^ý lž¬ºTX“±ó>½~¿¯B"íËl\{²Ý«Í´Þ7ïó¯ëF|øðáÇŸïü#š”iR¬¡X1Þˆ ðîý‡{ïýïÿïSïR I™ö{íßà À¸{þóÿõŸe÷¢Þ5¤X“’zÀ¸c~¯ý{ļƒH±&%õ€p×UvN¥ Ù0èU€dàW}?øíoûË_þòÉ“' €ï©M¤B‘:Ɇ€ð¦\€Ÿÿüç¿úÕ¯^½z•|×Hm"Ê“'O®{wÀ/ùKyñ[ïR§Hµ‚dÃÀ¸{žÀòOd:åj·;,túh,7vgKµړ߯Äzg|5¬—uî½ÅÂ1ŒšëGg–µÇCϱÍÖF°@ì*–ް*šmÖFr¯ß¯Yv¥b[Q˜$QÇ–Ù–Õ âØ÷çnÍ4ŒŠçKæs?ÈS®mf­¡“3+NPÌÔI31L»ï¥f˜4dºv£ÓIƒ*/þ?7±ïV,3 ˆh¹1?À×YZ¥ÞÏ ‚þçí³V¹|ÑîöδGÐþü4#`h­å.w ‹4Hþ¦dœ–b+ÿªq~6X\ W˜öz2[þÓM§ÄÁ¤– nCibÓÍÅx<éÔŒ}-Óã¹£-€ÆÈóÜ–­¿«S"¤ÿ0Fê0áuL=Ý`…#c›J.øµ s½‘#O°úYt€×R§WœIønGdõÕ ‚`ÔH“h¹Þ¤¯Šçø·Ÿ¶0ïXÊKðßseØnÈO0FFFÀN# ØMãq3äogÓA]~i2g 3¶ŽWeã¼Tÿ“Åò¯zU™ÔFÛ§-Ê;Œ€_4ÓÙ¥?Inhˆ8p[•Ôp&EU-ÏMÞÍšãgÁ"UÌ«Ã|5Ï?‹ù<©ÒÍtŒ>peš­Õ{ O3wL P©µ¼ì™”öáË͵š~ß–¹jû ”ß^´:}åìã>ý÷¿ñÿýqáówÏÿmuñ¾7q]w4RŽÄѤ### ç—’þ| õ³Ãø'¯¿ž–ÏWkÍ¿z}’Îôñåá 5&o×*ùX½ÙŸG¹ àJí-¨âöûzGXS>À†`k}ªñúÖ\Šzk-×WF€»ÓXÉï•Y ‚þ*!;.”…±t¨J9ßuŠðoñû¯¼ýùæ…¶ÒˮԚºP####à#@Kúv&éµP¿µ 7žÕò_G³ÿS}’ŒµCˆøæk¤ú]ÊìZ(Ò!ý⸽RÚ5ç?l†žÁ¯Çð^á(Ö‚_§`Tl)«[Q!%ò­=F@n+„®ÏÕùóõœýpT3 K‡+ö–pd­ÁßþÝg¿ûéÿî§ÃüóÇ¿›ýìë$³¬U„W1LŒŒŒŒ€“Œ€¨(é.…úpùêvF@<ûCøȧ,eR½-Oa·ðõr:¨W»ÃÙòF€–Ķ©µó6Çí…kªÉùq¬ÏSù­5¹Qq¼0 Ó©õ†áN‰Zé~/Ú°Fõ ƒ¹Ó°ÒeDìë´ÜH«WÿáG"_;Àt½ –y{zU‚ÚDèåý ½º¡>£xúIãÏCßmYzÝ7Y1### ãU´ü›år¡V¨å—å2ʤùðBãÿB/Ú§†ô«Ã«äVF€öÎÛS)ÚeJ]ù}|RDÀ/ê·]#@OÒeÿ kÄ›jy’íhMòBêæÕº¦Ýš‡BÜSê|#@ŸæïÐÓ ô[‚~š¶Qóbü¯Ià äßÕ †ÝÅ©1‘osCºÙé:fáN@èØ« Fºn¡+øÀÀÀX)pcãÓ6¶_D¯_ ϲ½Û!ý§®\ .VY4‡‹ÓÖx5V‹ž—šÓ[·PÑ)×·«uþ?ÞÒ]är××Á//FFFÀgçëó}±ÿ”$_PݽFÀkyÿÜr€» öGŽÓ°õ[m [FÀŸRÒW/ºãʼn§ÄWê~§ÀYoqÓìÞ´Íûµþ~£Õj4:¦ÚFFFÀ–ð‹ÙX2œ-¢SψþJž0ÿùR$€€ð€€€€€€€€€€€€€€€€€€€ðfŒñ" Áã xŸz³ > ü‡þ‰§ˆÐ³ÍŠŠïçO—ˆ‚”0æw###à]7üû†¬ý±ü—'ÈÞ§žy¾:Åè?:.ïEà†ÑñO5bßíO·ó»ŒœQð­ŠÀµ³ÿ&­áuZ^$ø§00#àÛE<õ½OG5¥êíà# ¼´eVxá“`>õ£—§ÜÝB —Ÿ¬a×4Œþ[¼©CáÞE¨‚œ7l$~GVK-äß ÀÀŒ€Ûâé¼s¯R¹×è_º›F€>íWZ¦¬+³e;ŸæCù"]:¶Ún9Ž{ézOŽ*߸_±,Û®TóÂhv8jÉ­•F§U±ÔPzÅÉFåEìûs·&oÅó%󹿯sW–I½[¶eš®ÞNZ¦iµtÁÜ©˜2݆'bÒ°e¾–¥Î°k­†Î¨æúŲ9*ŸÑªX2)U*y^g.ÿÒÈ¿¬þ<–¹ûnÇ2³¡ÿÖF:i•õ‹æ…'²„vk"·ÄsÇÔÅòó©ò*š•¦eÕœ ^Ÿæ¶*ÙvÛ6ÍÚF°Bñ£§aüòÄ»;°7U¹©áe»]©™ÝÕnýçv˜½VÚ†;¢8qä¹îj€=t-Ó VHýœfåšFêèÜåß,HëÈ“:ßôâ-ß‘¹¤õÄs¾ HˆCO™î蚯±ÃÈJ²Ú²®tMQ(+^ûêºZ*è ú–aÔæAK"µRÂÖòƒú\{{±á§Ñ»‚00¨2Œ€‚àf±ýa-Wûâѵaÿ‚ ´èeEøø&Qè"°®–aõƒýF€{-ƒXOXa¯ù“úyehõž¢¯Œùm•»ü²6RQ}m¡ÀHª|³ãoYéj*¿Ñ¨UìSŒµeegˆ¢P1®‡=¸z˜?ökÅ­Vk«x±ò)¶Í ¾ˆ™€pÈh)…ßøTëÏ/æV µäóô¥–÷TX¿áç“þå|­ÒµpÊË (ì^7òl¿eXÛF€ˆæŽëËE’Ðw”ŠÏŽQé­yv˜ßÉå½È#”àf_¬U)‚þN# 'RŒ7ü`¢Çí×^C!H!ªh8/–™×@:쟖P¤³Dv^4wÝy(E}Åa0Ñ—¸1Èyʦ˜oñÄiÔj­ïí #00¾ý©žWëÿ; k5òo"ò`ãÜîÜwZ÷,ý½’zö¹‘¿;Ð4ÏMg¾«…”ì~Ì]½Ê~êSb¿¢×îÓÒ5Öcä5?_M0UVSåeéÒ)ôéÔ€ÖÈW!õqÐQjz5³@­ 0òÃ0›ro¸~‡~C¯(®¤aózX~5£ žwöŒ®Ù½]ð&”z¯¨"ùjI5S_Jv=/%»ºÄ‘Ì­1—Wèûéö4ˆ@8³-TT8BºÝj¹j’C”­8PÓ‹ê\Ô…¨K =}‰ÑF«¹öµ…²ÅX#00#à ÞK¿²=àBK_¹Ž]œПêÀgž¹y|g¾«½Æµ x=®žÎ“×Z;LWÔBy´z=AÇZ_é{A’¯PŒ¦_€¯#êÍŠ­§Xÿí¿å)¸þ¼aêùâ@ÇÊÇíõ{©ßÂW‚<_Û/s4¼U@¿Ýè4t.z¸^…6l‘ã¯ç2X•ôz³éý¡vFVWØè{i\¿R(ì¨8áŽÅ;ñ5ç"½üÆ„w FF`ì} ÖB¼âÀ®—ßY´¹ž™°µeµ]ì>þ†9( o¹»ÎÚ=å^Ü"½§ˆ]R¼Äë‹$¨×Öö¨}Á´ÀÀŒ€ãFÀ‡M¥ïö;¦a´"š 00##àÖ„ÇÇï…ká9/bÜ00##00##00#########àM#^DÁ£ xON^±OˆðQà?ôOõ£NI^‰àÑ †ÞƒKÓ8ï¿ô-Ó øéÏ›)¬}d˜?œÄ¿Ž\Ç0>êÄÔ F``¼‡F€ð?qìs)­Më¢VkF»gÀ¼s¯R¹×è_º›F€>íWZòÃlÙΧ~¦ÉE8ºtmµÝr÷ÒõžUëqÿ²Úvå¢1¶>8ü¤eµìŠÓi]X*— 'x‘fûŸÏÝ{2‹Š÷¹/¿Ï?æ!&-Û²+¶eu¼8‰&–iU*˪ÍÕEÆn«bfcÿ¶ëLJÊÓM»5‘9ÆsÇ4-Ën¬NŠƒI-#¨9Þ·ÉáÌ­äQvˬ]ª2ˆ'ëÜ´?Ö¹Ïó\Ö[Ãÿ" ?mÉV°[–)+ª]k9]cnüê`þÜÛf®ÊÀ5>²‚tRÀ?zÆG†û÷`FFÀûfÌûfÆ¿úbû/¥ì…£`x§GZ §–Î0ûs%÷·Oé«þ§#÷²µ5‰@<¥)Û}×û´¯$î}_{×KU9잣¥¾åEBJy·¡þªtF‘ÒÓže˜-× ßmI¿ÔvD€”Âò0S#ˆÐwû-™”£mØwÔ<‚ZßB¢s¬¸·TÉ"°å…?ðÂgá\×LzíÉ‹ÀýØJC!ÄSß} v9EüØkµUëô/[Wˆ{Ù96)C¸¶q÷`UŠ¿í+#à_ô_öGFÿo10##àý2^ø––Óîçq*5©àÂUÚÒ°œQ,D8uÖF@~ÊèQ‡³þÊ;PzøY8é«©Oüèi¿<­¯”ôÝ®ºŽ— òK)€×ºZÿyƒ©¾æ­(=W)àuL{,eûÈuݑ۱ Ã>bHB×0VY2­¾:'ÕÕ Yo)¾¬üeTÀKUõËyø,Ž_ÄÁgîèažÐw}á…J /-ó¾*§Û2¬ò‹pÎ çðê b‡ËüØ2>r²¢|X€€ðÞâQ*ã3‘¬Uh>3~n¸YlX[E <º6ì_0´JW¡éîã›HDX×€LÓî3n2Þ{R¦wÔн’î /»ÜÀ­èõ+F£b›†aûÇŒôÓˆ€ôM#àÚ{x;,üËZ±z[ŸdeÐ1…ÜóJ ¤FÀªÒ„{ÄýåÍ¢ö·’šà"ŒŒÀÀxÏ"ž§+ü›^>??~é_Î *½râËÖèÁíMï@kÚËLë7€ÖïÅDJþÚ(ðòÿ•6 /ˆ&†a§«€á›Y8½~Ë@e¤ÎÎÖ·؃‘ÓhÔï„—¼ŠÜûnøBÄÏ¢(‹°Èæ,h# Ïý…o敦Œ€A¡ÒDÿÜpz1"¯s8&@ü½k|dú¿N¿ŒŒ /ÀŒŒ€÷m€läß87k·jítò%|•éyµþ¿Ó°V£Ó÷&b}ŠÝ¹ï´îYë‰úÏ=©çówšæ¹éÌŽÇ‹g¡ÿ0f®<«réüà‰>å _­–wÏ _Ja»2ÁšŸ»á'²l¶÷( ÍÇ:ºL@’ŽfgKëkWêÝñÃÐ÷Ò×Zî<Ð//aàA0j˜FÕ_|?Ýž¥ÓùQè;:  âêH\ÐrçQGjŵo­Šµtî-/:Þ&/U|„õñ(üBˆ—±×—؈^¥F€«üè©ïèV¨\úñ¡ë˜Æ…½ŒUÓ´ÝÔÇ‘»îZ¦G Ãqã_‡ý{Æzš`FFÀûcHq¹Ž½DoUÜlFºðîW¶§\èqø­SÎíþTt?óÌÍã;Ó#º×s®Ï2P¡ïÁe–¾} 51>Í}´z=A§µ^,°ÿÙ)oø}¥õ­¢8ŽTö §c›ù‚y:æÏBz±[ËÞ3`UÒ£Ò bÞ¯­6+}¯àNÄž>§Ô"½Q!¦óÙ*Ž ÖoLÐË7\¤UdÿèAVW•ËùÈ1õ„ŽhrOEmø/ﺳ#ó#ÃPÛûကð>™Ââ…Šóß½ýF§¼µ"¿<º¼Ývã'œ°JÞéçìYt/òT@@ËN¿´,1Yï¾õ…ß-ÿ"â/cñÿ `FFÀ{mÀ›$PÑµŠŒŒÀÀø0ßé >FFFFFFFFFFFF`````F``¼§F€x|ÿa>'–µQhÂøÍ–çö»?+óðù¿¾ýkŒ³K bVŒŒŒŒ€·IøYKV{þ1ƒ—ß½àZFŠéøo4§¿ûáëÿþë¿ðÿí­_b`g—h8>N````¼MÕÝRúßùÌûÞ,xwTiзL'x£Yü“ÿ»?ÿƒoÿÓo¿«Ê`FFFFÀÛ‘¡Ï|÷~ÇÖ±û®{9 ópñdÞ¹g›ç¦üØ÷ÿY*VÅü~;¨ØNð,py€<·6¾7‡I˶ìŠmY/N¢‰eZ•JŲjóXîÝVÅÌÆÅm×"”§›vk"‹ÏÓ´,»±:)&µ<Ž æxññ«ÿ·Ÿþà›?ûÁ7þƒoþ⳯óÿú×øÍŸýWõùÉ|óãßýãÿxdâ€,•mÚy‰¶'Âk¨ë•Uú:–!ö[•lì_ýÚ% wÓ†-/qªKtd­YVÃ]ÅDˆ`âä—h9“U͈¹ÛJ«Ñ´lYE ü‰ë8.3#### X…IêÓy¨ä¢xìnm—ŸÉS¡„kÛ¸¾+=kwž£5ªåEBŠf·¡þªtF‘’ºže˜-× ßmI…[Ùߎ:Ìì«r„¾Ûo­âêcßQ2¸Ö÷ƒÐŸè+îáûÕ¿ÿÙï«yòóÉÿ}eüô?eןòïþ×!' p´›a9žÌ1œ»úz+#?Ró:ª(žžºD{«TÛ§fEè-Â÷Ü–m¤×+ñµ Pë{ALœŠ¾Ä@;®ª/ˆÂ@Ÿ°9× š¼I€ïÃÔ€W"zêwôÔ€ÑÃ0|‰WÉJí[{ZPÆ£{¦üŽ—žä?°µþoøÏ…xxS?~u(_ óV” ]W*ÕÎj\<–²}äºîÈí(•|Ä(ÑÛÏRÓìûZ3«TF 2ü¾ЧDüOÿwRêÿÙÚH’_ÿû'Zÿþü_³ïÿéw/§"|u…^”úê ×Cÿ"ô=}‰#u‰Ö#@RŒå…™ú”tMÚ$¿Ä¨¯lU“"èËoî<ˆâXÄ‘çn†V? "H]ŒŒŒÖHeQ„gF€û$Û$õ•òoe <¸¬È?‡'‡šÇžÒ¬j˜Z©ÙF*˜•)PÑCÕ•F£Q±¥”¶ýcF€½ùyª FÀ6nx¼„ÿëé5# ‹øæï¾Ê¿—Iâéè‘Jw£åWž̬ÔšºÄãFÀÆ– `Tv\bM»5³°Ñm*BÄÌ ŒŒŒŒ€m#àea‹Š0*—™Ÿ÷õ ‚‹QÑè?:][ЉT±µQà5äÿ…Å»ŽWWìVpа (Ðãðnj¨‰ºxBˆTûŠ“Š'Ifü¯£ …#)ÁGßRY]b`õ£I-SõÅÊ¿fÈ-­yv‰~Ç̼Tšr~iù¥FsÇõU€$ô{kBéBÿñõ'?‚ÿ_ÿï?È·üÁï~šÿä~wLF 7²/¬tªwÇ ÃÀSæŠa˜­y ¹ˆÕUseÈËV¤J]W‹ÕRÕ2qÒýxõ «(–çNô%*W% ë$B¦ª& Ô¼‚CÁ€€€€°2>km.ûgyϲ]ÁgŽYØîÎô(·›ËZ}ï´¬„žÓnm,cç9«pö†Ó±ux»áOçÃoÅùgòzoe«ñ§ ļ_[mVúÞ‘—òýõÿqmQÀÿªŒ€Ï‹ÿ|ó—+Sàǃ„ß×Kõ¶˜;«ˆ~»ãè•õR+g¤ÒŸ–8öÝÕ›Ò:±úAZùÅ)¦Ýò‚8É€•Á¤õÒ˜„ü3L 8¢mÅ õ¹«ÄâáúâÔ þSÎÉÒûîêkç\üÛ^brò%®§Cì=‹Â############00000#000##00##00Þâ0H‰yQ``FFÀÛäQø(qØF†ããFF``¼-EîFç;“â¢oN€€ðaâé¼uaÊ–5ÎM»m™#©•Å“‰%ÿüx"¿Ç3Ç<·¬vÃÿBm·Ï-u˜:Þnõ–úRóŸŸ”•»%ÅE8÷¶™ûáþ–eÙ•ŠeV¼8‰&-Sýe[•~¬vÇn«bfcÿ¶ëLJsåé¦Õš¨ìæNÅ”)7ÜÕ9q0©YYZ5Ç‹ùG0000¾>€Û6Œv?x3×Vª¾¯´ò‹ÀýØJ¿‹§¾û %›Þy(’/äv[~oét¥†÷×F€X«íÁ¥eœ«qòàuÐXÉýXjøÖñ¼Ït#`K{«éæÇž¼ây8yП?EU?ÿBý?ñçÕZâ‘ÿf.¿‡ŸÔvv°mØ«ÃÒïG€h溳P¼ˆ£gqøhbç>‚üÆüEzTìœÖå*"ÀRž…2lý####àÃ4^©5öV“öÍs£òÀÏ„ûãl¿ítœû-+ý~T½òì,pÀR ÿé$;åÂ^¥9z"ÄÓ‰UXÀ<7ûz­>‘/Ow?uóc¬ÉÓC"]O °FC!DüÄ“gÕ>‹R#@­ ðñ(|NîëÕ/Üø•?wåu¹£Xûî#¡/­–­} ÂÆfð¿Õ÷V;£ÏÝâ"ö½~˜kgñ¤¨ímç³Ì ðúöõÅÿÄ“Ñöb„ÓH'22sñï\:«GOY˜N˜Gø—µl{;}ÙÑÿþ:¿„Úü¡rŒö(Ö„µŽVŒŒŒ€ijÀ¯à…PŸW»v½T³vÿòM¶¿Ò…y%v枈7œ;FFFFÀ÷ÛŒŒŒŒŒÀŒŒŒÀ@ÕR€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ð¾Ïæµ¶íLÃ7ús BÏ6+^(øeÀŒŒ€ïÒú²Íûþ‰‡ÏÔì‹~øjïÁÈÛ‚_®aÿT#ÀwÉ[r ĤãïžA!‚Qg¬ÿ~¶>2ŒõǾZï å5xáN¦ÓèïÜáuZ^„/`DÀ¾ã4܇ñ‰úÔmƹ½O9§‚ßÝ¡áE„ñ©ÂS¸¦aöƒ·ð;¸¶aTÞ¹H¨b þ_û#£2ôü¿öý‡sÿo7Ô}ìwdµï²NbGî¨M®ïð;¦Üò/```¼ŸF€˜|\±/ìʽVãÂ2ÏM³UeÚ^Ìï×ì ¹× ž®c›çRÉ×æÏµ|а/j §Ö¸ï­´b4íÛíJ¥]i|ܰÔÁV?8 âàs¯¡¶˜îÔ÷?ŸÏnIÏØ1•~ÝÚØ¯X–mW*ùzZL¶ÜØèt*òyRÇËŠþÜk¨tú¾d>÷ƒ(?)t[C#Ï5Íšö#TR¦ik;¶%i¸þ* ËRصV£b)Qìb„¯òq rX„­–iµ¬Îgaôpd«‹5ì¾®œW±ûqEמ²BVÖIøIËjÙ§Óº°Tl…¬çëôÂÏÝZÛ²Z•þ§žëÈÓmï©J,~4©µÒ¤ŒÚ}/ÞŒ°ðu=n¸-_)# ÿ·"y%ÄŽp ]ó¶»Ã ðÝÖL<××ðo```¼F@ÜÉêÆÇ}$ò1üíOç¡Ú5ºÈ·´Ö2¸´¯¯D©xعžŽÿ²PŠp"5gËÛ .þdäºRõý‚´ FTÒ·\oÒ¯É/Žž8Žjƹ¾ Õè½íaÌ[¶rÒ©çJ‰¯ãû…ï¹j—Ùz»>ªáö©Ù ¥øê,]^™—¹QÞW±÷‰ÛÉ«¥rßu˸ÐÖÆsÏ:7[—^ðØw?¶Ò:Q—÷xdf~ë}Ú7 ó,¢iK[N¿‘ó±¾Hâϵý^ßúŸ:j×EQǪ ZóZÔ«©µáöTŽÀ­ì ÚÑð®›GúŒA€€€ð~N xáëákK8 O)U#S°jä?Õö ÿ¹Ïoꯆ ÅúÄvQˆÆ}=XÝø4Ì¿ÛJð¿Œü騦#œO<ï3Ï›m ZG^c[W„ª½iH¹k+}e¢Ô2¬õ\õçõ©A_êýÚ<cIä»ýÉ*+×4Vý•_`f—£·gyéô|³`¨òèZYÃËŠ¼ÆÑ£mQ?ñ'Ÿ¸îåÈ•%9·ƒ—yiÛ†áx¹"w¥¹ å~|œëù/æRð»WÖL#x!„ü¡[Çôž¯ëQû)[å£ÖúÄ_FÞ°f|dt>7õ¾kl×ðº2 kG°€žaû,ï¥ ‚JAϋǮçï‹LJek8ÅÑ×ÊvCµÚ~QôžW‚]‹¦Âr÷ò"°¶dêÆ–F€u}€Øßˆ°Zyz¢_0‚µ°Ú¾ÊK~Yûò˼͆Ðu(¯½á4*ms£NZ†õ Ø6^…µó¢\Žl‚ý1îQ”ôî¡ Eÿ#Ãü«rLF°Ã†ñyë;ô¬}Æ FFFÀ{aœ[Þ³BDÀ=¯(bûö­F@­ZWò>ýÓš¡•äþpZô÷:"`SÜc´òw7€kÓ×£¹ëÎC!â(ŠÃ`¢2ËŽQ‹ ®4°ZÏÊÇ䳈e¸Ù+¸ úÅw+<›ÈJX§Ó2¬ËìøPM¬(DÜË‚2ēɺJ[y°†Ðþ_©Ð€BƒÜÎðô{vÈzOfg:×wDzÇ#000Þg#@}ÌÕ óc¡^;×2óagSîª<Èdüy_-+xnæg™*^]$á§üøÆèrõ½¥§Ÿ¯F³-;[ëÎÊ#ä“xÞ¹>Â,¢Ð÷ƒ`îê¥é¼ ðƒPûnºtŸ^:OõWÜ|1A1ªH•ïèÕF +[&@O °F~(åszjž@afaµü0ô'ŽŽ¨ø±<Æo¤YÄjž¼ZO¯Æïæjy®VÎß*—‡> \Ç47xøƒ¸0ìo\8þ“ПºéŠî,PïAøÂW5Ï _êÕú5ÿ™¾,½€<²¦×\y1©/ÓºœG_Ä‘Zq@Mܘ<«z4¯-µ –^뿹þßG·™ ¯Ùêï™`15000Þo# rO­lo¶j“GZ(ూnõ³0xz}ñ?µøÉÚpÔVß³µñžL¬õñ¶óYa±¹h¢ßU·±üœ×Ø^ûO¯ä§¥»Æ …^PË÷ü…y"ôìÕᕆ¨kÑ…d*Îji¼ØwÍ|iA[³ú½ÎŸ«×• ÆZG“ÆÖ{Ù”ŠÂÇÉÃ(¢©³Úظ߱s«eµ¶¢}Š'ùéùê ñcÏù¸ÑpœÉtRYeˆùºbÕtƒþgE6t=n´ï/<³°X`ãÇ; Üç¯ 4;óZ,°C@```¼—F€x6WÒ´åDâmŒðŠ—B~vhË=Áö·ÌEl]Lú§H9~øñ ‚Âü‚Ð1ü»ÞÞw/|³`+då}±»ÈûV[_Æñ?Æâ_®Ÿ«à†ÊdÇëU˜†1ÚóúÀ-×###àý0Ä£þƘÿåwörøæ·¿[ètûÍ•7žõ­–]»—.4X Å©õX¹‰CûJí{ÑŽ=ÎîwꕌVÄ¿T€€€ð^F<÷;N£õqK~NË{ü]êðpâ¸ïÓtÂëtÞ\yÅc¯å4d£8—^øâ&'†“Vß?ñàÈë÷½¢>ì·ÜpçU;/byÀÀÀx×ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀxׂà7¿ù ?1ðN!uŠT+H6ŒŒ€»ç—¿üå¯~õ+~eàâË/¿”jɆ€p÷üö·¿ ‚àW¿úqð. µÉ—_~)uŠT+H6ŒŒ€7åüò—¿”·Ùà»Fj©P®»H6À W Ù0€^€dÃz’ #€^H6Œz Ù0èU€dàW’ #€^H6ŒzÕI$‰ø2ŽÐP€dŒ€ï²W%‹Ùð~½þÃzs<[~} _‹Åz³¯v'ýl:ýËñø§‹¸¸õg½ò…a¤ŸÅ\¾Š®~2žþåt¶˜€dÀ7۫ĸªÅywð£vU õæô7GƒåàÂ(ý|—lÿÚe8ÕúŸ—kã Ë:‹¾–§NÛò»/Ö§|y5üa¹$7Þë-iD@²aÀìUÿ0®Kþ—Q¦é¿Z åŸ|%’hz¯TrÚS¹ãŸ¯z¥³{åæB©÷䋟ÕY?š-$þÕâˤhÈΖ»Üÿ‘–,ä÷ÿ¾Ür¢?2Œ{ƒm#àŸ³õ?[ 00àÛ÷ªd|f\Ô§Qžü÷’qÑž%ÉrÜ>»( ~#e|´Ô0þòÀè‡y„ÿê3.¨úÔØ GYüåÕTBó· ²tvÑý4‹Òà+Z00àNŒ€{Ã寖²qQÿFÅóKI?ȧ (¡¾ÆOÕþb÷Ô€]FÀë×Y.xÍ«×'⿟éãËÃßк€€wb\t×€$ç/åF@²ÃøùÉF€ÞhŒõòÿ0ëªïQr‚ vüZˆ¯iZÀÀ€;éU~·taT×ú;YÜ3Œ?F¯³‰ýÝ_çÛ‹Sô®òòd#àËYSæòÙ_‘Ôü?Zžd,§½VëãYDãFFÜE¯3{?X ñëxñ§*¿œÆü§Ãø<^|-~¤ûÿh˜ÍHô[~4[~-Òknz;Œ€$ÒIM—_%ÉÿÐ þ䤈€|=ÖŒŒ¸«^õU4sÖ+ÿÕ¶–èb\/¥ÛïUËúK9_ ùY·œŸRº?˜ý:?gϬÄTWkÜ^›°ÛH~ROט%´.``ÀÝõ*5ÿŸEr}6~¢Ø}Î×Iò›kûv¾>0?^f!¾ÚÚîצ e##ÞÑ^¥—0îU«:^žxÊ—WÃ?*«Ðƒ{½%H6Œx¯zUýt<þÉxøSýŽ€Sø*ºúÉxü—ãéσÿ€dÃz’ #èUH6Œz Ù0èUð^“ˆh)‰/¢ôî­´œRø»BÄq|£*H¡ÎHvÕº¸iZò ÁRÛMãÖûêqcn•;JJŸ²#±ï¶Ý÷çžì¿ö¿&QõE@²aЫÞC¢«q»^¯7ÛÃñx0ÇïÆc­X Óè6OúË¡é-\I2,=æ¦2n1ì6e=öd=‡³ãjNŒ»ƒe²]ú3U®³Åo…d\OëÉ8kÏNÈ-™õªFNupUKE¯ürZcÝÆrhž•Î$i(•š§¼%TuËSïÁ…êtõE¬ê±©ëñxcíEŒ{½áPéî>y›¤Õ¹ŒöRÈSd(åëæíž,ËJ³ÏŠ«År}ü¬}VíÍÒŠqó5~ ÷HÝ Í©Hbm/tW7ÃrÜ ² gƒm·è¥®Ý#Ɇ@¯zŸˆ´ 0ÎGÀ’h,ÿÌEH²œ¦Ï¹êQ·7]føÍòY¹ÜìvS¹[íÎ RL{«Qæú4ÿLfí²ÔCêH±h§ãkgÝô\>‘W3Ef”ÛÃ\/ùÐ?¬ËíU­®¤X=j‹å´ž«ÞÛÈ}6h—¥î’j|<(7”ƨÇÃvUžTmÒyâj “¨VåENµÞ¨Ê¿ä5 ‹™*ÿ`QÔåat )±\\Í”Õ‘Šœ«««e¼ªw­RÚÍTdH±³Ê'^Œók/5ÙµËV+«lšÝ¶#-U§Ëcªþu2<“Ò)Ky&uTu|TG‰X=”U0ÅrX^ɰX§ut|=‰Wj2‘MuŠ¿£kOÆÕLÔ-g¥ÞêË"‰¦g¥R¹=MTè•Jª#-ÄÑ^wÊm6È--uûÈL¦ª‚DOuÖ³æpqÍÃ:ÕPM’ ޵ÞÛXGËZÞ¾q'•,¦Ã^o¸1ÇFßYy"±î\Ñ)í.³^o0+¶à:©ñ÷‰ì€òv;^]{r×wÜYV^}/7{pñf)ziò¬ñ´GD’ #€^õ~¡Ô ÑœmJ‹ì‰>ìªËÇòh9Õ±ÁÕ¡VMãfñ;œMõBt½ÐC­%)l£å"ê‡ë¥<°›Åñ–ê]zPO»¯ºgÊKX,3U–ôi>õ#vÆýŠEO'2X,£Å´WÒÅJ÷¤¦E½7´³¼†ÇŒ€êÊvSÕ-^/ÚeõG:~›õw$¦£”7Ä[4JEº?©tÈtó ‡Ë¢ 6Ìfº3‰ÏÚZêö®–ËÙP'u6ú„,¤»ÜÍÆÊ?9atT ¡Õ gQÉŸ‚:~=Ì›JÐlP4ÕT§•¤{4áî®=è.»atµÌ“EigZZÍò´W}{¯;ñWF€¼T?×±÷‰ìóª{lø&F@Q«ŽÖ¾:ÚXGËz LfGRñ4»¯‹’~#Ö&Ù©¢wµ{”ý²+D+êƒÅ>îFÞÌVîºr#`ÃÅXÿN^‹Ps‹äu%ÑðöK€dàW}WFÀÙJÈž¿ëÓ|C¬E~1«Æ ›³xë9Çž.³3„R&¥•2QËÆŽÐhyÜl:ªYõ[ñ·ËáÙ5Q§†þd2yÉBí–”z×Rmœ?¾‹«žqZDÀÙ*Ž=Q:¤Ô]¤ºs¥Òë:,3vu-a÷&¥EWoÇÔ€ÂaZSiGCIwÕ"kµ5X]c¤ê¥¤ø‘:ën>ޭ˪²Mëve[dJ¯»kpõ„´ÎNÕwyíIEÚìZ‰ˆ¢t¨xCÔ­Ç¢÷õº[) W® ¿Uó·1bí‚í˜$­±noìNJ÷Ï­íºJyçÚ¥¢w·{ê$*;°]0n*7Rˆx¦mÇëž‘¶'z7ð®å¾ÔæŒØ[;.A;Sõ(í3%¦ Ù0èUï›ÍèN¥õÀ[/Y–o ‡ñ7”·€kÃÜãd—Z©ˆ4—j½Ù¬«±ïò¶0Üel3Œ=ñ[?—DþQ#àl3j`V˜i¬¾+ãcGÐÄ#@)ýk•íMjO!7Ôìê­¸6ÔHáôb]&Å7ÆiOZÍi²Ç¹AD€¸J£%ޝÓwÇ×¾jµÌØPì«zH¶Œ€½î@‰ÇÕ³Õ›_™+#`yF€èâM¯•ggcÝÎ8”Trí=×~"6"µ»LJöƒ®Í"meœìtìÊ}£Óêvï1ô½lT‡ãaOuœU«Ý3Ɇ@¯z_Ð5{N‡ñ³bý(ŸÎìÍ_œµzVQ¾®c ÒµúSñ“ZxåÖN# È]ižYuC0,uÒÉuç"5Öyèaaj_OzrÁ‘©¯•ÙQÙV1ßõ\¨ë‘ürµ|JÔq:@Ý΢$2E³ž½½/©kND¶YK¯VGWµ­Ý­Øo}iìzq`yóôýF@y5Œ¯¦Í¯×™KsöªÕú °Þûë|jÃYwÛÑcò½$+TU©¬«œ6«Õæ`ãÅI4;+,qLCÝíµ4V Åik,ÅØ×ëKÖnÞUfïKòR²LÝÒµN®Œ€SC*’HÏi)ç:Çëh­\7§&%¦½f½ÞžEÛkä—U ËònwÙëêÕúp³×6t‹Å;ï`míÎ]'’½©!—´éªlDN¥[ôR)j=’tÑɳæɆ@¯z3PŸ-c©m–³UD}: z6¼Z !–‹©žë®†Ü³·‡Ùä麋“|ÊýYûj /f:ê4};ú•Zo¼yµ\.‹HGJÞlE 5=[=O—‘XË'©p–Q´¼ê©…óÔ{úΰöðJå±\è9ÖzsqUÒÓ¸g •Y®|h`5½588œ-W5¿|CÍÚ¥ôíg§ÔcÕÜËk‰®Æú-eÝű¤”F*÷fQ¬N9Ë6“…~ßp¯ ™^È2PÎäµGËiu=°)t­¨Õã•¶,œ~½ªŸº"¾JgÍoÌÖ®_›­DÙlðáìêj¦|—õ¨©v:êR4Çj¸uSª­VC(Ø4I6\j¾Å•ŠøÞä;äé^{"ÓPKÍ—T?^.×+Èé¨Ùˆq´è•BÍïéu|ÃЋ”c©¤Öj?ÝÕV~š¾Í®ºÐw„,ÕB–f¡æžËûNÞ)«{a_.YÝÖ‡W‹+µ`Ç*.ã@cÉKuï¤í"¿Šä„¤¢]kdc}!„žF±l?Üî;{ݬÝ.¢xßÔ€«®òNšp(wµ¢¡ll‘DzÚÇ:AÝS®šiÿ^.£íرPk¦41>’ #€^õ^!µë…YRK_å ² ;Jå¶^Í;ž­C££^¬Ýwôº×ñ¬øãtý Õ“çÎ=YŽW2[«úõ ˜5ÈæJËÁêµ*¬€dàW½v€ìxμIR7<ãðñ»wî-ÖÍ‹»7“D­…Ã×Ë«éÒâ¦IݰÄIr»‹<Ðîûò¹ùµïM뎺é]^ûͺܭn†$íß¾Ñßñ_äÐÊM+OB»SºËjÜs÷’ #€^bÑëvóð„Þ·Zì“@²F½ ÞIɳO{½•Ú¯ôU·#ÿT®Fñz3q= N›ÓÞÇ®áT¯èv­äÆ \÷=/Ê¿¬ªÁà¶lîn‰‹tµUxÎ÷/Ù®½•§ºyn_ApNTwÜãfçßn?N?ŽÜö©qªò©MUêñöí[¢ÕÀ_-UØûÁ¹(:D7”«ÃÍÞýîÞÿ¹ÉíŒò‘É  6o÷O§Å–ùy­úfËɺÍ&ŸÇA·­8ûrôx=XÚ}ø§ÃàT,¦¢53à_ú¹#""""²5ºÊÓ¶¤¢&,ã¶´<½L~•vuþ'"ïZýöìT¶Dõ?,«MY}î&"¬¶úMy#Šl1쇫q|) /•õ~A€þª¿½sÓ£ºÓONuuùeŸ>{¯ˆ½¢a1\ ³‘s¥Üªåí4æR|Üý¬·JqÃ<Ø9íã^ÜÈ“sv;½u;«Â¿1¬–Û}MžÀ;e悆àÓZ‡º¾¸ì ×ß°oQ_Þ©T|)å†HOÎÉnJ~™f$vðuõežŽÏ@[ÏûñJnUŧv'‘›aáf„ù—u³5pƒŸ¬¡7íÇ‘|9s’_èsGDDDD$  8”AÀ gËx1Ý‹ÞÖös5êÂúÜVûqstßÞöÈ»Žiëm¯_ßѶóÿžªn˜¦ƒ;“·¾_¸o¿^7eêÔ¨ì#^ÙŒ)oÓýs¾Í^ææè. ä–RwT³!òÏÕx*Á¸çw­ æñSr´wóƒ4ø(ØJìÍÕ÷2Ti»¨¥7.ÅU½Qô×…Í5ÌHÎí¸äâ´ŸmÎ6ÁùPºÓk¬rsÂO•jø¡ˆÛusGé;²\ïÏ÷˜W³ë2¼À玈ˆˆˆH@@pƒW:z‰k;Ÿë¿³L¸›V`ªý{“¦ß«ž7[~ë×L†×r6p kiw'|2® 6¦Ú‚GoŸìts†÷nz´·ßÅ첪ü¸›pÑFÃiÝiñW“äÃ(Ž©6úÜ ]p¯´mö^¯t•¹ž©·?OâKiþå¾5¡®?Ÿ^å~+VÅí÷¶dm×ÔSß8;~©  ^Ÿ¹…®§zlM.¦;ÄÜ.šÁºØU›æN-?—ñîõƒnSvE½@Œ:ÚF·÷ç.ð÷ Ì©ˆm¯ÄF™z^4ZGÐÖùãFýæóÙ‡E§ÅžÉôöp=‚O†gÀÝÕo·¬ï¹íßžá¯D¶^ë{ªùªi¶ ûAÏÞä·£ò?UÏá玈ˆˆˆH@@pÈ‚€ºøÐÝ*þ°¬n—ÅéiᣠöËÌ¿“¹ ðy¹!åí´]¸.ZWÝýs/H×esG5›íLûØuhµ%«/Û¾n§ÊWÕþ«Ó5r³’›a‡m÷UmÔª½õ½Ú~ý›3¿îš6ôd*‘¹©òýOƒ©„âtß~cÂ=Ui»è˯F%}þÖ¼¾h'ù›y~¯®ì¢ƒ¢úJ¹#òž;´KÃïôL '{"&ˆ¶zÿ´ª·ªrÝ­Ób°©ìÂwÌA™sèNËm{Zä–î¶s®pÝ-µàµK ¶ÛOÅíFÝiìŠ6Ù)š{m¢aDÝÓúNi' |ØÌ/ ܘ>í/ô¹#""""¦ À”|§¦;ʧî˶±Üÿ¸^æÿpµ‘ ®÷ãC·X}Û_Öýñ.N%ù—J*Û)úû,èæáOcûö]éÞŽ¿nkìq{¼Ë;ÊOƳ’Ò•î2ŸÚ»Ù%ýº†ùQG}Ø-ìŸÿׯp—.ðÂß*×1úr„r·ï_Ôír‰SõvS~:Úu’}Òž®a¸0ð÷a<—á”›M0šÞoOLðWóvÁÿñiéÞ••Ó³?Üb~ïö\rñ"Ÿ;"""""AAAÀ¡[#`/õ 6íë{zñ[îíþÔëq~ïãFú{ñѶ5üÂ…µ¾£õ.çäd×·t‹ξxô¡Ì¿K >Ù5|y“Ÿ""""AAÀ ðE²×i¿~H¦ÖÛåæ¿;‘ € € € —o ØÌÒõæpŒv+O×iþGDDDD‚‚‚‚DDDDDD‚‚‚‚DDDDDD‚‚‚ d#àªJ6‚®* d#ઠd‚®*J6‚àªzh­š¦ÑúˆM#-ËîÞ±ì[겄½ú .U·G •ærž>3æÊæ¤P²pUÁd¡$"oDVÖ‡?;?«–ªê‹t|ü¾X¦d”Âî¡Z¶ºTý^.õ«=äpô V½ãóÒ»Ó¤%瀒 €« ÚZ©N£¤°÷›~b*¦´9G%|/Èå’¯ô³­µ^¶‡Àv4K–6˜xÅI@7¬Ü÷2IÁÛQ±çù…TM%Ì•Ý(Î %AWL¡©ç…“…¤V•È2Q¤âR7ý^wŸ7J’ÐúÃ}YæQA”õm¦1 ÌQdqÐÝŽ39¬UÕïõÒÐsÒ˳¬×Ë«}{ÈÕ òý0Œ¢XŒ-Ó 0¦½ÔíÆïÝ®•¬¥ðÍP󲪪Á`°w€ ë"ôÍÖà ÌÔs]&æû¯(¯Ú§QwïßÓJ-5&‚]˜Ó㇅=?*³g&HD5t‘ÃûåY!ÍG2©ßŽ*ßv »íÝ>nNVØw„qšDv±Ø³}C׃r–AUï=*xþð(ÍõÉH(Ù¸ª`T\›‚ßöùT=Vvwp`úÍUæ*Î$ï—…hkâöf{åªÚ kõ…l‹gû„Ÿ”•”Uá¦ADm±Ü”yE¾-ª£8Ž£0.÷÷¯›RôE/œ>'ªŸøÝ>Ë2ýᳺˆ½"±gÉ­efGdJsÛÊ^„ÛnÔ¯lì ÊžÝ€=’ÒFáÌD†ÙŽYÚ9 î]•Âf~Þ>Ýž®8/e-‹,Ú`{éÂM*‘M-Ý>ºé »íÝîƒ7g«*Ú›ê‘[Q·ÓôÍk•2ï-܉ŒëQ¼R¶ë,,õm:“ö+;ûBI;g!.Ÿï¾wUWnœ•yqÔ®Màš&Dõ’Wõoìgë ©šA5€’ €« l×ƽÖ~>h¦c‚¸-8ëƒ3bU%ãû©è¹Çý8 ýñ:‚Ã%÷º'“¼lï%ËnµÁ1ý}î€×É\{º]Ž®rï ݺ­~£Iµ]äoøŠ$—KL¶Ðn-ƒ ›\»Q²QGØËÚõ mc¢µôº†UŽ=lÏI·~ž®'ûùý0-å¸N.Ý—¤¥ZîÊg&^ŒÖ\\´÷ÿŸŸjàŽ!’J¶+U¾ì¸Iqô‚^ɼJ6‚®*˜(˜”eq¥¤bµÛjq»¯"·Ôs¯zÈ/ú¡ìv„/k×»œ”&]º`òÙå ¿ÙÓÞ^Û„”l\U°kélç ´³'(Ù¸ªŽA 5÷Ѐ’ €« (Ù¸ª€’ €«ê€qñMHÉF@@€ˆˆˆˆˆ”lˆˆˆˆˆHˆˆˆˆˆH@ˆˆˆˆˆH@\U¿*З•º|ˆ~¡èfMÊ‹R®é1žËµÌëO]ž Â3µ~íǨ?í1Ö—ø{†ˆˆˆˆ‡=¸,"ÏóNTúPü*¹\$oyCüüâ›O%äÙápÞzÕçPŠf7¯ÿ“’âäðŒÿFó÷  u ªw]…wRŽ àbàyÙà[ë˨(ՂצØ;󼩣Öò]‚DDDD$  8ìAÀZìyiÿ½È;9SÄjuAdïŠòâÁ)üªþozéŠçyIïÝ,{·—½× Ûªþ™ »e}2/»6]Ÿ ýAðvY_ªú§}÷|¯\۵е¯?E'ƒð]õür™˜ÞŽÂQ~Á¾@]H£îƸž®ÔL‰~q:¸\$'}ÿdQ_~þüRšaœHąѳ²x·°w"+–èkP«‘ÿVhÆŸm¦ú#Ì O&½3‘;¼¨w^í=¹ 8'ÍA…½Uóé§Á‰0z; NäƒKö4Š3ßu7¤ãÑŽ‚€ßxÞD ÍÛßê¦*¸á™-‹êÒèúÉâí¶‚ø]©ÆïéÛÝã¡9E+“ Ô¼ê‘ € € àH2?áùgõlk-ã®L=0S.òwBWЇÑJ¿Fï¶³åËÔNˆ²sR^=û‚ +Ý/öÅo¢aß~OœM/»WÝúbÙMÙySˆÖƒ³®(~»_ÙUž1?‹ò‚”çSSćgõ^AÀYžµÍ ò²-°Ë³i82[!ÇùyY_,2[Gb¿,@PŠ÷ÜÑMï¥ÿN{x©8_ä6%ɪË{ÞÕ?ßF™ D.„}»©ó®z¾õÎVòb)N›ÇE}y¯ àù%÷27½VŠß„öÔu¡‰9üwÊꢬιàí¶à¯í,ƒ“¥\«åª='Ó‡sð®:DDDD$  8JA€:oJ®¢iûíOÈ™ÛïY{;÷í6e`n¨¶'ß‹‹ñ}þ*?99ÓAØ üeB_0erZ~ÐÖöæ­½j´<Þåº:ßgEÿ½žÙe°O`wí·AÀ°öÝ[Üf½øœÚ`ý ·EóµÌð곦Hž>–5³µ¤ðóË"ð‚ýÖMÐn2H©F ¼5Уòkeñžgû.ÈåÞA@÷qŒŽÚì½]µ¡]S __jQU¿±Q…m:pÙ“·2kJ]RÍ‘ŸS‡àªCDDDD‚‚‚€#¸’Ìë™Ê6³·…Ãp¥˜¹¬.¸í¹zÛU§S%«žª–/OVãËX¦f{ïêîÞõ;Ã>üK6P°7ÏW’d%ô— .ç»–A@äͳ²Léëêöé ÀîwtøKÏŸ`Ñï]°¯·)Âù‰Û»ñqòNì:/ö¦Žz¼w)Þž?ÂH¬µÍñä£Ái9;'åó € € à•uqÚìÜõ0´‰€LÝ6×ò\¯¤ùùV•¹Ž=5yÞÞm¿âMV§/<¯ß³w³åS-GýµÉz{Ôuß+]U¿ÇÀÜ®G«zouÙÛT»e­»^/wÜe3Ë:Úþ‚© @ì¿â@mÆï½SÉsî¾ýå‰y"£:ÿƒxÙ À6\ʼnïím7ÎîІGz¥œƒ5­/5Í¥Zž3ƒ'|P¯:DDDD$  8*k ;ÞÏúÞ[¢Z›¨¾.o¶¶ª/V7ÔÁY]¨ä°ÞÞ«K”•ºT•îKâsÚ5ºK¹š˜‰U)/Vrm¹ò²ý>Åéõ¶zÏÎ×u7ÞóOÜÍ^*;¾˜ùႬ/Êr/8]ÕkUÑ~5ÃÛ•º<ð ób3`YsSåWê=GÕØñ_l§ôç¥=üÚnꊪìmüX\У›íÑÙfßlÔ•0±Ò«Þß¶³÷+·‚ç%bµÛKíön×#xg`F2Ü{;Í!Hß«›µv±³w5l.Ò³²¹¤šîŒµÓ7Ü^NôÍŦ/«ú¼ÖÑÍk8 W""""µ  m­Ÿ¯¾¤XiËÝú üiëç©vúnlzM$'F†é{jÔ?Ųå¥vsÚ»uï†{d£v÷“½ìø‹s{ÏPÕYø–ÐýÔõí›Ço^KyiÏ!­%sönS.kpˆúr=ɸ‘aw+71dreAÝœÍY“3IhGèn×÷2>ÉÃÛøU{؇Þn¶í#.µØ­Ô˜äç•nㆩÓåW|<¨W""""ÁŽ€=î_>L¿eºµ÷^ÎÖÏTw»xÑüb··t‹¾¹`E©Ë»Œê—œùÝŽ}î©ö>u¯:DDDD$  8RA""""""AAAA""""""AAAA""""""AAAA"""""P²¼FDDDDDÄ7!%AAA"""""P² """""A """""AA """""AApUàÒÖµ|*­?kÎ""""£  ùÞ÷&2ÊÂ×\7õ³×ε̆ùG•æS@DDDD‚‚‚€c´a^>®ªÇÕà'Y×üªz­êÇæü¿±R\?¼u‚DDDD$  8nA€+õ‚@«Ç"ûQ>=fmõ@|Ó6JøÁvà$¤=9uñﯧÅÏæçAöµ¬‡I¦ž×E²„ÛAð‘y}“Dëæ‡X<^®jJq9QŠ×ÕOeùã´?Õ»×êºþ>ô·£ÈŒá_Ì`J;˜¯£p=ÊíT•En`vl©킽ƒýs|„ÿlw§~Šü‚`[Tφ¯Vdÿ0ìù‡B>ã¯""""ÖŽ€Q—x^ý}òÙ2n?^7umÏIV>mê§"ݶ?W6PòÇ4ð‚ì©+×ÌíSöÌÈ2 mmü‘ÿÁž­èŸEöõ~'­VõϵQ~ï{õ¥û¹6¥u-Bož6‰Ø-JȢܬŽµØ sÆ×}÷Qzëf®åãv{ ‘ € € à€® Ÿ¦ÑJù³ROElª»jül•­»:ôky¬‚ù[åž6ê™V/EV ÏI-Ö}Xm^ÐÝ̾—IóÃϦrÎíý½ƒýØ_PïÔ¶fè9÷íð7[KË¿·¨Cot_?«Êï…Èú}›VùÓ=ƒãÔ#"ð|÷–60Š‹§ÝÔc³5?ý‰?lˆˆˆˆH@@pØ‚€¹z²½û=1;àÙñ[>ð™ËDFl÷‡·¾e>ÚY.¨sÔ®Šöòî‡}Ú(†õO _F/f?”yËÔ¼ê_lG€Øö¼?4Ã4roâ?$ñ×æÃ ÷ ¦©EÐeÓ#C¢giIDDDD$  8RA€–ß'ñ?¤ùǪÞÓÍO™xlÊò¦ù{S?¶wÒÃîËd¾î oƒëêŸ=o» †6ÝëKµQÌ•âZµÓ¦ÔûnªþwS˜÷åãÔ”çýŸ'ZÆ/£îöþÌý9xƒî‘g¦úÄÓq—„[K²ëPÐ5)""""¾  .ÿÒ?ÖÍ3Õ<Íg§ÔÅñ\#À½iÿ±²wìŸöLeÿØuØûíëýêçºú¾½Ù.ªgª~œ¸Õ͋̓‘©œ]þÄ2{{…//é[jÑhbG{ Yù¸®‹ÔÎò’LÚ•lÜPUOe•ùÞGb`~xÜ>ÞŽŽÅ^ÛŠ¿ÛB}ú vÅ/\Ða©åç>ôÝÞòK¶†ˆˆˆˆ”ltDDDDDD‚‚‚‚DDDDDD‚‚‚‚DDDDDD‚‚‚‚DDDDDD‚‚‚€7Í""""""¾ )Ù‘ €’ € €  € € €  € €  €«êWú‰jþÖ¨‚_UˆˆˆˆˆH@@păYüÑR4OŽÜ¯ž¢ßûFj~#""""<ÿOÙ¿oêÿDüUé'úhþêyx^.Ÿð[‘ € € àØ:7Er\ü°ðY­r‘ýI”J@ Hƒ÷ƒàZ¯ü¡©¾ }ÛÂö¾sÃ{"‹?][õ¬xÔ¾EÉ|P>4/Œòïª* þ*]˃®ÿøï‡éŸÍ{ÕàO¾-w*eßR¿wÿüS­þÖOo» Þ.ë'ºþ6 ®…ÑN/Ý´ù›…Ü&E=x¹qzþµ0x?öØ»ÝupÛìżÃ柳ݑ=Tüý@DDDD‚‚ x)A€–]1½é*ÏßWÓóʸ«««ƒÒW_”ý‡½¨+÷£ìa–\ó¢oM9]e×Ì#qþ¬™­Ÿ#[r?)bo÷ø>×DzÍó¿Ñ¶,ÏEþ{óTV=qÙÁw"ÿc[¼{þ}!þxï‹ú‰yKÒ>þ±,¿í)ûfŸˆD? ÍËóïêæ‡°»ð³|½›]§¡Írñ'û_oS;kƒvDDDD$ ‚€—¨²]`³ßV¶Þýɹômumž=Pìkaêü÷û“µ±«·½øÏZ?qþÍö9xTÃgÍ¿²ùZº~èy£JÞna¢Þ~™¢=ùVÏîú¶çí4ã åÚ>g¦m¸­›BéB–ûU±÷ÞkqÍÏlT!/Èm–‘-<"""""AApUý‚  )wLÅܯÝ?›ï¼¹šS«â - ó®Tž "oža¨¡gŠüQ7Ä7ã[ú3¯±ÙÁûó}R\óü‡zù àù“JÜŸSÚ´÷Þ‡G÷dŸ  € à¥N (Õâ;çZþ9‰ï§ùwúÀfäQß®t u;þ'ZO=+ã®ÜŸzyË‚"ßvŒ‚{Kÿö~AÀßDö°n¿š±ù¡èݵWì¶w{tù0p³r‚DDDD$ ‚€—´÷ÒýäÛFefÆ+›ñÝìâ ­  )‰ä}/yh~¨ªGªØaç\ƒGJ²ú³›i¿îÞøƒ9Æ0sõûvAÁ°]±Ï… i?oê< Ûår»z_ý¨<ô½÷ÍÖd•Ëz´"`!lãÁýv%…öV¿¨þ¶÷é5» ÒokõD›3Ü»6=³`vïJý`.zh>{DáCív`üADDDD‚‚ øÕA€­H¿õGëÅ£éNx×Öîÿ¾>¿Dº¥ 'ß*×?ˆøýÑã~øûrbIÿº[ ÁÕÛÉ7R=é ûá[‚¨ûv€JÛÂ{Šaÿxïá·ÚÍêo' Ôz¯ œÚÖûYùÃ8V˜ÛûÿúÛà ÿÚOì³¢þ›‹cÎzˆˆˆˆˆ‡<põê¥ ¥?uˆ~Ët‹î2]_/:÷–W;¤=öª÷ŽˆˆˆˆH@@@€ˆˆˆˆˆH@@@€ˆˆˆˆˆH@@@€ˆˆˆˆˆH@@@€ˆˆˆˆˆH@@”l\U@ÉFÀU@ÉFÉFÀU@É\U”lÀU@ÉF\UK£¥ð¦RsZ€’ €«êhÒ”©æ•´TýÄó‚Š(Ù¸ªŽµ½PLæZU"ËDI“P²pU5šÔó’²™|¨ŒÛé´ %AWÕÑÂ-àÏüU¸ ¢%(Ù¸ªŽƒÔ›™ÐJ%AWÕÑBËhn^€{¸Hâ8ÍK² d#àª::¨Ao~^Àóçº` d#àª:rè~¸x^€. ðÓš“”l\UG( Ðz÷§8=@ÉFÀU”l\U@ÉFÀU”l\U”l@ÀUõòù"""""â›’ € €  (Ù‘ ‘ € ‘ € ¸ª~q õƒ¦¹¯ô›ùÕ ëÐ_+ëW¹—²·ö64¿ˆ Žw°Sf«ÞXl½ @Þ2»îUË•ø¬Ø#5ÐÛYïö\Á¿#³“Ï– ÔV–½®Ô`ñ€ß¸;Eï39‘ ÕåUo‚@lOç,×ÊfÁ‡R׳ò¾ÛKnÖü]DDDD$ d# xÝA@ý…-Âm©¶#‹kæçz5§”w—îGؾççÛ»>k þð ½ ï`[.Ýt åMÏ[‘¯£Eb׿Y¥Xõ¼µZÏ«Õý~Ú6k¬vó&ÔVuí~xm¸]OW{ã]ô®î£)‹›Q`ÆÙv:ìÈâ³ »»&+¦ƒw%Dâît4pÆóoÙãÕ‹òµéÞ²½ à7O„·ô‚Œ`Á‡…ˆˆˆˆ@@ðŠ;ÔVhªÊøf%7³ÈÔeW'oê–qW(VûÞ×ۉߕ•Iï³¶Zö{®ðVÛ}q3êž\é‰[IàÅ]ŸS_a;&ÙïºÐS±Qä®&wêþo†© s§°¾®fBŠf«/nõìqÞœxñƒ~Ò–ô«¢ÜÈã•áaÞg÷á‰nl;Âl$¼)›ûrp+ô†ÔÛ"=Óþ¬ë-‘_ë¬Ìã¶nOr{È6þ·ÌyÆí ¬ä†È¯wçÒ¿"„)×WÚjY•×=oM”[Rn¤ÁøØw;]æXRwΓÞõ$ô†kËû*;cïÇç²Þ.²5oº†¯ ³‘•RÍ÷Œ¸2P;³­ s×Ïðk‹›ô¶}G²Á_GDDDD‚  xkü®'ê»dsªßÛ•‹¦ø\¦I¾¶õÞ™²ó¶˜%¶„ö¯î²íp:0¬y$)ïšç'‹góÏ]¦ÜMl5¼±ËðVÛÚÓ"ìÚÝ€õv01·lÁ|ü±“›=¾%ëûJí4r#ïoOlj”2LŽ{|´w{Z²?ÛÞoÀ¶Bö“ùù;uµÑ·Dÿ‹žn0:œÅ§«à0ªç½•î-ڎжåëçý<˜Ê#J;¬ëÍlóÈQ|SÖ”ܰñ…ÿ™Z0›`u>3j×€˜þ|'¦E·˜€ˆˆˆH¯sj€-ÒDekÈÚÞpžmÕÖêÁ’ušmŸ,êÜêÃ[Óvb&wvë&f Å©GÁ ÀÕ·¡ØÞuxÓA€;öÕ.›ÐSaDÌǪºåO¶#¤Ýw[rÚ &6åJqûøhï2?3v°=ü•¹Šúp‘]I’+¡?QBïrº\Ÿ\wÓº†È›çÊðx÷¯Ïݦfƒ×ê?ÛGÐv˜Á¦ƒóÛqIÓl""""AAÀ+ »üZ=qcy²\×òv_Ió¥ÖÏo——ÏÓ«Äí¸[èbêÙɲÜU¶b:/Ø{òÓÅ­®'«ý©1¸~u.؈›ƒzG«ûº/‹ë£YîõÂÖM°?îߥ$ÏÛ ß/xn û¹ÂUûÃ`åwMqe"×X|ºÚ”§?|¼H¼QG€ÙTÔ·s†þw´~õ ƒ€¦¼æy+ ›Tî[!eº ³ € € àUv¸öø´Ø6aåVÈë×;Ó3Ø—[#`8Üó¯ôËÍR\w_1wSÙž‚»Rn&ö» 7¥Ü®ä]=ž½·ª¶åà–[gnCÊ-Y?ho¼·ße¨Ýýd;ŠèÖpž~dªçÏd}W¾H‚ÉeôtÚïÔf³r[ØÖJ3€jÛ}C9Þ5× qw´Ç¨Ý£=-®¡Ünêí~vuXð·òµª~`N—t íÌ‚¶äNû[M½•¹ûövSúA%Ì{¯Tj§MIÌi´?D·†_‘°`ÀªÞ®ì YƒmYu'dDÙF]o—nUÏ¿6p's÷Óõ skÑ•n]À®¼w‹xgÌ.”z «Û©ýçxÍ;‰`öFýN™_åV£4{M 8óbSB{‘05‘ ^ç;ƒ|m¼DÀôÝié¢SpÖËv¬öÒnkAr«ý†¹éEæ¦b7}Û`ïêív•¾z§¾½½ƒíªôѲ~tµ”ã[ÍnuÃéõêšÛóMð¶7¡'ïV@¨§÷ØÕ½½Ñ°W’¼]‡ü²nHÙ¨WâˆWºïö_ý¿ÿukøº[•[Ï/Ûuqu²*žðì.&8Üd£Ojµ—]u“V¥Þût=(ÅgIrµ'nùÄ* úîhÀíwLžÆÆ rzy¿2=31ª«•š«ê#oaŸ¿KˆMp3º%‘ ^WЖd”z Þö×Ë~»[Û{ÿÚ~¡ØUîž/óùéÖÒ[p6º5ö I¿àQ¼è€ç‡´´U¶2ý½ ¿ë \~’…Þ1׉R»~}`\Ü{êAÏö{Ü^ðõƒëÓ(ˆˆˆˆH¯-øõª-·þÜ™4»Þ[nMWcÛm~ˆ¢Õ¾ŸGgÂèJäºâþÝ%ßènã¯Ê¥sÊÎ&¸ÖÌWûÕxÅL@ñ݈ˆˆˆ”l‡7ÐÍF_MÓ«I|%N¿x“Ë¿éí,½Õ¢ßŒ¯vÀvn’\M{Ÿ•ÕÝ{cïú‚•ÿv{qv½lÜÛoÊ›y÷½†3ÞÍÓ[5 (ÙkG""""""AAAA"""""P²%AW%üJN~{òþßÿp¦X3%ç à%óÕ÷_ýëÿùWÎÀAãÿ÷?š’ó@ð’ùïÿùï“ßžì zôLöOå?™bÍ”lœ ‚€W’|õýWæ ózˆˆˆˆˆˆøÆ5š)ÓH` ‚€cAÀ1‚ àApŒ 8F#ŽLjÿF2¾s²¶IEND®B`‚Cython-0.23.4/docs/src/quickstart/install.rst0000644000175600017570000000421412606202452022316 0ustar jenkinsjenkins00000000000000Installing Cython ================= Many scientific Python distributions, such as Anaconda [Anaconda]_, Enthought Canopy [Canopy]_, Python(x,y) [Pythonxy]_, and Sage [Sage]_, bundle Cython and no setup is needed. Note however that if your distribution ships a version of Cython which is too old you can still use the instructions below to update Cython. Everything in this tutorial should work with Cython 0.11.2 and newer, unless a footnote says otherwise. Unlike most Python software, Cython requires a C compiler to be present on the system. The details of getting a C compiler varies according to the system used: - **Linux** The GNU C Compiler (gcc) is usually present, or easily available through the package system. On Ubuntu or Debian, for instance, the command ``sudo apt-get install build-essential`` will fetch everything you need. - **Mac OS X** To retrieve gcc, one option is to install Apple's XCode, which can be retrieved from the Mac OS X's install DVDs or from http://developer.apple.com. - **Windows** A popular option is to use the open source MinGW (a Windows distribution of gcc). See the appendix for instructions for setting up MinGW manually. Enthought Canopy and Python(x,y) bundle MinGW, but some of the configuration steps in the appendix might still be necessary. Another option is to use Microsoft's Visual C. One must then use the same version which the installed Python was compiled with. .. dagss tried other forms of ReST lists and they didn't look nice .. with rst2latex. The newest Cython release can always be downloaded from http://cython.org. Unpack the tarball or zip file, enter the directory, and then run:: python setup.py install If you have Python setuptools set up on your system, you should be able to fetch Cython from PyPI and install it using:: easy_install cython or :: pip install cython For Windows there is also an executable installer available for download. .. [Anaconda] http://docs.continuum.io/anaconda/ .. [Canopy] https://enthought.com/products/canopy/ .. [Pythonxy] http://www.pythonxy.com/ .. [Sage] W. Stein et al., Sage Mathematics Software, http://sagemath.org Cython-0.23.4/docs/src/quickstart/index.rst0000644000175600017570000000015412606202452021756 0ustar jenkinsjenkins00000000000000Getting Started =============== .. toctree:: :maxdepth: 2 overview install build cythonize Cython-0.23.4/docs/src/quickstart/htmlreport.png0000644000175600017570000010655012606202452023032 0ustar jenkinsjenkins00000000000000‰PNG  IHDR²2¸«¾sRGB®Îé pHYs  šœtIMEÙ   #dKbKGDÿÿÿ ½§“ŒèIDATxÚì]XÇûNb×{‹ú3&1jSŒcbFŒ¢bCÅÞbE 6Št‰(HS@ŠŠŠˆt¢H©v¥)VŽ˜ÿ «›ûßí{G¾÷ùž{fçfæ›þ½3;»ûÁ¿@ •ø€ª€@ Â|ð-¸}3‰„„„„„„¤iŠ¥)Ñ¢$$$$$$$D HHHHHHHjž rç¸î5’¼§íØ»Jýf‰Æ #¾>—ü}/×$-`ç—z¤µªº!L {'Z@=Š„„¤^$!.Òí¬ËÙÓN²Ó‚þ?ji¢ù@<§6ò¢Ô­[פ1Bþ1Qá¿ú*:òZ=NÓ<‹S/S¼`ë|òIû‰Æx7Zðê%K²õ¢$$MYœìO»8&'ÆÂíêì7CàpqvšÔÁD#³9”-“'OÚ«µ[ÈsÛÖ-sg×ïê­ÓÆq+-ñúµµkV}óÍ×Mp·@攉Ô—Àü_¼pÖÇÛƒ¹LLˆÆï%sðd(BµhèN~ZJšÕ+:wîܺuë©N‰¨©ÔfÖÌmÚ´îÚµ‹ºÚV!Õ2¯Û.œ;ݯßÿn¦Þ`}R’âzöìáës©Êrýï}/_ºÀ8¤§Í8àÿœÜY‡µÕ±¾lÞ¼yïÞŸjÜËYê¤1 4WbîœÙìFìÚ¡Žr}øá‡Ã~þÉÄXŸUä×½[·Øèp™3 --[¶”œ cçÝ\{ô衱k;ã ®Ö§OŸ-Z Èà¶zº?û¬Ê>xð t_&J ¿÷¸q¿·mÛÚÇŒ ‚"ZXq*D+³:VYæRW3’{ޏÁ(صÔTUºtéŒa5{–³z !!iÜ‚‰èœ›«Ð6ùøho/AÏ£›7m-7*48s¬¸Ò‚y5E V®X6ö÷ß0õ‡_ † U-óhôèQf¦Fì% ü“&ð)—’Ò|f§þíÚµc¦Ý½š •æ×-èÔ©Ó?f&˜»aÈgqÆ]¾lÉï¿ajé×_åV,_ʃaˆ¯0œ¶Ö–_|ñ9Ë„”ê6™3Œ4×ÿ½æ—_†I΀„Œá×ÒÂÖ똹ë‰&¹âžºUeêvÊ”?ØË¡C¿g‚}ùåö'm@uÁi–(/šþ—¼haÅ©à¬L™ûªl¥®~6$÷qƒQ°k1c ‚|®Z¹œfL’F/·Òùü+ãÙQÓ…E»5©+ûš:[€u{`Kù¤Žövß ù–½øÕWgÏ8ó)—ÅÑ`~à€Y…ÉaV{þ9ÙòØ‘êß«-W¯^=5÷ìÂ,/Á0tïÞÝÏÇ“­%Tìjh  å52<cU s[ wèð »k".2¦¥©Ýκ¦ÆrX¡ËfÍš‰f þhÎÂrªà¬L™­² ¥®‘lHî9â£`×bÇÓhÆ$!iÄâéqÓ àAIKI8íâó‡`5¹[€)[pzbvqkd·)#Ólîk@°u8iˬ¤‡&šÎr%ÄE~úi/†I·4ÿñÇ¡pÃçF|Tmì 9Çû½cÇŽ}ûöa™‡P\¡Zb-¨P0,š?ïߦÉÿ¹g÷Îê´QtäµM×1\r$d ÅY³z¥„ wéêìøóO?¶iÓF¨³‰†UÁY™2׃ ¥®‘lHî9â£`×âÌ I#¦°ý¢í!7So`REf9Qc´«Ÿ°šY ‰ànV65K °î3f4r£FÚXYˆfF\¹À!›~ÿݸñ s;bÄ/5;¹ ý{+-ÑêøÑnݺŠÛ-ÜSÁ¥¸D@eV®XÖ§w¸jf891¶U«V’3 !cX+÷ë÷?uµ­ÒÒt SƒØèp'.溸ãTÁY™ÕÙ-¶Ô5’ É=G\§åÜ-€ƒÝÌ !!i¬‚éš“¨á³[U6ýþÛ˜?/,>.yœcöØk„¬X¾몈ð·÷AEUòI{vËT†{-_}5ÀàÎàA93#®\ªÛT0™2 îÝ;zö졦ªRK´@~êŸ^žî°âÇ-Í;uêÄYê¥K³w‹At–-U§ž:÷U“ºÁ*«lÙÈÖ›¸ HÎØÕÐÀÏû÷ß¶u³T´ c‡àaèÄþÞh ´@TgeÊ\²•ºúÙÜsÄuZÁŠbÆdÜØß@iÒ$!iô‚ ÁÓã<ó+©ÉñXž;®1Zp3õfÞÞ½?mÞ¼9 -lOM-ÁQ˜1½uëÖ]ºt}ãÔ¶m[™÷ õu›5kfh ÇY@qåºxá,b1§Û0õÃ}ÑÝ­–h‰±> T 𥭵%g©ÑÒŠ³g¶«l˪øç°ñgŸõc÷en£6mÚüú«œà³.œ¨2c×®|ñÅç›7màO ŽšîÛ·*äÓO{™I¦B*8+S憓¹ÔÕ̆äž#®Ór>‰0Saºä5 Icz@ñ¼›+C˜3†2> HÒ˜düø±ÆFúTMYè$$MP\œ`þãb®3ÁÕÙ‘YxÃÁ¸ùÒ‚ê¿Ù­ú'«kif¬{¥5•OÙ’Â"òà½_~ù…àÛ_½mQK]·!¿ ‹„„¤LÀÙ3Îng]˜fB.ÒnAÓZ#öéÝ›}“„v HHHš¦\ò8çíÅ}&h ÑÉ´×$$$$$$$MVþ£@hòøo·€@ BS- !!!!!!¡#‡$$$$$$$D HHHHHHHˆ- !!!!!!!Z@BBBBBBB´€¤Š†'!!i‚RƒÏ°ÑôÒȤfh÷•3µmÀoľ†öVZ¢¨4p>H šÚ;jjdùÇL 4½4²¾Q´ÀÃÏÑÛÛ»¶ ØäM_ÆÇE5d6àáºnÿ© «Ž ša0à/½Ÿ•Lä×[šÚ]LHˆ½™z£FÈALôõÕ;ØÛÛ/ÿ¼­è¯ƒƒCà9GFõ[Éwo§Ü»“zÿîÍ÷o§?¸“‘~/3ã~Væƒì̇’õN2Â3+ã # "":©Á%@¨%`à×%-¨ãuµoõûFuiÁ9o[__¹U]j»½}||~ÿûÓ¸˜ÈÈ âââÖj9ü²è-›kVž)îá="2nŸ‰›·Óuè\£ —R“ãA¬]}~[vD6–N°~H÷ëׯ[­šŸ úk6o²“““TÌà-xË Þ¿ {«ÿ(+ýñ£ÌœÇYOr²…žøëQv:ø?`4& ¢D š4-p¹t400PÏn«——Wm·÷ØuŸfggOUÑ 8ArRˆE‡×è_Øï”¸Ü$\á@ðô}W” ¶1÷¼yÐ!ò;Eƒã–NžCç™~ö§NbBtZJ‚Œœ`éìèèèã‹þý;‘–0 _±Up7íA%'ÐÑ)gDW—•7o¯—b7·"Æ“ †(ˆˆèD „‚’’’´J7ZðÙˆQ_ñ¢5ˆœ'9ž—=l쎛XY[x\rÏÊΪZàpÁœàÇùùùu³[pÜÅèÅ‹ò[Æ4f€Eÿ=—5º—¼¢²ïYûÜq ¼Òÿ®Ñ¹”= KŒ¯ÍÓ;蚤ã3dŽÑwsM´ã@ "ÂCR’âøop‚YQQQæÓÇá÷ø‚©‚¿W¯^ů´Ì€ix¬õÜ»™þàNVæƒ B S~ôh™£cIXXþÝ;yå>öòÅó—yyø}¡§÷¦’(TC`DIx÷Á½[H„Æ$Е•õêÕ+ƒŒŒŒ†C „¹Ëëò§yÅYÏ ½(,(.ü+²ë'D joÞ¼ ¿~Íö„Õ£GŠŠ A à¶w´»ôúõ뚤6gõÀ ;hæææZºê×ÍntsÑ}þüùÔ­£"Ã-¸è2aõñÓÁ÷œŒœ½Ýù·–Cfý8ÏD~óÉÕ‡¼þ¹˜¶ãDÜ"£«»¹¡súÆa› þÞ7â£o¦ÞŠ_2322ÒhÔ¶¶¶&c~‚ûø¼É̯ŸŸß®ví*˜Ó¼É±±±ü™Á;Zöàþ­Ìô{²ÓaìõôÊaÿór_>–çâRjfövÃàå‹Wù¾¾ÅÌe…è”#JfņhAšè˜d7ÕjV#›ZÝä}©¢¦™Ã†ÜI0×§¤¤0î´´´²²²†F ¼Â^M^ûÉ0¯6?_jûó%üvûÅÅÔùNH\^yù›÷ލªª6ØÎy=⚟¿OQqé¡SQ‹´}”´}ëútŒÀ*/4,Ì ÆhÁQç}AAÆö»°v7pT…µ–[ÕÌ@ôwÜß}¤²ßÖguaÛÄ¥vÄéÀÓ§OÍœ4Ÿ={6]uP½3,÷Õô]g¨þaž©ÜBÃ*ÚÛ4tèèíÓÖÛ°]wâR¡óŒwÚF€,=¾áx´ŠMŒÁ…TÐ/O÷„¸Hž´`õÀûÊ ø5ù=ì½åÎíŽŽŽÆ£€¥âD___ÍîÝîܹ£Õ«§···¥â¤ f0÷ž£úþÝ´‡nge<Èy”ÉÜ5xö,ïå˼‹KYpèЛüü|CÃ7OŸXýο<çqVV惇î ¢D ê%‡õ[¢†ÖI0I>~ü˜q?©Dƒ¢޾y½Æ8k™\Ë|ôß Ž‹¾OûO¶i=`Gγ|¢5Öž==neQRZºH×gŸS¬]ÀÝ#—o:—²úȵ¥úOŸçÚ;Ø ÝM‘˜8ì¸r%ÈÐ^OÇ~=úßQ—ƒ/_¾4wþ=â¼?##cüß½ùï–ƒì¶\™~Á?tí7B£‘c…ö¿T]¿Z´vý¯ ÇûËëîÖ;~ÂÎꔃÛY—Kç._ºàqñÜÙÓN[÷þVÑPÓ1v½EÔ*óˆuQÚg’@ <=Îó§öööV«æ‡‡‡™"gkk NPPP`khPÁ 䆢ÆÀ =ztê”#˜Á®vmƒƒƒ-gOHHXþy[Þ´ âBvÖÃ'9Ù0öúåééùÖÖ¯ÁNzËœ_?V‡…Eù³§oé¢ búûH„?-ò—m>MLLüüóÏ…Ü ™HH«º‰'¶­¸d÷ÕÔÔ:vìØ©S§íÛ·ãR6ÿÚ«"i[ª¾Ì<›‡çÏŸ+**¢ž»víª©©Y|JÛIØôù4“TÛ˜³³³1ßÞ¿?99™Ý.++Ã%<ÓÓÓÁðW=Ò¿ë¹]åÎjùr9Ï‹òò kü&B^^ž›››¶¶6êyÏž=VVVìVJ£§Aþé¦gãõÏ܈¾ý<üæS—°‡ *¶±-"ŒÎÄfegz\r¯.-еÙ|Eß~kNNξ+ÐϘßý'Vdeeíµ[Ž_-Ûå™™™Z6Ëà{Àú599†g£Ê­ê‚”Ø­­H¡2&MV «Q×~X°‚Úײ1ƒSŽ'U¹©hÁPE#u}o/oÐà€¨È«ñ±7â£ðy=Ô××s¸’¡òÁËG¯9ù·e”¦s"h¨Zëo¡ðûµk׌G~6NÀ2–ànÔ¶…ÂoiµrøÏQýàÞ­Œ‡we§?}ò–þĉҔä8\\Ê ò Ž©Ø?ˆ/ŽŒ(ywü°ôÁýÆýôÉcD̨<^PÇ´ÀØØxÍš5Bî÷” :&êE%444~øáÆÿرc#FŒÈ¬Ç—Í¿öªHÚ–ª/ZÀæaîܹÊÊÊÏ*±hÑ"™ó)m'aÓçÓLü6€)±°¥¥¥Bw Àà‰¿ŠŠŠ ü@-X³zç³ìð¯Z°õŸÇ†«²D‚´@ª, MAXO‚`í.ˆzÀ´ ’$XÛ›89;¼Znà•þ¤àVVÞ…ˆ MçZΉúçST,®æååZY[T‹ì³\¬{r3ú–†º×.ë>Üi5ÿÁƒ;ŽÏÃïv˹`¦êsïÝ»·éÈTüûÛšî<íÄËËKÃrñ­[·ÔŽÍA:Û-*RÛ~|neúó‘4V赩øÝbÕãÇgnr5,DÚçýÞÎÎV˜œ:Úþâùþ´`»KXX(@ltxÒ˜´”x2’’·FëÄèå–;NÄîtˆgd‡C†¥¿s;?4ôí‚ÀÀÒ¼¼Š½/ Nœx»s §÷´ ''DAÄŠçÄЂ£GöëׯE‹°|±±±Œ§à«3Dß²‡žž^÷îݱ¤[ºt©àijÁ™÷Ï?ÿ<{ö¬› €IpÅŠŸTbåÊ•¸dü1EnÙ²+E¬Õ Ï;wîL›6íã?nÕªÕäÉ“Ù=XÁ,‰D‚OOÏo¾ù…™†D‹)˜~ëÖ­Ùb"‘6mÚ0î‘#Gúûû3n8ääädóª"©Ê‚ðæææýû÷oÙ²% bkk;`À&:zk~° ëÖ­2Ó‹Uš¨jqõŒ²/Y²ÍÝ£GC‡ V;ÕU6“` F‚ñ3=z´hÎN"®€¢´@´õ…ÒçÓLüI«)>!Q^¬²$ÐLŒÓÿ’2Àð7ÁJE ÞüûïwŠ~=F›KE ¤Ê’ÐäêêÊÖ³(ÀŸNŸ>½»gΜaé”8ô ggç;wîÝ»700e¬£¼¼M¯¥¥…0œÔ%Ì™-Ñ÷?x×#*Ë=2ãŸË·œN:|馵ß]Ëëy¯òŒM d¤h€ÿ(‡††hX-º{÷î–£âWåèt rói·oßÞ|¤ò÷ù›7on<ü'Ù¢C?ÄÄĨ›/v·|bžÎ×qqq«ŒGj›Ì¦‚%0éo92­BãÑ¿ð»õX…ö­òà³v~fÀŸ|°FÝÜüË ,,,0ì_å½”Š[€€ @R“ãá|³aBB쀿ÉÙ‡ü}/ó?røv·@~Thh¨ÅÔ‘ø5ö5Ë À 0)hvëvùòeæ_æWêÝ‚ô{ßÑ‚ôôW‡½aOܼY”—›Ÿÿ*$àèÑòôôÂìì‚—/^i•#Êc‰´(V3ùùùKÆ ã³[€Ë©S§>®fI555Ñ%%%°^X[ ¹Ù[·nE\¤ÎôÇlÛ¶ñLj4iº ÂoÞ¼™ñüúë¯1}`E…åŦM›”””Dg|΂ˆÓ‹‚ óíòåËÅ­&YŸÙ³g#YhG®455qÉø£\¹¹¹ìÒVJ6¡*’ª,?sæLrô·ƒ¶oß^QQ‘½Äb— ¶oß¾‰'¢ba/aã×®]+ªZ\=c2-Õ  ‚ÕÎGu•Í$˜‡víÚ ÒÎ*âì$â (J 8[_0}>ÍİFÈJ ‡äMTÂH¾‰€õÌÈÃY 7|jä&BIÙ›AнÿG*Z U–„¦ ýû÷£zÅi¹xñ¢µµõ«J€½yxxTéogg—_ ÐSQZàëëkii hz77·ú¥.§0K¯û'øÈå[ã‹iÚg“ÿñ¼åpå¾[xº†]þµ±;.#-HJŒ ˜¯ù ÖîËMFÆÇÇ/6zãÆeF#“’’VŽILL\ª_á¿@û»¨¨¨ÙûFFFÎÚûlùokzHµ[ zx~DDĬ})(în±Xot­0ƒ®†£+tƒ¥\hð|vX(!äÒÒ¦·™šš¢QÍḬ̀6*,È¿s+™ôˆ¨èA39 ÿHe3PHB\dpß…s§O9ذ³bÎx\<~5˜ÿŠÌnÖIǦ g~AHÁ˜}ön‚ÑσØ0Žz·@€¼x‘ëí]bbRneU~ölÙÇ…¨È‹…>>¥ ÙÙù))ù‡«¢˜y7²Ú¼ysž´\qƒöéÓG´Ç >\ÔÍ&õé§Ÿ".{ç¾wïÞŒ©±wî9|bE(:ãsDœ–¾}û¢Sa²æ¹7Ž)+KfÖƒ#33“ñÿè£Ø¹ŽfÍšÉæ/TER•áŸ>}ʆºd£#Û©©©ŒÖë~QÕâêºØ‡jÁj磺ÊfÌ(ײeËžWbéÒ¥œa8;‰¸ŠÒÎÖLŸO3I d +%ÑGÎXnaÆ`1Ty¶ 6:üûï¿Cqð wM--øøg·^Ãm¥¥ü³$4©«« R%vÈ’öË wÎÁÁ°|jGæ!ä²ýceàoË•kiiöVp÷vŠTqýƒ¯ oê›íå•y1"óLÈý‰ë¬4Mœâb®§&Ç#q8®_ ¹qs¿¼×Ì…ÿV»[pìaW®\9öÇÏ '`Î`œ ž30úé+&Lpp°ôg ÞÞDpq)ÉËÍÍË}•—›ï^Q||±¿)TÍ$`ûYÚ$ 0¡©_ò‘Èð1cFã·‚“ôî׿[ëWÿowýuù¿¡IÅñ…×RK.G¾wá!ôz˜\ŠÊZw,rÕ‘ˆ­6±¦ç¿™¥¯kbrÅ?1!šùösü@ËÌí³?u6pcv·àèøï}||vµm ÖÏrÃï?g™åÎí666frƒ¥Ú-z@U˜œüv{„àIN!Ë àyêTYFFþÿ{@±â½7ùÓ,ØýXÑKÃb+§òòò‚}™°úéСCii©[PÅ–-[Ø “'OVQQad¢·;wî|þüyÌž¨Þ¹sçò·7â´Ì›7ý¿¤¤mÔµkWÎb ¦óÃ?°O"ìÞ½û§Ÿ~bü= ÂY‡ƒ=¿&•¿¸*âYž¶sâŸþyûöm¬³ÑcQ¢ªÅÕó¶mÛ˜gN“Ô,-ÊÃòåËÑú………çÎûßÿþÇ´ˆPÎNÂY@Ní¢­/”>Ÿf’ 2ìr–y]Ú v¼z¤™OŠÚ =±:—,”ùÌgå-ÿg``u¹iª¶3'Ì9*y'4;Ÿ¸»»cÂdÎXYY]¼xQ²•g @A@4Á +;;ÛÁÁ¡0ƒc–Gnß¹õâÅóüü¼—/_$§$›¨oßfes줣­ 3ýuFá×Â&oþüÆ 5GamºAo&lÿ¯«» ýŽ^Õ¿Gœ4ù7jtÔu0///ÑÔð –0I¥OTTÔí©þ{­ªßwyW옜¹úPýdœŠuìRÓð]ö ªÇB†(®Ð°²sñ ½z-äjøYÏ =‹ £—üóý\ÓŸ™ëugÎ'òzÉ´ƒƒÙœIGûýU«gL©àè£GûÑpH0p‚S§N|Ó>–s'‡‡‡¯ØAæ×ARR RS zsáBéãÇoGEpr*{öô•ßÛwJ÷:#öòÀü±¸KÁ'”••@L˜3gÎÀ€1>‚nA˜÷—-[Ö¾pà’=N¼iÓ&اN:1ž°Ÿþy³fÍ`'>ÌŸˆÓâää4pàÀæÍ›óÍ7èÏœÅL}{ìØ±m*1nÜ8vÇŠ“NÇJ¨«« ¾Ÿ€¿¿¸*âYž¶S¡¶¶6óÀ·ß~‹…š¨jqõŒ&^¼x1ÊŽFz¡ú´@(˜¸?ýôSæýX`pö"ÎNÂY@Ní¢­/”>Ÿf’ [ ,ìQÊäJ°«[Lì8ªß×…ÅåtøÑ¡ÝΦ§3 Šÿ»ñs÷u«ÿø§&w ;WWWÔ3˜7ì={€­Œ¿4*Ë¢$ø£e™'0Ínß¾]ˆ ˜w$ÆÅÅ5=P+ÁA.§Ì™99;ù‡††,]®lh|ÈÚÖ‚aqq±ÿVóåÇ‘×&nè«´[.11±¾‰f°æÀ4p‚e{+Þëg`§Zï¯8dh}à=c·Dãó)»ìã^Ýd½Ã6fæ·1+­¾žeô­¢ñÏ ÍG­´°íâÔÞßÎÖw=㖚ϓžsD_4›[É Æ ¾pá®¶mÁÌäççÇü~ÛÝ]p_¸-çþN°~H÷˜èë²½ü˜aåÉIÏž½zþüUÎãü#GÊâ ÓÒ r_æ=ÉÉ51yÍçåDz¡Êç¿W¯^mbb"ê&TY]MGµTy¨í|ÖA°„½wïÄ0{™™™eee¯_¿ÎÊÊÂ%ìÙýû÷Ù'*ëýåÇ/òŠíÎÆÏÛäÿñw'Zpè=ÞªÏDëog:˜÷ºŸžóïûð–ÃÇëèè¼×ÓBll à ¬l,lO_½vÅ¿ÕÿTRLÅʾlÕª}òuðM„ß×öŠ_¨1ÆÇÇç¨ó¾†ð‘$†ìµ¬p軹Æ;l¢¶ZÇÌÓ w(l©qø2ãð%Fá …)잪8E#àÛy¦›4ͼ<Ý£#¯ñß-bà¨móÑ•œ@à÷ð/_Vp‚9“øs ŸJb˜‘QyXhA^ÞËÜ—/Ÿ=Ë}ð Ï×·èòå"®O%ݬÁO%UI °âLJJuª¬®¦£Zª<Ôv>ë Xª‚¤§§úÂDÝRj ŸJªØ€yó¦°¸¸Läé‰K °C}‚`Y[[³‡I3ÐÓ×Vß¡öo|X9.6jÜߟ^»v­nv Õ†ùøxÛŸ7i ßNô ð—Þ÷І–nÑûz¦þ*£+ëF)é‡)–× š¼;ð€ ;ýÛæùÍ<³_êr°»è+Õ“œ{`¢¿Òr>V60(?®ÈÇ»à¿Ï#Õþ‡•ÓÙ†'j$ñz¡R}U¹ÁÒ‚--­]»v:uª¤¤¤ô´¸¸ØÕkW€0ï«ZIˆ»îÓºÙ-38ãeÕp>©zíú¨Å‡-í\Ϲ¹žwsÝgd5hºÞ¨åV3v_žµÏ_aÐäÞrÏ}¯lûå_:³×j[Y[x{yÄD…KµUÀHjrüÅ“è‹fs&%$$X­œ'ú Nð÷·]¯] ŽŠ¼ŠðÒÑ‚;©÷ïÞ|XÉ ²2<ÊJü(3çqÖ“œl!'þz”ž•ùýέúª)ÐðQ/´ n„¦ éեĄ˜‰þWÛííëës)À©p‚·Ol¦$ÜˆŠ¼~5˜ùu;~Æ‘‘ õ¿UÐí/¯3pºîðyºÓWikë;:‰À`ó‘‘ '@úq1fúöööË?oËù»r@û _0„Œç³!Á4ü[É,3ÀÒ?ýÁØûÌŒû0üÙ™+$ëd>„'x ؃wœÑ‘IhÑ¢ÌKâj»½¯\½Ô 8ûòãäÄXór‚¸˜ëa!Þ—/ºuqv²wr<áâìpÞÍÕÇÛãjh`|lÿ“†¢¯j†¨ˆÕ‡í¿~-*ÂBƒ +òzX ¿wB|Ttäµ”$)^ŠP³ã–Æ$@´ iIõ¥ÆhA“Á °,æ?*ò*Ìöµ°+ø…©Nˆ‹„¿ ÷ê€\Ó¸%!i‚S?€á_}‘L ˆ„½§Ä‘hAÓ·BÓÄ5šH«u Z@BBBBBBB´€„„„„„„„h ÑÞ´ FN¨’¼§ò-ø€@ B“Ç[Z@›'$Mêém¡)<†NB"Û$I´€¤ uwª’¦ ôj’ ee¥$$[ˆ4ƒcT$Õ¢˜1CƒýIH·- !Z@BB´€„„h Ñ¢$$D HˆÔ-8p ”SNž¸cq,Ëêxº?™’÷‘hk¿æ”snOžxqÊñ™?M$D Hš4-02Ê5?òÈÅ9ÙË3<À/øJ` ÿcöl­}{‰ÔÏnH€µÕÖüWr…¢¿`ãµJ Ä™ó¡~>—:vìèìt²Î ›“ã hô÷õ$/ƒ %g`¨objhwÒnþâE‹–-!`8æJÇSöGŽš™3F†Ý‚´”dg§§¬ùW¸™štèPibBê‘#ÒÒ!ÙæèË—.ôíÛGÈݸi•ÅÈÃ[µjÕ±C‡éÉ_¿Ò0ilÕÅ'Ö/r£Ù~¾@yñеk@N ¼|9ÛÏGþö;Ñ’* QÎ÷Â_FZ ­]äãuÕÄä9x€ù‘ÇŒù77BÀÜ_€a8i§%®Òœóä5B vïÚþÛ˜_ÙK¯ËgöêÙ³Y³fíÛ·ÿu´œ©±~mlhij—AÖ®_¯´Xù¸µ…ŽîÁ“ö¶ó•.ZºdÑ’ NpÊÙÁÐØÀî¤Í\¥6m”–è镯Fß:jž`m˘[›—‰7R™û p LÝÓ‚];ÕÌŸ+änÜ´ÄÚêXB\$’Ò|P„¦F ¶ªª‚é²ý|ÁÂE+1…¯®àl?Ÿ·PI}Çv¢$|îI^ qøÀ_FZ`föÄý| Gͼ‚Ûíl¼«KCìlïyy†¿§´`ìØßvkì`/‡ÿ2LAaúiÇà _÷³ûöî:ôû·mš{vN˜0Žl¼ ‚vY¼t™’²²•õq}Ý“vó””/[êäìhzØsåœó—,_.tì€-°´Ì ¾‡íK0“"¸ýúxe0TàÌé'Q·ÅÑ‚}{÷ôîýióæÍtñÂYÆ“…è%㣦ªÒ¥Kç6mZÏž¥œËi9~ÿmÌ‘L…Ül€¤1sg\‰¹sfã’ñOMŽ_ºtq§N>ù¤ýŽíªŒg ¿÷¸q¿·mÛ¶eË–cÆŒfWá‚Y-ˆ-<%1!ZaÆt³k×.(2«Ë_»Î;·nÝzêŸSâc#DãÞˆFn%$1`À—È0²­}p¯„ºöóO&ÆúlÄà ¿îݺM“ÿSWçë©£½Ÿ%aRµ/ã³WkwŸ>}Z´h,9;Ùëéüì³~L¬KçøÓÔÌʵk.YÂöóù */_Æöspß5¯:v@´€Dœ¤$Å^³=nøÈ~áò¥ëN§R«ï`+8(P[»(( ÈìðSö†BÅQDÿ`8¤¢plÛº¹gÏ6E¶ÖŒ' ÁðâüS±Pi~ÇŽ[µj5~Üï>^ÿ@¯?§üѺu«Î:­[»Š33½zõtq²g/[´hîëíÁiK\ääF¶iÓc~øða˜_ÏÉ“'1ZÖ®YUe®˜¤0Å—™,ZºdþâE˜1 8i‹IÓä°¡­âüUrq´ âúKYŒÕ¿pþQZJ²ž^iJRŠ¥Å+ÆSG§ ´ éF*¢fV-,$àF|Ô¦ë¿ò-ŸÝ\Žýý7Øfìýª•ËECbèÂÇD… ¹ÙË—-A\¤~5ø×_åV,_Êø£+Ž=*48á—.YÌx~ùåö'm`¤c£Ã—(/ÂrA”pDœž‚èàÁá!ðVÝæMFËUd„`ÖÌJ æ‰Æ=fn†á&!qPŸÌL`øaægI¨[[kË/¾øüfê & «nSA­öóaCø˜šÀ F%sûþ1iBÈP™­*›Úµk7eÊì%Rí1Àä¯X³zòbÑ~>gR•œ€h‰`Ôÿýwèø…»Zg |¼® >npÑ= Ì â„%†¹Þ—¯ùz‡] Dï×Õ-”–À^ž;ëâçs ÇàA%ï ˆó_±| ÖngazÁfüÅøƒõ9öÛýÂÌ,œ™Íöóùï6ÿ? Åüu쨙è½°~Ìðgn4Lš8žñŸ7Wñ×Ñrîg!à Uæ à ½dàe–ŠÃK–Ì[¨dqÜBßPOßP×ÊÆRqþü%+–UÉ ÄÑ‚Øè[º\ ½fp35 $à°iatÔ­¸˜›©ÉÉ·Ò’ôõKDÍFTäUvuÛ¬Y3ž´Àß÷2ãF'?™§ì0†EÝlRÝ»wG\Æíës©G·‰ 5\JóÈ'–颴€³ â´ð„ô÷fÜ(2«äØÇÛƒqƒptíÚE("/ß’ f¯¹g¸Ÿº…E72<Äz¢ŒŒjhY³z~áæÜöçÙ¾Qal0¡Kq±ª`«WÏ_´P°ŸÏY°€' Z@"*àåcÆŒÆou‚œ°»««[`büÂÒ"ÓË3üm òöºŠ¿@|}B/ºGK{OóïŽþybØÈF 0¼1c2n0¬Úw·n]Ù³„NŽ'83Ó²eKéÿÎx^À¿ÿÏàߣGw˜ÿË—ÎsTôìØ±#««Æ uUæŠhAÍÐå%Š æÿcn¦£wP[wÿ‘£fs•”ŸM–€œ=“c`PräHýÉQ·ß­×Sb¢ná/ƒøØ›a¡÷ª<[ îV½è¥à sÖlʺµ«ÿ^·FÔÍ&…Xœ‰ú³âêìøóO?¶iÓ†ÙuûðÃyfXœž"]0YÁ]@6?Œ8ÚÛ}úi¯³gœ%'îvÖeܸß1ûöícyìˆäº=fnöyÿþð™&ÿçžÝ;ÙD6¬_‹(ìÝ–šjßjà`ÎÎQZ ØÏç-\¸z-Ñ’ú{ÁâXVÈ•Š÷€xz\w;oò6|ü}C(ao"ø;Øß¥}ô¡Ð4KxÊfþÅù‹N.ï´$ø›¸›§]9Ÿwt°ÅÜñóÏ?2>GÍ÷Ý·­[·æ©E\®˜›˜ïȺWƒ(Ïš7×ÐH_sïSCÓÃF{÷ï121œ5oÞâ¥Ëd¸‰pòÄ‹[iï'9ˆ¿èÿðœÛcøÜˆOcßX «S–x#õÂùG5H Ø-œKðï¿F+êÜ-`Áª—v  ÂÔÄ 6:üVZb\ÌuÑ|ŠË°8-<á9w 0úÂB8£ ŸˆuÎÍ•ÿ¡*«ãGÁÑ%×-‚ üê«•+–õéÝ›½·zÑÝ Õe~ÄÁØXõN *9ÁªÙóç‰öóÙóç¯\»–n"Ô-ÐÕ-p?#x9^À^êÊ÷õ =awW”`°ÙÙX úØX[ôêÙ³fiA÷îÝÎuýw œOwäP«b’Û~øùx¶hÑœMm¯Ön¯Ëî` Þ—/²©uíÚ…s·@\®Þ9?– ¼Ìœ`†¢âíýÛwªéÒùkæÌ³fêèîÔØ®£{pÆìÙ‹—,A0©hAIB\ZHð}Á×1Ç ØKcãâøØ›gÏäð§Ÿ|ÒžÝ$½D0,sßÞqûl•P Ñ‘×Ú·oÏÜêt ªXºt1{}̘ÑË–*³[ ¢g :vè€årrb,ŒôÔ?§ð§â´EçFø‰ÆG^…ž-ت²é÷߯øyÁÂ]ò8‡,1þ;w¨7c”ñ™¼ä§þéåéÜÒ¼S§NUÖ-þÕ9¸ïÝö~ˆ÷,ùúëÁ‰ Ñ<«E´AkŠ0œ@aζŸOŸ5Kaö,¶Ÿ+(*®\³šŽ’ÔÛ{ Ξ¾Á2…ÿ^`p ÄüÈcï0Î'Ö¬^1pàWGÍý½ ÇŽš}5àËukWI6óü1»ýÎÇÕÊå#G wq²‡18ag5~ÜïŒÿüysääFz¸Ÿ½xá,s“óÅ_ýï]FC‡~¿oïn÷ g°ât;ã<{–ÂÐï¿cþ £½¥ _9µ½;[0)\ºè<[ .W„3 /ƒ¬^»<@cÏÎM[6híל:cÆÂ%Ê ò ûökmSÛ¢µw¼ÂŒuÖËðÞßt–€€(°œžÖÖ¹±17ù< È^ªlÙØ¶m[q—‚§åg*L<ÞÏ„ùÇÌƘñt ª€ Sœ=³]%à`MÄåEà:|²k‡:ãyÔüpß¾}š5k£»g÷Nþ´@œž´àF|ôôéÓZ·n‚ 4oÞœñ¿™zcÛÖÍÌ ÿ¯¾ƒÍÆBB\¤¸ÉËÄXÿóþýQ¨ÊcË–UÖí?‡?û¬kPfL?xà¿—¡®0êyV‹hƒÖ-ج¢Àöstï«W(L›9“íçÓf*lUS%Z@R?´â~!ú¢{4˜Õñt?ŸPÆÁüÈ£@ÿ+ö'osÒ,¬7oZÿÅçý[T ¤*8µgnòôòÃažhÀ5=ãàwyòäI­ZµêÔ©£¸'˜Sì¦&&,†°,û裺wë6uêPæ/,/0™Â¿Gî(›RøcÒF ¨ò 9WΧN"$½ÎH6ùyÔèuÖa®TÛ®:Y^~þÂ…—/÷ô8?wÁüÉòSÕ·«ªlÝ´zíê_FËò:#HXȽ°Ð{º:e§Ÿ±´ÁÆ:7éF*û®ÃºyÛx­Æ®í¢î÷Z¼½<úôéSï%?~¬±‘~¯¥ar¿²ý|Ê´iK–/޼yuÑRå)ÓäÙ~>ü×߈Ô-p¿äïb ŸwÎ-ÎÃ=28(žzzïï7`¼kêåÇŽ¶½zõ”ºèåÇ2 –Gc'MZºbé¸?&Íš3ÇÁÞö„•­µ…Õ±iÓ§ÿ6~¼òå1ã'lSS%•€„ßONLIIJ¹ŸfbRøàZØÝ›©É †%uI °²÷òtu¿²tÉb¶kaW~ÿmÌÒ¥‹ë…ÜL½qðÀÞ/¿ü‚}F±ÁÊž½Zãþøý|üä?æ/Zè}ùâ%s/œ½pîôLEÅß'L@?ÿmÂD­}ZÞHC´€¤viDW·ÐÅ)¹r €y ÁþämæHAÿTÒÅYX³ºŸ?=rÄð¹sf“ñ®ÕO%mVÙüÓH¹¥Ë—:Ÿ:yÂö¸å±Ž1=vÔÌÊÒ|î‚ù?ü2bÓ–ÍW}d£}ý’Ëž™•VäícçÜ3G jö ŠMjÊÖØµ½S§NmÛ¶ýkÚT w$W—(¤ª[xöéÝ»ÊGÈkévíÞU±7¶~Ÿ§ÇÅsgO;¹8;œvq<çæª¼téÃGîÐØ™–’@´€¤>iDG§ÈÚê!{Ë@Tš¦­Ú´ñï:´iÓfâ„ñâÞ†DRƒÌV?Àï²WÅ lì¼›+~áÆ¢Êß×ÿùUçÃʇ•:9=ú<}X™¤Ž™¬~Ò˜øØˆ¨ˆ°kaW®†âî¸˜ë‰ ÑøWò¶Ñ’Z¡$$ODi Iã¢$D HHˆ- ©9Z€nDBÒè…hIÓ¡4ÞIdž'+h@ Ñ@ D @ - @´€@ Ñ@ D @ - @´€@ Ñ@ D RãåË—wïÞåãIhš@ -‹üüüÝ»wkUBCCÃÀÀ Žóçìì,Uøòòrýû÷sþkhh(î/ž(,,Ü] Tˆ¾¾¾ä Í|õ3À‰””55µ½{÷IyðàA]]]¡ñD·nÝ>|ȸ=zsXý49+DªZâl¸;w2ލ¨(T©ÚQ†6J„gÿ§ˆ³DÕ,&@h@´@SSSÔÓ××—YO`µqåÊÆÓÕÕUAA«1ø«¨¨0S0gHÐ ø`‘é 0ÆÄbå +‹ÉÓŒ]»DGGKОÍ,Ga SòÕŒÞ'NÀ'))iäÈ‘žžžp'''C£Ï ),,äŒ..ó€¢¢"|6nÜxÿþ}ÆÄkÇŽ ÈØÉ“'%Ô§8hii1ŽÜÜ\>;:Õä+ñññT³DoÞ¼ÌsÉn´Ü»wÝBàì œ5jÔÙ³gÙ”‡hthY¶lÙæÍ›ÑÐȪ¥¥¥ÌRe-‰k8Ö^9r„ <`À€iÓ¦ F_½zµ¹¹9"Þºu«Jí¢Ñ9Û]Bš|ÊÎY"©ŠI 4-`§ }}}¸™!=qâÄýï 8ѬZµŠqèèèH 6ìÁƒìeii)̆¶¶¶½½½à<%j«8ÓTUU……fܧN’`á~üñG6¤Ýµkט(ׯ_‡£¨¨ˆÉ¹„ÝQOqÑ9³±fÍš+ïΰkbd¾¸¸˜q;;;_½zU\}VÙL°v|¬{uhØ ì%³R‡ê—¨Ê…,ã–ÐÁ„hn{´àÑ£G™üsF1bz#ãvssóóó“¡BøÔ’¸†¯…ÉDVѯov˜šš í·cÈ<}ú4//oÏž=‚ nNí¢Ñ9+Y\š<ËÎY"©ŠI Þ§ÝfH‹›ÐEgm S¿ÐdCé8==]2-àL«Á¼ ÇlN°!™ êׯ_oݺ¬Ù›&œÀòWÔS\tÉÖ—uR 6KœõYï»ÉÉÉ;vì(++“¬ú%âI øp ¶fXwLL ³Qij‡HU!s¶@CCÃÚÚZ0!£¾bÅ 6¤­­-ûfÃ)S¦deeI®Ì_˜^Ab˜[*¬ñãŒ.šy¦–°f:þ<iiiðÌÈÈPWWG‰%;;; õ).WÌIo¤ ô$ÂÀååå…²ÄV~dd¤OÑèß}÷sŒ¿Ê§ª_"æ$€o±žHM³È0þzòä ggàÄâÅ‹Ñ LC:ÌáyÎè6l­A³§OijBø×’¸†³´´D>‘%ðN ­!‰¸(†cÎ%hçÓ8Óä_vq%’ª˜¡AÓ‚¦Xˆêœx¯ftBÃAm<*B D Þ0'ÛçÌ™³qãÆ‚‚‚:ŽNhP`6«´µµùß›'¢@ ˆ@ Z@ h@ ¢@ ˆ@ Z@ h@ Ñ@ D @ - @´€@ Ñ@ D @ - @´€@ Ñ@ µM Ç¿ÿþ½{÷jhh”––Öqþœë1:W…íß_T—5P^þ¯ŽN]+%põ¥’:èuÖÁø+ª~–øT]mŽ>x.›ŠË—Kwí*,çlÍœœ7€Ä™d££ßjçT„t™Çóĉq=Dœ'c'0Gš‹Ÿ?Ùóùóó÷ì)q…JJùâÒdòŸC‡Š˜Œ‰S$®‡ˆöyβ‹zŠ«:þ]‘³ÝEG‡¸\»VÆh—ÜîUÒ‚àà²#GŠ% X$ˆšGoDÓ0…âlΡÝ@FG|ük‡©´ãwÙ²\¢8¨KËŠ*JJzæðô¬Ø]NN~ Õ>>¥yyofÏÎG_‚çâÅùh)ÉrÎ8rsß tRÕ<¡vi,+Lø–-[tttÊÊ*ºQii©«««¶¶¶½½=cŒ¯_¿îçç—ŸŸ?}úôââbwww†.pBUUaÞí.:_½zUteϺE—û#FŒ`ïe¸¹¹A¯Tјššž:uJ¶*czs~þŒw%*|W ŠýÒ«W˘™¿¨0tYL¾ÌàŸ8ñ3&!Ó¦½’ i¾5 §N•0ÑQnÌhÚÚEöö%ì4·uk!{oÇÍíí,Ó½û‹ØØŠÙS^`àÛÁÏéÉœÑùg‰ÙëL°jÕÛ¹© àŽN‘¸Öä\Õq*úñÇ\¶áììJ`“Ä¥)NLf7Ìà²}ýz™Ÿ_:áô鯈»{)c Ä¥ –;!˜ˆ¨"q=D´Ïs–]\Í‹Vÿ®ÈÙƒsĉ˃h»‹,7Ì*lI090ÀlÍÃŒ1$@\»‹f¾!Œp>¦ê¤Õ>bDž "ôL¦hè¥pýWÃH¬t õ;û()aO…³æ u±[àëë{èÐ!Ö®GDDÀ6§§§3ÿ–””à_,âan<(áHëÆø`“åi×wíÚUè5¸éÇ:@T²ô=^4ó+yø¸`šLtL(e¨Úôôr6}Á쾂©i1þ+ÇLÁ.)D=ùƒ3:ÿ,ñ/{)²Œ›³59m§"v-.3MqŠFÊ[¿¾àÅ I³fIÉ¿ocS˜+¬ü˜'.MÎü‹*×CDû:°¦ß±£°¬Líœ}þõë ^‡¥eqfæ\ãÉ“7`¨â¶ÁdØ-à¬yBÝDpuu9¨l--ÆçæÍ›ì¿ Ë–-+//_»víÞ½{%$¸mÛ6v·ÀÅÅ%$$„q³·!²³³ÙdÙ¤ÞTŽ~ø¡¨èm?°··—*:»[àääTS´`Û¶ÿ誋KIHH™¸I tþÙ³·Ù|ŸiŠ2}vœÜ¼ùßàYfNNo× G³ƒ°]»Œ›Ó“?8£óÏÿ²×™"NóÀÙš‚“,úÓ•8ùßÊéܹҠ 2qiŠS„l¼|ùfÆÉS'¨À²eX~­][ÀæM\šœÆOT‘¸"Úç9Ë.®æE«ŽWälwÎÑQ«´å…’°’† dë!s·E\»‹f¾~GGxxÙž=o÷ $÷:Ní?ü ÚñnNþïú¿·w)»Ã<~üfÍš‚§OßlÞ\ðêUÌ@E忳̮ۻٻÅ‘\ó„Z¤FFFãÇ?sæ cYÿþûccc˜[MMMæß˜˜Æ*ÃsssÁ½(222ÔÕÕ÷íÛ§¡¡aggÇúãR³‡B²Ož<'Ü{+4srrà³aà Pøœ8qBÚè (///C}YXTÜ¢{=¾Ž´´×•%*WW¯¸¹¥¡QhgWÑCOŸ.Á¿Ì¨›4é:+.srÞäç¿Ù½»"$¡„û”̆siZ[¿½/hl\ÌÜ’42*b|þ¸U‰”Ïœy;øÿú«b«žJJùì"NOþàŒÎ?KüË^gŠ˜ÖLH¨HÊÁ¡„i#ÑÖdÀܘgîÍ#§"ämÅŠ¶álmKÞõyŽ49=‘SŠ€€2,ª`KÄeJQ'•#®˜]®q¦õš½ÁobR,AgÍsöyÎJWó¢UÇ¿+r¶»èèØ¹³sÄ1ÚÙâc`ŠkwqÀbŠP"P( ù|øðí|Ð5}ý"Ø?qÍÁ9´ëwt|÷].|Ø› Òj³×AÙÏÓ0,pÊ”WYYå,µ<8Ybl¹œ\E§’ ‹yzaàÀ\yùW’kžP»» µq_ ÑÏ̬¸if©–@h ÃP“¼E ZP+`ö'´µµËÊj÷y•>xNBBBBòÞ Ùõ&·[@ h@ ¢@ ˆ@ Z@ h@ ¢@ ˆ@ Z@ h@ ¢@ ˆ@ Z@ h@ „ÆF \IHHHHHH- !!!!!!!Z@BBBBBBR‹´àƒw š%!!!!!¡Ý‚·ä€j–„„„„„„hÑ¢UÑâ $$$$$$D ˆ- !!!!!!!Z@´€„„„„„„hÝD !!!!!!Z `ûA´€„„„„„¤©ï- !!!!!!!Z@BBBBBBÒ„i@ „&¢@ ê›T>³ cÄwO@Ô…º:Hí=ë1ïgÙeë6M­3p–¥šU×” ÐThÁ… FÕ²eËÎ;/Z´(''§á'Ùæ&&VuæµúëF{õk©ÎŠÙš£:Ú%„i"´€H ˘0aÂ¥K—^½zõìÙ3UUÕqãÆ- Z ³®¤¤¤±cÇÂ1hРçÏŸ- Z@´€@xÏh [´h!íÀݓĥ……E—.]ºuëæîîÎx–––nÙ²¥k×®;v422’0z/Ywffæˆ#Ú´i³cÇÖ377WAA¡uëÖ?ÿüóƒ¤5xü3/òÒ'IÚ@__¿oß¾mÛ¶…Cœ'g1á@QL6++K‚vqe.//ìØ18ð ·„²WŸèéé&''ÿú믂qvqÅä¬Ož™”ÐëdîÉï]g>|8†„—‘‘!''ײeKüÂ-¹‡ŽŽÎO?ý”——'N»——×!C0Ÿôë×ÏÆÆFÂÐWLQOÎ|Š«OžµD -OOϯ¿þºúë6fHX[[<˜ñܹsç”)S0˜1ª««KK ,X ¦¦â²uëVÖsݺu«W¯†§¶¶¶¢¢b,)83ÏRœv›6mÚýû÷±\fw_D=ÅM‘ªªªH…]¼x± DÑèwîÜÁÚ%8p ܵ´œrrrú@âóï âê“gæ%(jRAIIIBôyóæ1!UTTæÏŸ/¡ê˜ˆ¨ ô¨'OžHÐ"uñâÅ’’t9eeeÉ´@´˜œžœù¬f!ˆˆVx=zô¸|ùrÐf“B³fÍÏ>}úܺu‹gtQ7V-ÙÙÙp`éÀzöìÙ“Y½|ù²sçÎ5E D3ÏRœv\ʈó7E2ÅÄo÷îÝe°œÑ÷ìÙ3vìXMMÍZÝe-//ïÝ»wYYÙ¢E‹¼½½%„äßÄÕ'ÏÌKPÔ¤:Œ´„肃 n U‡ˆîîîŸ}öY•›sX»ëéé%&&¢êd(&§'g>«ÙC¢ܸ~ý:æ5,jÊ²Šº1«¾~ýZæè}ô¬HD0MÁçÃ?¬½Ìs^ŠÓ.î¸Á)’-¦d;$®,œÑSSSñWZZZ­Î›111&L€cÀ€¶—¥ê 2ÉRh—B‚¢&ÛD£ .6$gÕ!b§N°d¯R{DDÄÌ™3Á-ÚµkÇÜÃ’ª˜œžœù”ª‡D xáüùóXLxxxÈ®˜ÇdŠuäíÛ·9£cœ€0à‹‹‹áÈÉÉa£#‡=Ú-@š………Õ­5i,Á›7oØKqÚyZÎbÂÁ¿¢+qâĶmÛ$‡”ÐD‹).“BÝFZE¯3ˆja£ ¡ª›;w. ·„ªcòvçÎü177W‚öÙ³g'$$”””œ>}3Œ´Åäôä̧„§–¢U/ò^¼x!ÕF¥è3ÎÉÄÆÁ÷;tè xžüßÊÓjíÛ·gC^¸pë„´°°`=322†ÞºukÁ'^½z…Ep»víúöíkkk[ͲWi ´µµÛ¶m[¥vž–€³˜p¨©©¡˜(¬ÐíR!íâ̘hô‰'2Ù³±±™4i’„²WhßÏ>û kPEEÅ€€€*‹ë ¢Å—=¡n#­¢Æ×8i¢ æç¬º‡Ž9²E‹£FJOO—Pul”óçÏ/Z´H‚v€æÍ›2ÄÏÏOÚbrzræSBáSKÑBÃnÂêMa4RghŤžL - - - žL - - - žL - @´€@ Bã¥ïõ‡•묰”ÃÚè ¸Bø—…>—L jŒøøøL˜0¡U«V]ºtY¼x1}X¹JïãJŸKn4Ú黈Db„Ú¥“'O3(((xúô©††óU\¢D AŸK&Z@´€@h*´@EEE­Zµ’vˆ¾¿V÷íWÑ×ÚpjçŒ~ïÞ½‰'¢aGáf<³³³Gމè»wï–!óô¹d>ŠªÙ?ésÉÿÒç’ ¢‚xùò¥–––lŸ%}O?¬ÌùíWÎ,qjçŒþÅ_øùù›šš²•‰UTT—!óô¹dþŠd!ésÉ|† }.™@h„´€™î{öìÉ.pÿmVæüö+g–8µKˆÎl½`Uĸ»wïÎ~%V†ÌÓç’ù+’¹r†¤Ï%ó2ô¹d¡qî¼xñb÷îÝXIÈÆ*ªœ à‡•9¿ýÊ™%NíœÑ/]º„(r%¸°®fæésÉô¹ä*;ÿô¹dP³´€Yà¶nݺ–hAƒý°ò¿ÿÿÛ¯l¶?ÉÊ©3z=ÜÜܰ–‚eCbaÄÜIÜ-àŸyú\2EÕ§ô¹di‡ }.™@hT´`ÆŒááá0cOž|¸ Öå=ý°2ç·_}’•S;gô:„„„ K‚!•••‘O”HðÄ¢„ÌÓç’eVTMZ@ŸK¦Ï%Mœ;wî—_~iÙ²%¸?ÆüÇ¥ÝÒ|?¬ÌùíWBŸdåÔÎÝÊÊ Ó*óðáÃlÈììlæA---v/ZBæésÉô¹dÉ´€>—L·„Ú¢„ºÄóçÏ1{JÝ®46¦QJ@"D Û¶mÃÒSOOoÖ¬YdHˆ- D š4tuu?þøã¡C‡ ½c€ Ñ¢h@ ¢@ ˆ@xohÁ”)SèÎ@ D þuuuýú믉ÐÔiA^^^Ÿ>}BBBˆÐÔiÁÆ—/_þoUŸ!ÐÈiAtttÏž=Ÿ={F´€@ „¦N † fggG<€@ ¢_Î¥z$¡‰Ò!Š á’@ Ñ@ M@ Z@ h@ ¢@ ˆ@ ZP«Še}fA¶—%ÔÙ#|YXX|üñÇu%z0„@ µN »Œê†0±¤ŠË'p¯^½bccë±Þˆ.¡&iAýçû}¦~øaýÖÑ@ 4ZÀ¹Í€K ‹.]ºtëÖÍÝÝñ,--ݲeK×®];vìhdd$!‚—¬;33sĈmÚ´Ù±cë™››«  ÐºuëŸþùÁƒÒQÎ,ñWĹÑâåå5dÈ-Zôë×ÏÆÆFr~ Š .++‹ñ”——?vìø…[B%- B­ÐØÅæÍ›ñÅû÷ï/++“1ˆÚu¼‚‚kkëÁƒ3ž;wîœ2eJFFL¬ººº´´`Á‚jjj………[·ne=×­[·zõjxjkk+**J[vÎ,I«H(ó`B/^,))¹s玲²²äJSUUEšP·xñbƱ „ª8p Ü m_‡@ œ0xýúõ7&L˜°qãÆ¡ÏŸ?‡Ö±Y³fŒgŸ>}nݺÅ3º¨Ü%;;,¬YÏž={bqÇË—/;wî,m©9³$­"¡Ì÷íÛWOO/11e¯²ÒEøíÞ½;ë¿gÏž±cÇjjjÖì¾@ ˆH‡GuèÐA¶-‡*í:øȇÌÑ?úè£òòr†Á¦ à/øÈpŸ3KÒ*Ê|DDÄÌ™3A8ÚµkÇÜPi¬"–<©©©ø+--h@ ê“<}úô“O>©%ZлwïÛ·osF‡¡4ϰ‘ÅÅÅpäää°Ñ»uëÖ"´ˆGš………2——3KÒ*g­½½½;uê$¹ÒEø…RÖÑ¢E .do+- BÝтٳgÇÄÄ”––>xðî+VÈ`‡øÐ‚íÛ·O:¶6//o×®]‚áû÷ïÄ^4ÈÚÚfQØèJJJ¸,**RUUe=7lذeË$ˆÌ‹ÚÑ*Á™%i •u˜PRRrúôé^½zI®%uuu(‚:(evˆó4>'-€¥Ü¸qc—.]:tè ¯¯/˜ˆ““SûöíÙ.\Àê!-,,XÏŒŒŒáÇ·nÝZðW¯^aaÝ®]»¾}û¢ Ò–3KÒ*ª%ÐÔç!Cüüü$Ó555(‚:(e<'NœÈ¤occ3iÒ$ •L BÍÓB½µx@ - - ÑÑ@ - @´€@ Ñ<5¤o×ÞÓÌËüô)@ 9-ð÷÷—““kӦͧŸ~ #W÷æ§6¾M\gƬn>¬\ý¯"Ix·„l5Ij"„FH ÂÂÂÀÜÝÝ 322V­ZU÷æ¹6¾M\gæªn>¬L´€@ uA äååeVYß&ægtÉŸ!LSÜ'˜@__¿oß¾mÛ¶eÞhÄùUhqv‘3ó¢i‚oÉÉɵlٿ웋¬{÷ªðÔÐЖpF¿wïÞĉ[µj5vìX¸%äSªbr†$Z@ `º733ëÕ«¬ø´iÓ˜·ôó_PÖÆ·‰9ÁÿgˆÅiG0”úþýûÏŸ?7nÜ¿b¾ -ÕbZ4Íyóæ1ßPVQQ™?> l†ùýì³ÏdXý‹Fÿâ‹/üüüŠ‹‹MMMÕv x³úB „÷†|ôÑGkÖ¬yöììú† f̘!Õü^ß&愸è@ 4rZðÓO?±´+iiiA­~›XHgt Ÿ!~óæM•Ñë†téÒ…­ÁÝ‚§=zôpssò>//O”VÑ@ ZÀ==½eË–±7¤²µñmbNpF—ðâÎ;GDDHŽ^g´`îܹÌ7”·mÛwíÑ‚:„„„ ˜‚5ÏY!Š)ó¾Q@xïilêúõë;uêÔºukyyyiÖÆ·‰9Áó3Ä ´µµÛ¶m[¥öº¡>9rd‹-F•žž^{´ÀÊÊ æ­yøða¡4…*„h@ - @´€@ Ñ@ D @ - @h”´@æ#ú¢žU~v¡r¨©©9gΜRLäDKK‹† @ -à0$ >ùä“FI dN­ñôéÓ®]»2ï`nÅDNŸgÏžÑÈ!¢ؼyó¶mÛˆÔŒŒŒV®\Ù Š¹bÅ ccc9@´@/^¼èܹ³Ð7~êœße÷mbQ[È|ñч.´4²—â¾¶, //¯!C†´hÑ¢_¿~666ljœŸ÷ÁâñãÇûøø4¨bz{{O˜0F@ -ÆÁƒ•••ÂÚšó»Ìâ¾MÌi/™HDIIIB‰$|ëY°ñ/^,))¹sçŽäZ’ðb$òôéÓULä¹¢‘C D þŠ‹‹ÿ¯½3¢Ê×>ÙȾ/$@®z‡„;q™a CȦa_‚ÄÁÙÂ"Jâ ŒÈ\"̨„! ŽŠˆ€DP‚€`dF2 Lä‚ òaؘ@LH ïoÊiÚêêJ§³t'ùýž÷éçôéS§Î©®®óÖ©êú‡……>|Ølf\fs±‰5ÇK¥¤¼ªÆ< £-›¾xñbÙ>â ÔÝâ€ÅÎÎÎJEûéfee¥1 ™Û‚•+Wöë×ÏNº¡—Y'6±éxiZRs¼Ô‰õ¬"''gРAíÛ·÷ôô\±b…¾-0÷‘j¶ÀºÉl¶@ÍÍ›7;tè°gÏ;é†f\fÍØÄ2Ú•——KââÅ‹Æã¥RR^CBBŒk–AQQÃ[XÏæÈÊÊò÷÷·ÎÄÅÅÉâvÕÍmÛ¶qo¶àglÚ´)::Z£:]DЌˬ›8"""##CÆ<)o<^*%%SÁùŽ;îØ½{·á­N¬g ¹¹¹ëׯ ³Î¤¥¥%%%ÙU7Ç¿téR~9Ø‚[tíÚuÆ öc 4ã2kÆ&Þ¼y³œsËvzzºj¼”Å;wî,çÜÆ5¯]»ÖÛÛÛ’XÏ*Ö­['c³³³sTTÔŽ; +2¦F[PXXdøÍ»)õKÆ×5[Gjjªþ_“„„žr€-l` [ØÀÔ–cÇŽÅÇÇ{TÓ«W¯ãdzZ¨-¸÷Þ{_xá…âj$qß}÷±Z¨-pssS¬[U0ÉÝÝíÐBmÁ Aƒ.\x¹I?lÇVO9ÛØ‚üüü_üâÊã{%¡ÄêÅ´D[ЧOåÞ‚¢¢¢”””Þ½{³Z¨-0¾·àêÕ«ò–íÐBmATTTJJJQQQqqqjjê=÷Üs«:."´([päÈ‘¸¸8÷j$qôèQl@ µ€-l´x[p!„BÍNØ„B5E[Pýw†ʤ§§xyyXRÒò:-Y¤Õ¨KÍ5>%eÒС½í¼ñ¦’6§¦Nâg†B-Ôœ;÷Y¿~ÝÜÝ]|§LUY™Ûø¶ ,,øàÁê·NË©ãÈªÙø‚‚/‚‚üÏžÝeç7•´YZ^X¸×®vúµŒ!„-¸¥G‰}úéÅÅ_ÊH˜øè’%3ÿ€îààÐ@ƒD#Œ¬š_ºtÖ„ ößxM%% NK›ÝälÁ¸q>½SJÊ«¤9R „°ÖØ7ñJZœA§NÿS«Ö\»vhÚ´±r~éçç-c¡áŒ³sç{ÜÝ]çÎ`8 _¾üåÀqnn®²Š¼¼OU3á5·kÖyæÌ®˜˜ûZ·v‘WI›!†´$dAY<:únÕI¼j½ší47V™k|\\çíÛÿjÏïß¿ûŠó%!¯’6þ(+keÏž]ô¿wÍiÖ©¹‡˜Û”nʶ:wî³Úî!↠{XÊÈ«a{"„¶ v¶ÀÓÓ]ŽÑ[àííY«S´gŸÐ§Ïƒr–JfϯdŽÙoÖ¬'ÊÊ̘1ÎPɤIÃ'N*™‹=3dHïÚž jÖ9|xŸääÇ%súôÄ#úê¬JI©dÔ¨þ:k×i§å'²ÁÁþ_ØsãOœØqGiéþn—´ê ˆ´_¿×š+Ò¬SsÑ\ܸ›cÇ>RÛ=Ä` dêlWBØKmÁ£ö˜:uŒ²Å<ùä''ÇZLÛ·osüøÇªL95ÌÏܸ߭`¨$44H9Ó-.þ2 À·¶GmÍ:3%­?²*%åU5æ©Ö®ÓNËm³³Ó¹vÞøùó{JŠúÃÊÊ\gýeÍ­È´NÍ=Dsqãn†„Ôå"Bbâ£Ø„¶ N·†…/[6×0>Y(±¦w):::*ƒ¢|d8"KI‘ 9ªëñ–µ5ë4Î4s#«iI͵ë´ÓêÙûlü7ßl‘bÇŽm1½_²ÆÙs+2­SsÑ\ÜònrË!B5”-0Ö{ïýiÀ€‡jÕšvíB¾ýöÓAñüù=ª“c)YVvÀêC¹f~†Lƒ¡‘¥¼ü+I\¼˜m<²*%åUu&*Ã’ñ¸¥ÓNË×9+k¥7~̘£G÷WM׋¶mK¯ñÞs+2­SsÑ\ܸ›¦“"7o~Í!„Ü<õÔP–ä™ù—¶mCöî}»V£õœ9Iýúu“®\Ù7oÞ“Jæ¨Qý%ÿêÕÉÉ*™thƒñGãÇ2ÜhNš+Ò¬SsÑ\ܸ›ª[(|srÞkÐ?2 „¶à°rÓxhh»»kLÌ};v¬ªíÁ´¢âà”)£äÄ×××ËðçÆ3gvEGßíæö³ïKJrä<ÒÓÓ=<7&æ¾sç>uérÏk¯=-h é„`6H3d°ffÏž]¶n}­¤$G@ròã=zD*±ÃpÉ!„š†-ˆŽ¾Ûðì¼;3ÄØÉH¿dÉÌððP7åÁ8–kÖŒ5 Y§ä¤§§úûgfþE§=Û¶¥GEÝåââ|ÛmmW¯^ 3û¢S§*³flbÍÁ5Æ.+;`ñÈ’pÉ!„°¶ÀÇÇëÊ•}Jº¸øK__/{8 —UðÐwßm¿téïÊy°åÁšulªNÉ™;wBiéþŒŒ‘‘ÿ­Óã?úèÕŠŠƒ'NlÓÙ§S§*¨’flbÍÁ:q„}üñë;Þi|µ¢ÆH!„°Ø!¸ßüZµ¶Üp¶@5þY¬YǨꔱUÕOíUÅñS)<9þÊ)Qm›èèøÓø'‡9CÍrÉG‚êf‚ºØK>2·vÍvj¶gëV?9/”4§”k\‘ælæÚ3 C޹AÔ´dm›dy7­þÞmÛ#:ëb ,Üëtj»páG›"ö¢ÆÙ„² [ðᇾr„Ú²ÅÏŠ&Ê‚çÏ«ÏÛµs,+ ®ã}aµ:@ß¼yë­æÚCB¥…š³ª’mÚ8nÜè+g‡W®[±"ýYY~ú[)0ðV¦áÜZƳòòë¼x1ÈxUJÊ«tDu §Œ‚–4ÉònZý½Û¶G:u6-0Þôk›8Ñ}Á‚ŸÝÔ²m÷ „ìÒ¼òŠWX˜ãþýÖ á£F¹Í™ãqõjprò­kÌ“'»O›æ!ãM^^àØ±n m srü o5מ˜è&™2Àß"§Ù__‡ìlYܸG–¯HQZšWR’»þV6Ìmöì3gÎô´’ᔑá#í”òƃ¨RR2U+ºã§Ý»-j’åÝ´ú{·mtêl„½N¿¶ãÇCCk?Þ}éR/." „li 4ï neBQQ°å©3g‚¢£]ÜÜ~vGzIIðèÑnžžááNkÖøX1õªÙNs•,Zäåáá ¿öüüŸîœOMõ4ž‹6mϪUÞrÄ÷÷wX¾ÜÛŠ)*,üñtÙpׂæV:u*°K—V]»ºœ>ýSÉÍ›œ¹‘ÓîôtoÕ *‹K”9ƒÖ®õñö¶¨Ivó‹/ücb\¬ûÞmÛ#suZØ£:îu5šŒ„WÃ[Ù8²AŒ/3a B6›-háºt)XŽÈ°"ñúwÎÛ§bc[ïÚåל¾q;ì‘XžrˆÂØX3gzÈ©çâÅ^ÆžC!„°-Q/½äåååpï½Î'N²5Bµ[-l` ¤ó­jî~zzº———%%-)Ó-°¥-0úóÕ-¶oßÞ³gOWW×ÀÀÀ±cÇ^¼x±yØ‚°°°ƒ2ض cÛÃ?,Π´´´  à¹çž‹m¶ÀÁÁ9ÀX?¶]½zÕÕÕÕæ}»víÚ´iÓ‚‚‚üüü–.]ªdž={¶sçÎîîîsçÎ5táòåËtssëÔ©S^^ž¡ƒ?.Þ¦0-SK7=00088833³^êhb¶ ¸¸855µG6?9~öÙgûôésæÌõgÏž­dŽ9rÖ¬Yeee3fÌ04lÒ¤I'N”ÌE‹ 2ĺ3{S[ Σ´´4###22²^êhJ¶@9Á =yò¤ÍǶöíÛ?~\•”ŸŸ/‰sçÎ& >{ö¬âiêË\ºtINNNØh‰³EEEÏ?ÿ¼œ¦Û¼o2WVVª2oܸ! ùÈЧj«Ãîªn&¨‹-°ä#l4g[PU}o›››ÍûÖ®]»o¿ýV•|þüyÕl”,++«ãÀ\+[póæMl4[[ðØc}ùå—ßÿý¬Y³¢££m>¶Í™3§_¿~2ü_¹reÞ¼yJæ¨Q£$_ŒKrr²¡a“'Ož6mšËËË;vlCÛ‚€€€œœl4[ y;ý¦M›î¿ÿþÖ­[ûûû'$$œ:uÊæc›x”)S¦úúú.Y²DÉ;;ÛNÆ¡F ¬¬Yç™3gdÀkݺµ¼JÚt£?øH”Å£££•ˆMæ6²f;-oRÿþýW¬X! y•tm·ç¶mÛ¢¢¢\\\n»í¶Õ«W×Ëw$]Þ½{·’Þ¹s§8~“ÍÄL™2eüøñUuˆ T¿4Z`eÍ:‡žœœ,™Ó§O1b„¾-PJJ%£FÒY»N;-iÒ‰'"""JKK;tè éÚnÏààà>ú¨¢¢B–MLL¬—ïÈÇÇGܤ’...öõõå7 ÐlÁBCC íÇ4Z`eÍ:3%­o ”’ò*C¯ÎÚuÚiI“„ùóçÇÆÆ¦¤¤X±=ÃÃÃ/^|øðaq5îεZ>ðÀ’PE €¦j ~ûÛß¾ñƶõ*-°²fÆ™†ÑΜ-0-©¹vvZÒ$á›o¾‘·Ç޳b{æää 4HÌ–§§§r1‚Ùlöˆeù b£Ñh•5ë 4df dP///—ÄÅ‹mRR^CBBŒk–±ßØÙè´Ó’& cÆŒ=z´*JdmÉÊÊò÷÷¯—Ù‚èèè={ö(é]»vqo@3±úŽÁ&}k´ÀÊšu6löìÙ’9sæLI+™2´Kyc[ ””LÕÚï¸ãÃyúí´¤IìØ±ãõë×###:TÛn&$$äææVTT¬_¿>,,¬^¾£åË—?øàƒùÕÄÄÄðO€¦g j<´[Ðh•5ë}:00ÐøÂ„éTjóŠ!À f À”ÔÔÔ!C†ÔWm2Æ«žrh:U€-l`  IÚ‚7nܼy“ ÐÒmAeeåœ9s~øáãGþÙôôt//¯ú½?ßòÚšÐÿŒ£B›ƒXÏØ¡Nóñ>;w‰qss“ºwï^XXhÎ ,,ìàÁƒ|Óú˜F…Ö Ö¬ëZîlÊìÝ»·mÛ¶™™™ßÿ½|òôÓO_ºtÉæÎÀÁÁ¯¹FL£B› Ö¬ë°?Ñ¿ÿ÷Þ{O?üðƒ|ôí·ß'''ÙÊh>véÌ™3111­[·–W㇔ÂK–, ÷ððDuZ¾vUfzzz`` l±P5Ö j’ffÍ:óóó»téâîîþüóÏÚpùò庹¹uêÔ)//Ïx]¦Q¡Ík6ë°·aéÏþsXX˜ráæÍ›GŽ ˜?¾òÖf=üy;‡®Ä;ž>}úˆ#Œ‹ 0à»ï¾»té’*ºquZ^RÞÎ;·´´4###22²ÆeUMÒ Á¬Ygbb¢tPº9{ölC&Mš4qâDÉ\´h‘ê±K¦qžÌkÖŒÞÄ£°?[ÖÑÑñ©§ž*,,Tâ]»vM2:äçç'oå<ÕVÎ@ÕNãhË’6.f2Ölë[ÀlÊE„ .¨& „÷ßßÏÏoãÆrËÓ‘‡K—.É@nIIK¢B›ÆzlAͶàܹsrªš0Þzë-9ßݲe‹Ê1@½3sæÌ’’’Å‹?¯À¶àÔ©S† ƒ7nüêW¿òøâ öîÝ«r P¿¼ôÒK^^^÷Þ{ï‰'Ø`K[pòäÉsçÎ=ztÕªU2ü¿òÊ+‘‘‘¯¾úêÛo¿ýî»ïnذ᫯¾*//ç hþ¶àøñã999ááá>>>ßÿ}iii@@@zzºx…âââË—/—••ÙIˆEhX[°{÷î¶mÛöïß?::zþüùׯ_OMMíÖ­ÛÙ³gq-Ë„††<øÓO?ݼy³¿¿aaaQQ‘OffæÕ«WÙî-Å888Œ3f×®]%%%±±±/¼ðBeee·nÝfÍš¥< š¿-(++°ÿþÂÂÂÕìܹÓÇÇ'...00pÙ²eØ€–b *++¯\¹b|GáÕ«W·lÙòÌ3Ϭ\¹òèÑ£lw€a ÕsŠämyyù¥jÄð#€d [Ø‚`Ë–- èÙ³§Ë–——/\¸oZ ²çëûlã´ùúõë,ªfРA¦!:¥f©-77×Ðì&±akå!***dÿ7WlÍš5õ IÎéF}àÀýû÷3Æð©xsËÊaѧ#H=û«QjNOO߸qãÚµkßxã y{ìØ1ÅŽüûßÿ®Çs¾ž?Gs¦äæÍ›Ï<óL]¦LlØAáoû›ø¶Õ«W›«¹ÚüòË/\$4k–†-\¸°î³¹aMŒæžc¡-8r䈸%ŽzÐämA¯^½®W# ç:!—,¿ˆ õ(5?üðÃòVÎ#SRR&NœxñâE¥ÀÓÕX=P_³uÙŒ6é b 222¬¸=¢.mÞ·oßsÏ=7oÞ³õþÌüF˜-°Il€æl â™ù ú¼9ûy„>@s³ÆoyÎ?3ÐlmÏùo çü4ÃÙÀ¶°€-l` [ØÀ@“³ï#„B¨Ù [€B!l*=ýI//·V­Z©òSR† Úź:Mk«cyiIjê¾,„ÂÔ` ZýÍLw¶»9……ù<ø²*³  #(ÈûìÙôz\‘ÎØ_£-–H{ Wó}!„¶ æÙqeêÔ~3g`»›“ƒƒƒiæÒ¥‰&ÄÕ×*Æ{èôé×å;’WI[7»”—––È÷…BØëmAQÑš€¯3gV4¡ ´mÛ¼¨¨ÿrqqºí¶àÕ«Wï3öææTŒ?Š‹‹Ú¾ý9ÃÛ“'_¿ÛÕÕ%6ö$­³vÍÚÄ ÖU2åÕð]œ=›Þ¹ó]îî­çÎh(ß¿ÿoV¬˜ y•´q%YYózöŒâ÷ƒBØëmÁÂ…#»×Ë Úh öùè£Ùïž8ñgUãë×è,.m((È0¼½óÎ6;v<_^þβe÷èñ«7g †1Ø‚‘#˜5ëѲ²·gÌ`(/]ŽˆhWZú·ÚJZu]CZÅï!„°VÚÆÂÂüþߦe ÂÃ/%Íg`ŸÞÊ+6³³ÓëLó¯^}GÎïkk Œ/"ŒNPw~þJIœ;—n\~þü„ØØÿIIQß`XYùž‹‹¿„ÂXi V®œØ¯ß¯›ÜÊÉùã AÑíÛzzº*3ê–\°ÄX=[°uëÜÈÈvNNކµè¯Ý¯àèè 8ï?úæ›Wäí±cËLï‚d¶!„°VÚ‚›7×uèÐvÏžšî–ÊÊšçïïi“Ù‚¸¸(Y»ám›6¾7ά¨x÷Ê•7MWgÝu ãÏŸÿ«élÁ˜1ÝF~pìØî¦·\poBa ¬´›6%GGßUïWâA ssÿ$cðúõÓÃÂümroAZZbRÒ­"øúzdgÿAQ!•‹osss1þ'B|üÝkÖL’ÄêÕ¿ëÕë㛽¯k „ ÆSjê!CºØIc:ó”C„Â` B!l¶!„˜§B!„š°!„´(Uÿ¿€í€B¨mÑáne;öP||‡‡“¨W¯àãÇbLmü&a BÙf¶@5Ý{¯Ï /ü²¸¸·H÷Ýçƒ-¨‹Ækút\uPƒ8Ic B5%[àææX^ÞGIKÂÝÝÉNFú%K"ÃÃÝ=<œ$!9—/÷80TZÛ©“o^^Õü‡ñ,ˆqUiU’“žØ:8¸uff'ölÛvT”·‹‹Ãm·¹¯^}·NIqƵ­ŽŒÜöÌ™8’gÏÆuîì'|îÜ_ÚÙ¿ÈŠQ’WIó@!Ô¨¶`РЅ ;È +’Ä!aöp +«0 Íwßõ¸t©W’3iÒm'þWYÙËý¬‘¦íÔ±ª:%G†äÒÒ‡32ôÒiø†>úmEEŸ'bÛ[b †¯ÁŒÙvÖ¬;¥G3fü·¡RD„—4©COIó@!Ô¨¶ ?¿ç/~ᩜmKBÞÚ‰-P©¡¡®rz-‰ââÞ.ÖÙU’#A2Þ;99è´'<Ü}ñâˆÃ‡»IIË/"舠 ÖÊÖ>w®§q;çÏ¿+660%å.~!„Ûôé¬Ü[PTÔK†¢Þ½ƒíóv¶EŽŽò‘ƒC+ëlÎZô=PNNÌ A¡íÛ»yz:)“üu¿W :\r_ITVö5.ÿÍ7U‡K~ˆB![Þ[põjykŸ¶ ];·²²‡Í¾yógBéÑÅ‹ñõe Êʺßßߥ^úÜúüyÙ‚1cÚÝnìØöüB5¶-ˆŠòNI¹«¨¨WqqïÔÔ_Þs\DPåLž|û´iw\¹Ò;/¯‡jÈ p‘³yÃÛˆ¯ŒŒ»ÅCÌ™sg}Ù‚„„°Üܯ ¬_ÿë°0×zéã¨Qí¤…bÅ’“oÝ[pðàƒ;z]¿Þ72ÒëСù „j([ yßþ‘#Ýãâ‚ÜÝD’8z´»}Ú‚’’Þríééî¾fÍ=Æ-ZÔÁÃÃÉ°ÈæÍäD<0°uzzT}Ù‚uë~-nÃÙÙA\ÔŽÑõÒÇ3g⢣ýÜÜÿ‰¤ônõê»{õ æ7€B¨ag B!„-@!„¶!„B-Ø@ [ØÀ¶°€-l` [ØÀ¶°€-l` [ØÀ¶°€-l` [ØÀ¶°€-l` [ØÀ¶°Õ¶`õÊe!„jáºe Z@ãÒC°Õuþl¶@ÞûïÿC!„P£©!†`«ëÄ „BØlB!ÔtlÁWû¿<óõvIdgïÉüäã/v~¾âõ×c B¡g öÿóó ioڼɓ4>éÙyÏb B¡–xaS懟|²U'ŽêÓõž¤¤¦<7ïÙ÷×½Ó¨¶@¹;ÑÁÁÁËË+22bâ“ãs¾Ìæ‹D!„Úüß×ûOüûk%übÚ‘o—~<¯êÆ™¿Î!‹Äõ8rä¨Å/ÿ©±m’øú_û3?ü qìèÝŸmç»D!„Ô|¸nÙço%ïùâóW3ÖlúýýUoô«úçûUÅyUU%kæmÓ¦”Ù›õvÝm,Rk[`ÐïŸ~êÑGüÇÈ|5tH‚W5Æ&È[ÃRxa~»vm###>Ú¼AÉ?v4÷©‰Innnýúöù×Áö „BØs–,õ³ ß½p_ÕÊ>¹‹]xãwU¹k«.ÿ¿ªª‹Ç÷n‘¬¯ëE¥¼õ¶àóÝ;‚ƒƒ”ôø'Æ=Ô½Û¾dù÷Ï|0&iüㆥdÔß›½ëëífÊïïŽú•’?õ™ÉÄtýâó]bzlÔÈáì!„°:e.ÿ-áâÊQ}ºß–©ÝÊÖŽ/xsRÕõŸ¿ |ºk׎ºØÃ“Ž­·ßù—³³³’ Ù±ýc%ýéö­Ê„†²Ôþþý?W899)évíÚnÏÚ¢¤ÅI²O „Âh~š¶êÍœ¥#ò—ÄN>à½'ï¯zwäŽY±ûÿðhÕ;ƒoúÓ'Û³¶}œY—Û=Af B‚ƒ•´Œ÷ÇŽæ.†ÕR†·RÀø9‹ì!„°¦­~ûý׿Ž+Ië6lØÐÃ#ªÞxxÃïîmâÃU+ûfMN^ôÊï¼›™>åÿ²×Yg Tž N÷<öØ#†Ù‚Ÿ~b˜-·ú¶ ,,toö.ö„BÈܾþõy›V>ÿÂ’å'6¤üqTç…n¯z­ÓÊQ÷=½bì¹w/\ú—ÿÌÇï;xàïVØÓy+þ‰p óÃÆ%Ž1þ'Âã}¨û¾d‹ºu{à‰ÇõmÁŒéÏ<Ô½Û®ÛŽÍݺeS¿¾}Ø'Ba Œ3s}¹)s³$þ9û7Ïuou~aä‹ýn>tXÞ’¸+«ÝõÁª=ŸïªËý ¦ž v÷(³ý‘žœ0^€áÓù†$ ò¬FòVßüû›¯gΘªüCá—¿¼kÙ+bŸ@!„-Ðütÿ“®;ft|¾{«WÆüöÒÿ>ðåÂÏ¥ßyoÝ?>˜ÿÿþý/ëêÔôµ°!„²‰-8üêˆìqûæþöëͯ¼85qIú›Jþ‡ëÓ¿Úÿ¥uêxlB!d×¶À 9‹ÿòÆ;ï×±N}O€-@!„š€-Ø´uËçkç×±Îç °!„P°_çæ¼¿êźÔY£'àÞ„B¨É\D¨K–xlB!Ôümåž[€B5ÿÙ‚Z-xËT@£ÓCp]êlÅWØÀ¶°€-l` [ØÀ¶°€-l` [ØÀ¶°€-l` [ØÀ¶°€-l` [ØÀ¶°ØÀ¶° ÇÿÏ·Ž‘ölö«IEND®B`‚Cython-0.23.4/docs/src/quickstart/demo.pyx0000644000175600017570000000256312606202452021611 0ustar jenkinsjenkins00000000000000from time import time from math import sin cdef double first_time = 0 def timeit(f, label): global first_time t = time() f(1.0, 2.0, 10**7) cdef double elapsed = time() - t if first_time == 0: first_time = elapsed print label, elapsed, (100*elapsed/first_time), '% or', first_time/elapsed, 'x' # Pure Python py_funcs = {'sin': sin} py_funcs.update(__builtins__.__dict__) exec """ def f(x): return x**2-x def integrate_f(a, b, N): s = 0 dx = (b-a)/N for i in range(N): s += f(a+i*dx) return s * dx """ in py_funcs timeit(py_funcs['integrate_f'], "Python") # Just compiled def f0(x): return x**2-x def integrate_f0(a, b, N): s = 0 dx = (b-a)/N for i in range(N): s += f0(a+i*dx) return s * dx timeit(integrate_f0, "Cython") # Typed vars def f1(double x): return x**2-x def integrate_f1(double a, double b, int N): cdef int i cdef double s, dx s = 0 dx = (b-a)/N for i in range(N): s += f1(a+i*dx) return s * dx timeit(integrate_f1, "Typed vars") # Typed func cdef double f2(double x) except? -2: return x**2-x def integrate_f2(double a, double b, int N): cdef int i cdef double s, dx s = 0 dx = (b-a)/N for i in range(N): s += f2(a+i*dx) return s * dx timeit(integrate_f2, "Typed func") Cython-0.23.4/docs/src/quickstart/cythonize.rst0000644000175600017570000001307212606202452022666 0ustar jenkinsjenkins00000000000000Faster code via static typing ============================= Cython is a Python compiler. This means that it can compile normal Python code without changes (with a few obvious exceptions of some as-yet unsupported language features). However, for performance critical code, it is often helpful to add static type declarations, as they will allow Cython to step out of the dynamic nature of the Python code and generate simpler and faster C code - sometimes faster by orders of magnitude. It must be noted, however, that type declarations can make the source code more verbose and thus less readable. It is therefore discouraged to use them without good reason, such as where benchmarks prove that they really make the code substantially faster in a performance critical section. Typically a few types in the right spots go a long way. All C types are available for type declarations: integer and floating point types, complex numbers, structs, unions and pointer types. Cython can automatically and correctly convert between the types on assignment. This also includes Python's arbitrary size integer types, where value overflows on conversion to a C type will raise a Python ``OverflowError`` at runtime. (It does not, however, check for overflow when doing arithmetic.) The generated C code will handle the platform dependent sizes of C types correctly and safely in this case. Types are declared via the cdef keyword. Typing Variables ---------------- Consider the following pure Python code:: def f(x): return x**2-x def integrate_f(a, b, N): s = 0 dx = (b-a)/N for i in range(N): s += f(a+i*dx) return s * dx Simply compiling this in Cython merely gives a 35% speedup. This is better than nothing, but adding some static types can make a much larger difference. With additional type declarations, this might look like:: def f(double x): return x**2-x def integrate_f(double a, double b, int N): cdef int i cdef double s, dx s = 0 dx = (b-a)/N for i in range(N): s += f(a+i*dx) return s * dx Since the iterator variable ``i`` is typed with C semantics, the for-loop will be compiled to pure C code. Typing ``a``, ``s`` and ``dx`` is important as they are involved in arithmetic within the for-loop; typing ``b`` and ``N`` makes less of a difference, but in this case it is not much extra work to be consistent and type the entire function. This results in a 4 times speedup over the pure Python version. Typing Functions ---------------- Python function calls can be expensive -- in Cython doubly so because one might need to convert to and from Python objects to do the call. In our example above, the argument is assumed to be a C double both inside f() and in the call to it, yet a Python ``float`` object must be constructed around the argument in order to pass it. Therefore Cython provides a syntax for declaring a C-style function, the cdef keyword:: cdef double f(double x) except? -2: return x**2-x Some form of except-modifier should usually be added, otherwise Cython will not be able to propagate exceptions raised in the function (or a function it calls). The ``except? -2`` means that an error will be checked for if ``-2`` is returned (though the ``?`` indicates that ``-2`` may also be used as a valid return value). Alternatively, the slower ``except *`` is always safe. An except clause can be left out if the function returns a Python object or if it is guaranteed that an exception will not be raised within the function call. A side-effect of cdef is that the function is no longer available from Python-space, as Python wouldn't know how to call it. It is also no longer possible to change :func:`f` at runtime. Using the ``cpdef`` keyword instead of ``cdef``, a Python wrapper is also created, so that the function is available both from Cython (fast, passing typed values directly) and from Python (wrapping values in Python objects). In fact, ``cpdef`` does not just provide a Python wrapper, it also installs logic to allow the method to be overridden by python methods, even when called from within cython. This does add a tiny overhead compared to ``cdef`` methods. Speedup: 150 times over pure Python. Determining where to add types ------------------------------ Because static typing is often the key to large speed gains, beginners often have a tendency to type everything in sight. This cuts down on both readability and flexibility, and can even slow things down (e.g. by adding unnecessary type checks, conversions, or slow buffer unpacking). On the other hand, it is easy to kill performance by forgetting to type a critical loop variable. Two essential tools to help with this task are profiling and annotation. Profiling should be the first step of any optimization effort, and can tell you where you are spending your time. Cython's annotation can then tell you why your code is taking time. Using the ``-a`` switch to the ``cython`` command line program (or following a link from the Sage notebook) results in an HTML report of Cython code interleaved with the generated C code. Lines are colored according to the level of "typedness" -- white lines translate to pure C, while lines that require the Python C-API are yellow (darker as they translate to more C-API interaction). Lines that translate to C code have a plus (``+``) in front and can be clicked to show the generated code. This report is invaluable when optimizing a function for speed, and for determining when to :ref:`release the GIL `: in general, a ``nogil`` block may contain only "white" code. .. figure:: htmlreport.png Cython-0.23.4/docs/src/quickstart/build.rst0000644000175600017570000000564412606202452021757 0ustar jenkinsjenkins00000000000000Building Cython code ==================== Cython code must, unlike Python, be compiled. This happens in two stages: - A ``.pyx`` file is compiled by Cython to a ``.c`` file, containing the code of a Python extension module - The ``.c`` file is compiled by a C compiler to a ``.so`` file (or ``.pyd`` on Windows) which can be ``import``-ed directly into a Python session. There are several ways to build Cython code: - Write a distutils ``setup.py``. - Use ``pyximport``, importing Cython ``.pyx`` files as if they were ``.py`` files (using distutils to compile and build in the background). - Run the ``cython`` command-line utility manually to produce the ``.c`` file from the ``.pyx`` file, then manually compiling the ``.c`` file into a shared object library or DLL suitable for import from Python. (These manual steps are mostly for debugging and experimentation.) - Use the [IPython]_ notebook or the [Sage]_ notebook, both of which allow Cython code inline. Currently, distutils is the most common way Cython files are built and distributed. The other methods are described in more detail in the :ref:`compilation` section of the reference manual. Building a Cython module using distutils ---------------------------------------- Imagine a simple "hello world" script in a file ``hello.pyx``:: def say_hello_to(name): print("Hello %s!" % name) The following could be a corresponding ``setup.py`` script:: from distutils.core import setup from Cython.Build import cythonize setup( name = 'Hello world app', ext_modules = cythonize("hello.pyx"), ) To build, run ``python setup.py build_ext --inplace``. Then simply start a Python session and do ``from hello import say_hello_to`` and use the imported function as you see fit. Using the IPython notebook -------------------------- Cython can be used conveniently and interactively from a web browser through the IPython notebook. To install IPython, e.g. into a virtualenv, use pip: .. sourcecode:: bash (venv)$ pip install "ipython[notebook]" (venv)$ ipython notebook To enable support for Cython compilation, install Cython and load the ``Cython`` extension from within IPython:: %load_ext Cython Then, prefix a cell with the ``%%cython`` marker to compile it:: %%cython cdef int a = 0 for i in range(10): a += i print a You can show Cython's code analysis by passing the ``--annotate`` option:: %%cython --annotate ... .. figure:: ipython.png Using the Sage notebook ----------------------- .. figure:: sage.png For users of the Sage math distribution, the Sage notebook allows transparently editing and compiling Cython code simply by typing ``%cython`` at the top of a cell and evaluate it. Variables and functions defined in a Cython cell imported into the running session. .. [IPython] http://ipython.org .. [Sage] W. Stein et al., Sage Mathematics Software, http://sagemath.org Cython-0.23.4/docs/sphinxext/0000755000175600017570000000000012606202455017171 5ustar jenkinsjenkins00000000000000Cython-0.23.4/docs/sphinxext/ipython_console_highlighting.py0000644000175600017570000000532412606202452025505 0ustar jenkinsjenkins00000000000000from pygments.lexer import Lexer, do_insertions from pygments.lexers.agile import PythonConsoleLexer, PythonLexer, \ PythonTracebackLexer from pygments.token import Comment, Generic from sphinx import highlighting import re line_re = re.compile('.*?\n') class IPythonConsoleLexer(Lexer): """ For IPython console output or doctests, such as: Tracebacks are not currently supported. .. sourcecode:: ipython In [1]: a = 'foo' In [2]: a Out[2]: 'foo' In [3]: print a foo In [4]: 1 / 0 """ name = 'IPython console session' aliases = ['ipython'] mimetypes = ['text/x-ipython-console'] input_prompt = re.compile("(In \[[0-9]+\]: )|( \.\.\.+:)") output_prompt = re.compile("(Out\[[0-9]+\]: )|( \.\.\.+:)") continue_prompt = re.compile(" \.\.\.+:") tb_start = re.compile("\-+") def get_tokens_unprocessed(self, text): pylexer = PythonLexer(**self.options) tblexer = PythonTracebackLexer(**self.options) curcode = '' insertions = [] for match in line_re.finditer(text): line = match.group() input_prompt = self.input_prompt.match(line) continue_prompt = self.continue_prompt.match(line.rstrip()) output_prompt = self.output_prompt.match(line) if line.startswith("#"): insertions.append((len(curcode), [(0, Comment, line)])) elif input_prompt is not None: insertions.append((len(curcode), [(0, Generic.Prompt, input_prompt.group())])) curcode += line[input_prompt.end():] elif continue_prompt is not None: insertions.append((len(curcode), [(0, Generic.Prompt, continue_prompt.group())])) curcode += line[continue_prompt.end():] elif output_prompt is not None: insertions.append((len(curcode), [(0, Generic.Output, output_prompt.group())])) curcode += line[output_prompt.end():] else: if curcode: for item in do_insertions(insertions, pylexer.get_tokens_unprocessed(curcode)): yield item curcode = '' insertions = [] yield match.start(), Generic.Output, line if curcode: for item in do_insertions(insertions, pylexer.get_tokens_unprocessed(curcode)): yield item def setup(app): app.add_lexer('ipython', IPythonConsoleLexer()) Cython-0.23.4/docs/sphinxext/cython_highlighting.py0000644000175600017570000001725612606202452023604 0ustar jenkinsjenkins00000000000000import re from pygments.lexer import Lexer, RegexLexer, ExtendedRegexLexer, \ LexerContext, include, combined, do_insertions, bygroups, using from pygments.token import Error, Text, \ Comment, Operator, Keyword, Name, String, Number, Generic, Punctuation from pygments.util import get_bool_opt, get_list_opt, shebang_matches from pygments import unistring as uni from sphinx import highlighting line_re = re.compile('.*?\n') class CythonLexer(RegexLexer): """ For `Cython `_ source code. """ name = 'Cython' aliases = ['cython', 'pyx'] filenames = ['*.pyx', '*.pxd', '*.pxi'] mimetypes = ['text/x-cython', 'application/x-cython'] tokens = { 'root': [ (r'\n', Text), (r'^(\s*)("""(?:.|\n)*?""")', bygroups(Text, String.Doc)), (r"^(\s*)('''(?:.|\n)*?''')", bygroups(Text, String.Doc)), (r'[^\S\n]+', Text), (r'#.*$', Comment), (r'[]{}:(),;[]', Punctuation), (r'\\\n', Text), (r'\\', Text), (r'(in|is|and|or|not)\b', Operator.Word), (r'(<)([a-zA-Z0-9.?]+)(>)', bygroups(Punctuation, Keyword.Type, Punctuation)), (r'!=|==|<<|>>|[-~+/*%=<>&^|.?]', Operator), (r'(from)(\d+)(<=)(\s+)(<)(\d+)(:)', bygroups(Keyword, Number.Integer, Operator, Name, Operator, Name, Punctuation)), include('keywords'), (r'(def|property)(\s+)', bygroups(Keyword, Text), 'funcname'), (r'(cp?def)(\s+)', bygroups(Keyword, Text), 'cdef'), (r'(class|struct)(\s+)', bygroups(Keyword, Text), 'classname'), (r'(from)(\s+)', bygroups(Keyword, Text), 'fromimport'), (r'(c?import)(\s+)', bygroups(Keyword, Text), 'import'), include('builtins'), include('backtick'), ('(?:[rR]|[uU][rR]|[rR][uU])"""', String, 'tdqs'), ("(?:[rR]|[uU][rR]|[rR][uU])'''", String, 'tsqs'), ('(?:[rR]|[uU][rR]|[rR][uU])"', String, 'dqs'), ("(?:[rR]|[uU][rR]|[rR][uU])'", String, 'sqs'), ('[uU]?"""', String, combined('stringescape', 'tdqs')), ("[uU]?'''", String, combined('stringescape', 'tsqs')), ('[uU]?"', String, combined('stringescape', 'dqs')), ("[uU]?'", String, combined('stringescape', 'sqs')), include('name'), include('numbers'), ], 'keywords': [ (r'(assert|break|by|continue|ctypedef|del|elif|else|except\??|exec|' r'finally|for|gil|global|if|include|lambda|nogil|pass|print|raise|' r'return|try|while|yield|as|with)\b', Keyword), (r'(DEF|IF|ELIF|ELSE)\b', Comment.Preproc), ], 'builtins': [ (r'(? 1000: kmax = 1000 k = 0 n = 2 while k < kmax: i = 0 while i < k and n % p[i] != 0: i = i + 1 if i == k: p[k] = n k = k + 1 result.append(n) n = n + 1 return result Cython-0.23.4/docs/examples/tutorial/primes/primes.py0000644000175600017570000000051012606202452023761 0ustar jenkinsjenkins00000000000000 def primes(kmax): result = [] if kmax > 1000: kmax = 1000 p = [0] * 1000 k = 0 n = 2 while k < kmax: i = 0 while i < k and n % p[i] != 0: i += 1 if i == k: p[k] = n k += 1 result.append(n) n += 1 return result Cython-0.23.4/docs/examples/tutorial/great_circle/0000755000175600017570000000000012606202455023243 5ustar jenkinsjenkins00000000000000Cython-0.23.4/docs/examples/tutorial/great_circle/p1.py0000644000175600017570000000043612606202452024135 0ustar jenkinsjenkins00000000000000import math def great_circle(lon1, lat1, lon2, lat2): radius = 3956 # miles x = math.pi/180.0 a = (90.0 - lat1)*x b = (90.0 - lat2)*x theta = (lon2 - lon1)*x c = math.acos(math.cos(a)*math.cos(b) + math.sin(a)*math.sin(b)*math.cos(theta)) return radius*c Cython-0.23.4/docs/examples/tutorial/great_circle/c2.pyx0000644000175600017570000000056112606202452024310 0ustar jenkinsjenkins00000000000000import math def great_circle(double lon1, double lat1, double lon2, double lat2): cdef double radius = 3956 # miles cdef double x = math.pi/180.0 cdef double a, b, theta, c a = (90.0 - lat1)*x b = (90.0 - lat2)*x theta = (lon2 - lon1)*x c = math.acos(math.cos(a)*math.cos(b) + math.sin(a)*math.sin(b)*math.cos(theta)) return radius*c Cython-0.23.4/docs/examples/tutorial/great_circle/c1.pyx0000644000175600017570000000043612606202452024310 0ustar jenkinsjenkins00000000000000import math def great_circle(lon1, lat1, lon2, lat2): radius = 3956 # miles x = math.pi/180.0 a = (90.0 - lat1)*x b = (90.0 - lat2)*x theta = (lon2 - lon1)*x c = math.acos(math.cos(a)*math.cos(b) + math.sin(a)*math.sin(b)*math.cos(theta)) return radius*c Cython-0.23.4/docs/examples/tutorial/fib1/0000755000175600017570000000000012606202455021441 5ustar jenkinsjenkins00000000000000Cython-0.23.4/docs/examples/tutorial/fib1/setup.py0000644000175600017570000000016412606202452023151 0ustar jenkinsjenkins00000000000000from distutils.core import setup from Cython.Build import cythonize setup( ext_modules=cythonize("fib.pyx"), ) Cython-0.23.4/docs/examples/tutorial/fib1/fib.pyx0000644000175600017570000000020412606202452022734 0ustar jenkinsjenkins00000000000000def fib(n): """Print the Fibonacci series up to n.""" a, b = 0, 1 while b < n: print b, a, b = b, a + b Cython-0.23.4/docs/_templates/0000755000175600017570000000000012606202455017274 5ustar jenkinsjenkins00000000000000Cython-0.23.4/docs/_templates/layout.html0000644000175600017570000000074412606202452021501 0ustar jenkinsjenkins00000000000000{% extends "!layout.html" %} {% block footer %} {{ super() }} {% endblock %} Cython-0.23.4/docs/_static/0000755000175600017570000000000012606202455016565 5ustar jenkinsjenkins00000000000000Cython-0.23.4/docs/_static/favicon.ico0000644000175600017570000000217612606202452020711 0ustar jenkinsjenkins00000000000000 h(  ddddddKddd£dddÚdddödddüdddídddÆdddƒddd ddddddÄdddÿdddÿeee×jjj£kkkšfff«dddédddÿdddùddd‚dddddd dddädddÿdddùddd^ˆˆˆššš››› eeedddŒdddÿdddÿddd£dddddddddÊdddÿdddÿdddoQÛÿ?FØÿÂ=ÔÿÛ;Ôÿ‘;ÔÿdddddddddÇdddÇdddIdddWdddÿdddÿdddáddd]àÿ¹TÜÿÿIÙÿÿAÖÿž;Ôÿfddd±dddÿdddÿddd©x<;£s8œmäý¼câÿÿYÞÿÓNÛÿ¼D×ÿª<Ôÿ•;Ôÿdddædddÿdddÿddd`¯~@ͨw;ÿvÞð¹pæÿÿhäÿÿ]àÿÿQÜÿÿFØÿÿ?Õÿ|dddüdddÿdddÿdddMµƒDî®}?ÿ£ƒOË‹©•¼†¦”½~«ŸºaßüâVÝÿÿMÚÿždddôdddÿdddÿdddS»ˆHÉ´ƒDÿ­|?ÿ¦u:ÿŸo5ÿ™j1ÿ©›ºeãÿÿ\àÿydddÌdddÿdddÿdddo¾‹J-¹‡G‘³B²¬{>¼¤t9èžn4ÿŒ’tšpæÿiäÿddd{dddÿdddÿddd´¹†G¡±A±«z=ÿ¤t8ÿŸo4fddd ddd!ddd!dddddddddçdddÿdddýddd6½ŠJN¸…F¬±AÊ©x<§£s8dddddd²dddÿdddÿddd£ddd>dddödddÿdddèdddAddd dddœdddÿdddÿdddÐdddddd9dddßdddÿdddÿdddÎddd”ddd†ddd©dddïdddÿdddÿddd°dddddd dddndddÇdddúdddÿdddÿdddÿdddîddd«dddDdddddddddddd%ddddddÿÿóïïóÏÿžžÿš›ï˜/Ÿ¿Ÿ?ßùïóóçþ?ÿÿCython-0.23.4/docs/_static/cythonlogo.png0000644000175600017570000001014112606202452021452 0ustar jenkinsjenkins00000000000000‰PNG  IHDR˜@毾csRGB®Îé pHYs  šœtIMEØ ,c$bKGDÿÿÿ ½§“áIDATxÚíy|”ÅÇ9+– H¡­V©¶ÒW¹È6ám@Å@8²lB6’D‚Kä QÀ*G8rB8B@?ÔO R¥•#BP ZP E˜þfw6™Ý¼»ûîdÙMÈûÇï³Ë›ÙwÞ÷/Ï<óÌ3ó6#„4s…&Nœø4J†Þ…r bèT ýýª†þ „ò¡P*4òƒ~áªkVTÝO ~EA™PDœ¤›Ð~ªÔZiÈ&»+´:ëD ìéGh4XiÐ04î“ÐÐ-‚%¥ãÐH¨…Ò¸`hÈîÐZènËRg h¥ûl¤€¡ábëç–¥.@JC7"ÀØhðX‹×]h¶Òm6ÀÐHзõlpÚ€æAj(zjµƒzBC¡)P:´ºíÐJ Ç”Fo€€Ñÿý ˆ{‚û‹{ERˆ¬f;C+®§¿w òQ¾F›, Ò ·XØ¢ƒC!Ù9Eý¿;Ð8¥ñ`hˆæÐÁ†¤ë‰ûÈí}*xmΡ îl`ã©]4ýÔ Jd޼£×ù4@ÀM€ááOœÆæê›@±‚–ìè . }ˆ€Co_wÝêž#'}ÔÕ×÷PLLÌ &dA>M0<ì_³QŸ£ õ¦ÜJÃÒK:«ÒÊÆª•¤«”d‡ÍÛ[òvñÑàÔ¢ãAú]õ;ó¦l_é—²}®ÒV¿fz} ™½/ÙJ7ü‡È4ÕÀTM 0‘FúÔÒ^e‹u _|°0|qÙ=Õ¢ýdÐÂ6/\$8u7\$ð­$ e8{ñKÞJ|“¶ŸY›OxÍÚÐSf8åˆ`0ÖÃÅ€e79Àp³Ï±a¼£~W{éõ¤Åàôƒ§Ã ®(\¡óöášKá*$svÿ¸ò)\Äû<â5cã Ï™Ÿ•9ºqú¹2ÚßTÛ-Ð0«åT4ä݃Á®´ý$,­$42?¿%àJ1ÀUd×À7 Œp%R¸6Q¸È€é뉇.»Tfã} ØUNvÖƒU«Õíácy(€ÕÞpˆ`£ô–SºÆñáiÔr•ž1¤ß×1˜Â¥7ÁµÝ—×L#\žÓr)`7ôúV2k uPGg$Z˜dÞ¬V{ÇD|/¹E,.‹W-,%a ö‘A öùá`ó Ô]3‚ pí$þ) ®ä|⛸…ƒkƒ®þºlÒ/>“xƯy¼!?P<“îù(€q#G‘©—±r+‚õÒ,jrêç}mpêÍàÚj€Ëg…+ ˜Q —G|é·Žxh³º(€5>ÀÆ v²­ àÒI·×Ž pm6‡+!Ç×Ôu¤Ï”5l¹X#l»\_:RQHjqÏÐÔbMPj‘&HOU¨\?ª7 4>‰[4€ë:b4µ¾®~¸Ö’Þ“W+€56ÀpƒmØÂ GÛnµ;|÷£Þ§~QéÕÂ=,—>ìíb}ÈÜ"}ÐÜB=àÒé×ÌÞ¦˜¼UEI¸NУçt—ŽÂ•‰®ÑW¯Ø #`Õ rešÞ «ÓñA®Îh+úÐÀý!º”®HfÙeT%ŽàŽwgÇ øÔmSY|_(0|ïMS“pî4|®Ç¿“äΙj4šÎ(;ÊciãßCÒ{ƒ†:ðŸäa6ý¶: ]ƒn@§ ùŽdǘ¦…DºÇ$Ë“ [r¨ûàwí7…#ŒÔ}†X—#á#\Ù5põ™¼†ôÒf°U °iÇ©U!ÕSÏjíóŽÂ…FyÊtOhÔãöÊ£L4Æ2+–KJßÛ çd+HŒ2Ë£££ÛØßå.Û¹†Ì„„„‡í¤ÂOakSù¤€Ÿ%òûfÊ,Q°A–QzÀužÂņ£.£So%±E*a1šàêÍà’¬:žËq–Kšî ß;RP 7¸gô!;Fl 0ênp¹ježæ¬Akø 1µjVÀPs‰˜ÿtП©ŒßŒ†Jø{¨]$f@ÔÜuÐÄÌÉlQOsöé •Z0ðšÀ–9#þ‘þaND:…«Œ¨$àr4AGŒÔ©çá2Ì`µÖ€KÈÅI„|9ßÏ€ÕÇcç¢IÏK”Ç'Œ?þi‹¿w3¥”ãU¸¾:³*‘‘‘-ù®er-ÎÑ…«£‚ºM6ò˸²Gå¶E°n5#Ä%û:F¤¼e€kQ)1 G¤ÙሄÚp„®ÕfpQõUg´'Wtè©ÕšL­àR¬ „|MÈ…1[`8gœÕjÖŒ6êW\c-γ•«o”™…Ö Zî@íg°ã2¦âLeoËì#AÀ:pÝãZ¸¬M`× GxÛGúUʸ@®i«u—\ÒòV pá¹_ˆ‚^»Ñس7ŠdN»éÓ9hzòë ôvf9ðÛÙ\ùbAÀZ³=D åå&²Ìÿ?1ž~@ÇgGÔL`KfGÔN`Û GÔ… Òd¼…îp°±K4Y­qÔjRõ:!ç_%¤r$ý|üLÍ]ã*ÎïËÏ—1?Êù•`¬üUG».˜ÙˆHµpÿò:pÙÏŽ°ލ—vUéáÉ¢K¬$c˜ÕŠ6Z­ªÑ€êÀIȹ—¡áÞ`¨ó)ÀXÈÀT×{ö®Ýâ#|;ÆÆÆ>ê Àn ö­9`%%5N½üpÄ·€«ÜC—S¸ÊW9FŒå½´åʤ“½4«vöŽ]¥¹Q× ]ânC—h°Z´K„ÕªÂ@æ<\Ê¿¬—© j €Q«Å#IÎýâ7?˜~à¼\Ø" ;,¦>•ޏã=sã|¯„õÝ ‰lIªtlêbBGrYë «5\йÊ9òœÕi´Z#9; LHyxJ±`9\]oÉ ¢ÞæÎÕË€‰nP9·w»õpÄVŽÈ»îõÆÆþ¤:¡©žVJ®L»a,僦ñ,ü`Å‘¯±Z‘Ìj½°†r&p¡­N‡Nj"€é¹ºVØ»öèèè|jµ0¹°½‚€u­gÜ“n/1`fÞDr5a8 º# •ŽÅ¶&»Ž¼¡KaìÏ\á€kà !äTÐÀ&Ø®®]2œüç¸òW]åäç V³Ü+øíâI6Ã36Uæ ¯L»b.³ˆ< PGþ5sG¾Æj fV+ \„üË»³`4PÙ˜Ãï^àêºak*‰•âʹ °%‚€™N8·(ØŽ1nÈ`AÖ»D>"¯&fŽ<µZU¯Öuä V+‚Y­Pjµ9éOÈ ¿o‰ƒEEEµåæÚî=º]}ñrBÎŒg÷·vÎsÐTÖÌÓU€Í,Þt’¾êŒÖpêÏ›¹pDÿéë“Òé.‘ÈÇÙŽ¼¡K c]b àB¯xÂòY"bÃoA°ÔNÙ[€adö9S)Î  ôá-ð¸qã:Yé=¹ÍkŠlL90OAÀÖò' HÙ6±N8‚M`{$ä&±×9Ù‘gV+€Z- Õmrʯ«`c,îí~B˜:Ãlëª-æ—Y9_%·Â€û û;¿ÅÃß,AioÃ…'.Lš4éYWÖBpϯ#ü‰¨óKÊ?/™‘ÅÆ;ò G~t­#ÎäÈ“päY—èk‚ ò^^DÁw$î‘æA³XwSjÚF"uæg.Câï86ç~ÆêœÈeTPKõ‹“}ÉÃGsÆ$îýþÆ~P ¸»³Ùb[ߤÍ=×Ç–Ù}ã×39ò—œàȺD^ÛH…g;QÀX#©pOŸXä?Ýf“Ä+hÊ…5ÛÖ´ þ¾ƒ›)ù^hºÅç”ó·s]CMeiôÞF9zm¹ImÂ,× 8Ý®À 0¸óï‘Ø'¦òrS v“ÁR'õ˜™ÕÅcÚ†`X.•ÇÔ,Uÿ)kºÁ×ÒÙuä«F-$ç"U°ZÐ0(BEÊ©AÁ*r’*ò­Õ Ÿ@GFìуú34›ÁâáŽâ,Ï2M»¹2U™æ§Ñ{°¼~wåäw,CveÕ“uvùÊ—?"gGdчg£K„²aµ²Ñ%B³É±önιOæ‹rçµ4¶u‘§ûZΞ]RëŒVËäÈ¿.áÈ·ïÈŸ pë¢X…uÜ\ž²ƒµ€E Z±PY•}1^'àÈ_&§üKàÈß­ñµÜ Mƒ6ù Ö|EÒ€µâ†×ލX`Ñq9ò§ý¿"áÆüÜ;¶°Oý:¹ëa±|ªåNÍ(ª»ùÉxA+æe·²Ê1!æùù."ï{°æ·'½ú­—Ï57Z® è"»ßëtšFÈqÀ¨;/X™ÝÊ®Fµ%•£.ÔZ­aF«U‘¶ŒÈ£[ôŽ\½Vi}ã\Ž #È'hx€†"ðy˜O¶Ä±pñ è&83da¦Š—úÀת”‘—w© h#ÃÒ¨ØÎ6·ÐQ~% ØäDóÐÿŠnRy™C=k!±þMŽ.ó)™žžÞ–Š~§Ç¡_ØZ©Ì–°Ÿ¸¦rº©‡Òø èu~¬A5ÝiúÞ -]º´àz êš™™ùDVVÖSÙÙÙÏlÞ¼ùú™››Û zråÊ•¿…:ÀŽiiiP袢¢è›ßÂè¾YüòuTz¿­ª"AÀdalS3áwik4šùÉÉÉž¬œœœÚ±cG¯ÂÂÂ~EEE}vîÜÙ3//ï9 u:uª?}¿¿RºéÖæ­”FoÀ€1ÈþÈÞïSŸ·ÏÒŒËË111ŸœR@·166v™V«ï«q¬;ʦfîÔ³.ú{­ÒØ0.re=ß>ë –5Oª¨aÆö4[¾~·ECaJ7rÀ8Оgyý÷Ü Þ¢4ì˜Eè`9¿èÀºÆ6h{‘N)ú&±w¨šY¶ïœÔ-6çH7Ûí¥@ÕD³€­%]€Êbi³ÙÆÃtyÝýøŸlbý'¶æg?cmbï¯Ô³íµCéîJÃ5ý:S’ )øÇIEND®B`‚Cython-0.23.4/docs/_static/cython-logo-light.png0000644000175600017570000001011712606202452022637 0ustar jenkinsjenkins00000000000000‰PNG  IHDR@õxþ—sBIT|dˆ pHYsˆˆštEXtSoftwarewww.inkscape.org›î<ÌIDATxÚí tTÕÇY+¤‚ÐV+ŠV[éa !ÙÃ$l¢eBK&,àÙB°Ê¶,@€–$О¤•%’!{B°·ÿ;sgrg2Ë››ÉdHžçüOâË›wß¼ûã»ßrï}!¡²²²¡‘Ðè3( Ê„N@ùÐ-è—2íÿŽ@©Ð*(š yA¿qÔ=˲®ÚæÐh#¤†ˆt:Ä@tƒšËYOBgv„–B—íŒ5ýí‡úÉú˜„Î{úºç@pLé 4j"wîc:ª3´ú_ƒc¬KÐhyxsR€Ð1O0‹ó«“c¬«¯ÜÑN‹¦N998¼BsåaÍ B'„@7kØ¡t¸; -€B¡`è ¨5Ô ê €&CqÐ>è¾@Ê‚ž•;½¢ÿzY‡?ì¼ÿ²¼Ï ‰€ÕkÅrH™5ô·J ¹ãMܱ0Y¤Ãî±°¾SmÙ5Eý¯Ð¹ótch³`GQ‹ó|-&*»C§ïÂ7@ öZ$Ø9¡*4ƒ¢˜£lë}þ õ–!¨%€ðp'–:úK Í‰‚–èèÏ2vµ¿€A[Ϻú"h{ž D´N÷Œ£ï7//ï‰ŠŠŠþ¥¥¥ G½ów,j²µ#>’ÚhP\V{ElÎ(Å’¬8Å¢¬Ä 2>É<é“qÆOµ÷°¯jOjŸè]«½¢wÍ÷ž½Ã«‘JÕD"D_B´ÚѾ¼¼|#×¾¢>$Ò ÿ‚šZk,déÑÁK¤/Íy¤Xrˆô]œE‚ €‡øÇì#€‡ø~¼‡øDï&}æî$^svÏÙۉǬmçÜfmî"1ÝpB0Ùèâ`‹™XïÂy…¹¶ú=¯ZkH¥"Múʼô0aðÜ¢ð.د…g>…'øÌÛM¼õð¤Rxˆû‡)ÄmÆ–;®3·¼"1:qªO92[]_Ú'ðà×Ji¨ÿgGüC(<±‡HPlVàÔÔ¦€gN€ž xú|”¦…'ŠÂ³•ÂCzOßD\”‰Ù;çKÁ¡l’½ìÍ›7[c˜ri0áK>ônRÂÐ568–ZžìKºc}UÛúSxT:xviàñâᙩ…ÇuZ2è®JÕL@Í¡j[ÓZRRB'Ò¥Ñ$*ÚÖ:*âûHm(diN„bq6 Ztô]tÐ ûÅìá§gñŽfðÌI%žQÛ9x6kàé¥L$=#6׈uÏ9ó4>ºçÓ`b‘—Hi`”Ô†`}”‡êœæù×5N³<;4ðxÌ¢ð¤Þ3ªàq‰H =¦l .á d€œ Q‚×dkx”¦#®]U—žm†ðD&iᙺtŸ¼­”rB€v ÀSdKC1™]c2Ãüb2ÂüTTéa€'̋ꣴ0¨ía€ç[qiáÙ¤‡§§žõ¤Û¤µ2@În¾›˜n+@»ÌWŸ}ÝMã4/Éž§Xœ¥‚åQ}’© ˜Ÿ¡ò›Ÿ®<*8Í*Ÿ¹;U}æìPyÎÙ®òŒÚª<çhÄå:Á£¤ðlÄÐ¥…§ëÄx-@e‘a¤|šJ£ŠéQøB*f´¬A§÷¢KJKK3$ž»‚i°îxqqqgv,Íhj­îÜÅRÂ=tC#¡XßÍ®¨¨T³Ãyíñ¹éøL kûGè+öÝØbx’•‡6@Ç JètZÈϮЕ-D†¯ÙÆ \v´s¿OÒ…ëÚDáAM®Ç–p] O¢žî“Ö‘®áñh hÚ@CªIHÙÔK¤,üux^ä'åK84wþ S–ÇŒ~´Ô×R¬T«Õ-ÌÝ-‡àJ-ÝÍ~ô'­LUžÌÖæñEç_MÌïš©(J ¾ÆYfÀS@áaáº&âÒÀ£ušÍ„ëÛM…뚈KO7I€Ê")…Rv¸®BÇÐyJ tä‡Üß¿bp(Þû[¨H7W ×ÏÁ5TÐüÿ:>)J­’™Žå&ÚÝ€”¸Ÿ¿]»ví9üþ›©ÿŽ•••LdðC¹û ï&±EYZ¤”mÄÀðF̼Ö8ÿ÷URH…'‡(LÀck¸N#.ê4óð¤±:g2À™HHñBŠÆAc{Ö@5ô›´÷º Ë2†/XŠ—Œ†­NÜ”_5@5Uhj4´&ÝKîoyÔ­±0?,‡;÷$=¸] NúkÙÁ¶!qGîiàY’M Âõ˜ "9\¬ ×µð¬5€‡ªGh|kR®ÄpE­Î$juO(Àù€ÂÑ„\¹ãqL±Ð&í´kÜ5G]gwa®ÓŸÍcçÒ©É=ÍtFB©Hwî}zàkA€ÚpÃWÿ*xÌH«‡ëîÂu­Ó¼ÆHñWIeøS°:II8oužëÕÐð;¡RXé´’8Îútáç{ãX3+י˟)Ps¶‡æüF‚Ëñ…Çà¸ÃJ¾º®/š¬®WH-…ëÕáÂâ?ÆpÕO;dé¬ÎjuQ¿OHÁ»„ä¥?Ÿ«g…rç®áÚâów©¢4¸k"±ó+x€n dQ(ZY ëÕu‹áz5xÂ×d;õ †¬|R<žYÑZ«£~мx†råmh{}VçS±Zwüsk÷~ýúõ§ù~,,,|ÆÝè¦!@YYz§Yz¸~ðäº(“rO.àÉEÄ•‹p=Àèt¾kØš=Ý&® »“7¥†¬}š!Kcuè«£x0ôçÿà¼EHÞ hÀˆPª¥´Š™voé>‡ÛÍŠLœ7*Sœ–®?pŸ¹e¡[ä¦Î„ iJÔÊ6UÙá¹;¬ÎtR2¾‚s”9«3Tkuòry ÔÜàèP×ÖǺÏÔÕ‰.SÖg~Øe>\ßÁÂõ”ÛnnéEÊ"{" Ï&åÓî&ù¤` ÏÍ8Êz«3„Y7ÎB.…ôÅÅÀ  š/⎯²vïjµº ߇•••OÙ ‚u¬ªsí³®÷ž™2ŽTD$LƒC¥d¹IĪ£¬²k‡¬ËýO0àé x¹à×§!DK\[{%tükÜu*ìåD' ¤_ãÿIæ‹áúŒ­yšZUù´r³ðd”a@ª9Êà e½ÕéǬNäx|9ëÞ^ õ㢪7¸ãw,•:X›#¸t@†½Z&Ÿî‚¾ó3üuáºéˆks2ò3?dñåPbà(S«£~·º£¬±:!ÌêR«CÈyoBÎyý`KÐ’«õ<ºqãF«š„c}¤„ÖöˆÝÏ^îoƒ­tüݹøÞ®öh† @º öo§¹À ââÂõ^Ó7Í(“MY|Fy<‘ì(k†¬ 6dùŒZçÑ;ÇU ×YÔ%29 ޳ÒÎŽ2³:>ÔêPp¨î“ ^ ª#*ß_òGêl⺵Í7FÏ`…™œ¯‹VÍMŰ@&– §ET#xü¸ðýjqqñ+ö¨‰àž?'ø‹R+„p½Àdu=2ˆw”ÃL8ÊïU9ÊWtŽò@޲/²×Ž»þ~ Ïé[Ýù¦j-¶ÈßT.3:¸LÛìË£p™š è5y]'ø:J«Ž²zØbreˆV…(H.U_È_AÎSù@žU:çákKÔ%uÝ:Áü‰ÆF9Œ³@“¥Î¤Ó.9Õ”ÎObS;;bNt'A€â%7V6IiÕQÎûkryp"e¨_"†,((V'CÔ'‘œ h]—s€Ùçºï?¢.ïÅÙÖ…]躔5ñ•„*µVGç(¿oÂQdÝQ>ïS§“êa•6py_ *€F Z¡@IŽU 8Ê¥ä‚wå‡z_§ŽbÓT5> 9Ÿ¢¡ÔŒ ?mQ¦4€FO±ÉQ¾è}äk;è{÷‰z€N{µ««‡Å㟤–ÜSx0c­›ÕÆòGf”›È(peÏ#úÏžw륵>•uÍ¥³ï{›–d€ªD­P@9V«Ñ’ä»Zeuj­Ž>£ìoœQưå>ðt8Ù5ÍóØ*DXϳðy.[¥ŸLë,Ãc~ƒ©ìÒ(ï­îðuò%d”MÈ=‡¨}ZHÌåÜcó^¤ê$¿Á(q§Ó/çòfåÖjbbý•òS<ÌêTæärH¬N‰ùŒ²Ž‘ žÜü ‰ºm¼A«gfë²Âè Ùa¶m“Ígg*~#ù‚Ôš\ôõF”Eä/ Ã€è†«Mø=š|ï1”\pÆè¨1{­÷  Z=ã÷ƒ…Ëí$q3ØV;áÛšuLRN–câ@z‰-¯}èdàÐ=Hî`'ˆéu6¯úQƒCËýåŽ}Ì2 ­W²mÒM%Û€éMZÎ;õ1ȦN,“&øþ1K/ò¥5/º™eWšz Lt“ÇÞ,—4—mì¹…íúoV¸ý™­¹*bkš($[ÙûËTlûÙ@º‡±ÜqΣÿûã:³£°.IEND®B`‚Cython-0.23.4/bin/0000755000175600017570000000000012606202455014757 5ustar jenkinsjenkins00000000000000Cython-0.23.4/bin/move-declarators.sed0000644000175600017570000000144712606202452020726 0ustar jenkinsjenkins00000000000000# Moves # # use: sed [-E | -r] -i -f move-declarators.sed [files] # Arrays # cdef int a[5] -> cdef int[5] a s/^([ \t]*)cdef +([_0-9a-zA-Z. ]+) +([_0-9a-zA-Z]+)((\[[0-9]*\])+)$/\1cdef \2\4 \3/ # Pointers # cdef int a, *b -> cdef int a \n cdef int *b s/^([ \t]*)cdef +([_0-9a-zA-Z. ]+)( +[_0-9a-zA-Z]+ +(=[^()]+)?),( *[*]+ *)([^()]+)/\1cdef \2\3\ \1cdef \2\5\6/ s/^([ \t]*)cdef +([_0-9a-zA-Z. ]+)( +[_0-9a-zA-Z]+ +(=[^()]+)?),( *[*]+ *)([^()]+)/\1cdef \2\3\ \1cdef \2\5\6/ s/^([ \t]*)cdef +([_0-9a-zA-Z. ]+)( +[_0-9a-zA-Z]+ +(=[^()]+)?),( *[*]+ *)([^()]+)/\1cdef \2\3\ \1cdef \2\5\6/ s/^([ \t]*)cdef +([_0-9a-zA-Z. ]+)( +[_0-9a-zA-Z]+ +(=[^()]+)?),( *[*]+ *)([^()]+)/\1cdef \2\3\ \1cdef \2\5\6/ s/^([ \t]*)cdef +([_0-9a-zA-Z. ]+)( +[_0-9a-zA-Z]+ +(=[^()]+)?),( *[*]+ *)([^()]+)/\1cdef \2\3\ \1cdef \2\5\6/ Cython-0.23.4/bin/cythonrun0000755000175600017570000000055612606202452016741 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python """ Compile a Python script into an executable that embeds CPython and run it. Requires CPython to be built as a shared library ('libpythonX.Y'). Basic usage: python cythonrun somefile.py [ARGS] """ from Cython.Build.BuildExecutable import build, build_and_run if __name__ == '__main__': import sys build_and_run(sys.argv[1:]) Cython-0.23.4/bin/cythonize0000755000175600017570000000016312606202452016716 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # # command line frontend for cythonize() # from Cython.Build.Cythonize import main main() Cython-0.23.4/bin/cython_freeze0000755000175600017570000001451612606202452017555 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python """ Create a C file for embedding one or more Cython source files. Requires Cython 0.11.2 (or perhaps newer). See Demos/freeze/README.txt for more details. """ import optparse from os.path import splitext, basename usage= '%prog [-o outfile] [-p] module [module ...]' description = 'Create a C file for embedding Cython modules.' p = optparse.OptionParser(usage=usage, description=description) p.add_option('-o', '--output', metavar='FILE', help='write output to FILE instead of standard output') p.add_option('-p', '--pymain', action='store_true', default=False, help='do not automatically run the first module as __main__') options, args = p.parse_args() if len(args) < 1: p.print_help() p.exit(1) if options.output: import sys old_stdout = sys.stdout sys.stdout = open(options.output, 'w') modules = [basename(splitext(x)[0]).replace('.', '_') for x in args] print """\ #include #include #include #include #ifdef __FreeBSD__ #include #endif #if PY_MAJOR_VERSION < 3 # define MODINIT(name) init ## name #else # define MODINIT(name) PyInit_ ## name #endif """ for name in modules: print "PyMODINIT_FUNC MODINIT(%s) (void);" % name print """ static struct _inittab inittab[] = {""" for name in modules: print ' {"%(name)s", MODINIT(%(name)s)},' % {'name' : name} print """ {NULL, NULL} }; """, if not options.pymain: print "\nextern int __pyx_module_is_main_%s;" % modules[0] print """ #if PY_MAJOR_VERSION < 3 int main(int argc, char** argv) { #elif defined(WIN32) || defined(MS_WINDOWS) int wmain(int argc, wchar_t **argv) { #else static int python_main(int argc, wchar_t **argv) { #endif """, if not options.pymain: print """\ PyObject *m = NULL; int r = 0; """, print """\ /* 754 requires that FP exceptions run in "no stop" mode by default, * and until C vendors implement C99's ways to control FP exceptions, * Python requires non-stop mode. Alas, some platforms enable FP * exceptions by default. Here we disable them. */ #ifdef __FreeBSD__ fp_except_t m; m = fpgetmask(); fpsetmask(m & ~FP_X_OFL); #endif if (PyImport_ExtendInittab(inittab)) { fprintf(stderr, "No memory\\n"); exit(1); } """, if options.pymain: print """\ return Py_Main(argc, argv); } """ else: print """\ Py_SetProgramName(argv[0]); Py_Initialize(); PySys_SetArgv(argc, argv); __pyx_module_is_main_%(main)s = 1; m = PyImport_ImportModule(inittab[0].name); if (!m) { r = 1; PyErr_Print(); /* This exits with the right code if SystemExit. */ #if PY_MAJOR_VERSION < 3 if (Py_FlushLine()) PyErr_Clear(); #endif } Py_XDECREF(m); Py_Finalize(); return r; } """ % {'main' : modules[0]}, print r""" #if PY_MAJOR_VERSION >= 3 && !defined(WIN32) && !defined(MS_WINDOWS) static wchar_t* char2wchar(char* arg) { wchar_t *res; #ifdef HAVE_BROKEN_MBSTOWCS /* Some platforms have a broken implementation of * mbstowcs which does not count the characters that * would result from conversion. Use an upper bound. */ size_t argsize = strlen(arg); #else size_t argsize = mbstowcs(NULL, arg, 0); #endif size_t count; unsigned char *in; wchar_t *out; #ifdef HAVE_MBRTOWC mbstate_t mbs; #endif if (argsize != (size_t)-1) { res = (wchar_t *)malloc((argsize+1)*sizeof(wchar_t)); if (!res) goto oom; count = mbstowcs(res, arg, argsize+1); if (count != (size_t)-1) { wchar_t *tmp; /* Only use the result if it contains no surrogate characters. */ for (tmp = res; *tmp != 0 && (*tmp < 0xd800 || *tmp > 0xdfff); tmp++) ; if (*tmp == 0) return res; } free(res); } /* Conversion failed. Fall back to escaping with surrogateescape. */ #ifdef HAVE_MBRTOWC /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */ /* Overallocate; as multi-byte characters are in the argument, the actual output could use less memory. */ argsize = strlen(arg) + 1; res = malloc(argsize*sizeof(wchar_t)); if (!res) goto oom; in = (unsigned char*)arg; out = res; memset(&mbs, 0, sizeof mbs); while (argsize) { size_t converted = mbrtowc(out, (char*)in, argsize, &mbs); if (converted == 0) /* Reached end of string; null char stored. */ break; if (converted == (size_t)-2) { /* Incomplete character. This should never happen, since we provide everything that we have - unless there is a bug in the C library, or I misunderstood how mbrtowc works. */ fprintf(stderr, "unexpected mbrtowc result -2\n"); return NULL; } if (converted == (size_t)-1) { /* Conversion error. Escape as UTF-8b, and start over in the initial shift state. */ *out++ = 0xdc00 + *in++; argsize--; memset(&mbs, 0, sizeof mbs); continue; } if (*out >= 0xd800 && *out <= 0xdfff) { /* Surrogate character. Escape the original byte sequence with surrogateescape. */ argsize -= converted; while (converted--) *out++ = 0xdc00 + *in++; continue; } /* successfully converted some bytes */ in += converted; argsize -= converted; out++; } #else /* Cannot use C locale for escaping; manually escape as if charset is ASCII (i.e. escape all bytes > 128. This will still roundtrip correctly in the locale's charset, which must be an ASCII superset. */ res = malloc((strlen(arg)+1)*sizeof(wchar_t)); if (!res) goto oom; in = (unsigned char*)arg; out = res; while(*in) if(*in < 128) *out++ = *in++; else *out++ = 0xdc00 + *in++; *out = 0; #endif return res; oom: fprintf(stderr, "out of memory\n"); return NULL; } int main(int argc, char **argv) { wchar_t **argv_copy = (wchar_t **)malloc(sizeof(wchar_t*)*argc); /* We need a second copies, as Python might modify the first one. */ wchar_t **argv_copy2 = (wchar_t **)malloc(sizeof(wchar_t*)*argc); int i, res; char *oldloc; if (!argv_copy || !argv_copy2) { fprintf(stderr, "out of memory\n"); return 1; } oldloc = strdup(setlocale(LC_ALL, NULL)); setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { argv_copy2[i] = argv_copy[i] = char2wchar(argv[i]); if (!argv_copy[i]) return 1; } setlocale(LC_ALL, oldloc); free(oldloc); res = python_main(argc, argv_copy); for (i = 0; i < argc; i++) { free(argv_copy2[i]); } free(argv_copy); free(argv_copy2); return res; } #endif""" Cython-0.23.4/bin/cython.bat0000644000175600017570000000040012606202452016742 0ustar jenkinsjenkins00000000000000@REM Start cython from windows commandline as "cython", not "cython.py". @REM This is especially useful for windows power shell, as no extra window @REM is used. @echo OFF python -c "from Cython.Compiler.Main import main; main(command_line = 1)" %* Cython-0.23.4/bin/cython0000755000175600017570000000017212606202452016206 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python # # Cython -- Main Program, Unix # from Cython.Compiler.Main import main main(command_line = 1) Cython-0.23.4/bin/cygdb0000755000175600017570000000017312606202452015773 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python import sys from Cython.Debugger import Cygdb as cygdb if __name__ == '__main__': cygdb.main() Cython-0.23.4/Tools/0000755000175600017570000000000012606202455015307 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Tools/kate.diff0000644000175600017570000013463112606202452017072 0ustar jenkinsjenkins00000000000000# HG changeset patch # User Sturla Molden # Date 1256723843 25200 # Node ID 0a6ce52272f641d58c874fa007187778d4c2c81c # Parent db4133d43a7ee34d4f172aced054785acba65a57 Syntax highlighting for Cython and NumPy for KATE and KDevelop. diff -r db4133d43a7e -r 0a6ce52272f6 Tools/cython-numpy-mode-kate.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tools/cython-numpy-mode-kate.xml Wed Oct 28 02:57:23 2009 -0700 @@ -0,0 +1,1133 @@ + + + + + + + + + + + + + + + as + + + cimport + import + from + as + + + DEF + IF + ELIF + ELSE + include + + + class + cpdef + def + + + cdef + ctypedef + + + extern + api + del + global + property + nogil + gil + inline + + + readonly + public + + + and + assert + in + is + by + not + or + sizeof + + + + print + + + break + continue + elif + else + except + finally + for + if + pass + raise + return + try + while + with + + + + __import__ + abs + all + any + apply + basestring + buffer + callable + chr + classmethod + cmp + coerce + compile + delattr + dir + divmod + enumerate + eval + execfile + filter + getattr + + hasattr + hash + hex + id + input + intern + isinstance + issubclass + iter + len + + map + max + min + oct + open + ord + pow + + range + raw_input + reduce + reload + repr + reversed + round + setattr + sorted + staticmethod + sum + super + type + unichr + unicode + + xrange + zip + + + + unsigned + void + enum + double + long + short + char + Py_ssize_t + Py_intptr_t + Py_buffer + bint + struct + union + enum + + + + int + float + object + list + tuple + str + dict + set + frozenset + slice + bool + complex + file + + + + np + numpy + + + numpy + + + cython + + + dtype + flatiter + broadcast + ndarray + int8_t + int16_t + int32_t + int64_t + uint8_t + uint16_t + uint32_t + uint64_t + float32_t + float64_t + complex64_t + complex128_t + int_t + long_t + uint_t + ulong_t + float_t + double_t + longdouble_t + cfloat_t + cdouble_t + clongdouble_t + complex_t + npy_int8 + npy_int16 + npy_int32 + npy_int64 + npy_int96 + npy_int128 + npy_uint8 + npy_uint16 + npy_uint32 + npy_uint64 + npy_uint96 + npy_uint128 + npy_float32 + npy_float64 + npy_float80 + npy_float96 + npy_float128 + npy_complex64 + npy_complex128 + npy_complex120 + npy_complex192 + npy_complex256 + npy_cfloat + npy_cdouble + npy_clongdouble + npy_bool + npy_byte + npy_short + npy_int + npy_long + npy_longlong + npy_ubyte + npy_ushort + npy_uint + npy_ulong + npy_ulonglong + npy_float + npy_double + npy_longdouble + npy_intp + + + DataSource + MachAr + PackageLoader + RankWarning + Tester + abs + absolute + add + add_docstring + add_newdoc + alen + all + allclose + alltrue + alterdot + amax + amin + angle + any + append + apply_along_axis + apply_over_axes + arange + arccos + arccosh + arcsin + arcsinh + arctan + arctan2 + arctanh + argmax + argmin + argsort + argwhere + around + array + array2string + array_equal + array_equiv + array_repr + array_split + array_str + asanyarray + asarray + asarray_chkfinite + ascontiguousarray + asfarray + asfortranarray + asmatrix + asscalar + atleast_1d + atleast_2d + atleast_3d + average + bartlett + base_repr + bench + binary_repr + bincount + bitwise_and + bitwise_not + bitwise_or + bitwise_xor + blackman + bmat + bool + bool8 + bool_ + broadcast + broadcast_arrays + byte + byte_bounds + can_cast + cdouble + ceil + cfloat + character + chararray + choose + clip + clongdouble + clongfloat + column_stack + common_type + compare_chararrays + complex + complex128 + complex192 + complex64 + complex_ + complexfloating + compress + concatenate + conj + conjugate + convolve + copy + corrcoef + correlate + cos + cosh + cov + cross + csingle + cumprod + cumproduct + cumsum + deg2rad + degrees + delete + deprecate + deprecate_with_doc + diag + diagflat + diagonal + diff + digitize + disp + divide + dot + double + dsplit + dstack + dtype + ediff1d + empty + empty_like + equal + errstate + exp + exp2 + expand_dims + expm1 + extract + eye + fabs + fastCopyAndTranspose + find_common_type + finfo + fix + flatiter + flatnonzero + flexible + fliplr + flipud + float + float32 + float64 + float96 + float_ + floating + floor + floor_divide + fmax + fmin + fmod + frexp + frombuffer + fromfile + fromfunction + fromiter + frompyfunc + fromregex + fromstring + fv + generic + genfromtxt + get_array_wrap + get_include + get_numarray_include + get_numpy_include + get_printoptions + getbuffer + getbufsize + geterr + geterrcall + geterrobj + gradient + greater + greater_equal + hamming + hanning + histogram + histogram2d + histogramdd + hsplit + hstack + hypot + i0 + identity + imag + indices + inexact + info + inner + insert + int + int0 + int16 + int32 + int64 + int8 + int_ + int_asbuffer + intc + integer + interp + intersect1d + intersect1d_nu + intp + invert + ipmt + irr + iscomplex + iscomplexobj + isfinite + isfortran + isinf + isnan + isneginf + isposinf + isreal + isrealobj + isscalar + issctype + issubclass_ + issubdtype + issubsctype + iterable + ix_ + kaiser + kron + ldexp + left_shift + less + less_equal + lexsort + linspace + load + loads + loadtxt + log + log10 + log1p + log2 + logaddexp + logaddexp2 + logical_and + logical_not + logical_or + logical_xor + logspace + long + longcomplex + longdouble + longfloat + longlong + lookfor + mafromtxt + mat + matrix + max + maximum + maximum_sctype + may_share_memory + mean + median + memmap + meshgrid + min + minimum + mintypecode + mirr + mod + modf + msort + multiply + nan_to_num + nanargmax + nanargmin + nanmax + nanmin + nansum + ndarray + ndenumerate + ndfromtxt + ndim + ndindex + negative + newbuffer + nonzero + not_equal + nper + npv + number + obj2sctype + object + object0 + object_ + ones + ones_like + outer + packbits + piecewise + pkgload + place + pmt + poly + poly1d + polyadd + polyder + polydiv + polyfit + polyint + polymul + polysub + polyval + power + ppmt + prod + product + ptp + put + putmask + pv + rad2deg + radians + rank + rate + ravel + real + real_if_close + recarray + recfromcsv + recfromtxt + reciprocal + record + remainder + repeat + require + reshape + resize + restoredot + right_shift + rint + roll + rollaxis + roots + rot90 + round + round_ + row_stack + safe_eval + save + savetxt + savez + sctype2char + searchsorted + select + set_numeric_ops + set_printoptions + set_string_function + setbufsize + setdiff1d + seterr + seterrcall + seterrobj + setmember1d + setxor1d + shape + short + show_config + sign + signbit + signedinteger + sin + sinc + single + singlecomplex + sinh + size + sometrue + sort + sort_complex + source + split + sqrt + square + squeeze + std + str + str_ + string0 + string_ + subtract + sum + swapaxes + take + tan + tanh + tensordot + test + tile + trace + transpose + trapz + tri + tril + trim_zeros + triu + true_divide + trunc + typename + ubyte + ufunc + uint + uint0 + uint16 + uint32 + uint64 + uint8 + uintc + uintp + ulonglong + unicode + unicode0 + unicode_ + union1d + unique + unique1d + unpackbits + unravel_index + unsignedinteger + unwrap + ushort + vander + var + vdot + vectorize + void + void0 + vsplit + vstack + where + who + zeros + zeros_like + + + __future__ + __import__ + __name__ + __cythonbufferdefaults__ + __weakref__ + None + self + True + False + NotImplemented + Ellipsis + NULL + + + __new__ + __init__ + __cinit__ + __dealloc__ + __cmp__ + __richcmp__ + __str__ + __repr__ + __hash__ + __call__ + __iter__ + __getattr__ + __setattr__ + __delattr__ + __add__ + __sub__ + __mul__ + __div__ + __floordiv__ + __truediv__ + __mod__ + __divmod__ + __pow__ + __neg__ + __pos__ + __abs__ + __nonzero__ + __invert__ + __lshift__ + __rshift__ + __and__ + __or__ + __xor__ + __int__ + __long__ + __float__ + __oct__ + __hex__ + __index__ + __iadd__ + __isub__ + __imul__ + __idiv__ + __ifloordiv__ + __itruediv__ + __imod__ + __ipow__ + __ilshift__ + __irshift__ + __iand__ + __ior__ + __ixor__ + __len__ + __getitem__ + __setitem__ + __delitem__ + __getslice__ + __setslice__ + __delslice__ + __contains__ + __next__ + __getreadbuffer__ + __getwritebuffer__ + __getsegcount__ + __getcharbuffer__ + __get__ + __set__ + __delete__ + __getbuffer__ + __releasebuffer__ + + + ArithmeticError + AssertionError + AttributeError + BaseException + DeprecationWarning + EnvironmentError + EOFError + Exception + FloatingPointError + FutureWarning + GeneratorExit + IOError + ImportError + ImportWarning + IndexError + KeyError + KeyboardInterrupt + LookupError + MemoryError + NameError + NotImplementedError + OSError + OverflowError + PendingDeprecationWarning + ReferenceError + RuntimeError + RuntimeWarning + StandardError + StopIteration + SyntaxError + SyntaxWarning + SystemError + SystemExit + TypeError + UnboundLocalError + UserWarning + UnicodeError + UnicodeWarning + UnicodeEncodeError + UnicodeDecodeError + UnicodeTranslateError + ValueError + Warning + WindowsError + ZeroDivisionError + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Cython-0.23.4/Tools/jedityper.py0000644000175600017570000001033612606202452017660 0ustar jenkinsjenkins00000000000000""" Inject Cython type declarations into a .py file using the Jedi static analysis tool. """ from __future__ import absolute_import from io import open from collections import defaultdict from itertools import chain import jedi from jedi.parser.tree import Module, ImportName from jedi.evaluate.representation import Function, Instance, Class from jedi.evaluate.iterable import ArrayMixin, GeneratorComprehension from Cython.Utils import open_source_file default_type_map = { 'float': 'double', 'int': 'long', } def analyse(source_path=None, code=None): """ Analyse a Python source code file with Jedi. Returns a mapping from (scope-name, (line, column)) pairs to a name-types mapping. """ if not source_path and code is None: raise ValueError("Either 'source_path' or 'code' is required.") scoped_names = {} statement_iter = jedi.names(source=code, path=source_path, all_scopes=True) for statement in statement_iter: parent = statement.parent() scope = parent._definition evaluator = statement._evaluator # skip function/generator definitions, class definitions, and module imports if any(isinstance(statement._definition, t) for t in [Function, Class, ImportName]): continue key = (None if isinstance(scope, Module) else str(parent.name), scope.start_pos) try: names = scoped_names[key] except KeyError: names = scoped_names[key] = defaultdict(set) position = statement.start_pos if statement.name in names else None for name_type in evaluator.find_types(scope, statement.name, position=position ,search_global=True): if isinstance(name_type, Instance): if isinstance(name_type.base, Class): type_name = 'object' else: type_name = name_type.base.obj.__name__ elif isinstance(name_type, ArrayMixin): type_name = name_type.type elif isinstance(name_type, GeneratorComprehension): type_name = None else: try: type_name = type(name_type.obj).__name__ except AttributeError as error: type_name = None if type_name is not None: names[str(statement.name)].add(type_name) return scoped_names def inject_types(source_path, types, type_map=default_type_map, mode='python'): """ Hack type declarations into source code file. @param mode is currently 'python', which means that the generated type declarations use pure Python syntax. """ col_and_types_by_line = dict( # {line: (column, scope_name or None, [(name, type)])} (k[-1][0], (k[-1][1], k[0], [(n, next(iter(t))) for (n, t) in v.items() if len(t) == 1])) for (k, v) in types.items()) lines = [u'import cython\n'] with open_source_file(source_path) as f: for line_no, line in enumerate(f, 1): if line_no in col_and_types_by_line: col, scope, types = col_and_types_by_line[line_no] if types: types = ', '.join("%s='%s'" % (name, type_map.get(type_name, type_name)) for name, type_name in types) if scope is None: type_decl = u'{indent}cython.declare({types})\n' else: type_decl = u'{indent}@cython.locals({types})\n' lines.append(type_decl.format(indent=' '*col, types=types)) lines.append(line) return lines def main(file_paths=None, overwrite=False): """ Main entry point to process a list of .py files and inject type inferred declarations. """ if file_paths is None: import sys file_paths = sys.argv[1:] for source_path in file_paths: types = analyse(source_path) lines = inject_types(source_path, types) target_path = source_path + ('' if overwrite else '_typed.py') with open(target_path, 'w', encoding='utf8') as f: for line in lines: f.write(line) if __name__ == '__main__': main() Cython-0.23.4/Tools/cython.st0000644000175600017570000000115212606202452017157 0ustar jenkinsjenkins00000000000000/** * Name: pyrex * Description: Pyrex - a Language for Writing Python Extension Modules * Author: Markku Rossi */ state pyrex extends python { /* Additional keywords. (build-re '( NULL as cdef char ctypedef double enum extern float include int long private public short signed sizeof struct union unsigned void )) */ /\b(NULL|as|c(def|har|typedef)|double|e(num|xtern)|float|in(clude|t)\ |long|p(rivate|ublic)|s(hort|i(gned|zeof)|truct)|un(ion|signed)|void)\b/ { keyword_face(true); language_print($0); keyword_face(false); } } /* Local variables: mode: c End: */ Cython-0.23.4/Tools/cython-numpy-mode-kate.xml0000644000175600017570000013154412606202452022354 0ustar jenkinsjenkins00000000000000 as cimport import from as DEF IF ELIF ELSE include class cpdef def cdef ctypedef extern api del global property nogil gil inline readonly public and assert in is by not or sizeof print break continue elif else except finally for if pass raise return try while with __import__ abs all any apply basestring buffer callable chr classmethod cmp coerce compile delattr dir divmod enumerate eval execfile filter getattr hasattr hash hex id input intern isinstance issubclass iter len map max min oct open ord pow range raw_input reduce reload repr reversed round setattr sorted staticmethod sum super type unichr unicode xrange zip unsigned void enum double long short char Py_ssize_t Py_intptr_t Py_buffer bint struct union enum int float object list tuple str dict set frozenset slice bool complex file np numpy numpy cython dtype flatiter broadcast ndarray int8_t int16_t int32_t int64_t uint8_t uint16_t uint32_t uint64_t float32_t float64_t complex64_t complex128_t int_t long_t uint_t ulong_t float_t double_t longdouble_t cfloat_t cdouble_t clongdouble_t complex_t npy_int8 npy_int16 npy_int32 npy_int64 npy_int96 npy_int128 npy_uint8 npy_uint16 npy_uint32 npy_uint64 npy_uint96 npy_uint128 npy_float32 npy_float64 npy_float80 npy_float96 npy_float128 npy_complex64 npy_complex128 npy_complex120 npy_complex192 npy_complex256 npy_cfloat npy_cdouble npy_clongdouble npy_bool npy_byte npy_short npy_int npy_long npy_longlong npy_ubyte npy_ushort npy_uint npy_ulong npy_ulonglong npy_float npy_double npy_longdouble npy_intp DataSource MachAr PackageLoader RankWarning Tester abs absolute add add_docstring add_newdoc alen all allclose alltrue alterdot amax amin angle any append apply_along_axis apply_over_axes arange arccos arccosh arcsin arcsinh arctan arctan2 arctanh argmax argmin argsort argwhere around array array2string array_equal array_equiv array_repr array_split array_str asanyarray asarray asarray_chkfinite ascontiguousarray asfarray asfortranarray asmatrix asscalar atleast_1d atleast_2d atleast_3d average bartlett base_repr bench binary_repr bincount bitwise_and bitwise_not bitwise_or bitwise_xor blackman bmat bool bool8 bool_ broadcast broadcast_arrays byte byte_bounds can_cast cdouble ceil cfloat character chararray choose clip clongdouble clongfloat column_stack common_type compare_chararrays complex complex128 complex192 complex64 complex_ complexfloating compress concatenate conj conjugate convolve copy corrcoef correlate cos cosh cov cross csingle cumprod cumproduct cumsum deg2rad degrees delete deprecate deprecate_with_doc diag diagflat diagonal diff digitize disp divide dot double dsplit dstack dtype ediff1d empty empty_like equal errstate exp exp2 expand_dims expm1 extract eye fabs fastCopyAndTranspose find_common_type finfo fix flatiter flatnonzero flexible fliplr flipud float float32 float64 float96 float_ floating floor floor_divide fmax fmin fmod frexp frombuffer fromfile fromfunction fromiter frompyfunc fromregex fromstring fv generic genfromtxt get_array_wrap get_include get_numarray_include get_numpy_include get_printoptions getbuffer getbufsize geterr geterrcall geterrobj gradient greater greater_equal hamming hanning histogram histogram2d histogramdd hsplit hstack hypot i0 identity imag indices inexact info inner insert int int0 int16 int32 int64 int8 int_ int_asbuffer intc integer interp intersect1d intersect1d_nu intp invert ipmt irr iscomplex iscomplexobj isfinite isfortran isinf isnan isneginf isposinf isreal isrealobj isscalar issctype issubclass_ issubdtype issubsctype iterable ix_ kaiser kron ldexp left_shift less less_equal lexsort linspace load loads loadtxt log log10 log1p log2 logaddexp logaddexp2 logical_and logical_not logical_or logical_xor logspace long longcomplex longdouble longfloat longlong lookfor mafromtxt mat matrix max maximum maximum_sctype may_share_memory mean median memmap meshgrid min minimum mintypecode mirr mod modf msort multiply nan_to_num nanargmax nanargmin nanmax nanmin nansum ndarray ndenumerate ndfromtxt ndim ndindex negative newbuffer nonzero not_equal nper npv number obj2sctype object object0 object_ ones ones_like outer packbits piecewise pkgload place pmt poly poly1d polyadd polyder polydiv polyfit polyint polymul polysub polyval power ppmt prod product ptp put putmask pv rad2deg radians rank rate ravel real real_if_close recarray recfromcsv recfromtxt reciprocal record remainder repeat require reshape resize restoredot right_shift rint roll rollaxis roots rot90 round round_ row_stack safe_eval save savetxt savez sctype2char searchsorted select set_numeric_ops set_printoptions set_string_function setbufsize setdiff1d seterr seterrcall seterrobj setmember1d setxor1d shape short show_config sign signbit signedinteger sin sinc single singlecomplex sinh size sometrue sort sort_complex source split sqrt square squeeze std str str_ string0 string_ subtract sum swapaxes take tan tanh tensordot test tile trace transpose trapz tri tril trim_zeros triu true_divide trunc typename ubyte ufunc uint uint0 uint16 uint32 uint64 uint8 uintc uintp ulonglong unicode unicode0 unicode_ union1d unique unique1d unpackbits unravel_index unsignedinteger unwrap ushort vander var vdot vectorize void void0 vsplit vstack where who zeros zeros_like __future__ __import__ __name__ __cythonbufferdefaults__ __weakref__ None self True False NotImplemented Ellipsis NULL __new__ __init__ __cinit__ __dealloc__ __cmp__ __richcmp__ __str__ __repr__ __hash__ __call__ __iter__ __getattr__ __setattr__ __delattr__ __add__ __sub__ __mul__ __div__ __floordiv__ __truediv__ __mod__ __divmod__ __pow__ __neg__ __pos__ __abs__ __nonzero__ __invert__ __lshift__ __rshift__ __and__ __or__ __xor__ __int__ __long__ __float__ __oct__ __hex__ __index__ __iadd__ __isub__ __imul__ __idiv__ __ifloordiv__ __itruediv__ __imod__ __ipow__ __ilshift__ __irshift__ __iand__ __ior__ __ixor__ __len__ __getitem__ __setitem__ __delitem__ __getslice__ __setslice__ __delslice__ __contains__ __next__ __getreadbuffer__ __getwritebuffer__ __getsegcount__ __getcharbuffer__ __get__ __set__ __delete__ __getbuffer__ __releasebuffer__ ArithmeticError AssertionError AttributeError BaseException DeprecationWarning EnvironmentError EOFError Exception FloatingPointError FutureWarning GeneratorExit IOError ImportError ImportWarning IndexError KeyError KeyboardInterrupt LookupError MemoryError NameError NotImplementedError OSError OverflowError PendingDeprecationWarning ReferenceError RuntimeError RuntimeWarning StandardError StopIteration SyntaxError SyntaxWarning SystemError SystemExit TypeError UnboundLocalError UserWarning UnicodeError UnicodeWarning UnicodeEncodeError UnicodeDecodeError UnicodeTranslateError ValueError Warning WindowsError ZeroDivisionError Cython-0.23.4/Tools/cython-mode.el0000644000175600017570000002723312606202452020063 0ustar jenkinsjenkins00000000000000;;; cython-mode.el --- Major mode for editing Cython files ;;; Commentary: ;; This should work with python-mode.el as well as either the new ;; python.el or the old. ;;; Code: ;; Load python-mode if available, otherwise use builtin emacs python package (when (not (require 'python-mode nil t)) (require 'python)) (eval-when-compile (require 'rx)) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.pyx\\'" . cython-mode)) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.pxd\\'" . cython-mode)) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.pxi\\'" . cython-mode)) (defvar cython-buffer nil "Variable pointing to the cython buffer which was compiled.") (defun cython-compile () "Compile the file via Cython." (interactive) (let ((cy-buffer (current-buffer))) (with-current-buffer (compile compile-command) (set (make-local-variable 'cython-buffer) cy-buffer) (add-to-list (make-local-variable 'compilation-finish-functions) 'cython-compilation-finish)))) (defun cython-compilation-finish (buffer how) "Called when Cython compilation finishes." ;; XXX could annotate source here ) (defvar cython-mode-map (let ((map (make-sparse-keymap))) ;; Will inherit from `python-mode-map' thanks to define-derived-mode. (define-key map "\C-c\C-c" 'cython-compile) map) "Keymap used in `cython-mode'.") (defvar cython-font-lock-keywords `(;; ctypedef statement: "ctypedef (...type... alias)?" (,(rx ;; keyword itself symbol-start (group "ctypedef") ;; type specifier: at least 1 non-identifier symbol + 1 identifier ;; symbol and anything but a comment-starter after that. (opt (regexp "[^a-zA-z0-9_\n]+[a-zA-Z0-9_][^#\n]*") ;; type alias: an identifier symbol-start (group (regexp "[a-zA-Z_]+[a-zA-Z0-9_]*")) ;; space-or-comments till the end of the line (* space) (opt "#" (* nonl)) line-end)) (1 font-lock-keyword-face) (2 font-lock-type-face nil 'noerror)) ;; new keywords in Cython language (,(rx symbol-start (or "by" "cdef" "cimport" "cpdef" "extern" "gil" "include" "nogil" "property" "public" "readonly" "DEF" "IF" "ELIF" "ELSE" "new" "del" "cppclass" "namespace" "const" "__stdcall" "__cdecl" "__fastcall" "inline" "api") symbol-end) . font-lock-keyword-face) ;; Question mark won't match at a symbol-end, so 'except?' must be ;; special-cased. It's simpler to handle it separately than weaving it ;; into the lengthy list of other keywords. (,(rx symbol-start "except?") . font-lock-keyword-face) ;; C and Python types (highlight as builtins) (,(rx symbol-start (or "object" "dict" "list" ;; basic c type names "void" "char" "int" "float" "double" "bint" ;; longness/signed/constness "signed" "unsigned" "long" "short" ;; special basic c types "size_t" "Py_ssize_t" "Py_UNICODE" "Py_UCS4" "ssize_t" "ptrdiff_t") symbol-end) . font-lock-builtin-face) (,(rx symbol-start "NULL" symbol-end) . font-lock-constant-face) ;; cdef is used for more than functions, so simply highlighting the next ;; word is problematic. struct, enum and property work though. (,(rx symbol-start (group (or "struct" "enum" "union" (seq "ctypedef" (+ space "fused")))) (+ space) (group (regexp "[a-zA-Z_]+[a-zA-Z0-9_]*"))) (1 font-lock-keyword-face prepend) (2 font-lock-type-face)) ("\\_ (current-indentation) block-indentation) (or (cython-end-of-statement) t)) ;; comment or empty line (looking-at (rx (0+ space) (or eol "#")))))) (forward-comment -1)) ;; Count trailing space in defun (but not trailing comments). (skip-syntax-forward " >") (unless (eobp) ; e.g. missing final newline (beginning-of-line))) ;; Catch pathological cases like this, where the beginning-of-defun ;; skips to a definition we're not in: ;; if ...: ;; ... ;; else: ;; ... # point here ;; ... ;; def ... (if (< (point) orig) (goto-char (point-max))))) (defun cython-current-defun () "`add-log-current-defun-function' for Cython." (save-excursion ;; Move up the tree of nested `class' and `def' blocks until we ;; get to zero indentation, accumulating the defined names. (let ((start t) accum) (while (or start (> (current-indentation) 0)) (setq start nil) (cython-beginning-of-block) (end-of-line) (beginning-of-defun) (if (looking-at (rx (0+ space) (or "def" "cdef" "cpdef" "class") (1+ space) (group (1+ (or word (syntax symbol)))))) (push (match-string 1) accum))) (if accum (mapconcat 'identity accum "."))))) ;;;###autoload (define-derived-mode cython-mode python-mode "Cython" "Major mode for Cython development, derived from Python mode. \\{cython-mode-map}" (font-lock-add-keywords nil cython-font-lock-keywords) (set (make-local-variable 'outline-regexp) (rx (* space) (or "class" "def" "cdef" "cpdef" "elif" "else" "except" "finally" "for" "if" "try" "while" "with") symbol-end)) (set (make-local-variable 'beginning-of-defun-function) #'cython-beginning-of-defun) (set (make-local-variable 'end-of-defun-function) #'cython-end-of-defun) (set (make-local-variable 'compile-command) (format cython-default-compile-format (shell-quote-argument buffer-file-name))) (set (make-local-variable 'add-log-current-defun-function) #'cython-current-defun) (add-hook 'which-func-functions #'cython-current-defun nil t) (add-to-list (make-local-variable 'compilation-finish-functions) 'cython-compilation-finish)) (provide 'cython-mode) ;;; cython-mode.el ends here Cython-0.23.4/Tools/cython-epydoc.py0000644000175600017570000000263412606202452020450 0ustar jenkinsjenkins00000000000000#! /usr/bin/env python # -------------------------------------------------------------------- import re from epydoc import docstringparser as dsp CYTHON_SIGNATURE_RE = re.compile( # Class name (for builtin methods) r'^\s*((?P\w+)\.)?' + # The function name r'(?P\w+)' + # The parameters r'\(((?P(?:self|cls|mcs)),?)?(?P.*)\)' + # The return value (optional) r'(\s*(->)\s*(?P\w+(?:\s*\w+)))?' + # The end marker r'\s*(?:\n|$)') parse_signature = dsp.parse_function_signature def parse_function_signature(func_doc, doc_source, docformat, parse_errors): PYTHON_SIGNATURE_RE = dsp._SIGNATURE_RE assert PYTHON_SIGNATURE_RE is not CYTHON_SIGNATURE_RE try: dsp._SIGNATURE_RE = CYTHON_SIGNATURE_RE found = parse_signature(func_doc, doc_source, docformat, parse_errors) dsp._SIGNATURE_RE = PYTHON_SIGNATURE_RE if not found: found = parse_signature(func_doc, doc_source, docformat, parse_errors) return found finally: dsp._SIGNATURE_RE = PYTHON_SIGNATURE_RE dsp.parse_function_signature = parse_function_signature # -------------------------------------------------------------------- from epydoc.cli import cli cli() # -------------------------------------------------------------------- Cython-0.23.4/Tools/cystdlib.py0000644000175600017570000001260212606202452017474 0ustar jenkinsjenkins00000000000000""" Highly experimental script that compiles the CPython standard library using Cython. Execute the script either in the CPython 'Lib' directory or pass the option '--current-python' to compile the standard library of the running Python interpreter. Pass '-j N' to get a parallel build with N processes. Usage example:: $ python cystdlib.py --current-python build_ext -i """ import os import sys from distutils.core import setup from Cython.Build import cythonize from Cython.Compiler import Options # improve Python compatibility by allowing some broken code Options.error_on_unknown_names = False Options.error_on_uninitialized = False exclude_patterns = ['**/test/**/*.py', '**/tests/**/*.py', '**/__init__.py'] broken = [ 'idlelib/MultiCall.py', 'email/utils.py', 'multiprocessing/reduction.py', 'multiprocessing/util.py', 'threading.py', # interrupt handling 'lib2to3/fixes/fix_sys_exc.py', 'traceback.py', 'types.py', 'enum.py', 'keyword.py', '_collections_abc.py', 'importlib/_bootstrap', ] default_directives = dict( auto_cpdef=False, # enable when it's safe, see long list of failures below binding=True, set_initial_path='SOURCEFILE') default_directives['optimize.inline_defnode_calls'] = True special_directives = [ (['pkgutil.py', 'decimal.py', 'datetime.py', 'optparse.py', 'sndhdr.py', 'opcode.py', 'ntpath.py', 'urllib/request.py', 'plat-*/TYPES.py', 'plat-*/IN.py', 'tkinter/_fix.py', 'lib2to3/refactor.py', 'webbrowser.py', 'shutil.py', 'multiprocessing/forking.py', 'xml/sax/expatreader.py', 'xmlrpc/client.py', 'pydoc.py', 'xml/etree/ElementTree.py', 'posixpath.py', 'inspect.py', 'ctypes/util.py', 'urllib/parse.py', 'warnings.py', 'tempfile.py', 'trace.py', 'heapq.py', 'pickletools.py', 'multiprocessing/connection.py', 'hashlib.py', 'getopt.py', 'os.py', 'types.py', ], dict(auto_cpdef=False)), ] del special_directives[:] # currently unused def build_extensions(includes='**/*.py', excludes=None, special_directives=special_directives, language_level=sys.version_info[0], parallel=None): if isinstance(includes, str): includes = [includes] excludes = list(excludes or exclude_patterns) + broken all_groups = (special_directives or []) + [(includes, {})] extensions = [] for modules, directives in all_groups: exclude_now = excludes[:] for other_modules, _ in special_directives: if other_modules != modules: exclude_now.extend(other_modules) d = dict(default_directives) d.update(directives) extensions.extend( cythonize( modules, exclude=exclude_now, exclude_failures=True, language_level=language_level, compiler_directives=d, nthreads=parallel, )) return extensions def build(extensions): try: setup(ext_modules=extensions) result = True except: import traceback print('error building extensions %s' % ( [ext.name for ext in extensions],)) traceback.print_exc() result = False return extensions, result def _build(args): sys_args, ext = args sys.argv[1:] = sys_args return build([ext]) def parse_args(): from optparse import OptionParser parser = OptionParser('%prog [options] [LIB_DIR (default: ./Lib)]') parser.add_option( '--current-python', dest='current_python', action='store_true', help='compile the stdlib of the running Python') parser.add_option( '-j', '--jobs', dest='parallel_jobs', metavar='N', type=int, default=1, help='run builds in N parallel jobs (default: 1)') parser.add_option( '-x', '--exclude', dest='excludes', metavar='PATTERN', action="append", help='exclude modules/packages matching PATTERN') options, args = parser.parse_args() if not args: args = ['./Lib'] elif len(args) > 1: parser.error('only one argument expected, got %d' % len(args)) return options, args if __name__ == '__main__': options, args = parse_args() if options.current_python: # assume that the stdlib is where the "os" module lives os.chdir(os.path.dirname(os.__file__)) else: os.chdir(args[0]) pool = None parallel_jobs = options.parallel_jobs if options.parallel_jobs: try: import multiprocessing pool = multiprocessing.Pool(parallel_jobs) print("Building in %d parallel processes" % parallel_jobs) except (ImportError, OSError): print("Not building in parallel") parallel_jobs = 0 extensions = build_extensions( parallel=parallel_jobs, excludes=options.excludes) sys_args = ['build_ext', '-i'] if pool is not None: results = pool.map(_build, [(sys_args, ext) for ext in extensions]) pool.close() pool.join() for ext, result in results: if not result: print("building extension %s failed" % (ext[0].name,)) else: sys.argv[1:] = sys_args build(extensions) Cython-0.23.4/Tools/site_scons/0000755000175600017570000000000012606202455017460 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Tools/site_scons/site_tools/0000755000175600017570000000000012606202455021644 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Tools/site_scons/site_tools/pyext.py0000644000175600017570000002205612606202452023371 0ustar jenkinsjenkins00000000000000"""SCons.Tool.pyext Tool-specific initialization for python extensions builder. AUTHORS: - David Cournapeau - Dag Sverre Seljebotn """ # # __COPYRIGHT__ # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import sys import SCons from SCons.Tool import SourceFileScanner, ProgramScanner # Create common python builders def createPythonObjectBuilder(env): """This is a utility function that creates the PythonObject Builder in an Environment if it is not there already. If it is already there, we return the existing one. """ try: pyobj = env['BUILDERS']['PythonObject'] except KeyError: pyobj = SCons.Builder.Builder(action = {}, emitter = {}, prefix = '$PYEXTOBJPREFIX', suffix = '$PYEXTOBJSUFFIX', src_builder = ['CFile', 'CXXFile'], source_scanner = SourceFileScanner, single_source = 1) env['BUILDERS']['PythonObject'] = pyobj return pyobj def createPythonExtensionBuilder(env): """This is a utility function that creates the PythonExtension Builder in an Environment if it is not there already. If it is already there, we return the existing one. """ try: pyext = env['BUILDERS']['PythonExtension'] except KeyError: import SCons.Action import SCons.Defaults action = SCons.Action.Action("$PYEXTLINKCOM", "$PYEXTLINKCOMSTR") action_list = [ SCons.Defaults.SharedCheck, action] pyext = SCons.Builder.Builder(action = action_list, emitter = "$SHLIBEMITTER", prefix = '$PYEXTPREFIX', suffix = '$PYEXTSUFFIX', target_scanner = ProgramScanner, src_suffix = '$PYEXTOBJSUFFIX', src_builder = 'PythonObject') env['BUILDERS']['PythonExtension'] = pyext return pyext def pyext_coms(platform): """Return PYEXTCCCOM, PYEXTCXXCOM and PYEXTLINKCOM for the given platform.""" if platform == 'win32': pyext_cccom = "$PYEXTCC /Fo$TARGET /c $PYEXTCCSHARED "\ "$PYEXTCFLAGS $PYEXTCCFLAGS $_CCCOMCOM "\ "$_PYEXTCPPINCFLAGS $SOURCES" pyext_cxxcom = "$PYEXTCXX /Fo$TARGET /c $PYEXTCSHARED "\ "$PYEXTCXXFLAGS $PYEXTCCFLAGS $_CCCOMCOM "\ "$_PYEXTCPPINCFLAGS $SOURCES" pyext_linkcom = '${TEMPFILE("$PYEXTLINK $PYEXTLINKFLAGS '\ '/OUT:$TARGET.windows $( $_LIBDIRFLAGS $) '\ '$_LIBFLAGS $_PYEXTRUNTIME $SOURCES.windows")}' else: pyext_cccom = "$PYEXTCC -o $TARGET -c $PYEXTCCSHARED "\ "$PYEXTCFLAGS $PYEXTCCFLAGS $_CCCOMCOM "\ "$_PYEXTCPPINCFLAGS $SOURCES" pyext_cxxcom = "$PYEXTCXX -o $TARGET -c $PYEXTCSHARED "\ "$PYEXTCXXFLAGS $PYEXTCCFLAGS $_CCCOMCOM "\ "$_PYEXTCPPINCFLAGS $SOURCES" pyext_linkcom = "$PYEXTLINK -o $TARGET $PYEXTLINKFLAGS "\ "$SOURCES $_LIBDIRFLAGS $_LIBFLAGS $_PYEXTRUNTIME" if platform == 'darwin': pyext_linkcom += ' $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS' return pyext_cccom, pyext_cxxcom, pyext_linkcom def set_basic_vars(env): # Set construction variables which are independant on whether we are using # distutils or not. env['PYEXTCPPPATH'] = SCons.Util.CLVar('$PYEXTINCPATH') env['_PYEXTCPPINCFLAGS'] = '$( ${_concat(INCPREFIX, PYEXTCPPPATH, '\ 'INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' env['PYEXTOBJSUFFIX'] = '$SHOBJSUFFIX' env['PYEXTOBJPREFIX'] = '$SHOBJPREFIX' env['PYEXTRUNTIME'] = SCons.Util.CLVar("") # XXX: this should be handled with different flags env['_PYEXTRUNTIME'] = '$( ${_concat(LIBLINKPREFIX, PYEXTRUNTIME, '\ 'LIBLINKSUFFIX, __env__)} $)' # XXX: This won't work in all cases (using mingw, for example). To make # this work, we need to know whether PYEXTCC accepts /c and /Fo or -c -o. # This is difficult with the current way tools work in scons. pycc, pycxx, pylink = pyext_coms(sys.platform) env['PYEXTLINKFLAGSEND'] = SCons.Util.CLVar('$LINKFLAGSEND') env['PYEXTCCCOM'] = pycc env['PYEXTCXXCOM'] = pycxx env['PYEXTLINKCOM'] = pylink def _set_configuration_nodistutils(env): # Set env variables to sensible values when not using distutils def_cfg = {'PYEXTCC' : '$SHCC', 'PYEXTCFLAGS' : '$SHCFLAGS', 'PYEXTCCFLAGS' : '$SHCCFLAGS', 'PYEXTCXX' : '$SHCXX', 'PYEXTCXXFLAGS' : '$SHCXXFLAGS', 'PYEXTLINK' : '$LDMODULE', 'PYEXTSUFFIX' : '$LDMODULESUFFIX', 'PYEXTPREFIX' : ''} if sys.platform == 'darwin': def_cfg['PYEXTSUFFIX'] = '.so' for k, v in def_cfg.items(): ifnotset(env, k, v) ifnotset(env, 'PYEXT_ALLOW_UNDEFINED', SCons.Util.CLVar('$ALLOW_UNDEFINED')) ifnotset(env, 'PYEXTLINKFLAGS', SCons.Util.CLVar('$LDMODULEFLAGS')) env.AppendUnique(PYEXTLINKFLAGS = env['PYEXT_ALLOW_UNDEFINED']) def ifnotset(env, name, value): if name not in env: env[name] = value def set_configuration(env, use_distutils): """Set construction variables which are platform dependants. If use_distutils == True, use distutils configuration. Otherwise, use 'sensible' default. Any variable already defined is untouched.""" # We define commands as strings so that we can either execute them using # eval (same python for scons and distutils) or by executing them through # the shell. dist_cfg = {'PYEXTCC': ("sysconfig.get_config_var('CC')", False), 'PYEXTCFLAGS': ("sysconfig.get_config_var('CFLAGS')", True), 'PYEXTCCSHARED': ("sysconfig.get_config_var('CCSHARED')", False), 'PYEXTLINKFLAGS': ("sysconfig.get_config_var('LDFLAGS')", True), 'PYEXTLINK': ("sysconfig.get_config_var('LDSHARED')", False), 'PYEXTINCPATH': ("sysconfig.get_python_inc()", False), 'PYEXTSUFFIX': ("sysconfig.get_config_var('SO')", False)} from distutils import sysconfig # We set the python path even when not using distutils, because we rarely # want to change this, even if not using distutils ifnotset(env, 'PYEXTINCPATH', sysconfig.get_python_inc()) if use_distutils: for k, (v, should_split) in dist_cfg.items(): val = eval(v) if should_split: val = val.split() ifnotset(env, k, val) else: _set_configuration_nodistutils(env) def generate(env): """Add Builders and construction variables for python extensions to an Environment.""" if 'PYEXT_USE_DISTUTILS' not in env: env['PYEXT_USE_DISTUTILS'] = False # This sets all constructions variables used for pyext builders. set_basic_vars(env) set_configuration(env, env['PYEXT_USE_DISTUTILS']) # Create the PythonObject builder pyobj = createPythonObjectBuilder(env) action = SCons.Action.Action("$PYEXTCCCOM", "$PYEXTCCCOMSTR") pyobj.add_emitter('.c', SCons.Defaults.SharedObjectEmitter) pyobj.add_action('.c', action) action = SCons.Action.Action("$PYEXTCXXCOM", "$PYEXTCXXCOMSTR") pyobj.add_emitter('$CXXFILESUFFIX', SCons.Defaults.SharedObjectEmitter) pyobj.add_action('$CXXFILESUFFIX', action) # Create the PythonExtension builder createPythonExtensionBuilder(env) def exists(env): try: # This is not quite right: if someone defines all variables by himself, # it would work without distutils from distutils import sysconfig return True except ImportError: return False Cython-0.23.4/Tools/site_scons/site_tools/cython.py0000644000175600017570000000327112606202452023522 0ustar jenkinsjenkins00000000000000""" Tool to run Cython files (.pyx) into .c and .cpp. TODO: - Add support for dynamically selecting in-process Cython through CYTHONINPROCESS variable. - Have a CYTHONCPP option which turns on C++ in flags and changes output extension at the same time VARIABLES: - CYTHON - The path to the "cython" command line tool. - CYTHONFLAGS - Flags to pass to the "cython" command line tool. AUTHORS: - David Cournapeau - Dag Sverre Seljebotn """ import SCons from SCons.Builder import Builder from SCons.Action import Action #def cython_action(target, source, env): # print target, source, env # from Cython.Compiler.Main import compile as cython_compile # res = cython_compile(str(source[0])) cythonAction = Action("$CYTHONCOM") def create_builder(env): try: cython = env['BUILDERS']['Cython'] except KeyError: cython = SCons.Builder.Builder( action = cythonAction, emitter = {}, suffix = cython_suffix_emitter, single_source = 1) env['BUILDERS']['Cython'] = cython return cython def cython_suffix_emitter(env, source): return "$CYTHONCFILESUFFIX" def generate(env): env["CYTHON"] = "cython" env["CYTHONCOM"] = "$CYTHON $CYTHONFLAGS -o $TARGET $SOURCE" env["CYTHONCFILESUFFIX"] = ".c" c_file, cxx_file = SCons.Tool.createCFileBuilders(env) c_file.suffix['.pyx'] = cython_suffix_emitter c_file.add_action('.pyx', cythonAction) c_file.suffix['.py'] = cython_suffix_emitter c_file.add_action('.py', cythonAction) create_builder(env) def exists(env): try: # import Cython return True except ImportError: return False Cython-0.23.4/Doc/0000755000175600017570000000000012606202455014714 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Doc/special_methods.html0000644000175600017570000004574512606202452020761 0ustar jenkinsjenkins00000000000000 Special Methods of Extenstion Types


Special Methods of Extension Types

This page describes the special methods currently supported by Cython extension types. A complete list of all the special methods appears in the table at the bottom. Some of these methods behave differently from their Python counterparts or have no direct Python counterparts, and require special mention.

Note: Everything said on this page applies only to extension types, defined with the cdef class statement. It doesn't apply  to classes defined with the Python class statement, where the normal Python rules apply.

Declaration

Special methods of extension types must be declared with def, not cdef.

Docstrings

Currently, docstrings are not fully supported in special methods of extension types. You can place a docstring in the source to serve as a comment, but it won't show up in the corresponding __doc__ attribute at run time. (This is a Python limitation -- there's nowhere in the PyTypeObject data structure to put such docstrings.)

Initialisation methods: __new__ and __init__

There are two methods concerned with initialising the object.

The __new__ method is where you should perform basic C-level initialisation of the object, including allocation of any C data structures that your object will own. You need to be careful what you do in the __new__ method, because the object may not yet be a valid Python object when it is called. Therefore, you must not invoke any Python operations which might touch the object; in particular, do not try to call any of its methods.

Unlike the corresponding method in Python, your __new__ method is not responsible for creating the object. By the time your __new__ method is called, memory has been allocated for the object and any C attributes it has have been initialised to 0 or null. (Any Python attributes have also been initialised to None, but you probably shouldn't rely on that.) Your __new__ method is guaranteed to be called exactly once.

If your extension type has a base type, the __new__ method of the base type is automatically called before your __new__ method is called; you cannot explicitly call the inherited __new__ method. If you need to pass a modified argument list to the base type, you will have to do the relevant part of the initialisation in the __init__ method instead (where the normal rules for calling inherited methods apply).

Note that the first parameter of the __new__ method is the object to be initialised, not the class of the object as it is in Python.

Any initialisation which cannot safely be done in the __new__ method should be done in the __init__ method. By the time __init__ is called, the object is a fully valid Python object and all operations are safe. Under some circumstances it is possible for __init__ to be called more than once or not to be called at all, so your other methods should be designed to be robust in such situations.

Keep in mind that any arguments passed to the constructor will be passed to the __new__ method as well as the __init__ method. If you anticipate subclassing your extension type in Python, you may find it useful to give the __new__ method * and ** arguments so that it can accept and ignore extra arguments. Otherwise, any Python subclass which has an __init__ with a different signature will have to override __new__ as well as __init__, which the writer of a Python class wouldn't expect to have to do.

Finalization method: __dealloc__

The counterpart to the __new__ method is the __dealloc__ method, which should perform the inverse of the __new__ method. Any C data structures that you allocated in your __new__ method should be freed in your __dealloc__ method.

You need to be careful what you do in a __dealloc__ method. By the time your __dealloc__ method is called, the object may already have been partially destroyed and may not be in a valid state as far as Python is concerned, so you should avoid invoking any Python operations which might touch the object. In particular, don't call any other methods of the object or do anything which might cause the object to be resurrected. It's best if you stick to just deallocating C data.

You don't need to worry about deallocating Python attributes of your object, because that will be done for you by Cython after your __dealloc__ method returns.

Note: There is no __del__ method for extension types. (Earlier versions of the Cython documentation stated that there was, but this turned out to be incorrect.)

Arithmetic methods

Arithmetic operator methods, such as __add__, behave differently from their Python counterparts. There are no separate "reversed" versions of these methods (__radd__, etc.) Instead, if the first operand cannot perform the operation, the same method of the second operand is called, with the operands in the same order.

This means that you can't rely on the first parameter of these methods being "self", and you should test the types of both operands before deciding what to do. If you can't handle the combination of types you've been given, you should return NotImplemented.

This also applies to the in-place arithmetic method __ipow__. It doesn't apply to any of the other in-place methods (__iadd__, etc.) which always take self as the first argument.

Rich comparisons

There are no separate methods for the individual rich comparison operations (__eq__, __le__, etc.) Instead there is a single method __richcmp__ which takes an integer indicating which operation is to be performed, as follows:
       
      <
      0
      ==
      2
      >
      4
      <=
      1
      !=
      3
      >=
      5

The __next__ method

Extension types wishing to implement the iterator interface should define a method called __next__, not next. The Python system will automatically supply a next method which calls your __next__. Do NOT explicitly give your type a next method, or bad things could happen (see note 3).

Special Method Table

This table lists all of the special methods together with their parameter and return types. A parameter named self is of the type the method belongs to. Other untyped parameters are generic Python objects.

You don't have to declare your method as taking these parameter types. If you declare different types, conversions will be performed as necessary.
 
Name Parameters Return type Description
General
__new__ self, ...   Basic initialisation (no direct Python equivalent)
__init__ self, ...   Further initialisation
__dealloc__ self   Basic deallocation (no direct Python equivalent)
__cmp__ x, y int 3-way comparison
__richcmp__ x, y, int op object Rich comparison (no direct Python equivalent)
__str__ self object str(self)
__repr__ self object repr(self)
__hash__ self int Hash function
__call__ self, ... object self(...)
__iter__ self object Return iterator for sequence
__getattr__ self, name object Get attribute
__getattribute__ self, name object Get attribute, unconditionally
__setattr__ self, name, val   Set attribute
__delattr__ self, name   Delete attribute
Arithmetic operators
__add__ x, y object binary + operator
__sub__ x, y object binary - operator
__mul__ x, y object * operator
__div__ x, y object /  operator for old-style division
__floordiv__ x, y object //  operator
__truediv__ x, y object /  operator for new-style division
__mod__ x, y object % operator
__divmod__ x, y object combined div and mod
__pow__ x, y, z object ** operator or pow(x, y, z)
__neg__ self object unary - operator
__pos__ self object unary + operator
__abs__ self object absolute value
__nonzero__ self int convert to boolean
__invert__ self object ~ operator
__lshift__ x, y object << operator
__rshift__ x, y object >> operator
__and__ x, y object & operator
__or__ x, y object | operator
__xor__ x, y object ^ operator
Numeric conversions
__int__ self object Convert to integer
__long__ self object Convert to long integer
__float__ self object Convert to float
__oct__ self object Convert to octal
__hex__ self object Convert to hexadecimal
In-place arithmetic operators
__iadd__ self, x object += operator
__isub__ self, x object -= operator
__imul__ self, x object *= operator
__idiv__ self, x object /= operator for old-style division
__ifloordiv__ self, x object //= operator
__itruediv__ self, x object /= operator for new-style division
__imod__ self, x object %= operator
__ipow__ x, y, z object **= operator
__ilshift__ self, x object <<= operator
__irshift__ self, x object >>= operator
__iand__ self, x object &= operator
__ior__ self, x object |= operator
__ixor__ self, x object ^= operator
Sequences and mappings
__len__ self int len(self)
__getitem__ self, x object self[x]
__setitem__ self, x, y   self[x] = y
__delitem__ self, x   del self[x]
__getslice__ self, int i, int j object self[i:j]
__setslice__ self, int i, int j, x   self[i:j] = x
__delslice__ self, int i, int j   del self[i:j]
__contains__ self, x int x in self
Iterators
__next__ self object Get next item (called next in Python)
Buffer interface  (no Python equivalents - see note 1)
__getreadbuffer__ self, int i, void **p    
__getwritebuffer__ self, int i, void **p    
__getsegcount__ self, int *p    
__getcharbuffer__ self, int i, char **p    
Descriptor objects  (no Python equivalents - see note 2)
__get__ self, instance, class object Get value of attribute
__set__ self, instance, value   Set value of attribute
__delete__ self, instance   Delete attribute

Note 1: The buffer interface is intended for use by C code and is not directly accessible from Python. It is described in the Python/C API Reference Manual under sections 6.6 and 10.6.

Note 2: Descriptor objects are part of the support mechanism for new-style Python classes. See the discussion of descriptors in the Python documentation. See also PEP 252, "Making Types Look More Like Classes", and PEP 253, "Subtyping Built-In Types".

Note 3: If your type defines a __new__ method, any method called new that you define will be overwritten with the system-supplied new at module import time.



Cython-0.23.4/Doc/sharing.html0000644000175600017570000002454712606202452017246 0ustar jenkinsjenkins00000000000000 Sharing Declarations Between Cython Modules


Sharing Declarations Between Cython Modules

This section describes a new set of facilities introduced in Cython 0.8 for making C declarations and extension types in one Cython module available for use in another Cython module. These facilities are closely modelled on the Python import mechanism, and can be thought of as a compile-time version of it.

Contents

Definition and Implementation files

A Cython module can be split into two parts: a definition file with a .pxd suffix, containing C declarations that are to be available to other Cython modules, and an implementation file with a .pyx suffix, containing everything else. When a module wants to use something declared in another module's definition file, it imports it using the cimport statement.

What a Definition File contains

A definition file can contain:
  • Any kind of C type declaration.
  • extern C function or variable declarations.
  • The definition part of an extension type (see below).
It cannot currently contain any non-extern C function or variable declarations (although this may be possible in a future version).

It cannot contain the implementations of any C or Python functions, or any Python class definitions, or any executable statements.

NOTE: You don't need to (and shouldn't) declare anything in a declaration file public in order to make it available to other Cython modules; its mere presence in a definition file does that. You only need a public declaration if you want to make something available to external C code.

What an Implementation File contains

An implementation file can contain any kind of Cython statement, although there are some restrictions on the implementation part of an extension type if the corresponding definition file also defines that type (see below).

The cimport statement

The cimport statement is used in a definition or implementation file to gain access to names declared in another definition file. Its syntax exactly parallels that of the normal Python import statement:
cimport module [, module...]
from module cimport name [as name] [, name [as name] ...]
Here is an example. The file on the left is a definition file which exports a C data type. The file on the right is an implementation file which imports and uses it.
 
dishes.pxd restaurant.pyx
cdef enum otherstuff:
    sausage, eggs, lettuce

cdef struct spamdish:
    int oz_of_spam
    otherstuff filler

cimport dishes
from dishes cimport spamdish

cdef void prepare(spamdish *d):
    d.oz_of_spam = 42
    d.filler = dishes.sausage

def serve():
    spamdish d
    prepare(&d)
    print "%d oz spam, filler no. %d" % \
         (d->oz_of_spam, d->filler)

It is important to understand that the cimport statement can only be used to import C data types, external C functions and variables, and extension types. It cannot be used to import any Python objects, and (with one exception) it doesn't imply any Python import at run time. If you want to refer to any Python names from a module that you have cimported, you will have to include a regular import statement for it as well.

The exception is that when you use cimport to import an extension type, its type object is imported at run time and made available by the name under which you imported it. Using cimport to import extension types is covered in more detail below.

Search paths for definition files

When you cimport a module called modulename, the Cython compiler searches for a file called modulename.pxd along the search path for include files, as specified by -I command line options.

Also, whenever you compile a file modulename.pyx, the corresponding definition file modulename.pxd is first searched for along the same path, and if found, it is processed before processing the .pyx file.

Using cimport to resolve naming conflicts

The cimport mechanism provides a clean and simple way to solve the problem of wrapping external C functions with Python functions of the same name. All you need to do is put the extern C declarations into a .pxd file for an imaginary module, and cimport that module. You can then refer to the C functions by qualifying them with the name of the module. Here's an example:
 
c_lunch.pxd lunch.pyx
cdef extern from "lunch.h":
    void eject_tomato(float)
cimport c_lunch

def eject_tomato(float speed):
    c_lunch.eject_tomato(speed)

You don't need any c_lunch.pyx file, because the only things defined in c_lunch.pxd are extern C entities. There won't be any actual c_lunch module at run time, but that doesn't matter -- c_lunch has done its job of providing an additional namespace at compile time.

Sharing Extension Types

An extension type declaration can also be split into two parts, one in a definition file and the other in the corresponding implementation file.

The definition part of the extension type can only declare C attributes and C methods, not Python methods, and it must declare all of that type's C attributes and C methods.

The implementation part must implement all of the C methods declared in the definition part, and may not add any further C attributes. It may also define Python methods.

Here is an example of a module which defines and exports an extension type, and another module which uses it.
 
Shrubbing.pxd Shrubbing.pyx
cdef class Shrubbery:
    cdef int width
    cdef int length
cdef class Shrubbery:
    def __new__(self, int w, int l):
        self.width = w
        self.length = l

def standard_shrubbery():
    return Shrubbery(3, 7)

Landscaping.pyx
cimport Shrubbing
import Shrubbing

cdef Shrubbing.Shrubbery sh
sh = Shrubbing.standard_shrubbery()
print "Shrubbery size is %d x %d" % (sh.width, sh.height)
 

Some things to note about this example:

  • There is a cdef class Shrubbery declaration in both Shrubbing.pxd and Shrubbing.pyx. When the Shrubbing module is compiled, these two declarations are combined into one.
  •  
  • In Landscaping.pyx, the cimport Shrubbing declaration allows us to refer to the Shrubbery type as Shrubbing.Shrubbery. But it doesn't bind the name Shrubbery in Landscaping's module namespace at run time, so to access Shrubbery.standard_shrubbery we also need to import Shrubbing.

Back to the Language Overview

Cython-0.23.4/Doc/primes.c0000644000175600017570000000773612606202452016371 0ustar jenkinsjenkins00000000000000#include "Python.h" static PyObject *__Pyx_UnpackItem(PyObject *, int); static int __Pyx_EndUnpack(PyObject *, int); static int __Pyx_PrintItem(PyObject *); static int __Pyx_PrintNewline(void); static void __Pyx_ReRaise(void); static void __Pyx_RaiseWithTraceback(PyObject *, PyObject *, PyObject *); static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); static PyObject *__Pyx_GetExcValue(void); static PyObject *__Pyx_GetName(PyObject *dict, char *name); static PyObject *__pyx_m; static PyObject *__pyx_d; static PyObject *__pyx_b; PyObject *__pyx_f_primes(PyObject *__pyx_self, PyObject *__pyx_args); /*proto*/ PyObject *__pyx_f_primes(PyObject *__pyx_self, PyObject *__pyx_args) { int __pyx_v_kmax; int __pyx_v_n; int __pyx_v_k; int __pyx_v_i; int (__pyx_v_p[1000]); PyObject *__pyx_v_result; PyObject *__pyx_r; PyObject *__pyx_1 = 0; int __pyx_2; int __pyx_3; int __pyx_4; PyObject *__pyx_5 = 0; PyObject *__pyx_6 = 0; if (!PyArg_ParseTuple(__pyx_args, "i", &__pyx_v_kmax)) return 0; __pyx_v_result = Py_None; Py_INCREF(__pyx_v_result); /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":2 */ /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":3 */ /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":4 */ __pyx_1 = PyList_New(0); if (!__pyx_1) goto __pyx_L1; Py_DECREF(__pyx_v_result); __pyx_v_result = __pyx_1; __pyx_1 = 0; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":5 */ __pyx_2 = (__pyx_v_kmax > 1000); if (__pyx_2) { /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":6 */ __pyx_v_kmax = 1000; goto __pyx_L2; } __pyx_L2:; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":7 */ __pyx_v_k = 0; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":8 */ __pyx_v_n = 2; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":9 */ while (1) { __pyx_L3:; __pyx_2 = (__pyx_v_k < __pyx_v_kmax); if (!__pyx_2) break; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":10 */ __pyx_v_i = 0; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":11 */ while (1) { __pyx_L5:; if (__pyx_3 = (__pyx_v_i < __pyx_v_k)) { __pyx_3 = ((__pyx_v_n % (__pyx_v_p[__pyx_v_i])) != 0); } if (!__pyx_3) break; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":12 */ __pyx_v_i = (__pyx_v_i + 1); } __pyx_L6:; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":13 */ __pyx_4 = (__pyx_v_i == __pyx_v_k); if (__pyx_4) { /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":14 */ (__pyx_v_p[__pyx_v_k]) = __pyx_v_n; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":15 */ __pyx_v_k = (__pyx_v_k + 1); /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":16 */ __pyx_1 = PyObject_GetAttrString(__pyx_v_result, "append"); if (!__pyx_1) goto __pyx_L1; __pyx_5 = PyInt_FromLong(__pyx_v_n); if (!__pyx_5) goto __pyx_L1; __pyx_6 = PyTuple_New(1); if (!__pyx_6) goto __pyx_L1; PyTuple_SET_ITEM(__pyx_6, 0, __pyx_5); __pyx_5 = 0; __pyx_5 = PyObject_CallObject(__pyx_1, __pyx_6); if (!__pyx_5) goto __pyx_L1; Py_DECREF(__pyx_6); __pyx_6 = 0; Py_DECREF(__pyx_5); __pyx_5 = 0; goto __pyx_L7; } __pyx_L7:; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":17 */ __pyx_v_n = (__pyx_v_n + 1); } __pyx_L4:; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":18 */ Py_INCREF(__pyx_v_result); __pyx_r = __pyx_v_result; goto __pyx_L0; __pyx_r = Py_None; Py_INCREF(__pyx_r); goto __pyx_L0; __pyx_L1:; Py_XDECREF(__pyx_1); Py_XDECREF(__pyx_5); Py_XDECREF(__pyx_6); __pyx_r = 0; __pyx_L0:; Py_DECREF(__pyx_v_result); return __pyx_r; } static struct PyMethodDef __pyx_methods[] = { {"primes", (PyCFunction)__pyx_f_primes, METH_VARARGS, 0}, {0, 0, 0, 0} }; void initprimes(void); /*proto*/ void initprimes(void) { __pyx_m = Py_InitModule4("primes", __pyx_methods, 0, 0, PYTHON_API_VERSION); __pyx_d = PyModule_GetDict(__pyx_m); __pyx_b = PyImport_AddModule("__builtin__"); PyDict_SetItemString(__pyx_d, "__builtins__", __pyx_b); } /* Runtime support code */ Cython-0.23.4/Doc/overview.html0000644000175600017570000012133712606202452017454 0ustar jenkinsjenkins00000000000000 Cython Language Overview


Overview of the Cython Language 

This document informally describes the extensions to the Python language made by Cython. Some day there will be a reference manual covering everything in more detail.
 

Contents


Basics

This section describes the basic features of the Cython language. The facilities covered in this section allow you to create Python-callable functions that manipulate C data structures and convert between Python and C data types. Later sections will cover facilities for wrapping external C code, creating new Python types and cooperation between Cython modules.

Python functions vs. C functions

There are two kinds of function definition in Cython:

Python functions are defined using the def statement, as in Python. They take Python objects as parameters and return Python objects.

C functions are defined using the new cdef statement. They take either Python objects or C values as parameters, and can return either Python objects or C values.

Within a Cython module, Python functions and C functions can call each other freely, but only Python functions can be called from outside the module by interpreted Python code. So, any functions that you want to "export" from your Cython module must be declared as Python functions using def.

Parameters of either type of function can be declared to have C data types, using normal C declaration syntax. For example,

def spam(int i, char *s):
    ...
cdef int eggs(unsigned long l, float f):
    ...
When a parameter of a Python function is declared to have a C data type, it is passed in as a Python object and automatically converted to a C value, if possible. Automatic conversion is currently only possible for numeric types and string types; attempting to use any other type for the parameter of a Python function will result in a compile-time error.

C functions, on the other hand, can have parameters of any type, since they're passed in directly using a normal C function call.

Python objects as parameters and return values

If no type is specified for a parameter or return value, it is assumed to be a Python object. (Note that this is different from the C convention, where it would default to int.) For example, the following defines a C function that takes two Python objects as parameters and returns a Python object:
cdef spamobjs(x, y):
    ...
Reference counting for these objects is performed automatically according to the standard Python/C API rules (i.e. borrowed references are taken as parameters and a new reference is returned).

The name object can also be used to explicitly declare something as a Python object. This can be useful if the name being declared would otherwise be taken as the name of a type, for example,

cdef ftang(object int):
    ...
declares a parameter called int which is a Python object. You can also use object as the explicit return type of a function, e.g.
cdef object ftang(object int):
    ...
In the interests of clarity, it is probably a good idea to always be explicit about object parameters in C functions.

C variable and type definitions

The cdef statement is also used to declare C variables, either local or module-level:
cdef int i, j, k
cdef float f, g[42], *h
and C struct, union or enum types:
cdef struct Grail:
    int age
    float volume
cdef union Food:
    char *spam
    float *eggs
cdef enum CheeseType:
    cheddar, edam, 
    camembert
cdef enum CheeseState:
    hard = 1
    soft = 2
    runny = 3
There is currently no special syntax for defining a constant, but you can use an anonymous enum declaration for this purpose, for example,
cdef enum:
    tons_of_spam = 3
Note that the words struct, union and enum are used only when defining a type, not when referring to it. For example, to declare a variable pointing to a Grail you would write
cdef Grail *gp
and not
cdef struct Grail *gp # WRONG
There is also a ctypedef statement for giving names to types, e.g.
ctypedef unsigned long ULong
ctypedef int *IntPtr

Automatic type conversions

In most situations, automatic conversions will be performed for the basic numeric and string types when a Python object is used in a context requiring a C value, or vice versa. The following table summarises the conversion possibilities.

C types
From Python types
To Python types
[unsigned] char
[unsigned] short
int, long
int, long
int
unsigned int
unsigned long
[unsigned] long long
int, long

long

float, double, long double
int, long, float
float
char *
str
str

Caveats when using a Python string in a C context

You need to be careful when using a Python string in a context expecting a char *. In this situation, a pointer to the contents of the Python string is used, which is only valid as long as the Python string exists. So you need to make sure that a reference to the original Python string is held for as long as the C string is needed. If you can't guarantee that the Python string will live long enough, you will need to copy the C string.

Cython detects and prevents some mistakes of this kind. For instance, if you attempt something like
cdef char *s
s = pystring1 + pystring2
then Cython will produce the error message "Obtaining char * from temporary Python value". The reason is that concatenating the two Python strings produces a new Python string object that is referenced only by a temporary internal variable that Cython generates. As soon as the statement has finished, the temporary variable will be decrefed and the Python string deallocated, leaving s dangling. Since this code could not possibly work, Cython refuses to compile it.

The solution is to assign the result of the concatenation to a Python variable, and then obtain the char * from that, i.e.
cdef char *s
p = pystring1 + pystring2
s = p
It is then your responsibility to hold the reference p for as long as necessary.

Keep in mind that the rules used to detect such errors are only heuristics. Sometimes Cython will complain unnecessarily, and sometimes it will fail to detect a problem that exists. Ultimately, you need to understand the issue and be careful what you do.

Scope rules

Cython determines whether a variable belongs to a local scope, the module scope, or the built-in scope completely statically. As with Python, assigning to a variable which is not otherwise declared implicitly declares it to be a Python variable residing in the scope where it is assigned. Unlike Python, however, a name which is referred to but not declared or assigned is assumed to reside in the builtin scope, not the module scope. Names added to the module dictionary at run time will not shadow such names.

You can use a global statement at the module level to explicitly declare a name to be a module-level name when there would otherwise not be any indication of this, for example,

global __name__
print __name__
Without the global statement, the above would print the name of the builtins module.

Note: A consequence of these rules is that the module-level scope behaves the same way as a Python local scope if you refer to a variable before assigning to it. In particular, tricks such as the following will not work in Cython:
try:
  x = True
except NameError:
  True = 1
because, due to the assignment, the True will always be looked up in the module-level scope. You would have to do something like this instead:
import __builtin__
try:
True = __builtin__.True
except AttributeError:
True = 1

Statements and expressions

Control structures and expressions follow Python syntax for the most part. When applied to Python objects, they have the same semantics as in Python (unless otherwise noted). Most of the Python operators can also be applied to C values, with the obvious semantics.

If Python objects and C values are mixed in an expression, conversions are performed automatically between Python objects and C numeric or string types.

Reference counts are maintained automatically for all Python objects, and all Python operations are automatically checked for errors, with appropriate action taken.

Differences between C and Cython expressions

There are some differences in syntax and semantics between C expressions and Cython expressions, particularly in the area of C constructs which have no direct equivalent in Python.
  • An integer literal without an L suffix is treated as a C constant, and will be truncated to whatever size your C compiler thinks appropriate. With an L suffix, it will be converted to Python long integer (even if it would be small enough to fit into a C int).

  • There is no -> operator in Cython. Instead of p->x, use p.x
  •  
  • There is no * operator in Cython. Instead of *p, use p[0]
  •  
  • There is an & operator, with the same semantics as in C.
  •  
  • The null C pointer is called NULL, not 0 (and NULL is a reserved word).
  •  
  • Character literals are written with a c prefix, for example:
    • c'X'
  • Type casts are written <type>value , for example:
    • cdef char *p, float *q
      p = <char*>q
    Warning: Don't attempt to use a typecast to convert between Python and C data types -- it won't do the right thing. Leave Cython to perform the conversion automatically.

Integer for-loops

You should be aware that a for-loop such as
for i in range(n):
    ...
won't be very fast, even if i and n are declared as C integers, because range is a Python function. For iterating over ranges of integers, Cython has another form of for-loop:
for i from 0 <= i < n:
    ...
If the loop variable and the lower and upper bounds are all C integers, this form of loop will be much faster, because Cython will translate it into pure C code.

Some things to note about the for-from loop:

  • The target expression must be a variable name.
  • The name between the lower and upper bounds must be the same as the target name.
  • The direction of iteration is determined by the relations. If they are both from the set {<, <=} then it is upwards; if they are both from the set {>, >=} then it is downwards. (Any other combination is disallowed.)
Like other Python looping statements, break and continue may be used in the body, and the loop may have an else clause.


Error return values

If you don't do anything special, a function declared with cdef that does not return a Python object has no way of reporting Python exceptions to its caller. If an exception is detected in such a function, a warning message is printed and the exception is ignored.

If you want a C function that does not return a Python object to be able to propagate exceptions to its caller, you need to declare an exception value for it. Here is an example:

cdef int spam() except -1:
    ...
With this declaration, whenever an exception occurs inside spam, it will immediately return with the value -1. Furthermore, whenever a call to spam returns -1, an exception will be assumed to have occurred and will be propagated.

When you declare an exception value for a function, you should never explicitly return that value. If all possible return values are legal and you can't reserve one entirely for signalling errors, you can use an alternative form of exception value declaration:

cdef int spam() except? -1:
    ...
The "?" indicates that the value -1 only indicates a possible error. In this case, Cython generates a call to PyErr_Occurredif the exception value is returned, to make sure it really is an error.

There is also a third form of exception value declaration:

cdef int spam() except *:
    ...
This form causes Cython to generate a call to PyErr_Occurred after every call to spam, regardless of what value it returns. If you have a function returning void that needs to propagate errors, you will have to use this form, since there isn't any return value to test.

Some things to note:

  • Currently, exception values can only declared for functions returning an integer, float or pointer type, and the value must be a literal, not an expression (although it can be negative). The only possible pointer exception value is NULL. Void functions can only use the except * form.

  •  
  • The exception value specification is part of the signature of the function. If you're passing a pointer to a function as a parameter or assigning it to a variable, the declared type of the parameter or variable must have the same exception value specification (or lack thereof). Here is an example of a pointer-to-function declaration with an exception value:
    • int (*grail)(int, char *) except -1
  • You don't need to (and shouldn't) declare exception values for functions which return Python objects. Remember that a function with no declared return type implicitly returns a Python object.

Checking return values of non-Cython functions

It's important to understand that the except clause does not cause an error to be raised when the specified value is returned. For example, you can't write something like
cdef extern FILE *fopen(char *filename, char *mode) except NULL # WRONG!
and expect an exception to be automatically raised if a call to fopen returns NULL. The except clause doesn't work that way; its only purpose is for propagating exceptions that have already been raised, either by a Cython function or a C function that calls Python/C API routines. To get an exception from a non-Python-aware function such as fopen, you will have to check the return value and raise it yourself, for example,
cdef FILE *p
p = fopen("spam.txt", "r")
if p == NULL:
    raise SpamError("Couldn't open the spam file")


The include statement

For convenience, a large Cython module can be split up into a number of files which are put together using the include statement, for example
include "spamstuff.pxi"
The contents of the named file are textually included at that point. The included file can contain any complete top-level Cython statements, including other include statements. The include statement itself can only appear at the top level of a file.

The include statement can also be used in conjunction with public declarations to make C functions and variables defined in one Cython module accessible to another. However, note that some of these uses have been superseded by the facilities described in Sharing Declarations Between Cython Modules, and it is expected that use of the include statement for this purpose will be phased out altogether in future versions.


Interfacing with External C Code

One of the main uses of Cython is wrapping existing libraries of C code. This is achieved by using external declarations to declare the C functions and variables from the library that you want to use.

You can also use public declarations to make C functions and variables defined in a Cython module available to external C code. The need for this is expected to be less frequent, but you might want to do it, for example, if you are embedding Python in another application as a scripting language. Just as a Cython module can be used as a bridge to allow Python code to call C code, it can also be used to allow C code to call Python code.

External declarations

By default, C functions and variables declared at the module level are local to the module (i.e. they have the C static storage class). They can also be declared extern to specify that they are defined elsewhere, for example:
cdef extern int spam_counter
cdef extern void order_spam(int tons)

Referencing C header files

When you use an extern definition on its own as in the examples above, Cython includes a declaration for it in the generated C file. This can cause problems if the declaration doesn't exactly match the declaration that will be seen by other C code. If you're wrapping an existing C library, for example, it's important that the generated C code is compiled with exactly the same declarations as the rest of the library.

To achieve this, you can tell Cython that the declarations are to be found in a C header file, like this:

cdef extern from "spam.h":
    int spam_counter
    void order_spam(int tons)
The cdef extern from clause does three things:
  1. It directs Cython to place a #include statement for the named header file in the generated C code.
  2.  
  3. It prevents Cython from generating any C code for the declarations found in the associated block.
  4.  
  5. It treats all declarations within the block as though they started with cdef extern.
It's important to understand that Cython does not itself read the C header file, so you still need to provide Cython versions of any declarations from it that you use. However, the Cython declarations don't always have to exactly match the C ones, and in some cases they shouldn't or can't. In particular:
  1. Don't use const. Cython doesn't know anything about const, so just leave it out. Most of the time this shouldn't cause any problem, although on rare occasions you might have to use a cast. 1
  2.  
  3. Leave out any platform-specific extensions to C declarations such as __declspec().
  4.  
  5. If the header file declares a big struct and you only want to use a few members, you only need to declare the members you're interested in. Leaving the rest out doesn't do any harm, because the C compiler will use the full definition from the header file.

    In some cases, you might not need any of the struct's members, in which case you can just put pass in the body of the struct declaration, e.g.

        cdef extern from "foo.h":
            struct spam:
                pass


    Note that you can only do this inside a cdef extern from block; struct declarations anywhere else must be non-empty.

  6. If the header file uses typedef names such as size_t to refer to platform-dependent flavours of numeric types, you will need a corresponding ctypedef statement, but you don't need to match the type exactly, just use something of the right general kind (int, float, etc). For example,
    1. ctypedef int size_t
    will work okay whatever the actual size of a size_t is (provided the header file defines it correctly).
     
  7. If the header file uses macros to define constants, translate them into a dummy enum declaration.
  8.  
  9. If the header file defines a function using a macro, declare it as though it were an ordinary function, with appropriate argument and result types.
A few more tricks and tips:
  • If you want to include a C header because it's needed by another header, but don't want to use any declarations from it, put pass in the extern-from block:
      cdef extern from "spam.h":
          pass
  • If you want to include some external declarations, but don't want to specify a header file (because it's included by some other header that you've already included) you can put * in place of the header file name:
cdef extern from *:
    ...

Styles of struct, union and enum declaration

There are two main ways that structs, unions and enums can be declared in C header files: using a tag name, or using a typedef. There are also some variations based on various combinations of these.

It's important to make the Cython declarations match the style used in the header file, so that Cython can emit the right sort of references to the type in the code it generates. To make this possible, Cython provides two different syntaxes for declaring a struct, union or enum type. The style introduced above corresponds to the use of a tag name. To get the other style, you prefix the declaration with ctypedef, as illustrated below.

The following table shows the various possible styles that can be found in a header file, and the corresponding Cython declaration that you should put in the cdef exern from block. Struct declarations are used as an example; the same applies equally to union and enum declarations.

Note that in all the cases below, you refer to the type in Cython code simply as Foo, not struct Foo.
 
  C code Possibilities for corresponding Cython code Comments
1 struct Foo {
  ...
};
cdef struct Foo:
  ...
Cython will refer to the type as struct Foo in the generated C code.
2 typedef struct {
  ...
} Foo;
ctypedef struct Foo:
  ...
Cython will refer to the type simply as Foo in the generated C code.
3 typedef struct foo {
  ...
} Foo;
cdef struct foo:
  ...
ctypedef foo Foo #optional
If the C header uses both a tag and a typedef with different names, you can use either form of declaration in Cython (although if you need to forward reference the type, you'll have to use the first form).
ctypedef struct Foo:
  ...
4 typedef struct Foo {
  ...
} Foo;
cdef struct Foo:
  ...
If the header uses the same name for the tag and the typedef, you won't be able to include a ctypedef for it -- but then, it's not necessary.

Accessing Python/C API routines

One particular use of the cdef extern from statement is for gaining access to routines in the Python/C API. For example,
cdef extern from "Python.h":
    object PyString_FromStringAndSize(char *s, int len)
will allow you to create Python strings containing null bytes.


Resolving naming conflicts - C name specifications

Each Cython module has a single module-level namespace for both Python and C names. This can be inconvenient if you want to wrap some external C functions and provide the Python user with Python functions of the same names.

Cython 0.8 provides a couple of different ways of solving this problem. The best way, especially if you have many C functions to wrap, is probably to put the extern C function declarations into a different namespace using the facilities described in the section on sharing declarations between Cython modules.

The other way is to use a c name specification to give different Cython and C names to the C function. Suppose, for example, that you want to wrap an external function called eject_tomato. If you declare it as

cdef extern void c_eject_tomato "eject_tomato" (float speed)
then its name inside the Cython module will be c_eject_tomato, whereas its name in C will be eject_tomato. You can then wrap it with
def eject_tomato(speed):
  c_eject_tomato(speed)
so that users of your module can refer to it as eject_tomato.

Another use for this feature is referring to external names that happen to be Cython keywords. For example, if you want to call an external function called print, you can rename it to something else in your Cython module.

As well as functions, C names can be specified for variables, structs, unions, enums, struct and union members, and enum values. For example,

cdef extern int one "ein", two "zwei"
cdef extern float three "drei"

cdef struct spam "SPAM":
  int i "eye"
cdef enum surprise "inquisition":
  first "alpha"
  second "beta" = 3

Public Declarations

You can make C variables and functions defined in a Cython module accessible to external C code (or another Cython module) using the public keyword, as follows:
cdef public int spam # public variable declaration

cdef public void grail(int num_nuns): # public function declaration
    ...

If there are any public declarations in a Cython module, a .h file is generated containing equivalent C declarations for inclusion in other C code.

Cython also generates a .pxi file containing Cython versions of the declarations for inclusion in another Cython module using the include statement. If you use this, you will need to arrange for the module using the declarations to be linked against the module defining them, and for both modules to be available to the dynamic linker at run time. I haven't tested this, so I can't say how well it will work on the various platforms.

NOTE: If all you want to export is an extension type, there is now a better way -- see Sharing Declarations Between Cython Modules.


Extension Types

One of the most powerful features of Cython is the ability to easily create new built-in Python types, called extension types. This is a major topic in itself, so there is a  separate page devoted to it.


Sharing Declarations Between Cython Modules

Cython 0.8 introduces a substantial new set of facilities allowing a Cython module to easily import and use C declarations and extension types from another Cython module. You can now create a set of co-operating Cython modules just as easily as you can create a set of co-operating Python modules. There is a separate page devoted to this topic.


Limitations

Unsupported Python features

Cython is not quite a full superset of Python. The following restrictions apply:
  • Function definitions (whether using def or cdef) cannot be nested within other function definitions.
  •  
  • Class definitions can only appear at the top level of a module, not inside a function.
  •  
  • The import * form of import is not allowed anywhere (other forms of the import statement are fine, though).
  •  
  • Generators cannot be defined in Cython.

  • The globals() and locals() functions cannot be used.
  • The above restrictions will most likely remain, since removing them would be difficult and they're not really needed for Cython's intended applications.

    There are also some temporary limitations, which may eventually be lifted, including:

  • Class and function definitions cannot be placed inside control structures.
  •  
  • In-place arithmetic operators (+=, etc) are not yet supported.
  •  
  • List comprehensions are not yet supported.
  •  
  • There is no support for Unicode.
  •  
  • Special methods of extension types cannot have functioning docstrings.

  • The use of string literals as comments is not recommended at present, because Cython doesn't optimize them away, and won't even accept them in places where executable statements are not allowed.
  • Semantic differences between Python and Cython

    Behaviour of class scopes

    In Python, referring to a method of a class inside the class definition, i.e. while the class is being defined, yields a plain function object, but in Cython it yields an unbound method2. A consequence of this is that the usual idiom for using the classmethod and staticmethod functions, e.g.
    class Spam:
      def method(cls):
        ...
      method = classmethod(method)
    will not work in Cython. This can be worked around by defining the function outside the class, and then assigning the result of classmethod or staticmethod inside the class, i.e.
    def Spam_method(cls):
      ...
    class Spam:
      method = classmethod(Spam_method)


    Footnotes

    1. A problem with const could arise if you have something like
    cdef extern from "grail.h":
      char *nun
    where grail.h actually contains
    extern const char *nun;
    and you do
    cdef void languissement(char *s):
      #something that doesn't change s
    ...
    languissement(nun)
    which will cause the C compiler to complain. You can work around it by casting away the constness:
    languissement(<char *>nun)

    2. The reason for the different behaviour of class scopes is that Cython-defined Python functions are PyCFunction objects, not PyFunction objects, and are not recognised by the machinery that creates a bound or unbound method when a function is extracted from a class. To get around this, Cython wraps each method in an unbound method object itself before storing it in the class's dictionary.
     

    Cython-0.23.4/Doc/index.html0000644000175600017570000000567612606202452016724 0ustar jenkinsjenkins00000000000000 Cython - Front Page  
    Cython A smooth blend of the finest Python 
    with the unsurpassed power 
    of raw C.
    Welcome to Cython, a language for writing Python extension modules. Cython makes creating an extension module is almost as easy as creating a Python module! To find out more, consult one of the edifying documents below.

    Documentation

    About Cython

    Read this to find out what Cython is all about and what it can do for you.

    Language Overview

    A description of all the features of the Cython language. This is the closest thing to a reference manual in existence yet.

    FAQ

    Want to know how to do something in Cython? Check here first.

    Other Resources

    Michael's Quick Guide to Cython

    This tutorial-style presentation will take you through the steps of creating some Cython modules to wrap existing C libraries. Contributed by Michael JasonSmith.

    Mail to the Author

    If you have a question that's not answered by anything here, you're not sure about something, or you have a bug to report or a suggestion to make, or anything at all to say about Cython, feel free to email me: greg@cosc.canterbury.ac.nz
    Cython-0.23.4/Doc/extension_types.html0000644000175600017570000006001212606202452021036 0ustar jenkinsjenkins00000000000000 Extension Types


    Extension Types

    Contents

    Introduction

    As well as creating normal user-defined classes with the Python class statement, Cython also lets you create new built-in Python types, known as extension types. You define an extension type using the cdef class statement. Here's an example:
    cdef class Shrubbery:

        cdef int width, height

        def __init__(self, w, h):
            self.width = w
            self.height = h

        def describe(self):
            print "This shrubbery is", self.width, \
                "by", self.height, "cubits."

    As you can see, a Cython extension type definition looks a lot like a Python class definition. Within it, you use the def statement to define methods that can be called from Python code. You can even define many of the special methods such as __init__ as you would in Python.

    The main difference is that you can use the cdef statement to define attributes. The attributes may be Python objects (either generic or of a particular extension type), or they may be of any C data type. So you can use extension types to wrap arbitrary C data structures and provide a Python-like interface to them.

    Attributes

    Attributes of an extension type are stored directly in the object's C struct. The set of attributes is fixed at compile time; you can't add attributes to an extension type instance at run time simply by assigning to them, as you could with a Python class instance. (You can subclass the extension type in Python and add attributes to instances of the subclass, however.)

    There are two ways that attributes of an extension type can be accessed: by Python attribute lookup, or by direct access to the C struct from Cython code. Python code is only able to access attributes of an extension type by the first method, but Cython code can use either method.

    By default, extension type attributes are only accessible by direct access, not Python access, which means that they are not accessible from Python code. To make them accessible from Python code, you need to declare them as public or readonly. For example,

    cdef class Shrubbery:
        cdef public int width, height
        cdef readonly float depth
    makes the width and height attributes readable and writable from Python code, and the depth attribute readable but not writable.

    Note that you can only expose simple C types, such as ints, floats and strings, for Python access. You can also expose Python-valued attributes, although read-write exposure is only possible for generic Python attributes (of type object). If the attribute is declared to be of an extension type, it must be exposed readonly.

    Note also that the public and readonly options apply only to Python access, not direct access. All the attributes of an extension type are always readable and writable by direct access.

    Howerver, for direct access to be possible, the Cython compiler must know that you have an instance of that type, and not just a generic Python object. It knows this already in the case of the "self" parameter of the methods of that type, but in other cases you will have to tell it by means of a declaration. For example,

    cdef widen_shrubbery(Shrubbery sh, extra_width):
        sh.width = sh.width + extra_width
    If you attempt to access an extension type attribute through a generic object reference, Cython will use a Python attribute lookup. If the attribute is exposed for Python access (using public or readonly) then this will work, but it will be much slower than direct access.

    Extension types and None

    When you declare a parameter or C variable as being of an extension type, Cython will allow it to take on the value None as well as values of its declared type. This is analogous to the way a C pointer can take on the value NULL, and you need to exercise the same caution because of it. There is no problem as long as you are performing Python operations on it, because full dynamic type checking will be applied. However, when you access C attributes of an extension type (as in the widen_shrubbery function above), it's up to you to make sure the reference you're using is not None -- in the interests of efficiency, Cython does not check this.

    You need to be particularly careful when exposing Python functions which take extension types as arguments. If we wanted to make widen_shrubbery a Python function, for example, if we simply wrote

    def widen_shrubbery(Shrubbery sh, extra_width): # This is
        sh.width = sh.width + extra_width           # dangerous!
    then users of our module could crash it by passing None for the sh parameter.

    One way to fix this would be

    def widen_shrubbery(Shrubbery sh, extra_width):
        if sh is None:
            raise TypeError
        sh.width = sh.width + extra_width
    but since this is anticipated to be such a frequent requirement, Cython provides a more convenient way. Parameters of a Python function declared as an extension type can have a not None clause:
    def widen_shrubbery(Shrubbery sh not None, extra_width):
        sh.width = sh.width + extra_width
    Now the function will automatically check that sh is not None along with checking that it has the right type.

    Note, however that the not None clause can only be used in Python functions (defined with def) and not C functions (defined with cdef). If you need to check whether a parameter to a C function is None, you will need to do it yourself.

    Some more things to note:

    • The self parameter of a method of an extension type is guaranteed never to be None.
    • When comparing a value with None, keep in mind that, if x is a Python object, x is None and x is not None are very efficient because they translate directly to C pointer comparisons, whereas x == None and x != None, or simply using x as a boolean value (as in if x: ...) will invoke Python operations and therefore be much slower.

    Special methods

    Although the principles are similar, there are substantial differences between many of the __xxx__ special methods of extension types and their Python counterparts. There is a separate page devoted to this subject, and you should read it carefully before attempting to use any special methods in your extension types.

    Properties

    There is a special syntax for defining properties in an extension class:
    cdef class Spam:

        property cheese:

            "A doc string can go here."

            def __get__(self):
                # This is called when the property is read.
                ...

            def __set__(self, value):
                # This is called when the property is written.
                ...

            def __del__(self):
                # This is called when the property is deleted.
     

    The __get__, __set__ and __del__ methods are all optional; if they are omitted, an exception will be raised when the corresponding operation is attempted.

    Here's a complete example. It defines a property which adds to a list each time it is written to, returns the list when it is read, and empties the list when it is deleted.
     

    cheesy.pyx Test input
    cdef class CheeseShop:

      cdef object cheeses

      def __new__(self):
        self.cheeses = []

      property cheese:

        def __get__(self):
          return "We don't have: %s" % self.cheeses

        def __set__(self, value):
          self.cheeses.append(value)

        def __del__(self):
          del self.cheeses[:]

    from cheesy import CheeseShop

    shop = CheeseShop()
    print shop.cheese

    shop.cheese = "camembert"
    print shop.cheese

    shop.cheese = "cheddar"
    print shop.cheese

    del shop.cheese
    print shop.cheese

    Test output
    We don't have: []
    We don't have: ['camembert']
    We don't have: ['camembert', 'cheddar']
    We don't have: []

    Subclassing

    An extension type may inherit from a built-in type or another extension type:
    cdef class Parrot:
        ...

    cdef class Norwegian(Parrot):
        ...


    A complete definition of the base type must be available to Cython, so if the base type is a built-in type, it must have been previously declared as an extern extension type. If the base type is defined in another Cython module, it must either be declared as an extern extension type or imported using the cimport statement.

    An extension type can only have one base class (no multiple inheritance).

    Cython extension types can also be subclassed in Python. A Python class can inherit from multiple extension types provided that the usual Python rules for multiple inheritance are followed (i.e. the C layouts of all the base classes must be compatible).

    C methods

    Extension types can have C methods as well as Python methods. Like C functions, C methods are declared using cdef instead of def. C methods are "virtual", and may be overridden in derived extension types.

    pets.pyx
    Output
    cdef class Parrot:

      cdef void describe(self):
        print "This parrot is resting."

    cdef class Norwegian(Parrot):

      cdef void describe(self):
        Parrot.describe(self)
        print "Lovely plumage!"


    cdef Parrot p1, p2
    p1 = Parrot()
    p2 = Norwegian()
    print "p1:"
    p1.describe()
    print "p2:"
    p2.describe()

    p1:
    This parrot is resting.
    p2:
    This parrot is resting.
    Lovely plumage!

    The above example also illustrates that a C method can call an inherited C method using the usual Python technique, i.e.
    Parrot.describe(self)

    Forward-declaring extension types

    Extension types can be forward-declared, like struct and union types. This will be necessary if you have two extension types that need to refer to each other, e.g.
    cdef class Shrubbery # forward declaration

    cdef class Shrubber:
        cdef Shrubbery work_in_progress

    cdef class Shrubbery:
        cdef Shrubber creator

    If you are forward-declaring an exension type that has a base class, you must specify the base class in both the forward declaration and its subsequent definition, for example,
    cdef class A(B)

    ...

    cdef class A(B):
        # attributes and methods

    Making extension types weak-referenceable

    By default, extension types do not support having weak references made to them. You can enable weak referencing by declaring a C attribute of type object called __weakref__. For example,

    cdef class ExplodingAnimal:
        """This animal will self-destruct when it is
           no longer strongly referenced."""
       
        cdef object __weakref__

    Public and external extension types

    Extension types can be declared extern or public. An extern extension type declaration makes an extension type defined in external C code available to a Cython module. A public extension type declaration makes an extension type defined in a Cython module available to external C code.

    External extension types

    An extern extension type allows you to gain access to the internals of Python objects defined in the Python core or in a non-Cython extension module.
    NOTE: In Cython versions before 0.8, extern extension types were also used to reference extension types defined in another Cython module. While you can still do that, Cython 0.8 and later provides a better mechanism for this. See Sharing C Declarations Between Cython Modules.
    Here is an example which will let you get at the C-level members of the built-in complex object.
    cdef extern from "complexobject.h":

        struct Py_complex:
            double real
            double imag

        ctypedef class __builtin__.complex [object PyComplexObject]:
            cdef Py_complex cval

    # A function which uses the above type
    def spam(complex c):
        print "Real:", c.cval.real
        print "Imag:", c.cval.imag

    Some important things to note are:
    1. In this example, ctypedef class has been used. This is because, in the Python header files, the PyComplexObject struct is declared with

      ctypedef struct {
          ...
      } PyComplexObject;

    2. As well as the name of the extension type, the module in which its type object can be found is also specified. See the implicit importing section below. 

    3. When declaring an external extension type, you don't declare any methods. Declaration of methods is not required in order to call them, because the calls are Python method calls. Also, as with structs and unions, if your extension class declaration is inside a cdef extern from block, you only need to declare those C members which you wish to access.

    Implicit importing

    Backwards Incompatibility Note: You will have to update any pre-0.8 Cython modules you have which use extern extension types. I apologise for this, but for complicated reasons it proved to be too difficult to continue supporting the old way of doing these while introducing the new features that I wanted.
    Cython 0.8 and later requires you to include a module name in an extern extension class declaration, for example,
    cdef extern class MyModule.Spam:
        ...
    The type object will be implicitly imported from the specified module and bound to the corresponding name in this module. In other words, in this example an implicit
      from MyModule import Spam
    statement will be executed at module load time.

    The module name can be a dotted name to refer to a module inside a package hierarchy, for example,

    cdef extern class My.Nested.Package.Spam:
        ...
    You can also specify an alternative name under which to import the type using an as clause, for example,
      cdef extern class My.Nested.Package.Spam as Yummy:
         ...
    which corresponds to the implicit import statement
      from My.Nested.Package import Spam as Yummy

    Type names vs. constructor names

    Inside a Cython module, the name of an extension type serves two distinct purposes. When used in an expression, it refers to a module-level global variable holding the type's constructor (i.e. its type-object). However, it can also be used as a C type name to declare variables, arguments and return values of that type.

    When you declare

    cdef extern class MyModule.Spam:
        ...
    the name Spam serves both these roles. There may be other names by which you can refer to the constructor, but only Spam can be used as a type name. For example, if you were to explicity import MyModule, you could use MyModule.Spam() to create a Spam instance, but you wouldn't be able to use MyModule.Spam as a type name.

    When an as clause is used, the name specified in the as clause also takes over both roles. So if you declare

    cdef extern class MyModule.Spam as Yummy:
        ...
    then Yummy becomes both the type name and a name for the constructor. Again, there are other ways that you could get hold of the constructor, but only Yummy is usable as a type name.

    Public extension types

    An extension type can be declared public, in which case a .h file is generated containing declarations for its object struct and type object. By including the .h file in external C code that you write, that code can access the attributes of the extension type.

    Name specification clause

    The part of the class declaration in square brackets is a special feature only available for extern or public extension types. The full form of this clause is
    [object object_struct_name, type type_object_name ]
    where object_struct_name is the name to assume for the type's C struct, and type_object_name is the name to assume for the type's statically declared type object. (The object and type clauses can be written in either order.)

    If the extension type declaration is inside a cdef extern from block, the object clause is required, because Cython must be able to generate code that is compatible with the declarations in the header file. Otherwise, for extern extension types, the object clause is optional.

    For public extension types, the object and type clauses are both required, because Cython must be able to generate code that is compatible with external C code.



    Back to the Language Overview
     

    Cython-0.23.4/Doc/FAQ.html0000644000175600017570000001074212606202452016212 0ustar jenkinsjenkins00000000000000 FAQ.html


    Cython FAQ

    Contents


    How do I call Python/C API routines?

    Declare them as C functions inside a cdef extern from block. Use the type name object for any parameters and return types which are Python object references. Don't use the word const anywhere. Here is an example which defines and uses the PyString_FromStringAndSize routine:
    cdef extern from "Python.h":
        object PyString_FromStringAndSize(char *, int)

    cdef char buf[42]
    my_string = PyString_FromStringAndSize(buf, 42)

    How do I convert a C string containing null bytes to a Python string?

    Put in a declaration for the PyString_FromStringAndSize API routine and use that. See How do I call Python/C API routines?

    How do I access the data inside a Numeric array object?

    Use a cdef extern from block to include the Numeric header file and declare the array object as an external extension type. The following code illustrates how to do this:
    cdef extern from "Numeric/arrayobject.h":

        struct PyArray_Descr:
            int type_num, elsize
            char type

        ctypedef class Numeric.ArrayType [object PyArrayObject]:
            cdef char *data
            cdef int nd
            cdef int *dimensions, *strides
            cdef object base
            cdef PyArray_Descr *descr
            cdef int flags

    For more information about external extension types, see the "External Extension Types" section of the "Extension Types" documentation page.

    Cython says my extension type object has no attribute 'rhubarb', but I know it does. What gives?

    You're probably trying to access it through a reference which Cython thinks is a generic Python object. You need to tell Cython that it's a reference to your extension type by means of a declaration,
    for example,
    cdef class Vegetables:
        cdef int rhubarb

    ...
    cdef Vegetables veg
    veg.rhubarb = 42
    Also see the "Attributes" section of the "Extension Types" documentation page.

    Python says my extension type has no method called 'quack', but I know it does. What gives?

    You may have declared the method using cdef instead of def. Only functions and methods declared with def are callable from Python code.
    --- Cython-0.23.4/Doc/About.html0000644000175600017570000002117612606202452016660 0ustar jenkinsjenkins00000000000000 About Cython


    Cython

    A language for writing Python extension modules

    What is Cython all about?

    Cython is a language specially designed for writing Python extension modules. It's designed to bridge the gap between the nice, high-level, easy-to-use world of Python and the messy, low-level world of C.

    You may be wondering why anyone would want a special language for this. Python is really easy to extend using C or C++, isn't it? Why not just write your extension modules in one of those languages?

    Well, if you've ever written an extension module for Python, you'll know that things are not as easy as all that. First of all, there is a fair bit of boilerplate code to write before you can even get off the ground. Then you're faced with the problem of converting between Python and C data types. For the basic types such as numbers and strings this is not too bad, but anything more elaborate and you're into picking Python objects apart using the Python/C API calls, which requires you to be meticulous about maintaining reference counts, checking for errors at every step and cleaning up properly if anything goes wrong. Any mistakes and you have a nasty crash that's very difficult to debug.

    Various tools have been developed to ease some of the burdens of producing extension code, of which perhaps SWIG is the best known. SWIG takes a definition file consisting of a mixture of C code and specialised declarations, and produces an extension module. It writes all the boilerplate for you, and in many cases you can use it without knowing about the Python/C API. But you need to use API calls if any substantial restructuring of the data is required between Python and C.

    What's more, SWIG gives you no help at all if you want to create a new built-in Python type. It will generate pure-Python classes which wrap (in a slightly unsafe manner) pointers to C data structures, but creation of true extension types is outside its scope.

    Another notable attempt at making it easier to extend Python is PyInline , inspired by a similar facility for Perl. PyInline lets you embed pieces of C code in the midst of a Python file, and automatically extracts them and compiles them into an extension. But it only converts the basic types automatically, and as with SWIG,  it doesn't address the creation of new Python types.

    Cython aims to go far beyond what any of these previous tools provides. Cython deals with the basic types just as easily as SWIG, but it also lets you write code to convert between arbitrary Python data structures and arbitrary C data structures, in a simple and natural way, without knowing anything about the Python/C API. That's right -- nothing at all! Nor do you have to worry about reference counting or error checking -- it's all taken care of automatically, behind the scenes, just as it is in interpreted Python code. And what's more, Cython lets you define new built-in Python types just as easily as you can define new classes in Python.

    Sound too good to be true? Read on and find out how it's done.

    The Basics of Cython

    The fundamental nature of Cython can be summed up as follows: Cython is Python with C data types.

    Cython is Python: Almost any piece of Python code is also valid Cython code. (There are a few limitations, but this approximation will serve for now.) The Cython compiler will convert it into C code which makes equivalent calls to the Python/C API. In this respect, Cython is similar to the former Python2C project (to which I would supply a reference except that it no longer seems to exist).

    ...with C data types. But Cython is much more than that, because parameters and variables can be declared to have C data types. Code which manipulates Python values and C values can be freely intermixed, with conversions occurring automatically wherever possible. Reference count maintenance and error checking of Python operations is also automatic, and the full power of Python's exception handling facilities, including the try-except and try-finally statements, is available to you -- even in the midst of manipulating C data.

    Here's a small example showing some of what can be done. It's a routine for finding prime numbers. You tell it how many primes you want, and it returns them as a Python list.

    primes.pyx
     1  def primes(int kmax):
     2      cdef int n, k, i
     3      cdef int p[1000]
     4      result = []
     5      if kmax > 1000:
     6          kmax = 1000
     7      k = 0
     8      n = 2
     9      while k < kmax:
    10          i = 0
    11          while i < k and n % p[i] <> 0:
    12              i = i + 1
    13          if i == k:
    14             p[k] = n
    15             k = k + 1
    16             result.append(n)
    17          n = n + 1
    18      return result
    You'll see that it starts out just like a normal Python function definition, except that the parameter kmax is declared to be of type int . This means that the object passed will be converted to a C integer (or a TypeError will be raised if it can't be).

    Lines 2 and 3 use the cdef statement to define some local C variables. Line 4 creates a Python list which will be used to return the result. You'll notice that this is done exactly the same way it would be in Python. Because the variable result hasn't been given a type, it is assumed to hold a Python object.

    Lines 7-9 set up for a loop which will test candidate numbers for primeness until the required number of primes has been found. Lines 11-12, which try dividing a candidate by all the primes found so far, are of particular interest. Because no Python objects are referred to, the loop is translated entirely into C code, and thus runs very fast.

    When a prime is found, lines 14-15 add it to the p array for fast access by the testing loop, and line 16 adds it to the result list. Again, you'll notice that line 16 looks very much like a Python statement, and in fact it is, with the twist that the C parameter n is automatically converted to a Python object before being passed to the append method. Finally, at line 18, a normal Python return statement returns the result list.

    Compiling primes.pyx with the Cython compiler produces an extension module which we can try out in the interactive interpreter as follows:

    >>> import primes
    >>> primes.primes(10)
    [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
    >>>
    See, it works! And if you're curious about how much work Cython has saved you, take a look at the C code generated for this module .

    Language Details

    For more about the Cython language, see the Language Overview .

    Future Plans

    Cython is not finished. Substantial tasks remaining include:
    • Support for certain Python language features which are planned but not yet implemented. See the Limitations section of the Language Overview for a current list.
    • C++ support. This could be a very big can of worms - careful thought required before going there.
    • Reading C/C++ header files directly would be very nice, but there are some severe problems that I will have to find solutions for first, such as what to do about preprocessor macros. My current thinking is to use a separate tool to convert .h files into Cython declarations, possibly with some manual intervention.
    Cython-0.23.4/Demos/0000755000175600017570000000000012606202455015256 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Demos/spam.pyx0000644000175600017570000000062612606202452016761 0ustar jenkinsjenkins00000000000000# cython: language_level=3 # # Example of an extension type. # cdef class Spam: cdef public int amount def __cinit__(self): self.amount = 0 def __dealloc__(self): print(self.amount, "tons of spam is history.") def get_amount(self): return self.amount def set_amount(self, new_amount): self.amount = new_amount def describe(self): print(self.amount, "tons of spam!") Cython-0.23.4/Demos/setup.py0000644000175600017570000000122412606202452016764 0ustar jenkinsjenkins00000000000000# Run as: # python setup.py build_ext --inplace import sys sys.path.insert(0, "..") from distutils.core import setup from distutils.extension import Extension from Cython.Build import cythonize ext_modules = cythonize("**/*.pyx", exclude="numpy_*.pyx") # Only compile the following if numpy is installed. try: from numpy.distutils.misc_util import get_numpy_include_dirs numpy_demo = [Extension("*", ["numpy_*.pyx"], include_dirs=get_numpy_include_dirs())] ext_modules.extend(cythonize(numpy_demo)) except ImportError: pass setup( name = 'Demos', ext_modules = ext_modules, ) Cython-0.23.4/Demos/run_spam.py0000644000175600017570000000027012606202452017450 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import, print_function from spam import Spam s = Spam() print("Created:", s) s.set_amount(42) print("Amount =", s.get_amount()) s.describe() s = None Cython-0.23.4/Demos/run_primes.py0000644000175600017570000000026312606202452020011 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import, print_function import sys from primes import primes if len(sys.argv) >= 2: n = int(sys.argv[1]) else: n = 1000 print(primes(n)) Cython-0.23.4/Demos/run_numeric_demo.py0000644000175600017570000000017612606202452021163 0ustar jenkinsjenkins00000000000000import Numeric import numeric_demo a = Numeric.array([[1.0, 3.5, 8.4], [2.3, 6.6, 4.1]], "f") numeric_demo.print_2d_array(a) Cython-0.23.4/Demos/pyprimes.py0000644000175600017570000000036012606202452017474 0ustar jenkinsjenkins00000000000000def primes(kmax): p = [] k = 0 n = 2 while k < kmax: i = 0 while i < k and n % p[i] != 0: i = i + 1 if i == k: p.append(n) k = k + 1 n = n + 1 return p Cython-0.23.4/Demos/primes.pyx0000644000175600017570000000062212606202452017314 0ustar jenkinsjenkins00000000000000# cython: language_level=3 print("starting") def primes(int kmax): # cdef int n, k, i cdef int p[1000] result = [] if kmax > 1000: kmax = 1000 k = 0 n = 2 while k < kmax: i = 0 while i < k and n % p[i] != 0: i += 1 if i == k: p[k] = n k += 1 result.append(n) n += 1 return result Cython-0.23.4/Demos/overflow_perf_run.py0000644000175600017570000000370312606202452021373 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import, print_function from overflow_perf import * import sys import timeit try: import numpy as np except ImportError: np = None def run_tests(N): global f for func in most_orthogonal, fib, collatz, factorial: print(func.__name__) for type in ['int', 'unsigned int', 'long long', 'unsigned long long', 'object']: if func == most_orthogonal: if type == 'object' or np == None: continue type_map = {'int': 'int32', 'unsigned int': 'uint32', 'long long': 'int64', 'unsigned long long': 'uint64'} shape = N, 3 arg = np.ndarray(shape, dtype=type_map[type]) arg[:] = 1000 * np.random.random(shape) else: arg = N try: print("%s[%s](%s)" % (func.__name__, type, N)) with_overflow = my_timeit(globals()[func.__name__ + "_overflow"][type], arg) no_overflow = my_timeit(func[type], arg) print("\t%0.04e\t%0.04e\t%0.04f" % (no_overflow, with_overflow, with_overflow / no_overflow)) if func.__name__ + "_overflow_fold" in globals(): with_overflow = my_timeit(globals()[func.__name__ + "_overflow_fold"][type], arg) print("\t%0.04e\t%0.04e\t%0.04f (folded)" % ( no_overflow, with_overflow, with_overflow / no_overflow)) except OverflowError: print(" ", "Overflow") def my_timeit(func, N): global f, arg f = func arg = N for exponent in range(10, 30): times = 2 ** exponent res = min(timeit.repeat("f(arg)", setup="from __main__ import f, arg", repeat=5, number=times)) if res > .25: break return res / times params = sys.argv[1:] if not params: params = [129, 9, 97] for arg in params: print() print("N", arg) run_tests(int(arg)) Cython-0.23.4/Demos/overflow_perf.pyx0000644000175600017570000001041312606202452020673 0ustar jenkinsjenkins00000000000000# cython: language_level=3 # distutils: extra_compile_args = -O3 cimport cython ctypedef fused INT: int long long unsigned int unsigned long long object ctypedef fused C_INT: int long long unsigned int unsigned long long @cython.overflowcheck(False) def fib(INT n): """ >>> [fib(k) for k in range(10)] [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] """ cdef INT a, b, k a, b = 0, 1 for k in range(n): a, b = b, a + b return int(b) @cython.overflowcheck(True) def fib_overflow(INT n): """ >>> [fib_overflow(k) for k in range(10)] [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] """ cdef INT a, b, k a, b = 0, 1 for k in range(n): a, b = b, a + b return int(b) @cython.overflowcheck(False) def collatz(INT n): """ >>> collatz(1) 0 >>> collatz(5) 5 >>> collatz(10) 6 """ cdef INT k = 0 while n != 1: if n % 2 == 0: n //= 2 else: n = 3*n + 1 k += 1 return int(k) @cython.overflowcheck(True) @cython.overflowcheck.fold(False) def collatz_overflow(INT n): """ >>> collatz_overflow(1) 0 >>> collatz_overflow(5) 5 >>> collatz_overflow(10) 6 """ cdef INT k = 0 while n != 1: if n % 2 == 0: n //= 2 else: n = 3*n + 1 k += 1 return int(k) @cython.overflowcheck(True) @cython.overflowcheck.fold(True) def collatz_overflow_fold(INT n): """ >>> collatz_overflow_fold(1) 0 >>> collatz_overflow_fold(5) 5 >>> collatz_overflow_fold(10) 6 """ cdef INT k = 0 while n != 1: if n % 2 == 0: n //= 2 else: n = 3*n + 1 k += 1 return int(k) @cython.overflowcheck(False) def factorial(INT n): """ >>> factorial(2) 2 >>> factorial(5) 120 """ cdef INT k, res = 1 for k in range(2, n+1): res = res * k return int(res) @cython.overflowcheck(True) def factorial_overflow(INT n): """ >>> factorial_overflow(2) 2 >>> factorial_overflow(5) 120 """ cdef INT k, res = 1 for k in range(2, n+1): res = res * k return int(res) @cython.overflowcheck(False) def most_orthogonal(C_INT[:,::1] vectors): cdef C_INT n = vectors.shape[0] cdef C_INT* a cdef C_INT* b cdef double min_dot = 2 # actual max is 1 for i in range(n): for j in range(i): a = &vectors[i, 0] b = &vectors[j, 0] # A highly nested arithmetic expression... normalized_dot = (1.0 * (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]) / ((a[0]*a[0] + a[1]*a[1] + a[2]*a[2]) * (b[0]*b[0] + b[1]*b[1]+b[2]*b[2]))) if normalized_dot < min_dot: min_dot = normalized_dot min_pair = i, j return vectors[i], vectors[j] @cython.overflowcheck(True) @cython.overflowcheck.fold(False) def most_orthogonal_overflow(C_INT[:,::1] vectors): cdef C_INT n = vectors.shape[0] cdef C_INT* a cdef C_INT* b cdef double min_dot = 2 # actual max is 1 for i in range(n): for j in range(i): a = &vectors[i, 0] b = &vectors[j, 0] # A highly nested arithmetic expression... normalized_dot = ((a[0]*b[0] + a[1]*b[1] + a[2]*b[2]) / (1.0 * (a[0]*a[0] + a[1]*a[1] + a[2]*a[2]) * (b[0]*b[0] + b[1]*b[1]+b[2]*b[2]))) if normalized_dot < min_dot: min_dot = normalized_dot min_pair = i, j return vectors[i], vectors[j] @cython.overflowcheck(True) @cython.overflowcheck.fold(True) def most_orthogonal_overflow_fold(C_INT[:,::1] vectors): cdef C_INT n = vectors.shape[0] cdef C_INT* a cdef C_INT* b cdef double min_dot = 2 # actual max is 1 for i in range(n): for j in range(i): a = &vectors[i, 0] b = &vectors[j, 0] # A highly nested arithmetic expression... normalized_dot = ((a[0]*b[0] + a[1]*b[1] + a[2]*b[2]) / (1.0 * (a[0]*a[0] + a[1]*a[1] + a[2]*a[2]) * (b[0]*b[0] + b[1]*b[1]+b[2]*b[2]))) if normalized_dot < min_dot: min_dot = normalized_dot min_pair = i, j return vectors[i], vectors[j] Cython-0.23.4/Demos/numpy_demo.pyx0000644000175600017570000000027712606202452020177 0ustar jenkinsjenkins00000000000000cimport numpy as cnp def sum_of_squares(cnp.ndarray[double, ndim=1] arr): cdef long N = arr.shape[0] cdef double ss = 0 for i in range(N): ss += arr[i]**2 return ss Cython-0.23.4/Demos/integrate_timing.py0000644000175600017570000000065512606202452021164 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import, print_function import timeit import integrate0, integrate1, integrate2 number = 10 py_time = None for m in ('integrate0', 'integrate1', 'integrate2'): print(m) t = min(timeit.repeat("integrate_f(0.0, 10.0, 10000000)", "from %s import integrate_f" % m, number=number)) if py_time is None: py_time = t print(" ", t / number, "s") print(" ", py_time / t) Cython-0.23.4/Demos/integrate2.pyx0000644000175600017570000000035412606202452020063 0ustar jenkinsjenkins00000000000000# cython: language_level=3 cdef double f(double x) except? -2: return x**2-x def integrate_f(double a, double b, int N): cdef int i s = 0.0 dx = (b-a)/N for i in range(N): s += f(a+i*dx) return s * dx Cython-0.23.4/Demos/integrate1.pyx0000644000175600017570000000026112606202452020057 0ustar jenkinsjenkins00000000000000# cython: language_level=3 def f(x): return x**2-x def integrate_f(a, b, N): s = 0.0 dx = (b-a)/N for i in range(N): s += f(a+i*dx) return s * dx Cython-0.23.4/Demos/integrate0.py0000644000175600017570000000022412606202452017665 0ustar jenkinsjenkins00000000000000def f(x): return x**2-x def integrate_f(a, b, N): s = 0.0 dx = (b-a)/N for i in range(N): s += f(a+i*dx) return s * dx Cython-0.23.4/Demos/Makefile.nodistutils0000644000175600017570000000060612606202452021275 0ustar jenkinsjenkins00000000000000PYHOME = $(HOME)/pkg/python/version PYINCLUDE = \ -I$(PYHOME)/include/python2.2 \ -I$(PYHOME)/$(ARCH)/include/python2.2 %.c: %.pyx ../bin/cython $< %.o: %.c gcc -c -fPIC $(PYINCLUDE) $< %.so: %.o gcc -shared $< -lm -o $@ all: primes.so spam.so numeric_demo.so clean: @echo Cleaning Demos @rm -f *.c *.o *.so *~ core core.* @cd callback; $(MAKE) clean @cd embed; $(MAKE) clean Cython-0.23.4/Demos/Makefile0000644000175600017570000000043212606202452016712 0ustar jenkinsjenkins00000000000000all: python setup.py build_ext --inplace test: all python run_primes.py 20 python run_numeric_demo.py python run_spam.py cd callback; $(MAKE) test clean: @echo Cleaning Demos @rm -f *.c *.o *.so *~ core @rm -rf build @cd callback; $(MAKE) clean @cd embed; $(MAKE) clean Cython-0.23.4/Demos/libraries/0000755000175600017570000000000012606202455017232 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Demos/libraries/setup.py0000644000175600017570000000165612606202452020751 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import, print_function import os import sys from distutils.core import setup from distutils.extension import Extension from Cython.Build import cythonize # For demo purposes, we build our own tiny library. try: print("building libmymath.a") assert os.system("gcc -shared -fPIC -c mymath.c -o mymath.o") == 0 assert os.system("ar rcs libmymath.a mymath.o") == 0 except: if not os.path.exists("libmymath.a"): print("Error building external library, please create libmymath.a manually.") sys.exit(1) # Here is how to use the library built above. ext_modules = cythonize([ Extension("call_mymath", sources=["call_mymath.pyx"], include_dirs=[os.getcwd()], # path to .h file(s) library_dirs=[os.getcwd()], # path to .a or .so file(s) libraries=['mymath']) ]) setup( name='Demos', ext_modules=ext_modules, ) Cython-0.23.4/Demos/libraries/mymath.h0000644000175600017570000000002512606202452020674 0ustar jenkinsjenkins00000000000000double sinc(double); Cython-0.23.4/Demos/libraries/mymath.c0000644000175600017570000000011712606202452020671 0ustar jenkinsjenkins00000000000000#include "math.h" double sinc(double x) { return x == 0 ? 1 : sin(x)/x; } Cython-0.23.4/Demos/libraries/call_mymath.pyx0000644000175600017570000000013312606202452022260 0ustar jenkinsjenkins00000000000000cdef extern from "mymath.h": double sinc(double) def call_sinc(x): return sinc(x) Cython-0.23.4/Demos/freeze/0000755000175600017570000000000012606202455016536 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Demos/freeze/lcmath.pyx0000644000175600017570000000113712606202452020547 0ustar jenkinsjenkins00000000000000# cython: language_level=3 cdef extern from "math.h": double c_lgamma "lgamma" (double) double c_exp "exp" (double) def exp(n): """Return e**n.""" return c_exp(n) def lfactorial(n): """Return an estimate of the log factorial of n.""" return c_lgamma(n+1) def factorial(n): """Return an estimate of the factorial of n.""" return c_exp( c_lgamma(n+1) ) if __name__ == "__main__": import sys if len(sys.argv) != 2: sys.stderr.write("USAGE: %s n\nPrints n!.\n" % sys.argv[0]) sys.exit(2) n, = map(float, sys.argv[1:]) print(factorial(n)) Cython-0.23.4/Demos/freeze/combinatorics.pyx0000644000175600017570000000073612606202452022137 0ustar jenkinsjenkins00000000000000# cython: language_level=3 import lcmath def nCr(n, r): """Return the number of ways to choose r elements of a set of n.""" return lcmath.exp( lcmath.lfactorial(n) - lcmath.lfactorial(r) - lcmath.lfactorial(n-r) ) if __name__ == "__main__": import sys if len(sys.argv) != 3: sys.stderr.write("USAGE: %s n r\nPrints n-choose-r.\n" % sys.argv[0]) sys.exit(2) n, r = map(float, sys.argv[1:]) print(nCr(n, r)) Cython-0.23.4/Demos/freeze/README.txt0000644000175600017570000000677712606202452020252 0ustar jenkinsjenkins00000000000000NAME ==== cython_freeze - create a C file for embedding Cython modules SYNOPSIS ======== cython_freeze [-o outfile] [-p] module [...] DESCRIPTION =========== **cython_freeze** generates a C source file to embed a Python interpreter with one or more Cython modules built in. This allows one to create a single executable from Cython code, without having to have separate shared objects for each Cython module. A major advantage of this approach is that it allows debuging with gprof(1), which does not work with shared objects. Unless ``-p`` is given, the first module's ``__name__`` is set to ``"__main__"`` and is imported on startup; if ``-p`` is given, a normal Python interpreter is built, with the given modules built into the binary. Note that this method differs from ``cython --embed``. The ``--embed`` options modifies the resulting C source file to include a ``main()`` function, so it can only be used on a single Cython module. The advantage ``--embed`` is simplicity. This module, on the other hand, can be used with multiple modules, but it requires another C source file to be created. OPTIONS ======= -o FILE, --outfile=FILE write output to FILE instead of standard output -p, --pymain do not automatically run the first module as __main__ EXAMPLE ======= In the Demos/freeze directory, there exist two Cython modules: lcmath.pyx A module that interfaces with the -lm library. combinatorics.pyx A module that implements n-choose-r using lcmath. Both modules have the Python idiom ``if __name__ == "__main__"``, which only execute if that module is the "main" module. If run as main, lcmath prints the factorial of the argument, while combinatorics prints n-choose-r. The provided Makefile creates an executable, *nCr*, using combinatorics as the "main" module. It basically performs the following (ignoring the compiler flags):: $ cython_freeze combinatorics lcmath > nCr.c $ cython combinatorics.pyx $ cython lcmath.pyx $ gcc -c nCr.c $ gcc -c combinatorics.c $ gcc -c lcmath.c $ gcc nCr.o combinatorics.o lcmath.o -o nCr Because the combinatorics module was listed first, its ``__name__`` is set to ``"__main__"``, while lcmath's is set to ``"lcmath"``. The executable now contains a Python interpreter and both Cython modules. :: $ ./nCr USAGE: ./nCr n r Prints n-choose-r. $ ./nCr 15812351235 12 5.10028093999e+113 You may wish to build a normal Python interpreter, rather than having one module as "main". This may happen if you want to use your module from an interactive shell or from another script, yet you still want it statically linked so you can profile it with gprof. To do this, add the ``--pymain`` flag to ``cython_freeze``. In the Makefile, the *python* executable is built like this. :: $ cython_freeze --pymain combinatorics lcmath -o python.c $ gcc -c python.c $ gcc python.o combinatorics.o lcmath.o -o python Now ``python`` is a normal Python interpreter, but the lcmath and combinatorics modules will be built into the executable. :: $ ./python Python 2.6.2 (release26-maint, Apr 19 2009, 01:58:18) [GCC 4.3.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import lcmath >>> lcmath.factorial(155) 4.7891429014634364e+273 PREREQUISITES ============= Cython 0.11.2 (or newer, assuming the API does not change) SEE ALSO ======== * `Python `_ * `Cython `_ * `freeze.py `_ Cython-0.23.4/Demos/freeze/Makefile0000644000175600017570000000251012606202452020171 0ustar jenkinsjenkins00000000000000CC = gcc CYTHON = ../../bin/cython CYTHON_FREEZE = ../../bin/cython_freeze PYTHON = python RST2HTML = rst2html PY_LDFLAGS = $(shell $(PYTHON) -c 'from distutils.sysconfig import get_config_var as g; import sys; sys.stdout.write(" ".join([g("LINKFORSHARED"), "-L"+g("LIBPL")]) + "\n")') PY_CPPFLAGS = $(shell $(PYTHON) -c 'from distutils.sysconfig import *; import sys; sys.stdout.write("-I"+get_python_inc() + "\n")') PY_LDLIBS = $(shell $(PYTHON) -c 'from distutils.sysconfig import get_config_var as g; import sys; sys.stdout.write(" ".join(["-lpython"+g("VERSION"), g("SYSLIBS"), g("LIBS"), g("LOCALMODLIBS")]) + "\n")') CFLAGS = -fPIC -fno-strict-aliasing -g -O2 -Wall -Wextra CPPFLAGS = $(PY_CPPFLAGS) LDFLAGS = $(PY_LDFLAGS) LDLIBS = $(PY_LDLIBS) # Name of executable TARGETS = nCr python # List of Cython source files, with main module first. CYTHON_SOURCE = combinatorics.pyx lcmath.pyx CYTHON_SECONDARY = $(CYTHON_SOURCE:.pyx=.c) $(TARGETS:=.c) all : $(TARGETS) html : README.html $(TARGETS) : % : %.o $(CYTHON_SOURCE:.pyx=.o) nCr.c : $(CYTHON_FREEZE) $(CYTHON_SOURCE:.pyx=) > $@ python.c : $(CYTHON_FREEZE) --pymain $(CYTHON_SOURCE:.pyx=) > $@ %.c : %.pyx $(CYTHON) $(CYTHONFLAGS) $^ %.html : %.txt $(RST2HTML) $^ $@ clean: $(RM) *.o $(CYTHON_SECONDARY) $(TARGETS) README.html .PHONY: clean .SECONDARY: $(CYTHON_SECONDARY) Cython-0.23.4/Demos/embed/0000755000175600017570000000000012606202455016332 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Demos/embed/embedded.pyx0000644000175600017570000000021612606202452020621 0ustar jenkinsjenkins00000000000000# cython: language_level=3 print(__name__) if __name__ == "__main__": print("Hi, I'm embedded.") else: print("I'm being imported.") Cython-0.23.4/Demos/embed/embedded.output0000644000175600017570000000003312606202452021336 0ustar jenkinsjenkins00000000000000__main__ Hi, I'm embedded. Cython-0.23.4/Demos/embed/assert_equal.py0000644000175600017570000000043212606202452021370 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import, print_function import sys f1 = open(sys.argv[1]) f2 = open(sys.argv[2]) try: if f1.read() != f2.read(): print("Files differ") sys.exit(1) else: print("Files identical") finally: f1.close() f2.close() Cython-0.23.4/Demos/embed/README0000644000175600017570000000031412606202452017205 0ustar jenkinsjenkins00000000000000This example demonstrates how Cython-generated code can be called directly from a main program written in C. The Windows makefiles were contributed by Duncan Booth . Cython-0.23.4/Demos/embed/Makefile.unix0000644000175600017570000000063012606202452020750 0ustar jenkinsjenkins00000000000000# Makefile for creating our standalone Cython program PYVERSION=2.3 PYPREFIX=/usr INCLUDES=-I$(PYPREFIX)/include/python$(PYVERSION) embedded: embedded.o gcc -o $@ $^ -lpython$(PYVERSION) embedded.o: embedded.c gcc -c $^ $(INCLUDES) embedded.c: embedded.pyx @python ../../cython.py --embed embedded.pyx all: embedded clean: @echo Cleaning Demos/embed @rm -f *~ *.o *.so core core.* *.c embedded Cython-0.23.4/Demos/embed/Makefile.msc.static0000644000175600017570000000076412606202452022045 0ustar jenkinsjenkins00000000000000# Makefile for Microsoft compiler statically linking PYVERSION = 2.2 PYHOME = \Python$(PYVERSION:.=) PYINCLUDE = -I$(PYHOME)\include PYLIB = /LIBPATH:$(PYHOME)\libs python22.lib CFLAGS = $(PYINCLUDE) /Ox /W3 /GX -nologo .SUFFIXES: .exe .dll .obj .c .cpp .pyx .pyx.c: $(PYHOME)\Python.exe ../../cython.py $< all: main.exe clean: -del /Q/F *.obj embedded.h embedded.c main.exe main.exe: main.obj embedded.obj link /nologo $** $(PYLIB) /OUT:main.exe embedded.h: embedded.c main.obj: embedded.h Cython-0.23.4/Demos/embed/Makefile.msc0000644000175600017570000000175512606202452020560 0ustar jenkinsjenkins00000000000000# Makefile for Microsoft C Compiler, building a DLL PYVERSION = 2.2 PYHOME = \Python$(PYVERSION:.=) PYINCLUDE = -I$(PYHOME)\include PYLIB = /LIBPATH:$(PYHOME)\libs CFLAGS = $(PYINCLUDE) /Ox /W3 /GX -nologo .SUFFIXES: .exe .dll .obj .c .cpp .pyx .pyx.c: $(PYHOME)\Python.exe ../../cython.py $< all: main.exe clean: del /Q/F *.obj embedded.h embedded.c main.exe embedded.dll embedded.lib embedded.exp # When linking the DLL we must explicitly list all of the exports # There doesn't seem to be an easy way to get DL_EXPORT to have the correct definition # to do the export for us without breaking the importing of symbols from the core # python library. embedded.dll: embedded.obj link /nologo /DLL /INCREMENTAL:NO $(PYLIB) $** /IMPLIB:$*.lib /DEF:<< /OUT:$*.dll EXPORTS initembedded EXPORTS spam << main.exe: main.obj embedded.lib link /nologo $** $(PYLIB) /OUT:main.exe embedded.h: embedded.c main.obj: embedded.h embedded.obj: embedded.c $(CC) /MD $(CFLAGS) -c $** embedded.lib: embedded.dll Cython-0.23.4/Demos/embed/Makefile0000644000175600017570000000341412606202452017771 0ustar jenkinsjenkins00000000000000# Makefile for creating our standalone Cython program PYTHON := python PYVERSION := $(shell $(PYTHON) -c "import sys; print(sys.version[:3])") INCDIR := $(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_python_inc())") PLATINCDIR := $(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_python_inc(plat_specific=True))") LIBDIR1 := $(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_config_var('LIBDIR'))") LIBDIR2 := $(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_config_var('LIBPL'))") PYLIB := $(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_config_var('LIBRARY')[3:-2])") CC := $(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('CC'))") LINKCC := $(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LINKCC'))") LINKFORSHARED := $(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LINKFORSHARED'))") LIBS := $(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LIBS'))") SYSLIBS := $(shell $(PYTHON) -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('SYSLIBS'))") embedded: embedded.o $(LINKCC) -o $@ $^ -L$(LIBDIR1) -L$(LIBDIR2) -l$(PYLIB) $(LIBS) $(SYSLIBS) $(LINKFORSHARED) embedded.o: embedded.c $(CC) -c $^ -I$(INCDIR) -I$(PLATINCDIR) CYTHON := ../../cython.py embedded.c: embedded.pyx @$(PYTHON) $(CYTHON) --embed embedded.pyx all: embedded clean: @echo Cleaning Demos/embed @rm -f *~ *.o *.so core core.* *.c embedded test.output test: clean all LD_LIBRARY_PATH=$(LIBDIR1):$$LD_LIBRARY_PATH ./embedded > test.output $(PYTHON) assert_equal.py embedded.output test.output Cython-0.23.4/Demos/callback/0000755000175600017570000000000012606202455017012 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Demos/callback/run_cheese.py0000644000175600017570000000015012606202452021475 0ustar jenkinsjenkins00000000000000import cheese def report_cheese(name): print("Found cheese: " + name) cheese.find(report_cheese) Cython-0.23.4/Demos/callback/cheesefinder.h0000644000175600017570000000016312606202452021604 0ustar jenkinsjenkins00000000000000typedef void (*cheesefunc)(char *name, void *user_data); void find_cheeses(cheesefunc user_func, void *user_data); Cython-0.23.4/Demos/callback/cheesefinder.c0000644000175600017570000000050312606202452021575 0ustar jenkinsjenkins00000000000000/* * An example of a C API that provides a callback mechanism. */ #include "cheesefinder.h" static char *cheeses[] = { "cheddar", "camembert", "that runny one", 0 }; void find_cheeses(cheesefunc user_func, void *user_data) { char **p = cheeses; while (*p) { user_func(*p, user_data); ++p; } } Cython-0.23.4/Demos/callback/cheese.pyx0000644000175600017570000000050512606202452021005 0ustar jenkinsjenkins00000000000000# # Cython wrapper for the cheesefinder API # cdef extern from "cheesefinder.h": ctypedef void (*cheesefunc)(char *name, void *user_data) void find_cheeses(cheesefunc user_func, void *user_data) def find(f): find_cheeses(callback, f) cdef void callback(char *name, void *f): (f)(name) Cython-0.23.4/Demos/callback/Setup.py0000644000175600017570000000035212606202452020461 0ustar jenkinsjenkins00000000000000from distutils.core import setup from distutils.extension import Extension from Cython.Build import cythonize setup( name = 'callback', ext_modules=cythonize([ Extension("cheese", ["cheese.pyx", "cheesefinder.c"]), ]), ) Cython-0.23.4/Demos/callback/README.txt0000644000175600017570000000052712606202452020511 0ustar jenkinsjenkins00000000000000This example demonstrates how you can wrap a C API that has a callback interface, so that you can pass Python functions to it as callbacks. The files cheesefinder.h and cheesefinder.c represent the C library to be wrapped. The file cheese.pyx is the Pyrex module which wraps it. The file run_cheese.py demonstrates how to call the wrapper. Cython-0.23.4/Demos/callback/Makefile.nodistutils0000644000175600017570000000050312606202452023025 0ustar jenkinsjenkins00000000000000PYHOME = $(HOME)/pkg/python/version PYINCLUDE = \ -I$(PYHOME)/include/python2.2 \ -I$(PYHOME)/$(ARCH)/include/python2.2 %.c: %.pyx ../../bin/cython $< %.o: %.c gcc -c -fPIC $(PYINCLUDE) $< %.so: %.o gcc -shared $< -lm -o $@ all: cheese.so clean: @echo Cleaning Demos/callback @rm -f *.c *.o *.so *~ core core.* Cython-0.23.4/Demos/callback/Makefile0000644000175600017570000000024312606202452020446 0ustar jenkinsjenkins00000000000000all: python Setup.py build_ext --inplace test: all python run_cheese.py clean: @echo Cleaning Demos/callback @rm -f cheese.c *.o *.so *~ core @rm -rf build Cython-0.23.4/Demos/benchmarks/0000755000175600017570000000000012606202455017373 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Demos/benchmarks/util.py0000644000175600017570000000351412606202452020722 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python """Utility code for benchmark scripts.""" __author__ = "collinwinter@google.com (Collin Winter)" import math import operator try: reduce except NameError: from functools import reduce def run_benchmark(options, num_runs, bench_func, *args): """Run the given benchmark, print results to stdout. Args: options: optparse.Values instance. num_runs: number of times to run the benchmark bench_func: benchmark function. `num_runs, *args` will be passed to this function. This should return a list of floats (benchmark execution times). """ if options.profile: import cProfile prof = cProfile.Profile() prof.runcall(bench_func, num_runs, *args) prof.print_stats(sort=options.profile_sort) else: data = bench_func(num_runs, *args) if options.take_geo_mean: product = reduce(operator.mul, data, 1) print(math.pow(product, 1.0 / len(data))) else: for x in data: print(x) def add_standard_options_to(parser): """Add a bunch of common command-line flags to an existing OptionParser. This function operates on `parser` in-place. Args: parser: optparse.OptionParser instance. """ parser.add_option("-n", action="store", type="int", default=100, dest="num_runs", help="Number of times to run the test.") parser.add_option("--profile", action="store_true", help="Run the benchmark through cProfile.") parser.add_option("--profile_sort", action="store", type="str", default="time", help="Column to sort cProfile output by.") parser.add_option("--take_geo_mean", action="store_true", help="Return the geo mean, rather than individual data.") Cython-0.23.4/Demos/benchmarks/spectralnorm.py0000644000175600017570000000313512606202452022455 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- # The Computer Language Benchmarks Game # http://shootout.alioth.debian.org/ # Contributed by Sebastien Loisel # Fixed by Isaac Gouy # Sped up by Josh Goldfoot # Dirtily sped up by Simon Descarpentries # Concurrency by Jason Stitt from time import time import util import optparse def eval_A (i, j): return 1.0 / ((i + j) * (i + j + 1) / 2 + i + 1) def eval_A_times_u (u): return [ part_A_times_u(i,u) for i in range(len(u)) ] def eval_At_times_u (u): return [ part_At_times_u(i,u) for i in range(len(u)) ] def eval_AtA_times_u (u): return eval_At_times_u (eval_A_times_u (u)) def part_A_times_u(i, u): partial_sum = 0 for j, u_j in enumerate(u): partial_sum += eval_A (i, j) * u_j return partial_sum def part_At_times_u(i, u): partial_sum = 0 for j, u_j in enumerate(u): partial_sum += eval_A (j, i) * u_j return partial_sum DEFAULT_N = 130 def main(n): times = [] for i in range(n): t0 = time() u = [1] * DEFAULT_N for dummy in range (10): v = eval_AtA_times_u (u) u = eval_AtA_times_u (v) vBv = vv = 0 for ue, ve in zip (u, v): vBv += ue * ve vv += ve * ve tk = time() times.append(tk - t0) return times if __name__ == "__main__": parser = optparse.OptionParser( usage="%prog [options]", description="Test the performance of the spectralnorm benchmark") util.add_standard_options_to(parser) options, args = parser.parse_args() util.run_benchmark(options, options.num_runs, main) Cython-0.23.4/Demos/benchmarks/spectralnorm.pxd0000644000175600017570000000064112606202452022617 0ustar jenkinsjenkins00000000000000 cimport cython cdef inline double eval_A(double i, double j) @cython.locals(i=long) cdef list eval_A_times_u(list u) @cython.locals(i=long) cdef list eval_At_times_u(list u) cdef list eval_AtA_times_u(list u) @cython.locals(j=long, u_j=double, partial_sum=double) cdef double part_A_times_u(double i, list u) @cython.locals(j=long, u_j=double, partial_sum=double) cdef double part_At_times_u(double i, list u) Cython-0.23.4/Demos/benchmarks/setup.py0000644000175600017570000000051512606202452021103 0ustar jenkinsjenkins00000000000000from distutils.core import setup from Cython.Build import cythonize directives = { 'optimize.inline_defnode_calls': True } setup( name = 'benchmarks', ext_modules = cythonize("*.py", language_level=3, annotate=True, compiler_directives=directives, exclude="setup.py"), ) Cython-0.23.4/Demos/benchmarks/richards.py0000644000175600017570000002443012606202452021544 0ustar jenkinsjenkins00000000000000# based on a Java version: # Based on original version written in BCPL by Dr Martin Richards # in 1981 at Cambridge University Computer Laboratory, England # and a C++ version derived from a Smalltalk version written by # L Peter Deutsch. # Java version: Copyright (C) 1995 Sun Microsystems, Inc. # Translation from C++, Mario Wolczko # Outer loop added by Alex Jacoby # Task IDs I_IDLE = 1 I_WORK = 2 I_HANDLERA = 3 I_HANDLERB = 4 I_DEVA = 5 I_DEVB = 6 # Packet types K_DEV = 1000 K_WORK = 1001 # Packet BUFSIZE = 4 BUFSIZE_RANGE = range(BUFSIZE) class Packet(object): def __init__(self,l,i,k): self.link = l self.ident = i self.kind = k self.datum = 0 self.data = [0] * BUFSIZE def append_to(self,lst): self.link = None if lst is None: return self else: p = lst next = p.link while next is not None: p = next next = p.link p.link = self return lst # Task Records class TaskRec(object): pass class DeviceTaskRec(TaskRec): def __init__(self): self.pending = None class IdleTaskRec(TaskRec): def __init__(self): self.control = 1 self.count = 10000 class HandlerTaskRec(TaskRec): def __init__(self): self.work_in = None self.device_in = None def workInAdd(self,p): self.work_in = p.append_to(self.work_in) return self.work_in def deviceInAdd(self,p): self.device_in = p.append_to(self.device_in) return self.device_in class WorkerTaskRec(TaskRec): def __init__(self): self.destination = I_HANDLERA self.count = 0 # Task class TaskState(object): def __init__(self): self.packet_pending = True self.task_waiting = False self.task_holding = False def packetPending(self): self.packet_pending = True self.task_waiting = False self.task_holding = False return self def waiting(self): self.packet_pending = False self.task_waiting = True self.task_holding = False return self def running(self): self.packet_pending = False self.task_waiting = False self.task_holding = False return self def waitingWithPacket(self): self.packet_pending = True self.task_waiting = True self.task_holding = False return self def isPacketPending(self): return self.packet_pending def isTaskWaiting(self): return self.task_waiting def isTaskHolding(self): return self.task_holding def isTaskHoldingOrWaiting(self): return self.task_holding or (not self.packet_pending and self.task_waiting) def isWaitingWithPacket(self): return self.packet_pending and self.task_waiting and not self.task_holding tracing = False layout = 0 def trace(a): global layout layout -= 1 if layout <= 0: print() layout = 50 print(a, end='') TASKTABSIZE = 10 class TaskWorkArea(object): def __init__(self): self.taskTab = [None] * TASKTABSIZE self.taskList = None self.holdCount = 0 self.qpktCount = 0 taskWorkArea = TaskWorkArea() class Task(TaskState): def __init__(self,i,p,w,initialState,r): self.link = taskWorkArea.taskList self.ident = i self.priority = p self.input = w self.packet_pending = initialState.isPacketPending() self.task_waiting = initialState.isTaskWaiting() self.task_holding = initialState.isTaskHolding() self.handle = r taskWorkArea.taskList = self taskWorkArea.taskTab[i] = self def fn(self,pkt,r): raise NotImplementedError def addPacket(self,p,old): if self.input is None: self.input = p self.packet_pending = True if self.priority > old.priority: return self else: p.append_to(self.input) return old def runTask(self): if self.isWaitingWithPacket(): msg = self.input self.input = msg.link if self.input is None: self.running() else: self.packetPending() else: msg = None return self.fn(msg,self.handle) def waitTask(self): self.task_waiting = True return self def hold(self): taskWorkArea.holdCount += 1 self.task_holding = True return self.link def release(self,i): t = self.findtcb(i) t.task_holding = False if t.priority > self.priority: return t else: return self def qpkt(self,pkt): t = self.findtcb(pkt.ident) taskWorkArea.qpktCount += 1 pkt.link = None pkt.ident = self.ident return t.addPacket(pkt,self) def findtcb(self,id): t = taskWorkArea.taskTab[id] if t is None: raise Exception("Bad task id %d" % id) return t # DeviceTask class DeviceTask(Task): def __init__(self,i,p,w,s,r): Task.__init__(self,i,p,w,s,r) def fn(self,pkt,r): d = r assert isinstance(d, DeviceTaskRec) if pkt is None: pkt = d.pending if pkt is None: return self.waitTask() else: d.pending = None return self.qpkt(pkt) else: d.pending = pkt if tracing: trace(pkt.datum) return self.hold() class HandlerTask(Task): def __init__(self,i,p,w,s,r): Task.__init__(self,i,p,w,s,r) def fn(self,pkt,r): h = r assert isinstance(h, HandlerTaskRec) if pkt is not None: if pkt.kind == K_WORK: h.workInAdd(pkt) else: h.deviceInAdd(pkt) work = h.work_in if work is None: return self.waitTask() count = work.datum if count >= BUFSIZE: h.work_in = work.link return self.qpkt(work) dev = h.device_in if dev is None: return self.waitTask() h.device_in = dev.link dev.datum = work.data[count] work.datum = count + 1 return self.qpkt(dev) # IdleTask class IdleTask(Task): def __init__(self,i,p,w,s,r): Task.__init__(self,i,0,None,s,r) def fn(self,pkt,r): i = r assert isinstance(i, IdleTaskRec) i.count -= 1 if i.count == 0: return self.hold() elif i.control & 1 == 0: i.control //= 2 return self.release(I_DEVA) else: i.control = i.control//2 ^ 0xd008 return self.release(I_DEVB) # WorkTask A = ord('A') class WorkTask(Task): def __init__(self,i,p,w,s,r): Task.__init__(self,i,p,w,s,r) def fn(self,pkt,r): w = r assert isinstance(w, WorkerTaskRec) if pkt is None: return self.waitTask() if w.destination == I_HANDLERA: dest = I_HANDLERB else: dest = I_HANDLERA w.destination = dest pkt.ident = dest pkt.datum = 0 for i in BUFSIZE_RANGE: # range(BUFSIZE) w.count += 1 if w.count > 26: w.count = 1 pkt.data[i] = A + w.count - 1 return self.qpkt(pkt) import time def schedule(): t = taskWorkArea.taskList while t is not None: pkt = None if tracing: print("tcb =", t.ident) if t.isTaskHoldingOrWaiting(): t = t.link else: if tracing: trace(chr(ord("0")+t.ident)) t = t.runTask() class Richards(object): def run(self, iterations): for i in range(iterations): taskWorkArea.holdCount = 0 taskWorkArea.qpktCount = 0 IdleTask(I_IDLE, 1, 10000, TaskState().running(), IdleTaskRec()) wkq = Packet(None, 0, K_WORK) wkq = Packet(wkq , 0, K_WORK) WorkTask(I_WORK, 1000, wkq, TaskState().waitingWithPacket(), WorkerTaskRec()) wkq = Packet(None, I_DEVA, K_DEV) wkq = Packet(wkq , I_DEVA, K_DEV) wkq = Packet(wkq , I_DEVA, K_DEV) HandlerTask(I_HANDLERA, 2000, wkq, TaskState().waitingWithPacket(), HandlerTaskRec()) wkq = Packet(None, I_DEVB, K_DEV) wkq = Packet(wkq , I_DEVB, K_DEV) wkq = Packet(wkq , I_DEVB, K_DEV) HandlerTask(I_HANDLERB, 3000, wkq, TaskState().waitingWithPacket(), HandlerTaskRec()) wkq = None; DeviceTask(I_DEVA, 4000, wkq, TaskState().waiting(), DeviceTaskRec()); DeviceTask(I_DEVB, 5000, wkq, TaskState().waiting(), DeviceTaskRec()); schedule() if taskWorkArea.holdCount == 9297 and taskWorkArea.qpktCount == 23246: pass else: return False return True def entry_point(iterations): r = Richards() startTime = time.time() result = r.run(iterations) endTime = time.time() return result, startTime, endTime def main(iterations = 10, entry_point = entry_point): print("Richards benchmark (Python) starting... [%r]" % entry_point) result, startTime, endTime = entry_point(iterations) if not result: print("Incorrect results!") return -1 print("finished.") total_s = endTime - startTime print("Total time for %d iterations: %.2f secs" % (iterations, total_s)) print("Average time per iteration: %.2f ms" % (total_s*1000/iterations)) return 42 try: import sys if '-nojit' in sys.argv: sys.argv.remove('-nojit') raise ImportError import pypyjit except ImportError: pass else: import types for item in globals().values(): if isinstance(item, types.FunctionType): pypyjit.enable(item.func_code) elif isinstance(item, type): for it in item.__dict__.values(): if isinstance(it, types.FunctionType): pypyjit.enable(it.func_code) if __name__ == '__main__': import sys if len(sys.argv) >= 2: main(iterations = int(sys.argv[1])) else: main() Cython-0.23.4/Demos/benchmarks/richards.pxd0000644000175600017570000000457112606202452021713 0ustar jenkinsjenkins00000000000000cimport cython @cython.final cdef class Packet: cdef public object link cdef public object ident cdef public object kind cdef public Py_ssize_t datum cdef public list data cpdef append_to(self,lst) cdef class TaskRec: pass @cython.final cdef class DeviceTaskRec(TaskRec): cdef public object pending @cython.final cdef class IdleTaskRec(TaskRec): cdef public long control cdef public Py_ssize_t count @cython.final cdef class HandlerTaskRec(TaskRec): cdef public object work_in # = None cdef public object device_in # = None cpdef workInAdd(self, Packet p) cpdef deviceInAdd(self, Packet p) @cython.final cdef class WorkerTaskRec(TaskRec): cdef public object destination # = I_HANDLERA cdef public Py_ssize_t count cdef class TaskState: cdef public bint packet_pending # = True cdef public bint task_waiting # = False cdef public bint task_holding # = False cpdef packetPending(self) cpdef waiting(self) cpdef running(self) cpdef waitingWithPacket(self) cpdef bint isPacketPending(self) cpdef bint isTaskWaiting(self) cpdef bint isTaskHolding(self) cpdef bint isTaskHoldingOrWaiting(self) cpdef bint isWaitingWithPacket(self) cdef class TaskWorkArea: cdef public list taskTab # = [None] * TASKTABSIZE cdef public object taskList # = None cdef public Py_ssize_t holdCount # = 0 cdef public Py_ssize_t qpktCount # = 0 cdef class Task(TaskState): cdef public Task link # = taskWorkArea.taskList cdef public object ident # = i cdef public object priority # = p cdef public object input # = w cdef public object handle # = r cpdef addPacket(self,Packet p,Task old) cpdef runTask(self) cpdef waitTask(self) cpdef hold(self) cpdef release(self,i) cpdef qpkt(self,Packet pkt) cpdef findtcb(self,id) cdef class DeviceTask(Task): @cython.locals(d=DeviceTaskRec) cpdef fn(self,Packet pkt,DeviceTaskRec r) cdef class HandlerTask(Task): @cython.locals(h=HandlerTaskRec) cpdef fn(self,Packet pkt,HandlerTaskRec r) cdef class IdleTask(Task): @cython.locals(i=IdleTaskRec) cpdef fn(self,Packet pkt,IdleTaskRec r) cdef class WorkTask(Task): @cython.locals(w=WorkerTaskRec) cpdef fn(self,Packet pkt,WorkerTaskRec r) @cython.locals(t=Task) cpdef schedule() cdef class Richards: cpdef run(self, iterations) Cython-0.23.4/Demos/benchmarks/nqueens.py0000644000175600017570000000457612606202452021434 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python """Simple, brute-force N-Queens solver.""" __author__ = "collinwinter@google.com (Collin Winter)" # Python imports import optparse import re import string from time import time # Local imports import util import cython try: from builtins import range as _xrange except ImportError: from __builtin__ import xrange as _xrange # Pure-Python implementation of itertools.permutations(). @cython.locals(n=int, i=int, j=int) def permutations(iterable): """permutations(range(3), 2) --> (0,1) (0,2) (1,0) (1,2) (2,0) (2,1)""" pool = tuple(iterable) n = len(pool) indices = list(range(n)) cycles = list(range(1, n+1))[::-1] yield [ pool[i] for i in indices ] while n: for i in reversed(range(n)): j = cycles[i] - 1 if j == 0: indices[i:] = indices[i+1:] + indices[i:i+1] cycles[i] = n - i else: cycles[i] = j indices[i], indices[-j] = indices[-j], indices[i] yield [ pool[i] for i in indices ] break else: return # From http://code.activestate.com/recipes/576647/ @cython.locals(queen_count=int, i=int, vec=list) def n_queens(queen_count): """N-Queens solver. Args: queen_count: the number of queens to solve for. This is also the board size. Yields: Solutions to the problem. Each yielded value is looks like (3, 8, 2, 1, 4, ..., 6) where each number is the column position for the queen, and the index into the tuple indicates the row. """ cols = list(range(queen_count)) for vec in permutations(cols): if (queen_count == len({ vec[i]+i for i in cols }) == len({ vec[i]-i for i in cols })): yield vec def test_n_queens(iterations): # Warm-up runs. list(n_queens(8)) list(n_queens(8)) times = [] for _ in _xrange(iterations): t0 = time() list(n_queens(8)) t1 = time() times.append(t1 - t0) return times main = test_n_queens if __name__ == "__main__": parser = optparse.OptionParser( usage="%prog [options]", description=("Test the performance of an N-Queens solvers.")) util.add_standard_options_to(parser) options, args = parser.parse_args() util.run_benchmark(options, options.num_runs, test_n_queens) Cython-0.23.4/Demos/benchmarks/nbody.py0000644000175600017570000001071512606202452021061 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python """N-body benchmark from the Computer Language Benchmarks Game. This is intended to support Unladen Swallow's perf.py. Accordingly, it has been modified from the Shootout version: - Accept standard Unladen Swallow benchmark options. - Run report_energy()/advance() in a loop. - Reimplement itertools.combinations() to work with older Python versions. """ # Pulled from http://shootout.alioth.debian.org/u64q/benchmark.php?test=nbody&lang=python&id=4 # Contributed by Kevin Carson. # Modified by Tupteq, Fredrik Johansson, and Daniel Nanz. __contact__ = "collinwinter@google.com (Collin Winter)" # Python imports import optparse import sys from time import time # Local imports import util def combinations(l): """Pure-Python implementation of itertools.combinations(l, 2).""" result = [] for x in range(len(l) - 1): ls = l[x+1:] for y in ls: result.append((l[x],y)) return result PI = 3.14159265358979323 SOLAR_MASS = 4 * PI * PI DAYS_PER_YEAR = 365.24 BODIES = { 'sun': ([0.0, 0.0, 0.0], [0.0, 0.0, 0.0], SOLAR_MASS), 'jupiter': ([4.84143144246472090e+00, -1.16032004402742839e+00, -1.03622044471123109e-01], [1.66007664274403694e-03 * DAYS_PER_YEAR, 7.69901118419740425e-03 * DAYS_PER_YEAR, -6.90460016972063023e-05 * DAYS_PER_YEAR], 9.54791938424326609e-04 * SOLAR_MASS), 'saturn': ([8.34336671824457987e+00, 4.12479856412430479e+00, -4.03523417114321381e-01], [-2.76742510726862411e-03 * DAYS_PER_YEAR, 4.99852801234917238e-03 * DAYS_PER_YEAR, 2.30417297573763929e-05 * DAYS_PER_YEAR], 2.85885980666130812e-04 * SOLAR_MASS), 'uranus': ([1.28943695621391310e+01, -1.51111514016986312e+01, -2.23307578892655734e-01], [2.96460137564761618e-03 * DAYS_PER_YEAR, 2.37847173959480950e-03 * DAYS_PER_YEAR, -2.96589568540237556e-05 * DAYS_PER_YEAR], 4.36624404335156298e-05 * SOLAR_MASS), 'neptune': ([1.53796971148509165e+01, -2.59193146099879641e+01, 1.79258772950371181e-01], [2.68067772490389322e-03 * DAYS_PER_YEAR, 1.62824170038242295e-03 * DAYS_PER_YEAR, -9.51592254519715870e-05 * DAYS_PER_YEAR], 5.15138902046611451e-05 * SOLAR_MASS) } SYSTEM = list(BODIES.values()) PAIRS = combinations(SYSTEM) def advance(dt, n, bodies=SYSTEM, pairs=PAIRS): for i in range(n): for (([x1, y1, z1], v1, m1), ([x2, y2, z2], v2, m2)) in pairs: dx = x1 - x2 dy = y1 - y2 dz = z1 - z2 mag = dt * ((dx * dx + dy * dy + dz * dz) ** (-1.5)) b1m = m1 * mag b2m = m2 * mag v1[0] -= dx * b2m v1[1] -= dy * b2m v1[2] -= dz * b2m v2[0] += dx * b1m v2[1] += dy * b1m v2[2] += dz * b1m for (r, [vx, vy, vz], m) in bodies: r[0] += dt * vx r[1] += dt * vy r[2] += dt * vz def report_energy(bodies=SYSTEM, pairs=PAIRS, e=0.0): for (((x1, y1, z1), v1, m1), ((x2, y2, z2), v2, m2)) in pairs: dx = x1 - x2 dy = y1 - y2 dz = z1 - z2 e -= (m1 * m2) / ((dx * dx + dy * dy + dz * dz) ** 0.5) for (r, [vx, vy, vz], m) in bodies: e += m * (vx * vx + vy * vy + vz * vz) / 2. return e def offset_momentum(ref, bodies=SYSTEM, px=0.0, py=0.0, pz=0.0): for (r, [vx, vy, vz], m) in bodies: px -= vx * m py -= vy * m pz -= vz * m (r, v, m) = ref v[0] = px / m v[1] = py / m v[2] = pz / m def test_nbody(iterations): # Warm-up runs. report_energy() advance(0.01, 20000) report_energy() times = [] for _ in range(iterations): t0 = time() report_energy() advance(0.01, 20000) report_energy() t1 = time() times.append(t1 - t0) return times main = test_nbody if __name__ == '__main__': parser = optparse.OptionParser( usage="%prog [options]", description=("Run the n-body benchmark.")) util.add_standard_options_to(parser) options, args = parser.parse_args() offset_momentum(BODIES['sun']) # Set up global state util.run_benchmark(options, options.num_runs, test_nbody) Cython-0.23.4/Demos/benchmarks/nbody.pxd0000644000175600017570000000126712606202452021226 0ustar jenkinsjenkins00000000000000 cimport cython @cython.locals(x=Py_ssize_t) cdef combinations(list l) @cython.locals(x1=double, x2=double, y1=double, y2=double, z1=double, z2=double, m1=double, m2=double, vx=double, vy=double, vz=double, i=long) cdef advance(double dt, long n, list bodies=*, list pairs=*) @cython.locals(x1=double, x2=double, y1=double, y2=double, z1=double, z2=double, m=double, m1=double, m2=double, vx=double, vy=double, vz=double) cdef report_energy(list bodies=*, list pairs=*, double e=*) @cython.locals(vx=double, vy=double, vz=double, m=double) cdef offset_momentum(tuple ref, list bodies=*, double px=*, double py=*, double pz=*) cpdef test_nbody(long iterations) Cython-0.23.4/Demos/benchmarks/meteor_contest.py0000644000175600017570000001044512606202452023000 0ustar jenkinsjenkins00000000000000# The Computer Language Benchmarks Game # http://shootout.alioth.debian.org/ # # contributed by Daniel Nanz, 2008-08-21 import optparse import time from bisect import bisect import util w, h = 5, 10 dir_no = 6 S, E = w * h, 2 SE = S + (E / 2) SW = SE - E W, NW, NE = -E, -SE, -SW def rotate(ido, rd={E: NE, NE: NW, NW: W, W: SW, SW: SE, SE: E}): return [rd[o] for o in ido] def flip(ido, fd={E: E, NE: SE, NW: SW, W: W, SW: NW, SE: NE}): return [fd[o] for o in ido] def permute(ido, r_ido): ps = [ido] for r in range(dir_no - 1): ps.append(rotate(ps[-1])) if ido == r_ido: # C2-symmetry ps = ps[0:dir_no//2] for pp in ps[:]: ps.append(flip(pp)) return ps def convert(ido): '''incremental direction offsets -> "coordinate offsets" ''' out = [0] for o in ido: out.append(out[-1] + o) return list(set(out)) def get_footprints(board, cti, pieces): fps = [[[] for p in range(len(pieces))] for ci in range(len(board))] for c in board: for pi, p in enumerate(pieces): for pp in p: fp = frozenset([cti[c + o] for o in pp if (c + o) in cti]) if len(fp) == 5: fps[min(fp)][pi].append(fp) return fps def get_senh(board, cti): '''-> south-east neighborhood''' se_nh = [] nh = [E, SW, SE] for c in board: se_nh.append(frozenset([cti[c + o] for o in nh if (c + o) in cti])) return se_nh def get_puzzle(w=w, h=h): board = [E*x + S*y + (y%2) for y in range(h) for x in range(w)] cti = dict((board[i], i) for i in range(len(board))) idos = [[E, E, E, SE], # incremental direction offsets [SE, SW, W, SW], [W, W, SW, SE], [E, E, SW, SE], [NW, W, NW, SE, SW], [E, E, NE, W], [NW, NE, NE, W], [NE, SE, E, NE], [SE, SE, E, SE], [E, NW, NW, NW]] perms = (permute(p, idos[3]) for p in idos) # restrict piece 4 pieces = [[convert(pp) for pp in p] for p in perms] return (board, cti, pieces) def print_board(board, w=w, h=h): for y in range(h): for x in range(w): print(board[x + y * w]) print('') if y % 2 == 0: print('') print() board, cti, pieces = get_puzzle() fps = get_footprints(board, cti, pieces) se_nh = get_senh(board, cti) def solve(n, i_min, free, curr_board, pieces_left, solutions, fps=fps, se_nh=se_nh, bisect=bisect): fp_i_cands = fps[i_min] for p in pieces_left: fp_cands = fp_i_cands[p] for fp in fp_cands: if fp <= free: n_curr_board = curr_board[:] for ci in fp: n_curr_board[ci] = p if len(pieces_left) > 1: n_free = free - fp n_i_min = min(n_free) if len(n_free & se_nh[n_i_min]) > 0: n_pieces_left = pieces_left[:] n_pieces_left.remove(p) solve(n, n_i_min, n_free, n_curr_board, n_pieces_left, solutions) else: s = ''.join(map(str, n_curr_board)) solutions.insert(bisect(solutions, s), s) rs = s[::-1] solutions.insert(bisect(solutions, rs), rs) if len(solutions) >= n: return if len(solutions) >= n: return return SOLVE_ARG = 60 def main(n): times = [] for i in range(n): t0 = time.time() free = frozenset(range(len(board))) curr_board = [-1] * len(board) pieces_left = list(range(len(pieces))) solutions = [] solve(SOLVE_ARG, 0, free, curr_board, pieces_left, solutions) #print len(solutions), 'solutions found\n' #for i in (0, -1): print_board(solutions[i]) tk = time.time() times.append(tk - t0) return times if __name__ == "__main__": parser = optparse.OptionParser( usage="%prog [options]", description="Test the performance of the Float benchmark") util.add_standard_options_to(parser) options, args = parser.parse_args() util.run_benchmark(options, options.num_runs, main) Cython-0.23.4/Demos/benchmarks/meteor_contest.pxd0000644000175600017570000000045312606202452023141 0ustar jenkinsjenkins00000000000000cimport cython cdef list rotate(list ido, dict rd=*) cdef list flip(list ido, dict fd=*) cdef list permute(list ido, list r_ido) @cython.locals(n_i_min=long) cpdef solve(long n, long i_min, free, list curr_board, list pieces_left, list solutions, list fps=*, list se_nh=*, bisect=*) Cython-0.23.4/Demos/benchmarks/hexiom2.py0000644000175600017570000004160612606202452021324 0ustar jenkinsjenkins00000000000000"""Benchmark from Laurent Vaucher. Source: https://github.com/slowfrog/hexiom : hexiom2.py, level36.txt (Main function tweaked by Armin Rigo.) """ from __future__ import division, print_function import time from io import StringIO import cython ################################## class Dir(object): def __init__(self, x, y): self.x = x self.y = y DIRS = [ Dir(1, 0), Dir(-1, 0), Dir(0, 1), Dir(0, -1), Dir(1, 1), Dir(-1, -1) ] EMPTY = 7 ################################## class Done(object): MIN_CHOICE_STRATEGY = 0 MAX_CHOICE_STRATEGY = 1 HIGHEST_VALUE_STRATEGY = 2 FIRST_STRATEGY = 3 MAX_NEIGHBORS_STRATEGY = 4 MIN_NEIGHBORS_STRATEGY = 5 def __init__(self, count, empty=False): self.count = count self.cells = None if empty else [[0, 1, 2, 3, 4, 5, 6, EMPTY] for i in range(count)] def clone(self): ret = Done(self.count, True) ret.cells = [self.cells[i][:] for i in range(self.count)] return ret def __getitem__(self, i): return self.cells[i] def set_done(self, i, v): self.cells[i] = [v] def already_done(self, i): return len(self.cells[i]) == 1 def remove(self, i, v): if v in self.cells[i]: self.cells[i].remove(v) return True else: return False def remove_all(self, v): for i in range(self.count): self.remove(i, v) def remove_unfixed(self, v): changed = False for i in range(self.count): if not self.already_done(i): if self.remove(i, v): changed = True return changed def filter_tiles(self, tiles): for v in range(8): if tiles[v] == 0: self.remove_all(v) @cython.locals(i=cython.int) def next_cell_min_choice(self): minlen = 10 mini = -1 for i in range(self.count): if 1 < len(self.cells[i]) < minlen: minlen = len(self.cells[i]) mini = i return mini @cython.locals(i=cython.int) def next_cell_max_choice(self): maxlen = 1 maxi = -1 for i in range(self.count): if maxlen < len(self.cells[i]): maxlen = len(self.cells[i]) maxi = i return maxi @cython.locals(i=cython.int) def next_cell_highest_value(self): maxval = -1 maxi = -1 for i in range(self.count): if (not self.already_done(i)): maxvali = max([k for k in self.cells[i] if k != EMPTY]) if maxval < maxvali: maxval = maxvali maxi = i return maxi @cython.locals(i=cython.int) def next_cell_first(self): for i in range(self.count): if (not self.already_done(i)): return i return -1 @cython.locals(i=cython.int) def next_cell_max_neighbors(self, pos): maxn = -1 maxi = -1 for i in range(self.count): if not self.already_done(i): cells_around = pos.hex.get_by_id(i).links n = sum([1 if (self.already_done(nid) and (self[nid][0] != EMPTY)) else 0 for nid in cells_around]) if n > maxn: maxn = n maxi = i return maxi @cython.locals(i=cython.int) def next_cell_min_neighbors(self, pos): minn = 7 mini = -1 for i in range(self.count): if not self.already_done(i): cells_around = pos.hex.get_by_id(i).links n = sum([1 if (self.already_done(nid) and (self[nid][0] != EMPTY)) else 0 for nid in cells_around]) if n < minn: minn = n mini = i return mini def next_cell(self, pos, strategy=HIGHEST_VALUE_STRATEGY): if strategy == Done.HIGHEST_VALUE_STRATEGY: return self.next_cell_highest_value() elif strategy == Done.MIN_CHOICE_STRATEGY: return self.next_cell_min_choice() elif strategy == Done.MAX_CHOICE_STRATEGY: return self.next_cell_max_choice() elif strategy == Done.FIRST_STRATEGY: return self.next_cell_first() elif strategy == Done.MAX_NEIGHBORS_STRATEGY: return self.next_cell_max_neighbors(pos) elif strategy == Done.MIN_NEIGHBORS_STRATEGY: return self.next_cell_min_neighbors(pos) else: raise Exception("Wrong strategy: %d" % strategy) ################################## class Node(object): def __init__(self, pos, id, links): self.pos = pos self.id = id self.links = links ################################## class Hex(object): @cython.locals(size=cython.int, id=cython.int, x=cython.int, y=cython.int) def __init__(self, size): self.size = size self.count = 3 * size * (size - 1) + 1 self.nodes_by_id = self.count * [None] self.nodes_by_pos = {} id = 0 for y in range(size): for x in range(size + y): pos = (x, y) node = Node(pos, id, []) self.nodes_by_pos[pos] = node self.nodes_by_id[node.id] = node id += 1 for y in range(1, size): for x in range(y, size * 2 - 1): ry = size + y - 1 pos = (x, ry) node = Node(pos, id, []) self.nodes_by_pos[pos] = node self.nodes_by_id[node.id] = node id += 1 @cython.locals(dir=Dir, x=cython.int, y=cython.int, nx=cython.int, ny=cython.int, node=Node) def link_nodes(self): for node in self.nodes_by_id: (x, y) = node.pos for dir in DIRS: nx = x + dir.x ny = y + dir.y if self.contains_pos((nx, ny)): node.links.append(self.nodes_by_pos[(nx, ny)].id) def contains_pos(self, pos): return pos in self.nodes_by_pos def get_by_pos(self, pos): return self.nodes_by_pos[pos] def get_by_id(self, id): return self.nodes_by_id[id] ################################## class Pos(object): def __init__(self, hex, tiles, done = None): self.hex = hex self.tiles = tiles self.done = Done(hex.count) if done is None else done def clone(self): return Pos(self.hex, self.tiles, self.done.clone()) ################################## @cython.locals(pos=Pos, i=cython.long, v=cython.int, nid=cython.int, num=cython.int, empties=cython.int, filled=cython.int, vmax=cython.int, vmin=cython.int, cell=list, left=cython.int[8]) def constraint_pass(pos, last_move=None): changed = False left = pos.tiles[:] done = pos.done # Remove impossible values from free cells free_cells = (range(done.count) if last_move is None else pos.hex.get_by_id(last_move).links) for i in free_cells: if not done.already_done(i): vmax = 0 vmin = 0 cells_around = pos.hex.get_by_id(i).links for nid in cells_around: if done.already_done(nid): if done[nid][0] != EMPTY: vmin += 1 vmax += 1 else: vmax += 1 for num in range(7): if (num < vmin) or (num > vmax): if done.remove(i, num): changed = True # Computes how many of each value is still free for cell in done.cells: if len(cell) == 1: left[cell[0]] -= 1 for v in range(8): # If there is none, remove the possibility from all tiles if (pos.tiles[v] > 0) and (left[v] == 0): if done.remove_unfixed(v): changed = True else: possible = sum([(1 if v in cell else 0) for cell in done.cells]) # If the number of possible cells for a value is exactly the number of available tiles # put a tile in each cell if pos.tiles[v] == possible: for i in range(done.count): cell = done.cells[i] if (not done.already_done(i)) and (v in cell): done.set_done(i, v) changed = True # Force empty or non-empty around filled cells filled_cells = (range(done.count) if last_move is None else [last_move]) for i in filled_cells: if done.already_done(i): num = done[i][0] empties = 0 filled = 0 unknown = [] cells_around = pos.hex.get_by_id(i).links for nid in cells_around: if done.already_done(nid): if done[nid][0] == EMPTY: empties += 1 else: filled += 1 else: unknown.append(nid) if len(unknown) > 0: if num == filled: for u in unknown: if EMPTY in done[u]: done.set_done(u, EMPTY) changed = True #else: # raise Exception("Houston, we've got a problem") elif num == filled + len(unknown): for u in unknown: if done.remove(u, EMPTY): changed = True return changed ASCENDING = 1 DESCENDING = -1 def find_moves(pos, strategy, order): done = pos.done cell_id = done.next_cell(pos, strategy) if cell_id < 0: return [] if order == ASCENDING: return [(cell_id, v) for v in done[cell_id]] else: # Try higher values first and EMPTY last moves = list(reversed([(cell_id, v) for v in done[cell_id] if v != EMPTY])) if EMPTY in done[cell_id]: moves.append((cell_id, EMPTY)) return moves def play_move(pos, move): (cell_id, i) = move pos.done.set_done(cell_id, i) @cython.locals(x=cython.int, y=cython.int, ry=cython.int, id=cython.int) def print_pos(pos, output): hex = pos.hex done = pos.done size = hex.size for y in range(size): print(u" " * (size - y - 1), end=u"", file=output) for x in range(size + y): pos2 = (x, y) id = hex.get_by_pos(pos2).id if done.already_done(id): c = str(done[id][0]) if done[id][0] != EMPTY else u"." else: c = u"?" print(u"%s " % c, end=u"", file=output) print(end=u"\n", file=output) for y in range(1, size): print(u" " * y, end=u"", file=output) for x in range(y, size * 2 - 1): ry = size + y - 1 pos2 = (x, ry) id = hex.get_by_pos(pos2).id if done.already_done(id): c = str(done[id][0]) if done[id][0] != EMPTY else (u".") else: c = u"?" print(u"%s " % c, end=u"", file=output) print(end=u"\n", file=output) OPEN = 0 SOLVED = 1 IMPOSSIBLE = -1 @cython.locals(i=cython.int, num=cython.int, nid=cython.int, vmin=cython.int, vmax=cython.int, tiles=cython.int[8]) def solved(pos, output, verbose=False): hex = pos.hex tiles = pos.tiles[:] done = pos.done exact = True all_done = True for i in range(hex.count): if len(done[i]) == 0: return IMPOSSIBLE elif done.already_done(i): num = done[i][0] tiles[num] -= 1 if (tiles[num] < 0): return IMPOSSIBLE vmax = 0 vmin = 0 if num != EMPTY: cells_around = hex.get_by_id(i).links for nid in cells_around: if done.already_done(nid): if done[nid][0] != EMPTY: vmin += 1 vmax += 1 else: vmax += 1 if (num < vmin) or (num > vmax): return IMPOSSIBLE if num != vmin: exact = False else: all_done = False if (not all_done) or (not exact): return OPEN print_pos(pos, output) return SOLVED @cython.locals(move=tuple) def solve_step(prev, strategy, order, output, first=False): if first: pos = prev.clone() while constraint_pass(pos): pass else: pos = prev moves = find_moves(pos, strategy, order) if len(moves) == 0: return solved(pos, output) else: for move in moves: #print("Trying (%d, %d)" % (move[0], move[1])) ret = OPEN new_pos = pos.clone() play_move(new_pos, move) #print_pos(new_pos) while constraint_pass(new_pos, move[0]): pass cur_status = solved(new_pos, output) if cur_status != OPEN: ret = cur_status else: ret = solve_step(new_pos, strategy, order, output) if ret == SOLVED: return SOLVED return IMPOSSIBLE @cython.locals(tot=cython.int, tiles=cython.int[8]) def check_valid(pos): hex = pos.hex tiles = pos.tiles done = pos.done # fill missing entries in tiles tot = 0 for i in range(8): if tiles[i] > 0: tot += tiles[i] else: tiles[i] = 0 # check total if tot != hex.count: raise Exception("Invalid input. Expected %d tiles, got %d." % (hex.count, tot)) def solve(pos, strategy, order, output): check_valid(pos) return solve_step(pos, strategy, order, output, first=True) # TODO Write an 'iterator' to go over all x,y positions @cython.locals(x=cython.int, y=cython.int, p=cython.int, tiles=cython.int[8], size=cython.int, inctile=cython.int, linei=cython.int) def read_file(file): lines = [line.strip("\r\n") for line in file.splitlines()] size = int(lines[0]) hex = Hex(size) linei = 1 tiles = 8 * [0] done = Done(hex.count) for y in range(size): line = lines[linei][size - y - 1:] p = 0 for x in range(size + y): tile = line[p:p + 2] p += 2 if tile[1] == ".": inctile = EMPTY else: inctile = int(tile) tiles[inctile] += 1 # Look for locked tiles if tile[0] == "+": print("Adding locked tile: %d at pos %d, %d, id=%d" % (inctile, x, y, hex.get_by_pos((x, y)).id)) done.set_done(hex.get_by_pos((x, y)).id, inctile) linei += 1 for y in range(1, size): ry = size - 1 + y line = lines[linei][y:] p = 0 for x in range(y, size * 2 - 1): tile = line[p:p + 2] p += 2 if tile[1] == ".": inctile = EMPTY else: inctile = int(tile) tiles[inctile] += 1 # Look for locked tiles if tile[0] == "+": print("Adding locked tile: %d at pos %d, %d, id=%d" % (inctile, x, ry, hex.get_by_pos((x, ry)).id)) done.set_done(hex.get_by_pos((x, ry)).id, inctile) linei += 1 hex.link_nodes() done.filter_tiles(tiles) return Pos(hex, tiles, done) def solve_file(file, strategy, order, output): pos = read_file(file) solve(pos, strategy, order, output) def run_level36(): f = """\ 4 2 1 1 2 3 3 3 . . 2 3 3 . 4 . . 2 . 2 4 3 2 2 2 . . . 2 4 3 4 . . 3 2 3 3 """ order = DESCENDING strategy = Done.FIRST_STRATEGY output = StringIO() solve_file(f, strategy, order, output) expected = """\ 3 4 3 2 3 4 4 . 3 2 . . 3 4 3 2 . 1 . 3 . 2 3 3 . 2 . 2 3 . 2 . 2 2 2 . 1 """ if output.getvalue() != expected: raise AssertionError("got a wrong answer:\n%s" % output.getvalue()) def main(n): # only run 1/25th of the requested number of iterations. # with the default n=50 from runner.py, this means twice. l = [] for i in range(n): t0 = time.time() run_level36() time_elapsed = time.time() - t0 l.append(time_elapsed) return l if __name__ == "__main__": import util, optparse parser = optparse.OptionParser( usage="%prog [options]", description="Test the performance of the hexiom2 benchmark") util.add_standard_options_to(parser) options, args = parser.parse_args() util.run_benchmark(options, options.num_runs, main) Cython-0.23.4/Demos/benchmarks/hexiom2.pxd0000644000175600017570000000353312606202452021464 0ustar jenkinsjenkins00000000000000cimport cython cdef object EMPTY cdef int IMPOSSIBLE, SOLVED, OPEN cdef int ASCENDING, DESCENDING cdef class Dir: cdef public int x, y @cython.final cdef class Done: cdef public int count cdef public list cells cdef Done clone(self) cdef inline int set_done(self, int i, v) except -123 cdef inline bint already_done(self, int i) except -123 cdef inline bint remove(self, int i, v) except -123 cdef inline bint remove_unfixed(self, v) except -123 cdef int next_cell(self, Pos pos, int strategy=*) except -123 cdef int filter_tiles(self, int* tiles) except -123 cdef int next_cell_min_choice(self) except -123 cdef int next_cell_max_choice(self) except -123 cdef int next_cell_highest_value(self) except -123 cdef int next_cell_first(self) except -123 cdef int next_cell_max_neighbors(self, Pos pos) except -123 cdef int next_cell_min_neighbors(self, Pos pos) except -123 @cython.final cdef class Node: cdef public tuple pos cdef public int id cdef public list links @cython.final cdef class Hex: cdef public list nodes_by_id cdef public dict nodes_by_pos cdef public int size cdef public int count cdef int link_nodes(self) except -123 cdef bint contains_pos(self, tuple pos) cdef Node get_by_pos(self, tuple pos) cdef Node get_by_id(self, int id) @cython.final cdef class Pos: cdef public Hex hex cdef public Done done cdef public int[8] tiles cdef Pos clone(self) cdef bint constraint_pass(Pos pos, last_move=*) except -123 cdef list find_moves(Pos pos, int strategy, int order) cdef inline int play_move(Pos pos, tuple move) except -123 cdef print_pos(Pos pos, output) cdef int solved(Pos pos, output, bint verbose=*) except -123 cdef int solve_step(Pos prev, int strategy, order, output, bint first=*) except -123 cdef check_valid(Pos pos) Cython-0.23.4/Demos/benchmarks/generators.py0000644000175600017570000000404112606202452022112 0ustar jenkinsjenkins00000000000000#!/usr/bin/python # micro benchmarks for generators COUNT = 10000 import cython @cython.locals(N=cython.Py_ssize_t) def count_to(N): for i in range(N): yield i @cython.locals(i=cython.Py_ssize_t) def round_robin(*_iterators): iterators = list(_iterators) to_drop = [] while iterators: for i, it in enumerate(iterators): try: value = next(it) except StopIteration: to_drop.append(i) else: yield value if to_drop: for i in reversed(to_drop): del iterators[i] del to_drop[:] def yield_from(*iterators): for it in iterators: yield from it def bm_plain(N): return count_to(COUNT * N) def bm_round_robin(N): return round_robin(*[ count_to(COUNT // i) for i in range(1,N+1) ]) def bm_yield_from(N): return yield_from(count_to(N), round_robin(*[ yield_from(count_to(COUNT // i)) for i in range(1,N+1) ]), count_to(N)) def bm_yield_from_nested(N): return yield_from(count_to(N), yield_from(count_to(N), round_robin(*[ yield_from(count_to(COUNT // i)) for i in range(1,N+1) ]), count_to(N)), count_to(N)) def time(fn, *args): from time import time begin = time() result = list(fn(*args)) end = time() return result, end-begin def benchmark(N): times = [] for _ in range(N): result, t = time(bm_yield_from_nested, 10) times.append(t) return times main = benchmark if __name__ == "__main__": import optparse parser = optparse.OptionParser( usage="%prog [options]", description=("Micro benchmarks for generators.")) import util util.add_standard_options_to(parser) options, args = parser.parse_args() util.run_benchmark(options, options.num_runs, benchmark) Cython-0.23.4/Demos/benchmarks/bpnn3.py0000644000175600017570000001237412606202452020771 0ustar jenkinsjenkins00000000000000#!/usr/bin/python # Back-Propagation Neural Networks # # Written in Python. See http://www.python.org/ # # Neil Schemenauer import math import random as random # Local imports import util random.seed(0) # calculate a random number where: a <= rand < b def rand(a, b, random=random.random): return (b-a)*random() + a # Make a matrix (we could use NumPy to speed this up) def makeMatrix(I, J, fill=0.0): m = [] for i in range(I): m.append([fill]*J) return m class NN(object): # print 'class NN' def __init__(self, ni, nh, no): # number of input, hidden, and output nodes self.ni = ni + 1 # +1 for bias node self.nh = nh self.no = no # activations for nodes self.ai = [1.0]*self.ni self.ah = [1.0]*self.nh self.ao = [1.0]*self.no # create weights self.wi = makeMatrix(self.ni, self.nh) self.wo = makeMatrix(self.nh, self.no) # set them to random vaules for i in range(self.ni): for j in range(self.nh): self.wi[i][j] = rand(-2.0, 2.0) for j in range(self.nh): for k in range(self.no): self.wo[j][k] = rand(-2.0, 2.0) # last change in weights for momentum self.ci = makeMatrix(self.ni, self.nh) self.co = makeMatrix(self.nh, self.no) def update(self, inputs): # print 'update', inputs if len(inputs) != self.ni-1: raise ValueError('wrong number of inputs') # input activations for i in range(self.ni-1): #self.ai[i] = 1.0/(1.0+math.exp(-inputs[i])) self.ai[i] = inputs[i] # hidden activations for j in range(self.nh): sum = 0.0 for i in range(self.ni): sum = sum + self.ai[i] * self.wi[i][j] self.ah[j] = 1.0/(1.0+math.exp(-sum)) # output activations for k in range(self.no): sum = 0.0 for j in range(self.nh): sum = sum + self.ah[j] * self.wo[j][k] self.ao[k] = 1.0/(1.0+math.exp(-sum)) return self.ao[:] def backPropagate(self, targets, N, M): # print N, M if len(targets) != self.no: raise ValueError('wrong number of target values') # calculate error terms for output output_deltas = [0.0] * self.no # print self.no for k in range(self.no): ao = self.ao[k] output_deltas[k] = ao*(1-ao)*(targets[k]-ao) # calculate error terms for hidden hidden_deltas = [0.0] * self.nh for j in range(self.nh): sum = 0.0 for k in range(self.no): sum = sum + output_deltas[k]*self.wo[j][k] hidden_deltas[j] = self.ah[j]*(1-self.ah[j])*sum # update output weights for j in range(self.nh): for k in range(self.no): change = output_deltas[k]*self.ah[j] self.wo[j][k] = self.wo[j][k] + N*change + M*self.co[j][k] self.co[j][k] = change # update input weights for i in range(self.ni): for j in range(self.nh): change = hidden_deltas[j]*self.ai[i] self.wi[i][j] = self.wi[i][j] + N*change + M*self.ci[i][j] self.ci[i][j] = change # calculate error error = 0.0 for k in range(len(targets)): error = error + 0.5*(targets[k]-self.ao[k])**2 return error def test(self, patterns): for p in patterns: print('%s -> %s' % (p[0], self.update(p[0]))) def weights(self): print('Input weights:') for i in range(self.ni): print(self.wi[i]) print('') print('Output weights:') for j in range(self.nh): print(self.wo[j]) def train(self, patterns, iterations=2000, N=0.5, M=0.1): # N: learning rate # M: momentum factor for i in range(iterations): error = 0.0 for p in patterns: inputs = p[0] targets = p[1] self.update(inputs) error = error + self.backPropagate(targets, N, M) #if i % 100 == 0: # print i, 'error %-14f' % error def demo(): # Teach network XOR function pat = [ [[0,0], [0]], [[0,1], [1]], [[1,0], [1]], [[1,1], [0]] ] # create a network with two input, two hidden, and two output nodes n = NN(2, 3, 1) # train it with some patterns n.train(pat, 5000) # test it #n.test(pat) def time(fn, *args): import time, traceback begin = time.time() result = fn(*args) end = time.time() return result, end-begin def test_bpnn(iterations): times = [] for _ in range(iterations): result, t = time(demo) times.append(t) return times main = test_bpnn if __name__ == "__main__": import optparse parser = optparse.OptionParser( usage="%prog [options]", description=("Test the performance of a neural network.")) util.add_standard_options_to(parser) options, args = parser.parse_args() util.run_benchmark(options, options.num_runs, test_bpnn) Cython-0.23.4/Demos/benchmarks/bpnn3.pxd0000644000175600017570000000117612606202452021132 0ustar jenkinsjenkins00000000000000cimport cython cdef double rand(double a, double b, random=*) @cython.locals(i=Py_ssize_t) cdef list makeMatrix(Py_ssize_t I, Py_ssize_t J, fill=*) cdef class NN: cdef Py_ssize_t ni, nh, no cdef list ai, ah, ao cdef list wi, wo cdef list ci, co @cython.locals(i=Py_ssize_t, j=Py_ssize_t, k=Py_ssize_t) cpdef update(self, list inputs) @cython.locals(i=Py_ssize_t, j=Py_ssize_t, k=Py_ssize_t, change=double) cpdef double backPropagate(self, list targets, double N, M) @cython.locals(i=Py_ssize_t, p=list, error=double) cpdef train(self, list patterns, Py_ssize_t iterations=*, double N=*, M=*) Cython-0.23.4/Cython/0000755000175600017570000000000012606202455015453 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/__init__.py0000644000175600017570000000052012606202452017556 0ustar jenkinsjenkins00000000000000from Cython.Shadow import __version__ # Void cython.* directives (for case insensitive operating systems). from Cython.Shadow import * def load_ipython_extension(ip): """Load the extension in IPython.""" from Cython.Build.IpythonMagic import CythonMagics # pylint: disable=cyclic-import ip.register_magics(CythonMagics) Cython-0.23.4/Cython/Utils.py0000644000175600017570000003170712606202452017132 0ustar jenkinsjenkins00000000000000# # Cython -- Things that don't belong # anywhere else in particular # from __future__ import absolute_import try: from __builtin__ import basestring except ImportError: basestring = str import os import sys import re import io import codecs from contextlib import contextmanager modification_time = os.path.getmtime def cached_function(f): cache = {} uncomputed = object() def wrapper(*args): res = cache.get(args, uncomputed) if res is uncomputed: res = cache[args] = f(*args) return res wrapper.uncached = f return wrapper def cached_method(f): cache_name = '__%s_cache' % f.__name__ def wrapper(self, *args): cache = getattr(self, cache_name, None) if cache is None: cache = {} setattr(self, cache_name, cache) if args in cache: return cache[args] res = cache[args] = f(self, *args) return res return wrapper def replace_suffix(path, newsuf): base, _ = os.path.splitext(path) return base + newsuf def open_new_file(path): if os.path.exists(path): # Make sure to create a new file here so we can # safely hard link the output files. os.unlink(path) # we use the ISO-8859-1 encoding here because we only write pure # ASCII strings or (e.g. for file names) byte encoded strings as # Unicode, so we need a direct mapping from the first 256 Unicode # characters to a byte sequence, which ISO-8859-1 provides # note: can't use io.open() in Py2 as we may be writing str objects return codecs.open(path, "w", encoding="ISO-8859-1") def castrate_file(path, st): # Remove junk contents from an output file after a # failed compilation. # Also sets access and modification times back to # those specified by st (a stat struct). try: f = open_new_file(path) except EnvironmentError: pass else: f.write( "#error Do not use this file, it is the result of a failed Cython compilation.\n") f.close() if st: os.utime(path, (st.st_atime, st.st_mtime-1)) def file_newer_than(path, time): ftime = modification_time(path) return ftime > time @cached_function def search_include_directories(dirs, qualified_name, suffix, pos, include=False, sys_path=False): # Search the list of include directories for the given # file name. If a source file position is given, first # searches the directory containing that file. Returns # None if not found, but does not report an error. # The 'include' option will disable package dereferencing. # If 'sys_path' is True, also search sys.path. if sys_path: dirs = dirs + tuple(sys.path) if pos: file_desc = pos[0] from Cython.Compiler.Scanning import FileSourceDescriptor if not isinstance(file_desc, FileSourceDescriptor): raise RuntimeError("Only file sources for code supported") if include: dirs = (os.path.dirname(file_desc.filename),) + dirs else: dirs = (find_root_package_dir(file_desc.filename),) + dirs dotted_filename = qualified_name if suffix: dotted_filename += suffix if not include: names = qualified_name.split('.') package_names = tuple(names[:-1]) module_name = names[-1] module_filename = module_name + suffix package_filename = "__init__" + suffix for dir in dirs: path = os.path.join(dir, dotted_filename) if path_exists(path): return path if not include: package_dir = check_package_dir(dir, package_names) if package_dir is not None: path = os.path.join(package_dir, module_filename) if path_exists(path): return path path = os.path.join(dir, package_dir, module_name, package_filename) if path_exists(path): return path return None @cached_function def find_root_package_dir(file_path): dir = os.path.dirname(file_path) if file_path == dir: return dir elif is_package_dir(dir): return find_root_package_dir(dir) else: return dir @cached_function def check_package_dir(dir, package_names): for dirname in package_names: dir = os.path.join(dir, dirname) if not is_package_dir(dir): return None return dir @cached_function def is_package_dir(dir_path): for filename in ("__init__.py", "__init__.pyc", "__init__.pyx", "__init__.pxd"): path = os.path.join(dir_path, filename) if path_exists(path): return 1 @cached_function def path_exists(path): # try on the filesystem first if os.path.exists(path): return True # figure out if a PEP 302 loader is around try: loader = __loader__ # XXX the code below assumes a 'zipimport.zipimporter' instance # XXX should be easy to generalize, but too lazy right now to write it archive_path = getattr(loader, 'archive', None) if archive_path: normpath = os.path.normpath(path) if normpath.startswith(archive_path): arcname = normpath[len(archive_path)+1:] try: loader.get_data(arcname) return True except IOError: return False except NameError: pass return False # file name encodings def decode_filename(filename): if isinstance(filename, bytes): try: filename_encoding = sys.getfilesystemencoding() if filename_encoding is None: filename_encoding = sys.getdefaultencoding() filename = filename.decode(filename_encoding) except UnicodeDecodeError: pass return filename # support for source file encoding detection _match_file_encoding = re.compile(u"coding[:=]\s*([-\w.]+)").search def detect_file_encoding(source_filename): f = open_source_file(source_filename, encoding="UTF-8", error_handling='ignore') try: return detect_opened_file_encoding(f) finally: f.close() def detect_opened_file_encoding(f): # PEPs 263 and 3120 # Most of the time the first two lines fall in the first 250 chars, # and this bulk read/split is much faster. lines = f.read(250).split(u"\n") if len(lines) > 1: m = _match_file_encoding(lines[0]) if m: return m.group(1) elif len(lines) > 2: m = _match_file_encoding(lines[1]) if m: return m.group(1) else: return "UTF-8" # Fallback to one-char-at-a-time detection. f.seek(0) chars = [] for i in range(2): c = f.read(1) while c and c != u'\n': chars.append(c) c = f.read(1) encoding = _match_file_encoding(u''.join(chars)) if encoding: return encoding.group(1) return "UTF-8" def skip_bom(f): """ Read past a BOM at the beginning of a source file. This could be added to the scanner, but it's *substantially* easier to keep it at this level. """ if f.read(1) != u'\uFEFF': f.seek(0) def open_source_file(source_filename, mode="r", encoding=None, error_handling=None): if encoding is None: # Most of the time the coding is unspecified, so be optimistic that # it's UTF-8. f = open_source_file(source_filename, encoding="UTF-8", mode=mode, error_handling='ignore') encoding = detect_opened_file_encoding(f) if encoding == "UTF-8" and error_handling == 'ignore': f.seek(0) skip_bom(f) return f else: f.close() if not os.path.exists(source_filename): try: loader = __loader__ if source_filename.startswith(loader.archive): return open_source_from_loader( loader, source_filename, encoding, error_handling) except (NameError, AttributeError): pass stream = io.open(source_filename, mode=mode, encoding=encoding, errors=error_handling) skip_bom(stream) return stream def open_source_from_loader(loader, source_filename, encoding=None, error_handling=None): nrmpath = os.path.normpath(source_filename) arcname = nrmpath[len(loader.archive)+1:] data = loader.get_data(arcname) return io.TextIOWrapper(io.BytesIO(data), encoding=encoding, errors=error_handling) def str_to_number(value): # note: this expects a string as input that was accepted by the # parser already, with an optional "-" sign in front is_neg = False if value[:1] == '-': is_neg = True value = value[1:] if len(value) < 2: value = int(value, 0) elif value[0] == '0': literal_type = value[1] # 0'o' - 0'b' - 0'x' if literal_type in 'xX': # hex notation ('0x1AF') value = int(value[2:], 16) elif literal_type in 'oO': # Py3 octal notation ('0o136') value = int(value[2:], 8) elif literal_type in 'bB': # Py3 binary notation ('0b101') value = int(value[2:], 2) else: # Py2 octal notation ('0136') value = int(value, 8) else: value = int(value, 0) return -value if is_neg else value def long_literal(value): if isinstance(value, basestring): value = str_to_number(value) return not -2**31 <= value < 2**31 @cached_function def get_cython_cache_dir(): """get the cython cache dir Priority: 1. CYTHON_CACHE_DIR 2. (OS X): ~/Library/Caches/Cython (posix not OS X): XDG_CACHE_HOME/cython if XDG_CACHE_HOME defined 3. ~/.cython """ if 'CYTHON_CACHE_DIR' in os.environ: return os.environ['CYTHON_CACHE_DIR'] parent = None if os.name == 'posix': if sys.platform == 'darwin': parent = os.path.expanduser('~/Library/Caches') else: # this could fallback on ~/.cache parent = os.environ.get('XDG_CACHE_HOME') if parent and os.path.isdir(parent): return os.path.join(parent, 'cython') # last fallback: ~/.cython return os.path.expanduser(os.path.join('~', '.cython')) @contextmanager def captured_fd(stream=2, encoding=None): pipe_in = t = None orig_stream = os.dup(stream) # keep copy of original stream try: pipe_in, pipe_out = os.pipe() os.dup2(pipe_out, stream) # replace stream by copy of pipe try: os.close(pipe_out) # close original pipe-out stream data = [] def copy(): try: while True: d = os.read(pipe_in, 1000) if d: data.append(d) else: break finally: os.close(pipe_in) def get_output(): output = b''.join(data) if encoding: output = output.decode(encoding) return output from threading import Thread t = Thread(target=copy) t.daemon = True # just in case t.start() yield get_output finally: os.dup2(orig_stream, stream) # restore original stream if t is not None: t.join() finally: os.close(orig_stream) def print_bytes(s, end=b'\n', file=sys.stdout, flush=True): file.flush() try: out = file.buffer # Py3 except AttributeError: out = file # Py2 out.write(s) if end: out.write(end) if flush: out.flush() class LazyStr: def __init__(self, callback): self.callback = callback def __str__(self): return self.callback() def __repr__(self): return self.callback() def __add__(self, right): return self.callback() + right def __radd__(self, left): return left + self.callback() # Class decorator that adds a metaclass and recreates the class with it. # Copied from 'six'. def add_metaclass(metaclass): """Class decorator for creating a class with a metaclass.""" def wrapper(cls): orig_vars = cls.__dict__.copy() slots = orig_vars.get('__slots__') if slots is not None: if isinstance(slots, str): slots = [slots] for slots_var in slots: orig_vars.pop(slots_var) orig_vars.pop('__dict__', None) orig_vars.pop('__weakref__', None) return metaclass(cls.__name__, cls.__bases__, orig_vars) return wrapper Cython-0.23.4/Cython/TestUtils.py0000644000175600017570000001702212606202452017764 0ustar jenkinsjenkins00000000000000import Cython.Compiler.Errors as Errors from Cython.CodeWriter import CodeWriter from Cython.Compiler.TreeFragment import TreeFragment, strip_common_indent from Cython.Compiler.Visitor import TreeVisitor, VisitorTransform from Cython.Compiler import TreePath import unittest import os, sys import tempfile class NodeTypeWriter(TreeVisitor): def __init__(self): super(NodeTypeWriter, self).__init__() self._indents = 0 self.result = [] def visit_Node(self, node): if not self.access_path: name = u"(root)" else: tip = self.access_path[-1] if tip[2] is not None: name = u"%s[%d]" % tip[1:3] else: name = tip[1] self.result.append(u" " * self._indents + u"%s: %s" % (name, node.__class__.__name__)) self._indents += 1 self.visitchildren(node) self._indents -= 1 def treetypes(root): """Returns a string representing the tree by class names. There's a leading and trailing whitespace so that it can be compared by simple string comparison while still making test cases look ok.""" w = NodeTypeWriter() w.visit(root) return u"\n".join([u""] + w.result + [u""]) class CythonTest(unittest.TestCase): def setUp(self): self.listing_file = Errors.listing_file self.echo_file = Errors.echo_file Errors.listing_file = Errors.echo_file = None def tearDown(self): Errors.listing_file = self.listing_file Errors.echo_file = self.echo_file def assertLines(self, expected, result): "Checks that the given strings or lists of strings are equal line by line" if not isinstance(expected, list): expected = expected.split(u"\n") if not isinstance(result, list): result = result.split(u"\n") for idx, (expected_line, result_line) in enumerate(zip(expected, result)): self.assertEqual(expected_line, result_line, "Line %d:\nExp: %s\nGot: %s" % (idx, expected_line, result_line)) self.assertEqual(len(expected), len(result), "Unmatched lines. Got:\n%s\nExpected:\n%s" % ("\n".join(expected), u"\n".join(result))) def codeToLines(self, tree): writer = CodeWriter() writer.write(tree) return writer.result.lines def codeToString(self, tree): return "\n".join(self.codeToLines(tree)) def assertCode(self, expected, result_tree): result_lines = self.codeToLines(result_tree) expected_lines = strip_common_indent(expected.split("\n")) for idx, (line, expected_line) in enumerate(zip(result_lines, expected_lines)): self.assertEqual(expected_line, line, "Line %d:\nGot: %s\nExp: %s" % (idx, line, expected_line)) self.assertEqual(len(result_lines), len(expected_lines), "Unmatched lines. Got:\n%s\nExpected:\n%s" % ("\n".join(result_lines), expected)) def assertNodeExists(self, path, result_tree): self.assertNotEqual(TreePath.find_first(result_tree, path), None, "Path '%s' not found in result tree" % path) def fragment(self, code, pxds={}, pipeline=[]): "Simply create a tree fragment using the name of the test-case in parse errors." name = self.id() if name.startswith("__main__."): name = name[len("__main__."):] name = name.replace(".", "_") return TreeFragment(code, name, pxds, pipeline=pipeline) def treetypes(self, root): return treetypes(root) def should_fail(self, func, exc_type=Exception): """Calls "func" and fails if it doesn't raise the right exception (any exception by default). Also returns the exception in question. """ try: func() self.fail("Expected an exception of type %r" % exc_type) except exc_type as e: self.assert_(isinstance(e, exc_type)) return e def should_not_fail(self, func): """Calls func and succeeds if and only if no exception is raised (i.e. converts exception raising into a failed testcase). Returns the return value of func.""" try: return func() except: self.fail(str(sys.exc_info()[1])) class TransformTest(CythonTest): """ Utility base class for transform unit tests. It is based around constructing test trees (either explicitly or by parsing a Cython code string); running the transform, serialize it using a customized Cython serializer (with special markup for nodes that cannot be represented in Cython), and do a string-comparison line-by-line of the result. To create a test case: - Call run_pipeline. The pipeline should at least contain the transform you are testing; pyx should be either a string (passed to the parser to create a post-parse tree) or a node representing input to pipeline. The result will be a transformed result. - Check that the tree is correct. If wanted, assertCode can be used, which takes a code string as expected, and a ModuleNode in result_tree (it serializes the ModuleNode to a string and compares line-by-line). All code strings are first stripped for whitespace lines and then common indentation. Plans: One could have a pxd dictionary parameter to run_pipeline. """ def run_pipeline(self, pipeline, pyx, pxds={}): tree = self.fragment(pyx, pxds).root # Run pipeline for T in pipeline: tree = T(tree) return tree class TreeAssertVisitor(VisitorTransform): # actually, a TreeVisitor would be enough, but this needs to run # as part of the compiler pipeline def visit_CompilerDirectivesNode(self, node): directives = node.directives if 'test_assert_path_exists' in directives: for path in directives['test_assert_path_exists']: if TreePath.find_first(node, path) is None: Errors.error( node.pos, "Expected path '%s' not found in result tree" % path) if 'test_fail_if_path_exists' in directives: for path in directives['test_fail_if_path_exists']: if TreePath.find_first(node, path) is not None: Errors.error( node.pos, "Unexpected path '%s' found in result tree" % path) self.visitchildren(node) return node visit_Node = VisitorTransform.recurse_to_children def unpack_source_tree(tree_file, dir=None): if dir is None: dir = tempfile.mkdtemp() header = [] cur_file = None f = open(tree_file) try: lines = f.readlines() finally: f.close() del f try: for line in lines: if line[:5] == '#####': filename = line.strip().strip('#').strip().replace('/', os.path.sep) path = os.path.join(dir, filename) if not os.path.exists(os.path.dirname(path)): os.makedirs(os.path.dirname(path)) if cur_file is not None: f, cur_file = cur_file, None f.close() cur_file = open(path, 'w') elif cur_file is not None: cur_file.write(line) elif line.strip() and not line.lstrip().startswith('#'): if line.strip() not in ('"""', "'''"): header.append(line) finally: if cur_file is not None: cur_file.close() return dir, ''.join(header) Cython-0.23.4/Cython/StringIOTree.py0000644000175600017570000000621712606202452020346 0ustar jenkinsjenkins00000000000000try: from cStringIO import StringIO except ImportError: from io import StringIO # does not support writing 'str' in Py2 class StringIOTree(object): """ See module docs. """ def __init__(self, stream=None): self.prepended_children = [] if stream is None: stream = StringIO() self.stream = stream self.write = stream.write self.markers = [] def getvalue(self): content = [x.getvalue() for x in self.prepended_children] content.append(self.stream.getvalue()) return "".join(content) def copyto(self, target): """Potentially cheaper than getvalue as no string concatenation needs to happen.""" for child in self.prepended_children: child.copyto(target) stream_content = self.stream.getvalue() if stream_content: target.write(stream_content) def commit(self): # Save what we have written until now so that the buffer # itself is empty -- this makes it ready for insertion if self.stream.tell(): self.prepended_children.append(StringIOTree(self.stream)) self.prepended_children[-1].markers = self.markers self.markers = [] self.stream = StringIO() self.write = self.stream.write def insert(self, iotree): """ Insert a StringIOTree (and all of its contents) at this location. Further writing to self appears after what is inserted. """ self.commit() self.prepended_children.append(iotree) def insertion_point(self): """ Returns a new StringIOTree, which is left behind at the current position (it what is written to the result will appear right before whatever is next written to self). Calling getvalue() or copyto() on the result will only return the contents written to it. """ # Save what we have written until now # This is so that getvalue on the result doesn't include it. self.commit() # Construct the new forked object to return other = StringIOTree() self.prepended_children.append(other) return other def allmarkers(self): children = self.prepended_children return [m for c in children for m in c.allmarkers()] + self.markers __doc__ = r""" Implements a buffer with insertion points. When you know you need to "get back" to a place and write more later, simply call insertion_point() at that spot and get a new StringIOTree object that is "left behind". EXAMPLE: >>> a = StringIOTree() >>> _= a.write('first\n') >>> b = a.insertion_point() >>> _= a.write('third\n') >>> _= b.write('second\n') >>> a.getvalue().split() ['first', 'second', 'third'] >>> c = b.insertion_point() >>> d = c.insertion_point() >>> _= d.write('alpha\n') >>> _= b.write('gamma\n') >>> _= c.write('beta\n') >>> b.getvalue().split() ['second', 'alpha', 'beta', 'gamma'] >>> i = StringIOTree() >>> d.insert(i) >>> _= i.write('inserted\n') >>> out = StringIO() >>> a.copyto(out) >>> out.getvalue().split() ['first', 'second', 'alpha', 'inserted', 'beta', 'gamma', 'third'] """ Cython-0.23.4/Cython/Shadow.py0000644000175600017570000002704112606202452017253 0ustar jenkinsjenkins00000000000000# cython.* namespace for pure mode. from __future__ import absolute_import __version__ = "0.23.4" try: from __builtin__ import basestring except ImportError: basestring = str # BEGIN shameless copy from Cython/minivect/minitypes.py class _ArrayType(object): is_array = True subtypes = ['dtype'] def __init__(self, dtype, ndim, is_c_contig=False, is_f_contig=False, inner_contig=False, broadcasting=None): self.dtype = dtype self.ndim = ndim self.is_c_contig = is_c_contig self.is_f_contig = is_f_contig self.inner_contig = inner_contig or is_c_contig or is_f_contig self.broadcasting = broadcasting def __repr__(self): axes = [":"] * self.ndim if self.is_c_contig: axes[-1] = "::1" elif self.is_f_contig: axes[0] = "::1" return "%s[%s]" % (self.dtype, ", ".join(axes)) def index_type(base_type, item): """ Support array type creation by slicing, e.g. double[:, :] specifies a 2D strided array of doubles. The syntax is the same as for Cython memoryviews. """ class InvalidTypeSpecification(Exception): pass def verify_slice(s): if s.start or s.stop or s.step not in (None, 1): raise InvalidTypeSpecification( "Only a step of 1 may be provided to indicate C or " "Fortran contiguity") if isinstance(item, tuple): step_idx = None for idx, s in enumerate(item): verify_slice(s) if s.step and (step_idx or idx not in (0, len(item) - 1)): raise InvalidTypeSpecification( "Step may only be provided once, and only in the " "first or last dimension.") if s.step == 1: step_idx = idx return _ArrayType(base_type, len(item), is_c_contig=step_idx == len(item) - 1, is_f_contig=step_idx == 0) elif isinstance(item, slice): verify_slice(item) return _ArrayType(base_type, 1, is_c_contig=bool(item.step)) else: # int[8] etc. assert int(item) == item # array size must be a plain integer array(base_type, item) # END shameless copy compiled = False _Unspecified = object() # Function decorators def _empty_decorator(x): return x def locals(**arg_types): return _empty_decorator def test_assert_path_exists(*paths): return _empty_decorator def test_fail_if_path_exists(*paths): return _empty_decorator class _EmptyDecoratorAndManager(object): def __call__(self, x): return x def __enter__(self): pass def __exit__(self, exc_type, exc_value, traceback): pass cclass = ccall = cfunc = _EmptyDecoratorAndManager() returns = wraparound = boundscheck = profile = freelist = lambda arg: _EmptyDecoratorAndManager() final = internal = type_version_tag = no_gc_clear = _empty_decorator def inline(f, *args, **kwds): if isinstance(f, basestring): from Cython.Build.Inline import cython_inline return cython_inline(f, *args, **kwds) else: assert len(args) == len(kwds) == 0 return f def compile(f): from Cython.Build.Inline import RuntimeCompiledFunction return RuntimeCompiledFunction(f) # Special functions def cdiv(a, b): q = a / b if q < 0: q += 1 def cmod(a, b): r = a % b if (a*b) < 0: r -= b return r # Emulated language constructs def cast(type, *args): if hasattr(type, '__call__'): return type(*args) else: return args[0] def sizeof(arg): return 1 def typeof(arg): return arg.__class__.__name__ # return type(arg) def address(arg): return pointer(type(arg))([arg]) def declare(type=None, value=_Unspecified, **kwds): if type not in (None, object) and hasattr(type, '__call__'): if value is not _Unspecified: return type(value) else: return type() else: return value class _nogil(object): """Support for 'with nogil' statement """ def __enter__(self): pass def __exit__(self, exc_class, exc, tb): return exc_class is None nogil = _nogil() gil = _nogil() del _nogil # Emulated types class CythonMetaType(type): def __getitem__(type, ix): return array(type, ix) CythonTypeObject = CythonMetaType('CythonTypeObject', (object,), {}) class CythonType(CythonTypeObject): def _pointer(self, n=1): for i in range(n): self = pointer(self) return self class PointerType(CythonType): def __init__(self, value=None): if isinstance(value, (ArrayType, PointerType)): self._items = [cast(self._basetype, a) for a in value._items] elif isinstance(value, list): self._items = [cast(self._basetype, a) for a in value] elif value is None or value == 0: self._items = [] else: raise ValueError def __getitem__(self, ix): if ix < 0: raise IndexError("negative indexing not allowed in C") return self._items[ix] def __setitem__(self, ix, value): if ix < 0: raise IndexError("negative indexing not allowed in C") self._items[ix] = cast(self._basetype, value) def __eq__(self, value): if value is None and not self._items: return True elif type(self) != type(value): return False else: return not self._items and not value._items def __repr__(self): return "%s *" % (self._basetype,) class ArrayType(PointerType): def __init__(self): self._items = [None] * self._n class StructType(CythonType): def __init__(self, cast_from=_Unspecified, **data): if cast_from is not _Unspecified: # do cast if len(data) > 0: raise ValueError('Cannot accept keyword arguments when casting.') if type(cast_from) is not type(self): raise ValueError('Cannot cast from %s'%cast_from) for key, value in cast_from.__dict__.items(): setattr(self, key, value) else: for key, value in data.items(): setattr(self, key, value) def __setattr__(self, key, value): if key in self._members: self.__dict__[key] = cast(self._members[key], value) else: raise AttributeError("Struct has no member '%s'" % key) class UnionType(CythonType): def __init__(self, cast_from=_Unspecified, **data): if cast_from is not _Unspecified: # do type cast if len(data) > 0: raise ValueError('Cannot accept keyword arguments when casting.') if isinstance(cast_from, dict): datadict = cast_from elif type(cast_from) is type(self): datadict = cast_from.__dict__ else: raise ValueError('Cannot cast from %s'%cast_from) else: datadict = data if len(datadict) > 1: raise AttributeError("Union can only store one field at a time.") for key, value in datadict.items(): setattr(self, key, value) def __setattr__(self, key, value): if key in '__dict__': CythonType.__setattr__(self, key, value) elif key in self._members: self.__dict__ = {key: cast(self._members[key], value)} else: raise AttributeError("Union has no member '%s'" % key) def pointer(basetype): class PointerInstance(PointerType): _basetype = basetype return PointerInstance def array(basetype, n): class ArrayInstance(ArrayType): _basetype = basetype _n = n return ArrayInstance def struct(**members): class StructInstance(StructType): _members = members for key in members: setattr(StructInstance, key, None) return StructInstance def union(**members): class UnionInstance(UnionType): _members = members for key in members: setattr(UnionInstance, key, None) return UnionInstance class typedef(CythonType): def __init__(self, type, name=None): self._basetype = type self.name = name def __call__(self, *arg): value = cast(self._basetype, *arg) return value def __repr__(self): return self.name or str(self._basetype) __getitem__ = index_type class _FusedType(CythonType): pass def fused_type(*args): if not args: raise TypeError("Expected at least one type as argument") # Find the numeric type with biggest rank if all types are numeric rank = -1 for type in args: if type not in (py_int, py_long, py_float, py_complex): break if type_ordering.index(type) > rank: result_type = type else: return result_type # Not a simple numeric type, return a fused type instance. The result # isn't really meant to be used, as we can't keep track of the context in # pure-mode. Casting won't do anything in this case. return _FusedType() def _specialized_from_args(signatures, args, kwargs): "Perhaps this should be implemented in a TreeFragment in Cython code" raise Exception("yet to be implemented") py_int = typedef(int, "int") try: py_long = typedef(long, "long") except NameError: # Py3 py_long = typedef(int, "long") py_float = typedef(float, "float") py_complex = typedef(complex, "double complex") # Predefined types int_types = ['char', 'short', 'Py_UNICODE', 'int', 'Py_UCS4', 'long', 'longlong', 'Py_ssize_t', 'size_t'] float_types = ['longdouble', 'double', 'float'] complex_types = ['longdoublecomplex', 'doublecomplex', 'floatcomplex', 'complex'] other_types = ['bint', 'void'] to_repr = { 'longlong': 'long long', 'longdouble': 'long double', 'longdoublecomplex': 'long double complex', 'doublecomplex': 'double complex', 'floatcomplex': 'float complex', }.get gs = globals() # note: cannot simply name the unicode type here as 2to3 gets in the way and replaces it by str try: import __builtin__ as builtins except ImportError: # Py3 import builtins gs['unicode'] = typedef(getattr(builtins, 'unicode', str), 'unicode') del builtins for name in int_types: reprname = to_repr(name, name) gs[name] = typedef(py_int, reprname) if name not in ('Py_UNICODE', 'Py_UCS4') and not name.endswith('size_t'): gs['u'+name] = typedef(py_int, "unsigned " + reprname) gs['s'+name] = typedef(py_int, "signed " + reprname) for name in float_types: gs[name] = typedef(py_float, to_repr(name, name)) for name in complex_types: gs[name] = typedef(py_complex, to_repr(name, name)) bint = typedef(bool, "bint") void = typedef(int, "void") for t in int_types + float_types + complex_types + other_types: for i in range(1, 4): gs["%s_%s" % ('p'*i, t)] = globals()[t]._pointer(i) void = typedef(None, "void") NULL = p_void(0) integral = floating = numeric = _FusedType() type_ordering = [py_int, py_long, py_float, py_complex] class CythonDotParallel(object): """ The cython.parallel module. """ __all__ = ['parallel', 'prange', 'threadid'] def parallel(self, num_threads=None): return nogil def prange(self, start=0, stop=None, step=1, schedule=None, nogil=False): if stop is None: stop = start start = 0 return range(start, stop, step) def threadid(self): return 0 # def threadsavailable(self): # return 1 import sys sys.modules['cython.parallel'] = CythonDotParallel() del sys Cython-0.23.4/Cython/Debugging.py0000644000175600017570000000105012606202452017711 0ustar jenkinsjenkins00000000000000############################################### # # Odds and ends for debugging # ############################################### def print_call_chain(*args): import sys print(" ".join(map(str, args))) f = sys._getframe(1) while f: name = f.f_code.co_name s = f.f_locals.get('self', None) if s: c = getattr(s, "__class__", None) if c: name = "%s.%s" % (c.__name__, name) print("Called from: %s %s" % (name, f.f_lineno)) f = f.f_back print("-" * 70) Cython-0.23.4/Cython/Coverage.py0000644000175600017570000002641512606202452017565 0ustar jenkinsjenkins00000000000000""" A Cython plugin for coverage.py Requires the coverage package at least in version 4.0 (which added the plugin API). """ from __future__ import absolute_import import re import os.path from collections import defaultdict from coverage.plugin import CoveragePlugin, FileTracer, FileReporter # requires coverage.py 4.0+ from .Utils import find_root_package_dir, is_package_dir, open_source_file from . import __version__ def _find_c_source(base_path): if os.path.exists(base_path + '.c'): c_file = base_path + '.c' elif os.path.exists(base_path + '.cpp'): c_file = base_path + '.cpp' else: c_file = None return c_file def _find_dep_file_path(main_file, file_path): abs_path = os.path.abspath(file_path) if file_path.endswith('.pxi') and not os.path.exists(abs_path): # include files are looked up relative to the main source file pxi_file_path = os.path.join(os.path.dirname(main_file), file_path) if os.path.exists(pxi_file_path): abs_path = os.path.abspath(pxi_file_path) return abs_path class Plugin(CoveragePlugin): # map from traced file paths to absolute file paths _file_path_map = None # map from traced file paths to corresponding C files _c_files_map = None # map from parsed C files to their content _parsed_c_files = None def sys_info(self): return [('Cython version', __version__)] def file_tracer(self, filename): """ Try to find a C source file for a file path found by the tracer. """ if filename.startswith('<') or filename.startswith('memory:'): return None c_file = py_file = None filename = os.path.abspath(filename) if self._c_files_map and filename in self._c_files_map: c_file = self._c_files_map[filename][0] if c_file is None: c_file, py_file = self._find_source_files(filename) if not c_file: return None # parse all source file paths and lines from C file # to learn about all relevant source files right away (pyx/pxi/pxd) # FIXME: this might already be too late if the first executed line # is not from the main .pyx file but a file with a different # name than the .c file (which prevents us from finding the # .c file) self._parse_lines(c_file, filename) if self._file_path_map is None: self._file_path_map = {} return CythonModuleTracer(filename, py_file, c_file, self._c_files_map, self._file_path_map) def file_reporter(self, filename): # TODO: let coverage.py handle .py files itself #ext = os.path.splitext(filename)[1].lower() #if ext == '.py': # from coverage.python import PythonFileReporter # return PythonFileReporter(filename) filename = os.path.abspath(filename) if self._c_files_map and filename in self._c_files_map: c_file, rel_file_path, code = self._c_files_map[filename] else: c_file, _ = self._find_source_files(filename) if not c_file: return None # unknown file rel_file_path, code = self._parse_lines(c_file, filename) return CythonModuleReporter(c_file, filename, rel_file_path, code) def _find_source_files(self, filename): basename, ext = os.path.splitext(filename) ext = ext.lower() if ext in ('.py', '.pyx', '.pxd', '.c', '.cpp'): pass elif ext in ('.so', '.pyd'): platform_suffix = re.search(r'[.]cpython-[0-9]+[a-z]*$', basename, re.I) if platform_suffix: basename = basename[:platform_suffix.start()] elif ext == '.pxi': # if we get here, it means that the first traced line of a Cython module was # not in the main module but in an include file, so try a little harder to # find the main source file self._find_c_source_files(os.path.dirname(filename), filename) if filename in self._c_files_map: return self._c_files_map[filename][0], None else: # none of our business return None, None c_file = filename if ext in ('.c', '.cpp') else _find_c_source(basename) if c_file is None: # a module "pkg/mod.so" can have a source file "pkg/pkg.mod.c" package_root = find_root_package_dir.uncached(filename) package_path = os.path.relpath(basename, package_root).split(os.path.sep) if len(package_path) > 1: test_basepath = os.path.join(os.path.dirname(filename), '.'.join(package_path)) c_file = _find_c_source(test_basepath) py_source_file = None if c_file: py_source_file = os.path.splitext(c_file)[0] + '.py' if not os.path.exists(py_source_file): py_source_file = None try: with open(c_file, 'rb') as f: if b'/* Generated by Cython ' not in f.read(30): return None # not a Cython file except (IOError, OSError): c_file = None return c_file, py_source_file def _find_c_source_files(self, dir_path, source_file): """ Desperately parse all C files in the directory or its package parents (not re-descending) to find the (included) source file in one of them. """ if not os.path.isdir(dir_path): return splitext = os.path.splitext for filename in os.listdir(dir_path): ext = splitext(filename)[1].lower() if ext in ('.c', '.cpp'): self._parse_lines(os.path.join(dir_path, filename), source_file) if source_file in self._c_files_map: return # not found? then try one package up if is_package_dir(dir_path): self._find_c_source_files(os.path.dirname(dir_path), source_file) def _parse_lines(self, c_file, sourcefile): """ Parse a Cython generated C/C++ source file and find the executable lines. Each executable line starts with a comment header that states source file and line number, as well as the surrounding range of source code lines. """ if self._parsed_c_files is None: self._parsed_c_files = {} if c_file in self._parsed_c_files: code_lines = self._parsed_c_files[c_file] else: match_source_path_line = re.compile(r' */[*] +"(.*)":([0-9]+)$').match match_current_code_line = re.compile(r' *[*] (.*) # <<<<<<+$').match match_comment_end = re.compile(r' *[*]/$').match not_executable = re.compile( r'\s*c(?:type)?def\s+' r'(?:(?:public|external)\s+)?' r'(?:struct|union|enum|class)' r'(\s+[^:]+|)\s*:' ).match code_lines = defaultdict(dict) filenames = set() with open(c_file) as lines: lines = iter(lines) for line in lines: match = match_source_path_line(line) if not match: continue filename, lineno = match.groups() filenames.add(filename) lineno = int(lineno) for comment_line in lines: match = match_current_code_line(comment_line) if match: code_line = match.group(1).rstrip() if not_executable(code_line): break code_lines[filename][lineno] = code_line break elif match_comment_end(comment_line): # unexpected comment format - false positive? break self._parsed_c_files[c_file] = code_lines if self._c_files_map is None: self._c_files_map = {} for filename, code in code_lines.items(): abs_path = _find_dep_file_path(c_file, filename) self._c_files_map[abs_path] = (c_file, filename, code) if sourcefile not in self._c_files_map: return (None,) * 2 # e.g. shared library file return self._c_files_map[sourcefile][1:] class CythonModuleTracer(FileTracer): """ Find the Python/Cython source file for a Cython module. """ def __init__(self, module_file, py_file, c_file, c_files_map, file_path_map): super(CythonModuleTracer, self).__init__() self.module_file = module_file self.py_file = py_file self.c_file = c_file self._c_files_map = c_files_map self._file_path_map = file_path_map def has_dynamic_source_filename(self): return True def dynamic_source_filename(self, filename, frame): """ Determine source file path. Called by the function call tracer. """ source_file = frame.f_code.co_filename try: return self._file_path_map[source_file] except KeyError: pass abs_path = os.path.abspath(source_file) if self.py_file and source_file[-3:].lower() == '.py': # always let coverage.py handle this case itself self._file_path_map[source_file] = self.py_file return self.py_file assert self._c_files_map is not None if abs_path not in self._c_files_map: self._c_files_map[abs_path] = (self.c_file, source_file, None) self._file_path_map[source_file] = abs_path return abs_path class CythonModuleReporter(FileReporter): """ Provide detailed trace information for one source file to coverage.py. """ def __init__(self, c_file, source_file, rel_file_path, code): super(CythonModuleReporter, self).__init__(source_file) self.name = rel_file_path self.c_file = c_file self._code = code def lines(self): """ Return set of line numbers that are possibly executable. """ return set(self._code) def _iter_source_tokens(self): current_line = 1 for line_no, code_line in sorted(self._code.items()): while line_no > current_line: yield [] current_line += 1 yield [('txt', code_line)] current_line += 1 def source(self): """ Return the source code of the file as a string. """ if os.path.exists(self.filename): with open_source_file(self.filename) as f: return f.read() else: return '\n'.join( (tokens[0][1] if tokens else '') for tokens in self._iter_source_tokens()) def source_token_lines(self): """ Iterate over the source code tokens. """ if os.path.exists(self.filename): with open_source_file(self.filename) as f: for line in f: yield [('txt', line.rstrip('\n'))] else: for line in self._iter_source_tokens(): yield [('txt', line)] def coverage_init(reg, options): reg.add_file_tracer(Plugin()) Cython-0.23.4/Cython/CodeWriter.py0000644000175600017570000003563412606202452020104 0ustar jenkinsjenkins00000000000000""" Serializes a Cython code tree to Cython code. This is primarily useful for debugging and testing purposes. The output is in a strict format, no whitespace or comments from the input is preserved (and it could not be as it is not present in the code tree). """ from __future__ import absolute_import, print_function from .Compiler.Visitor import TreeVisitor from .Compiler.ExprNodes import * class LinesResult(object): def __init__(self): self.lines = [] self.s = u"" def put(self, s): self.s += s def newline(self): self.lines.append(self.s) self.s = u"" def putline(self, s): self.put(s) self.newline() class DeclarationWriter(TreeVisitor): indent_string = u" " def __init__(self, result = None): super(DeclarationWriter, self).__init__() if result is None: result = LinesResult() self.result = result self.numindents = 0 self.tempnames = {} self.tempblockindex = 0 def write(self, tree): self.visit(tree) return self.result def indent(self): self.numindents += 1 def dedent(self): self.numindents -= 1 def startline(self, s = u""): self.result.put(self.indent_string * self.numindents + s) def put(self, s): self.result.put(s) def putline(self, s): self.result.putline(self.indent_string * self.numindents + s) def endline(self, s = u""): self.result.putline(s) def line(self, s): self.startline(s) self.endline() def comma_separated_list(self, items, output_rhs=False): if len(items) > 0: for item in items[:-1]: self.visit(item) if output_rhs and item.default is not None: self.put(u" = ") self.visit(item.default) self.put(u", ") self.visit(items[-1]) def visit_Node(self, node): raise AssertionError("Node not handled by serializer: %r" % node) def visit_ModuleNode(self, node): self.visitchildren(node) def visit_StatListNode(self, node): self.visitchildren(node) def visit_CDefExternNode(self, node): if node.include_file is None: file = u'*' else: file = u'"%s"' % node.include_file self.putline(u"cdef extern from %s:" % file) self.indent() self.visit(node.body) self.dedent() def visit_CPtrDeclaratorNode(self, node): self.put('*') self.visit(node.base) def visit_CReferenceDeclaratorNode(self, node): self.put('&') self.visit(node.base) def visit_CArrayDeclaratorNode(self, node): self.visit(node.base) self.put(u'[') if node.dimension is not None: self.visit(node.dimension) self.put(u']') def visit_CArrayDeclaratorNode(self, node): self.visit(node.base) self.put(u'[') if node.dimension is not None: self.visit(node.dimension) self.put(u']') def visit_CFuncDeclaratorNode(self, node): # TODO: except, gil, etc. self.visit(node.base) self.put(u'(') self.comma_separated_list(node.args) self.endline(u')') def visit_CNameDeclaratorNode(self, node): self.put(node.name) def visit_CSimpleBaseTypeNode(self, node): # See Parsing.p_sign_and_longness if node.is_basic_c_type: self.put(("unsigned ", "", "signed ")[node.signed]) if node.longness < 0: self.put("short " * -node.longness) elif node.longness > 0: self.put("long " * node.longness) self.put(node.name) def visit_CComplexBaseTypeNode(self, node): self.put(u'(') self.visit(node.base_type) self.visit(node.declarator) self.put(u')') def visit_CNestedBaseTypeNode(self, node): self.visit(node.base_type) self.put(u'.') self.put(node.name) def visit_TemplatedTypeNode(self, node): self.visit(node.base_type_node) self.put(u'[') self.comma_separated_list(node.positional_args + node.keyword_args.key_value_pairs) self.put(u']') def visit_CVarDefNode(self, node): self.startline(u"cdef ") self.visit(node.base_type) self.put(u" ") self.comma_separated_list(node.declarators, output_rhs=True) self.endline() def visit_container_node(self, node, decl, extras, attributes): # TODO: visibility self.startline(decl) if node.name: self.put(u' ') self.put(node.name) if node.cname is not None: self.put(u' "%s"' % node.cname) if extras: self.put(extras) self.endline(':') self.indent() if not attributes: self.putline('pass') else: for attribute in attributes: self.visit(attribute) self.dedent() def visit_CStructOrUnionDefNode(self, node): if node.typedef_flag: decl = u'ctypedef ' else: decl = u'cdef ' if node.visibility == 'public': decl += u'public ' if node.packed: decl += u'packed ' decl += node.kind self.visit_container_node(node, decl, None, node.attributes) def visit_CppClassNode(self, node): extras = "" if node.templates: extras = u"[%s]" % ", ".join(node.templates) if node.base_classes: extras += "(%s)" % ", ".join(node.base_classes) self.visit_container_node(node, u"cdef cppclass", extras, node.attributes) def visit_CEnumDefNode(self, node): self.visit_container_node(node, u"cdef enum", None, node.items) def visit_CEnumDefItemNode(self, node): self.startline(node.name) if node.cname: self.put(u' "%s"' % node.cname) if node.value: self.put(u" = ") self.visit(node.value) self.endline() def visit_CClassDefNode(self, node): assert not node.module_name if node.decorators: for decorator in node.decorators: self.visit(decorator) self.startline(u"cdef class ") self.put(node.class_name) if node.base_class_name: self.put(u"(") if node.base_class_module: self.put(node.base_class_module) self.put(u".") self.put(node.base_class_name) self.put(u")") self.endline(u":") self.indent() self.visit(node.body) self.dedent() def visit_CTypeDefNode(self, node): self.startline(u"ctypedef ") self.visit(node.base_type) self.put(u" ") self.visit(node.declarator) self.endline() def visit_FuncDefNode(self, node): self.startline(u"def %s(" % node.name) self.comma_separated_list(node.args) self.endline(u"):") self.indent() self.visit(node.body) self.dedent() def visit_CArgDeclNode(self, node): if node.base_type.name is not None: self.visit(node.base_type) self.put(u" ") self.visit(node.declarator) if node.default is not None: self.put(u" = ") self.visit(node.default) def visit_CImportStatNode(self, node): self.startline(u"cimport ") self.put(node.module_name) if node.as_name: self.put(u" as ") self.put(node.as_name) self.endline() def visit_FromCImportStatNode(self, node): self.startline(u"from ") self.put(node.module_name) self.put(u" cimport ") first = True for pos, name, as_name, kind in node.imported_names: assert kind is None if first: first = False else: self.put(u", ") self.put(name) if as_name: self.put(u" as ") self.put(as_name) self.endline() def visit_NameNode(self, node): self.put(node.name) def visit_IntNode(self, node): self.put(node.value) def visit_NoneNode(self, node): self.put(u"None") def visit_NotNode(self, node): self.put(u"(not ") self.visit(node.operand) self.put(u")") def visit_DecoratorNode(self, node): self.startline("@") self.visit(node.decorator) self.endline() def visit_BinopNode(self, node): self.visit(node.operand1) self.put(u" %s " % node.operator) self.visit(node.operand2) def visit_AttributeNode(self, node): self.visit(node.obj) self.put(u".%s" % node.attribute) def visit_BoolNode(self, node): self.put(str(node.value)) # FIXME: represent string nodes correctly def visit_StringNode(self, node): value = node.value if value.encoding is not None: value = value.encode(value.encoding) self.put(repr(value)) def visit_PassStatNode(self, node): self.startline(u"pass") self.endline() class CodeWriter(DeclarationWriter): def visit_SingleAssignmentNode(self, node): self.startline() self.visit(node.lhs) self.put(u" = ") self.visit(node.rhs) self.endline() def visit_CascadedAssignmentNode(self, node): self.startline() for lhs in node.lhs_list: self.visit(lhs) self.put(u" = ") self.visit(node.rhs) self.endline() def visit_PrintStatNode(self, node): self.startline(u"print ") self.comma_separated_list(node.arg_tuple.args) if not node.append_newline: self.put(u",") self.endline() def visit_ForInStatNode(self, node): self.startline(u"for ") self.visit(node.target) self.put(u" in ") self.visit(node.iterator.sequence) self.endline(u":") self.indent() self.visit(node.body) self.dedent() if node.else_clause is not None: self.line(u"else:") self.indent() self.visit(node.else_clause) self.dedent() def visit_IfStatNode(self, node): # The IfClauseNode is handled directly without a seperate match # for clariy. self.startline(u"if ") self.visit(node.if_clauses[0].condition) self.endline(":") self.indent() self.visit(node.if_clauses[0].body) self.dedent() for clause in node.if_clauses[1:]: self.startline("elif ") self.visit(clause.condition) self.endline(":") self.indent() self.visit(clause.body) self.dedent() if node.else_clause is not None: self.line("else:") self.indent() self.visit(node.else_clause) self.dedent() def visit_SequenceNode(self, node): self.comma_separated_list(node.args) # Might need to discover whether we need () around tuples...hmm... def visit_SimpleCallNode(self, node): self.visit(node.function) self.put(u"(") self.comma_separated_list(node.args) self.put(")") def visit_GeneralCallNode(self, node): self.visit(node.function) self.put(u"(") posarg = node.positional_args if isinstance(posarg, AsTupleNode): self.visit(posarg.arg) else: self.comma_separated_list(posarg.args) # TupleNode.args if node.keyword_args: if isinstance(node.keyword_args, DictNode): for i, (name, value) in enumerate(node.keyword_args.key_value_pairs): if i > 0: self.put(', ') self.visit(name) self.put('=') self.visit(value) else: raise Exception("Not implemented yet") self.put(u")") def visit_ExprStatNode(self, node): self.startline() self.visit(node.expr) self.endline() def visit_InPlaceAssignmentNode(self, node): self.startline() self.visit(node.lhs) self.put(u" %s= " % node.operator) self.visit(node.rhs) self.endline() def visit_WithStatNode(self, node): self.startline() self.put(u"with ") self.visit(node.manager) if node.target is not None: self.put(u" as ") self.visit(node.target) self.endline(u":") self.indent() self.visit(node.body) self.dedent() def visit_TryFinallyStatNode(self, node): self.line(u"try:") self.indent() self.visit(node.body) self.dedent() self.line(u"finally:") self.indent() self.visit(node.finally_clause) self.dedent() def visit_TryExceptStatNode(self, node): self.line(u"try:") self.indent() self.visit(node.body) self.dedent() for x in node.except_clauses: self.visit(x) if node.else_clause is not None: self.visit(node.else_clause) def visit_ExceptClauseNode(self, node): self.startline(u"except") if node.pattern is not None: self.put(u" ") self.visit(node.pattern) if node.target is not None: self.put(u", ") self.visit(node.target) self.endline(":") self.indent() self.visit(node.body) self.dedent() def visit_ReturnStatNode(self, node): self.startline("return ") self.visit(node.value) self.endline() def visit_ReraiseStatNode(self, node): self.line("raise") def visit_ImportNode(self, node): self.put(u"(import %s)" % node.module_name.value) def visit_TempsBlockNode(self, node): """ Temporaries are output like $1_1', where the first number is an index of the TempsBlockNode and the second number is an index of the temporary which that block allocates. """ idx = 0 for handle in node.temps: self.tempnames[handle] = "$%d_%d" % (self.tempblockindex, idx) idx += 1 self.tempblockindex += 1 self.visit(node.body) def visit_TempRefNode(self, node): self.put(self.tempnames[node.handle]) class PxdWriter(DeclarationWriter): def __call__(self, node): print(u'\n'.join(self.write(node).lines)) return node def visit_CFuncDefNode(self, node): if 'inline' in node.modifiers: return if node.overridable: self.startline(u'cpdef ') else: self.startline(u'cdef ') if node.visibility != 'private': self.put(node.visibility) self.put(u' ') if node.api: self.put(u'api ') self.visit(node.declarator) def visit_StatNode(self, node): pass Cython-0.23.4/Cython/Utility/0000755000175600017570000000000012606202455017116 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Utility/arrayarray.h0000644000175600017570000000756312606202452021454 0ustar jenkinsjenkins00000000000000/////////////// ArrayAPI.proto /////////////// // arrayarray.h // // Artificial C-API for Python's type, // used by array.pxd // // last changes: 2009-05-15 rk // 2012-05-02 andreasvc // (see revision control) // #ifndef _ARRAYARRAY_H #define _ARRAYARRAY_H // These two forward declarations are explicitly handled in the type // declaration code, as including them here is too late for cython-defined // types to use them. // struct arrayobject; // typedef struct arrayobject arrayobject; // All possible arraydescr values are defined in the vector "descriptors" // below. That's defined later because the appropriate get and set // functions aren't visible yet. typedef struct arraydescr { int typecode; int itemsize; PyObject * (*getitem)(struct arrayobject *, Py_ssize_t); int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *); #if PY_MAJOR_VERSION >= 3 char *formats; #endif } arraydescr; struct arrayobject { PyObject_HEAD Py_ssize_t ob_size; union { char *ob_item; float *as_floats; double *as_doubles; int *as_ints; unsigned int *as_uints; unsigned char *as_uchars; signed char *as_schars; char *as_chars; unsigned long *as_ulongs; long *as_longs; short *as_shorts; unsigned short *as_ushorts; Py_UNICODE *as_pyunicodes; void *as_voidptr; } data; Py_ssize_t allocated; struct arraydescr *ob_descr; PyObject *weakreflist; /* List of weak references */ #if PY_MAJOR_VERSION >= 3 int ob_exports; /* Number of exported buffers */ #endif }; #ifndef NO_NEWARRAY_INLINE // fast creation of a new array static CYTHON_INLINE PyObject * newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr) { arrayobject *op; size_t nbytes; if (size < 0) { PyErr_BadInternalCall(); return NULL; } nbytes = size * descr->itemsize; // Check for overflow if (nbytes / descr->itemsize != (size_t)size) { return PyErr_NoMemory(); } op = (arrayobject *) type->tp_alloc(type, 0); if (op == NULL) { return NULL; } op->ob_descr = descr; op->allocated = size; op->weakreflist = NULL; op->ob_size = size; if (size <= 0) { op->data.ob_item = NULL; } else { op->data.ob_item = PyMem_NEW(char, nbytes); if (op->data.ob_item == NULL) { Py_DECREF(op); return PyErr_NoMemory(); } } return (PyObject *) op; } #else PyObject* newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr); #endif /* ifndef NO_NEWARRAY_INLINE */ // fast resize (reallocation to the point) // not designed for filing small increments (but for fast opaque array apps) static CYTHON_INLINE int resize(arrayobject *self, Py_ssize_t n) { void *items = (void*) self->data.ob_item; PyMem_Resize(items, char, (size_t)(n * self->ob_descr->itemsize)); if (items == NULL) { PyErr_NoMemory(); return -1; } self->data.ob_item = (char*) items; self->ob_size = n; self->allocated = n; return 0; } // suitable for small increments; over allocation 50% ; static CYTHON_INLINE int resize_smart(arrayobject *self, Py_ssize_t n) { void *items = (void*) self->data.ob_item; Py_ssize_t newsize; if (n < self->ob_size) { self->ob_size = n; return 0; } newsize = n + (n / 2) + 1; if (newsize <= self->allocated) { /* overflow */ PyErr_NoMemory(); return -1; } PyMem_Resize(items, char, (size_t)(newsize * self->ob_descr->itemsize)); if (items == NULL) { PyErr_NoMemory(); return -1; } self->data.ob_item = (char*) items; self->ob_size = n; self->allocated = newsize; return 0; } #endif /* _ARRAYARRAY_H */ Cython-0.23.4/Cython/Utility/__init__.py0000644000175600017570000000220712606202452021225 0ustar jenkinsjenkins00000000000000 def pylong_join(count, digits_ptr='digits', join_type='unsigned long'): """ Generate an unrolled shift-then-or loop over the first 'count' digits. Assumes that they fit into 'join_type'. (((d[2] << n) | d[1]) << n) | d[0] """ return ('(' * (count * 2) + ' | '.join( "(%s)%s[%d])%s)" % (join_type, digits_ptr, _i, " << PyLong_SHIFT" if _i else '') for _i in range(count-1, -1, -1))) # although it could potentially make use of data independence, # this implementation is a bit slower than the simpler one above def _pylong_join(count, digits_ptr='digits', join_type='unsigned long'): """ Generate an or-ed series of shifts for the first 'count' digits. Assumes that they fit into 'join_type'. (d[2] << 2*n) | (d[1] << 1*n) | d[0] """ def shift(n): # avoid compiler warnings for overly large shifts that will be discarded anyway return " << (%d * PyLong_SHIFT < 8 * sizeof(%s) ? %d * PyLong_SHIFT : 0)" % (n, join_type, n) if n else '' return '(%s)' % ' | '.join( "(((%s)%s[%d])%s)" % (join_type, digits_ptr, i, shift(i)) for i in range(count-1, -1, -1)) Cython-0.23.4/Cython/Utility/TypeConversion.c0000644000175600017570000006456412606202452022265 0ustar jenkinsjenkins00000000000000/////////////// TypeConversions.proto /////////////// /* Type Conversion Predeclarations */ #define __Pyx_uchar_cast(c) ((unsigned char)c) #define __Pyx_long_cast(x) ((long)x) #define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \ (sizeof(type) < sizeof(Py_ssize_t)) || \ (sizeof(type) > sizeof(Py_ssize_t) && \ likely(v < (type)PY_SSIZE_T_MAX || \ v == (type)PY_SSIZE_T_MAX) && \ (!is_signed || likely(v > (type)PY_SSIZE_T_MIN || \ v == (type)PY_SSIZE_T_MIN))) || \ (sizeof(type) == sizeof(Py_ssize_t) && \ (is_signed || likely(v < (type)PY_SSIZE_T_MAX || \ v == (type)PY_SSIZE_T_MAX))) ) // fast and unsafe abs(Py_ssize_t) that ignores the overflow for (-PY_SSIZE_T_MAX-1) #if defined (__cplusplus) && __cplusplus >= 201103L #include #define __Pyx_sst_abs(value) std::abs(value) #elif SIZEOF_INT >= SIZEOF_SIZE_T #define __Pyx_sst_abs(value) abs(value) #elif SIZEOF_LONG >= SIZEOF_SIZE_T #define __Pyx_sst_abs(value) labs(value) #elif defined (_MSC_VER) && defined (_M_X64) // abs() is defined for long, but 64-bits type on MSVC is long long. // Use MS-specific _abs64 instead. #define __Pyx_sst_abs(value) _abs64(value) #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define __Pyx_sst_abs(value) llabs(value) #elif defined (__GNUC__) // gcc or clang on 64 bit windows. #define __Pyx_sst_abs(value) __builtin_llabs(value) #else #define __Pyx_sst_abs(value) ((value<0) ? -value : value) #endif static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*); static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); #define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) #define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) #define __Pyx_PyBytes_FromString PyBytes_FromString #define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); #if PY_MAJOR_VERSION < 3 #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize #else #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize #endif #define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) #define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) #define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) #define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) #define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) #define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) #define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) #if PY_MAJOR_VERSION < 3 static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) { const Py_UNICODE *u_end = u; while (*u_end++) ; return (size_t)(u_end - u - 1); } #else #define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen #endif #define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) #define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode #define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode #define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) #define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) #define __Pyx_PyBool_FromLong(b) ((b) ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False)) static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x); static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); #if CYTHON_COMPILING_IN_CPYTHON #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) #else #define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) #endif #define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) #if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII static int __Pyx_sys_getdefaultencoding_not_ascii; static int __Pyx_init_sys_getdefaultencoding_params(void) { PyObject* sys; PyObject* default_encoding = NULL; PyObject* ascii_chars_u = NULL; PyObject* ascii_chars_b = NULL; const char* default_encoding_c; sys = PyImport_ImportModule("sys"); if (!sys) goto bad; default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); Py_DECREF(sys); if (!default_encoding) goto bad; default_encoding_c = PyBytes_AsString(default_encoding); if (!default_encoding_c) goto bad; if (strcmp(default_encoding_c, "ascii") == 0) { __Pyx_sys_getdefaultencoding_not_ascii = 0; } else { char ascii_chars[128]; int c; for (c = 0; c < 128; c++) { ascii_chars[c] = c; } __Pyx_sys_getdefaultencoding_not_ascii = 1; ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); if (!ascii_chars_u) goto bad; ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { PyErr_Format( PyExc_ValueError, "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", default_encoding_c); goto bad; } Py_DECREF(ascii_chars_u); Py_DECREF(ascii_chars_b); } Py_DECREF(default_encoding); return 0; bad: Py_XDECREF(default_encoding); Py_XDECREF(ascii_chars_u); Py_XDECREF(ascii_chars_b); return -1; } #endif #if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) #else #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) // __PYX_DEFAULT_STRING_ENCODING is either a user provided string constant // or we need to look it up here #if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT static char* __PYX_DEFAULT_STRING_ENCODING; static int __Pyx_init_sys_getdefaultencoding_params(void) { PyObject* sys; PyObject* default_encoding = NULL; char* default_encoding_c; sys = PyImport_ImportModule("sys"); if (!sys) goto bad; default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); Py_DECREF(sys); if (!default_encoding) goto bad; default_encoding_c = PyBytes_AsString(default_encoding); if (!default_encoding_c) goto bad; __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c)); if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); Py_DECREF(default_encoding); return 0; bad: Py_XDECREF(default_encoding); return -1; } #endif #endif /////////////// TypeConversions /////////////// //@requires: PyLongInternals /* Type Conversion Functions */ static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); } static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) { Py_ssize_t ignore; return __Pyx_PyObject_AsStringAndSize(o, &ignore); } static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { #if CYTHON_COMPILING_IN_CPYTHON && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) if ( #if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII __Pyx_sys_getdefaultencoding_not_ascii && #endif PyUnicode_Check(o)) { #if PY_VERSION_HEX < 0x03030000 char* defenc_c; // borrowed reference, cached internally in 'o' by CPython PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); if (!defenc) return NULL; defenc_c = PyBytes_AS_STRING(defenc); #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII { char* end = defenc_c + PyBytes_GET_SIZE(defenc); char* c; for (c = defenc_c; c < end; c++) { if ((unsigned char) (*c) >= 128) { // raise the error PyUnicode_AsASCIIString(o); return NULL; } } } #endif /*__PYX_DEFAULT_STRING_ENCODING_IS_ASCII*/ *length = PyBytes_GET_SIZE(defenc); return defenc_c; #else /* PY_VERSION_HEX < 0x03030000 */ if (__Pyx_PyUnicode_READY(o) == -1) return NULL; #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII if (PyUnicode_IS_ASCII(o)) { // cached for the lifetime of the object *length = PyUnicode_GET_LENGTH(o); return PyUnicode_AsUTF8(o); } else { // raise the error PyUnicode_AsASCIIString(o); return NULL; } #else /* __PYX_DEFAULT_STRING_ENCODING_IS_ASCII */ return PyUnicode_AsUTF8AndSize(o, length); #endif /* __PYX_DEFAULT_STRING_ENCODING_IS_ASCII */ #endif /* PY_VERSION_HEX < 0x03030000 */ } else #endif /* __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT */ #if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) if (PyByteArray_Check(o)) { *length = PyByteArray_GET_SIZE(o); return PyByteArray_AS_STRING(o); } else #endif { char* result; int r = PyBytes_AsStringAndSize(o, &result, length); if (unlikely(r < 0)) { return NULL; } else { return result; } } } /* Note: __Pyx_PyObject_IsTrue is written to minimize branching. */ static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { int is_true = x == Py_True; if (is_true | (x == Py_False) | (x == Py_None)) return is_true; else return PyObject_IsTrue(x); } static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) { PyNumberMethods *m; const char *name = NULL; PyObject *res = NULL; #if PY_MAJOR_VERSION < 3 if (PyInt_Check(x) || PyLong_Check(x)) #else if (PyLong_Check(x)) #endif return __Pyx_NewRef(x); m = Py_TYPE(x)->tp_as_number; #if PY_MAJOR_VERSION < 3 if (m && m->nb_int) { name = "int"; res = PyNumber_Int(x); } else if (m && m->nb_long) { name = "long"; res = PyNumber_Long(x); } #else if (m && m->nb_int) { name = "int"; res = PyNumber_Long(x); } #endif if (res) { #if PY_MAJOR_VERSION < 3 if (!PyInt_Check(res) && !PyLong_Check(res)) { #else if (!PyLong_Check(res)) { #endif PyErr_Format(PyExc_TypeError, "__%.4s__ returned non-%.4s (type %.200s)", name, name, Py_TYPE(res)->tp_name); Py_DECREF(res); return NULL; } } else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "an integer is required"); } return res; } {{py: from Cython.Utility import pylong_join }} static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { Py_ssize_t ival; PyObject *x; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_CheckExact(b))) { if (sizeof(Py_ssize_t) >= sizeof(long)) return PyInt_AS_LONG(b); else return PyInt_AsSsize_t(x); } #endif if (likely(PyLong_CheckExact(b))) { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)b)->ob_digit; const Py_ssize_t size = Py_SIZE(b); // handle most common case first to avoid indirect branch and optimise branch prediction if (likely(__Pyx_sst_abs(size) <= 1)) { ival = likely(size) ? digits[0] : 0; if (size == -1) ival = -ival; return ival; } else { switch (size) { {{for _size in (2, 3, 4)}} {{for _case in (_size, -_size)}} case {{_case}}: if (8 * sizeof(Py_ssize_t) > {{_size}} * PyLong_SHIFT) { return {{'-' if _case < 0 else ''}}(Py_ssize_t) {{pylong_join(_size, 'digits', 'size_t')}}; } break; {{endfor}} {{endfor}} } } #endif return PyLong_AsSsize_t(b); } x = PyNumber_Index(b); if (!x) return -1; ival = PyInt_AsSsize_t(x); Py_DECREF(x); return ival; } static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { return PyInt_FromSize_t(ival); } /////////////// ToPyCTupleUtility.proto /////////////// static PyObject* {{funcname}}({{struct_type_decl}}); /////////////// ToPyCTupleUtility /////////////// static PyObject* {{funcname}}({{struct_type_decl}} value) { PyObject* item = NULL; PyObject* result = PyTuple_New({{size}}); if (!result) goto bad; {{for ix, component in enumerate(components):}} {{py:attr = "value.f%s" % ix}} item = {{component.to_py_function}}({{attr}}); if (!item) goto bad; PyTuple_SET_ITEM(result, {{ix}}, item); {{endfor}} return result; bad: Py_XDECREF(item); Py_XDECREF(result); return NULL; } /////////////// FromPyCTupleUtility.proto /////////////// static {{struct_type_decl}} {{funcname}}(PyObject *); /////////////// FromPyCTupleUtility /////////////// static {{struct_type_decl}} {{funcname}}(PyObject * o) { {{struct_type_decl}} result; if (!PyTuple_Check(o) || PyTuple_GET_SIZE(o) != {{size}}) { PyErr_Format(PyExc_TypeError, "Expected %.16s of size %d, got %.200s", "a tuple", {{size}}, Py_TYPE(o)->tp_name); goto bad; } #if CYTHON_COMPILING_IN_CPYTHON {{for ix, component in enumerate(components):}} {{py:attr = "result.f%s" % ix}} {{attr}} = {{component.from_py_function}}(PyTuple_GET_ITEM(o, {{ix}})); if ({{component.error_condition(attr)}}) goto bad; {{endfor}} #else { PyObject *item; {{for ix, component in enumerate(components):}} {{py:attr = "result.f%s" % ix}} item = PySequence_ITEM(o, {{ix}}); if (unlikely(!item)) goto bad; {{attr}} = {{component.from_py_function}}(item); Py_DECREF(item); if ({{component.error_condition(attr)}}) goto bad; {{endfor}} } #endif return result; bad: return result; } /////////////// UnicodeAsUCS4.proto /////////////// static CYTHON_INLINE Py_UCS4 __Pyx_PyUnicode_AsPy_UCS4(PyObject*); /////////////// UnicodeAsUCS4 /////////////// static CYTHON_INLINE Py_UCS4 __Pyx_PyUnicode_AsPy_UCS4(PyObject* x) { Py_ssize_t length; #if CYTHON_PEP393_ENABLED length = PyUnicode_GET_LENGTH(x); if (likely(length == 1)) { return PyUnicode_READ_CHAR(x, 0); } #else length = PyUnicode_GET_SIZE(x); if (likely(length == 1)) { return PyUnicode_AS_UNICODE(x)[0]; } #if Py_UNICODE_SIZE == 2 else if (PyUnicode_GET_SIZE(x) == 2) { Py_UCS4 high_val = PyUnicode_AS_UNICODE(x)[0]; if (high_val >= 0xD800 && high_val <= 0xDBFF) { Py_UCS4 low_val = PyUnicode_AS_UNICODE(x)[1]; if (low_val >= 0xDC00 && low_val <= 0xDFFF) { return 0x10000 + (((high_val & ((1<<10)-1)) << 10) | (low_val & ((1<<10)-1))); } } } #endif #endif PyErr_Format(PyExc_ValueError, "only single character unicode strings can be converted to Py_UCS4, " "got length %" CYTHON_FORMAT_SSIZE_T "d", length); return (Py_UCS4)-1; } /////////////// ObjectAsUCS4.proto /////////////// //@requires: UnicodeAsUCS4 #define __Pyx_PyObject_AsPy_UCS4(x) \ (likely(PyUnicode_Check(x)) ? __Pyx_PyUnicode_AsPy_UCS4(x) : __Pyx__PyObject_AsPy_UCS4(x)) static Py_UCS4 __Pyx__PyObject_AsPy_UCS4(PyObject*); /////////////// ObjectAsUCS4 /////////////// static Py_UCS4 __Pyx__PyObject_AsPy_UCS4(PyObject* x) { long ival; ival = __Pyx_PyInt_As_long(x); if (unlikely(ival < 0)) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_OverflowError, "cannot convert negative value to Py_UCS4"); return (Py_UCS4)-1; } else if (unlikely(ival > 1114111)) { PyErr_SetString(PyExc_OverflowError, "value too large to convert to Py_UCS4"); return (Py_UCS4)-1; } return (Py_UCS4)ival; } /////////////// ObjectAsPyUnicode.proto /////////////// static CYTHON_INLINE Py_UNICODE __Pyx_PyObject_AsPy_UNICODE(PyObject*); /////////////// ObjectAsPyUnicode /////////////// static CYTHON_INLINE Py_UNICODE __Pyx_PyObject_AsPy_UNICODE(PyObject* x) { long ival; #if CYTHON_PEP393_ENABLED #if Py_UNICODE_SIZE > 2 const long maxval = 1114111; #else const long maxval = 65535; #endif #else static long maxval = 0; #endif if (PyUnicode_Check(x)) { if (unlikely(__Pyx_PyUnicode_GET_LENGTH(x) != 1)) { PyErr_Format(PyExc_ValueError, "only single character unicode strings can be converted to Py_UNICODE, " "got length %" CYTHON_FORMAT_SSIZE_T "d", __Pyx_PyUnicode_GET_LENGTH(x)); return (Py_UNICODE)-1; } #if CYTHON_PEP393_ENABLED ival = PyUnicode_READ_CHAR(x, 0); #else return PyUnicode_AS_UNICODE(x)[0]; #endif } else { #if !CYTHON_PEP393_ENABLED if (unlikely(!maxval)) maxval = (long)PyUnicode_GetMax(); #endif ival = __Pyx_PyInt_As_long(x); } if (unlikely(ival < 0)) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_OverflowError, "cannot convert negative value to Py_UNICODE"); return (Py_UNICODE)-1; } else if (unlikely(ival > maxval)) { PyErr_SetString(PyExc_OverflowError, "value too large to convert to Py_UNICODE"); return (Py_UNICODE)-1; } return (Py_UNICODE)ival; } /////////////// CIntToPy.proto /////////////// static CYTHON_INLINE PyObject* {{TO_PY_FUNCTION}}({{TYPE}} value); /////////////// CIntToPy /////////////// static CYTHON_INLINE PyObject* {{TO_PY_FUNCTION}}({{TYPE}} value) { const {{TYPE}} neg_one = ({{TYPE}}) -1, const_zero = ({{TYPE}}) 0; const int is_unsigned = neg_one > const_zero; if (is_unsigned) { if (sizeof({{TYPE}}) < sizeof(long)) { return PyInt_FromLong((long) value); } else if (sizeof({{TYPE}}) <= sizeof(unsigned long)) { return PyLong_FromUnsignedLong((unsigned long) value); } else if (sizeof({{TYPE}}) <= sizeof(unsigned PY_LONG_LONG)) { return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); } } else { if (sizeof({{TYPE}}) <= sizeof(long)) { return PyInt_FromLong((long) value); } else if (sizeof({{TYPE}}) <= sizeof(PY_LONG_LONG)) { return PyLong_FromLongLong((PY_LONG_LONG) value); } } { int one = 1; int little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&value; return _PyLong_FromByteArray(bytes, sizeof({{TYPE}}), little, !is_unsigned); } } /////////////// CIntFromPyVerify /////////////// // see CIntFromPy #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value) \ __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) #define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value) \ __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) #define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc) \ { \ func_type value = func_value; \ if (sizeof(target_type) < sizeof(func_type)) { \ if (unlikely(value != (func_type) (target_type) value)) { \ func_type zero = 0; \ if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred())) \ return (target_type) -1; \ if (is_unsigned && unlikely(value < zero)) \ goto raise_neg_overflow; \ else \ goto raise_overflow; \ } \ } \ return (target_type) value; \ } /////////////// PyLongInternals /////////////// #if CYTHON_USE_PYLONG_INTERNALS #include "longintrepr.h" #endif /////////////// CIntFromPy.proto /////////////// static CYTHON_INLINE {{TYPE}} {{FROM_PY_FUNCTION}}(PyObject *); /////////////// CIntFromPy /////////////// //@requires: CIntFromPyVerify //@requires: PyLongInternals {{py: from Cython.Utility import pylong_join }} static CYTHON_INLINE {{TYPE}} {{FROM_PY_FUNCTION}}(PyObject *x) { const {{TYPE}} neg_one = ({{TYPE}}) -1, const_zero = ({{TYPE}}) 0; const int is_unsigned = neg_one > const_zero; #if PY_MAJOR_VERSION < 3 if (likely(PyInt_Check(x))) { if (sizeof({{TYPE}}) < sizeof(long)) { __PYX_VERIFY_RETURN_INT({{TYPE}}, long, PyInt_AS_LONG(x)) } else { long val = PyInt_AS_LONG(x); if (is_unsigned && unlikely(val < 0)) { goto raise_neg_overflow; } return ({{TYPE}}) val; } } else #endif if (likely(PyLong_Check(x))) { if (is_unsigned) { #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return ({{TYPE}}) 0; case 1: __PYX_VERIFY_RETURN_INT({{TYPE}}, digit, digits[0]) {{for _size in (2, 3, 4)}} case {{_size}}: if (8 * sizeof({{TYPE}}) > {{_size-1}} * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > {{_size}} * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT({{TYPE}}, unsigned long, {{pylong_join(_size, 'digits')}}) } else if (8 * sizeof({{TYPE}}) >= {{_size}} * PyLong_SHIFT) { return ({{TYPE}}) {{pylong_join(_size, 'digits', TYPE)}}; } } break; {{endfor}} } #endif #if CYTHON_COMPILING_IN_CPYTHON if (unlikely(Py_SIZE(x) < 0)) { goto raise_neg_overflow; } #else { // misuse Py_False as a quick way to compare to a '0' int object in PyPy int result = PyObject_RichCompareBool(x, Py_False, Py_LT); if (unlikely(result < 0)) return ({{TYPE}}) -1; if (unlikely(result == 1)) goto raise_neg_overflow; } #endif if (sizeof({{TYPE}}) <= sizeof(unsigned long)) { __PYX_VERIFY_RETURN_INT_EXC({{TYPE}}, unsigned long, PyLong_AsUnsignedLong(x)) } else if (sizeof({{TYPE}}) <= sizeof(unsigned PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC({{TYPE}}, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) } } else { // signed #if CYTHON_USE_PYLONG_INTERNALS const digit* digits = ((PyLongObject*)x)->ob_digit; switch (Py_SIZE(x)) { case 0: return ({{TYPE}}) 0; case -1: __PYX_VERIFY_RETURN_INT({{TYPE}}, sdigit, -(sdigit) digits[0]) case 1: __PYX_VERIFY_RETURN_INT({{TYPE}}, digit, +digits[0]) {{for _size in (2, 3, 4)}} {{for _case in (-_size, _size)}} case {{_case}}: if (8 * sizeof({{TYPE}}){{' - 1' if _case < 0 else ''}} > {{_size-1}} * PyLong_SHIFT) { if (8 * sizeof(unsigned long) > {{_size}} * PyLong_SHIFT) { __PYX_VERIFY_RETURN_INT({{TYPE}}, {{'long' if _case < 0 else 'unsigned long'}}, {{'-(long) ' if _case < 0 else ''}}{{pylong_join(_size, 'digits')}}) } else if (8 * sizeof({{TYPE}}) - 1 > {{_size}} * PyLong_SHIFT) { return ({{TYPE}}) ({{'((%s)-1)*' % TYPE if _case < 0 else ''}}{{pylong_join(_size, 'digits', TYPE)}}); } } break; {{endfor}} {{endfor}} } #endif if (sizeof({{TYPE}}) <= sizeof(long)) { __PYX_VERIFY_RETURN_INT_EXC({{TYPE}}, long, PyLong_AsLong(x)) } else if (sizeof({{TYPE}}) <= sizeof(PY_LONG_LONG)) { __PYX_VERIFY_RETURN_INT_EXC({{TYPE}}, PY_LONG_LONG, PyLong_AsLongLong(x)) } } { #if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) PyErr_SetString(PyExc_RuntimeError, "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); #else {{TYPE}} val; PyObject *v = __Pyx_PyNumber_Int(x); #if PY_MAJOR_VERSION < 3 if (likely(v) && !PyLong_Check(v)) { PyObject *tmp = v; v = PyNumber_Long(tmp); Py_DECREF(tmp); } #endif if (likely(v)) { int one = 1; int is_little = (int)*(unsigned char *)&one; unsigned char *bytes = (unsigned char *)&val; int ret = _PyLong_AsByteArray((PyLongObject *)v, bytes, sizeof(val), is_little, !is_unsigned); Py_DECREF(v); if (likely(!ret)) return val; } #endif return ({{TYPE}}) -1; } } else { {{TYPE}} val; PyObject *tmp = __Pyx_PyNumber_Int(x); if (!tmp) return ({{TYPE}}) -1; val = {{FROM_PY_FUNCTION}}(tmp); Py_DECREF(tmp); return val; } raise_overflow: PyErr_SetString(PyExc_OverflowError, "value too large to convert to {{TYPE}}"); return ({{TYPE}}) -1; raise_neg_overflow: PyErr_SetString(PyExc_OverflowError, "can't convert negative value to {{TYPE}}"); return ({{TYPE}}) -1; } Cython-0.23.4/Cython/Utility/TestUtilityLoader.c0000644000175600017570000000042712606202452022714 0ustar jenkinsjenkins00000000000000////////// TestUtilityLoader.proto ////////// test {{loader}} prototype ////////// TestUtilityLoader ////////// //@requires: OtherUtility test {{loader}} impl ////////// OtherUtility.proto ////////// req {{loader}} proto ////////// OtherUtility ////////// req {{loader}} impl Cython-0.23.4/Cython/Utility/TestCythonScope.pyx0000644000175600017570000000307312606202452022756 0ustar jenkinsjenkins00000000000000########## TestClass ########## # These utilities are for testing purposes cdef extern from *: cdef object __pyx_test_dep(object) @cname('__pyx_TestClass') cdef class TestClass(object): cdef public int value def __init__(self, int value): self.value = value def __str__(self): return 'TestClass(%d)' % self.value cdef cdef_method(self, int value): print 'Hello from cdef_method', value cpdef cpdef_method(self, int value): print 'Hello from cpdef_method', value def def_method(self, int value): print 'Hello from def_method', value @cname('cdef_cname') cdef cdef_cname_method(self, int value): print "Hello from cdef_cname_method", value @cname('cpdef_cname') cpdef cpdef_cname_method(self, int value): print "Hello from cpdef_cname_method", value @cname('def_cname') def def_cname_method(self, int value): print "Hello from def_cname_method", value @cname('__pyx_test_call_other_cy_util') cdef test_call(obj): print 'test_call' __pyx_test_dep(obj) @cname('__pyx_TestClass_New') cdef _testclass_new(int value): return TestClass(value) ########### TestDep ########## @cname('__pyx_test_dep') cdef test_dep(obj): print 'test_dep', obj ########## TestScope ########## @cname('__pyx_testscope') cdef object _testscope(int value): return "hello from cython scope, value=%d" % value ########## View.TestScope ########## @cname('__pyx_view_testscope') cdef object _testscope(int value): return "hello from cython.view scope, value=%d" % value Cython-0.23.4/Cython/Utility/TestCyUtilityLoader.pyx0000644000175600017570000000023012606202452023576 0ustar jenkinsjenkins00000000000000########## TestCyUtilityLoader ########## #@requires: OtherUtility test {{cy_loader}} impl ########## OtherUtility ########## req {{cy_loader}} impl Cython-0.23.4/Cython/Utility/StringTools.c0000644000175600017570000006773412606202452021567 0ustar jenkinsjenkins00000000000000 //////////////////// IncludeStringH.proto //////////////////// #include //////////////////// IncludeCppStringH.proto //////////////////// #include //////////////////// InitStrings.proto //////////////////// static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/ //////////////////// InitStrings //////////////////// static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { while (t->p) { #if PY_MAJOR_VERSION < 3 if (t->is_unicode) { *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); } else if (t->intern) { *t->p = PyString_InternFromString(t->s); } else { *t->p = PyString_FromStringAndSize(t->s, t->n - 1); } #else /* Python 3+ has unicode identifiers */ if (t->is_unicode | t->is_str) { if (t->intern) { *t->p = PyUnicode_InternFromString(t->s); } else if (t->encoding) { *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); } else { *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); } } else { *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); } #endif if (!*t->p) return -1; ++t; } return 0; } //////////////////// BytesContains.proto //////////////////// static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character); /*proto*/ //////////////////// BytesContains //////////////////// static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character) { const Py_ssize_t length = PyBytes_GET_SIZE(bytes); char* char_start = PyBytes_AS_STRING(bytes); char* pos; for (pos=char_start; pos < char_start+length; pos++) { if (character == pos[0]) return 1; } return 0; } //////////////////// PyUCS4InUnicode.proto //////////////////// static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character); /*proto*/ static CYTHON_INLINE int __Pyx_PyUnicodeBufferContainsUCS4(Py_UNICODE* buffer, Py_ssize_t length, Py_UCS4 character); /*proto*/ //////////////////// PyUCS4InUnicode //////////////////// static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character) { #if CYTHON_PEP393_ENABLED const int kind = PyUnicode_KIND(unicode); if (likely(kind != PyUnicode_WCHAR_KIND)) { Py_ssize_t i; const void* udata = PyUnicode_DATA(unicode); const Py_ssize_t length = PyUnicode_GET_LENGTH(unicode); for (i=0; i < length; i++) { if (unlikely(character == PyUnicode_READ(kind, udata, i))) return 1; } return 0; } #endif return __Pyx_PyUnicodeBufferContainsUCS4( PyUnicode_AS_UNICODE(unicode), PyUnicode_GET_SIZE(unicode), character); } static CYTHON_INLINE int __Pyx_PyUnicodeBufferContainsUCS4(Py_UNICODE* buffer, Py_ssize_t length, Py_UCS4 character) { Py_UNICODE uchar; Py_UNICODE* pos; #if Py_UNICODE_SIZE == 2 if (character > 65535) { /* handle surrogate pairs for Py_UNICODE buffers in 16bit Unicode builds */ Py_UNICODE high_val, low_val; high_val = (Py_UNICODE) (0xD800 | (((character - 0x10000) >> 10) & ((1<<10)-1))); low_val = (Py_UNICODE) (0xDC00 | ( (character - 0x10000) & ((1<<10)-1))); for (pos=buffer; pos < buffer+length-1; pos++) { if (unlikely(high_val == pos[0]) & unlikely(low_val == pos[1])) return 1; } return 0; } #endif uchar = (Py_UNICODE) character; for (pos=buffer; pos < buffer+length; pos++) { if (unlikely(uchar == pos[0])) return 1; } return 0; } //////////////////// PyUnicodeContains.proto //////////////////// static CYTHON_INLINE int __Pyx_PyUnicode_ContainsTF(PyObject* substring, PyObject* text, int eq) { int result = PyUnicode_Contains(text, substring); return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); } //////////////////// CStringEquals.proto //////////////////// static CYTHON_INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/ //////////////////// CStringEquals //////////////////// static CYTHON_INLINE int __Pyx_StrEq(const char *s1, const char *s2) { while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; } return *s1 == *s2; } //////////////////// StrEquals.proto //////////////////// //@requires: BytesEquals //@requires: UnicodeEquals #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals #else #define __Pyx_PyString_Equals __Pyx_PyBytes_Equals #endif //////////////////// UnicodeEquals.proto //////////////////// static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/ //////////////////// UnicodeEquals //////////////////// //@requires: BytesEquals static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { #if CYTHON_COMPILING_IN_PYPY return PyObject_RichCompareBool(s1, s2, equals); #else #if PY_MAJOR_VERSION < 3 PyObject* owned_ref = NULL; #endif int s1_is_unicode, s2_is_unicode; if (s1 == s2) { /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */ goto return_eq; } s1_is_unicode = PyUnicode_CheckExact(s1); s2_is_unicode = PyUnicode_CheckExact(s2); #if PY_MAJOR_VERSION < 3 if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) { owned_ref = PyUnicode_FromObject(s2); if (unlikely(!owned_ref)) return -1; s2 = owned_ref; s2_is_unicode = 1; } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) { owned_ref = PyUnicode_FromObject(s1); if (unlikely(!owned_ref)) return -1; s1 = owned_ref; s1_is_unicode = 1; } else if (((!s2_is_unicode) & (!s1_is_unicode))) { return __Pyx_PyBytes_Equals(s1, s2, equals); } #endif if (s1_is_unicode & s2_is_unicode) { Py_ssize_t length; int kind; void *data1, *data2; if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) return -1; length = __Pyx_PyUnicode_GET_LENGTH(s1); if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) { goto return_ne; } // len(s1) == len(s2) >= 1 (empty string is interned, and "s1 is not s2") kind = __Pyx_PyUnicode_KIND(s1); if (kind != __Pyx_PyUnicode_KIND(s2)) { goto return_ne; } data1 = __Pyx_PyUnicode_DATA(s1); data2 = __Pyx_PyUnicode_DATA(s2); if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { goto return_ne; } else if (length == 1) { goto return_eq; } else { int result = memcmp(data1, data2, (size_t)(length * kind)); #if PY_MAJOR_VERSION < 3 Py_XDECREF(owned_ref); #endif return (equals == Py_EQ) ? (result == 0) : (result != 0); } } else if ((s1 == Py_None) & s2_is_unicode) { goto return_ne; } else if ((s2 == Py_None) & s1_is_unicode) { goto return_ne; } else { int result; PyObject* py_result = PyObject_RichCompare(s1, s2, equals); if (!py_result) return -1; result = __Pyx_PyObject_IsTrue(py_result); Py_DECREF(py_result); return result; } return_eq: #if PY_MAJOR_VERSION < 3 Py_XDECREF(owned_ref); #endif return (equals == Py_EQ); return_ne: #if PY_MAJOR_VERSION < 3 Py_XDECREF(owned_ref); #endif return (equals == Py_NE); #endif } //////////////////// BytesEquals.proto //////////////////// static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/ //////////////////// BytesEquals //////////////////// //@requires: IncludeStringH static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { #if CYTHON_COMPILING_IN_PYPY return PyObject_RichCompareBool(s1, s2, equals); #else if (s1 == s2) { /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */ return (equals == Py_EQ); } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { const char *ps1, *ps2; Py_ssize_t length = PyBytes_GET_SIZE(s1); if (length != PyBytes_GET_SIZE(s2)) return (equals == Py_NE); // len(s1) == len(s2) >= 1 (empty string is interned, and "s1 is not s2") ps1 = PyBytes_AS_STRING(s1); ps2 = PyBytes_AS_STRING(s2); if (ps1[0] != ps2[0]) { return (equals == Py_NE); } else if (length == 1) { return (equals == Py_EQ); } else { int result = memcmp(ps1, ps2, (size_t)length); return (equals == Py_EQ) ? (result == 0) : (result != 0); } } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { return (equals == Py_NE); } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { return (equals == Py_NE); } else { int result; PyObject* py_result = PyObject_RichCompare(s1, s2, equals); if (!py_result) return -1; result = __Pyx_PyObject_IsTrue(py_result); Py_DECREF(py_result); return result; } #endif } //////////////////// GetItemIntByteArray.proto //////////////////// #define __Pyx_GetItemInt_ByteArray(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ __Pyx_GetItemInt_ByteArray_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \ (PyErr_SetString(PyExc_IndexError, "bytearray index out of range"), -1)) static CYTHON_INLINE int __Pyx_GetItemInt_ByteArray_Fast(PyObject* string, Py_ssize_t i, int wraparound, int boundscheck); //////////////////// GetItemIntByteArray //////////////////// static CYTHON_INLINE int __Pyx_GetItemInt_ByteArray_Fast(PyObject* string, Py_ssize_t i, int wraparound, int boundscheck) { Py_ssize_t length; if (wraparound | boundscheck) { length = PyByteArray_GET_SIZE(string); if (wraparound & unlikely(i < 0)) i += length; if ((!boundscheck) || likely((0 <= i) & (i < length))) { return (unsigned char) (PyByteArray_AS_STRING(string)[i]); } else { PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); return -1; } } else { return (unsigned char) (PyByteArray_AS_STRING(string)[i]); } } //////////////////// SetItemIntByteArray.proto //////////////////// #define __Pyx_SetItemInt_ByteArray(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ __Pyx_SetItemInt_ByteArray_Fast(o, (Py_ssize_t)i, v, wraparound, boundscheck) : \ (PyErr_SetString(PyExc_IndexError, "bytearray index out of range"), -1)) static CYTHON_INLINE int __Pyx_SetItemInt_ByteArray_Fast(PyObject* string, Py_ssize_t i, unsigned char v, int wraparound, int boundscheck); //////////////////// SetItemIntByteArray //////////////////// static CYTHON_INLINE int __Pyx_SetItemInt_ByteArray_Fast(PyObject* string, Py_ssize_t i, unsigned char v, int wraparound, int boundscheck) { Py_ssize_t length; if (wraparound | boundscheck) { length = PyByteArray_GET_SIZE(string); if (wraparound & unlikely(i < 0)) i += length; if ((!boundscheck) || likely((0 <= i) & (i < length))) { PyByteArray_AS_STRING(string)[i] = (char) v; return 0; } else { PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); return -1; } } else { PyByteArray_AS_STRING(string)[i] = (char) v; return 0; } } //////////////////// GetItemIntUnicode.proto //////////////////// #define __Pyx_GetItemInt_Unicode(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ __Pyx_GetItemInt_Unicode_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \ (PyErr_SetString(PyExc_IndexError, "string index out of range"), (Py_UCS4)-1)) static CYTHON_INLINE Py_UCS4 __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i, int wraparound, int boundscheck); //////////////////// GetItemIntUnicode //////////////////// static CYTHON_INLINE Py_UCS4 __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i, int wraparound, int boundscheck) { Py_ssize_t length; if (unlikely(__Pyx_PyUnicode_READY(ustring) < 0)) return (Py_UCS4)-1; if (wraparound | boundscheck) { length = __Pyx_PyUnicode_GET_LENGTH(ustring); if (wraparound & unlikely(i < 0)) i += length; if ((!boundscheck) || likely((0 <= i) & (i < length))) { return __Pyx_PyUnicode_READ_CHAR(ustring, i); } else { PyErr_SetString(PyExc_IndexError, "string index out of range"); return (Py_UCS4)-1; } } else { return __Pyx_PyUnicode_READ_CHAR(ustring, i); } } /////////////// decode_cpp_string.proto /////////////// //@requires: IncludeCppStringH //@requires: decode_c_bytes static CYTHON_INLINE PyObject* __Pyx_decode_cpp_string( std::string cppstring, Py_ssize_t start, Py_ssize_t stop, const char* encoding, const char* errors, PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { return __Pyx_decode_c_bytes( cppstring.data(), cppstring.size(), start, stop, encoding, errors, decode_func); } /////////////// decode_c_string.proto /////////////// static CYTHON_INLINE PyObject* __Pyx_decode_c_string( const char* cstring, Py_ssize_t start, Py_ssize_t stop, const char* encoding, const char* errors, PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)); /////////////// decode_c_string /////////////// //@requires: IncludeStringH /* duplicate code to avoid calling strlen() if start >= 0 and stop >= 0 */ static CYTHON_INLINE PyObject* __Pyx_decode_c_string( const char* cstring, Py_ssize_t start, Py_ssize_t stop, const char* encoding, const char* errors, PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { Py_ssize_t length; if (unlikely((start < 0) | (stop < 0))) { size_t slen = strlen(cstring); if (unlikely(slen > (size_t) PY_SSIZE_T_MAX)) { PyErr_SetString(PyExc_OverflowError, "c-string too long to convert to Python"); return NULL; } length = (Py_ssize_t) slen; if (start < 0) { start += length; if (start < 0) start = 0; } if (stop < 0) stop += length; } length = stop - start; if (unlikely(length <= 0)) return PyUnicode_FromUnicode(NULL, 0); cstring += start; if (decode_func) { return decode_func(cstring, length, errors); } else { return PyUnicode_Decode(cstring, length, encoding, errors); } } /////////////// decode_c_bytes.proto /////////////// static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes( const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop, const char* encoding, const char* errors, PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)); /////////////// decode_c_bytes /////////////// static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes( const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop, const char* encoding, const char* errors, PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { if (unlikely((start < 0) | (stop < 0))) { if (start < 0) { start += length; if (start < 0) start = 0; } if (stop < 0) stop += length; } if (stop > length) stop = length; length = stop - start; if (unlikely(length <= 0)) return PyUnicode_FromUnicode(NULL, 0); cstring += start; if (decode_func) { return decode_func(cstring, length, errors); } else { return PyUnicode_Decode(cstring, length, encoding, errors); } } /////////////// decode_bytes.proto /////////////// //@requires: decode_c_bytes static CYTHON_INLINE PyObject* __Pyx_decode_bytes( PyObject* string, Py_ssize_t start, Py_ssize_t stop, const char* encoding, const char* errors, PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { return __Pyx_decode_c_bytes( PyBytes_AS_STRING(string), PyBytes_GET_SIZE(string), start, stop, encoding, errors, decode_func); } /////////////// decode_bytearray.proto /////////////// //@requires: decode_c_bytes static CYTHON_INLINE PyObject* __Pyx_decode_bytearray( PyObject* string, Py_ssize_t start, Py_ssize_t stop, const char* encoding, const char* errors, PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) { return __Pyx_decode_c_bytes( PyByteArray_AS_STRING(string), PyByteArray_GET_SIZE(string), start, stop, encoding, errors, decode_func); } /////////////// PyUnicode_Substring.proto /////////////// static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Substring( PyObject* text, Py_ssize_t start, Py_ssize_t stop); /////////////// PyUnicode_Substring /////////////// static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Substring( PyObject* text, Py_ssize_t start, Py_ssize_t stop) { Py_ssize_t length; if (unlikely(__Pyx_PyUnicode_READY(text) == -1)) return NULL; length = __Pyx_PyUnicode_GET_LENGTH(text); if (start < 0) { start += length; if (start < 0) start = 0; } if (stop < 0) stop += length; else if (stop > length) stop = length; length = stop - start; if (length <= 0) return PyUnicode_FromUnicode(NULL, 0); #if CYTHON_PEP393_ENABLED return PyUnicode_FromKindAndData(PyUnicode_KIND(text), PyUnicode_1BYTE_DATA(text) + start*PyUnicode_KIND(text), stop-start); #else return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(text)+start, stop-start); #endif } /////////////// py_unicode_istitle.proto /////////////// // Py_UNICODE_ISTITLE() doesn't match unicode.istitle() as the latter // additionally allows character that comply with Py_UNICODE_ISUPPER() #if PY_VERSION_HEX < 0x030200A2 static CYTHON_INLINE int __Pyx_Py_UNICODE_ISTITLE(Py_UNICODE uchar) #else static CYTHON_INLINE int __Pyx_Py_UNICODE_ISTITLE(Py_UCS4 uchar) #endif { return Py_UNICODE_ISTITLE(uchar) || Py_UNICODE_ISUPPER(uchar); } /////////////// unicode_tailmatch.proto /////////////// static int __Pyx_PyUnicode_Tailmatch(PyObject* s, PyObject* substr, Py_ssize_t start, Py_ssize_t end, int direction); /*proto*/ /////////////// unicode_tailmatch /////////////// // Python's unicode.startswith() and unicode.endswith() support a // tuple of prefixes/suffixes, whereas it's much more common to // test for a single unicode string. static int __Pyx_PyUnicode_Tailmatch(PyObject* s, PyObject* substr, Py_ssize_t start, Py_ssize_t end, int direction) { if (unlikely(PyTuple_Check(substr))) { Py_ssize_t i, count = PyTuple_GET_SIZE(substr); for (i = 0; i < count; i++) { Py_ssize_t result; #if CYTHON_COMPILING_IN_CPYTHON result = PyUnicode_Tailmatch(s, PyTuple_GET_ITEM(substr, i), start, end, direction); #else PyObject* sub = PySequence_ITEM(substr, i); if (unlikely(!sub)) return -1; result = PyUnicode_Tailmatch(s, sub, start, end, direction); Py_DECREF(sub); #endif if (result) { return (int) result; } } return 0; } return (int) PyUnicode_Tailmatch(s, substr, start, end, direction); } /////////////// bytes_tailmatch.proto /////////////// static int __Pyx_PyBytes_SingleTailmatch(PyObject* self, PyObject* arg, Py_ssize_t start, Py_ssize_t end, int direction); /*proto*/ static int __Pyx_PyBytes_Tailmatch(PyObject* self, PyObject* substr, Py_ssize_t start, Py_ssize_t end, int direction); /*proto*/ /////////////// bytes_tailmatch /////////////// static int __Pyx_PyBytes_SingleTailmatch(PyObject* self, PyObject* arg, Py_ssize_t start, Py_ssize_t end, int direction) { const char* self_ptr = PyBytes_AS_STRING(self); Py_ssize_t self_len = PyBytes_GET_SIZE(self); const char* sub_ptr; Py_ssize_t sub_len; int retval; Py_buffer view; view.obj = NULL; if ( PyBytes_Check(arg) ) { sub_ptr = PyBytes_AS_STRING(arg); sub_len = PyBytes_GET_SIZE(arg); } #if PY_MAJOR_VERSION < 3 // Python 2.x allows mixing unicode and str else if ( PyUnicode_Check(arg) ) { return (int) PyUnicode_Tailmatch(self, arg, start, end, direction); } #endif else { if (unlikely(PyObject_GetBuffer(self, &view, PyBUF_SIMPLE) == -1)) return -1; sub_ptr = (const char*) view.buf; sub_len = view.len; } if (end > self_len) end = self_len; else if (end < 0) end += self_len; if (end < 0) end = 0; if (start < 0) start += self_len; if (start < 0) start = 0; if (direction > 0) { /* endswith */ if (end-sub_len > start) start = end - sub_len; } if (start + sub_len <= end) retval = !memcmp(self_ptr+start, sub_ptr, (size_t)sub_len); else retval = 0; if (view.obj) PyBuffer_Release(&view); return retval; } static int __Pyx_PyBytes_Tailmatch(PyObject* self, PyObject* substr, Py_ssize_t start, Py_ssize_t end, int direction) { if (unlikely(PyTuple_Check(substr))) { Py_ssize_t i, count = PyTuple_GET_SIZE(substr); for (i = 0; i < count; i++) { int result; #if CYTHON_COMPILING_IN_CPYTHON result = __Pyx_PyBytes_SingleTailmatch(self, PyTuple_GET_ITEM(substr, i), start, end, direction); #else PyObject* sub = PySequence_ITEM(substr, i); if (unlikely(!sub)) return -1; result = __Pyx_PyBytes_SingleTailmatch(self, sub, start, end, direction); Py_DECREF(sub); #endif if (result) { return result; } } return 0; } return __Pyx_PyBytes_SingleTailmatch(self, substr, start, end, direction); } /////////////// str_tailmatch.proto /////////////// static CYTHON_INLINE int __Pyx_PyStr_Tailmatch(PyObject* self, PyObject* arg, Py_ssize_t start, Py_ssize_t end, int direction); /*proto*/ /////////////// str_tailmatch /////////////// //@requires: bytes_tailmatch //@requires: unicode_tailmatch static CYTHON_INLINE int __Pyx_PyStr_Tailmatch(PyObject* self, PyObject* arg, Py_ssize_t start, Py_ssize_t end, int direction) { // We do not use a C compiler macro here to avoid "unused function" // warnings for the *_Tailmatch() function that is not being used in // the specific CPython version. The C compiler will generate the same // code anyway, and will usually just remove the unused function. if (PY_MAJOR_VERSION < 3) return __Pyx_PyBytes_Tailmatch(self, arg, start, end, direction); else return __Pyx_PyUnicode_Tailmatch(self, arg, start, end, direction); } /////////////// bytes_index.proto /////////////// static CYTHON_INLINE char __Pyx_PyBytes_GetItemInt(PyObject* bytes, Py_ssize_t index, int check_bounds); /*proto*/ /////////////// bytes_index /////////////// static CYTHON_INLINE char __Pyx_PyBytes_GetItemInt(PyObject* bytes, Py_ssize_t index, int check_bounds) { if (check_bounds) { Py_ssize_t size = PyBytes_GET_SIZE(bytes); if (unlikely(index >= size) | ((index < 0) & unlikely(index < -size))) { PyErr_SetString(PyExc_IndexError, "string index out of range"); return -1; } } if (index < 0) index += PyBytes_GET_SIZE(bytes); return PyBytes_AS_STRING(bytes)[index]; } //////////////////// StringJoin.proto //////////////////// #if PY_MAJOR_VERSION < 3 #define __Pyx_PyString_Join __Pyx_PyBytes_Join #define __Pyx_PyBaseString_Join(s, v) (PyUnicode_CheckExact(s) ? PyUnicode_Join(s, v) : __Pyx_PyBytes_Join(s, v)) #else #define __Pyx_PyString_Join PyUnicode_Join #define __Pyx_PyBaseString_Join PyUnicode_Join #endif #if CYTHON_COMPILING_IN_CPYTHON #if PY_MAJOR_VERSION < 3 #define __Pyx_PyBytes_Join _PyString_Join #else #define __Pyx_PyBytes_Join _PyBytes_Join #endif #else static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values); /*proto*/ #endif //////////////////// StringJoin //////////////////// #if !CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values) { return PyObject_CallMethodObjArgs(sep, PYIDENT("join"), values, NULL); } #endif //////////////////// ByteArrayAppendObject.proto //////////////////// static CYTHON_INLINE int __Pyx_PyByteArray_AppendObject(PyObject* bytearray, PyObject* value); //////////////////// ByteArrayAppendObject //////////////////// //@requires: TypeConversion.c::PyLongInternals //@requires: ByteArrayAppend static CYTHON_INLINE int __Pyx_PyByteArray_AppendObject(PyObject* bytearray, PyObject* value) { Py_ssize_t ival; #if PY_MAJOR_VERSION < 3 if (unlikely(PyString_Check(value))) { if (unlikely(PyString_GET_SIZE(value) != 1)) { PyErr_SetString(PyExc_ValueError, "string must be of size 1"); return -1; } ival = (unsigned char) (PyString_AS_STRING(value)[0]); } else #endif #if CYTHON_USE_PYLONG_INTERNALS if (likely(PyLong_CheckExact(value)) && likely(Py_SIZE(value) == 1 || Py_SIZE(value) == 0)) { if (Py_SIZE(value) == 0) { ival = 0; } else { ival = ((PyLongObject*)value)->ob_digit[0]; if (unlikely(ival > 255)) goto bad_range; } } else #endif { // CPython calls PyNumber_Index() internally ival = __Pyx_PyIndex_AsSsize_t(value); if (unlikely((ival < 0) | (ival > 255))) { if (ival == -1 && PyErr_Occurred()) return -1; goto bad_range; } } return __Pyx_PyByteArray_Append(bytearray, ival); bad_range: PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); return -1; } //////////////////// ByteArrayAppend.proto //////////////////// static CYTHON_INLINE int __Pyx_PyByteArray_Append(PyObject* bytearray, int value); //////////////////// ByteArrayAppend //////////////////// //@requires: ObjectHandling.c::PyObjectCallMethod1 static CYTHON_INLINE int __Pyx_PyByteArray_Append(PyObject* bytearray, int value) { PyObject *pyval, *retval; #if CYTHON_COMPILING_IN_CPYTHON if (likely((value >= 0) & (value <= 255))) { Py_ssize_t n = Py_SIZE(bytearray); if (likely(n != PY_SSIZE_T_MAX)) { if (unlikely(PyByteArray_Resize(bytearray, n + 1) < 0)) return -1; PyByteArray_AS_STRING(bytearray)[n] = value; return 0; } } else { PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)"); return -1; } #endif pyval = PyInt_FromLong(value); if (unlikely(!pyval)) return -1; retval = __Pyx_PyObject_CallMethod1(bytearray, PYIDENT("append"), pyval); Py_DECREF(pyval); if (unlikely(!retval)) return -1; Py_DECREF(retval); return 0; } Cython-0.23.4/Cython/Utility/Profile.c0000644000175600017570000003755712606202452020700 0ustar jenkinsjenkins00000000000000/////////////// Profile.proto /////////////// //@substitute: naming // Note that cPython ignores PyTrace_EXCEPTION, // but maybe some other profilers don't. #ifndef CYTHON_PROFILE #define CYTHON_PROFILE 1 #endif #ifndef CYTHON_TRACE_NOGIL #define CYTHON_TRACE_NOGIL 0 #else #if CYTHON_TRACE_NOGIL && !defined(CYTHON_TRACE) #define CYTHON_TRACE 1 #endif #endif #ifndef CYTHON_TRACE #define CYTHON_TRACE 0 #endif #if CYTHON_TRACE #undef CYTHON_PROFILE_REUSE_FRAME #endif #ifndef CYTHON_PROFILE_REUSE_FRAME #define CYTHON_PROFILE_REUSE_FRAME 0 #endif #if CYTHON_PROFILE || CYTHON_TRACE #include "compile.h" #include "frameobject.h" #include "traceback.h" #if CYTHON_PROFILE_REUSE_FRAME #define CYTHON_FRAME_MODIFIER static #define CYTHON_FRAME_DEL(frame) #else #define CYTHON_FRAME_MODIFIER #define CYTHON_FRAME_DEL(frame) Py_CLEAR(frame) #endif #define __Pyx_TraceDeclarations \ static PyCodeObject *$frame_code_cname = NULL; \ CYTHON_FRAME_MODIFIER PyFrameObject *$frame_cname = NULL; \ int __Pyx_use_tracing = 0; #define __Pyx_TraceFrameInit(codeobj) \ if (codeobj) $frame_code_cname = (PyCodeObject*) codeobj; #ifdef WITH_THREAD #define __Pyx_TraceCall(funcname, srcfile, firstlineno, nogil, goto_error) \ if (nogil) { \ if (CYTHON_TRACE_NOGIL) { \ PyThreadState *tstate; \ PyGILState_STATE state = PyGILState_Ensure(); \ tstate = PyThreadState_GET(); \ if (unlikely(tstate->use_tracing) && !tstate->tracing && \ (tstate->c_profilefunc || (CYTHON_TRACE && tstate->c_tracefunc))) { \ __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&$frame_code_cname, &$frame_cname, funcname, srcfile, firstlineno); \ } \ PyGILState_Release(state); \ if (unlikely(__Pyx_use_tracing < 0)) goto_error; \ } \ } else { \ PyThreadState* tstate = PyThreadState_GET(); \ if (unlikely(tstate->use_tracing) && !tstate->tracing && \ (tstate->c_profilefunc || (CYTHON_TRACE && tstate->c_tracefunc))) { \ __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&$frame_code_cname, &$frame_cname, funcname, srcfile, firstlineno); \ if (unlikely(__Pyx_use_tracing < 0)) goto_error; \ } \ } #else #define __Pyx_TraceCall(funcname, srcfile, firstlineno, nogil, goto_error) \ { PyThreadState* tstate = PyThreadState_GET(); \ if (unlikely(tstate->use_tracing) && !tstate->tracing && \ (tstate->c_profilefunc || (CYTHON_TRACE && tstate->c_tracefunc))) { \ __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&$frame_code_cname, &$frame_cname, funcname, srcfile, firstlineno); \ if (unlikely(__Pyx_use_tracing < 0)) goto_error; \ } \ } #endif #define __Pyx_TraceException() \ if (likely(!__Pyx_use_tracing)); else { \ PyThreadState* tstate = PyThreadState_GET(); \ if (tstate->use_tracing && \ (tstate->c_profilefunc || (CYTHON_TRACE && tstate->c_tracefunc))) { \ tstate->tracing++; \ tstate->use_tracing = 0; \ PyObject *exc_info = __Pyx_GetExceptionTuple(); \ if (exc_info) { \ if (CYTHON_TRACE && tstate->c_tracefunc) \ tstate->c_tracefunc( \ tstate->c_traceobj, $frame_cname, PyTrace_EXCEPTION, exc_info); \ tstate->c_profilefunc( \ tstate->c_profileobj, $frame_cname, PyTrace_EXCEPTION, exc_info); \ Py_DECREF(exc_info); \ } \ tstate->use_tracing = 1; \ tstate->tracing--; \ } \ } static void __Pyx_call_return_trace_func(PyThreadState *tstate, PyFrameObject *frame, PyObject *result) { PyObject *type, *value, *traceback; PyErr_Fetch(&type, &value, &traceback); tstate->tracing++; tstate->use_tracing = 0; if (CYTHON_TRACE && tstate->c_tracefunc) tstate->c_tracefunc(tstate->c_traceobj, frame, PyTrace_RETURN, result); if (tstate->c_profilefunc) tstate->c_profilefunc(tstate->c_profileobj, frame, PyTrace_RETURN, result); CYTHON_FRAME_DEL(frame); tstate->use_tracing = 1; tstate->tracing--; PyErr_Restore(type, value, traceback); } #ifdef WITH_THREAD #define __Pyx_TraceReturn(result, nogil) \ if (likely(!__Pyx_use_tracing)); else { \ if (nogil) { \ if (CYTHON_TRACE_NOGIL) { \ PyThreadState *tstate; \ PyGILState_STATE state = PyGILState_Ensure(); \ tstate = PyThreadState_GET(); \ if (tstate->use_tracing) { \ __Pyx_call_return_trace_func(tstate, $frame_cname, (PyObject*)result); \ } \ PyGILState_Release(state); \ } \ } else { \ PyThreadState* tstate = PyThreadState_GET(); \ if (tstate->use_tracing) { \ __Pyx_call_return_trace_func(tstate, $frame_cname, (PyObject*)result); \ } \ } \ } #else #define __Pyx_TraceReturn(result, nogil) \ if (likely(!__Pyx_use_tracing)); else { \ PyThreadState* tstate = PyThreadState_GET(); \ if (tstate->use_tracing) { \ __Pyx_call_return_trace_func(tstate, $frame_cname, (PyObject*)result); \ } \ } #endif static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/ static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/ #else #define __Pyx_TraceDeclarations #define __Pyx_TraceFrameInit(codeobj) // mark error label as used to avoid compiler warnings #define __Pyx_TraceCall(funcname, srcfile, firstlineno, nogil, goto_error) if (1); else goto_error; #define __Pyx_TraceException() #define __Pyx_TraceReturn(result, nogil) #endif /* CYTHON_PROFILE */ #if CYTHON_TRACE // see call_trace_protected() in CPython's ceval.c static int __Pyx_call_line_trace_func(PyThreadState *tstate, PyFrameObject *frame, int lineno) { int ret; PyObject *type, *value, *traceback; PyErr_Fetch(&type, &value, &traceback); frame->f_lineno = lineno; tstate->tracing++; tstate->use_tracing = 0; ret = tstate->c_tracefunc(tstate->c_traceobj, frame, PyTrace_LINE, NULL); tstate->use_tracing = 1; tstate->tracing--; if (likely(!ret)) { PyErr_Restore(type, value, traceback); } else { Py_XDECREF(type); Py_XDECREF(value); Py_XDECREF(traceback); } return ret; } #ifdef WITH_THREAD #define __Pyx_TraceLine(lineno, nogil, goto_error) \ if (likely(!__Pyx_use_tracing)); else { \ if (nogil) { \ if (CYTHON_TRACE_NOGIL) { \ int ret = 0; \ PyThreadState *tstate; \ PyGILState_STATE state = PyGILState_Ensure(); \ tstate = PyThreadState_GET(); \ if (unlikely(tstate->use_tracing && tstate->c_tracefunc)) { \ ret = __Pyx_call_line_trace_func(tstate, $frame_cname, lineno); \ } \ PyGILState_Release(state); \ if (unlikely(ret)) goto_error; \ } \ } else { \ PyThreadState* tstate = PyThreadState_GET(); \ if (unlikely(tstate->use_tracing && tstate->c_tracefunc)) { \ int ret = __Pyx_call_line_trace_func(tstate, $frame_cname, lineno); \ if (unlikely(ret)) goto_error; \ } \ } \ } #else #define __Pyx_TraceLine(lineno, nogil, goto_error) \ if (likely(!__Pyx_use_tracing)); else { \ PyThreadState* tstate = PyThreadState_GET(); \ if (unlikely(tstate->use_tracing && tstate->c_tracefunc)) { \ int ret = __Pyx_call_line_trace_func(tstate, $frame_cname, lineno); \ if (unlikely(ret)) goto_error; \ } \ } #endif #else // mark error label as used to avoid compiler warnings #define __Pyx_TraceLine(lineno, nogil, goto_error) if (1); else goto_error; #endif /////////////// Profile /////////////// //@substitute: naming #if CYTHON_PROFILE static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno) { PyObject *type, *value, *traceback; int retval; PyThreadState* tstate = PyThreadState_GET(); if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) { if (*code == NULL) { *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno); if (*code == NULL) return 0; } *frame = PyFrame_New( tstate, /*PyThreadState *tstate*/ *code, /*PyCodeObject *code*/ $moddict_cname, /*PyObject *globals*/ 0 /*PyObject *locals*/ ); if (*frame == NULL) return 0; if (CYTHON_TRACE && (*frame)->f_trace == NULL) { // this enables "f_lineno" lookup, at least in CPython ... Py_INCREF(Py_None); (*frame)->f_trace = Py_None; } #if PY_VERSION_HEX < 0x030400B1 } else { (*frame)->f_tstate = tstate; #endif } (*frame)->f_lineno = firstlineno; retval = 1; tstate->tracing++; tstate->use_tracing = 0; PyErr_Fetch(&type, &value, &traceback); #if CYTHON_TRACE if (tstate->c_tracefunc) retval = tstate->c_tracefunc(tstate->c_traceobj, *frame, PyTrace_CALL, NULL) == 0; if (retval && tstate->c_profilefunc) #endif retval = tstate->c_profilefunc(tstate->c_profileobj, *frame, PyTrace_CALL, NULL) == 0; tstate->use_tracing = (tstate->c_profilefunc || (CYTHON_TRACE && tstate->c_tracefunc)); tstate->tracing--; if (retval) { PyErr_Restore(type, value, traceback); return tstate->use_tracing && retval; } else { Py_XDECREF(type); Py_XDECREF(value); Py_XDECREF(traceback); return -1; } } static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) { PyObject *py_srcfile = 0; PyObject *py_funcname = 0; PyCodeObject *py_code = 0; #if PY_MAJOR_VERSION < 3 py_funcname = PyString_FromString(funcname); py_srcfile = PyString_FromString(srcfile); #else py_funcname = PyUnicode_FromString(funcname); py_srcfile = PyUnicode_FromString(srcfile); #endif if (!py_funcname | !py_srcfile) goto bad; py_code = PyCode_New( 0, /*int argcount,*/ #if PY_MAJOR_VERSION >= 3 0, /*int kwonlyargcount,*/ #endif 0, /*int nlocals,*/ 0, /*int stacksize,*/ 0, /*int flags,*/ $empty_bytes, /*PyObject *code,*/ $empty_tuple, /*PyObject *consts,*/ $empty_tuple, /*PyObject *names,*/ $empty_tuple, /*PyObject *varnames,*/ $empty_tuple, /*PyObject *freevars,*/ $empty_tuple, /*PyObject *cellvars,*/ py_srcfile, /*PyObject *filename,*/ py_funcname, /*PyObject *name,*/ firstlineno, /*int firstlineno,*/ $empty_bytes /*PyObject *lnotab*/ ); bad: Py_XDECREF(py_srcfile); Py_XDECREF(py_funcname); return py_code; } #endif /* CYTHON_PROFILE */ Cython-0.23.4/Cython/Utility/Printing.c0000644000175600017570000001175712606202452021064 0ustar jenkinsjenkins00000000000000////////////////////// Print.proto ////////////////////// //@substitute: naming static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/ #if CYTHON_COMPILING_IN_PYPY || PY_MAJOR_VERSION >= 3 static PyObject* $print_function = 0; static PyObject* $print_function_kwargs = 0; #endif ////////////////////// Print.cleanup ////////////////////// //@substitute: naming #if CYTHON_COMPILING_IN_PYPY || PY_MAJOR_VERSION >= 3 Py_CLEAR($print_function); Py_CLEAR($print_function_kwargs); #endif ////////////////////// Print ////////////////////// //@substitute: naming #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION < 3 static PyObject *__Pyx_GetStdout(void) { PyObject *f = PySys_GetObject((char *)"stdout"); if (!f) { PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); } return f; } static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) { int i; if (!f) { if (!(f = __Pyx_GetStdout())) return -1; } Py_INCREF(f); for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) { PyObject* v; if (PyFile_SoftSpace(f, 1)) { if (PyFile_WriteString(" ", f) < 0) goto error; } v = PyTuple_GET_ITEM(arg_tuple, i); if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0) goto error; if (PyString_Check(v)) { char *s = PyString_AsString(v); Py_ssize_t len = PyString_Size(v); if (len > 0) { // append soft-space if necessary (not using isspace() due to C/C++ problem on MacOS-X) switch (s[len-1]) { case ' ': break; case '\f': case '\r': case '\n': case '\t': case '\v': PyFile_SoftSpace(f, 0); break; default: break; } } } } if (newline) { if (PyFile_WriteString("\n", f) < 0) goto error; PyFile_SoftSpace(f, 0); } Py_DECREF(f); return 0; error: Py_DECREF(f); return -1; } #else /* Python 3 has a print function */ static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) { PyObject* kwargs = 0; PyObject* result = 0; PyObject* end_string; if (unlikely(!$print_function)) { $print_function = PyObject_GetAttr($builtins_cname, PYIDENT("print")); if (!$print_function) return -1; } if (stream) { kwargs = PyDict_New(); if (unlikely(!kwargs)) return -1; if (unlikely(PyDict_SetItem(kwargs, PYIDENT("file"), stream) < 0)) goto bad; if (!newline) { end_string = PyUnicode_FromStringAndSize(" ", 1); if (unlikely(!end_string)) goto bad; if (PyDict_SetItem(kwargs, PYIDENT("end"), end_string) < 0) { Py_DECREF(end_string); goto bad; } Py_DECREF(end_string); } } else if (!newline) { if (unlikely(!$print_function_kwargs)) { $print_function_kwargs = PyDict_New(); if (unlikely(!$print_function_kwargs)) return -1; end_string = PyUnicode_FromStringAndSize(" ", 1); if (unlikely(!end_string)) return -1; if (PyDict_SetItem($print_function_kwargs, PYIDENT("end"), end_string) < 0) { Py_DECREF(end_string); return -1; } Py_DECREF(end_string); } kwargs = $print_function_kwargs; } result = PyObject_Call($print_function, arg_tuple, kwargs); if (unlikely(kwargs) && (kwargs != $print_function_kwargs)) Py_DECREF(kwargs); if (!result) return -1; Py_DECREF(result); return 0; bad: if (kwargs != $print_function_kwargs) Py_XDECREF(kwargs); return -1; } #endif ////////////////////// PrintOne.proto ////////////////////// //@requires: Print static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/ ////////////////////// PrintOne ////////////////////// #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION < 3 static int __Pyx_PrintOne(PyObject* f, PyObject *o) { if (!f) { if (!(f = __Pyx_GetStdout())) return -1; } Py_INCREF(f); if (PyFile_SoftSpace(f, 0)) { if (PyFile_WriteString(" ", f) < 0) goto error; } if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0) goto error; if (PyFile_WriteString("\n", f) < 0) goto error; Py_DECREF(f); return 0; error: Py_DECREF(f); return -1; /* the line below is just to avoid C compiler * warnings about unused functions */ return __Pyx_Print(f, NULL, 0); } #else /* Python 3 has a print function */ static int __Pyx_PrintOne(PyObject* stream, PyObject *o) { int res; PyObject* arg_tuple = PyTuple_Pack(1, o); if (unlikely(!arg_tuple)) return -1; res = __Pyx_Print(stream, arg_tuple, 1); Py_DECREF(arg_tuple); return res; } #endif Cython-0.23.4/Cython/Utility/Overflow.c0000644000175600017570000002706712606202452021076 0ustar jenkinsjenkins00000000000000/* These functions provide integer arithmetic with integer checking. They do not actually raise an exception when an overflow is detected, but rather set a bit in the overflow parameter. (This parameter may be re-used accross several arithmetic operations, so should be or-ed rather than assigned to.) The implementation is divided into two parts, the signed and unsigned basecases, which is where the magic happens, and a generic template matching a specific type to an implementation based on its (c-compile-time) size and signedness. When possible, branching is avoided, and preference is given to speed over accuracy (a low rate of falsely "detected" overflows are acceptable, undetected overflows are not). TODO: Hook up checking. TODO: Conditionally support 128-bit with intmax_t? */ /////////////// Common.proto /////////////// static int __Pyx_check_twos_complement(void) { if (-1 != ~0) { PyErr_SetString(PyExc_RuntimeError, "Two's complement required for overflow checks."); return 1; } else if (sizeof(short) == sizeof(int)) { PyErr_SetString(PyExc_RuntimeError, "sizeof(short) < sizeof(int) required for overflow checks."); return 1; } else { return 0; } } #define __PYX_IS_UNSIGNED(type) (((type) -1) > 0) #define __PYX_SIGN_BIT(type) (((unsigned type) 1) << (sizeof(type) * 8 - 1)) #define __PYX_HALF_MAX(type) (((type) 1) << (sizeof(type) * 8 - 2)) #define __PYX_MIN(type) (__PYX_IS_UNSIGNED(type) ? (type) 0 : 0 - __PYX_HALF_MAX(type) - __PYX_HALF_MAX(type)) #define __PYX_MAX(type) (~__PYX_MIN(type)) #define __Pyx_add_no_overflow(a, b, overflow) ((a) + (b)) #define __Pyx_add_const_no_overflow(a, b, overflow) ((a) + (b)) #define __Pyx_sub_no_overflow(a, b, overflow) ((a) - (b)) #define __Pyx_sub_const_no_overflow(a, b, overflow) ((a) - (b)) #define __Pyx_mul_no_overflow(a, b, overflow) ((a) * (b)) #define __Pyx_mul_const_no_overflow(a, b, overflow) ((a) * (b)) #define __Pyx_div_no_overflow(a, b, overflow) ((a) / (b)) #define __Pyx_div_const_no_overflow(a, b, overflow) ((a) / (b)) /////////////// Common.init /////////////// __Pyx_check_twos_complement(); /////////////// BaseCaseUnsigned.proto /////////////// static CYTHON_INLINE {{UINT}} __Pyx_add_{{NAME}}_checking_overflow({{UINT}} a, {{UINT}} b, int *overflow); static CYTHON_INLINE {{UINT}} __Pyx_sub_{{NAME}}_checking_overflow({{UINT}} a, {{UINT}} b, int *overflow); static CYTHON_INLINE {{UINT}} __Pyx_mul_{{NAME}}_checking_overflow({{UINT}} a, {{UINT}} b, int *overflow); static CYTHON_INLINE {{UINT}} __Pyx_div_{{NAME}}_checking_overflow({{UINT}} a, {{UINT}} b, int *overflow); // Use these when b is known at compile time. #define __Pyx_add_const_{{NAME}}_checking_overflow __Pyx_add_{{NAME}}_checking_overflow #define __Pyx_sub_const_{{NAME}}_checking_overflow __Pyx_sub_{{NAME}}_checking_overflow static CYTHON_INLINE {{UINT}} __Pyx_mul_const_{{NAME}}_checking_overflow({{UINT}} a, {{UINT}} constant, int *overflow); #define __Pyx_div_const_{{NAME}}_checking_overflow __Pyx_div_{{NAME}}_checking_overflow /////////////// BaseCaseUnsigned /////////////// static CYTHON_INLINE {{UINT}} __Pyx_add_{{NAME}}_checking_overflow({{UINT}} a, {{UINT}} b, int *overflow) { {{UINT}} r = a + b; *overflow |= r < a; return r; } static CYTHON_INLINE {{UINT}} __Pyx_sub_{{NAME}}_checking_overflow({{UINT}} a, {{UINT}} b, int *overflow) { {{UINT}} r = a - b; *overflow |= r > a; return r; } static CYTHON_INLINE {{UINT}} __Pyx_mul_{{NAME}}_checking_overflow({{UINT}} a, {{UINT}} b, int *overflow) { if (sizeof({{UINT}}) < sizeof(unsigned long)) { unsigned long big_r = ((unsigned long) a) * ((unsigned long) b); {{UINT}} r = ({{UINT}}) big_r; *overflow |= big_r != r; return r; } else if (sizeof({{UINT}}) < sizeof(unsigned PY_LONG_LONG)) { unsigned PY_LONG_LONG big_r = ((unsigned PY_LONG_LONG) a) * ((unsigned PY_LONG_LONG) b); {{UINT}} r = ({{UINT}}) big_r; *overflow |= big_r != r; return r; } else { {{UINT}} prod = a * b; double dprod = ((double) a) * ((double) b); // Overflow results in an error of at least 2^sizeof(UINT), // whereas rounding represents an error on the order of 2^(sizeof(UINT)-53). *overflow |= fabs(dprod - prod) > (__PYX_MAX({{UINT}}) / 2); return prod; } } static CYTHON_INLINE {{UINT}} __Pyx_mul_const_{{NAME}}_checking_overflow({{UINT}} a, {{UINT}} b, int *overflow) { if (b > 1) { *overflow |= a > __PYX_MAX({{UINT}}) / b; } return a * b; } static CYTHON_INLINE {{UINT}} __Pyx_div_{{NAME}}_checking_overflow({{UINT}} a, {{UINT}} b, int *overflow) { if (b == 0) { *overflow |= 1; return 0; } return a / b; } /////////////// BaseCaseSigned.proto /////////////// static CYTHON_INLINE {{INT}} __Pyx_add_{{NAME}}_checking_overflow({{INT}} a, {{INT}} b, int *overflow); static CYTHON_INLINE {{INT}} __Pyx_sub_{{NAME}}_checking_overflow({{INT}} a, {{INT}} b, int *overflow); static CYTHON_INLINE {{INT}} __Pyx_mul_{{NAME}}_checking_overflow({{INT}} a, {{INT}} b, int *overflow); static CYTHON_INLINE {{INT}} __Pyx_div_{{NAME}}_checking_overflow({{INT}} a, {{INT}} b, int *overflow); // Use when b is known at compile time. static CYTHON_INLINE {{INT}} __Pyx_add_const_{{NAME}}_checking_overflow({{INT}} a, {{INT}} b, int *overflow); static CYTHON_INLINE {{INT}} __Pyx_sub_const_{{NAME}}_checking_overflow({{INT}} a, {{INT}} b, int *overflow); static CYTHON_INLINE {{INT}} __Pyx_mul_const_{{NAME}}_checking_overflow({{INT}} a, {{INT}} constant, int *overflow); #define __Pyx_div_const_{{NAME}}_checking_overflow __Pyx_div_{{NAME}}_checking_overflow /////////////// BaseCaseSigned /////////////// static CYTHON_INLINE {{INT}} __Pyx_add_{{NAME}}_checking_overflow({{INT}} a, {{INT}} b, int *overflow) { if (sizeof({{INT}}) < sizeof(long)) { long big_r = ((long) a) + ((long) b); {{INT}} r = ({{INT}}) big_r; *overflow |= big_r != r; return r; } else if (sizeof({{INT}}) < sizeof(PY_LONG_LONG)) { PY_LONG_LONG big_r = ((PY_LONG_LONG) a) + ((PY_LONG_LONG) b); {{INT}} r = ({{INT}}) big_r; *overflow |= big_r != r; return r; } else { // Signed overflow undefined, but unsigned overflow is well defined. {{INT}} r = ({{INT}}) ((unsigned {{INT}}) a + (unsigned {{INT}}) b); // Overflow happened if the operands have the same sign, but the result // has opposite sign. // sign(a) == sign(b) != sign(r) {{INT}} sign_a = __PYX_SIGN_BIT({{INT}}) & a; {{INT}} sign_b = __PYX_SIGN_BIT({{INT}}) & b; {{INT}} sign_r = __PYX_SIGN_BIT({{INT}}) & r; *overflow |= (sign_a == sign_b) & (sign_a != sign_r); return r; } } static CYTHON_INLINE {{INT}} __Pyx_add_const_{{NAME}}_checking_overflow({{INT}} a, {{INT}} b, int *overflow) { if (b > 0) { *overflow |= a > __PYX_MAX({{INT}}) - b; } else if (b < 0) { *overflow |= a < __PYX_MIN({{INT}}) - b; } return a + b; } static CYTHON_INLINE {{INT}} __Pyx_sub_{{NAME}}_checking_overflow({{INT}} a, {{INT}} b, int *overflow) { *overflow |= b == __PYX_MIN({{INT}}); return __Pyx_add_{{NAME}}_checking_overflow(a, -b, overflow); } static CYTHON_INLINE {{INT}} __Pyx_sub_const_{{NAME}}_checking_overflow({{INT}} a, {{INT}} b, int *overflow) { *overflow |= b == __PYX_MIN({{INT}}); return __Pyx_add_const_{{NAME}}_checking_overflow(a, -b, overflow); } static CYTHON_INLINE {{INT}} __Pyx_mul_{{NAME}}_checking_overflow({{INT}} a, {{INT}} b, int *overflow) { if (sizeof({{INT}}) < sizeof(long)) { long big_r = ((long) a) * ((long) b); {{INT}} r = ({{INT}}) big_r; *overflow |= big_r != r; return ({{INT}}) r; } else if (sizeof({{INT}}) < sizeof(PY_LONG_LONG)) { PY_LONG_LONG big_r = ((PY_LONG_LONG) a) * ((PY_LONG_LONG) b); {{INT}} r = ({{INT}}) big_r; *overflow |= big_r != r; return ({{INT}}) r; } else { {{INT}} prod = a * b; double dprod = ((double) a) * ((double) b); // Overflow results in an error of at least 2^sizeof(INT), // whereas rounding represents an error on the order of 2^(sizeof(INT)-53). *overflow |= fabs(dprod - prod) > (__PYX_MAX({{INT}}) / 2); return prod; } } static CYTHON_INLINE {{INT}} __Pyx_mul_const_{{NAME}}_checking_overflow({{INT}} a, {{INT}} b, int *overflow) { if (b > 1) { *overflow |= a > __PYX_MAX({{INT}}) / b; *overflow |= a < __PYX_MIN({{INT}}) / b; } else if (b == -1) { *overflow |= a == __PYX_MIN({{INT}}); } else if (b < -1) { *overflow |= a > __PYX_MIN({{INT}}) / b; *overflow |= a < __PYX_MAX({{INT}}) / b; } return a * b; } static CYTHON_INLINE {{INT}} __Pyx_div_{{NAME}}_checking_overflow({{INT}} a, {{INT}} b, int *overflow) { if (b == 0) { *overflow |= 1; return 0; } *overflow |= (a == __PYX_MIN({{INT}})) & (b == -1); return a / b; } /////////////// SizeCheck.init /////////////// __Pyx_check_sane_{{NAME}}(); /////////////// SizeCheck.proto /////////////// static int __Pyx_check_sane_{{NAME}}(void) { if (sizeof({{TYPE}}) <= sizeof(int) || sizeof({{TYPE}}) == sizeof(long) || sizeof({{TYPE}}) == sizeof(PY_LONG_LONG)) { return 0; } else { PyErr_Format(PyExc_RuntimeError, \ "Bad size for int type %.{{max(60, len(TYPE))}}s: %d", "{{TYPE}}", (int) sizeof({{TYPE}})); return 1; } } /////////////// Binop.proto /////////////// static CYTHON_INLINE {{TYPE}} __Pyx_{{BINOP}}_{{NAME}}_checking_overflow({{TYPE}} a, {{TYPE}} b, int *overflow); /////////////// Binop /////////////// static CYTHON_INLINE {{TYPE}} __Pyx_{{BINOP}}_{{NAME}}_checking_overflow({{TYPE}} a, {{TYPE}} b, int *overflow) { if (sizeof({{TYPE}}) < sizeof(int)) { return __Pyx_{{BINOP}}_no_overflow(a, b, overflow); } else if (__PYX_IS_UNSIGNED({{TYPE}})) { if (sizeof({{TYPE}}) == sizeof(unsigned int)) { return __Pyx_{{BINOP}}_unsigned_int_checking_overflow(a, b, overflow); } else if (sizeof({{TYPE}}) == sizeof(unsigned long)) { return __Pyx_{{BINOP}}_unsigned_long_checking_overflow(a, b, overflow); } else if (sizeof({{TYPE}}) == sizeof(unsigned PY_LONG_LONG)) { return __Pyx_{{BINOP}}_unsigned_long_long_checking_overflow(a, b, overflow); } else { abort(); return 0; // handled elsewhere } } else { if (sizeof({{TYPE}}) == sizeof(int)) { return __Pyx_{{BINOP}}_int_checking_overflow(a, b, overflow); } else if (sizeof({{TYPE}}) == sizeof(long)) { return __Pyx_{{BINOP}}_long_checking_overflow(a, b, overflow); } else if (sizeof({{TYPE}}) == sizeof(PY_LONG_LONG)) { return __Pyx_{{BINOP}}_long_long_checking_overflow(a, b, overflow); } else { abort(); return 0; // handled elsewhere } } } /////////////// LeftShift.proto /////////////// static CYTHON_INLINE {{TYPE}} __Pyx_lshift_{{NAME}}_checking_overflow({{TYPE}} a, {{TYPE}} b, int *overflow) { *overflow |= #if {{SIGNED}} (b < 0) | #endif (b > ({{TYPE}}) (8 * sizeof({{TYPE}}))) | (a > (__PYX_MAX({{TYPE}}) >> b)); return a << b; } #define __Pyx_lshift_const_{{NAME}}_checking_overflow __Pyx_lshift_{{NAME}}_checking_overflow /////////////// UnaryNegOverflows.proto /////////////// //FIXME: shouldn't the macro name be prefixed by "__Pyx_" ? Too late now, I guess... // from intobject.c #define UNARY_NEG_WOULD_OVERFLOW(x) \ (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x))) Cython-0.23.4/Cython/Utility/Optimize.c0000644000175600017570000007417512606202452021075 0ustar jenkinsjenkins00000000000000/* * Optional optimisations of built-in functions and methods. * * Required replacements of builtins are in Builtins.c. * * General object operations and protocols are in ObjectHandling.c. */ /////////////// append.proto /////////////// static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x); /*proto*/ /////////////// append /////////////// //@requires: ListAppend //@requires: ObjectHandling.c::PyObjectCallMethod1 static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x) { if (likely(PyList_CheckExact(L))) { if (unlikely(__Pyx_PyList_Append(L, x) < 0)) return -1; } else { PyObject* retval = __Pyx_PyObject_CallMethod1(L, PYIDENT("append"), x); if (unlikely(!retval)) return -1; Py_DECREF(retval); } return 0; } /////////////// ListAppend.proto /////////////// #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) { PyListObject* L = (PyListObject*) list; Py_ssize_t len = Py_SIZE(list); if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) { Py_INCREF(x); PyList_SET_ITEM(list, len, x); Py_SIZE(list) = len+1; return 0; } return PyList_Append(list, x); } #else #define __Pyx_PyList_Append(L,x) PyList_Append(L,x) #endif /////////////// ListCompAppend.proto /////////////// #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) { PyListObject* L = (PyListObject*) list; Py_ssize_t len = Py_SIZE(list); if (likely(L->allocated > len)) { Py_INCREF(x); PyList_SET_ITEM(list, len, x); Py_SIZE(list) = len+1; return 0; } return PyList_Append(list, x); } #else #define __Pyx_ListComp_Append(L,x) PyList_Append(L,x) #endif //////////////////// ListExtend.proto //////////////////// static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) { #if CYTHON_COMPILING_IN_CPYTHON PyObject* none = _PyList_Extend((PyListObject*)L, v); if (unlikely(!none)) return -1; Py_DECREF(none); return 0; #else return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v); #endif } /////////////// pop.proto /////////////// static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L); /*proto*/ #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyList_Pop(PyObject* L); /*proto*/ #define __Pyx_PyObject_Pop(L) (likely(PyList_CheckExact(L)) ? \ __Pyx_PyList_Pop(L) : __Pyx__PyObject_Pop(L)) #else #define __Pyx_PyList_Pop(L) __Pyx__PyObject_Pop(L) #define __Pyx_PyObject_Pop(L) __Pyx__PyObject_Pop(L) #endif /////////////// pop /////////////// //@requires: ObjectHandling.c::PyObjectCallMethod0 static CYTHON_INLINE PyObject* __Pyx__PyObject_Pop(PyObject* L) { #if CYTHON_COMPILING_IN_CPYTHON if (Py_TYPE(L) == &PySet_Type) { return PySet_Pop(L); } #endif return __Pyx_PyObject_CallMethod0(L, PYIDENT("pop")); } #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyList_Pop(PyObject* L) { /* Check that both the size is positive and no reallocation shrinking needs to be done. */ if (likely(PyList_GET_SIZE(L) > (((PyListObject*)L)->allocated >> 1))) { Py_SIZE(L) -= 1; return PyList_GET_ITEM(L, PyList_GET_SIZE(L)); } return CALL_UNBOUND_METHOD(PyList_Type, "pop", L); } #endif /////////////// pop_index.proto /////////////// static PyObject* __Pyx__PyObject_PopNewIndex(PyObject* L, PyObject* py_ix); /*proto*/ static PyObject* __Pyx__PyObject_PopIndex(PyObject* L, PyObject* py_ix); /*proto*/ #if CYTHON_COMPILING_IN_CPYTHON static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t ix); /*proto*/ #define __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) ( \ (likely(PyList_CheckExact(L) && __Pyx_fits_Py_ssize_t(ix, type, is_signed))) ? \ __Pyx__PyList_PopIndex(L, py_ix, ix) : ( \ (unlikely(py_ix == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) : \ __Pyx__PyObject_PopIndex(L, py_ix))) #define __Pyx_PyList_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) ( \ __Pyx_fits_Py_ssize_t(ix, type, is_signed) ? \ __Pyx__PyList_PopIndex(L, py_ix, ix) : ( \ (unlikely(py_ix == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) : \ __Pyx__PyObject_PopIndex(L, py_ix))) #else #define __Pyx_PyList_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) \ __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) #define __Pyx_PyObject_PopIndex(L, py_ix, ix, is_signed, type, to_py_func) ( \ (unlikely(py_ix == Py_None)) ? __Pyx__PyObject_PopNewIndex(L, to_py_func(ix)) : \ __Pyx__PyObject_PopIndex(L, py_ix)) #endif /////////////// pop_index /////////////// //@requires: ObjectHandling.c::PyObjectCallMethod1 static PyObject* __Pyx__PyObject_PopNewIndex(PyObject* L, PyObject* py_ix) { PyObject *r; if (unlikely(!py_ix)) return NULL; r = __Pyx__PyObject_PopIndex(L, py_ix); Py_DECREF(py_ix); return r; } static PyObject* __Pyx__PyObject_PopIndex(PyObject* L, PyObject* py_ix) { return __Pyx_PyObject_CallMethod1(L, PYIDENT("pop"), py_ix); } #if CYTHON_COMPILING_IN_CPYTHON static PyObject* __Pyx__PyList_PopIndex(PyObject* L, PyObject* py_ix, Py_ssize_t ix) { Py_ssize_t size = PyList_GET_SIZE(L); if (likely(size > (((PyListObject*)L)->allocated >> 1))) { Py_ssize_t cix = ix; if (cix < 0) { cix += size; } if (likely(0 <= cix && cix < size)) { PyObject* v = PyList_GET_ITEM(L, cix); Py_SIZE(L) -= 1; size -= 1; memmove(&PyList_GET_ITEM(L, cix), &PyList_GET_ITEM(L, cix+1), (size_t)(size-cix)*sizeof(PyObject*)); return v; } } if (py_ix == Py_None) { return __Pyx__PyObject_PopNewIndex(L, PyInt_FromSsize_t(ix)); } else { return __Pyx__PyObject_PopIndex(L, py_ix); } } #endif /////////////// dict_getitem_default.proto /////////////// static PyObject* __Pyx_PyDict_GetItemDefault(PyObject* d, PyObject* key, PyObject* default_value); /*proto*/ /////////////// dict_getitem_default /////////////// static PyObject* __Pyx_PyDict_GetItemDefault(PyObject* d, PyObject* key, PyObject* default_value) { PyObject* value; #if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY value = PyDict_GetItemWithError(d, key); if (unlikely(!value)) { if (unlikely(PyErr_Occurred())) return NULL; value = default_value; } Py_INCREF(value); #else if (PyString_CheckExact(key) || PyUnicode_CheckExact(key) || PyInt_CheckExact(key)) { /* these presumably have safe hash functions */ value = PyDict_GetItem(d, key); if (unlikely(!value)) { value = default_value; } Py_INCREF(value); } else { if (default_value == Py_None) default_value = NULL; value = PyObject_CallMethodObjArgs( d, PYIDENT("get"), key, default_value, NULL); } #endif return value; } /////////////// dict_setdefault.proto /////////////// static CYTHON_INLINE PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value, int is_safe_type); /*proto*/ /////////////// dict_setdefault /////////////// //@requires: ObjectHandling.c::PyObjectCallMethod2 static CYTHON_INLINE PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value, CYTHON_UNUSED int is_safe_type) { PyObject* value; #if PY_VERSION_HEX >= 0x030400A0 // we keep the method call at the end to avoid "unused" C compiler warnings if (1) { value = PyDict_SetDefault(d, key, default_value); if (unlikely(!value)) return NULL; Py_INCREF(value); #else if (is_safe_type == 1 || (is_safe_type == -1 && /* the following builtins presumably have repeatably safe and fast hash functions */ #if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY (PyUnicode_CheckExact(key) || PyString_CheckExact(key) || PyLong_CheckExact(key)))) { value = PyDict_GetItemWithError(d, key); if (unlikely(!value)) { if (unlikely(PyErr_Occurred())) return NULL; if (unlikely(PyDict_SetItem(d, key, default_value) == -1)) return NULL; value = default_value; } Py_INCREF(value); #else (PyString_CheckExact(key) || PyUnicode_CheckExact(key) || PyInt_CheckExact(key) || PyLong_CheckExact(key)))) { value = PyDict_GetItem(d, key); if (unlikely(!value)) { if (unlikely(PyDict_SetItem(d, key, default_value) == -1)) return NULL; value = default_value; } Py_INCREF(value); #endif #endif } else { value = __Pyx_PyObject_CallMethod2(d, PYIDENT("setdefault"), key, default_value); } return value; } /////////////// py_dict_clear.proto /////////////// #define __Pyx_PyDict_Clear(d) (PyDict_Clear(d), 0) /////////////// dict_iter.proto /////////////// static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* dict, int is_dict, PyObject* method_name, Py_ssize_t* p_orig_length, int* p_is_dict); static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* dict_or_iter, Py_ssize_t orig_length, Py_ssize_t* ppos, PyObject** pkey, PyObject** pvalue, PyObject** pitem, int is_dict); /////////////// dict_iter /////////////// //@requires: ObjectHandling.c::UnpackTuple2 //@requires: ObjectHandling.c::IterFinish //@requires: ObjectHandling.c::PyObjectCallMethod0 static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* iterable, int is_dict, PyObject* method_name, Py_ssize_t* p_orig_length, int* p_source_is_dict) { is_dict = is_dict || likely(PyDict_CheckExact(iterable)); *p_source_is_dict = is_dict; #if !CYTHON_COMPILING_IN_PYPY if (is_dict) { *p_orig_length = PyDict_Size(iterable); Py_INCREF(iterable); return iterable; } #endif *p_orig_length = 0; if (method_name) { PyObject* iter; iterable = __Pyx_PyObject_CallMethod0(iterable, method_name); if (!iterable) return NULL; #if !CYTHON_COMPILING_IN_PYPY if (PyTuple_CheckExact(iterable) || PyList_CheckExact(iterable)) return iterable; #endif iter = PyObject_GetIter(iterable); Py_DECREF(iterable); return iter; } return PyObject_GetIter(iterable); } static CYTHON_INLINE int __Pyx_dict_iter_next( PyObject* iter_obj, CYTHON_NCP_UNUSED Py_ssize_t orig_length, CYTHON_NCP_UNUSED Py_ssize_t* ppos, PyObject** pkey, PyObject** pvalue, PyObject** pitem, int source_is_dict) { PyObject* next_item; #if !CYTHON_COMPILING_IN_PYPY if (source_is_dict) { PyObject *key, *value; if (unlikely(orig_length != PyDict_Size(iter_obj))) { PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration"); return -1; } if (unlikely(!PyDict_Next(iter_obj, ppos, &key, &value))) { return 0; } if (pitem) { PyObject* tuple = PyTuple_New(2); if (unlikely(!tuple)) { return -1; } Py_INCREF(key); Py_INCREF(value); PyTuple_SET_ITEM(tuple, 0, key); PyTuple_SET_ITEM(tuple, 1, value); *pitem = tuple; } else { if (pkey) { Py_INCREF(key); *pkey = key; } if (pvalue) { Py_INCREF(value); *pvalue = value; } } return 1; } else if (PyTuple_CheckExact(iter_obj)) { Py_ssize_t pos = *ppos; if (unlikely(pos >= PyTuple_GET_SIZE(iter_obj))) return 0; *ppos = pos + 1; next_item = PyTuple_GET_ITEM(iter_obj, pos); Py_INCREF(next_item); } else if (PyList_CheckExact(iter_obj)) { Py_ssize_t pos = *ppos; if (unlikely(pos >= PyList_GET_SIZE(iter_obj))) return 0; *ppos = pos + 1; next_item = PyList_GET_ITEM(iter_obj, pos); Py_INCREF(next_item); } else #endif { next_item = PyIter_Next(iter_obj); if (unlikely(!next_item)) { return __Pyx_IterFinish(); } } if (pitem) { *pitem = next_item; } else if (pkey && pvalue) { if (__Pyx_unpack_tuple2(next_item, pkey, pvalue, source_is_dict, source_is_dict, 1)) return -1; } else if (pkey) { *pkey = next_item; } else { *pvalue = next_item; } return 1; } /////////////// unicode_iter.proto /////////////// static CYTHON_INLINE int __Pyx_init_unicode_iteration( PyObject* ustring, Py_ssize_t *length, void** data, int *kind); /* proto */ /////////////// unicode_iter /////////////// static CYTHON_INLINE int __Pyx_init_unicode_iteration( PyObject* ustring, Py_ssize_t *length, void** data, int *kind) { #if CYTHON_PEP393_ENABLED if (unlikely(__Pyx_PyUnicode_READY(ustring) < 0)) return -1; *kind = PyUnicode_KIND(ustring); *length = PyUnicode_GET_LENGTH(ustring); *data = PyUnicode_DATA(ustring); #else *kind = 0; *length = PyUnicode_GET_SIZE(ustring); *data = (void*)PyUnicode_AS_UNICODE(ustring); #endif return 0; } /////////////// pyobject_as_double.proto /////////////// static double __Pyx__PyObject_AsDouble(PyObject* obj); /* proto */ #if CYTHON_COMPILING_IN_PYPY #define __Pyx_PyObject_AsDouble(obj) \ (likely(PyFloat_CheckExact(obj)) ? PyFloat_AS_DOUBLE(obj) : \ likely(PyInt_CheckExact(obj)) ? \ PyFloat_AsDouble(obj) : __Pyx__PyObject_AsDouble(obj)) #else #define __Pyx_PyObject_AsDouble(obj) \ ((likely(PyFloat_CheckExact(obj))) ? \ PyFloat_AS_DOUBLE(obj) : __Pyx__PyObject_AsDouble(obj)) #endif /////////////// pyobject_as_double /////////////// static double __Pyx__PyObject_AsDouble(PyObject* obj) { PyObject* float_value; #if CYTHON_COMPILING_IN_PYPY float_value = PyNumber_Float(obj); if (0) goto bad; #else PyNumberMethods *nb = Py_TYPE(obj)->tp_as_number; if (likely(nb) && likely(nb->nb_float)) { float_value = nb->nb_float(obj); if (likely(float_value) && unlikely(!PyFloat_Check(float_value))) { PyErr_Format(PyExc_TypeError, "__float__ returned non-float (type %.200s)", Py_TYPE(float_value)->tp_name); Py_DECREF(float_value); goto bad; } } else if (PyUnicode_CheckExact(obj) || PyBytes_CheckExact(obj)) { #if PY_MAJOR_VERSION >= 3 float_value = PyFloat_FromString(obj); #else float_value = PyFloat_FromString(obj, 0); #endif } else { PyObject* args = PyTuple_New(1); if (unlikely(!args)) goto bad; PyTuple_SET_ITEM(args, 0, obj); float_value = PyObject_Call((PyObject*)&PyFloat_Type, args, 0); PyTuple_SET_ITEM(args, 0, 0); Py_DECREF(args); } #endif if (likely(float_value)) { double value = PyFloat_AS_DOUBLE(float_value); Py_DECREF(float_value); return value; } bad: return (double)-1; } /////////////// PyNumberPow2.proto /////////////// #define __Pyx_PyNumber_InPlacePowerOf2(a, b, c) __Pyx__PyNumber_PowerOf2(a, b, c, 1) #define __Pyx_PyNumber_PowerOf2(a, b, c) __Pyx__PyNumber_PowerOf2(a, b, c, 0) static PyObject* __Pyx__PyNumber_PowerOf2(PyObject *two, PyObject *exp, PyObject *none, int inplace); /*proto*/ /////////////// PyNumberPow2 /////////////// //@requires: TypeConversion.c::PyLongInternals static PyObject* __Pyx__PyNumber_PowerOf2(PyObject *two, PyObject *exp, PyObject *none, int inplace) { // in CPython, 1<ob_digit[0]; } else if (size == 0) { return PyInt_FromLong(1L); } else if (unlikely(size < 0)) { goto fallback; } else { shiftby = PyLong_AsSsize_t(exp); } #else shiftby = PyLong_AsSsize_t(exp); #endif } else { goto fallback; } if (likely(shiftby >= 0)) { if ((size_t)shiftby <= sizeof(long) * 8 - 2) { long value = 1L << shiftby; return PyInt_FromLong(value); } else if ((size_t)shiftby <= sizeof(unsigned PY_LONG_LONG) * 8 - 1) { unsigned PY_LONG_LONG value = ((unsigned PY_LONG_LONG)1) << shiftby; return PyLong_FromUnsignedLongLong(value); } else { PyObject *one = PyInt_FromLong(1L); if (unlikely(!one)) return NULL; return PyNumber_Lshift(one, exp); } } else if (shiftby == -1 && PyErr_Occurred()) { PyErr_Clear(); } fallback: #endif return (inplace ? PyNumber_InPlacePower : PyNumber_Power)(two, exp, none); } /////////////// PyIntBinop.proto /////////////// #if CYTHON_COMPILING_IN_CPYTHON static PyObject* __Pyx_PyInt_{{op}}{{order}}(PyObject *op1, PyObject *op2, long intval, int inplace); /*proto*/ #else #define __Pyx_PyInt_{{op}}{{order}}(op1, op2, intval, inplace) \ {{if op in ('Eq', 'Ne')}}PyObject_RichCompare(op1, op2, Py_{{op.upper()}}) {{else}}(inplace ? PyNumber_InPlace{{op}}(op1, op2) : PyNumber_{{op}}(op1, op2)) {{endif}} #endif /////////////// PyIntBinop /////////////// //@requires: TypeConversion.c::PyLongInternals #if CYTHON_COMPILING_IN_CPYTHON {{py: from Cython.Utility import pylong_join }} {{py: pyval, ival = ('op2', 'b') if order == 'CObj' else ('op1', 'a') }} {{py: slot_name = {'TrueDivide': 'true_divide', 'FloorDivide': 'floor_divide'}.get(op, op.lower()) }} {{py: c_op = { 'Add': '+', 'Subtract': '-', 'Remainder': '%', 'TrueDivide': '/', 'FloorDivide': '/', 'Or': '|', 'Xor': '^', 'And': '&', 'Rshift': '>>', 'Eq': '==', 'Ne': '!=', }[op] }} static PyObject* __Pyx_PyInt_{{op}}{{order}}(PyObject *op1, PyObject *op2, CYTHON_UNUSED long intval, CYTHON_UNUSED int inplace) { {{if op in ('Eq', 'Ne')}} if (op1 == op2) { Py_RETURN_{{'TRUE' if op == 'Eq' else 'FALSE'}}; } {{endif}} #if PY_MAJOR_VERSION < 3 if (likely(PyInt_CheckExact({{pyval}}))) { const long {{'a' if order == 'CObj' else 'b'}} = intval; {{if c_op in '+-%' or op == 'FloorDivide'}} long x; {{endif}} long {{ival}} = PyInt_AS_LONG({{pyval}}); {{if op in ('Eq', 'Ne')}} if (a {{c_op}} b) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } {{elif c_op in '+-'}} // adapted from intobject.c in Py2.7: // casts in the line below avoid undefined behaviour on overflow x = (long)((unsigned long)a {{c_op}} b); if (likely((x^a) >= 0 || (x^{{ '~' if op == 'Subtract' else '' }}b) >= 0)) return PyInt_FromLong(x); return PyLong_Type.tp_as_number->nb_{{slot_name}}(op1, op2); {{elif c_op == '%'}} // see ExprNodes.py :: mod_int_utility_code x = a % b; x += ((x != 0) & ((x ^ b) < 0)) * b; return PyInt_FromLong(x); {{elif op == 'TrueDivide'}} if (8 * sizeof(long) <= 53 || likely(labs({{ival}}) <= (1L << 53))) { return PyFloat_FromDouble((double)a / (double)b); } // let Python do the rounding return PyInt_Type.tp_as_number->nb_{{slot_name}}(op1, op2); {{elif op == 'FloorDivide'}} // INT_MIN / -1 is the only case that overflows if (unlikely(b == -1 && ((unsigned long)a) == 0-(unsigned long)a)) return PyInt_Type.tp_as_number->nb_{{slot_name}}(op1, op2); else { long q, r; // see ExprNodes.py :: div_int_utility_code q = a / b; r = a - q*b; q -= ((r != 0) & ((r ^ b) < 0)); x = q; } return PyInt_FromLong(x); {{else}} // other operations are safe, no overflow return PyInt_FromLong(a {{c_op}} b); {{endif}} } #endif #if CYTHON_USE_PYLONG_INTERNALS && PY_MAJOR_VERSION >= 3 if (likely(PyLong_CheckExact({{pyval}}))) { const long {{'a' if order == 'CObj' else 'b'}} = intval; long {{ival}}{{if op not in ('Eq', 'Ne')}}, x{{endif}}; {{if op not in ('Eq', 'Ne', 'TrueDivide')}} const PY_LONG_LONG ll{{'a' if order == 'CObj' else 'b'}} = intval; PY_LONG_LONG ll{{ival}}, llx; {{endif}} const digit* digits = ((PyLongObject*){{pyval}})->ob_digit; const Py_ssize_t size = Py_SIZE({{pyval}}); // handle most common case first to avoid indirect branch and optimise branch prediction if (likely(__Pyx_sst_abs(size) <= 1)) { {{ival}} = likely(size) ? digits[0] : 0; if (size == -1) {{ival}} = -{{ival}}; } else { switch (size) { {{for _size in range(2, 5)}} {{for _case in (-_size, _size)}} case {{_case}}: if (8 * sizeof(long) - 1 > {{_size}} * PyLong_SHIFT{{if op == 'TrueDivide'}} && {{_size-1}} * PyLong_SHIFT < 53{{endif}}) { {{ival}} = {{'-' if _case < 0 else ''}}(long) {{pylong_join(_size, 'digits')}}; break; {{if op not in ('Eq', 'Ne', 'TrueDivide')}} } else if (8 * sizeof(PY_LONG_LONG) - 1 > {{_size}} * PyLong_SHIFT) { ll{{ival}} = {{'-' if _case < 0 else ''}}(PY_LONG_LONG) {{pylong_join(_size, 'digits', 'unsigned PY_LONG_LONG')}}; goto long_long; {{endif}} } // if size doesn't fit into a long or PY_LONG_LONG anymore, fall through to default {{endfor}} {{endfor}} {{if op in ('Eq', 'Ne')}} #if PyLong_SHIFT < 30 && PyLong_SHIFT != 15 // unusual setup - your fault default: return PyLong_Type.tp_richcompare({{'op1, op2' if order == 'ObjC' else 'op2, op1'}}, Py_{{op.upper()}}); #else // too large for the long values we allow => definitely not equal default: Py_RETURN_{{'FALSE' if op == 'Eq' else 'TRUE'}}; #endif {{else}} default: return PyLong_Type.tp_as_number->nb_{{slot_name}}(op1, op2); {{endif}} } } {{if op in ('Eq', 'Ne')}} if (a {{c_op}} b) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } {{else}} {{if c_op == '%'}} // see ExprNodes.py :: mod_int_utility_code x = a % b; x += ((x != 0) & ((x ^ b) < 0)) * b; {{elif op == 'TrueDivide'}} if (8 * sizeof(long) <= 53 || (__Pyx_sst_abs(size) <= 52 / PyLong_SHIFT) || likely(labs({{ival}}) <= (1L << 53))) { return PyFloat_FromDouble((double)a / (double)b); } return PyLong_Type.tp_as_number->nb_{{slot_name}}(op1, op2); {{elif op == 'FloorDivide'}} { long q, r; // see ExprNodes.py :: div_int_utility_code q = a / b; r = a - q*b; q -= ((r != 0) & ((r ^ b) < 0)); x = q; } {{else}} x = a {{c_op}} b; {{endif}} return PyLong_FromLong(x); {{if op != 'TrueDivide'}} long_long: {{if c_op == '%'}} // see ExprNodes.py :: mod_int_utility_code llx = lla % llb; llx += ((llx != 0) & ((llx ^ llb) < 0)) * llb; {{elif op == 'FloorDivide'}} { PY_LONG_LONG q, r; // see ExprNodes.py :: div_int_utility_code q = lla / llb; r = lla - q*llb; q -= ((r != 0) & ((r ^ llb) < 0)); llx = q; } {{else}} llx = lla {{c_op}} llb; {{endif}} return PyLong_FromLongLong(llx); {{endif}} {{endif}} } #endif {{if c_op in '+-' or op in ('TrueDivide', 'Eq', 'Ne')}} if (PyFloat_CheckExact({{pyval}})) { const long {{'a' if order == 'CObj' else 'b'}} = intval; double {{ival}} = PyFloat_AS_DOUBLE({{pyval}}); {{if op in ('Eq', 'Ne')}} if ((double)a {{c_op}} (double)b) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } {{else}} double result; // copied from floatobject.c in Py3.5: PyFPE_START_PROTECT("{{op.lower() if not op.endswith('Divide') else 'divide'}}", return NULL) result = ((double)a) {{c_op}} (double)b; PyFPE_END_PROTECT(result) return PyFloat_FromDouble(result); {{endif}} } {{endif}} {{if op in ('Eq', 'Ne')}} return PyObject_RichCompare(op1, op2, Py_{{op.upper()}}); {{else}} return (inplace ? PyNumber_InPlace{{op}} : PyNumber_{{op}})(op1, op2); {{endif}} } #endif /////////////// PyFloatBinop.proto /////////////// #if CYTHON_COMPILING_IN_CPYTHON static PyObject* __Pyx_PyFloat_{{op}}{{order}}(PyObject *op1, PyObject *op2, double floatval, int inplace); /*proto*/ #else #define __Pyx_PyFloat_{{op}}{{order}}(op1, op2, floatval, inplace) \ {{if op in ('Eq', 'Ne')}}PyObject_RichCompare(op1, op2, Py_{{op.upper()}}) {{elif op == 'Divide'}}((inplace ? __Pyx_PyNumber_InPlaceDivide(op1, op2) : __Pyx_PyNumber_Divide(op1, op2))) {{else}}(inplace ? PyNumber_InPlace{{op}}(op1, op2) : PyNumber_{{op}}(op1, op2)) {{endif}} #endif /////////////// PyFloatBinop /////////////// //@requires: TypeConversion.c::PyLongInternals #if CYTHON_COMPILING_IN_CPYTHON {{py: from Cython.Utility import pylong_join }} {{py: pyval, fval = ('op2', 'b') if order == 'CObj' else ('op1', 'a') }} {{py: c_op = { 'Add': '+', 'Subtract': '-', 'TrueDivide': '/', 'Divide': '/', 'Remainder': '%', 'Eq': '==', 'Ne': '!=', }[op] }} static PyObject* __Pyx_PyFloat_{{op}}{{order}}(PyObject *op1, PyObject *op2, double floatval, CYTHON_UNUSED int inplace) { const double {{'a' if order == 'CObj' else 'b'}} = floatval; double {{fval}}{{if op not in ('Eq', 'Ne')}}, result{{endif}}; {{if op in ('Eq', 'Ne')}} if (op1 == op2) { Py_RETURN_{{'TRUE' if op == 'Eq' else 'FALSE'}}; } {{endif}} if (likely(PyFloat_CheckExact({{pyval}}))) { {{fval}} = PyFloat_AS_DOUBLE({{pyval}}); } else #if PY_MAJOR_VERSION < 3 if (likely(PyInt_CheckExact({{pyval}}))) { {{fval}} = (double) PyInt_AS_LONG({{pyval}}); } else #endif if (likely(PyLong_CheckExact({{pyval}}))) { #if CYTHON_USE_PYLONG_INTERNALS && PY_MAJOR_VERSION >= 3 const digit* digits = ((PyLongObject*){{pyval}})->ob_digit; const Py_ssize_t size = Py_SIZE({{pyval}}); switch (size) { case 0: {{fval}} = 0.0; break; case -1: {{fval}} = -(double) digits[0]; break; case 1: {{fval}} = (double) digits[0]; break; {{for _size in (2, 3, 4)}} case -{{_size}}: case {{_size}}: if (8 * sizeof(unsigned long) > {{_size}} * PyLong_SHIFT && ((8 * sizeof(unsigned long) < 53) || ({{_size-1}} * PyLong_SHIFT < 53))) { {{fval}} = (double) {{pylong_join(_size, 'digits')}}; // let CPython do its own float rounding from 2**53 on (max. consecutive integer in double float) if ((8 * sizeof(unsigned long) < 53) || ({{_size}} * PyLong_SHIFT < 53) || ({{fval}} < (double) (1L<<53))) { if (size == {{-_size}}) {{fval}} = -{{fval}}; break; } } // Fall through if size doesn't fit safely into a double anymore. // It may not be obvious that this is a safe fall-through given the "fval < 2**53" // check above. However, the number of digits that CPython uses for a given PyLong // value is minimal, and together with the "(size-1) * SHIFT < 53" check above, // this should make it safe. {{endfor}} default: #else { #endif {{if op in ('Eq', 'Ne')}} return PyFloat_Type.tp_richcompare({{'op1, op2' if order == 'CObj' else 'op2, op1'}}, Py_{{op.upper()}}); {{else}} {{fval}} = PyLong_AsDouble({{pyval}}); if (unlikely({{fval}} == -1.0 && PyErr_Occurred())) return NULL; {{endif}} } } else { {{if op in ('Eq', 'Ne')}} return PyObject_RichCompare(op1, op2, Py_{{op.upper()}}); {{elif op == 'Divide'}} return (inplace ? __Pyx_PyNumber_InPlaceDivide(op1, op2) : __Pyx_PyNumber_Divide(op1, op2)); {{else}} return (inplace ? PyNumber_InPlace{{op}} : PyNumber_{{op}})(op1, op2); {{endif}} } {{if op in ('Eq', 'Ne')}} if (a {{c_op}} b) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } {{else}} // copied from floatobject.c in Py3.5: PyFPE_START_PROTECT("{{op.lower() if not op.endswith('Divide') else 'divide'}}", return NULL) {{if c_op == '%'}} result = fmod(a, b); if (result) result += ((result < 0) ^ (b < 0)) * b; else result = copysign(0.0, b); {{else}} result = a {{c_op}} b; {{endif}} PyFPE_END_PROTECT(result) return PyFloat_FromDouble(result); {{endif}} } #endif Cython-0.23.4/Cython/Utility/ObjectHandling.c0000644000175600017570000015312512606202452022141 0ustar jenkinsjenkins00000000000000/* * General object operations and protocol implementations, * including their specialisations for certain builtins. * * Optional optimisations for builtins are in Optimize.c. * * Required replacements of builtins are in Builtins.c. */ /////////////// RaiseNoneIterError.proto /////////////// static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); /////////////// RaiseNoneIterError /////////////// static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); } /////////////// RaiseTooManyValuesToUnpack.proto /////////////// static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); /////////////// RaiseTooManyValuesToUnpack /////////////// static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { PyErr_Format(PyExc_ValueError, "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); } /////////////// RaiseNeedMoreValuesToUnpack.proto /////////////// static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); /////////////// RaiseNeedMoreValuesToUnpack /////////////// static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { PyErr_Format(PyExc_ValueError, "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", index, (index == 1) ? "" : "s"); } /////////////// UnpackTupleError.proto /////////////// static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/ /////////////// UnpackTupleError /////////////// //@requires: RaiseNoneIterError //@requires: RaiseNeedMoreValuesToUnpack //@requires: RaiseTooManyValuesToUnpack static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) { if (t == Py_None) { __Pyx_RaiseNoneNotIterableError(); } else if (PyTuple_GET_SIZE(t) < index) { __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t)); } else { __Pyx_RaiseTooManyValuesError(index); } } /////////////// UnpackItemEndCheck.proto /////////////// static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); /*proto*/ /////////////// UnpackItemEndCheck /////////////// //@requires: RaiseTooManyValuesToUnpack //@requires: IterFinish static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { if (unlikely(retval)) { Py_DECREF(retval); __Pyx_RaiseTooManyValuesError(expected); return -1; } else { return __Pyx_IterFinish(); } return 0; } /////////////// UnpackTuple2.proto /////////////// static CYTHON_INLINE int __Pyx_unpack_tuple2(PyObject* tuple, PyObject** value1, PyObject** value2, int is_tuple, int has_known_size, int decref_tuple); /////////////// UnpackTuple2 /////////////// //@requires: UnpackItemEndCheck //@requires: UnpackTupleError //@requires: RaiseNeedMoreValuesToUnpack static CYTHON_INLINE int __Pyx_unpack_tuple2(PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2, int is_tuple, int has_known_size, int decref_tuple) { Py_ssize_t index; PyObject *value1 = NULL, *value2 = NULL, *iter = NULL; if (!is_tuple && unlikely(!PyTuple_Check(tuple))) { iternextfunc iternext; iter = PyObject_GetIter(tuple); if (unlikely(!iter)) goto bad; if (decref_tuple) { Py_DECREF(tuple); tuple = NULL; } iternext = Py_TYPE(iter)->tp_iternext; value1 = iternext(iter); if (unlikely(!value1)) { index = 0; goto unpacking_failed; } value2 = iternext(iter); if (unlikely(!value2)) { index = 1; goto unpacking_failed; } if (!has_known_size && unlikely(__Pyx_IternextUnpackEndCheck(iternext(iter), 2))) goto bad; Py_DECREF(iter); } else { if (!has_known_size && unlikely(PyTuple_GET_SIZE(tuple) != 2)) { __Pyx_UnpackTupleError(tuple, 2); goto bad; } #if CYTHON_COMPILING_IN_PYPY value1 = PySequence_ITEM(tuple, 0); if (unlikely(!value1)) goto bad; value2 = PySequence_ITEM(tuple, 1); if (unlikely(!value2)) goto bad; #else value1 = PyTuple_GET_ITEM(tuple, 0); value2 = PyTuple_GET_ITEM(tuple, 1); Py_INCREF(value1); Py_INCREF(value2); #endif if (decref_tuple) { Py_DECREF(tuple); } } *pvalue1 = value1; *pvalue2 = value2; return 0; unpacking_failed: if (!has_known_size && __Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); bad: Py_XDECREF(iter); Py_XDECREF(value1); Py_XDECREF(value2); if (decref_tuple) { Py_XDECREF(tuple); } return -1; } /////////////// IterNext.proto /////////////// #define __Pyx_PyIter_Next(obj) __Pyx_PyIter_Next2(obj, NULL) static CYTHON_INLINE PyObject *__Pyx_PyIter_Next2(PyObject *, PyObject *); /*proto*/ /////////////// IterNext /////////////// // originally copied from Py3's builtin_next() static CYTHON_INLINE PyObject *__Pyx_PyIter_Next2(PyObject* iterator, PyObject* defval) { PyObject* next; iternextfunc iternext = Py_TYPE(iterator)->tp_iternext; #if CYTHON_COMPILING_IN_CPYTHON if (unlikely(!iternext)) { #else if (unlikely(!iternext) || unlikely(!PyIter_Check(iterator))) { #endif PyErr_Format(PyExc_TypeError, "%.200s object is not an iterator", Py_TYPE(iterator)->tp_name); return NULL; } next = iternext(iterator); if (likely(next)) return next; #if CYTHON_COMPILING_IN_CPYTHON #if PY_VERSION_HEX >= 0x02070000 if (unlikely(iternext == &_PyObject_NextNotImplemented)) return NULL; #endif #endif if (defval) { PyObject* exc_type = PyErr_Occurred(); if (exc_type) { if (unlikely(exc_type != PyExc_StopIteration) && !PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) return NULL; PyErr_Clear(); } Py_INCREF(defval); return defval; } if (!PyErr_Occurred()) PyErr_SetNone(PyExc_StopIteration); return NULL; } /////////////// IterFinish.proto /////////////// static CYTHON_INLINE int __Pyx_IterFinish(void); /*proto*/ /////////////// IterFinish /////////////// // When PyIter_Next(iter) has returned NULL in order to signal termination, // this function does the right cleanup and returns 0 on success. If it // detects an error that occurred in the iterator, it returns -1. static CYTHON_INLINE int __Pyx_IterFinish(void) { #if CYTHON_COMPILING_IN_CPYTHON PyThreadState *tstate = PyThreadState_GET(); PyObject* exc_type = tstate->curexc_type; if (unlikely(exc_type)) { if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) { PyObject *exc_value, *exc_tb; exc_value = tstate->curexc_value; exc_tb = tstate->curexc_traceback; tstate->curexc_type = 0; tstate->curexc_value = 0; tstate->curexc_traceback = 0; Py_DECREF(exc_type); Py_XDECREF(exc_value); Py_XDECREF(exc_tb); return 0; } else { return -1; } } return 0; #else if (unlikely(PyErr_Occurred())) { if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) { PyErr_Clear(); return 0; } else { return -1; } } return 0; #endif } /////////////// DictGetItem.proto /////////////// #if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { PyObject *value; value = PyDict_GetItemWithError(d, key); if (unlikely(!value)) { if (!PyErr_Occurred()) { PyObject* args = PyTuple_Pack(1, key); if (likely(args)) PyErr_SetObject(PyExc_KeyError, args); Py_XDECREF(args); } return NULL; } Py_INCREF(value); return value; } #else #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key) #endif /////////////// GetItemInt.proto /////////////// #define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \ (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \ __Pyx_GetItemInt_Generic(o, to_py_func(i)))) {{for type in ['List', 'Tuple']}} #define __Pyx_GetItemInt_{{type}}(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ __Pyx_GetItemInt_{{type}}_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \ (PyErr_SetString(PyExc_IndexError, "{{ type.lower() }} index out of range"), (PyObject*)NULL)) static CYTHON_INLINE PyObject *__Pyx_GetItemInt_{{type}}_Fast(PyObject *o, Py_ssize_t i, int wraparound, int boundscheck); {{endfor}} static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j); static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, int wraparound, int boundscheck); /////////////// GetItemInt /////////////// static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { PyObject *r; if (!j) return NULL; r = PyObject_GetItem(o, j); Py_DECREF(j); return r; } {{for type in ['List', 'Tuple']}} static CYTHON_INLINE PyObject *__Pyx_GetItemInt_{{type}}_Fast(PyObject *o, Py_ssize_t i, CYTHON_NCP_UNUSED int wraparound, CYTHON_NCP_UNUSED int boundscheck) { #if CYTHON_COMPILING_IN_CPYTHON if (wraparound & unlikely(i < 0)) i += Py{{type}}_GET_SIZE(o); if ((!boundscheck) || likely((0 <= i) & (i < Py{{type}}_GET_SIZE(o)))) { PyObject *r = Py{{type}}_GET_ITEM(o, i); Py_INCREF(r); return r; } return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); #else return PySequence_GetItem(o, i); #endif } {{endfor}} static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, CYTHON_NCP_UNUSED int wraparound, CYTHON_NCP_UNUSED int boundscheck) { #if CYTHON_COMPILING_IN_CPYTHON if (is_list || PyList_CheckExact(o)) { Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o); if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) { PyObject *r = PyList_GET_ITEM(o, n); Py_INCREF(r); return r; } } else if (PyTuple_CheckExact(o)) { Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o); if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) { PyObject *r = PyTuple_GET_ITEM(o, n); Py_INCREF(r); return r; } } else { // inlined PySequence_GetItem() + special cased length overflow PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; if (likely(m && m->sq_item)) { if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { Py_ssize_t l = m->sq_length(o); if (likely(l >= 0)) { i += l; } else { // if length > max(Py_ssize_t), maybe the object can wrap around itself? if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_Clear(); else return NULL; } } return m->sq_item(o, i); } } #else if (is_list || PySequence_Check(o)) { return PySequence_GetItem(o, i); } #endif return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i)); } /////////////// SetItemInt.proto /////////////// #define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) : \ (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) : \ __Pyx_SetItemInt_Generic(o, to_py_func(i), v))) static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v); static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int is_list, int wraparound, int boundscheck); /////////////// SetItemInt /////////////// static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) { int r; if (!j) return -1; r = PyObject_SetItem(o, j, v); Py_DECREF(j); return r; } static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int is_list, CYTHON_NCP_UNUSED int wraparound, CYTHON_NCP_UNUSED int boundscheck) { #if CYTHON_COMPILING_IN_CPYTHON if (is_list || PyList_CheckExact(o)) { Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o)); if ((!boundscheck) || likely((n >= 0) & (n < PyList_GET_SIZE(o)))) { PyObject* old = PyList_GET_ITEM(o, n); Py_INCREF(v); PyList_SET_ITEM(o, n, v); Py_DECREF(old); return 1; } } else { // inlined PySequence_SetItem() + special cased length overflow PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; if (likely(m && m->sq_ass_item)) { if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { Py_ssize_t l = m->sq_length(o); if (likely(l >= 0)) { i += l; } else { // if length > max(Py_ssize_t), maybe the object can wrap around itself? if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_Clear(); else return -1; } } return m->sq_ass_item(o, i, v); } } #else #if CYTHON_COMPILING_IN_PYPY if (is_list || (PySequence_Check(o) && !PyDict_Check(o))) { #else if (is_list || PySequence_Check(o)) { #endif return PySequence_SetItem(o, i, v); } #endif return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v); } /////////////// DelItemInt.proto /////////////// #define __Pyx_DelItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \ __Pyx_DelItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound) : \ (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) : \ __Pyx_DelItem_Generic(o, to_py_func(i)))) static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j); static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list, int wraparound); /////////////// DelItemInt /////////////// static CYTHON_INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) { int r; if (!j) return -1; r = PyObject_DelItem(o, j); Py_DECREF(j); return r; } static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i, CYTHON_UNUSED int is_list, CYTHON_NCP_UNUSED int wraparound) { #if CYTHON_COMPILING_IN_PYPY if (is_list || PySequence_Check(o)) { return PySequence_DelItem(o, i); } #else // inlined PySequence_DelItem() + special cased length overflow PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence; if (likely(m && m->sq_ass_item)) { if (wraparound && unlikely(i < 0) && likely(m->sq_length)) { Py_ssize_t l = m->sq_length(o); if (likely(l >= 0)) { i += l; } else { // if length > max(Py_ssize_t), maybe the object can wrap around itself? if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_Clear(); else return -1; } } return m->sq_ass_item(o, i, (PyObject *)NULL); } #endif return __Pyx_DelItem_Generic(o, PyInt_FromSsize_t(i)); } /////////////// SliceObject.proto /////////////// // we pass pointer addresses to show the C compiler what is NULL and what isn't {{if access == 'Get'}} static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice( PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop, PyObject** py_start, PyObject** py_stop, PyObject** py_slice, int has_cstart, int has_cstop, int wraparound); {{else}} #define __Pyx_PyObject_DelSlice(obj, cstart, cstop, py_start, py_stop, py_slice, has_cstart, has_cstop, wraparound) \ __Pyx_PyObject_SetSlice(obj, (PyObject*)NULL, cstart, cstop, py_start, py_stop, py_slice, has_cstart, has_cstop, wraparound) // we pass pointer addresses to show the C compiler what is NULL and what isn't static CYTHON_INLINE int __Pyx_PyObject_SetSlice( PyObject* obj, PyObject* value, Py_ssize_t cstart, Py_ssize_t cstop, PyObject** py_start, PyObject** py_stop, PyObject** py_slice, int has_cstart, int has_cstop, int wraparound); {{endif}} /////////////// SliceObject /////////////// {{if access == 'Get'}} static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(PyObject* obj, {{else}} static CYTHON_INLINE int __Pyx_PyObject_SetSlice(PyObject* obj, PyObject* value, {{endif}} Py_ssize_t cstart, Py_ssize_t cstop, PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice, int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) { #if CYTHON_COMPILING_IN_CPYTHON PyMappingMethods* mp; #if PY_MAJOR_VERSION < 3 PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence; if (likely(ms && ms->sq_{{if access == 'Set'}}ass_{{endif}}slice)) { if (!has_cstart) { if (_py_start && (*_py_start != Py_None)) { cstart = __Pyx_PyIndex_AsSsize_t(*_py_start); if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; } else cstart = 0; } if (!has_cstop) { if (_py_stop && (*_py_stop != Py_None)) { cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop); if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad; } else cstop = PY_SSIZE_T_MAX; } if (wraparound && unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) { Py_ssize_t l = ms->sq_length(obj); if (likely(l >= 0)) { if (cstop < 0) { cstop += l; if (cstop < 0) cstop = 0; } if (cstart < 0) { cstart += l; if (cstart < 0) cstart = 0; } } else { // if length > max(Py_ssize_t), maybe the object can wrap around itself? if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_Clear(); else goto bad; } } {{if access == 'Get'}} return ms->sq_slice(obj, cstart, cstop); {{else}} return ms->sq_ass_slice(obj, cstart, cstop, value); {{endif}} } #endif mp = Py_TYPE(obj)->tp_as_mapping; {{if access == 'Get'}} if (likely(mp && mp->mp_subscript)) {{else}} if (likely(mp && mp->mp_ass_subscript)) {{endif}} #endif { {{if access == 'Get'}}PyObject*{{else}}int{{endif}} result; PyObject *py_slice, *py_start, *py_stop; if (_py_slice) { py_slice = *_py_slice; } else { PyObject* owned_start = NULL; PyObject* owned_stop = NULL; if (_py_start) { py_start = *_py_start; } else { if (has_cstart) { owned_start = py_start = PyInt_FromSsize_t(cstart); if (unlikely(!py_start)) goto bad; } else py_start = Py_None; } if (_py_stop) { py_stop = *_py_stop; } else { if (has_cstop) { owned_stop = py_stop = PyInt_FromSsize_t(cstop); if (unlikely(!py_stop)) { Py_XDECREF(owned_start); goto bad; } } else py_stop = Py_None; } py_slice = PySlice_New(py_start, py_stop, Py_None); Py_XDECREF(owned_start); Py_XDECREF(owned_stop); if (unlikely(!py_slice)) goto bad; } #if CYTHON_COMPILING_IN_CPYTHON {{if access == 'Get'}} result = mp->mp_subscript(obj, py_slice); #else result = PyObject_GetItem(obj, py_slice); {{else}} result = mp->mp_ass_subscript(obj, py_slice, value); #else result = value ? PyObject_SetItem(obj, py_slice, value) : PyObject_DelItem(obj, py_slice); {{endif}} #endif if (!_py_slice) { Py_DECREF(py_slice); } return result; } PyErr_Format(PyExc_TypeError, {{if access == 'Get'}} "'%.200s' object is unsliceable", Py_TYPE(obj)->tp_name); {{else}} "'%.200s' object does not support slice %.10s", Py_TYPE(obj)->tp_name, value ? "assignment" : "deletion"); {{endif}} bad: return {{if access == 'Get'}}NULL{{else}}-1{{endif}}; } /////////////// SliceTupleAndList.proto /////////////// #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyList_GetSlice(PyObject* src, Py_ssize_t start, Py_ssize_t stop); static CYTHON_INLINE PyObject* __Pyx_PyTuple_GetSlice(PyObject* src, Py_ssize_t start, Py_ssize_t stop); #else #define __Pyx_PyList_GetSlice(seq, start, stop) PySequence_GetSlice(seq, start, stop) #define __Pyx_PyTuple_GetSlice(seq, start, stop) PySequence_GetSlice(seq, start, stop) #endif /////////////// SliceTupleAndList /////////////// #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE void __Pyx_crop_slice(Py_ssize_t* _start, Py_ssize_t* _stop, Py_ssize_t* _length) { Py_ssize_t start = *_start, stop = *_stop, length = *_length; if (start < 0) { start += length; if (start < 0) start = 0; } if (stop < 0) stop += length; else if (stop > length) stop = length; *_length = stop - start; *_start = start; *_stop = stop; } static CYTHON_INLINE void __Pyx_copy_object_array(PyObject** CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) { PyObject *v; Py_ssize_t i; for (i = 0; i < length; i++) { v = dest[i] = src[i]; Py_INCREF(v); } } {{for type in ['List', 'Tuple']}} static CYTHON_INLINE PyObject* __Pyx_Py{{type}}_GetSlice( PyObject* src, Py_ssize_t start, Py_ssize_t stop) { PyObject* dest; Py_ssize_t length = Py{{type}}_GET_SIZE(src); __Pyx_crop_slice(&start, &stop, &length); if (unlikely(length <= 0)) return Py{{type}}_New(0); dest = Py{{type}}_New(length); if (unlikely(!dest)) return NULL; __Pyx_copy_object_array( ((Py{{type}}Object*)src)->ob_item + start, ((Py{{type}}Object*)dest)->ob_item, length); return dest; } {{endfor}} #endif /////////////// CalculateMetaclass.proto /////////////// static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases); /////////////// CalculateMetaclass /////////////// static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases) { Py_ssize_t i, nbases = PyTuple_GET_SIZE(bases); for (i=0; i < nbases; i++) { PyTypeObject *tmptype; PyObject *tmp = PyTuple_GET_ITEM(bases, i); tmptype = Py_TYPE(tmp); #if PY_MAJOR_VERSION < 3 if (tmptype == &PyClass_Type) continue; #endif if (!metaclass) { metaclass = tmptype; continue; } if (PyType_IsSubtype(metaclass, tmptype)) continue; if (PyType_IsSubtype(tmptype, metaclass)) { metaclass = tmptype; continue; } // else: PyErr_SetString(PyExc_TypeError, "metaclass conflict: " "the metaclass of a derived class " "must be a (non-strict) subclass " "of the metaclasses of all its bases"); return NULL; } if (!metaclass) { #if PY_MAJOR_VERSION < 3 metaclass = &PyClass_Type; #else metaclass = &PyType_Type; #endif } // make owned reference Py_INCREF((PyObject*) metaclass); return (PyObject*) metaclass; } /////////////// FindInheritedMetaclass.proto /////////////// static PyObject *__Pyx_FindInheritedMetaclass(PyObject *bases); /*proto*/ /////////////// FindInheritedMetaclass /////////////// //@requires: PyObjectGetAttrStr //@requires: CalculateMetaclass static PyObject *__Pyx_FindInheritedMetaclass(PyObject *bases) { PyObject *metaclass; if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) { PyTypeObject *metatype; #if CYTHON_COMPILING_IN_CPYTHON PyObject *base = PyTuple_GET_ITEM(bases, 0); #else PyObject *base = PySequence_ITEM(bases, 0); #endif #if PY_MAJOR_VERSION < 3 PyObject* basetype = __Pyx_PyObject_GetAttrStr(base, PYIDENT("__class__")); if (basetype) { metatype = (PyType_Check(basetype)) ? ((PyTypeObject*) basetype) : NULL; } else { PyErr_Clear(); metatype = Py_TYPE(base); basetype = (PyObject*) metatype; Py_INCREF(basetype); } #else metatype = Py_TYPE(base); #endif metaclass = __Pyx_CalculateMetaclass(metatype, bases); #if !CYTHON_COMPILING_IN_CPYTHON Py_DECREF(base); #endif #if PY_MAJOR_VERSION < 3 Py_DECREF(basetype); #endif } else { // no bases => use default metaclass #if PY_MAJOR_VERSION < 3 metaclass = (PyObject *) &PyClass_Type; #else metaclass = (PyObject *) &PyType_Type; #endif Py_INCREF(metaclass); } return metaclass; } /////////////// Py3MetaclassGet.proto /////////////// static PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw); /*proto*/ /////////////// Py3MetaclassGet /////////////// //@requires: FindInheritedMetaclass //@requires: CalculateMetaclass static PyObject *__Pyx_Py3MetaclassGet(PyObject *bases, PyObject *mkw) { PyObject *metaclass = mkw ? PyDict_GetItem(mkw, PYIDENT("metaclass")) : NULL; if (metaclass) { Py_INCREF(metaclass); if (PyDict_DelItem(mkw, PYIDENT("metaclass")) < 0) { Py_DECREF(metaclass); return NULL; } if (PyType_Check(metaclass)) { PyObject* orig = metaclass; metaclass = __Pyx_CalculateMetaclass((PyTypeObject*) metaclass, bases); Py_DECREF(orig); } return metaclass; } return __Pyx_FindInheritedMetaclass(bases); } /////////////// CreateClass.proto /////////////// static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, PyObject *qualname, PyObject *modname); /*proto*/ /////////////// CreateClass /////////////// //@requires: FindInheritedMetaclass //@requires: CalculateMetaclass static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, PyObject *qualname, PyObject *modname) { PyObject *result; PyObject *metaclass; if (PyDict_SetItem(dict, PYIDENT("__module__"), modname) < 0) return NULL; if (PyDict_SetItem(dict, PYIDENT("__qualname__"), qualname) < 0) return NULL; /* Python2 __metaclass__ */ metaclass = PyDict_GetItem(dict, PYIDENT("__metaclass__")); if (metaclass) { Py_INCREF(metaclass); if (PyType_Check(metaclass)) { PyObject* orig = metaclass; metaclass = __Pyx_CalculateMetaclass((PyTypeObject*) metaclass, bases); Py_DECREF(orig); } } else { metaclass = __Pyx_FindInheritedMetaclass(bases); } if (unlikely(!metaclass)) return NULL; result = PyObject_CallFunctionObjArgs(metaclass, name, bases, dict, NULL); Py_DECREF(metaclass); return result; } /////////////// Py3ClassCreate.proto /////////////// static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *qualname, PyObject *mkw, PyObject *modname, PyObject *doc); /*proto*/ static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw, int calculate_metaclass, int allow_py2_metaclass); /*proto*/ /////////////// Py3ClassCreate /////////////// //@requires: PyObjectGetAttrStr //@requires: CalculateMetaclass static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *qualname, PyObject *mkw, PyObject *modname, PyObject *doc) { PyObject *ns; if (metaclass) { PyObject *prep = __Pyx_PyObject_GetAttrStr(metaclass, PYIDENT("__prepare__")); if (prep) { PyObject *pargs = PyTuple_Pack(2, name, bases); if (unlikely(!pargs)) { Py_DECREF(prep); return NULL; } ns = PyObject_Call(prep, pargs, mkw); Py_DECREF(prep); Py_DECREF(pargs); } else { if (unlikely(!PyErr_ExceptionMatches(PyExc_AttributeError))) return NULL; PyErr_Clear(); ns = PyDict_New(); } } else { ns = PyDict_New(); } if (unlikely(!ns)) return NULL; /* Required here to emulate assignment order */ if (unlikely(PyObject_SetItem(ns, PYIDENT("__module__"), modname) < 0)) goto bad; if (unlikely(PyObject_SetItem(ns, PYIDENT("__qualname__"), qualname) < 0)) goto bad; if (unlikely(doc && PyObject_SetItem(ns, PYIDENT("__doc__"), doc) < 0)) goto bad; return ns; bad: Py_DECREF(ns); return NULL; } static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict, PyObject *mkw, int calculate_metaclass, int allow_py2_metaclass) { PyObject *result, *margs; PyObject *owned_metaclass = NULL; if (allow_py2_metaclass) { /* honour Python2 __metaclass__ for backward compatibility */ owned_metaclass = PyObject_GetItem(dict, PYIDENT("__metaclass__")); if (owned_metaclass) { metaclass = owned_metaclass; } else if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) { PyErr_Clear(); } else { return NULL; } } if (calculate_metaclass && (!metaclass || PyType_Check(metaclass))) { metaclass = __Pyx_CalculateMetaclass((PyTypeObject*) metaclass, bases); Py_XDECREF(owned_metaclass); if (unlikely(!metaclass)) return NULL; owned_metaclass = metaclass; } margs = PyTuple_Pack(3, name, bases, dict); if (unlikely(!margs)) { result = NULL; } else { result = PyObject_Call(metaclass, margs, mkw); Py_DECREF(margs); } Py_XDECREF(owned_metaclass); return result; } /////////////// ExtTypeTest.proto /////////////// static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/ /////////////// ExtTypeTest /////////////// static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { if (unlikely(!type)) { PyErr_SetString(PyExc_SystemError, "Missing type object"); return 0; } if (likely(PyObject_TypeCheck(obj, type))) return 1; PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s", Py_TYPE(obj)->tp_name, type->tp_name); return 0; } /////////////// CallableCheck.proto /////////////// #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 #define __Pyx_PyCallable_Check(obj) ((obj)->ob_type->tp_call != NULL) #else #define __Pyx_PyCallable_Check(obj) PyCallable_Check(obj) #endif /////////////// PyDictContains.proto /////////////// static CYTHON_INLINE int __Pyx_PyDict_ContainsTF(PyObject* item, PyObject* dict, int eq) { int result = PyDict_Contains(dict, item); return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); } /////////////// PySequenceContains.proto /////////////// static CYTHON_INLINE int __Pyx_PySequence_ContainsTF(PyObject* item, PyObject* seq, int eq) { int result = PySequence_Contains(seq, item); return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); } /////////////// PyBoolOrNullFromLong.proto /////////////// static CYTHON_INLINE PyObject* __Pyx_PyBoolOrNull_FromLong(long b) { return unlikely(b < 0) ? NULL : __Pyx_PyBool_FromLong(b); } /////////////// GetBuiltinName.proto /////////////// static PyObject *__Pyx_GetBuiltinName(PyObject *name); /*proto*/ /////////////// GetBuiltinName /////////////// //@requires: PyObjectGetAttrStr //@substitute: naming static PyObject *__Pyx_GetBuiltinName(PyObject *name) { PyObject* result = __Pyx_PyObject_GetAttrStr($builtins_cname, name); if (unlikely(!result)) { PyErr_Format(PyExc_NameError, #if PY_MAJOR_VERSION >= 3 "name '%U' is not defined", name); #else "name '%.200s' is not defined", PyString_AS_STRING(name)); #endif } return result; } /////////////// GetNameInClass.proto /////////////// static PyObject *__Pyx_GetNameInClass(PyObject *nmspace, PyObject *name); /*proto*/ /////////////// GetNameInClass /////////////// //@requires: PyObjectGetAttrStr //@requires: GetModuleGlobalName static PyObject *__Pyx_GetNameInClass(PyObject *nmspace, PyObject *name) { PyObject *result; result = __Pyx_PyObject_GetAttrStr(nmspace, name); if (!result) result = __Pyx_GetModuleGlobalName(name); return result; } /////////////// GetModuleGlobalName.proto /////////////// static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); /*proto*/ /////////////// GetModuleGlobalName /////////////// //@requires: GetBuiltinName //@substitute: naming static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) { PyObject *result; #if CYTHON_COMPILING_IN_CPYTHON result = PyDict_GetItem($moddict_cname, name); if (likely(result)) { Py_INCREF(result); } else { #else result = PyObject_GetItem($moddict_cname, name); if (!result) { PyErr_Clear(); #endif result = __Pyx_GetBuiltinName(name); } return result; } //////////////////// GetAttr.proto //////////////////// static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); /*proto*/ //////////////////// GetAttr //////////////////// //@requires: PyObjectGetAttrStr static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { #if CYTHON_COMPILING_IN_CPYTHON #if PY_MAJOR_VERSION >= 3 if (likely(PyUnicode_Check(n))) #else if (likely(PyString_Check(n))) #endif return __Pyx_PyObject_GetAttrStr(o, n); #endif return PyObject_GetAttr(o, n); } /////////////// PyObjectLookupSpecial.proto /////////////// //@requires: PyObjectGetAttrStr #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02070000 // looks like calling _PyType_Lookup() isn't safe in Py<=2.6/3.1 static CYTHON_INLINE PyObject* __Pyx_PyObject_LookupSpecial(PyObject* obj, PyObject* attr_name) { PyObject *res; PyTypeObject *tp = Py_TYPE(obj); #if PY_MAJOR_VERSION < 3 if (unlikely(PyInstance_Check(obj))) return __Pyx_PyObject_GetAttrStr(obj, attr_name); #endif // adapted from CPython's special_lookup() in ceval.c res = _PyType_Lookup(tp, attr_name); if (likely(res)) { descrgetfunc f = Py_TYPE(res)->tp_descr_get; if (!f) { Py_INCREF(res); } else { res = f(res, obj, (PyObject *)tp); } } else { PyErr_SetObject(PyExc_AttributeError, attr_name); } return res; } #else #define __Pyx_PyObject_LookupSpecial(o,n) __Pyx_PyObject_GetAttrStr(o,n) #endif /////////////// PyObjectGetAttrStr.proto /////////////// #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { PyTypeObject* tp = Py_TYPE(obj); if (likely(tp->tp_getattro)) return tp->tp_getattro(obj, attr_name); #if PY_MAJOR_VERSION < 3 if (likely(tp->tp_getattr)) return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); #endif return PyObject_GetAttr(obj, attr_name); } #else #define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) #endif /////////////// PyObjectSetAttrStr.proto /////////////// #if CYTHON_COMPILING_IN_CPYTHON #define __Pyx_PyObject_DelAttrStr(o,n) __Pyx_PyObject_SetAttrStr(o,n,NULL) static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr_name, PyObject* value) { PyTypeObject* tp = Py_TYPE(obj); if (likely(tp->tp_setattro)) return tp->tp_setattro(obj, attr_name, value); #if PY_MAJOR_VERSION < 3 if (likely(tp->tp_setattr)) return tp->tp_setattr(obj, PyString_AS_STRING(attr_name), value); #endif return PyObject_SetAttr(obj, attr_name, value); } #else #define __Pyx_PyObject_DelAttrStr(o,n) PyObject_DelAttr(o,n) #define __Pyx_PyObject_SetAttrStr(o,n,v) PyObject_SetAttr(o,n,v) #endif /////////////// UnpackUnboundCMethod.proto /////////////// typedef struct { PyObject *type; PyObject **method_name; // "func" is set on first access (direct C function pointer) PyCFunction func; // "method" is set on first access (fallback) PyObject *method; int flag; } __Pyx_CachedCFunction; /////////////// UnpackUnboundCMethod /////////////// //@requires: PyObjectGetAttrStr static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) { PyObject *method; method = __Pyx_PyObject_GetAttrStr(target->type, *target->method_name); if (unlikely(!method)) return -1; target->method = method; #if CYTHON_COMPILING_IN_CPYTHON #if PY_MAJOR_VERSION >= 3 // method dscriptor type isn't exported in Py2.x, cannot easily check the type there if (likely(PyObject_TypeCheck(method, &PyMethodDescr_Type))) #endif { PyMethodDescrObject *descr = (PyMethodDescrObject*) method; target->func = descr->d_method->ml_meth; target->flag = descr->d_method->ml_flags & (METH_VARARGS | METH_KEYWORDS | METH_O | METH_NOARGS); } #endif return 0; } /////////////// CallUnboundCMethod0.proto /////////////// //@substitute: naming static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self); /*proto*/ #if CYTHON_COMPILING_IN_CPYTHON #define __Pyx_CallUnboundCMethod0(cfunc, self) \ ((likely((cfunc)->func)) ? \ (likely((cfunc)->flag == METH_NOARGS) ? (*((cfunc)->func))(self, NULL) : \ (likely((cfunc)->flag == (METH_VARARGS | METH_KEYWORDS)) ? ((*(PyCFunctionWithKeywords)(cfunc)->func)(self, $empty_tuple, NULL)) : \ ((cfunc)->flag == METH_VARARGS ? (*((cfunc)->func))(self, $empty_tuple) : __Pyx__CallUnboundCMethod0(cfunc, self)))) : \ __Pyx__CallUnboundCMethod0(cfunc, self)) #else #define __Pyx_CallUnboundCMethod0(cfunc, self) __Pyx__CallUnboundCMethod0(cfunc, self) #endif /////////////// CallUnboundCMethod0 /////////////// //@requires: UnpackUnboundCMethod //@requires: PyObjectCall static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self) { PyObject *args, *result = NULL; if (unlikely(!cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; #if CYTHON_COMPILING_IN_CPYTHON args = PyTuple_New(1); if (unlikely(!args)) goto bad; Py_INCREF(self); PyTuple_SET_ITEM(args, 0, self); #else args = PyTuple_Pack(1, self); if (unlikely(!args)) goto bad; #endif result = __Pyx_PyObject_Call(cfunc->method, args, NULL); Py_DECREF(args); bad: return result; } /////////////// CallUnboundCMethod1.proto /////////////// static PyObject* __Pyx__CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg); /*proto*/ #if CYTHON_COMPILING_IN_CPYTHON #define __Pyx_CallUnboundCMethod1(cfunc, self, arg) \ ((likely((cfunc)->func && (cfunc)->flag == METH_O)) ? (*((cfunc)->func))(self, arg) : \ __Pyx__CallUnboundCMethod1(cfunc, self, arg)) #else #define __Pyx_CallUnboundCMethod1(cfunc, self, arg) __Pyx__CallUnboundCMethod1(cfunc, self, arg) #endif /////////////// CallUnboundCMethod1 /////////////// //@requires: UnpackUnboundCMethod //@requires: PyObjectCall static PyObject* __Pyx__CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg){ PyObject *args, *result = NULL; if (unlikely(!cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; #if CYTHON_COMPILING_IN_CPYTHON if (cfunc->func && (cfunc->flag & METH_VARARGS)) { args = PyTuple_New(1); if (unlikely(!args)) goto bad; Py_INCREF(arg); PyTuple_SET_ITEM(args, 0, arg); if (cfunc->flag & METH_KEYWORDS) result = (*(PyCFunctionWithKeywords)cfunc->func)(self, args, NULL); else result = (*cfunc->func)(self, args); } else { args = PyTuple_New(2); if (unlikely(!args)) goto bad; Py_INCREF(self); PyTuple_SET_ITEM(args, 0, self); Py_INCREF(arg); PyTuple_SET_ITEM(args, 1, arg); result = __Pyx_PyObject_Call(cfunc->method, args, NULL); } #else args = PyTuple_Pack(2, self, arg); if (unlikely(!args)) goto bad; result = __Pyx_PyObject_Call(cfunc->method, args, NULL); #endif bad: Py_XDECREF(args); return result; } /////////////// PyObjectCallMethod0.proto /////////////// static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name); /*proto*/ /////////////// PyObjectCallMethod0 /////////////// //@requires: PyObjectGetAttrStr //@requires: PyObjectCallOneArg //@requires: PyObjectCallNoArg static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) { PyObject *method, *result = NULL; method = __Pyx_PyObject_GetAttrStr(obj, method_name); if (unlikely(!method)) goto bad; #if CYTHON_COMPILING_IN_CPYTHON if (likely(PyMethod_Check(method))) { PyObject *self = PyMethod_GET_SELF(method); if (likely(self)) { PyObject *function = PyMethod_GET_FUNCTION(method); result = __Pyx_PyObject_CallOneArg(function, self); Py_DECREF(method); return result; } } #endif result = __Pyx_PyObject_CallNoArg(method); Py_DECREF(method); bad: return result; } /////////////// PyObjectCallMethod1.proto /////////////// static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg); /*proto*/ /////////////// PyObjectCallMethod1 /////////////// //@requires: PyObjectGetAttrStr //@requires: PyObjectCallOneArg static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) { PyObject *method, *result = NULL; method = __Pyx_PyObject_GetAttrStr(obj, method_name); if (unlikely(!method)) goto bad; #if CYTHON_COMPILING_IN_CPYTHON if (likely(PyMethod_Check(method))) { PyObject *self = PyMethod_GET_SELF(method); if (likely(self)) { PyObject *args; PyObject *function = PyMethod_GET_FUNCTION(method); args = PyTuple_New(2); if (unlikely(!args)) goto bad; Py_INCREF(self); PyTuple_SET_ITEM(args, 0, self); Py_INCREF(arg); PyTuple_SET_ITEM(args, 1, arg); Py_INCREF(function); Py_DECREF(method); method = NULL; result = __Pyx_PyObject_Call(function, args, NULL); Py_DECREF(args); Py_DECREF(function); return result; } } #endif result = __Pyx_PyObject_CallOneArg(method, arg); bad: Py_XDECREF(method); return result; } /////////////// PyObjectCallMethod2.proto /////////////// static PyObject* __Pyx_PyObject_CallMethod2(PyObject* obj, PyObject* method_name, PyObject* arg1, PyObject* arg2); /*proto*/ /////////////// PyObjectCallMethod2 /////////////// //@requires: PyObjectGetAttrStr //@requires: PyObjectCall static PyObject* __Pyx_PyObject_CallMethod2(PyObject* obj, PyObject* method_name, PyObject* arg1, PyObject* arg2) { PyObject *args, *method, *result = NULL; method = __Pyx_PyObject_GetAttrStr(obj, method_name); #if CYTHON_COMPILING_IN_CPYTHON if (likely(PyMethod_Check(method)) && likely(PyMethod_GET_SELF(method))) { PyObject *self, *function; self = PyMethod_GET_SELF(method); function = PyMethod_GET_FUNCTION(method); args = PyTuple_New(3); if (unlikely(!args)) goto bad; Py_INCREF(self); PyTuple_SET_ITEM(args, 0, self); Py_INCREF(arg1); PyTuple_SET_ITEM(args, 1, arg1); Py_INCREF(arg2); PyTuple_SET_ITEM(args, 2, arg2); Py_INCREF(function); Py_DECREF(method); method = function; } else #endif { args = PyTuple_New(2); if (unlikely(!args)) goto bad; Py_INCREF(arg1); PyTuple_SET_ITEM(args, 0, arg1); Py_INCREF(arg2); PyTuple_SET_ITEM(args, 1, arg2); } result = __Pyx_PyObject_Call(method, args, NULL); Py_DECREF(args); Py_DECREF(method); return result; bad: Py_XDECREF(method); return result; } /////////////// tp_new.proto /////////////// #define __Pyx_tp_new(type_obj, args) __Pyx_tp_new_kwargs(type_obj, args, NULL) static CYTHON_INLINE PyObject* __Pyx_tp_new_kwargs(PyObject* type_obj, PyObject* args, PyObject* kwargs) { return (PyObject*) (((PyTypeObject*)type_obj)->tp_new((PyTypeObject*)type_obj, args, kwargs)); } /////////////// PyObjectCall.proto /////////////// #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); /*proto*/ #else #define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) #endif /////////////// PyObjectCall /////////////// #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { PyObject *result; ternaryfunc call = func->ob_type->tp_call; if (unlikely(!call)) return PyObject_Call(func, arg, kw); if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) return NULL; result = (*call)(func, arg, kw); Py_LeaveRecursiveCall(); if (unlikely(!result) && unlikely(!PyErr_Occurred())) { PyErr_SetString( PyExc_SystemError, "NULL result without error in PyObject_Call"); } return result; } #endif /////////////// PyObjectCallMethO.proto /////////////// #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); /*proto*/ #endif /////////////// PyObjectCallMethO /////////////// #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { PyObject *self, *result; PyCFunction cfunc; cfunc = PyCFunction_GET_FUNCTION(func); self = PyCFunction_GET_SELF(func); if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) return NULL; result = cfunc(self, arg); Py_LeaveRecursiveCall(); if (unlikely(!result) && unlikely(!PyErr_Occurred())) { PyErr_SetString( PyExc_SystemError, "NULL result without error in PyObject_Call"); } return result; } #endif /////////////// PyObjectCallOneArg.proto /////////////// static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); /*proto*/ /////////////// PyObjectCallOneArg /////////////// //@requires: PyObjectCallMethO //@requires: PyObjectCall #if CYTHON_COMPILING_IN_CPYTHON static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { PyObject *result; PyObject *args = PyTuple_New(1); if (unlikely(!args)) return NULL; Py_INCREF(arg); PyTuple_SET_ITEM(args, 0, arg); result = __Pyx_PyObject_Call(func, args, NULL); Py_DECREF(args); return result; } static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { #ifdef __Pyx_CyFunction_USED if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) { #else if (likely(PyCFunction_Check(func))) { #endif if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { // fast and simple case that we are optimising for return __Pyx_PyObject_CallMethO(func, arg); } } return __Pyx__PyObject_CallOneArg(func, arg); } #else static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { PyObject *result; PyObject *args = PyTuple_Pack(1, arg); if (unlikely(!args)) return NULL; result = __Pyx_PyObject_Call(func, args, NULL); Py_DECREF(args); return result; } #endif /////////////// PyObjectCallNoArg.proto /////////////// //@requires: PyObjectCall //@substitute: naming #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); /*proto*/ #else #define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, $empty_tuple, NULL) #endif /////////////// PyObjectCallNoArg /////////////// //@requires: PyObjectCallMethO //@requires: PyObjectCall //@substitute: naming #if CYTHON_COMPILING_IN_CPYTHON static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { #ifdef __Pyx_CyFunction_USED if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) { #else if (likely(PyCFunction_Check(func))) { #endif if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) { // fast and simple case that we are optimising for return __Pyx_PyObject_CallMethO(func, NULL); } } return __Pyx_PyObject_Call(func, $empty_tuple, NULL); } #endif /////////////// MatrixMultiply.proto /////////////// #if PY_VERSION_HEX >= 0x03050000 #define __Pyx_PyNumber_MatrixMultiply(x,y) PyNumber_MatrixMultiply(x,y) #define __Pyx_PyNumber_InPlaceMatrixMultiply(x,y) PyNumber_InPlaceMatrixMultiply(x,y) #else #define __Pyx_PyNumber_MatrixMultiply(x,y) __Pyx__PyNumber_MatrixMultiply(x, y, "@") static PyObject* __Pyx__PyNumber_MatrixMultiply(PyObject* x, PyObject* y, const char* op_name); static PyObject* __Pyx_PyNumber_InPlaceMatrixMultiply(PyObject* x, PyObject* y); #endif /////////////// MatrixMultiply /////////////// //@requires: PyObjectGetAttrStr //@requires: PyObjectCallOneArg #if PY_VERSION_HEX < 0x03050000 static PyObject* __Pyx_PyObject_CallMatrixMethod(PyObject* method, PyObject* arg) { // NOTE: eats the method reference PyObject *result = NULL; #if CYTHON_COMPILING_IN_CPYTHON if (likely(PyMethod_Check(method))) { PyObject *self = PyMethod_GET_SELF(method); if (likely(self)) { PyObject *args; PyObject *function = PyMethod_GET_FUNCTION(method); args = PyTuple_New(2); if (unlikely(!args)) goto bad; Py_INCREF(self); PyTuple_SET_ITEM(args, 0, self); Py_INCREF(arg); PyTuple_SET_ITEM(args, 1, arg); Py_INCREF(function); Py_DECREF(method); method = NULL; result = __Pyx_PyObject_Call(function, args, NULL); Py_DECREF(args); Py_DECREF(function); return result; } } #endif result = __Pyx_PyObject_CallOneArg(method, arg); bad: Py_DECREF(method); return result; } #define __Pyx_TryMatrixMethod(x, y, py_method_name) { \ PyObject *func = __Pyx_PyObject_GetAttrStr(x, py_method_name); \ if (func) { \ PyObject *result = __Pyx_PyObject_CallMatrixMethod(func, y); \ if (result != Py_NotImplemented) \ return result; \ Py_DECREF(result); \ } else { \ if (!PyErr_ExceptionMatches(PyExc_AttributeError)) \ return NULL; \ PyErr_Clear(); \ } \ } static PyObject* __Pyx__PyNumber_MatrixMultiply(PyObject* x, PyObject* y, const char* op_name) { int right_is_subtype = PyObject_IsSubclass((PyObject*)Py_TYPE(y), (PyObject*)Py_TYPE(x)); if (unlikely(right_is_subtype == -1)) return NULL; if (right_is_subtype) { // to allow subtypes to override parent behaviour, try reversed operation first // see note at https://docs.python.org/3/reference/datamodel.html#emulating-numeric-types __Pyx_TryMatrixMethod(y, x, PYIDENT("__rmatmul__")) } __Pyx_TryMatrixMethod(x, y, PYIDENT("__matmul__")) if (!right_is_subtype) { __Pyx_TryMatrixMethod(y, x, PYIDENT("__rmatmul__")) } PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for %.2s: '%.100s' and '%.100s'", op_name, Py_TYPE(x)->tp_name, Py_TYPE(y)->tp_name); return NULL; } static PyObject* __Pyx_PyNumber_InPlaceMatrixMultiply(PyObject* x, PyObject* y) { __Pyx_TryMatrixMethod(x, y, PYIDENT("__imatmul__")) return __Pyx__PyNumber_MatrixMultiply(x, y, "@="); } #undef __Pyx_TryMatrixMethod #endif Cython-0.23.4/Cython/Utility/ModuleSetupCode.c0000644000175600017570000005203512606202452022325 0ustar jenkinsjenkins00000000000000/////////////// CModulePreamble /////////////// #include /* For offsetof */ #ifndef offsetof #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) #endif #if !defined(WIN32) && !defined(MS_WINDOWS) #ifndef __stdcall #define __stdcall #endif #ifndef __cdecl #define __cdecl #endif #ifndef __fastcall #define __fastcall #endif #endif #ifndef DL_IMPORT #define DL_IMPORT(t) t #endif #ifndef DL_EXPORT #define DL_EXPORT(t) t #endif #ifndef PY_LONG_LONG #define PY_LONG_LONG LONG_LONG #endif #ifndef Py_HUGE_VAL #define Py_HUGE_VAL HUGE_VAL #endif #ifdef PYPY_VERSION #define CYTHON_COMPILING_IN_PYPY 1 #define CYTHON_COMPILING_IN_CPYTHON 0 #else #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_CPYTHON 1 #endif #if !defined(CYTHON_USE_PYLONG_INTERNALS) && CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02070000 #define CYTHON_USE_PYLONG_INTERNALS 1 #endif #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) #define Py_OptimizeFlag 0 #endif #define __PYX_BUILD_PY_SSIZE_T "n" #define CYTHON_FORMAT_SSIZE_T "z" #if PY_MAJOR_VERSION < 3 #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \ PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) #define __Pyx_DefaultClassType PyClass_Type #else #define __Pyx_BUILTIN_MODULE_NAME "builtins" #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) #define __Pyx_DefaultClassType PyType_Type #endif #ifndef Py_TPFLAGS_CHECKTYPES #define Py_TPFLAGS_CHECKTYPES 0 #endif #ifndef Py_TPFLAGS_HAVE_INDEX #define Py_TPFLAGS_HAVE_INDEX 0 #endif #ifndef Py_TPFLAGS_HAVE_NEWBUFFER #define Py_TPFLAGS_HAVE_NEWBUFFER 0 #endif #ifndef Py_TPFLAGS_HAVE_FINALIZE #define Py_TPFLAGS_HAVE_FINALIZE 0 #endif /* new Py3.3 unicode type (PEP 393) */ #if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) #define CYTHON_PEP393_ENABLED 1 #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \ 0 : _PyUnicode_Ready((PyObject *)(op))) #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) #else #define CYTHON_PEP393_ENABLED 0 #define __Pyx_PyUnicode_READY(op) (0) #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) /* (void)(k) => avoid unused variable warning due to macro: */ #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) #endif #if CYTHON_COMPILING_IN_PYPY #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) #else #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) #endif #if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) #endif #define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) #define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) #else #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) #endif #if PY_MAJOR_VERSION >= 3 #define PyBaseString_Type PyUnicode_Type #define PyStringObject PyUnicodeObject #define PyString_Type PyUnicode_Type #define PyString_Check PyUnicode_Check #define PyString_CheckExact PyUnicode_CheckExact #endif #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) #else #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) #endif #ifndef PySet_CheckExact #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) #endif #define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) #if PY_MAJOR_VERSION >= 3 #define PyIntObject PyLongObject #define PyInt_Type PyLong_Type #define PyInt_Check(op) PyLong_Check(op) #define PyInt_CheckExact(op) PyLong_CheckExact(op) #define PyInt_FromString PyLong_FromString #define PyInt_FromUnicode PyLong_FromUnicode #define PyInt_FromLong PyLong_FromLong #define PyInt_FromSize_t PyLong_FromSize_t #define PyInt_FromSsize_t PyLong_FromSsize_t #define PyInt_AsLong PyLong_AsLong #define PyInt_AS_LONG PyLong_AS_LONG #define PyInt_AsSsize_t PyLong_AsSsize_t #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask #define PyNumber_Int PyNumber_Long #endif #if PY_MAJOR_VERSION >= 3 #define PyBoolObject PyLongObject #endif #if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY #ifndef PyUnicode_InternFromString #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) #endif #endif #if PY_VERSION_HEX < 0x030200A4 typedef long Py_hash_t; #define __Pyx_PyInt_FromHash_t PyInt_FromLong #define __Pyx_PyInt_AsHash_t PyInt_AsLong #else #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t #endif #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func)) #else #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) #endif // backport of PyAsyncMethods from Py3.5 to older Py3.x versions // (mis-)using the "tp_reserved" type slot which is re-activated as "tp_as_async" in Py3.5 #if PY_VERSION_HEX >= 0x030500B1 #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) #elif CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 typedef struct { unaryfunc am_await; unaryfunc am_aiter; unaryfunc am_anext; } __Pyx_PyAsyncMethodsStruct; #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) #else #define __Pyx_PyType_AsAsync(obj) NULL #endif // restrict #ifndef CYTHON_RESTRICT #if defined(__GNUC__) #define CYTHON_RESTRICT __restrict__ #elif defined(_MSC_VER) && _MSC_VER >= 1400 #define CYTHON_RESTRICT __restrict #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define CYTHON_RESTRICT restrict #else #define CYTHON_RESTRICT #endif #endif #define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) /////////////// CInitCode /////////////// // inline attribute #ifndef CYTHON_INLINE #if defined(__GNUC__) #define CYTHON_INLINE __inline__ #elif defined(_MSC_VER) #define CYTHON_INLINE __inline #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define CYTHON_INLINE inline #else #define CYTHON_INLINE #endif #endif /////////////// CppInitCode /////////////// #ifndef __cplusplus #error "Cython files generated with the C++ option must be compiled with a C++ compiler." #endif // inline attribute #ifndef CYTHON_INLINE #define CYTHON_INLINE inline #endif // Work around clang bug http://stackoverflow.com/questions/21847816/c-invoke-nested-template-class-destructor template void __Pyx_call_destructor(T& x) { x.~T(); } // Used for temporary variables of "reference" type. template class __Pyx_FakeReference { public: __Pyx_FakeReference() : ptr(NULL) { } // __Pyx_FakeReference(T& ref) : ptr(&ref) { } // Const version needed as Cython doesn't know about const overloads (e.g. for stl containers). __Pyx_FakeReference(const T& ref) : ptr(const_cast(&ref)) { } T *operator->() { return ptr; } operator T&() { return *ptr; } private: T *ptr; }; /////////////// MathInitCode /////////////// #if defined(WIN32) || defined(MS_WINDOWS) #define _USE_MATH_DEFINES #endif #include #ifdef NAN #define __PYX_NAN() ((float) NAN) #else static CYTHON_INLINE float __PYX_NAN() { // Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and // a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is // a quiet NaN. float value; memset(&value, 0xFF, sizeof(value)); return value; } #endif /////////////// UtilityFunctionPredeclarations.proto /////////////// /* unused attribute */ #ifndef CYTHON_UNUSED # if defined(__GNUC__) # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) # define CYTHON_UNUSED __attribute__ ((__unused__)) # else # define CYTHON_UNUSED # endif # elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) # define CYTHON_UNUSED __attribute__ ((__unused__)) # else # define CYTHON_UNUSED # endif #endif #ifndef CYTHON_NCP_UNUSED # if CYTHON_COMPILING_IN_CPYTHON # define CYTHON_NCP_UNUSED # else # define CYTHON_NCP_UNUSED CYTHON_UNUSED # endif #endif typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/ /////////////// ForceInitThreads.proto /////////////// #ifndef __PYX_FORCE_INIT_THREADS #define __PYX_FORCE_INIT_THREADS 0 #endif /////////////// InitThreads.init /////////////// #ifdef WITH_THREAD PyEval_InitThreads(); #endif /////////////// CodeObjectCache.proto /////////////// typedef struct { int code_line; PyCodeObject* code_object; } __Pyx_CodeObjectCacheEntry; struct __Pyx_CodeObjectCache { int count; int max_count; __Pyx_CodeObjectCacheEntry* entries; }; static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); static PyCodeObject *__pyx_find_code_object(int code_line); static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); /////////////// CodeObjectCache /////////////// // Note that errors are simply ignored in the code below. // This is just a cache, if a lookup or insertion fails - so what? static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { int start = 0, mid = 0, end = count - 1; if (end >= 0 && code_line > entries[end].code_line) { return count; } while (start < end) { mid = start + (end - start) / 2; if (code_line < entries[mid].code_line) { end = mid; } else if (code_line > entries[mid].code_line) { start = mid + 1; } else { return mid; } } if (code_line <= entries[mid].code_line) { return mid; } else { return mid + 1; } } static PyCodeObject *__pyx_find_code_object(int code_line) { PyCodeObject* code_object; int pos; if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { return NULL; } pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { return NULL; } code_object = __pyx_code_cache.entries[pos].code_object; Py_INCREF(code_object); return code_object; } static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { int pos, i; __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; if (unlikely(!code_line)) { return; } if (unlikely(!entries)) { entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); if (likely(entries)) { __pyx_code_cache.entries = entries; __pyx_code_cache.max_count = 64; __pyx_code_cache.count = 1; entries[0].code_line = code_line; entries[0].code_object = code_object; Py_INCREF(code_object); } return; } pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { PyCodeObject* tmp = entries[pos].code_object; entries[pos].code_object = code_object; Py_DECREF(tmp); return; } if (__pyx_code_cache.count == __pyx_code_cache.max_count) { int new_max = __pyx_code_cache.max_count + 64; entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry)); if (unlikely(!entries)) { return; } __pyx_code_cache.entries = entries; __pyx_code_cache.max_count = new_max; } for (i=__pyx_code_cache.count; i>pos; i--) { entries[i] = entries[i-1]; } entries[pos].code_line = code_line; entries[pos].code_object = code_object; __pyx_code_cache.count++; Py_INCREF(code_object); } /////////////// CodeObjectCache.cleanup /////////////// if (__pyx_code_cache.entries) { __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; int i, count = __pyx_code_cache.count; __pyx_code_cache.count = 0; __pyx_code_cache.max_count = 0; __pyx_code_cache.entries = NULL; for (i=0; iSetupContext((name), __LINE__, __FILE__); \ PyGILState_Release(__pyx_gilstate_save); \ } else { \ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \ } #else #define __Pyx_RefNannySetupContext(name, acquire_gil) \ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) #endif #define __Pyx_RefNannyFinishContext() \ __Pyx_RefNanny->FinishContext(&__pyx_refnanny) #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) #else #define __Pyx_RefNannyDeclarations #define __Pyx_RefNannySetupContext(name, acquire_gil) #define __Pyx_RefNannyFinishContext() #define __Pyx_INCREF(r) Py_INCREF(r) #define __Pyx_DECREF(r) Py_DECREF(r) #define __Pyx_GOTREF(r) #define __Pyx_GIVEREF(r) #define __Pyx_XINCREF(r) Py_XINCREF(r) #define __Pyx_XDECREF(r) Py_XDECREF(r) #define __Pyx_XGOTREF(r) #define __Pyx_XGIVEREF(r) #endif /* CYTHON_REFNANNY */ #define __Pyx_XDECREF_SET(r, v) do { \ PyObject *tmp = (PyObject *) r; \ r = v; __Pyx_XDECREF(tmp); \ } while (0) #define __Pyx_DECREF_SET(r, v) do { \ PyObject *tmp = (PyObject *) r; \ r = v; __Pyx_DECREF(tmp); \ } while (0) #define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) #define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) /////////////// Refnanny /////////////// #if CYTHON_REFNANNY static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { PyObject *m = NULL, *p = NULL; void *r = NULL; m = PyImport_ImportModule((char *)modname); if (!m) goto end; p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); if (!p) goto end; r = PyLong_AsVoidPtr(p); end: Py_XDECREF(p); Py_XDECREF(m); return (__Pyx_RefNannyAPIStruct *)r; } #endif /* CYTHON_REFNANNY */ /////////////// RegisterModuleCleanup.proto /////////////// //@substitute: naming static void ${cleanup_cname}(PyObject *self); /*proto*/ static int __Pyx_RegisterCleanup(void); /*proto*/ /////////////// RegisterModuleCleanup /////////////// //@substitute: naming //@requires: ImportExport.c::ModuleImport #if PY_MAJOR_VERSION < 3 static PyObject* ${cleanup_cname}_atexit(PyObject *module, CYTHON_UNUSED PyObject *unused) { ${cleanup_cname}(module); Py_INCREF(Py_None); return Py_None; } static int __Pyx_RegisterCleanup(void) { // Don't use Py_AtExit because that has a 32-call limit and is called // after python finalization. // Also, we try to prepend the cleanup function to "atexit._exithandlers" // in Py2 because CPython runs them last-to-first. Being run last allows // user exit code to run before us that may depend on the globals // and cached objects that we are about to clean up. static PyMethodDef cleanup_def = { "__cleanup", (PyCFunction)${cleanup_cname}_atexit, METH_NOARGS, 0}; PyObject *cleanup_func = 0; PyObject *atexit = 0; PyObject *reg = 0; PyObject *args = 0; PyObject *res = 0; int ret = -1; cleanup_func = PyCFunction_New(&cleanup_def, 0); if (!cleanup_func) goto bad; atexit = __Pyx_ImportModule("atexit"); if (!atexit) goto bad; reg = PyObject_GetAttrString(atexit, "_exithandlers"); if (reg && PyList_Check(reg)) { PyObject *a, *kw; a = PyTuple_New(0); kw = PyDict_New(); if (!a || !kw) { Py_XDECREF(a); Py_XDECREF(kw); goto bad; } args = PyTuple_Pack(3, cleanup_func, a, kw); Py_DECREF(a); Py_DECREF(kw); if (!args) goto bad; ret = PyList_Insert(reg, 0, args); } else { if (!reg) PyErr_Clear(); Py_XDECREF(reg); reg = PyObject_GetAttrString(atexit, "register"); if (!reg) goto bad; args = PyTuple_Pack(1, cleanup_func); if (!args) goto bad; res = PyObject_CallObject(reg, args); if (!res) goto bad; ret = 0; } bad: Py_XDECREF(cleanup_func); Py_XDECREF(atexit); Py_XDECREF(reg); Py_XDECREF(args); Py_XDECREF(res); return ret; } #else // fake call purely to work around "unused function" warning for __Pyx_ImportModule() static int __Pyx_RegisterCleanup(void) { if (0) __Pyx_ImportModule(NULL); return 0; } #endif Cython-0.23.4/Cython/Utility/MemoryView_C.c0000644000175600017570000006757412606202452021647 0ustar jenkinsjenkins00000000000000////////// MemviewSliceStruct.proto ////////// /* memoryview slice struct */ struct {{memview_struct_name}}; typedef struct { struct {{memview_struct_name}} *memview; char *data; Py_ssize_t shape[{{max_dims}}]; Py_ssize_t strides[{{max_dims}}]; Py_ssize_t suboffsets[{{max_dims}}]; } {{memviewslice_name}}; /////////// Atomics.proto ///////////// #include #ifndef CYTHON_ATOMICS #define CYTHON_ATOMICS 1 #endif #define __pyx_atomic_int_type int // todo: Portland pgcc, maybe OS X's OSAtomicIncrement32, // libatomic + autotools-like distutils support? Such a pain... #if CYTHON_ATOMICS && __GNUC__ >= 4 && (__GNUC_MINOR__ > 1 || \ (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL >= 2)) && \ !defined(__i386__) /* gcc >= 4.1.2 */ #define __pyx_atomic_incr_aligned(value, lock) __sync_fetch_and_add(value, 1) #define __pyx_atomic_decr_aligned(value, lock) __sync_fetch_and_sub(value, 1) #ifdef __PYX_DEBUG_ATOMICS #warning "Using GNU atomics" #endif #elif CYTHON_ATOMICS && defined(_MSC_VER) && 0 /* msvc */ #include #undef __pyx_atomic_int_type #define __pyx_atomic_int_type LONG #define __pyx_atomic_incr_aligned(value, lock) InterlockedIncrement(value) #define __pyx_atomic_decr_aligned(value, lock) InterlockedDecrement(value) #ifdef __PYX_DEBUG_ATOMICS #pragma message ("Using MSVC atomics") #endif #elif CYTHON_ATOMICS && (defined(__ICC) || defined(__INTEL_COMPILER)) && 0 #define __pyx_atomic_incr_aligned(value, lock) _InterlockedIncrement(value) #define __pyx_atomic_decr_aligned(value, lock) _InterlockedDecrement(value) #ifdef __PYX_DEBUG_ATOMICS #warning "Using Intel atomics" #endif #else #undef CYTHON_ATOMICS #define CYTHON_ATOMICS 0 #ifdef __PYX_DEBUG_ATOMICS #warning "Not using atomics" #endif #endif typedef volatile __pyx_atomic_int_type __pyx_atomic_int; #if CYTHON_ATOMICS #define __pyx_add_acquisition_count(memview) \ __pyx_atomic_incr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock) #define __pyx_sub_acquisition_count(memview) \ __pyx_atomic_decr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock) #else #define __pyx_add_acquisition_count(memview) \ __pyx_add_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock) #define __pyx_sub_acquisition_count(memview) \ __pyx_sub_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock) #endif /////////////// ObjectToMemviewSlice.proto /////////////// static CYTHON_INLINE {{memviewslice_name}} {{funcname}}(PyObject *); ////////// MemviewSliceInit.proto ////////// #define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d #define __Pyx_MEMVIEW_DIRECT 1 #define __Pyx_MEMVIEW_PTR 2 #define __Pyx_MEMVIEW_FULL 4 #define __Pyx_MEMVIEW_CONTIG 8 #define __Pyx_MEMVIEW_STRIDED 16 #define __Pyx_MEMVIEW_FOLLOW 32 #define __Pyx_IS_C_CONTIG 1 #define __Pyx_IS_F_CONTIG 2 static int __Pyx_init_memviewslice( struct __pyx_memoryview_obj *memview, int ndim, __Pyx_memviewslice *memviewslice, int memview_is_new_reference); static CYTHON_INLINE int __pyx_add_acquisition_count_locked( __pyx_atomic_int *acquisition_count, PyThread_type_lock lock); static CYTHON_INLINE int __pyx_sub_acquisition_count_locked( __pyx_atomic_int *acquisition_count, PyThread_type_lock lock); #define __pyx_get_slice_count_pointer(memview) (memview->acquisition_count_aligned_p) #define __pyx_get_slice_count(memview) (*__pyx_get_slice_count_pointer(memview)) #define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__) #define __PYX_XDEC_MEMVIEW(slice, have_gil) __Pyx_XDEC_MEMVIEW(slice, have_gil, __LINE__) static CYTHON_INLINE void __Pyx_INC_MEMVIEW({{memviewslice_name}} *, int, int); static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *, int, int); /////////////// MemviewSliceIndex.proto /////////////// static CYTHON_INLINE char *__pyx_memviewslice_index_full( const char *bufp, Py_ssize_t idx, Py_ssize_t stride, Py_ssize_t suboffset); /////////////// ObjectToMemviewSlice /////////////// //@requires: MemviewSliceValidateAndInit static CYTHON_INLINE {{memviewslice_name}} {{funcname}}(PyObject *obj) { {{memviewslice_name}} result = {{memslice_init}}; __Pyx_BufFmt_StackElem stack[{{struct_nesting_depth}}]; int axes_specs[] = { {{axes_specs}} }; int retcode; if (obj == Py_None) { /* We don't bother to refcount None */ result.memview = (struct __pyx_memoryview_obj *) Py_None; return result; } retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, {{c_or_f_flag}}, {{buf_flag}}, {{ndim}}, &{{dtype_typeinfo}}, stack, &result, obj); if (unlikely(retcode == -1)) goto __pyx_fail; return result; __pyx_fail: result.memview = NULL; result.data = NULL; return result; } /////////////// MemviewSliceValidateAndInit.proto /////////////// static int __Pyx_ValidateAndInit_memviewslice( int *axes_specs, int c_or_f_flag, int buf_flags, int ndim, __Pyx_TypeInfo *dtype, __Pyx_BufFmt_StackElem stack[], __Pyx_memviewslice *memviewslice, PyObject *original_obj); /////////////// MemviewSliceValidateAndInit /////////////// //@requires: Buffer.c::TypeInfoCompare static int __pyx_check_strides(Py_buffer *buf, int dim, int ndim, int spec) { if (buf->shape[dim] <= 1) return 1; if (buf->strides) { if (spec & __Pyx_MEMVIEW_CONTIG) { if (spec & (__Pyx_MEMVIEW_PTR|__Pyx_MEMVIEW_FULL)) { if (buf->strides[dim] != sizeof(void *)) { PyErr_Format(PyExc_ValueError, "Buffer is not indirectly contiguous " "in dimension %d.", dim); goto fail; } } else if (buf->strides[dim] != buf->itemsize) { PyErr_SetString(PyExc_ValueError, "Buffer and memoryview are not contiguous " "in the same dimension."); goto fail; } } if (spec & __Pyx_MEMVIEW_FOLLOW) { Py_ssize_t stride = buf->strides[dim]; if (stride < 0) stride = -stride; if (stride < buf->itemsize) { PyErr_SetString(PyExc_ValueError, "Buffer and memoryview are not contiguous " "in the same dimension."); goto fail; } } } else { if (spec & __Pyx_MEMVIEW_CONTIG && dim != ndim - 1) { PyErr_Format(PyExc_ValueError, "C-contiguous buffer is not contiguous in " "dimension %d", dim); goto fail; } else if (spec & (__Pyx_MEMVIEW_PTR)) { PyErr_Format(PyExc_ValueError, "C-contiguous buffer is not indirect in " "dimension %d", dim); goto fail; } else if (buf->suboffsets) { PyErr_SetString(PyExc_ValueError, "Buffer exposes suboffsets but no strides"); goto fail; } } return 1; fail: return 0; } static int __pyx_check_suboffsets(Py_buffer *buf, int dim, CYTHON_UNUSED int ndim, int spec) { // Todo: without PyBUF_INDIRECT we may not have suboffset information, i.e., the // ptr may not be set to NULL but may be uninitialized? if (spec & __Pyx_MEMVIEW_DIRECT) { if (buf->suboffsets && buf->suboffsets[dim] >= 0) { PyErr_Format(PyExc_ValueError, "Buffer not compatible with direct access " "in dimension %d.", dim); goto fail; } } if (spec & __Pyx_MEMVIEW_PTR) { if (!buf->suboffsets || (buf->suboffsets && buf->suboffsets[dim] < 0)) { PyErr_Format(PyExc_ValueError, "Buffer is not indirectly accessible " "in dimension %d.", dim); goto fail; } } return 1; fail: return 0; } static int __pyx_verify_contig(Py_buffer *buf, int ndim, int c_or_f_flag) { int i; if (c_or_f_flag & __Pyx_IS_F_CONTIG) { Py_ssize_t stride = 1; for (i = 0; i < ndim; i++) { if (stride * buf->itemsize != buf->strides[i] && buf->shape[i] > 1) { PyErr_SetString(PyExc_ValueError, "Buffer not fortran contiguous."); goto fail; } stride = stride * buf->shape[i]; } } else if (c_or_f_flag & __Pyx_IS_C_CONTIG) { Py_ssize_t stride = 1; for (i = ndim - 1; i >- 1; i--) { if (stride * buf->itemsize != buf->strides[i] && buf->shape[i] > 1) { PyErr_SetString(PyExc_ValueError, "Buffer not C contiguous."); goto fail; } stride = stride * buf->shape[i]; } } return 1; fail: return 0; } static int __Pyx_ValidateAndInit_memviewslice( int *axes_specs, int c_or_f_flag, int buf_flags, int ndim, __Pyx_TypeInfo *dtype, __Pyx_BufFmt_StackElem stack[], __Pyx_memviewslice *memviewslice, PyObject *original_obj) { struct __pyx_memoryview_obj *memview, *new_memview; __Pyx_RefNannyDeclarations Py_buffer *buf; int i, spec = 0, retval = -1; __Pyx_BufFmt_Context ctx; int from_memoryview = __pyx_memoryview_check(original_obj); __Pyx_RefNannySetupContext("ValidateAndInit_memviewslice", 0); if (from_memoryview && __pyx_typeinfo_cmp(dtype, ((struct __pyx_memoryview_obj *) original_obj)->typeinfo)) { /* We have a matching dtype, skip format parsing */ memview = (struct __pyx_memoryview_obj *) original_obj; new_memview = NULL; } else { memview = (struct __pyx_memoryview_obj *) __pyx_memoryview_new( original_obj, buf_flags, 0, dtype); new_memview = memview; if (unlikely(!memview)) goto fail; } buf = &memview->view; if (buf->ndim != ndim) { PyErr_Format(PyExc_ValueError, "Buffer has wrong number of dimensions (expected %d, got %d)", ndim, buf->ndim); goto fail; } if (new_memview) { __Pyx_BufFmt_Init(&ctx, stack, dtype); if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; } if ((unsigned) buf->itemsize != dtype->size) { PyErr_Format(PyExc_ValueError, "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "u byte%s) " "does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "u byte%s)", buf->itemsize, (buf->itemsize > 1) ? "s" : "", dtype->name, dtype->size, (dtype->size > 1) ? "s" : ""); goto fail; } /* Check axes */ for (i = 0; i < ndim; i++) { spec = axes_specs[i]; if (!__pyx_check_strides(buf, i, ndim, spec)) goto fail; if (!__pyx_check_suboffsets(buf, i, ndim, spec)) goto fail; } /* Check contiguity */ if (buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag)) goto fail; /* Initialize */ if (unlikely(__Pyx_init_memviewslice(memview, ndim, memviewslice, new_memview != NULL) == -1)) { goto fail; } retval = 0; goto no_fail; fail: Py_XDECREF(new_memview); retval = -1; no_fail: __Pyx_RefNannyFinishContext(); return retval; } ////////// MemviewSliceInit ////////// static int __Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview, int ndim, {{memviewslice_name}} *memviewslice, int memview_is_new_reference) { __Pyx_RefNannyDeclarations int i, retval=-1; Py_buffer *buf = &memview->view; __Pyx_RefNannySetupContext("init_memviewslice", 0); if (!buf) { PyErr_SetString(PyExc_ValueError, "buf is NULL."); goto fail; } else if (memviewslice->memview || memviewslice->data) { PyErr_SetString(PyExc_ValueError, "memviewslice is already initialized!"); goto fail; } if (buf->strides) { for (i = 0; i < ndim; i++) { memviewslice->strides[i] = buf->strides[i]; } } else { Py_ssize_t stride = buf->itemsize; for (i = ndim - 1; i >= 0; i--) { memviewslice->strides[i] = stride; stride *= buf->shape[i]; } } for (i = 0; i < ndim; i++) { memviewslice->shape[i] = buf->shape[i]; if (buf->suboffsets) { memviewslice->suboffsets[i] = buf->suboffsets[i]; } else { memviewslice->suboffsets[i] = -1; } } memviewslice->memview = memview; memviewslice->data = (char *)buf->buf; if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) { Py_INCREF(memview); } retval = 0; goto no_fail; fail: /* Don't decref, the memoryview may be borrowed. Let the caller do the cleanup */ /* __Pyx_XDECREF(memviewslice->memview); */ memviewslice->memview = 0; memviewslice->data = 0; retval = -1; no_fail: __Pyx_RefNannyFinishContext(); return retval; } static CYTHON_INLINE void __pyx_fatalerror(const char *fmt, ...) { va_list vargs; char msg[200]; #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, fmt); #else va_start(vargs); #endif vsnprintf(msg, 200, fmt, vargs); Py_FatalError(msg); va_end(vargs); } static CYTHON_INLINE int __pyx_add_acquisition_count_locked(__pyx_atomic_int *acquisition_count, PyThread_type_lock lock) { int result; PyThread_acquire_lock(lock, 1); result = (*acquisition_count)++; PyThread_release_lock(lock); return result; } static CYTHON_INLINE int __pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count, PyThread_type_lock lock) { int result; PyThread_acquire_lock(lock, 1); result = (*acquisition_count)--; PyThread_release_lock(lock); return result; } static CYTHON_INLINE void __Pyx_INC_MEMVIEW({{memviewslice_name}} *memslice, int have_gil, int lineno) { int first_time; struct {{memview_struct_name}} *memview = memslice->memview; if (!memview || (PyObject *) memview == Py_None) return; /* allow uninitialized memoryview assignment */ if (__pyx_get_slice_count(memview) < 0) __pyx_fatalerror("Acquisition count is %d (line %d)", __pyx_get_slice_count(memview), lineno); first_time = __pyx_add_acquisition_count(memview) == 0; if (first_time) { if (have_gil) { Py_INCREF((PyObject *) memview); } else { PyGILState_STATE _gilstate = PyGILState_Ensure(); Py_INCREF((PyObject *) memview); PyGILState_Release(_gilstate); } } } static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *memslice, int have_gil, int lineno) { int last_time; struct {{memview_struct_name}} *memview = memslice->memview; if (!memview ) { return; } else if ((PyObject *) memview == Py_None) { memslice->memview = NULL; return; } if (__pyx_get_slice_count(memview) <= 0) __pyx_fatalerror("Acquisition count is %d (line %d)", __pyx_get_slice_count(memview), lineno); last_time = __pyx_sub_acquisition_count(memview) == 1; memslice->data = NULL; if (last_time) { if (have_gil) { Py_CLEAR(memslice->memview); } else { PyGILState_STATE _gilstate = PyGILState_Ensure(); Py_CLEAR(memslice->memview); PyGILState_Release(_gilstate); } } else { memslice->memview = NULL; } } ////////// MemviewSliceCopyTemplate.proto ////////// static {{memviewslice_name}} __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, const char *mode, int ndim, size_t sizeof_dtype, int contig_flag, int dtype_is_object); ////////// MemviewSliceCopyTemplate ////////// static {{memviewslice_name}} __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, const char *mode, int ndim, size_t sizeof_dtype, int contig_flag, int dtype_is_object) { __Pyx_RefNannyDeclarations int i; __Pyx_memviewslice new_mvs = {{memslice_init}}; struct __pyx_memoryview_obj *from_memview = from_mvs->memview; Py_buffer *buf = &from_memview->view; PyObject *shape_tuple = NULL; PyObject *temp_int = NULL; struct __pyx_array_obj *array_obj = NULL; struct __pyx_memoryview_obj *memview_obj = NULL; __Pyx_RefNannySetupContext("__pyx_memoryview_copy_new_contig", 0); for (i = 0; i < ndim; i++) { if (from_mvs->suboffsets[i] >= 0) { PyErr_Format(PyExc_ValueError, "Cannot copy memoryview slice with " "indirect dimensions (axis %d)", i); goto fail; } } shape_tuple = PyTuple_New(ndim); if (unlikely(!shape_tuple)) { goto fail; } __Pyx_GOTREF(shape_tuple); for(i = 0; i < ndim; i++) { temp_int = PyInt_FromSsize_t(from_mvs->shape[i]); if(unlikely(!temp_int)) { goto fail; } else { PyTuple_SET_ITEM(shape_tuple, i, temp_int); temp_int = NULL; } } array_obj = __pyx_array_new(shape_tuple, sizeof_dtype, buf->format, (char *) mode, NULL); if (unlikely(!array_obj)) { goto fail; } __Pyx_GOTREF(array_obj); memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new( (PyObject *) array_obj, contig_flag, dtype_is_object, from_mvs->memview->typeinfo); if (unlikely(!memview_obj)) goto fail; /* initialize new_mvs */ if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs, 1) < 0)) goto fail; if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim, dtype_is_object) < 0)) goto fail; goto no_fail; fail: __Pyx_XDECREF(new_mvs.memview); new_mvs.memview = NULL; new_mvs.data = NULL; no_fail: __Pyx_XDECREF(shape_tuple); __Pyx_XDECREF(temp_int); __Pyx_XDECREF(array_obj); __Pyx_RefNannyFinishContext(); return new_mvs; } ////////// CopyContentsUtility.proto ///////// #define {{func_cname}}(slice) \ __pyx_memoryview_copy_new_contig(&slice, "{{mode}}", {{ndim}}, \ sizeof({{dtype_decl}}), {{contig_flag}}, \ {{dtype_is_object}}) ////////// OverlappingSlices.proto ////////// static int __pyx_slices_overlap({{memviewslice_name}} *slice1, {{memviewslice_name}} *slice2, int ndim, size_t itemsize); ////////// OverlappingSlices ////////// /* Based on numpy's core/src/multiarray/array_assign.c */ /* Gets a half-open range [start, end) which contains the array data */ static void __pyx_get_array_memory_extents({{memviewslice_name}} *slice, void **out_start, void **out_end, int ndim, size_t itemsize) { char *start, *end; int i; start = end = slice->data; for (i = 0; i < ndim; i++) { Py_ssize_t stride = slice->strides[i]; Py_ssize_t extent = slice->shape[i]; if (extent == 0) { *out_start = *out_end = start; return; } else { if (stride > 0) end += stride * (extent - 1); else start += stride * (extent - 1); } } /* Return a half-open range */ *out_start = start; *out_end = end + itemsize; } /* Returns 1 if the arrays have overlapping data, 0 otherwise */ static int __pyx_slices_overlap({{memviewslice_name}} *slice1, {{memviewslice_name}} *slice2, int ndim, size_t itemsize) { void *start1, *end1, *start2, *end2; __pyx_get_array_memory_extents(slice1, &start1, &end1, ndim, itemsize); __pyx_get_array_memory_extents(slice2, &start2, &end2, ndim, itemsize); return (start1 < end2) && (start2 < end1); } ////////// MemviewSliceIsCContig.proto ////////// #define __pyx_memviewslice_is_c_contig{{ndim}}(slice) \ __pyx_memviewslice_is_contig(&slice, 'C', {{ndim}}) ////////// MemviewSliceIsFContig.proto ////////// #define __pyx_memviewslice_is_f_contig{{ndim}}(slice) \ __pyx_memviewslice_is_contig(&slice, 'F', {{ndim}}) ////////// MemviewSliceIsContig.proto ////////// static int __pyx_memviewslice_is_contig(const {{memviewslice_name}} *mvs, char order, int ndim); ////////// MemviewSliceIsContig ////////// static int __pyx_memviewslice_is_contig(const {{memviewslice_name}} *mvs, char order, int ndim) { int i, index, step, start; Py_ssize_t itemsize = mvs->memview->view.itemsize; if (order == 'F') { step = 1; start = 0; } else { step = -1; start = ndim - 1; } for (i = 0; i < ndim; i++) { index = start + step * i; if (mvs->suboffsets[index] >= 0 || mvs->strides[index] != itemsize) return 0; itemsize *= mvs->shape[index]; } return 1; } /////////////// MemviewSliceIndex /////////////// static CYTHON_INLINE char * __pyx_memviewslice_index_full(const char *bufp, Py_ssize_t idx, Py_ssize_t stride, Py_ssize_t suboffset) { bufp = bufp + idx * stride; if (suboffset >= 0) { bufp = *((char **) bufp) + suboffset; } return (char *) bufp; } /////////////// MemviewDtypeToObject.proto /////////////// {{if to_py_function}} static PyObject *{{get_function}}(const char *itemp); /* proto */ {{endif}} {{if from_py_function}} static int {{set_function}}(const char *itemp, PyObject *obj); /* proto */ {{endif}} /////////////// MemviewDtypeToObject /////////////// {{#__pyx_memview__to_object}} /* Convert a dtype to or from a Python object */ {{if to_py_function}} static PyObject *{{get_function}}(const char *itemp) { return (PyObject *) {{to_py_function}}(*({{dtype}} *) itemp); } {{endif}} {{if from_py_function}} static int {{set_function}}(const char *itemp, PyObject *obj) { {{dtype}} value = {{from_py_function}}(obj); if ({{error_condition}}) return 0; *({{dtype}} *) itemp = value; return 1; } {{endif}} /////////////// MemviewObjectToObject.proto /////////////// /* Function callbacks (for memoryview object) for dtype object */ static PyObject *{{get_function}}(const char *itemp); /* proto */ static int {{set_function}}(const char *itemp, PyObject *obj); /* proto */ /////////////// MemviewObjectToObject /////////////// static PyObject *{{get_function}}(const char *itemp) { PyObject *result = *(PyObject **) itemp; Py_INCREF(result); return result; } static int {{set_function}}(const char *itemp, PyObject *obj) { Py_INCREF(obj); Py_DECREF(*(PyObject **) itemp); *(PyObject **) itemp = obj; return 1; } /////////// ToughSlice ////////// /* Dimension is indexed with 'start:stop:step' */ if (unlikely(__pyx_memoryview_slice_memviewslice( &{{dst}}, {{src}}.shape[{{dim}}], {{src}}.strides[{{dim}}], {{src}}.suboffsets[{{dim}}], {{dim}}, {{new_ndim}}, &{{get_suboffset_dim()}}, {{start}}, {{stop}}, {{step}}, {{int(have_start)}}, {{int(have_stop)}}, {{int(have_step)}}, 1) < 0)) { {{error_goto}} } ////////// SimpleSlice ////////// /* Dimension is indexed with ':' only */ {{dst}}.shape[{{new_ndim}}] = {{src}}.shape[{{dim}}]; {{dst}}.strides[{{new_ndim}}] = {{src}}.strides[{{dim}}]; {{if access == 'direct'}} {{dst}}.suboffsets[{{new_ndim}}] = -1; {{else}} {{dst}}.suboffsets[{{new_ndim}}] = {{src}}.suboffsets[{{dim}}]; if ({{src}}.suboffsets[{{dim}}] >= 0) {{get_suboffset_dim()}} = {{new_ndim}}; {{endif}} ////////// SliceIndex ////////// // Dimension is indexed with an integer, we could use the ToughSlice // approach, but this is faster { Py_ssize_t __pyx_tmp_idx = {{idx}}; Py_ssize_t __pyx_tmp_shape = {{src}}.shape[{{dim}}]; Py_ssize_t __pyx_tmp_stride = {{src}}.strides[{{dim}}]; if ({{wraparound}} && (__pyx_tmp_idx < 0)) __pyx_tmp_idx += __pyx_tmp_shape; if ({{boundscheck}} && (__pyx_tmp_idx < 0 || __pyx_tmp_idx >= __pyx_tmp_shape)) { {{if not have_gil}} #ifdef WITH_THREAD PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); #endif {{endif}} PyErr_SetString(PyExc_IndexError, "Index out of bounds (axis {{dim}})"); {{if not have_gil}} #ifdef WITH_THREAD PyGILState_Release(__pyx_gilstate_save); #endif {{endif}} {{error_goto}} } {{if all_dimensions_direct}} {{dst}}.data += __pyx_tmp_idx * __pyx_tmp_stride; {{else}} if ({{get_suboffset_dim()}} < 0) { {{dst}}.data += __pyx_tmp_idx * __pyx_tmp_stride; /* This dimension is the first dimension, or is preceded by */ /* direct or indirect dimensions that are indexed away. */ /* Hence suboffset_dim must be less than zero, and we can have */ /* our data pointer refer to another block by dereferencing. */ /* slice.data -> B -> C becomes slice.data -> C */ {{if indirect}} { Py_ssize_t __pyx_tmp_suboffset = {{src}}.suboffsets[{{dim}}]; {{if generic}} if (__pyx_tmp_suboffset >= 0) {{endif}} {{dst}}.data = *((char **) {{dst}}.data) + __pyx_tmp_suboffset; } {{endif}} } else { {{dst}}.suboffsets[{{get_suboffset_dim()}}] += __pyx_tmp_idx * __pyx_tmp_stride; /* Note: dimension can not be indirect, the compiler will have */ /* issued an error */ } {{endif}} } ////////// FillStrided1DScalar.proto ////////// static void __pyx_fill_slice_{{dtype_name}}({{type_decl}} *p, Py_ssize_t extent, Py_ssize_t stride, size_t itemsize, void *itemp); ////////// FillStrided1DScalar ////////// /* Fill a slice with a scalar value. The dimension is direct and strided or contiguous */ /* This can be used as a callback for the memoryview object to efficienty assign a scalar */ /* Currently unused */ static void __pyx_fill_slice_{{dtype_name}}({{type_decl}} *p, Py_ssize_t extent, Py_ssize_t stride, size_t itemsize, void *itemp) { Py_ssize_t i; {{type_decl}} item = *(({{type_decl}} *) itemp); {{type_decl}} *endp; stride /= sizeof({{type_decl}}); endp = p + stride * extent; while (p < endp) { *p = item; p += stride; } } Cython-0.23.4/Cython/Utility/MemoryView.pyx0000644000175600017570000013553512606202452021774 0ustar jenkinsjenkins00000000000000#################### View.MemoryView #################### # This utility provides cython.array and cython.view.memoryview from __future__ import absolute_import cimport cython # from cpython cimport ... cdef extern from "Python.h": int PyIndex_Check(object) object PyLong_FromVoidPtr(void *) cdef extern from "pythread.h": ctypedef void *PyThread_type_lock PyThread_type_lock PyThread_allocate_lock() void PyThread_free_lock(PyThread_type_lock) int PyThread_acquire_lock(PyThread_type_lock, int mode) nogil void PyThread_release_lock(PyThread_type_lock) nogil cdef extern from "string.h": void *memset(void *b, int c, size_t len) cdef extern from *: int __Pyx_GetBuffer(object, Py_buffer *, int) except -1 void __Pyx_ReleaseBuffer(Py_buffer *) ctypedef struct PyObject ctypedef Py_ssize_t Py_intptr_t void Py_INCREF(PyObject *) void Py_DECREF(PyObject *) void* PyMem_Malloc(size_t n) void PyMem_Free(void *p) cdef struct __pyx_memoryview "__pyx_memoryview_obj": Py_buffer view PyObject *obj __Pyx_TypeInfo *typeinfo ctypedef struct {{memviewslice_name}}: __pyx_memoryview *memview char *data Py_ssize_t shape[{{max_dims}}] Py_ssize_t strides[{{max_dims}}] Py_ssize_t suboffsets[{{max_dims}}] void __PYX_INC_MEMVIEW({{memviewslice_name}} *memslice, int have_gil) void __PYX_XDEC_MEMVIEW({{memviewslice_name}} *memslice, int have_gil) ctypedef struct __pyx_buffer "Py_buffer": PyObject *obj PyObject *Py_None cdef enum: PyBUF_C_CONTIGUOUS, PyBUF_F_CONTIGUOUS, PyBUF_ANY_CONTIGUOUS PyBUF_FORMAT PyBUF_WRITABLE PyBUF_STRIDES PyBUF_INDIRECT PyBUF_RECORDS ctypedef struct __Pyx_TypeInfo: pass cdef object capsule "__pyx_capsule_create" (void *p, char *sig) cdef int __pyx_array_getbuffer(PyObject *obj, Py_buffer view, int flags) cdef int __pyx_memoryview_getbuffer(PyObject *obj, Py_buffer view, int flags) cdef extern from *: ctypedef int __pyx_atomic_int {{memviewslice_name}} slice_copy_contig "__pyx_memoryview_copy_new_contig"( __Pyx_memviewslice *from_mvs, char *mode, int ndim, size_t sizeof_dtype, int contig_flag, bint dtype_is_object) nogil except * bint slice_is_contig "__pyx_memviewslice_is_contig" ( {{memviewslice_name}} *mvs, char order, int ndim) nogil bint slices_overlap "__pyx_slices_overlap" ({{memviewslice_name}} *slice1, {{memviewslice_name}} *slice2, int ndim, size_t itemsize) nogil cdef extern from "stdlib.h": void *malloc(size_t) nogil void free(void *) nogil void *memcpy(void *dest, void *src, size_t n) nogil # ### cython.array class # @cname("__pyx_array") cdef class array: cdef: char *data Py_ssize_t len char *format int ndim Py_ssize_t *_shape Py_ssize_t *_strides Py_ssize_t itemsize unicode mode # FIXME: this should have been a simple 'char' bytes _format void (*callback_free_data)(void *data) # cdef object _memview cdef bint free_data cdef bint dtype_is_object def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, mode="c", bint allocate_buffer=True): cdef int idx cdef Py_ssize_t i, dim cdef PyObject **p self.ndim = len(shape) self.itemsize = itemsize if not self.ndim: raise ValueError("Empty shape tuple for cython.array") if itemsize <= 0: raise ValueError("itemsize <= 0 for cython.array") if not isinstance(format, bytes): format = format.encode('ASCII') self._format = format # keep a reference to the byte string self.format = self._format # use single malloc() for both shape and strides self._shape = PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2) self._strides = self._shape + self.ndim if not self._shape: raise MemoryError("unable to allocate shape and strides.") # cdef Py_ssize_t dim, stride for idx, dim in enumerate(shape): if dim <= 0: raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) self._shape[idx] = dim cdef char order if mode == 'fortran': order = b'F' self.mode = u'fortran' elif mode == 'c': order = b'C' self.mode = u'c' else: raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) self.len = fill_contig_strides_array(self._shape, self._strides, itemsize, self.ndim, order) self.free_data = allocate_buffer self.dtype_is_object = format == b'O' if allocate_buffer: # use malloc() for backwards compatibility # in case external code wants to change the data pointer self.data = malloc(self.len) if not self.data: raise MemoryError("unable to allocate array data.") if self.dtype_is_object: p = self.data for i in range(self.len / itemsize): p[i] = Py_None Py_INCREF(Py_None) @cname('getbuffer') def __getbuffer__(self, Py_buffer *info, int flags): cdef int bufmode = -1 if self.mode == u"c": bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS elif self.mode == u"fortran": bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS if not (flags & bufmode): raise ValueError("Can only create a buffer that is contiguous in memory.") info.buf = self.data info.len = self.len info.ndim = self.ndim info.shape = self._shape info.strides = self._strides info.suboffsets = NULL info.itemsize = self.itemsize info.readonly = 0 if flags & PyBUF_FORMAT: info.format = self.format else: info.format = NULL info.obj = self __pyx_getbuffer = capsule( &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") def __dealloc__(array self): if self.callback_free_data != NULL: self.callback_free_data(self.data) elif self.free_data: if self.dtype_is_object: refcount_objects_in_slice(self.data, self._shape, self._strides, self.ndim, False) free(self.data) PyMem_Free(self._shape) property memview: @cname('get_memview') def __get__(self): # Make this a property as 'self.data' may be set after instantiation flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE return memoryview(self, flags, self.dtype_is_object) def __getattr__(self, attr): return getattr(self.memview, attr) def __getitem__(self, item): return self.memview[item] def __setitem__(self, item, value): self.memview[item] = value @cname("__pyx_array_new") cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, char *mode, char *buf): cdef array result if buf == NULL: result = array(shape, itemsize, format, mode.decode('ASCII')) else: result = array(shape, itemsize, format, mode.decode('ASCII'), allocate_buffer=False) result.data = buf return result # ### Memoryview constants and cython.view.memoryview class # # Disable generic_contiguous, as it makes trouble verifying contiguity: # - 'contiguous' or '::1' means the dimension is contiguous with dtype # - 'indirect_contiguous' means a contiguous list of pointers # - dtype contiguous must be contiguous in the first or last dimension # from the start, or from the dimension following the last indirect dimension # # e.g. # int[::indirect_contiguous, ::contiguous, :] # # is valid (list of pointers to 2d fortran-contiguous array), but # # int[::generic_contiguous, ::contiguous, :] # # would mean you'd have assert dimension 0 to be indirect (and pointer contiguous) at runtime. # So it doesn't bring any performance benefit, and it's only confusing. @cname('__pyx_MemviewEnum') cdef class Enum(object): cdef object name def __init__(self, name): self.name = name def __repr__(self): return self.name cdef generic = Enum("") cdef strided = Enum("") # default cdef indirect = Enum("") # Disable generic_contiguous, as it is a troublemaker #cdef generic_contiguous = Enum("") cdef contiguous = Enum("") cdef indirect_contiguous = Enum("") # 'follow' is implied when the first or last axis is ::1 @cname('__pyx_align_pointer') cdef void *align_pointer(void *memory, size_t alignment) nogil: "Align pointer memory on a given boundary" cdef Py_intptr_t aligned_p = memory cdef size_t offset with cython.cdivision(True): offset = aligned_p % alignment if offset > 0: aligned_p += alignment - offset return aligned_p @cname('__pyx_memoryview') cdef class memoryview(object): cdef object obj cdef object _size cdef object _array_interface cdef PyThread_type_lock lock # the following array will contain a single __pyx_atomic int with # suitable alignment cdef __pyx_atomic_int acquisition_count[2] cdef __pyx_atomic_int *acquisition_count_aligned_p cdef Py_buffer view cdef int flags cdef bint dtype_is_object cdef __Pyx_TypeInfo *typeinfo def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): self.obj = obj self.flags = flags if type(self) is memoryview or obj is not None: __Pyx_GetBuffer(obj, &self.view, flags) if self.view.obj == NULL: (<__pyx_buffer *> &self.view).obj = Py_None Py_INCREF(Py_None) self.lock = PyThread_allocate_lock() if self.lock == NULL: raise MemoryError if flags & PyBUF_FORMAT: self.dtype_is_object = self.view.format == b'O' else: self.dtype_is_object = dtype_is_object self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( &self.acquisition_count[0], sizeof(__pyx_atomic_int)) self.typeinfo = NULL def __dealloc__(memoryview self): if self.obj is not None: __Pyx_ReleaseBuffer(&self.view) if self.lock != NULL: PyThread_free_lock(self.lock) cdef char *get_item_pointer(memoryview self, object index) except NULL: cdef Py_ssize_t dim cdef char *itemp = self.view.buf for dim, idx in enumerate(index): itemp = pybuffer_index(&self.view, itemp, idx, dim) return itemp #@cname('__pyx_memoryview_getitem') def __getitem__(memoryview self, object index): if index is Ellipsis: return self have_slices, indices = _unellipsify(index, self.view.ndim) cdef char *itemp if have_slices: return memview_slice(self, indices) else: itemp = self.get_item_pointer(indices) return self.convert_item_to_object(itemp) def __setitem__(memoryview self, object index, object value): have_slices, index = _unellipsify(index, self.view.ndim) if have_slices: obj = self.is_slice(value) if obj: self.setitem_slice_assignment(self[index], obj) else: self.setitem_slice_assign_scalar(self[index], value) else: self.setitem_indexed(index, value) cdef is_slice(self, obj): if not isinstance(obj, memoryview): try: obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, self.dtype_is_object) except TypeError: return None return obj cdef setitem_slice_assignment(self, dst, src): cdef {{memviewslice_name}} dst_slice cdef {{memviewslice_name}} src_slice memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], get_slice_from_memview(dst, &dst_slice)[0], src.ndim, dst.ndim, self.dtype_is_object) cdef setitem_slice_assign_scalar(self, memoryview dst, value): cdef int array[128] cdef void *tmp = NULL cdef void *item cdef {{memviewslice_name}} *dst_slice cdef {{memviewslice_name}} tmp_slice dst_slice = get_slice_from_memview(dst, &tmp_slice) if self.view.itemsize > sizeof(array): tmp = PyMem_Malloc(self.view.itemsize) if tmp == NULL: raise MemoryError item = tmp else: item = array try: if self.dtype_is_object: ( item)[0] = value else: self.assign_item_from_object( item, value) # It would be easy to support indirect dimensions, but it's easier # to disallow :) if self.view.suboffsets != NULL: assert_direct_dimensions(self.view.suboffsets, self.view.ndim) slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, item, self.dtype_is_object) finally: PyMem_Free(tmp) cdef setitem_indexed(self, index, value): cdef char *itemp = self.get_item_pointer(index) self.assign_item_from_object(itemp, value) cdef convert_item_to_object(self, char *itemp): """Only used if instantiated manually by the user, or if Cython doesn't know how to convert the type""" import struct cdef bytes bytesitem # Do a manual and complete check here instead of this easy hack bytesitem = itemp[:self.view.itemsize] try: result = struct.unpack(self.view.format, bytesitem) except struct.error: raise ValueError("Unable to convert item to object") else: if len(self.view.format) == 1: return result[0] return result cdef assign_item_from_object(self, char *itemp, object value): """Only used if instantiated manually by the user, or if Cython doesn't know how to convert the type""" import struct cdef char c cdef bytes bytesvalue cdef Py_ssize_t i if isinstance(value, tuple): bytesvalue = struct.pack(self.view.format, *value) else: bytesvalue = struct.pack(self.view.format, value) for i, c in enumerate(bytesvalue): itemp[i] = c @cname('getbuffer') def __getbuffer__(self, Py_buffer *info, int flags): if flags & PyBUF_STRIDES: info.shape = self.view.shape else: info.shape = NULL if flags & PyBUF_STRIDES: info.strides = self.view.strides else: info.strides = NULL if flags & PyBUF_INDIRECT: info.suboffsets = self.view.suboffsets else: info.suboffsets = NULL if flags & PyBUF_FORMAT: info.format = self.view.format else: info.format = NULL info.buf = self.view.buf info.ndim = self.view.ndim info.itemsize = self.view.itemsize info.len = self.view.len info.readonly = 0 info.obj = self __pyx_getbuffer = capsule( &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # Some properties that have the same sematics as in NumPy property T: @cname('__pyx_memoryview_transpose') def __get__(self): cdef _memoryviewslice result = memoryview_copy(self) transpose_memslice(&result.from_slice) return result property base: @cname('__pyx_memoryview__get__base') def __get__(self): return self.obj property shape: @cname('__pyx_memoryview_get_shape') def __get__(self): return tuple([length for length in self.view.shape[:self.view.ndim]]) property strides: @cname('__pyx_memoryview_get_strides') def __get__(self): if self.view.strides == NULL: # Note: we always ask for strides, so if this is not set it's a bug raise ValueError("Buffer view does not expose strides") return tuple([stride for stride in self.view.strides[:self.view.ndim]]) property suboffsets: @cname('__pyx_memoryview_get_suboffsets') def __get__(self): if self.view.suboffsets == NULL: return (-1,) * self.view.ndim return tuple([suboffset for suboffset in self.view.suboffsets[:self.view.ndim]]) property ndim: @cname('__pyx_memoryview_get_ndim') def __get__(self): return self.view.ndim property itemsize: @cname('__pyx_memoryview_get_itemsize') def __get__(self): return self.view.itemsize property nbytes: @cname('__pyx_memoryview_get_nbytes') def __get__(self): return self.size * self.view.itemsize property size: @cname('__pyx_memoryview_get_size') def __get__(self): if self._size is None: result = 1 for length in self.view.shape[:self.view.ndim]: result *= length self._size = result return self._size def __len__(self): if self.view.ndim >= 1: return self.view.shape[0] return 0 def __repr__(self): return "" % (self.base.__class__.__name__, id(self)) def __str__(self): return "" % (self.base.__class__.__name__,) # Support the same attributes as memoryview slices def is_c_contig(self): cdef {{memviewslice_name}} *mslice cdef {{memviewslice_name}} tmp mslice = get_slice_from_memview(self, &tmp) return slice_is_contig(mslice, 'C', self.view.ndim) def is_f_contig(self): cdef {{memviewslice_name}} *mslice cdef {{memviewslice_name}} tmp mslice = get_slice_from_memview(self, &tmp) return slice_is_contig(mslice, 'F', self.view.ndim) def copy(self): cdef {{memviewslice_name}} mslice cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS slice_copy(self, &mslice) mslice = slice_copy_contig(&mslice, "c", self.view.ndim, self.view.itemsize, flags|PyBUF_C_CONTIGUOUS, self.dtype_is_object) return memoryview_copy_from_slice(self, &mslice) def copy_fortran(self): cdef {{memviewslice_name}} src, dst cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS slice_copy(self, &src) dst = slice_copy_contig(&src, "fortran", self.view.ndim, self.view.itemsize, flags|PyBUF_F_CONTIGUOUS, self.dtype_is_object) return memoryview_copy_from_slice(self, &dst) @cname('__pyx_memoryview_new') cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): cdef memoryview result = memoryview(o, flags, dtype_is_object) result.typeinfo = typeinfo return result @cname('__pyx_memoryview_check') cdef inline bint memoryview_check(object o): return isinstance(o, memoryview) cdef tuple _unellipsify(object index, int ndim): """ Replace all ellipses with full slices and fill incomplete indices with full slices. """ if not isinstance(index, tuple): tup = (index,) else: tup = index result = [] have_slices = False seen_ellipsis = False for idx, item in enumerate(tup): if item is Ellipsis: if not seen_ellipsis: result.extend([slice(None)] * (ndim - len(tup) + 1)) seen_ellipsis = True else: result.append(slice(None)) have_slices = True else: if not isinstance(item, slice) and not PyIndex_Check(item): raise TypeError("Cannot index with type '%s'" % type(item)) have_slices = have_slices or isinstance(item, slice) result.append(item) nslices = ndim - len(result) if nslices: result.extend([slice(None)] * nslices) return have_slices or nslices, tuple(result) cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): for suboffset in suboffsets[:ndim]: if suboffset >= 0: raise ValueError("Indirect dimensions not supported") # ### Slicing a memoryview # @cname('__pyx_memview_slice') cdef memoryview memview_slice(memoryview memview, object indices): cdef int new_ndim = 0, suboffset_dim = -1, dim cdef bint negative_step cdef {{memviewslice_name}} src, dst cdef {{memviewslice_name}} *p_src # dst is copied by value in memoryview_fromslice -- initialize it # src is never copied memset(&dst, 0, sizeof(dst)) cdef _memoryviewslice memviewsliceobj assert memview.view.ndim > 0 if isinstance(memview, _memoryviewslice): memviewsliceobj = memview p_src = &memviewsliceobj.from_slice else: slice_copy(memview, &src) p_src = &src # Note: don't use variable src at this point # SubNote: we should be able to declare variables in blocks... # memoryview_fromslice() will inc our dst slice dst.memview = p_src.memview dst.data = p_src.data # Put everything in temps to avoid this bloody warning: # "Argument evaluation order in C function call is undefined and # may not be as expected" cdef {{memviewslice_name}} *p_dst = &dst cdef int *p_suboffset_dim = &suboffset_dim cdef Py_ssize_t start, stop, step cdef bint have_start, have_stop, have_step for dim, index in enumerate(indices): if PyIndex_Check(index): slice_memviewslice( p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], dim, new_ndim, p_suboffset_dim, index, 0, 0, # start, stop, step 0, 0, 0, # have_{start,stop,step} False) elif index is None: p_dst.shape[new_ndim] = 1 p_dst.strides[new_ndim] = 0 p_dst.suboffsets[new_ndim] = -1 new_ndim += 1 else: start = index.start or 0 stop = index.stop or 0 step = index.step or 0 have_start = index.start is not None have_stop = index.stop is not None have_step = index.step is not None slice_memviewslice( p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim], dim, new_ndim, p_suboffset_dim, start, stop, step, have_start, have_stop, have_step, True) new_ndim += 1 if isinstance(memview, _memoryviewslice): return memoryview_fromslice(dst, new_ndim, memviewsliceobj.to_object_func, memviewsliceobj.to_dtype_func, memview.dtype_is_object) else: return memoryview_fromslice(dst, new_ndim, NULL, NULL, memview.dtype_is_object) # ### Slicing in a single dimension of a memoryviewslice # cdef extern from "stdlib.h": void abort() nogil void printf(char *s, ...) nogil cdef extern from "stdio.h": ctypedef struct FILE FILE *stderr int fputs(char *s, FILE *stream) cdef extern from "pystate.h": void PyThreadState_Get() nogil # These are not actually nogil, but we check for the GIL before calling them void PyErr_SetString(PyObject *type, char *msg) nogil PyObject *PyErr_Format(PyObject *exc, char *msg, ...) nogil @cname('__pyx_memoryview_slice_memviewslice') cdef int slice_memviewslice( {{memviewslice_name}} *dst, Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset, int dim, int new_ndim, int *suboffset_dim, Py_ssize_t start, Py_ssize_t stop, Py_ssize_t step, int have_start, int have_stop, int have_step, bint is_slice) nogil except -1: """ Create a new slice dst given slice src. dim - the current src dimension (indexing will make dimensions disappear) new_dim - the new dst dimension suboffset_dim - pointer to a single int initialized to -1 to keep track of where slicing offsets should be added """ cdef Py_ssize_t new_shape cdef bint negative_step if not is_slice: # index is a normal integer-like index if start < 0: start += shape if not 0 <= start < shape: _err_dim(IndexError, "Index out of bounds (axis %d)", dim) else: # index is a slice negative_step = have_step != 0 and step < 0 if have_step and step == 0: _err_dim(ValueError, "Step may not be zero (axis %d)", dim) # check our bounds and set defaults if have_start: if start < 0: start += shape if start < 0: start = 0 elif start >= shape: if negative_step: start = shape - 1 else: start = shape else: if negative_step: start = shape - 1 else: start = 0 if have_stop: if stop < 0: stop += shape if stop < 0: stop = 0 elif stop > shape: stop = shape else: if negative_step: stop = -1 else: stop = shape if not have_step: step = 1 # len = ceil( (stop - start) / step ) with cython.cdivision(True): new_shape = (stop - start) // step if (stop - start) - step * new_shape: new_shape += 1 if new_shape < 0: new_shape = 0 # shape/strides/suboffsets dst.strides[new_ndim] = stride * step dst.shape[new_ndim] = new_shape dst.suboffsets[new_ndim] = suboffset # Add the slicing or idexing offsets to the right suboffset or base data * if suboffset_dim[0] < 0: dst.data += start * stride else: dst.suboffsets[suboffset_dim[0]] += start * stride if suboffset >= 0: if not is_slice: if new_ndim == 0: dst.data = ( dst.data)[0] + suboffset else: _err_dim(IndexError, "All dimensions preceding dimension %d " "must be indexed and not sliced", dim) else: suboffset_dim[0] = new_ndim return 0 # ### Index a memoryview # @cname('__pyx_pybuffer_index') cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, Py_ssize_t dim) except NULL: cdef Py_ssize_t shape, stride, suboffset = -1 cdef Py_ssize_t itemsize = view.itemsize cdef char *resultp if view.ndim == 0: shape = view.len / itemsize stride = itemsize else: shape = view.shape[dim] stride = view.strides[dim] if view.suboffsets != NULL: suboffset = view.suboffsets[dim] if index < 0: index += view.shape[dim] if index < 0: raise IndexError("Out of bounds on buffer access (axis %d)" % dim) if index >= shape: raise IndexError("Out of bounds on buffer access (axis %d)" % dim) resultp = bufp + index * stride if suboffset >= 0: resultp = ( resultp)[0] + suboffset return resultp # ### Transposing a memoryviewslice # @cname('__pyx_memslice_transpose') cdef int transpose_memslice({{memviewslice_name}} *memslice) nogil except 0: cdef int ndim = memslice.memview.view.ndim cdef Py_ssize_t *shape = memslice.shape cdef Py_ssize_t *strides = memslice.strides # reverse strides and shape cdef int i, j for i in range(ndim / 2): j = ndim - 1 - i strides[i], strides[j] = strides[j], strides[i] shape[i], shape[j] = shape[j], shape[i] if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: _err(ValueError, "Cannot transpose memoryview with indirect dimensions") return 1 # ### Creating new memoryview objects from slices and memoryviews # @cname('__pyx_memoryviewslice') cdef class _memoryviewslice(memoryview): "Internal class for passing memoryview slices to Python" # We need this to keep our shape/strides/suboffset pointers valid cdef {{memviewslice_name}} from_slice # We need this only to print it's class' name cdef object from_object cdef object (*to_object_func)(char *) cdef int (*to_dtype_func)(char *, object) except 0 def __dealloc__(self): __PYX_XDEC_MEMVIEW(&self.from_slice, 1) cdef convert_item_to_object(self, char *itemp): if self.to_object_func != NULL: return self.to_object_func(itemp) else: return memoryview.convert_item_to_object(self, itemp) cdef assign_item_from_object(self, char *itemp, object value): if self.to_dtype_func != NULL: self.to_dtype_func(itemp, value) else: memoryview.assign_item_from_object(self, itemp, value) property base: @cname('__pyx_memoryviewslice__get__base') def __get__(self): return self.from_object __pyx_getbuffer = capsule( &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") @cname('__pyx_memoryview_fromslice') cdef memoryview_fromslice({{memviewslice_name}} memviewslice, int ndim, object (*to_object_func)(char *), int (*to_dtype_func)(char *, object) except 0, bint dtype_is_object): cdef _memoryviewslice result if memviewslice.memview == Py_None: return None # assert 0 < ndim <= memviewslice.memview.view.ndim, ( # ndim, memviewslice.memview.view.ndim) result = _memoryviewslice(None, 0, dtype_is_object) result.from_slice = memviewslice __PYX_INC_MEMVIEW(&memviewslice, 1) result.from_object = ( memviewslice.memview).base result.typeinfo = memviewslice.memview.typeinfo result.view = memviewslice.memview.view result.view.buf = memviewslice.data result.view.ndim = ndim (<__pyx_buffer *> &result.view).obj = Py_None Py_INCREF(Py_None) result.flags = PyBUF_RECORDS result.view.shape = result.from_slice.shape result.view.strides = result.from_slice.strides # only set suboffsets if actually used, otherwise set to NULL to improve compatibility result.view.suboffsets = NULL for suboffset in result.from_slice.suboffsets[:ndim]: if suboffset >= 0: result.view.suboffsets = result.from_slice.suboffsets break result.view.len = result.view.itemsize for length in result.view.shape[:ndim]: result.view.len *= length result.to_object_func = to_object_func result.to_dtype_func = to_dtype_func return result @cname('__pyx_memoryview_get_slice_from_memoryview') cdef {{memviewslice_name}} *get_slice_from_memview(memoryview memview, {{memviewslice_name}} *mslice): cdef _memoryviewslice obj if isinstance(memview, _memoryviewslice): obj = memview return &obj.from_slice else: slice_copy(memview, mslice) return mslice @cname('__pyx_memoryview_slice_copy') cdef void slice_copy(memoryview memview, {{memviewslice_name}} *dst): cdef int dim cdef (Py_ssize_t*) shape, strides, suboffsets shape = memview.view.shape strides = memview.view.strides suboffsets = memview.view.suboffsets dst.memview = <__pyx_memoryview *> memview dst.data = memview.view.buf for dim in range(memview.view.ndim): dst.shape[dim] = shape[dim] dst.strides[dim] = strides[dim] dst.suboffsets[dim] = suboffsets[dim] if suboffsets else -1 @cname('__pyx_memoryview_copy_object') cdef memoryview_copy(memoryview memview): "Create a new memoryview object" cdef {{memviewslice_name}} memviewslice slice_copy(memview, &memviewslice) return memoryview_copy_from_slice(memview, &memviewslice) @cname('__pyx_memoryview_copy_object_from_slice') cdef memoryview_copy_from_slice(memoryview memview, {{memviewslice_name}} *memviewslice): """ Create a new memoryview object from a given memoryview object and slice. """ cdef object (*to_object_func)(char *) cdef int (*to_dtype_func)(char *, object) except 0 if isinstance(memview, _memoryviewslice): to_object_func = (<_memoryviewslice> memview).to_object_func to_dtype_func = (<_memoryviewslice> memview).to_dtype_func else: to_object_func = NULL to_dtype_func = NULL return memoryview_fromslice(memviewslice[0], memview.view.ndim, to_object_func, to_dtype_func, memview.dtype_is_object) # ### Copy the contents of a memoryview slices # cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: if arg < 0: return -arg else: return arg @cname('__pyx_get_best_slice_order') cdef char get_best_order({{memviewslice_name}} *mslice, int ndim) nogil: """ Figure out the best memory access order for a given slice. """ cdef int i cdef Py_ssize_t c_stride = 0 cdef Py_ssize_t f_stride = 0 for i in range(ndim - 1, -1, -1): if mslice.shape[i] > 1: c_stride = mslice.strides[i] break for i in range(ndim): if mslice.shape[i] > 1: f_stride = mslice.strides[i] break if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): return 'C' else: return 'F' @cython.cdivision(True) cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, char *dst_data, Py_ssize_t *dst_strides, Py_ssize_t *src_shape, Py_ssize_t *dst_shape, int ndim, size_t itemsize) nogil: # Note: src_extent is 1 if we're broadcasting # dst_extent always >= src_extent as we don't do reductions cdef Py_ssize_t i cdef Py_ssize_t src_extent = src_shape[0] cdef Py_ssize_t dst_extent = dst_shape[0] cdef Py_ssize_t src_stride = src_strides[0] cdef Py_ssize_t dst_stride = dst_strides[0] if ndim == 1: if (src_stride > 0 and dst_stride > 0 and src_stride == itemsize == dst_stride): memcpy(dst_data, src_data, itemsize * dst_extent) else: for i in range(dst_extent): memcpy(dst_data, src_data, itemsize) src_data += src_stride dst_data += dst_stride else: for i in range(dst_extent): _copy_strided_to_strided(src_data, src_strides + 1, dst_data, dst_strides + 1, src_shape + 1, dst_shape + 1, ndim - 1, itemsize) src_data += src_stride dst_data += dst_stride cdef void copy_strided_to_strided({{memviewslice_name}} *src, {{memviewslice_name}} *dst, int ndim, size_t itemsize) nogil: _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides, src.shape, dst.shape, ndim, itemsize) @cname('__pyx_memoryview_slice_get_size') cdef Py_ssize_t slice_get_size({{memviewslice_name}} *src, int ndim) nogil: "Return the size of the memory occupied by the slice in number of bytes" cdef int i cdef Py_ssize_t size = src.memview.view.itemsize for i in range(ndim): size *= src.shape[i] return size @cname('__pyx_fill_contig_strides_array') cdef Py_ssize_t fill_contig_strides_array( Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride, int ndim, char order) nogil: """ Fill the strides array for a slice with C or F contiguous strides. This is like PyBuffer_FillContiguousStrides, but compatible with py < 2.6 """ cdef int idx if order == 'F': for idx in range(ndim): strides[idx] = stride stride = stride * shape[idx] else: for idx in range(ndim - 1, -1, -1): strides[idx] = stride stride = stride * shape[idx] return stride @cname('__pyx_memoryview_copy_data_to_temp') cdef void *copy_data_to_temp({{memviewslice_name}} *src, {{memviewslice_name}} *tmpslice, char order, int ndim) nogil except NULL: """ Copy a direct slice to temporary contiguous memory. The caller should free the result when done. """ cdef int i cdef void *result cdef size_t itemsize = src.memview.view.itemsize cdef size_t size = slice_get_size(src, ndim) result = malloc(size) if not result: _err(MemoryError, NULL) # tmpslice[0] = src tmpslice.data = result tmpslice.memview = src.memview for i in range(ndim): tmpslice.shape[i] = src.shape[i] tmpslice.suboffsets[i] = -1 fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, ndim, order) # We need to broadcast strides again for i in range(ndim): if tmpslice.shape[i] == 1: tmpslice.strides[i] = 0 if slice_is_contig(src, order, ndim): memcpy(result, src.data, size) else: copy_strided_to_strided(src, tmpslice, ndim, itemsize) return result # Use 'with gil' functions and avoid 'with gil' blocks, as the code within the blocks # has temporaries that need the GIL to clean up @cname('__pyx_memoryview_err_extents') cdef int _err_extents(int i, Py_ssize_t extent1, Py_ssize_t extent2) except -1 with gil: raise ValueError("got differing extents in dimension %d (got %d and %d)" % (i, extent1, extent2)) @cname('__pyx_memoryview_err_dim') cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: raise error(msg.decode('ascii') % dim) @cname('__pyx_memoryview_err') cdef int _err(object error, char *msg) except -1 with gil: if msg != NULL: raise error(msg.decode('ascii')) else: raise error @cname('__pyx_memoryview_copy_contents') cdef int memoryview_copy_contents({{memviewslice_name}} src, {{memviewslice_name}} dst, int src_ndim, int dst_ndim, bint dtype_is_object) nogil except -1: """ Copy memory from slice src to slice dst. Check for overlapping memory and verify the shapes. """ cdef void *tmpdata = NULL cdef size_t itemsize = src.memview.view.itemsize cdef int i cdef char order = get_best_order(&src, src_ndim) cdef bint broadcasting = False cdef bint direct_copy = False cdef {{memviewslice_name}} tmp if src_ndim < dst_ndim: broadcast_leading(&src, src_ndim, dst_ndim) elif dst_ndim < src_ndim: broadcast_leading(&dst, dst_ndim, src_ndim) cdef int ndim = max(src_ndim, dst_ndim) for i in range(ndim): if src.shape[i] != dst.shape[i]: if src.shape[i] == 1: broadcasting = True src.strides[i] = 0 else: _err_extents(i, dst.shape[i], src.shape[i]) if src.suboffsets[i] >= 0: _err_dim(ValueError, "Dimension %d is not direct", i) if slices_overlap(&src, &dst, ndim, itemsize): # slices overlap, copy to temp, copy temp to dst if not slice_is_contig(&src, order, ndim): order = get_best_order(&dst, ndim) tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) src = tmp if not broadcasting: # See if both slices have equal contiguity, in that case perform a # direct copy. This only works when we are not broadcasting. if slice_is_contig(&src, 'C', ndim): direct_copy = slice_is_contig(&dst, 'C', ndim) elif slice_is_contig(&src, 'F', ndim): direct_copy = slice_is_contig(&dst, 'F', ndim) if direct_copy: # Contiguous slices with same order refcount_copying(&dst, dtype_is_object, ndim, False) memcpy(dst.data, src.data, slice_get_size(&src, ndim)) refcount_copying(&dst, dtype_is_object, ndim, True) free(tmpdata) return 0 if order == 'F' == get_best_order(&dst, ndim): # see if both slices have Fortran order, transpose them to match our # C-style indexing order transpose_memslice(&src) transpose_memslice(&dst) refcount_copying(&dst, dtype_is_object, ndim, False) copy_strided_to_strided(&src, &dst, ndim, itemsize) refcount_copying(&dst, dtype_is_object, ndim, True) free(tmpdata) return 0 @cname('__pyx_memoryview_broadcast_leading') cdef void broadcast_leading({{memviewslice_name}} *mslice, int ndim, int ndim_other) nogil: cdef int i cdef int offset = ndim_other - ndim for i in range(ndim - 1, -1, -1): mslice.shape[i + offset] = mslice.shape[i] mslice.strides[i + offset] = mslice.strides[i] mslice.suboffsets[i + offset] = mslice.suboffsets[i] for i in range(offset): mslice.shape[i] = 1 mslice.strides[i] = mslice.strides[0] mslice.suboffsets[i] = -1 # ### Take care of refcounting the objects in slices. Do this seperately from any copying, ### to minimize acquiring the GIL # @cname('__pyx_memoryview_refcount_copying') cdef void refcount_copying({{memviewslice_name}} *dst, bint dtype_is_object, int ndim, bint inc) nogil: # incref or decref the objects in the destination slice if the dtype is # object if dtype_is_object: refcount_objects_in_slice_with_gil(dst.data, dst.shape, dst.strides, ndim, inc) @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil') cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, Py_ssize_t *strides, int ndim, bint inc) with gil: refcount_objects_in_slice(data, shape, strides, ndim, inc) @cname('__pyx_memoryview_refcount_objects_in_slice') cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, Py_ssize_t *strides, int ndim, bint inc): cdef Py_ssize_t i for i in range(shape[0]): if ndim == 1: if inc: Py_INCREF(( data)[0]) else: Py_DECREF(( data)[0]) else: refcount_objects_in_slice(data, shape + 1, strides + 1, ndim - 1, inc) data += strides[0] # ### Scalar to slice assignment # @cname('__pyx_memoryview_slice_assign_scalar') cdef void slice_assign_scalar({{memviewslice_name}} *dst, int ndim, size_t itemsize, void *item, bint dtype_is_object) nogil: refcount_copying(dst, dtype_is_object, ndim, False) _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, itemsize, item) refcount_copying(dst, dtype_is_object, ndim, True) @cname('__pyx_memoryview__slice_assign_scalar') cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, Py_ssize_t *strides, int ndim, size_t itemsize, void *item) nogil: cdef Py_ssize_t i cdef Py_ssize_t stride = strides[0] cdef Py_ssize_t extent = shape[0] if ndim == 1: for i in range(extent): memcpy(data, item, itemsize) data += stride else: for i in range(extent): _slice_assign_scalar(data, shape + 1, strides + 1, ndim - 1, itemsize, item) data += stride ############### BufferFormatFromTypeInfo ############### cdef extern from *: ctypedef struct __Pyx_StructField cdef enum: __PYX_BUF_FLAGS_PACKED_STRUCT __PYX_BUF_FLAGS_INTEGER_COMPLEX ctypedef struct __Pyx_TypeInfo: char* name __Pyx_StructField* fields size_t size size_t arraysize[8] int ndim char typegroup char is_unsigned int flags ctypedef struct __Pyx_StructField: __Pyx_TypeInfo* type char* name size_t offset ctypedef struct __Pyx_BufFmt_StackElem: __Pyx_StructField* field size_t parent_offset #ctypedef struct __Pyx_BufFmt_Context: # __Pyx_StructField root __Pyx_BufFmt_StackElem* head struct __pyx_typeinfo_string: char string[3] __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *) @cname('__pyx_format_from_typeinfo') cdef bytes format_from_typeinfo(__Pyx_TypeInfo *type): cdef __Pyx_StructField *field cdef __pyx_typeinfo_string fmt cdef bytes part, result if type.typegroup == 'S': assert type.fields != NULL and type.fields.type != NULL if type.flags & __PYX_BUF_FLAGS_PACKED_STRUCT: alignment = b'^' else: alignment = b'' parts = [b"T{"] field = type.fields while field.type: part = format_from_typeinfo(field.type) parts.append(part + b':' + field.name + b':') field += 1 result = alignment.join(parts) + b'}' else: fmt = __Pyx_TypeInfoToFormat(type) if type.arraysize[0]: extents = [unicode(type.arraysize[i]) for i in range(type.ndim)] result = (u"(%s)" % u','.join(extents)).encode('ascii') + fmt.string else: result = fmt.string return result Cython-0.23.4/Cython/Utility/ImportExport.c0000644000175600017570000004504712606202452021745 0ustar jenkinsjenkins00000000000000/////////////// PyIdentifierFromString.proto /////////////// #if !defined(__Pyx_PyIdentifier_FromString) #if PY_MAJOR_VERSION < 3 #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s) #else #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s) #endif #endif /////////////// Import.proto /////////////// static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level); /*proto*/ /////////////// Import /////////////// //@requires: ObjectHandling.c::PyObjectGetAttrStr //@substitute: naming static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) { PyObject *empty_list = 0; PyObject *module = 0; PyObject *global_dict = 0; PyObject *empty_dict = 0; PyObject *list; #if PY_VERSION_HEX < 0x03030000 PyObject *py_import; py_import = __Pyx_PyObject_GetAttrStr($builtins_cname, PYIDENT("__import__")); if (!py_import) goto bad; #endif if (from_list) list = from_list; else { empty_list = PyList_New(0); if (!empty_list) goto bad; list = empty_list; } global_dict = PyModule_GetDict($module_cname); if (!global_dict) goto bad; empty_dict = PyDict_New(); if (!empty_dict) goto bad; { #if PY_MAJOR_VERSION >= 3 if (level == -1) { if (strchr(__Pyx_MODULE_NAME, '.')) { /* try package relative import first */ #if PY_VERSION_HEX < 0x03030000 PyObject *py_level = PyInt_FromLong(1); if (!py_level) goto bad; module = PyObject_CallFunctionObjArgs(py_import, name, global_dict, empty_dict, list, py_level, NULL); Py_DECREF(py_level); #else module = PyImport_ImportModuleLevelObject( name, global_dict, empty_dict, list, 1); #endif if (!module) { if (!PyErr_ExceptionMatches(PyExc_ImportError)) goto bad; PyErr_Clear(); } } level = 0; /* try absolute import on failure */ } #endif if (!module) { #if PY_VERSION_HEX < 0x03030000 PyObject *py_level = PyInt_FromLong(level); if (!py_level) goto bad; module = PyObject_CallFunctionObjArgs(py_import, name, global_dict, empty_dict, list, py_level, NULL); Py_DECREF(py_level); #else module = PyImport_ImportModuleLevelObject( name, global_dict, empty_dict, list, level); #endif } } bad: #if PY_VERSION_HEX < 0x03030000 Py_XDECREF(py_import); #endif Py_XDECREF(empty_list); Py_XDECREF(empty_dict); return module; } /////////////// ImportFrom.proto /////////////// static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); /*proto*/ /////////////// ImportFrom /////////////// //@requires: ObjectHandling.c::PyObjectGetAttrStr static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Format(PyExc_ImportError, #if PY_MAJOR_VERSION < 3 "cannot import name %.230s", PyString_AS_STRING(name)); #else "cannot import name %S", name); #endif } return value; } /////////////// ImportStar /////////////// //@substitute: naming /* import_all_from is an unexposed function from ceval.c */ static int __Pyx_import_all_from(PyObject *locals, PyObject *v) { PyObject *all = PyObject_GetAttrString(v, "__all__"); PyObject *dict, *name, *value; int skip_leading_underscores = 0; int pos, err; if (all == NULL) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return -1; /* Unexpected error */ PyErr_Clear(); dict = PyObject_GetAttrString(v, "__dict__"); if (dict == NULL) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return -1; PyErr_SetString(PyExc_ImportError, "from-import-* object has no __dict__ and no __all__"); return -1; } #if PY_MAJOR_VERSION < 3 all = PyObject_CallMethod(dict, (char *)"keys", NULL); #else all = PyMapping_Keys(dict); #endif Py_DECREF(dict); if (all == NULL) return -1; skip_leading_underscores = 1; } for (pos = 0, err = 0; ; pos++) { name = PySequence_GetItem(all, pos); if (name == NULL) { if (!PyErr_ExceptionMatches(PyExc_IndexError)) err = -1; else PyErr_Clear(); break; } if (skip_leading_underscores && #if PY_MAJOR_VERSION < 3 PyString_Check(name) && PyString_AS_STRING(name)[0] == '_') #else PyUnicode_Check(name) && PyUnicode_AS_UNICODE(name)[0] == '_') #endif { Py_DECREF(name); continue; } value = PyObject_GetAttr(v, name); if (value == NULL) err = -1; else if (PyDict_CheckExact(locals)) err = PyDict_SetItem(locals, name, value); else err = PyObject_SetItem(locals, name, value); Py_DECREF(name); Py_XDECREF(value); if (err != 0) break; } Py_DECREF(all); return err; } static int ${import_star}(PyObject* m) { int i; int ret = -1; char* s; PyObject *locals = 0; PyObject *list = 0; #if PY_MAJOR_VERSION >= 3 PyObject *utf8_name = 0; #endif PyObject *name; PyObject *item; locals = PyDict_New(); if (!locals) goto bad; if (__Pyx_import_all_from(locals, m) < 0) goto bad; list = PyDict_Items(locals); if (!list) goto bad; for(i=0; i= 3 utf8_name = PyUnicode_AsUTF8String(name); if (!utf8_name) goto bad; s = PyBytes_AS_STRING(utf8_name); if (${import_star_set}(item, name, s) < 0) goto bad; Py_DECREF(utf8_name); utf8_name = 0; #else s = PyString_AsString(name); if (!s) goto bad; if (${import_star_set}(item, name, s) < 0) goto bad; #endif } ret = 0; bad: Py_XDECREF(locals); Py_XDECREF(list); #if PY_MAJOR_VERSION >= 3 Py_XDECREF(utf8_name); #endif return ret; } /////////////// ModuleImport.proto /////////////// static PyObject *__Pyx_ImportModule(const char *name); /*proto*/ /////////////// ModuleImport /////////////// //@requires: PyIdentifierFromString #ifndef __PYX_HAVE_RT_ImportModule #define __PYX_HAVE_RT_ImportModule static PyObject *__Pyx_ImportModule(const char *name) { PyObject *py_name = 0; PyObject *py_module = 0; py_name = __Pyx_PyIdentifier_FromString(name); if (!py_name) goto bad; py_module = PyImport_Import(py_name); Py_DECREF(py_name); return py_module; bad: Py_XDECREF(py_name); return 0; } #endif /////////////// SetPackagePathFromImportLib.proto /////////////// #if PY_VERSION_HEX >= 0x03030000 static int __Pyx_SetPackagePathFromImportLib(const char* parent_package_name, PyObject *module_name); #else #define __Pyx_SetPackagePathFromImportLib(a, b) 0 #endif /////////////// SetPackagePathFromImportLib /////////////// //@requires: ObjectHandling.c::PyObjectGetAttrStr //@substitute: naming #if PY_VERSION_HEX >= 0x03030000 static int __Pyx_SetPackagePathFromImportLib(const char* parent_package_name, PyObject *module_name) { PyObject *importlib, *loader, *osmod, *ossep, *parts, *package_path; PyObject *path = NULL, *file_path = NULL; int result; if (parent_package_name) { PyObject *package = PyImport_ImportModule(parent_package_name); if (unlikely(!package)) goto bad; path = PyObject_GetAttrString(package, "__path__"); Py_DECREF(package); if (unlikely(!path) || unlikely(path == Py_None)) goto bad; } else { path = Py_None; Py_INCREF(Py_None); } // package_path = [importlib.find_loader(module_name, path).path.rsplit(os.sep, 1)[0]] importlib = PyImport_ImportModule("importlib"); if (unlikely(!importlib)) goto bad; loader = PyObject_CallMethod(importlib, "find_loader", "(OO)", module_name, path); Py_DECREF(importlib); Py_DECREF(path); path = NULL; if (unlikely(!loader)) goto bad; file_path = PyObject_GetAttrString(loader, "path"); Py_DECREF(loader); if (unlikely(!file_path)) goto bad; if (unlikely(PyObject_SetAttrString($module_cname, "__file__", file_path) < 0)) goto bad; osmod = PyImport_ImportModule("os"); if (unlikely(!osmod)) goto bad; ossep = PyObject_GetAttrString(osmod, "sep"); Py_DECREF(osmod); if (unlikely(!ossep)) goto bad; parts = PyObject_CallMethod(file_path, "rsplit", "(Oi)", ossep, 1); Py_DECREF(file_path); file_path = NULL; Py_DECREF(ossep); if (unlikely(!parts)) goto bad; package_path = Py_BuildValue("[O]", PyList_GET_ITEM(parts, 0)); Py_DECREF(parts); if (unlikely(!package_path)) goto bad; goto set_path; bad: PyErr_WriteUnraisable(module_name); Py_XDECREF(path); Py_XDECREF(file_path); // set an empty path list on failure PyErr_Clear(); package_path = PyList_New(0); if (unlikely(!package_path)) return -1; set_path: result = PyObject_SetAttrString($module_cname, "__path__", package_path); Py_DECREF(package_path); return result; } #endif /////////////// TypeImport.proto /////////////// static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict); /*proto*/ /////////////// TypeImport /////////////// //@requires: PyIdentifierFromString //@requires: ModuleImport #ifndef __PYX_HAVE_RT_ImportType #define __PYX_HAVE_RT_ImportType static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict) { PyObject *py_module = 0; PyObject *result = 0; PyObject *py_name = 0; char warning[200]; Py_ssize_t basicsize; #ifdef Py_LIMITED_API PyObject *py_basicsize; #endif py_module = __Pyx_ImportModule(module_name); if (!py_module) goto bad; py_name = __Pyx_PyIdentifier_FromString(class_name); if (!py_name) goto bad; result = PyObject_GetAttr(py_module, py_name); Py_DECREF(py_name); py_name = 0; Py_DECREF(py_module); py_module = 0; if (!result) goto bad; if (!PyType_Check(result)) { PyErr_Format(PyExc_TypeError, "%.200s.%.200s is not a type object", module_name, class_name); goto bad; } #ifndef Py_LIMITED_API basicsize = ((PyTypeObject *)result)->tp_basicsize; #else py_basicsize = PyObject_GetAttrString(result, "__basicsize__"); if (!py_basicsize) goto bad; basicsize = PyLong_AsSsize_t(py_basicsize); Py_DECREF(py_basicsize); py_basicsize = 0; if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred()) goto bad; #endif if (!strict && (size_t)basicsize > size) { PyOS_snprintf(warning, sizeof(warning), "%s.%s size changed, may indicate binary incompatibility", module_name, class_name); if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad; } else if ((size_t)basicsize != size) { PyErr_Format(PyExc_ValueError, "%.200s.%.200s has the wrong size, try recompiling", module_name, class_name); goto bad; } return (PyTypeObject *)result; bad: Py_XDECREF(py_module); Py_XDECREF(result); return NULL; } #endif /////////////// FunctionImport.proto /////////////// static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig); /*proto*/ /////////////// FunctionImport /////////////// //@substitute: naming #ifndef __PYX_HAVE_RT_ImportFunction #define __PYX_HAVE_RT_ImportFunction static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig) { PyObject *d = 0; PyObject *cobj = 0; union { void (*fp)(void); void *p; } tmp; d = PyObject_GetAttrString(module, (char *)"$api_name"); if (!d) goto bad; cobj = PyDict_GetItemString(d, funcname); if (!cobj) { PyErr_Format(PyExc_ImportError, "%.200s does not export expected C function %.200s", PyModule_GetName(module), funcname); goto bad; } #if PY_VERSION_HEX >= 0x02070000 if (!PyCapsule_IsValid(cobj, sig)) { PyErr_Format(PyExc_TypeError, "C function %.200s.%.200s has wrong signature (expected %.500s, got %.500s)", PyModule_GetName(module), funcname, sig, PyCapsule_GetName(cobj)); goto bad; } tmp.p = PyCapsule_GetPointer(cobj, sig); #else {const char *desc, *s1, *s2; desc = (const char *)PyCObject_GetDesc(cobj); if (!desc) goto bad; s1 = desc; s2 = sig; while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; } if (*s1 != *s2) { PyErr_Format(PyExc_TypeError, "C function %.200s.%.200s has wrong signature (expected %.500s, got %.500s)", PyModule_GetName(module), funcname, sig, desc); goto bad; } tmp.p = PyCObject_AsVoidPtr(cobj);} #endif *f = tmp.fp; if (!(*f)) goto bad; Py_DECREF(d); return 0; bad: Py_XDECREF(d); return -1; } #endif /////////////// FunctionExport.proto /////////////// static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig); /*proto*/ /////////////// FunctionExport /////////////// //@substitute: naming static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig) { PyObject *d = 0; PyObject *cobj = 0; union { void (*fp)(void); void *p; } tmp; d = PyObject_GetAttrString($module_cname, (char *)"$api_name"); if (!d) { PyErr_Clear(); d = PyDict_New(); if (!d) goto bad; Py_INCREF(d); if (PyModule_AddObject($module_cname, (char *)"$api_name", d) < 0) goto bad; } tmp.fp = f; #if PY_VERSION_HEX >= 0x02070000 cobj = PyCapsule_New(tmp.p, sig, 0); #else cobj = PyCObject_FromVoidPtrAndDesc(tmp.p, (void *)sig, 0); #endif if (!cobj) goto bad; if (PyDict_SetItemString(d, name, cobj) < 0) goto bad; Py_DECREF(cobj); Py_DECREF(d); return 0; bad: Py_XDECREF(cobj); Py_XDECREF(d); return -1; } /////////////// VoidPtrImport.proto /////////////// static int __Pyx_ImportVoidPtr(PyObject *module, const char *name, void **p, const char *sig); /*proto*/ /////////////// VoidPtrImport /////////////// //@substitute: naming #ifndef __PYX_HAVE_RT_ImportVoidPtr #define __PYX_HAVE_RT_ImportVoidPtr static int __Pyx_ImportVoidPtr(PyObject *module, const char *name, void **p, const char *sig) { PyObject *d = 0; PyObject *cobj = 0; d = PyObject_GetAttrString(module, (char *)"$api_name"); if (!d) goto bad; cobj = PyDict_GetItemString(d, name); if (!cobj) { PyErr_Format(PyExc_ImportError, "%.200s does not export expected C variable %.200s", PyModule_GetName(module), name); goto bad; } #if PY_VERSION_HEX >= 0x02070000 if (!PyCapsule_IsValid(cobj, sig)) { PyErr_Format(PyExc_TypeError, "C variable %.200s.%.200s has wrong signature (expected %.500s, got %.500s)", PyModule_GetName(module), name, sig, PyCapsule_GetName(cobj)); goto bad; } *p = PyCapsule_GetPointer(cobj, sig); #else {const char *desc, *s1, *s2; desc = (const char *)PyCObject_GetDesc(cobj); if (!desc) goto bad; s1 = desc; s2 = sig; while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; } if (*s1 != *s2) { PyErr_Format(PyExc_TypeError, "C variable %.200s.%.200s has wrong signature (expected %.500s, got %.500s)", PyModule_GetName(module), name, sig, desc); goto bad; } *p = PyCObject_AsVoidPtr(cobj);} #endif if (!(*p)) goto bad; Py_DECREF(d); return 0; bad: Py_XDECREF(d); return -1; } #endif /////////////// VoidPtrExport.proto /////////////// static int __Pyx_ExportVoidPtr(PyObject *name, void *p, const char *sig); /*proto*/ /////////////// VoidPtrExport /////////////// //@substitute: naming //@requires: ObjectHandling.c::PyObjectSetAttrStr static int __Pyx_ExportVoidPtr(PyObject *name, void *p, const char *sig) { PyObject *d; PyObject *cobj = 0; d = PyDict_GetItem($moddict_cname, PYIDENT("$api_name")); Py_XINCREF(d); if (!d) { d = PyDict_New(); if (!d) goto bad; if (__Pyx_PyObject_SetAttrStr($module_cname, PYIDENT("$api_name"), d) < 0) goto bad; } #if PY_VERSION_HEX >= 0x02070000 cobj = PyCapsule_New(p, sig, 0); #else cobj = PyCObject_FromVoidPtrAndDesc(p, (void *)sig, 0); #endif if (!cobj) goto bad; if (PyDict_SetItem(d, name, cobj) < 0) goto bad; Py_DECREF(cobj); Py_DECREF(d); return 0; bad: Py_XDECREF(cobj); Py_XDECREF(d); return -1; } /////////////// SetVTable.proto /////////////// static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/ /////////////// SetVTable /////////////// static int __Pyx_SetVtable(PyObject *dict, void *vtable) { #if PY_VERSION_HEX >= 0x02070000 PyObject *ob = PyCapsule_New(vtable, 0, 0); #else PyObject *ob = PyCObject_FromVoidPtr(vtable, 0); #endif if (!ob) goto bad; if (PyDict_SetItem(dict, PYIDENT("__pyx_vtable__"), ob) < 0) goto bad; Py_DECREF(ob); return 0; bad: Py_XDECREF(ob); return -1; } /////////////// GetVTable.proto /////////////// static void* __Pyx_GetVtable(PyObject *dict); /*proto*/ /////////////// GetVTable /////////////// static void* __Pyx_GetVtable(PyObject *dict) { void* ptr; PyObject *ob = PyObject_GetItem(dict, PYIDENT("__pyx_vtable__")); if (!ob) goto bad; #if PY_VERSION_HEX >= 0x02070000 ptr = PyCapsule_GetPointer(ob, 0); #else ptr = PyCObject_AsVoidPtr(ob); #endif if (!ptr && !PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type"); Py_DECREF(ob); return ptr; bad: Py_XDECREF(ob); return NULL; } Cython-0.23.4/Cython/Utility/FunctionArguments.c0000644000175600017570000002774512606202452022751 0ustar jenkinsjenkins00000000000000//////////////////// ArgTypeTest.proto //////////////////// static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, const char *name, int exact); /*proto*/ //////////////////// ArgTypeTest //////////////////// static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) { PyErr_Format(PyExc_TypeError, "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)", name, type->tp_name, Py_TYPE(obj)->tp_name); } static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, const char *name, int exact) { if (unlikely(!type)) { PyErr_SetString(PyExc_SystemError, "Missing type object"); return 0; } if (none_allowed && obj == Py_None) return 1; else if (exact) { if (likely(Py_TYPE(obj) == type)) return 1; #if PY_MAJOR_VERSION == 2 else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1; #endif } else { if (likely(PyObject_TypeCheck(obj, type))) return 1; } __Pyx_RaiseArgumentTypeInvalid(name, obj, type); return 0; } //////////////////// RaiseArgTupleInvalid.proto //////////////////// static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/ //////////////////// RaiseArgTupleInvalid //////////////////// // __Pyx_RaiseArgtupleInvalid raises the correct exception when too // many or too few positional arguments were found. This handles // Py_ssize_t formatting correctly. static void __Pyx_RaiseArgtupleInvalid( const char* func_name, int exact, Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found) { Py_ssize_t num_expected; const char *more_or_less; if (num_found < num_min) { num_expected = num_min; more_or_less = "at least"; } else { num_expected = num_max; more_or_less = "at most"; } if (exact) { more_or_less = "exactly"; } PyErr_Format(PyExc_TypeError, "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", func_name, more_or_less, num_expected, (num_expected == 1) ? "" : "s", num_found); } //////////////////// RaiseKeywordRequired.proto //////////////////// static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/ //////////////////// RaiseKeywordRequired //////////////////// static CYTHON_INLINE void __Pyx_RaiseKeywordRequired( const char* func_name, PyObject* kw_name) { PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION >= 3 "%s() needs keyword-only argument %U", func_name, kw_name); #else "%s() needs keyword-only argument %s", func_name, PyString_AS_STRING(kw_name)); #endif } //////////////////// RaiseDoubleKeywords.proto //////////////////// static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/ //////////////////// RaiseDoubleKeywords //////////////////// static void __Pyx_RaiseDoubleKeywordsError( const char* func_name, PyObject* kw_name) { PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION >= 3 "%s() got multiple values for keyword argument '%U'", func_name, kw_name); #else "%s() got multiple values for keyword argument '%s'", func_name, PyString_AsString(kw_name)); #endif } //////////////////// RaiseMappingExpected.proto //////////////////// static void __Pyx_RaiseMappingExpectedError(PyObject* arg); /*proto*/ //////////////////// RaiseMappingExpected //////////////////// static void __Pyx_RaiseMappingExpectedError(PyObject* arg) { PyErr_Format(PyExc_TypeError, "'%.200s' object is not a mapping", Py_TYPE(arg)->tp_name); } //////////////////// KeywordStringCheck.proto //////////////////// static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict, const char* function_name, int kw_allowed); /*proto*/ //////////////////// KeywordStringCheck //////////////////// // __Pyx_CheckKeywordStrings raises an error if non-string keywords // were passed to a function, or if any keywords were passed to a // function that does not accept them. static CYTHON_INLINE int __Pyx_CheckKeywordStrings( PyObject *kwdict, const char* function_name, int kw_allowed) { PyObject* key = 0; Py_ssize_t pos = 0; #if CYTHON_COMPILING_IN_PYPY /* PyPy appears to check keywords at call time, not at unpacking time => not much to do here */ if (!kw_allowed && PyDict_Next(kwdict, &pos, &key, 0)) goto invalid_keyword; return 1; #else while (PyDict_Next(kwdict, &pos, &key, 0)) { #if PY_MAJOR_VERSION < 3 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) #endif if (unlikely(!PyUnicode_Check(key))) goto invalid_keyword_type; } if ((!kw_allowed) && unlikely(key)) goto invalid_keyword; return 1; invalid_keyword_type: PyErr_Format(PyExc_TypeError, "%.200s() keywords must be strings", function_name); return 0; #endif invalid_keyword: PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION < 3 "%.200s() got an unexpected keyword argument '%.200s'", function_name, PyString_AsString(key)); #else "%s() got an unexpected keyword argument '%U'", function_name, key); #endif return 0; } //////////////////// ParseKeywords.proto //////////////////// static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \ const char* function_name); /*proto*/ //////////////////// ParseKeywords //////////////////// //@requires: RaiseDoubleKeywords // __Pyx_ParseOptionalKeywords copies the optional/unknown keyword // arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown // keywords will raise an invalid keyword error. // // Three kinds of errors are checked: 1) non-string keywords, 2) // unexpected keywords and 3) overlap with positional arguments. // // If num_posargs is greater 0, it denotes the number of positional // arguments that were passed and that must therefore not appear // amongst the keywords as well. // // This method does not check for required keyword arguments. static int __Pyx_ParseOptionalKeywords( PyObject *kwds, PyObject **argnames[], PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, const char* function_name) { PyObject *key = 0, *value = 0; Py_ssize_t pos = 0; PyObject*** name; PyObject*** first_kw_arg = argnames + num_pos_args; while (PyDict_Next(kwds, &pos, &key, &value)) { name = first_kw_arg; while (*name && (**name != key)) name++; if (*name) { values[name-argnames] = value; continue; } name = first_kw_arg; #if PY_MAJOR_VERSION < 3 if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) { while (*name) { if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) && _PyString_Eq(**name, key)) { values[name-argnames] = value; break; } name++; } if (*name) continue; else { // not found after positional args, check for duplicate PyObject*** argname = argnames; while (argname != first_kw_arg) { if ((**argname == key) || ( (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) && _PyString_Eq(**argname, key))) { goto arg_passed_twice; } argname++; } } } else #endif if (likely(PyUnicode_Check(key))) { while (*name) { int cmp = (**name == key) ? 0 : #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 : #endif // need to convert argument name from bytes to unicode for comparison PyUnicode_Compare(**name, key); if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; if (cmp == 0) { values[name-argnames] = value; break; } name++; } if (*name) continue; else { // not found after positional args, check for duplicate PyObject*** argname = argnames; while (argname != first_kw_arg) { int cmp = (**argname == key) ? 0 : #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 : #endif // need to convert argument name from bytes to unicode for comparison PyUnicode_Compare(**argname, key); if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; if (cmp == 0) goto arg_passed_twice; argname++; } } } else goto invalid_keyword_type; if (kwds2) { if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; } else { goto invalid_keyword; } } return 0; arg_passed_twice: __Pyx_RaiseDoubleKeywordsError(function_name, key); goto bad; invalid_keyword_type: PyErr_Format(PyExc_TypeError, "%.200s() keywords must be strings", function_name); goto bad; invalid_keyword: PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION < 3 "%.200s() got an unexpected keyword argument '%.200s'", function_name, PyString_AsString(key)); #else "%s() got an unexpected keyword argument '%U'", function_name, key); #endif bad: return -1; } //////////////////// MergeKeywords.proto //////////////////// static int __Pyx_MergeKeywords(PyObject *kwdict, PyObject *source_mapping); /*proto*/ //////////////////// MergeKeywords //////////////////// //@requires: RaiseDoubleKeywords //@requires: Optimize.c::dict_iter static int __Pyx_MergeKeywords(PyObject *kwdict, PyObject *source_mapping) { PyObject *iter, *key = NULL, *value = NULL; int source_is_dict, result; Py_ssize_t orig_length, ppos = 0; iter = __Pyx_dict_iterator(source_mapping, 0, PYIDENT("items"), &orig_length, &source_is_dict); if (unlikely(!iter)) { // slow fallback: try converting to dict, then iterate PyObject *args; if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; PyErr_Clear(); args = PyTuple_Pack(1, source_mapping); if (likely(args)) { PyObject *fallback = PyObject_Call((PyObject*)&PyDict_Type, args, NULL); Py_DECREF(args); if (likely(fallback)) { iter = __Pyx_dict_iterator(fallback, 1, PYIDENT("items"), &orig_length, &source_is_dict); Py_DECREF(fallback); } } if (unlikely(!iter)) goto bad; } while (1) { result = __Pyx_dict_iter_next(iter, orig_length, &ppos, &key, &value, NULL, source_is_dict); if (unlikely(result < 0)) goto bad; if (!result) break; if (unlikely(PyDict_Contains(kwdict, key))) { __Pyx_RaiseDoubleKeywordsError("function", key); result = -1; } else { result = PyDict_SetItem(kwdict, key, value); } Py_DECREF(key); Py_DECREF(value); if (unlikely(result < 0)) goto bad; } Py_XDECREF(iter); return 0; bad: Py_XDECREF(iter); return -1; } Cython-0.23.4/Cython/Utility/ExtensionTypes.c0000644000175600017570000000375312606202452022270 0ustar jenkinsjenkins00000000000000 /////////////// CallNextTpDealloc.proto /////////////// static void __Pyx_call_next_tp_dealloc(PyObject* obj, destructor current_tp_dealloc); /////////////// CallNextTpDealloc /////////////// static void __Pyx_call_next_tp_dealloc(PyObject* obj, destructor current_tp_dealloc) { PyTypeObject* type = Py_TYPE(obj); /* try to find the first parent type that has a different tp_dealloc() function */ while (type && type->tp_dealloc != current_tp_dealloc) type = type->tp_base; while (type && type->tp_dealloc == current_tp_dealloc) type = type->tp_base; if (type) type->tp_dealloc(obj); } /////////////// CallNextTpTraverse.proto /////////////// static int __Pyx_call_next_tp_traverse(PyObject* obj, visitproc v, void *a, traverseproc current_tp_traverse); /////////////// CallNextTpTraverse /////////////// static int __Pyx_call_next_tp_traverse(PyObject* obj, visitproc v, void *a, traverseproc current_tp_traverse) { PyTypeObject* type = Py_TYPE(obj); /* try to find the first parent type that has a different tp_traverse() function */ while (type && type->tp_traverse != current_tp_traverse) type = type->tp_base; while (type && type->tp_traverse == current_tp_traverse) type = type->tp_base; if (type && type->tp_traverse) return type->tp_traverse(obj, v, a); // FIXME: really ignore? return 0; } /////////////// CallNextTpClear.proto /////////////// static void __Pyx_call_next_tp_clear(PyObject* obj, inquiry current_tp_dealloc); /////////////// CallNextTpClear /////////////// static void __Pyx_call_next_tp_clear(PyObject* obj, inquiry current_tp_clear) { PyTypeObject* type = Py_TYPE(obj); /* try to find the first parent type that has a different tp_clear() function */ while (type && type->tp_clear != current_tp_clear) type = type->tp_base; while (type && type->tp_clear == current_tp_clear) type = type->tp_base; if (type && type->tp_clear) type->tp_clear(obj); } Cython-0.23.4/Cython/Utility/Exceptions.c0000644000175600017570000004170212606202452021404 0ustar jenkinsjenkins00000000000000// Exception raising code // // Exceptions are raised by __Pyx_Raise() and stored as plain // type/value/tb in PyThreadState->curexc_*. When being caught by an // 'except' statement, curexc_* is moved over to exc_* by // __Pyx_GetException() /////////////// PyErrFetchRestore.proto /////////////// static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/ static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/ /////////////// PyErrFetchRestore /////////////// static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) { #if CYTHON_COMPILING_IN_CPYTHON PyObject *tmp_type, *tmp_value, *tmp_tb; PyThreadState *tstate = PyThreadState_GET(); tmp_type = tstate->curexc_type; tmp_value = tstate->curexc_value; tmp_tb = tstate->curexc_traceback; tstate->curexc_type = type; tstate->curexc_value = value; tstate->curexc_traceback = tb; Py_XDECREF(tmp_type); Py_XDECREF(tmp_value); Py_XDECREF(tmp_tb); #else PyErr_Restore(type, value, tb); #endif } static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) { #if CYTHON_COMPILING_IN_CPYTHON PyThreadState *tstate = PyThreadState_GET(); *type = tstate->curexc_type; *value = tstate->curexc_value; *tb = tstate->curexc_traceback; tstate->curexc_type = 0; tstate->curexc_value = 0; tstate->curexc_traceback = 0; #else PyErr_Fetch(type, value, tb); #endif } /////////////// RaiseException.proto /////////////// static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/ /////////////// RaiseException /////////////// //@requires: PyErrFetchRestore // The following function is based on do_raise() from ceval.c. There // are separate versions for Python2 and Python3 as exception handling // has changed quite a lot between the two versions. #if PY_MAJOR_VERSION < 3 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, CYTHON_UNUSED PyObject *cause) { /* 'cause' is only used in Py3 */ Py_XINCREF(type); if (!value || value == Py_None) value = NULL; else Py_INCREF(value); if (!tb || tb == Py_None) tb = NULL; else { Py_INCREF(tb); if (!PyTraceBack_Check(tb)) { PyErr_SetString(PyExc_TypeError, "raise: arg 3 must be a traceback or None"); goto raise_error; } } if (PyType_Check(type)) { /* instantiate the type now (we don't know when and how it will be caught) */ #if CYTHON_COMPILING_IN_PYPY /* PyPy can't handle value == NULL */ if (!value) { Py_INCREF(Py_None); value = Py_None; } #endif PyErr_NormalizeException(&type, &value, &tb); } else { /* Raising an instance. The value should be a dummy. */ if (value) { PyErr_SetString(PyExc_TypeError, "instance exception may not have a separate value"); goto raise_error; } /* Normalize to raise , */ value = type; type = (PyObject*) Py_TYPE(type); Py_INCREF(type); if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) { PyErr_SetString(PyExc_TypeError, "raise: exception class must be a subclass of BaseException"); goto raise_error; } } __Pyx_ErrRestore(type, value, tb); return; raise_error: Py_XDECREF(value); Py_XDECREF(type); Py_XDECREF(tb); return; } #else /* Python 3+ */ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) { PyObject* owned_instance = NULL; if (tb == Py_None) { tb = 0; } else if (tb && !PyTraceBack_Check(tb)) { PyErr_SetString(PyExc_TypeError, "raise: arg 3 must be a traceback or None"); goto bad; } if (value == Py_None) value = 0; if (PyExceptionInstance_Check(type)) { if (value) { PyErr_SetString(PyExc_TypeError, "instance exception may not have a separate value"); goto bad; } value = type; type = (PyObject*) Py_TYPE(value); } else if (PyExceptionClass_Check(type)) { // make sure value is an exception instance of type PyObject *instance_class = NULL; if (value && PyExceptionInstance_Check(value)) { instance_class = (PyObject*) Py_TYPE(value); if (instance_class != type) { int is_subclass = PyObject_IsSubclass(instance_class, type); if (!is_subclass) { instance_class = NULL; } else if (unlikely(is_subclass == -1)) { // error on subclass test goto bad; } else { // believe the instance type = instance_class; } } } if (!instance_class) { // instantiate the type now (we don't know when and how it will be caught) // assuming that 'value' is an argument to the type's constructor // not using PyErr_NormalizeException() to avoid ref-counting problems PyObject *args; if (!value) args = PyTuple_New(0); else if (PyTuple_Check(value)) { Py_INCREF(value); args = value; } else args = PyTuple_Pack(1, value); if (!args) goto bad; owned_instance = PyObject_Call(type, args, NULL); Py_DECREF(args); if (!owned_instance) goto bad; value = owned_instance; if (!PyExceptionInstance_Check(value)) { PyErr_Format(PyExc_TypeError, "calling %R should have returned an instance of " "BaseException, not %R", type, Py_TYPE(value)); goto bad; } } } else { PyErr_SetString(PyExc_TypeError, "raise: exception class must be a subclass of BaseException"); goto bad; } #if PY_VERSION_HEX >= 0x03030000 if (cause) { #else if (cause && cause != Py_None) { #endif PyObject *fixed_cause; if (cause == Py_None) { // raise ... from None fixed_cause = NULL; } else if (PyExceptionClass_Check(cause)) { fixed_cause = PyObject_CallObject(cause, NULL); if (fixed_cause == NULL) goto bad; } else if (PyExceptionInstance_Check(cause)) { fixed_cause = cause; Py_INCREF(fixed_cause); } else { PyErr_SetString(PyExc_TypeError, "exception causes must derive from " "BaseException"); goto bad; } PyException_SetCause(value, fixed_cause); } PyErr_SetObject(type, value); if (tb) { #if CYTHON_COMPILING_IN_PYPY PyObject *tmp_type, *tmp_value, *tmp_tb; PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb); Py_INCREF(tb); PyErr_Restore(tmp_type, tmp_value, tb); Py_XDECREF(tmp_tb); #else PyThreadState *tstate = PyThreadState_GET(); PyObject* tmp_tb = tstate->curexc_traceback; if (tb != tmp_tb) { Py_INCREF(tb); tstate->curexc_traceback = tb; Py_XDECREF(tmp_tb); } #endif } bad: Py_XDECREF(owned_instance); return; } #endif /////////////// GetException.proto /////////////// static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/ /////////////// GetException /////////////// static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) { PyObject *local_type, *local_value, *local_tb; #if CYTHON_COMPILING_IN_CPYTHON PyObject *tmp_type, *tmp_value, *tmp_tb; PyThreadState *tstate = PyThreadState_GET(); local_type = tstate->curexc_type; local_value = tstate->curexc_value; local_tb = tstate->curexc_traceback; tstate->curexc_type = 0; tstate->curexc_value = 0; tstate->curexc_traceback = 0; #else PyErr_Fetch(&local_type, &local_value, &local_tb); #endif PyErr_NormalizeException(&local_type, &local_value, &local_tb); #if CYTHON_COMPILING_IN_CPYTHON if (unlikely(tstate->curexc_type)) #else if (unlikely(PyErr_Occurred())) #endif goto bad; #if PY_MAJOR_VERSION >= 3 if (local_tb) { if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) goto bad; } #endif // traceback may be NULL for freshly raised exceptions Py_XINCREF(local_tb); // exception state may be temporarily empty in parallel loops (race condition) Py_XINCREF(local_type); Py_XINCREF(local_value); *type = local_type; *value = local_value; *tb = local_tb; #if CYTHON_COMPILING_IN_CPYTHON tmp_type = tstate->exc_type; tmp_value = tstate->exc_value; tmp_tb = tstate->exc_traceback; tstate->exc_type = local_type; tstate->exc_value = local_value; tstate->exc_traceback = local_tb; // Make sure tstate is in a consistent state when we XDECREF // these objects (DECREF may run arbitrary code). Py_XDECREF(tmp_type); Py_XDECREF(tmp_value); Py_XDECREF(tmp_tb); #else PyErr_SetExcInfo(local_type, local_value, local_tb); #endif return 0; bad: *type = 0; *value = 0; *tb = 0; Py_XDECREF(local_type); Py_XDECREF(local_value); Py_XDECREF(local_tb); return -1; } /////////////// ReRaiseException.proto /////////////// static CYTHON_INLINE void __Pyx_ReraiseException(void); /*proto*/ /////////////// ReRaiseException.proto /////////////// static CYTHON_INLINE void __Pyx_ReraiseException(void) { PyObject *type = NULL, *value = NULL, *tb = NULL; #if CYTHON_COMPILING_IN_CPYTHON PyThreadState *tstate = PyThreadState_GET(); type = tstate->exc_type; value = tstate->exc_value; tb = tstate->exc_traceback; #else PyErr_GetExcInfo(&type, &value, &tb); #endif if (!type || type == Py_None) { #if !CYTHON_COMPILING_IN_CPYTHON Py_XDECREF(type); Py_XDECREF(value); Py_XDECREF(tb); #endif // message copied from Py3 PyErr_SetString(PyExc_RuntimeError, "No active exception to reraise"); } else { #if CYTHON_COMPILING_IN_CPYTHON Py_INCREF(type); Py_XINCREF(value); Py_XINCREF(tb); #endif PyErr_Restore(type, value, tb); } } /////////////// SaveResetException.proto /////////////// static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/ static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/ /////////////// SaveResetException /////////////// static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) { #if CYTHON_COMPILING_IN_CPYTHON PyThreadState *tstate = PyThreadState_GET(); *type = tstate->exc_type; *value = tstate->exc_value; *tb = tstate->exc_traceback; Py_XINCREF(*type); Py_XINCREF(*value); Py_XINCREF(*tb); #else PyErr_GetExcInfo(type, value, tb); #endif } static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) { #if CYTHON_COMPILING_IN_CPYTHON PyObject *tmp_type, *tmp_value, *tmp_tb; PyThreadState *tstate = PyThreadState_GET(); tmp_type = tstate->exc_type; tmp_value = tstate->exc_value; tmp_tb = tstate->exc_traceback; tstate->exc_type = type; tstate->exc_value = value; tstate->exc_traceback = tb; Py_XDECREF(tmp_type); Py_XDECREF(tmp_value); Py_XDECREF(tmp_tb); #else PyErr_SetExcInfo(type, value, tb); #endif } /////////////// SwapException.proto /////////////// static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb); /*proto*/ /////////////// SwapException /////////////// static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; #if CYTHON_COMPILING_IN_CPYTHON PyThreadState *tstate = PyThreadState_GET(); tmp_type = tstate->exc_type; tmp_value = tstate->exc_value; tmp_tb = tstate->exc_traceback; tstate->exc_type = *type; tstate->exc_value = *value; tstate->exc_traceback = *tb; #else PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb); PyErr_SetExcInfo(*type, *value, *tb); #endif *type = tmp_type; *value = tmp_value; *tb = tmp_tb; } /////////////// WriteUnraisableException.proto /////////////// static void __Pyx_WriteUnraisable(const char *name, int clineno, int lineno, const char *filename, int full_traceback, int nogil); /*proto*/ /////////////// WriteUnraisableException /////////////// //@requires: PyErrFetchRestore static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno, CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename, int full_traceback, CYTHON_UNUSED int nogil) { PyObject *old_exc, *old_val, *old_tb; PyObject *ctx; #ifdef WITH_THREAD PyGILState_STATE state; if (nogil) state = PyGILState_Ensure(); #endif __Pyx_ErrFetch(&old_exc, &old_val, &old_tb); if (full_traceback) { Py_XINCREF(old_exc); Py_XINCREF(old_val); Py_XINCREF(old_tb); __Pyx_ErrRestore(old_exc, old_val, old_tb); PyErr_PrintEx(1); } #if PY_MAJOR_VERSION < 3 ctx = PyString_FromString(name); #else ctx = PyUnicode_FromString(name); #endif __Pyx_ErrRestore(old_exc, old_val, old_tb); if (!ctx) { PyErr_WriteUnraisable(Py_None); } else { PyErr_WriteUnraisable(ctx); Py_DECREF(ctx); } #ifdef WITH_THREAD if (nogil) PyGILState_Release(state); #endif } /////////////// AddTraceback.proto /////////////// static void __Pyx_AddTraceback(const char *funcname, int c_line, int py_line, const char *filename); /*proto*/ /////////////// AddTraceback /////////////// //@requires: ModuleSetupCode.c::CodeObjectCache //@substitute: naming #include "compile.h" #include "frameobject.h" #include "traceback.h" static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( const char *funcname, int c_line, int py_line, const char *filename) { PyCodeObject *py_code = 0; PyObject *py_srcfile = 0; PyObject *py_funcname = 0; #if PY_MAJOR_VERSION < 3 py_srcfile = PyString_FromString(filename); #else py_srcfile = PyUnicode_FromString(filename); #endif if (!py_srcfile) goto bad; if (c_line) { #if PY_MAJOR_VERSION < 3 py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, $cfilenm_cname, c_line); #else py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, $cfilenm_cname, c_line); #endif } else { #if PY_MAJOR_VERSION < 3 py_funcname = PyString_FromString(funcname); #else py_funcname = PyUnicode_FromString(funcname); #endif } if (!py_funcname) goto bad; py_code = __Pyx_PyCode_New( 0, /*int argcount,*/ 0, /*int kwonlyargcount,*/ 0, /*int nlocals,*/ 0, /*int stacksize,*/ 0, /*int flags,*/ $empty_bytes, /*PyObject *code,*/ $empty_tuple, /*PyObject *consts,*/ $empty_tuple, /*PyObject *names,*/ $empty_tuple, /*PyObject *varnames,*/ $empty_tuple, /*PyObject *freevars,*/ $empty_tuple, /*PyObject *cellvars,*/ py_srcfile, /*PyObject *filename,*/ py_funcname, /*PyObject *name,*/ py_line, /*int firstlineno,*/ $empty_bytes /*PyObject *lnotab*/ ); Py_DECREF(py_srcfile); Py_DECREF(py_funcname); return py_code; bad: Py_XDECREF(py_srcfile); Py_XDECREF(py_funcname); return NULL; } static void __Pyx_AddTraceback(const char *funcname, int c_line, int py_line, const char *filename) { PyCodeObject *py_code = 0; PyFrameObject *py_frame = 0; py_code = $global_code_object_cache_find(c_line ? c_line : py_line); if (!py_code) { py_code = __Pyx_CreateCodeObjectForTraceback( funcname, c_line, py_line, filename); if (!py_code) goto bad; $global_code_object_cache_insert(c_line ? c_line : py_line, py_code); } py_frame = PyFrame_New( PyThreadState_GET(), /*PyThreadState *tstate,*/ py_code, /*PyCodeObject *code,*/ $moddict_cname, /*PyObject *globals,*/ 0 /*PyObject *locals*/ ); if (!py_frame) goto bad; py_frame->f_lineno = py_line; PyTraceBack_Here(py_frame); bad: Py_XDECREF(py_code); Py_XDECREF(py_frame); } Cython-0.23.4/Cython/Utility/Embed.c0000644000175600017570000001357212606202452020303 0ustar jenkinsjenkins00000000000000//////////////////// MainFunction //////////////////// #ifdef __FreeBSD__ #include #endif #if PY_MAJOR_VERSION < 3 int %(main_method)s(int argc, char** argv) { #elif defined(WIN32) || defined(MS_WINDOWS) int %(wmain_method)s(int argc, wchar_t **argv) { #else static int __Pyx_main(int argc, wchar_t **argv) { #endif /* 754 requires that FP exceptions run in "no stop" mode by default, * and until C vendors implement C99's ways to control FP exceptions, * Python requires non-stop mode. Alas, some platforms enable FP * exceptions by default. Here we disable them. */ #ifdef __FreeBSD__ fp_except_t m; m = fpgetmask(); fpsetmask(m & ~FP_X_OFL); #endif if (argc && argv) Py_SetProgramName(argv[0]); Py_Initialize(); if (argc && argv) PySys_SetArgv(argc, argv); { /* init module '%(module_name)s' as '__main__' */ PyObject* m = NULL; %(module_is_main)s = 1; #if PY_MAJOR_VERSION < 3 init%(module_name)s(); #else m = PyInit_%(module_name)s(); #endif if (PyErr_Occurred()) { PyErr_Print(); /* This exits with the right code if SystemExit. */ #if PY_MAJOR_VERSION < 3 if (Py_FlushLine()) PyErr_Clear(); #endif return 1; } Py_XDECREF(m); } Py_Finalize(); return 0; } #if PY_MAJOR_VERSION >= 3 && !defined(WIN32) && !defined(MS_WINDOWS) #include static wchar_t* __Pyx_char2wchar(char* arg) { wchar_t *res; #ifdef HAVE_BROKEN_MBSTOWCS /* Some platforms have a broken implementation of * mbstowcs which does not count the characters that * would result from conversion. Use an upper bound. */ size_t argsize = strlen(arg); #else size_t argsize = mbstowcs(NULL, arg, 0); #endif size_t count; unsigned char *in; wchar_t *out; #ifdef HAVE_MBRTOWC mbstate_t mbs; #endif if (argsize != (size_t)-1) { res = (wchar_t *)malloc((argsize+1)*sizeof(wchar_t)); if (!res) goto oom; count = mbstowcs(res, arg, argsize+1); if (count != (size_t)-1) { wchar_t *tmp; /* Only use the result if it contains no surrogate characters. */ for (tmp = res; *tmp != 0 && (*tmp < 0xd800 || *tmp > 0xdfff); tmp++) ; if (*tmp == 0) return res; } free(res); } /* Conversion failed. Fall back to escaping with surrogateescape. */ #ifdef HAVE_MBRTOWC /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */ /* Overallocate; as multi-byte characters are in the argument, the actual output could use less memory. */ argsize = strlen(arg) + 1; res = (wchar_t *)malloc(argsize*sizeof(wchar_t)); if (!res) goto oom; in = (unsigned char*)arg; out = res; memset(&mbs, 0, sizeof mbs); while (argsize) { size_t converted = mbrtowc(out, (char*)in, argsize, &mbs); if (converted == 0) /* Reached end of string; null char stored. */ break; if (converted == (size_t)-2) { /* Incomplete character. This should never happen, since we provide everything that we have - unless there is a bug in the C library, or I misunderstood how mbrtowc works. */ fprintf(stderr, "unexpected mbrtowc result -2\\n"); free(res); return NULL; } if (converted == (size_t)-1) { /* Conversion error. Escape as UTF-8b, and start over in the initial shift state. */ *out++ = 0xdc00 + *in++; argsize--; memset(&mbs, 0, sizeof mbs); continue; } if (*out >= 0xd800 && *out <= 0xdfff) { /* Surrogate character. Escape the original byte sequence with surrogateescape. */ argsize -= converted; while (converted--) *out++ = 0xdc00 + *in++; continue; } /* successfully converted some bytes */ in += converted; argsize -= converted; out++; } #else /* Cannot use C locale for escaping; manually escape as if charset is ASCII (i.e. escape all bytes > 128. This will still roundtrip correctly in the locale's charset, which must be an ASCII superset. */ res = (wchar_t *)malloc((strlen(arg)+1)*sizeof(wchar_t)); if (!res) goto oom; in = (unsigned char*)arg; out = res; while(*in) if(*in < 128) *out++ = *in++; else *out++ = 0xdc00 + *in++; *out = 0; #endif return res; oom: fprintf(stderr, "out of memory\\n"); return NULL; } int %(main_method)s(int argc, char **argv) { if (!argc) { return __Pyx_main(0, NULL); } else { int i, res; wchar_t **argv_copy = (wchar_t **)malloc(sizeof(wchar_t*)*argc); /* We need a second copy, as Python might modify the first one. */ wchar_t **argv_copy2 = (wchar_t **)malloc(sizeof(wchar_t*)*argc); char *oldloc = strdup(setlocale(LC_ALL, NULL)); if (!argv_copy || !argv_copy2 || !oldloc) { fprintf(stderr, "out of memory\\n"); free(argv_copy); free(argv_copy2); free(oldloc); return 1; } res = 0; setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { argv_copy2[i] = argv_copy[i] = __Pyx_char2wchar(argv[i]); if (!argv_copy[i]) res = 1; /* failure, but continue to simplify cleanup */ } setlocale(LC_ALL, oldloc); free(oldloc); if (res == 0) res = __Pyx_main(argc, argv_copy); for (i = 0; i < argc; i++) { free(argv_copy2[i]); } free(argv_copy); free(argv_copy2); return res; } } #endif Cython-0.23.4/Cython/Utility/CythonFunction.c0000644000175600017570000012027212606202452022235 0ustar jenkinsjenkins00000000000000 //////////////////// CythonFunction.proto //////////////////// #define __Pyx_CyFunction_USED 1 #include #define __Pyx_CYFUNCTION_STATICMETHOD 0x01 #define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 #define __Pyx_CYFUNCTION_CCLASS 0x04 #define __Pyx_CyFunction_GetClosure(f) \ (((__pyx_CyFunctionObject *) (f))->func_closure) #define __Pyx_CyFunction_GetClassObj(f) \ (((__pyx_CyFunctionObject *) (f))->func_classobj) #define __Pyx_CyFunction_Defaults(type, f) \ ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) #define __Pyx_CyFunction_SetDefaultsGetter(f, g) \ ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) typedef struct { PyCFunctionObject func; #if PY_VERSION_HEX < 0x030500A0 PyObject *func_weakreflist; #endif PyObject *func_dict; PyObject *func_name; PyObject *func_qualname; PyObject *func_doc; PyObject *func_globals; PyObject *func_code; PyObject *func_closure; // No-args super() class cell PyObject *func_classobj; // Dynamic default args and annotations void *defaults; int defaults_pyobjects; int flags; // Defaults info PyObject *defaults_tuple; /* Const defaults tuple */ PyObject *defaults_kwdict; /* Const kwonly defaults dict */ PyObject *(*defaults_getter)(PyObject *); PyObject *func_annotations; /* function annotations dict */ } __pyx_CyFunctionObject; static PyTypeObject *__pyx_CyFunctionType = 0; #define __Pyx_CyFunction_NewEx(ml, flags, qualname, self, module, globals, code) \ __Pyx_CyFunction_New(__pyx_CyFunctionType, ml, flags, qualname, self, module, globals, code) static PyObject *__Pyx_CyFunction_New(PyTypeObject *, PyMethodDef *ml, int flags, PyObject* qualname, PyObject *self, PyObject *module, PyObject *globals, PyObject* code); static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m, size_t size, int pyobjects); static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, PyObject *tuple); static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, PyObject *dict); static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, PyObject *dict); static int __pyx_CyFunction_init(void); //////////////////// CythonFunction //////////////////// //@substitute: naming //@requires: CommonTypes.c::FetchCommonType ////@requires: ObjectHandling.c::PyObjectGetAttrStr static PyObject * __Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *closure) { if (unlikely(op->func_doc == NULL)) { if (op->func.m_ml->ml_doc) { #if PY_MAJOR_VERSION >= 3 op->func_doc = PyUnicode_FromString(op->func.m_ml->ml_doc); #else op->func_doc = PyString_FromString(op->func.m_ml->ml_doc); #endif if (unlikely(op->func_doc == NULL)) return NULL; } else { Py_INCREF(Py_None); return Py_None; } } Py_INCREF(op->func_doc); return op->func_doc; } static int __Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value) { PyObject *tmp = op->func_doc; if (value == NULL) { // Mark as deleted value = Py_None; } Py_INCREF(value); op->func_doc = value; Py_XDECREF(tmp); return 0; } static PyObject * __Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op) { if (unlikely(op->func_name == NULL)) { #if PY_MAJOR_VERSION >= 3 op->func_name = PyUnicode_InternFromString(op->func.m_ml->ml_name); #else op->func_name = PyString_InternFromString(op->func.m_ml->ml_name); #endif if (unlikely(op->func_name == NULL)) return NULL; } Py_INCREF(op->func_name); return op->func_name; } static int __Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value) { PyObject *tmp; #if PY_MAJOR_VERSION >= 3 if (unlikely(value == NULL || !PyUnicode_Check(value))) { #else if (unlikely(value == NULL || !PyString_Check(value))) { #endif PyErr_SetString(PyExc_TypeError, "__name__ must be set to a string object"); return -1; } tmp = op->func_name; Py_INCREF(value); op->func_name = value; Py_XDECREF(tmp); return 0; } static PyObject * __Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op) { Py_INCREF(op->func_qualname); return op->func_qualname; } static int __Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value) { PyObject *tmp; #if PY_MAJOR_VERSION >= 3 if (unlikely(value == NULL || !PyUnicode_Check(value))) { #else if (unlikely(value == NULL || !PyString_Check(value))) { #endif PyErr_SetString(PyExc_TypeError, "__qualname__ must be set to a string object"); return -1; } tmp = op->func_qualname; Py_INCREF(value); op->func_qualname = value; Py_XDECREF(tmp); return 0; } static PyObject * __Pyx_CyFunction_get_self(__pyx_CyFunctionObject *m, CYTHON_UNUSED void *closure) { PyObject *self; self = m->func_closure; if (self == NULL) self = Py_None; Py_INCREF(self); return self; } static PyObject * __Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op) { if (unlikely(op->func_dict == NULL)) { op->func_dict = PyDict_New(); if (unlikely(op->func_dict == NULL)) return NULL; } Py_INCREF(op->func_dict); return op->func_dict; } static int __Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value) { PyObject *tmp; if (unlikely(value == NULL)) { PyErr_SetString(PyExc_TypeError, "function's dictionary may not be deleted"); return -1; } if (unlikely(!PyDict_Check(value))) { PyErr_SetString(PyExc_TypeError, "setting function's dictionary to a non-dict"); return -1; } tmp = op->func_dict; Py_INCREF(value); op->func_dict = value; Py_XDECREF(tmp); return 0; } static PyObject * __Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op) { Py_INCREF(op->func_globals); return op->func_globals; } static PyObject * __Pyx_CyFunction_get_closure(CYTHON_UNUSED __pyx_CyFunctionObject *op) { Py_INCREF(Py_None); return Py_None; } static PyObject * __Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op) { PyObject* result = (op->func_code) ? op->func_code : Py_None; Py_INCREF(result); return result; } static int __Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { int result = 0; PyObject *res = op->defaults_getter((PyObject *) op); if (unlikely(!res)) return -1; // Cache result #if CYTHON_COMPILING_IN_CPYTHON op->defaults_tuple = PyTuple_GET_ITEM(res, 0); Py_INCREF(op->defaults_tuple); op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); Py_INCREF(op->defaults_kwdict); #else op->defaults_tuple = PySequence_ITEM(res, 0); if (unlikely(!op->defaults_tuple)) result = -1; else { op->defaults_kwdict = PySequence_ITEM(res, 1); if (unlikely(!op->defaults_kwdict)) result = -1; } #endif Py_DECREF(res); return result; } static int __Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value) { PyObject* tmp; if (!value) { // del => explicit None to prevent rebuilding value = Py_None; } else if (value != Py_None && !PyTuple_Check(value)) { PyErr_SetString(PyExc_TypeError, "__defaults__ must be set to a tuple object"); return -1; } Py_INCREF(value); tmp = op->defaults_tuple; op->defaults_tuple = value; Py_XDECREF(tmp); return 0; } static PyObject * __Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op) { PyObject* result = op->defaults_tuple; if (unlikely(!result)) { if (op->defaults_getter) { if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL; result = op->defaults_tuple; } else { result = Py_None; } } Py_INCREF(result); return result; } static int __Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value) { PyObject* tmp; if (!value) { // del => explicit None to prevent rebuilding value = Py_None; } else if (value != Py_None && !PyDict_Check(value)) { PyErr_SetString(PyExc_TypeError, "__kwdefaults__ must be set to a dict object"); return -1; } Py_INCREF(value); tmp = op->defaults_kwdict; op->defaults_kwdict = value; Py_XDECREF(tmp); return 0; } static PyObject * __Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op) { PyObject* result = op->defaults_kwdict; if (unlikely(!result)) { if (op->defaults_getter) { if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL; result = op->defaults_kwdict; } else { result = Py_None; } } Py_INCREF(result); return result; } static int __Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value) { PyObject* tmp; if (!value || value == Py_None) { value = NULL; } else if (!PyDict_Check(value)) { PyErr_SetString(PyExc_TypeError, "__annotations__ must be set to a dict object"); return -1; } Py_XINCREF(value); tmp = op->func_annotations; op->func_annotations = value; Py_XDECREF(tmp); return 0; } static PyObject * __Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op) { PyObject* result = op->func_annotations; if (unlikely(!result)) { result = PyDict_New(); if (unlikely(!result)) return NULL; op->func_annotations = result; } Py_INCREF(result); return result; } //#if PY_VERSION_HEX >= 0x030400C1 //static PyObject * //__Pyx_CyFunction_get_signature(__pyx_CyFunctionObject *op) { // PyObject *inspect_module, *signature_class, *signature; // // from inspect import Signature // inspect_module = PyImport_ImportModuleLevelObject(PYIDENT("inspect"), NULL, NULL, NULL, 0); // if (unlikely(!inspect_module)) // goto bad; // signature_class = __Pyx_PyObject_GetAttrStr(inspect_module, PYIDENT("Signature")); // Py_DECREF(inspect_module); // if (unlikely(!signature_class)) // goto bad; // // return Signature.from_function(op) // signature = PyObject_CallMethodObjArgs(signature_class, PYIDENT("from_function"), op, NULL); // Py_DECREF(signature_class); // if (likely(signature)) // return signature; //bad: // // make sure we raise an AttributeError from this property on any errors // if (!PyErr_ExceptionMatches(PyExc_AttributeError)) // PyErr_SetString(PyExc_AttributeError, "failed to calculate __signature__"); // return NULL; //} //#endif static PyGetSetDef __pyx_CyFunction_getsets[] = { {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, {(char *) "__self__", (getter)__Pyx_CyFunction_get_self, 0, 0, 0}, {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0}, {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, //#if PY_VERSION_HEX >= 0x030400C1 // {(char *) "__signature__", (getter)__Pyx_CyFunction_get_signature, 0, 0, 0}, //#endif {0, 0, 0, 0, 0} }; static PyMemberDef __pyx_CyFunction_members[] = { {(char *) "__module__", T_OBJECT, offsetof(__pyx_CyFunctionObject, func.m_module), PY_WRITE_RESTRICTED, 0}, {0, 0, 0, 0, 0} }; static PyObject * __Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, CYTHON_UNUSED PyObject *args) { #if PY_MAJOR_VERSION >= 3 return PyUnicode_FromString(m->func.m_ml->ml_name); #else return PyString_FromString(m->func.m_ml->ml_name); #endif } static PyMethodDef __pyx_CyFunction_methods[] = { {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, {0, 0, 0, 0} }; #if PY_VERSION_HEX < 0x030500A0 #define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) #else #define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func.m_weakreflist) #endif static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject* qualname, PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { __pyx_CyFunctionObject *op = PyObject_GC_New(__pyx_CyFunctionObject, type); if (op == NULL) return NULL; op->flags = flags; __Pyx_CyFunction_weakreflist(op) = NULL; op->func.m_ml = ml; op->func.m_self = (PyObject *) op; Py_XINCREF(closure); op->func_closure = closure; Py_XINCREF(module); op->func.m_module = module; op->func_dict = NULL; op->func_name = NULL; Py_INCREF(qualname); op->func_qualname = qualname; op->func_doc = NULL; op->func_classobj = NULL; op->func_globals = globals; Py_INCREF(op->func_globals); Py_XINCREF(code); op->func_code = code; // Dynamic Default args op->defaults_pyobjects = 0; op->defaults = NULL; op->defaults_tuple = NULL; op->defaults_kwdict = NULL; op->defaults_getter = NULL; op->func_annotations = NULL; PyObject_GC_Track(op); return (PyObject *) op; } static int __Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) { Py_CLEAR(m->func_closure); Py_CLEAR(m->func.m_module); Py_CLEAR(m->func_dict); Py_CLEAR(m->func_name); Py_CLEAR(m->func_qualname); Py_CLEAR(m->func_doc); Py_CLEAR(m->func_globals); Py_CLEAR(m->func_code); Py_CLEAR(m->func_classobj); Py_CLEAR(m->defaults_tuple); Py_CLEAR(m->defaults_kwdict); Py_CLEAR(m->func_annotations); if (m->defaults) { PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); int i; for (i = 0; i < m->defaults_pyobjects; i++) Py_XDECREF(pydefaults[i]); PyMem_Free(m->defaults); m->defaults = NULL; } return 0; } static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) { PyObject_GC_UnTrack(m); if (__Pyx_CyFunction_weakreflist(m) != NULL) PyObject_ClearWeakRefs((PyObject *) m); __Pyx_CyFunction_clear(m); PyObject_GC_Del(m); } static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) { Py_VISIT(m->func_closure); Py_VISIT(m->func.m_module); Py_VISIT(m->func_dict); Py_VISIT(m->func_name); Py_VISIT(m->func_qualname); Py_VISIT(m->func_doc); Py_VISIT(m->func_globals); Py_VISIT(m->func_code); Py_VISIT(m->func_classobj); Py_VISIT(m->defaults_tuple); Py_VISIT(m->defaults_kwdict); if (m->defaults) { PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m); int i; for (i = 0; i < m->defaults_pyobjects; i++) Py_VISIT(pydefaults[i]); } return 0; } static PyObject *__Pyx_CyFunction_descr_get(PyObject *func, PyObject *obj, PyObject *type) { __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; if (m->flags & __Pyx_CYFUNCTION_STATICMETHOD) { Py_INCREF(func); return func; } if (m->flags & __Pyx_CYFUNCTION_CLASSMETHOD) { if (type == NULL) type = (PyObject *)(Py_TYPE(obj)); return __Pyx_PyMethod_New(func, type, (PyObject *)(Py_TYPE(type))); } if (obj == Py_None) obj = NULL; return __Pyx_PyMethod_New(func, obj, type); } static PyObject* __Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) { #if PY_MAJOR_VERSION >= 3 return PyUnicode_FromFormat("", op->func_qualname, (void *)op); #else return PyString_FromFormat("", PyString_AsString(op->func_qualname), (void *)op); #endif } #if CYTHON_COMPILING_IN_PYPY // originally copied from PyCFunction_Call() in CPython's Objects/methodobject.c // PyPy does not have this function static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { PyCFunctionObject* f = (PyCFunctionObject*)func; PyCFunction meth = f->m_ml->ml_meth; PyObject *self = f->m_self; Py_ssize_t size; switch (f->m_ml->ml_flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { case METH_VARARGS: if (likely(kw == NULL || PyDict_Size(kw) == 0)) return (*meth)(self, arg); break; case METH_VARARGS | METH_KEYWORDS: return (*(PyCFunctionWithKeywords)meth)(self, arg, kw); case METH_NOARGS: if (likely(kw == NULL || PyDict_Size(kw) == 0)) { size = PyTuple_GET_SIZE(arg); if (likely(size == 0)) return (*meth)(self, NULL); PyErr_Format(PyExc_TypeError, "%.200s() takes no arguments (%" CYTHON_FORMAT_SSIZE_T "d given)", f->m_ml->ml_name, size); return NULL; } break; case METH_O: if (likely(kw == NULL || PyDict_Size(kw) == 0)) { size = PyTuple_GET_SIZE(arg); if (likely(size == 1)) { PyObject *result, *arg0 = PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; result = (*meth)(self, arg0); Py_DECREF(arg0); return result; } PyErr_Format(PyExc_TypeError, "%.200s() takes exactly one argument (%" CYTHON_FORMAT_SSIZE_T "d given)", f->m_ml->ml_name, size); return NULL; } break; default: PyErr_SetString(PyExc_SystemError, "Bad call flags in " "__Pyx_CyFunction_Call. METH_OLDARGS is no " "longer supported!"); return NULL; } PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", f->m_ml->ml_name); return NULL; } #else static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { return PyCFunction_Call(func, arg, kw); } #endif static PyTypeObject __pyx_CyFunctionType_type = { PyVarObject_HEAD_INIT(0, 0) "cython_function_or_method", /*tp_name*/ sizeof(__pyx_CyFunctionObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor) __Pyx_CyFunction_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #else 0, /*reserved*/ #endif (reprfunc) __Pyx_CyFunction_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ __Pyx_CyFunction_Call, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ 0, /*tp_doc*/ (traverseproc) __Pyx_CyFunction_traverse, /*tp_traverse*/ (inquiry) __Pyx_CyFunction_clear, /*tp_clear*/ 0, /*tp_richcompare*/ #if PY_VERSION_HEX < 0x030500A0 offsetof(__pyx_CyFunctionObject, func_weakreflist), /*tp_weaklistoffset*/ #else offsetof(PyCFunctionObject, m_weakreflist), /*tp_weaklistoffset*/ #endif 0, /*tp_iter*/ 0, /*tp_iternext*/ __pyx_CyFunction_methods, /*tp_methods*/ __pyx_CyFunction_members, /*tp_members*/ __pyx_CyFunction_getsets, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ __Pyx_CyFunction_descr_get, /*tp_descr_get*/ 0, /*tp_descr_set*/ offsetof(__pyx_CyFunctionObject, func_dict),/*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ 0, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static int __pyx_CyFunction_init(void) { #if !CYTHON_COMPILING_IN_PYPY // avoid a useless level of call indirection __pyx_CyFunctionType_type.tp_call = PyCFunction_Call; #endif __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type); if (__pyx_CyFunctionType == NULL) { return -1; } return 0; } static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) { __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; m->defaults = PyMem_Malloc(size); if (!m->defaults) return PyErr_NoMemory(); memset(m->defaults, 0, size); m->defaults_pyobjects = pyobjects; return m->defaults; } static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; m->defaults_tuple = tuple; Py_INCREF(tuple); } static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; m->defaults_kwdict = dict; Py_INCREF(dict); } static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; m->func_annotations = dict; Py_INCREF(dict); } //////////////////// CyFunctionClassCell.proto //////////////////// static CYTHON_INLINE int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *classobj); //////////////////// CyFunctionClassCell //////////////////// //@requires: CythonFunction static CYTHON_INLINE int __Pyx_CyFunction_InitClassCell(PyObject *cyfunctions, PyObject *classobj) { Py_ssize_t i, count = PyList_GET_SIZE(cyfunctions); for (i = 0; i < count; i++) { __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) #if CYTHON_COMPILING_IN_CPYTHON PyList_GET_ITEM(cyfunctions, i); #else PySequence_ITEM(cyfunctions, i); if (unlikely(!m)) return -1; #endif Py_INCREF(classobj); m->func_classobj = classobj; #if !CYTHON_COMPILING_IN_CPYTHON Py_DECREF((PyObject*)m); #endif } return 0; } //////////////////// FusedFunction.proto //////////////////// typedef struct { __pyx_CyFunctionObject func; PyObject *__signatures__; PyObject *type; PyObject *self; } __pyx_FusedFunctionObject; #define __pyx_FusedFunction_NewEx(ml, flags, qualname, self, module, globals, code) \ __pyx_FusedFunction_New(__pyx_FusedFunctionType, ml, flags, qualname, self, module, globals, code) static PyObject *__pyx_FusedFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject *qualname, PyObject *self, PyObject *module, PyObject *globals, PyObject *code); static int __pyx_FusedFunction_clear(__pyx_FusedFunctionObject *self); static PyTypeObject *__pyx_FusedFunctionType = NULL; static int __pyx_FusedFunction_init(void); #define __Pyx_FusedFunction_USED //////////////////// FusedFunction //////////////////// //@requires: CythonFunction static PyObject * __pyx_FusedFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject *qualname, PyObject *self, PyObject *module, PyObject *globals, PyObject *code) { __pyx_FusedFunctionObject *fusedfunc = (__pyx_FusedFunctionObject *) __Pyx_CyFunction_New(type, ml, flags, qualname, self, module, globals, code); if (!fusedfunc) return NULL; fusedfunc->__signatures__ = NULL; fusedfunc->type = NULL; fusedfunc->self = NULL; return (PyObject *) fusedfunc; } static void __pyx_FusedFunction_dealloc(__pyx_FusedFunctionObject *self) { __pyx_FusedFunction_clear(self); __pyx_FusedFunctionType->tp_free((PyObject *) self); } static int __pyx_FusedFunction_traverse(__pyx_FusedFunctionObject *self, visitproc visit, void *arg) { Py_VISIT(self->self); Py_VISIT(self->type); Py_VISIT(self->__signatures__); return __Pyx_CyFunction_traverse((__pyx_CyFunctionObject *) self, visit, arg); } static int __pyx_FusedFunction_clear(__pyx_FusedFunctionObject *self) { Py_CLEAR(self->self); Py_CLEAR(self->type); Py_CLEAR(self->__signatures__); return __Pyx_CyFunction_clear((__pyx_CyFunctionObject *) self); } static PyObject * __pyx_FusedFunction_descr_get(PyObject *self, PyObject *obj, PyObject *type) { __pyx_FusedFunctionObject *func, *meth; func = (__pyx_FusedFunctionObject *) self; if (func->self || func->func.flags & __Pyx_CYFUNCTION_STATICMETHOD) { // Do not allow rebinding and don't do anything for static methods Py_INCREF(self); return self; } if (obj == Py_None) obj = NULL; meth = (__pyx_FusedFunctionObject *) __pyx_FusedFunction_NewEx( ((PyCFunctionObject *) func)->m_ml, ((__pyx_CyFunctionObject *) func)->flags, ((__pyx_CyFunctionObject *) func)->func_qualname, ((__pyx_CyFunctionObject *) func)->func_closure, ((PyCFunctionObject *) func)->m_module, ((__pyx_CyFunctionObject *) func)->func_globals, ((__pyx_CyFunctionObject *) func)->func_code); if (!meth) return NULL; Py_XINCREF(func->func.func_classobj); meth->func.func_classobj = func->func.func_classobj; Py_XINCREF(func->__signatures__); meth->__signatures__ = func->__signatures__; Py_XINCREF(type); meth->type = type; Py_XINCREF(func->func.defaults_tuple); meth->func.defaults_tuple = func->func.defaults_tuple; if (func->func.flags & __Pyx_CYFUNCTION_CLASSMETHOD) obj = type; Py_XINCREF(obj); meth->self = obj; return (PyObject *) meth; } static PyObject * _obj_to_str(PyObject *obj) { if (PyType_Check(obj)) return PyObject_GetAttr(obj, PYIDENT("__name__")); else return PyObject_Str(obj); } static PyObject * __pyx_FusedFunction_getitem(__pyx_FusedFunctionObject *self, PyObject *idx) { PyObject *signature = NULL; PyObject *unbound_result_func; PyObject *result_func = NULL; if (self->__signatures__ == NULL) { PyErr_SetString(PyExc_TypeError, "Function is not fused"); return NULL; } if (PyTuple_Check(idx)) { PyObject *list = PyList_New(0); Py_ssize_t n = PyTuple_GET_SIZE(idx); PyObject *string = NULL; PyObject *sep = NULL; int i; if (!list) return NULL; for (i = 0; i < n; i++) { #if CYTHON_COMPILING_IN_CPYTHON PyObject *item = PyTuple_GET_ITEM(idx, i); #else PyObject *item = PySequence_ITEM(idx, i); #endif string = _obj_to_str(item); #if !CYTHON_COMPILING_IN_CPYTHON Py_DECREF(item); #endif if (!string || PyList_Append(list, string) < 0) goto __pyx_err; Py_DECREF(string); } sep = PyUnicode_FromString("|"); if (sep) signature = PyUnicode_Join(sep, list); __pyx_err: ; Py_DECREF(list); Py_XDECREF(sep); } else { signature = _obj_to_str(idx); } if (!signature) return NULL; unbound_result_func = PyObject_GetItem(self->__signatures__, signature); if (unbound_result_func) { if (self->self || self->type) { __pyx_FusedFunctionObject *unbound = (__pyx_FusedFunctionObject *) unbound_result_func; // TODO: move this to InitClassCell Py_CLEAR(unbound->func.func_classobj); Py_XINCREF(self->func.func_classobj); unbound->func.func_classobj = self->func.func_classobj; result_func = __pyx_FusedFunction_descr_get(unbound_result_func, self->self, self->type); } else { result_func = unbound_result_func; Py_INCREF(result_func); } } Py_DECREF(signature); Py_XDECREF(unbound_result_func); return result_func; } static PyObject * __pyx_FusedFunction_callfunction(PyObject *func, PyObject *args, PyObject *kw) { __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; PyObject *result; int static_specialized = (cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD && !((__pyx_FusedFunctionObject *) func)->__signatures__); if (cyfunc->flags & __Pyx_CYFUNCTION_CCLASS && !static_specialized) { Py_ssize_t argc; PyObject *new_args; PyObject *self; PyObject *m_self; argc = PyTuple_GET_SIZE(args); new_args = PyTuple_GetSlice(args, 1, argc); if (!new_args) return NULL; self = PyTuple_GetItem(args, 0); if (!self) return NULL; m_self = cyfunc->func.m_self; cyfunc->func.m_self = self; result = __Pyx_CyFunction_Call(func, new_args, kw); cyfunc->func.m_self = m_self; Py_DECREF(new_args); } else { result = __Pyx_CyFunction_Call(func, args, kw); } return result; } // Note: the 'self' from method binding is passed in in the args tuple, // whereas PyCFunctionObject's m_self is passed in as the first // argument to the C function. For extension methods we need // to pass 'self' as 'm_self' and not as the first element of the // args tuple. static PyObject * __pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw) { __pyx_FusedFunctionObject *binding_func = (__pyx_FusedFunctionObject *) func; Py_ssize_t argc = PyTuple_GET_SIZE(args); PyObject *new_args = NULL; __pyx_FusedFunctionObject *new_func = NULL; PyObject *result = NULL; PyObject *self = NULL; int is_staticmethod = binding_func->func.flags & __Pyx_CYFUNCTION_STATICMETHOD; int is_classmethod = binding_func->func.flags & __Pyx_CYFUNCTION_CLASSMETHOD; if (binding_func->self) { // Bound method call, put 'self' in the args tuple Py_ssize_t i; new_args = PyTuple_New(argc + 1); if (!new_args) return NULL; self = binding_func->self; #if !CYTHON_COMPILING_IN_CPYTHON Py_INCREF(self); #endif Py_INCREF(self); PyTuple_SET_ITEM(new_args, 0, self); for (i = 0; i < argc; i++) { #if CYTHON_COMPILING_IN_CPYTHON PyObject *item = PyTuple_GET_ITEM(args, i); Py_INCREF(item); #else PyObject *item = PySequence_ITEM(args, i); if (unlikely(!item)) goto bad; #endif PyTuple_SET_ITEM(new_args, i + 1, item); } args = new_args; } else if (binding_func->type) { // Unbound method call if (argc < 1) { PyErr_SetString(PyExc_TypeError, "Need at least one argument, 0 given."); return NULL; } #if CYTHON_COMPILING_IN_CPYTHON self = PyTuple_GET_ITEM(args, 0); #else self = PySequence_ITEM(args, 0); if (unlikely(!self)) return NULL; #endif } if (self && !is_classmethod && !is_staticmethod) { int is_instance = PyObject_IsInstance(self, binding_func->type); if (unlikely(!is_instance)) { PyErr_Format(PyExc_TypeError, "First argument should be of type %.200s, got %.200s.", ((PyTypeObject *) binding_func->type)->tp_name, self->ob_type->tp_name); goto bad; } else if (unlikely(is_instance == -1)) { goto bad; } } #if !CYTHON_COMPILING_IN_CPYTHON Py_XDECREF(self); self = NULL; #endif if (binding_func->__signatures__) { PyObject *tup = PyTuple_Pack(4, binding_func->__signatures__, args, kw == NULL ? Py_None : kw, binding_func->func.defaults_tuple); if (!tup) goto bad; new_func = (__pyx_FusedFunctionObject *) __pyx_FusedFunction_callfunction(func, tup, NULL); Py_DECREF(tup); if (!new_func) goto bad; Py_XINCREF(binding_func->func.func_classobj); Py_CLEAR(new_func->func.func_classobj); new_func->func.func_classobj = binding_func->func.func_classobj; func = (PyObject *) new_func; } result = __pyx_FusedFunction_callfunction(func, args, kw); bad: #if !CYTHON_COMPILING_IN_CPYTHON Py_XDECREF(self); #endif Py_XDECREF(new_args); Py_XDECREF((PyObject *) new_func); return result; } static PyMemberDef __pyx_FusedFunction_members[] = { {(char *) "__signatures__", T_OBJECT, offsetof(__pyx_FusedFunctionObject, __signatures__), READONLY, 0}, {0, 0, 0, 0, 0}, }; static PyMappingMethods __pyx_FusedFunction_mapping_methods = { 0, (binaryfunc) __pyx_FusedFunction_getitem, 0, }; static PyTypeObject __pyx_FusedFunctionType_type = { PyVarObject_HEAD_INIT(0, 0) "fused_cython_function", /*tp_name*/ sizeof(__pyx_FusedFunctionObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor) __pyx_FusedFunction_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #else 0, /*reserved*/ #endif 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ &__pyx_FusedFunction_mapping_methods, /*tp_as_mapping*/ 0, /*tp_hash*/ (ternaryfunc) __pyx_FusedFunction_call, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 0, /*tp_doc*/ (traverseproc) __pyx_FusedFunction_traverse, /*tp_traverse*/ (inquiry) __pyx_FusedFunction_clear,/*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ 0, /*tp_methods*/ __pyx_FusedFunction_members, /*tp_members*/ // __doc__ is None for the fused function type, but we need it to be // a descriptor for the instance's __doc__, so rebuild descriptors in our subclass __pyx_CyFunction_getsets, /*tp_getset*/ &__pyx_CyFunctionType_type, /*tp_base*/ 0, /*tp_dict*/ __pyx_FusedFunction_descr_get, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ 0, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static int __pyx_FusedFunction_init(void) { __pyx_FusedFunctionType = __Pyx_FetchCommonType(&__pyx_FusedFunctionType_type); if (__pyx_FusedFunctionType == NULL) { return -1; } return 0; } //////////////////// ClassMethod.proto //////////////////// #include "descrobject.h" static PyObject* __Pyx_Method_ClassMethod(PyObject *method); /*proto*/ //////////////////// ClassMethod //////////////////// static PyObject* __Pyx_Method_ClassMethod(PyObject *method) { #if CYTHON_COMPILING_IN_PYPY if (PyObject_TypeCheck(method, &PyWrapperDescr_Type)) { // cdef classes return PyClassMethod_New(method); } #else // It appears that PyMethodDescr_Type is not anywhere exposed in the Python/C API static PyTypeObject *methoddescr_type = NULL; if (methoddescr_type == NULL) { PyObject *meth = PyObject_GetAttrString((PyObject*)&PyList_Type, "append"); if (!meth) return NULL; methoddescr_type = Py_TYPE(meth); Py_DECREF(meth); } if (PyObject_TypeCheck(method, methoddescr_type)) { // cdef classes PyMethodDescrObject *descr = (PyMethodDescrObject *)method; #if PY_VERSION_HEX < 0x03020000 PyTypeObject *d_type = descr->d_type; #else PyTypeObject *d_type = descr->d_common.d_type; #endif return PyDescr_NewClassMethod(d_type, descr->d_method); } #endif else if (PyMethod_Check(method)) { // python classes return PyClassMethod_New(PyMethod_GET_FUNCTION(method)); } else if (PyCFunction_Check(method)) { return PyClassMethod_New(method); } #ifdef __Pyx_CyFunction_USED else if (PyObject_TypeCheck(method, __pyx_CyFunctionType)) { return PyClassMethod_New(method); } #endif PyErr_SetString(PyExc_TypeError, "Class-level classmethod() can only be called on " "a method_descriptor or instance method."); return NULL; } Cython-0.23.4/Cython/Utility/CppSupport.cpp0000644000175600017570000000317712606202452021746 0ustar jenkinsjenkins00000000000000/////////////// CppExceptionConversion.proto /////////////// #ifndef __Pyx_CppExn2PyErr #include #include #include #include static void __Pyx_CppExn2PyErr() { // Catch a handful of different errors here and turn them into the // equivalent Python errors. try { if (PyErr_Occurred()) ; // let the latest Python exn pass through and ignore the current one else throw; } catch (const std::bad_alloc& exn) { PyErr_SetString(PyExc_MemoryError, exn.what()); } catch (const std::bad_cast& exn) { PyErr_SetString(PyExc_TypeError, exn.what()); } catch (const std::domain_error& exn) { PyErr_SetString(PyExc_ValueError, exn.what()); } catch (const std::invalid_argument& exn) { PyErr_SetString(PyExc_ValueError, exn.what()); } catch (const std::ios_base::failure& exn) { // Unfortunately, in standard C++ we have no way of distinguishing EOF // from other errors here; be careful with the exception mask PyErr_SetString(PyExc_IOError, exn.what()); } catch (const std::out_of_range& exn) { // Change out_of_range to IndexError PyErr_SetString(PyExc_IndexError, exn.what()); } catch (const std::overflow_error& exn) { PyErr_SetString(PyExc_OverflowError, exn.what()); } catch (const std::range_error& exn) { PyErr_SetString(PyExc_ArithmeticError, exn.what()); } catch (const std::underflow_error& exn) { PyErr_SetString(PyExc_ArithmeticError, exn.what()); } catch (const std::exception& exn) { PyErr_SetString(PyExc_RuntimeError, exn.what()); } catch (...) { PyErr_SetString(PyExc_RuntimeError, "Unknown exception"); } } #endif Cython-0.23.4/Cython/Utility/CppConvert.pyx0000644000175600017570000001331712606202452021745 0ustar jenkinsjenkins00000000000000# TODO: Figure out how many of the pass-by-value copies the compiler can eliminate. #################### string.from_py #################### cdef extern from *: cdef cppclass string "{{type}}": string() string(char* c_str, size_t size) cdef char* __Pyx_PyObject_AsStringAndSize(object, Py_ssize_t*) except NULL @cname("{{cname}}") cdef string {{cname}}(object o) except *: cdef Py_ssize_t length cdef char* data = __Pyx_PyObject_AsStringAndSize(o, &length) return string(data, length) #################### string.to_py #################### #cimport cython #from libcpp.string cimport string cdef extern from *: cdef cppclass string "{{type}}": char* data() size_t size() {{for py_type in ['PyObject', 'PyUnicode', 'PyStr', 'PyBytes', 'PyByteArray']}} cdef extern from *: cdef object __Pyx_{{py_type}}_FromStringAndSize(char*, size_t) @cname("{{cname.replace("PyObject", py_type, 1)}}") cdef inline object {{cname.replace("PyObject", py_type, 1)}}(const string& s): return __Pyx_{{py_type}}_FromStringAndSize(s.data(), s.size()) {{endfor}} #################### vector.from_py #################### {{template_type_declarations}} cdef extern from *: cdef cppclass vector "std::vector" [T]: void push_back(T&) @cname("{{cname}}") cdef vector[X] {{cname}}(object o) except *: cdef vector[X] v for item in o: v.push_back(X_from_py(item)) return v #################### vector.to_py #################### {{template_type_declarations}} cdef extern from *: cdef cppclass vector "const std::vector" [T]: size_t size() T& operator[](size_t) @cname("{{cname}}") cdef object {{cname}}(vector[X]& v): return [X_to_py(v[i]) for i in range(v.size())] #################### list.from_py #################### {{template_type_declarations}} cdef extern from *: cdef cppclass cpp_list "std::list" [T]: void push_back(T&) @cname("{{cname}}") cdef cpp_list[X] {{cname}}(object o) except *: cdef cpp_list[X] l for item in o: l.push_back(X_from_py(item)) return l #################### list.to_py #################### cimport cython {{template_type_declarations}} cdef extern from *: cdef cppclass cpp_list "std::list" [T]: cppclass const_iterator: T& operator*() const_iterator operator++() bint operator!=(const_iterator) const_iterator begin() const_iterator end() @cname("{{cname}}") cdef object {{cname}}(const cpp_list[X]& v): o = [] cdef cpp_list[X].const_iterator iter = v.begin() while iter != v.end(): o.append(X_to_py(cython.operator.dereference(iter))) cython.operator.preincrement(iter) return o #################### set.from_py #################### {{template_type_declarations}} cdef extern from *: cdef cppclass set "std::{{maybe_unordered}}set" [T]: void insert(T&) @cname("{{cname}}") cdef set[X] {{cname}}(object o) except *: cdef set[X] s for item in o: s.insert(X_from_py(item)) return s #################### set.to_py #################### cimport cython {{template_type_declarations}} cdef extern from *: cdef cppclass cpp_set "std::{{maybe_unordered}}set" [T]: cppclass const_iterator: T& operator*() const_iterator operator++() bint operator!=(const_iterator) const_iterator begin() const_iterator end() @cname("{{cname}}") cdef object {{cname}}(const cpp_set[X]& s): o = set() cdef cpp_set[X].const_iterator iter = s.begin() while iter != s.end(): o.add(X_to_py(cython.operator.dereference(iter))) cython.operator.preincrement(iter) return o #################### pair.from_py #################### {{template_type_declarations}} cdef extern from *: cdef cppclass pair "std::pair" [T, U]: pair() pair(T&, U&) @cname("{{cname}}") cdef pair[X,Y] {{cname}}(object o) except *: x, y = o return pair[X,Y](X_from_py(x), Y_from_py(y)) #################### pair.to_py #################### {{template_type_declarations}} cdef extern from *: cdef cppclass pair "std::pair" [T, U]: T first U second @cname("{{cname}}") cdef object {{cname}}(const pair[X,Y]& p): return X_to_py(p.first), Y_to_py(p.second) #################### map.from_py #################### {{template_type_declarations}} cdef extern from *: cdef cppclass pair "std::pair" [T, U]: pair(T&, U&) cdef cppclass map "std::{{maybe_unordered}}map" [T, U]: void insert(pair[T, U]&) cdef cppclass vector "std::vector" [T]: pass @cname("{{cname}}") cdef map[X,Y] {{cname}}(object o) except *: cdef dict d = o cdef map[X,Y] m for key, value in d.iteritems(): m.insert(pair[X,Y](X_from_py(key), Y_from_py(value))) return m #################### map.to_py #################### # TODO: Work out const so that this can take a const # reference rather than pass by value. cimport cython {{template_type_declarations}} cdef extern from *: cdef cppclass map "std::{{maybe_unordered}}map" [T, U]: cppclass value_type: T first U second cppclass const_iterator: value_type& operator*() const_iterator operator++() bint operator!=(const_iterator) const_iterator begin() const_iterator end() @cname("{{cname}}") cdef object {{cname}}(const map[X,Y]& s): o = {} cdef const map[X,Y].value_type *key_value cdef map[X,Y].const_iterator iter = s.begin() while iter != s.end(): key_value = &cython.operator.dereference(iter) o[X_to_py(key_value.first)] = Y_to_py(key_value.second) cython.operator.preincrement(iter) return o Cython-0.23.4/Cython/Utility/Coroutine.c0000644000175600017570000017475712606202452021253 0ustar jenkinsjenkins00000000000000//////////////////// GeneratorYieldFrom.proto //////////////////// static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_CoroutineObject *gen, PyObject *source); //////////////////// GeneratorYieldFrom //////////////////// //@requires: Generator static CYTHON_INLINE PyObject* __Pyx_Generator_Yield_From(__pyx_CoroutineObject *gen, PyObject *source) { PyObject *source_gen, *retval; #ifdef __Pyx_Coroutine_USED if (__Pyx_Coroutine_CheckExact(source)) { // TODO: this should only happen for types.coroutine()ed generators, but we can't determine that here Py_INCREF(source); source_gen = source; retval = __Pyx_Generator_Next(source); } else #endif { #if CYTHON_COMPILING_IN_CPYTHON if (likely(Py_TYPE(source)->tp_iter)) { source_gen = Py_TYPE(source)->tp_iter(source); if (unlikely(!source_gen)) return NULL; if (unlikely(!PyIter_Check(source_gen))) { PyErr_Format(PyExc_TypeError, "iter() returned non-iterator of type '%.100s'", Py_TYPE(source_gen)->tp_name); Py_DECREF(source_gen); return NULL; } } else #endif source_gen = PyObject_GetIter(source); // source_gen is now the iterator, make the first next() call retval = Py_TYPE(source_gen)->tp_iternext(source_gen); } if (likely(retval)) { gen->yieldfrom = source_gen; return retval; } Py_DECREF(source_gen); return NULL; } //////////////////// CoroutineYieldFrom.proto //////////////////// static CYTHON_INLINE PyObject* __Pyx_Coroutine_Yield_From(__pyx_CoroutineObject *gen, PyObject *source); //////////////////// CoroutineYieldFrom //////////////////// //@requires: Coroutine //@requires: GetAwaitIter static CYTHON_INLINE PyObject* __Pyx_Coroutine_Yield_From(__pyx_CoroutineObject *gen, PyObject *source) { PyObject *retval; if (__Pyx_Coroutine_CheckExact(source)) { retval = __Pyx_Generator_Next(source); if (retval) { Py_INCREF(source); gen->yieldfrom = source; return retval; } } else { PyObject *source_gen = __Pyx__Coroutine_GetAwaitableIter(source); if (unlikely(!source_gen)) return NULL; // source_gen is now the iterator, make the first next() call if (__Pyx_Coroutine_CheckExact(source_gen)) { retval = __Pyx_Generator_Next(source_gen); } else { retval = Py_TYPE(source_gen)->tp_iternext(source_gen); } if (retval) { gen->yieldfrom = source_gen; return retval; } Py_DECREF(source_gen); } return NULL; } //////////////////// GetAwaitIter.proto //////////////////// static CYTHON_INLINE PyObject *__Pyx_Coroutine_GetAwaitableIter(PyObject *o); /*proto*/ static PyObject *__Pyx__Coroutine_GetAwaitableIter(PyObject *o); /*proto*/ //////////////////// GetAwaitIter //////////////////// //@requires: ObjectHandling.c::PyObjectGetAttrStr //@requires: ObjectHandling.c::PyObjectCallNoArg //@requires: ObjectHandling.c::PyObjectCallOneArg static CYTHON_INLINE PyObject *__Pyx_Coroutine_GetAwaitableIter(PyObject *o) { #ifdef __Pyx_Coroutine_USED if (__Pyx_Coroutine_CheckExact(o)) { Py_INCREF(o); return o; } #endif return __Pyx__Coroutine_GetAwaitableIter(o); } // adapted from genobject.c in Py3.5 static PyObject *__Pyx__Coroutine_GetAwaitableIter(PyObject *obj) { PyObject *res; #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 __Pyx_PyAsyncMethodsStruct* am = __Pyx_PyType_AsAsync(obj); if (likely(am && am->am_await)) { res = (*am->am_await)(obj); } else #endif #if (CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500B2) || defined(PyCoro_CheckExact) if (PyCoro_CheckExact(obj)) { Py_INCREF(obj); return obj; } else #endif #if CYTHON_COMPILING_IN_CPYTHON && defined(CO_ITERABLE_COROUTINE) if (PyGen_CheckExact(obj) && ((PyGenObject*)obj)->gi_code && ((PyCodeObject *)((PyGenObject*)obj)->gi_code)->co_flags & CO_ITERABLE_COROUTINE) { // Python generator marked with "@types.coroutine" decorator Py_INCREF(obj); return obj; } else #endif { PyObject *method = __Pyx_PyObject_GetAttrStr(obj, PYIDENT("__await__")); if (unlikely(!method)) goto slot_error; #if CYTHON_COMPILING_IN_CPYTHON if (likely(PyMethod_Check(method))) { PyObject *self = PyMethod_GET_SELF(method); if (likely(self)) { PyObject *function = PyMethod_GET_FUNCTION(method); res = __Pyx_PyObject_CallOneArg(function, self); } else res = __Pyx_PyObject_CallNoArg(method); } else #endif res = __Pyx_PyObject_CallNoArg(method); Py_DECREF(method); } if (unlikely(!res)) goto bad; if (!PyIter_Check(res)) { PyErr_Format(PyExc_TypeError, "__await__() returned non-iterator of type '%.100s'", Py_TYPE(res)->tp_name); Py_CLEAR(res); } else { int is_coroutine = 0; #ifdef __Pyx_Coroutine_USED is_coroutine |= __Pyx_Coroutine_CheckExact(res); #endif #if (CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030500B2) || defined(PyCoro_CheckExact) is_coroutine |= PyCoro_CheckExact(res); #endif if (unlikely(is_coroutine)) { /* __await__ must return an *iterator*, not a coroutine or another awaitable (see PEP 492) */ PyErr_SetString(PyExc_TypeError, "__await__() returned a coroutine"); Py_CLEAR(res); } } return res; slot_error: PyErr_Format(PyExc_TypeError, "object %.100s can't be used in 'await' expression", Py_TYPE(obj)->tp_name); bad: return NULL; } //////////////////// AsyncIter.proto //////////////////// static CYTHON_INLINE PyObject *__Pyx_Coroutine_GetAsyncIter(PyObject *o); /*proto*/ static CYTHON_INLINE PyObject *__Pyx_Coroutine_AsyncIterNext(PyObject *o); /*proto*/ //////////////////// AsyncIter //////////////////// //@requires: GetAwaitIter //@requires: ObjectHandling.c::PyObjectCallMethod0 static CYTHON_INLINE PyObject *__Pyx_Coroutine_GetAsyncIter(PyObject *obj) { #if PY_MAJOR_VERSION >= 3 __Pyx_PyAsyncMethodsStruct* am = __Pyx_PyType_AsAsync(obj); if (likely(am && am->am_aiter)) { return (*am->am_aiter)(obj); } #endif #if PY_VERSION_HEX < 0x030500B1 { PyObject *iter = __Pyx_PyObject_CallMethod0(obj, PYIDENT("__aiter__")); if (likely(iter)) return iter; // FIXME: for the sake of a nicely conforming exception message, assume any AttributeError meant '__aiter__' if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return NULL; } #else // avoid 'unused function' warning if (0) (void) __Pyx_PyObject_CallMethod0(obj, PYIDENT("__aiter__")); #endif PyErr_Format(PyExc_TypeError, "'async for' requires an object with __aiter__ method, got %.100s", Py_TYPE(obj)->tp_name); return NULL; } static CYTHON_INLINE PyObject *__Pyx_Coroutine_AsyncIterNext(PyObject *obj) { #if PY_MAJOR_VERSION >= 3 __Pyx_PyAsyncMethodsStruct* am = __Pyx_PyType_AsAsync(obj); if (likely(am && am->am_anext)) { return (*am->am_anext)(obj); } #endif #if PY_VERSION_HEX < 0x030500B1 { PyObject *value = __Pyx_PyObject_CallMethod0(obj, PYIDENT("__anext__")); if (likely(value)) return value; } // FIXME: for the sake of a nicely conforming exception message, assume any AttributeError meant '__anext__' if (PyErr_ExceptionMatches(PyExc_AttributeError)) #endif PyErr_Format(PyExc_TypeError, "'async for' requires an object with __anext__ method, got %.100s", Py_TYPE(obj)->tp_name); return NULL; } //////////////////// pep479.proto //////////////////// static void __Pyx_Generator_Replace_StopIteration(void); /*proto*/ //////////////////// pep479 //////////////////// //@requires: Exceptions.c::GetException static void __Pyx_Generator_Replace_StopIteration(void) { PyObject *exc, *val, *tb; // Chain exceptions by moving StopIteration to exc_info before creating the RuntimeError. // In Py2.x, no chaining happens, but the exception still stays visible in exc_info. __Pyx_GetException(&exc, &val, &tb); Py_XDECREF(exc); Py_XDECREF(val); Py_XDECREF(tb); PyErr_SetString(PyExc_RuntimeError, "generator raised StopIteration"); } //////////////////// CoroutineBase.proto //////////////////// typedef PyObject *(*__pyx_coroutine_body_t)(PyObject *, PyObject *); typedef struct { PyObject_HEAD __pyx_coroutine_body_t body; PyObject *closure; PyObject *exc_type; PyObject *exc_value; PyObject *exc_traceback; PyObject *gi_weakreflist; PyObject *classobj; PyObject *yieldfrom; PyObject *gi_name; PyObject *gi_qualname; int resume_label; // using T_BOOL for property below requires char value char is_running; } __pyx_CoroutineObject; static __pyx_CoroutineObject *__Pyx__Coroutine_New(PyTypeObject *type, __pyx_coroutine_body_t body, PyObject *closure, PyObject *name, PyObject *qualname); /*proto*/ static int __Pyx_Coroutine_clear(PyObject *self); /*proto*/ #if 1 || PY_VERSION_HEX < 0x030300B0 static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue); /*proto*/ #else #define __Pyx_PyGen_FetchStopIterationValue(pvalue) PyGen_FetchStopIterationValue(pvalue) #endif //////////////////// Coroutine.proto //////////////////// #define __Pyx_Coroutine_USED static PyTypeObject *__pyx_CoroutineType = 0; static PyTypeObject *__pyx_CoroutineAwaitType = 0; #define __Pyx_Coroutine_CheckExact(obj) (Py_TYPE(obj) == __pyx_CoroutineType) #define __Pyx_Coroutine_New(body, closure, name, qualname) \ __Pyx__Coroutine_New(__pyx_CoroutineType, body, closure, name, qualname) static int __pyx_Coroutine_init(void); /*proto*/ static PyObject *__Pyx__Coroutine_await(PyObject *coroutine); /*proto*/ //////////////////// Generator.proto //////////////////// #define __Pyx_Generator_USED static PyTypeObject *__pyx_GeneratorType = 0; #define __Pyx_Generator_CheckExact(obj) (Py_TYPE(obj) == __pyx_GeneratorType) #define __Pyx_Generator_New(body, closure, name, qualname) \ __Pyx__Coroutine_New(__pyx_GeneratorType, body, closure, name, qualname) static PyObject *__Pyx_Generator_Next(PyObject *self); static int __pyx_Generator_init(void); /*proto*/ //////////////////// CoroutineBase //////////////////// //@requires: Exceptions.c::PyErrFetchRestore //@requires: Exceptions.c::SwapException //@requires: Exceptions.c::RaiseException //@requires: ObjectHandling.c::PyObjectCallMethod1 //@requires: ObjectHandling.c::PyObjectGetAttrStr //@requires: CommonTypes.c::FetchCommonType #include #include static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value); static PyObject *__Pyx_Coroutine_Close(PyObject *self); static PyObject *__Pyx_Coroutine_Throw(PyObject *gen, PyObject *args); #define __Pyx_Coroutine_Undelegate(gen) Py_CLEAR((gen)->yieldfrom) // If StopIteration exception is set, fetches its 'value' // attribute if any, otherwise sets pvalue to None. // // Returns 0 if no exception or StopIteration is set. // If any other exception is set, returns -1 and leaves // pvalue unchanged. #if 1 || PY_VERSION_HEX < 0x030300B0 static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) { PyObject *et, *ev, *tb; PyObject *value = NULL; __Pyx_ErrFetch(&et, &ev, &tb); if (!et) { Py_XDECREF(tb); Py_XDECREF(ev); Py_INCREF(Py_None); *pvalue = Py_None; return 0; } // most common case: plain StopIteration without or with separate argument if (likely(et == PyExc_StopIteration)) { #if PY_VERSION_HEX >= 0x030300A0 if (ev && Py_TYPE(ev) == (PyTypeObject*)PyExc_StopIteration) { value = ((PyStopIterationObject *)ev)->value; Py_INCREF(value); Py_DECREF(ev); Py_XDECREF(tb); Py_DECREF(et); *pvalue = value; return 0; } #endif if (!ev || !PyObject_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration)) { // PyErr_SetObject() and friends put the value directly into ev if (!ev) { Py_INCREF(Py_None); ev = Py_None; } else if (PyTuple_Check(ev)) { // however, if it's a tuple, it is interpreted as separate constructor arguments (surprise!) if (PyTuple_GET_SIZE(ev) >= 1) { PyObject *value; #if CYTHON_COMPILING_IN_CPYTHON value = PySequence_ITEM(ev, 0); #else value = PyTuple_GET_ITEM(ev, 0); Py_INCREF(value); #endif Py_DECREF(ev); ev = value; } else { Py_INCREF(Py_None); Py_DECREF(ev); ev = Py_None; } } Py_XDECREF(tb); Py_DECREF(et); *pvalue = ev; return 0; } } else if (!PyErr_GivenExceptionMatches(et, PyExc_StopIteration)) { __Pyx_ErrRestore(et, ev, tb); return -1; } // otherwise: normalise and check what that gives us PyErr_NormalizeException(&et, &ev, &tb); if (unlikely(!PyObject_TypeCheck(ev, (PyTypeObject*)PyExc_StopIteration))) { // looks like normalisation failed - raise the new exception __Pyx_ErrRestore(et, ev, tb); return -1; } Py_XDECREF(tb); Py_DECREF(et); #if PY_VERSION_HEX >= 0x030300A0 value = ((PyStopIterationObject *)ev)->value; Py_INCREF(value); Py_DECREF(ev); #else { PyObject* args = __Pyx_PyObject_GetAttrStr(ev, PYIDENT("args")); Py_DECREF(ev); if (likely(args)) { value = PySequence_GetItem(args, 0); Py_DECREF(args); } if (unlikely(!value)) { __Pyx_ErrRestore(NULL, NULL, NULL); Py_INCREF(Py_None); value = Py_None; } } #endif *pvalue = value; return 0; } #endif static CYTHON_INLINE void __Pyx_Coroutine_ExceptionClear(__pyx_CoroutineObject *self) { PyObject *exc_type = self->exc_type; PyObject *exc_value = self->exc_value; PyObject *exc_traceback = self->exc_traceback; self->exc_type = NULL; self->exc_value = NULL; self->exc_traceback = NULL; Py_XDECREF(exc_type); Py_XDECREF(exc_value); Py_XDECREF(exc_traceback); } static CYTHON_INLINE int __Pyx_Coroutine_CheckRunning(__pyx_CoroutineObject *gen) { if (unlikely(gen->is_running)) { PyErr_SetString(PyExc_ValueError, "generator already executing"); return 1; } return 0; } static CYTHON_INLINE PyObject *__Pyx_Coroutine_SendEx(__pyx_CoroutineObject *self, PyObject *value) { PyObject *retval; assert(!self->is_running); if (unlikely(self->resume_label == 0)) { if (unlikely(value && value != Py_None)) { PyErr_SetString(PyExc_TypeError, "can't send non-None value to a " "just-started generator"); return NULL; } } if (unlikely(self->resume_label == -1)) { PyErr_SetNone(PyExc_StopIteration); return NULL; } if (value) { #if CYTHON_COMPILING_IN_PYPY // FIXME: what to do in PyPy? #else // Generators always return to their most recent caller, not // necessarily their creator. if (self->exc_traceback) { PyThreadState *tstate = PyThreadState_GET(); PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback; PyFrameObject *f = tb->tb_frame; Py_XINCREF(tstate->frame); assert(f->f_back == NULL); f->f_back = tstate->frame; } #endif __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value, &self->exc_traceback); } else { __Pyx_Coroutine_ExceptionClear(self); } self->is_running = 1; retval = self->body((PyObject *) self, value); self->is_running = 0; if (retval) { __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value, &self->exc_traceback); #if CYTHON_COMPILING_IN_PYPY // FIXME: what to do in PyPy? #else // Don't keep the reference to f_back any longer than necessary. It // may keep a chain of frames alive or it could create a reference // cycle. if (self->exc_traceback) { PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback; PyFrameObject *f = tb->tb_frame; Py_CLEAR(f->f_back); } #endif } else { __Pyx_Coroutine_ExceptionClear(self); } return retval; } static CYTHON_INLINE PyObject *__Pyx_Coroutine_MethodReturn(PyObject *retval) { if (unlikely(!retval && !PyErr_Occurred())) { // method call must not terminate with NULL without setting an exception PyErr_SetNone(PyExc_StopIteration); } return retval; } static CYTHON_INLINE PyObject *__Pyx_Coroutine_FinishDelegation(__pyx_CoroutineObject *gen) { PyObject *ret; PyObject *val = NULL; __Pyx_Coroutine_Undelegate(gen); __Pyx_PyGen_FetchStopIterationValue(&val); // val == NULL on failure => pass on exception ret = __Pyx_Coroutine_SendEx(gen, val); Py_XDECREF(val); return ret; } static PyObject *__Pyx_Coroutine_Send(PyObject *self, PyObject *value) { PyObject *retval; __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self; PyObject *yf = gen->yieldfrom; if (unlikely(__Pyx_Coroutine_CheckRunning(gen))) return NULL; if (yf) { PyObject *ret; // FIXME: does this really need an INCREF() ? //Py_INCREF(yf); gen->is_running = 1; #ifdef __Pyx_Generator_USED if (__Pyx_Generator_CheckExact(yf)) { ret = __Pyx_Coroutine_Send(yf, value); } else #endif #ifdef __Pyx_Coroutine_USED if (__Pyx_Coroutine_CheckExact(yf)) { ret = __Pyx_Coroutine_Send(yf, value); } else #endif { if (value == Py_None) // FIXME - is this the right thing to do? ret = PyIter_Next(yf); else ret = __Pyx_PyObject_CallMethod1(yf, PYIDENT("send"), value); } gen->is_running = 0; //Py_DECREF(yf); if (likely(ret)) { return ret; } retval = __Pyx_Coroutine_FinishDelegation(gen); } else { retval = __Pyx_Coroutine_SendEx(gen, value); } return __Pyx_Coroutine_MethodReturn(retval); } // This helper function is used by gen_close and gen_throw to // close a subiterator being delegated to by yield-from. static int __Pyx_Coroutine_CloseIter(__pyx_CoroutineObject *gen, PyObject *yf) { PyObject *retval = NULL; int err = 0; #ifdef __Pyx_Generator_USED if (__Pyx_Generator_CheckExact(yf)) { retval = __Pyx_Coroutine_Close(yf); if (!retval) return -1; } else #endif #ifdef __Pyx_Coroutine_USED if (__Pyx_Coroutine_CheckExact(yf)) { retval = __Pyx_Coroutine_Close(yf); if (!retval) return -1; } else #endif { PyObject *meth; gen->is_running = 1; meth = __Pyx_PyObject_GetAttrStr(yf, PYIDENT("close")); if (unlikely(!meth)) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_WriteUnraisable(yf); } PyErr_Clear(); } else { retval = PyObject_CallFunction(meth, NULL); Py_DECREF(meth); if (!retval) err = -1; } gen->is_running = 0; } Py_XDECREF(retval); return err; } static PyObject *__Pyx_Generator_Next(PyObject *self) { __pyx_CoroutineObject *gen = (__pyx_CoroutineObject*) self; PyObject *yf = gen->yieldfrom; if (unlikely(__Pyx_Coroutine_CheckRunning(gen))) return NULL; if (yf) { PyObject *ret; // FIXME: does this really need an INCREF() ? //Py_INCREF(yf); // YieldFrom code ensures that yf is an iterator gen->is_running = 1; ret = Py_TYPE(yf)->tp_iternext(yf); gen->is_running = 0; //Py_DECREF(yf); if (likely(ret)) { return ret; } return __Pyx_Coroutine_FinishDelegation(gen); } return __Pyx_Coroutine_SendEx(gen, Py_None); } static PyObject *__Pyx_Coroutine_Close(PyObject *self) { __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; PyObject *retval, *raised_exception; PyObject *yf = gen->yieldfrom; int err = 0; if (unlikely(__Pyx_Coroutine_CheckRunning(gen))) return NULL; if (yf) { Py_INCREF(yf); err = __Pyx_Coroutine_CloseIter(gen, yf); __Pyx_Coroutine_Undelegate(gen); Py_DECREF(yf); } if (err == 0) PyErr_SetNone(PyExc_GeneratorExit); retval = __Pyx_Coroutine_SendEx(gen, NULL); if (retval) { Py_DECREF(retval); PyErr_SetString(PyExc_RuntimeError, "generator ignored GeneratorExit"); return NULL; } raised_exception = PyErr_Occurred(); if (!raised_exception || raised_exception == PyExc_StopIteration || raised_exception == PyExc_GeneratorExit || PyErr_GivenExceptionMatches(raised_exception, PyExc_GeneratorExit) || PyErr_GivenExceptionMatches(raised_exception, PyExc_StopIteration)) { // ignore these errors if (raised_exception) PyErr_Clear(); Py_INCREF(Py_None); return Py_None; } return NULL; } static PyObject *__Pyx_Coroutine_Throw(PyObject *self, PyObject *args) { __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; PyObject *typ; PyObject *tb = NULL; PyObject *val = NULL; PyObject *yf = gen->yieldfrom; if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb)) return NULL; if (unlikely(__Pyx_Coroutine_CheckRunning(gen))) return NULL; if (yf) { PyObject *ret; Py_INCREF(yf); if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) { int err = __Pyx_Coroutine_CloseIter(gen, yf); Py_DECREF(yf); __Pyx_Coroutine_Undelegate(gen); if (err < 0) return __Pyx_Coroutine_MethodReturn(__Pyx_Coroutine_SendEx(gen, NULL)); goto throw_here; } gen->is_running = 1; #ifdef __Pyx_Generator_USED if (__Pyx_Generator_CheckExact(yf)) { ret = __Pyx_Coroutine_Throw(yf, args); } else #endif #ifdef __Pyx_Coroutine_USED if (__Pyx_Coroutine_CheckExact(yf)) { ret = __Pyx_Coroutine_Throw(yf, args); } else #endif { PyObject *meth = __Pyx_PyObject_GetAttrStr(yf, PYIDENT("throw")); if (unlikely(!meth)) { Py_DECREF(yf); if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { gen->is_running = 0; return NULL; } PyErr_Clear(); __Pyx_Coroutine_Undelegate(gen); gen->is_running = 0; goto throw_here; } ret = PyObject_CallObject(meth, args); Py_DECREF(meth); } gen->is_running = 0; Py_DECREF(yf); if (!ret) { ret = __Pyx_Coroutine_FinishDelegation(gen); } return __Pyx_Coroutine_MethodReturn(ret); } throw_here: __Pyx_Raise(typ, val, tb, NULL); return __Pyx_Coroutine_MethodReturn(__Pyx_Coroutine_SendEx(gen, NULL)); } static int __Pyx_Coroutine_traverse(PyObject *self, visitproc visit, void *arg) { __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; Py_VISIT(gen->closure); Py_VISIT(gen->classobj); Py_VISIT(gen->yieldfrom); Py_VISIT(gen->exc_type); Py_VISIT(gen->exc_value); Py_VISIT(gen->exc_traceback); return 0; } static int __Pyx_Coroutine_clear(PyObject *self) { __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; Py_CLEAR(gen->closure); Py_CLEAR(gen->classobj); Py_CLEAR(gen->yieldfrom); Py_CLEAR(gen->exc_type); Py_CLEAR(gen->exc_value); Py_CLEAR(gen->exc_traceback); Py_CLEAR(gen->gi_name); Py_CLEAR(gen->gi_qualname); return 0; } static void __Pyx_Coroutine_dealloc(PyObject *self) { __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; PyObject_GC_UnTrack(gen); if (gen->gi_weakreflist != NULL) PyObject_ClearWeakRefs(self); if (gen->resume_label > 0) { // Generator is paused, so we need to close PyObject_GC_Track(self); #if PY_VERSION_HEX >= 0x030400a1 if (PyObject_CallFinalizerFromDealloc(self)) #else Py_TYPE(gen)->tp_del(self); if (self->ob_refcnt > 0) #endif { // resurrected. :( return; } PyObject_GC_UnTrack(self); } __Pyx_Coroutine_clear(self); PyObject_GC_Del(gen); } static void __Pyx_Coroutine_del(PyObject *self) { PyObject *res; PyObject *error_type, *error_value, *error_traceback; __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; if (gen->resume_label <= 0) return ; #if PY_VERSION_HEX < 0x030400a1 // Temporarily resurrect the object. assert(self->ob_refcnt == 0); self->ob_refcnt = 1; #endif // Save the current exception, if any. __Pyx_ErrFetch(&error_type, &error_value, &error_traceback); res = __Pyx_Coroutine_Close(self); if (res == NULL) PyErr_WriteUnraisable(self); else Py_DECREF(res); // Restore the saved exception. __Pyx_ErrRestore(error_type, error_value, error_traceback); #if PY_VERSION_HEX < 0x030400a1 // Undo the temporary resurrection; can't use DECREF here, it would // cause a recursive call. assert(self->ob_refcnt > 0); if (--self->ob_refcnt == 0) { // this is the normal path out return; } // close() resurrected it! Make it look like the original Py_DECREF // never happened. { Py_ssize_t refcnt = self->ob_refcnt; _Py_NewReference(self); self->ob_refcnt = refcnt; } #if CYTHON_COMPILING_IN_CPYTHON assert(PyType_IS_GC(self->ob_type) && _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED); // If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so // we need to undo that. _Py_DEC_REFTOTAL; #endif // If Py_TRACE_REFS, _Py_NewReference re-added self to the object // chain, so no more to do there. // If COUNT_ALLOCS, the original decref bumped tp_frees, and // _Py_NewReference bumped tp_allocs: both of those need to be // undone. #ifdef COUNT_ALLOCS --Py_TYPE(self)->tp_frees; --Py_TYPE(self)->tp_allocs; #endif #endif } static PyObject * __Pyx_Coroutine_get_name(__pyx_CoroutineObject *self) { Py_INCREF(self->gi_name); return self->gi_name; } static int __Pyx_Coroutine_set_name(__pyx_CoroutineObject *self, PyObject *value) { PyObject *tmp; #if PY_MAJOR_VERSION >= 3 if (unlikely(value == NULL || !PyUnicode_Check(value))) { #else if (unlikely(value == NULL || !PyString_Check(value))) { #endif PyErr_SetString(PyExc_TypeError, "__name__ must be set to a string object"); return -1; } tmp = self->gi_name; Py_INCREF(value); self->gi_name = value; Py_XDECREF(tmp); return 0; } static PyObject * __Pyx_Coroutine_get_qualname(__pyx_CoroutineObject *self) { Py_INCREF(self->gi_qualname); return self->gi_qualname; } static int __Pyx_Coroutine_set_qualname(__pyx_CoroutineObject *self, PyObject *value) { PyObject *tmp; #if PY_MAJOR_VERSION >= 3 if (unlikely(value == NULL || !PyUnicode_Check(value))) { #else if (unlikely(value == NULL || !PyString_Check(value))) { #endif PyErr_SetString(PyExc_TypeError, "__qualname__ must be set to a string object"); return -1; } tmp = self->gi_qualname; Py_INCREF(value); self->gi_qualname = value; Py_XDECREF(tmp); return 0; } static __pyx_CoroutineObject *__Pyx__Coroutine_New(PyTypeObject* type, __pyx_coroutine_body_t body, PyObject *closure, PyObject *name, PyObject *qualname) { __pyx_CoroutineObject *gen = PyObject_GC_New(__pyx_CoroutineObject, type); if (gen == NULL) return NULL; gen->body = body; gen->closure = closure; Py_XINCREF(closure); gen->is_running = 0; gen->resume_label = 0; gen->classobj = NULL; gen->yieldfrom = NULL; gen->exc_type = NULL; gen->exc_value = NULL; gen->exc_traceback = NULL; gen->gi_weakreflist = NULL; Py_XINCREF(qualname); gen->gi_qualname = qualname; Py_XINCREF(name); gen->gi_name = name; PyObject_GC_Track(gen); return gen; } //////////////////// Coroutine //////////////////// //@requires: CoroutineBase //@requires: PatchGeneratorABC typedef struct { PyObject_HEAD PyObject *coroutine; } __pyx_CoroutineAwaitObject; static void __Pyx_CoroutineAwait_dealloc(PyObject *self) { #if CYTHON_COMPILING_IN_CPYTHON _PyObject_GC_UNTRACK(self); #else PyObject_GC_UnTrack(self); #endif Py_CLEAR(((__pyx_CoroutineAwaitObject*)self)->coroutine); PyObject_GC_Del(self); } static int __Pyx_CoroutineAwait_traverse(__pyx_CoroutineAwaitObject *self, visitproc visit, void *arg) { Py_VISIT(self->coroutine); return 0; } static int __Pyx_CoroutineAwait_clear(__pyx_CoroutineAwaitObject *self) { Py_CLEAR(self->coroutine); return 0; } static PyObject *__Pyx_CoroutineAwait_Next(__pyx_CoroutineAwaitObject *self) { return __Pyx_Generator_Next(self->coroutine); } static PyObject *__Pyx_CoroutineAwait_Send(__pyx_CoroutineAwaitObject *self, PyObject *value) { return __Pyx_Coroutine_Send(self->coroutine, value); } static PyObject *__Pyx_CoroutineAwait_Throw(__pyx_CoroutineAwaitObject *self, PyObject *args) { return __Pyx_Coroutine_Throw(self->coroutine, args); } static PyObject *__Pyx_CoroutineAwait_Close(__pyx_CoroutineAwaitObject *self) { return __Pyx_Coroutine_Close(self->coroutine); } static PyObject *__Pyx_CoroutineAwait_self(PyObject *self) { Py_INCREF(self); return self; } #if CYTHON_COMPILING_IN_CPYTHON static PyObject *__Pyx_CoroutineAwait_no_new(CYTHON_UNUSED PyTypeObject *type, CYTHON_UNUSED PyObject *args, CYTHON_UNUSED PyObject *kwargs) { PyErr_SetString(PyExc_TypeError, "cannot instantiate type, use 'await coroutine' instead"); return NULL; } #endif static PyMethodDef __pyx_CoroutineAwait_methods[] = { {"send", (PyCFunction) __Pyx_CoroutineAwait_Send, METH_O, (char*) PyDoc_STR("send(arg) -> send 'arg' into coroutine,\nreturn next yielded value or raise StopIteration.")}, {"throw", (PyCFunction) __Pyx_CoroutineAwait_Throw, METH_VARARGS, (char*) PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in coroutine,\nreturn next yielded value or raise StopIteration.")}, {"close", (PyCFunction) __Pyx_CoroutineAwait_Close, METH_NOARGS, (char*) PyDoc_STR("close() -> raise GeneratorExit inside coroutine.")}, {0, 0, 0, 0} }; static PyTypeObject __pyx_CoroutineAwaitType_type = { PyVarObject_HEAD_INIT(0, 0) "coroutine_wrapper", /*tp_name*/ sizeof(__pyx_CoroutineAwaitObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor) __Pyx_CoroutineAwait_dealloc,/*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_as_async resp. tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ PyDoc_STR("A wrapper object implementing __await__ for coroutines."), /*tp_doc*/ (traverseproc) __Pyx_CoroutineAwait_traverse, /*tp_traverse*/ (inquiry) __Pyx_CoroutineAwait_clear, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ __Pyx_CoroutineAwait_self, /*tp_iter*/ (iternextfunc) __Pyx_CoroutineAwait_Next, /*tp_iternext*/ __pyx_CoroutineAwait_methods, /*tp_methods*/ 0 , /*tp_members*/ 0 , /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ #if CYTHON_COMPILING_IN_CPYTHON __Pyx_CoroutineAwait_no_new, /*tp_new*/ #else 0, /*tp_new*/ #endif 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; static CYTHON_INLINE PyObject *__Pyx__Coroutine_await(PyObject *coroutine) { #if CYTHON_COMPILING_IN_CPYTHON __pyx_CoroutineAwaitObject *await = PyObject_GC_New(__pyx_CoroutineAwaitObject, __pyx_CoroutineAwaitType); #else __pyx_CoroutineAwaitObject *await = (__pyx_CoroutineAwaitObject*) __pyx_CoroutineAwaitType->tp_new(__pyx_CoroutineAwaitType, __pyx_empty_tuple, NULL); #endif if (unlikely(!await)) return NULL; Py_INCREF(coroutine); await->coroutine = coroutine; #if CYTHON_COMPILING_IN_CPYTHON _PyObject_GC_TRACK(await); #endif return (PyObject*)await; } static PyObject *__Pyx_Coroutine_await(PyObject *coroutine) { if (unlikely(!coroutine || !__Pyx_Coroutine_CheckExact(coroutine))) { PyErr_SetString(PyExc_TypeError, "invalid input, expected coroutine"); return NULL; } return __Pyx__Coroutine_await(coroutine); } static void __Pyx_Coroutine_check_and_dealloc(PyObject *self) { __pyx_CoroutineObject *gen = (__pyx_CoroutineObject *) self; if (gen->resume_label == 0 && !PyErr_Occurred()) { // untrack dead object as we are executing Python code (which might trigger GC) PyObject_GC_UnTrack(self); #if PY_VERSION_HEX >= 0x03030000 || defined(PyErr_WarnFormat) PyErr_WarnFormat(PyExc_RuntimeWarning, 1, "coroutine '%.50S' was never awaited", gen->gi_qualname); #else PyObject *msg; char *cmsg; #if CYTHON_COMPILING_IN_PYPY msg = NULL; cmsg = (char*) "coroutine was never awaited"; #else char *cname; PyObject *qualname; #if PY_MAJOR_VERSION >= 3 qualname = PyUnicode_AsUTF8String(gen->gi_qualname); if (likely(qualname)) { cname = PyBytes_AS_STRING(qualname); } else { PyErr_Clear(); cname = (char*) "?"; } msg = PyBytes_FromFormat( #else qualname = gen->gi_qualname; cname = PyString_AS_STRING(qualname); msg = PyString_FromFormat( #endif "coroutine '%.50s' was never awaited", cname); #if PY_MAJOR_VERSION >= 3 Py_XDECREF(qualname); #endif if (unlikely(!msg)) { PyErr_Clear(); cmsg = (char*) "coroutine was never awaited"; } else { #if PY_MAJOR_VERSION >= 3 cmsg = PyBytes_AS_STRING(msg); #else cmsg = PyString_AS_STRING(msg); #endif } #endif if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, cmsg, 1) < 0)) PyErr_WriteUnraisable(self); Py_XDECREF(msg); #endif PyObject_GC_Track(self); } __Pyx_Coroutine_dealloc(self); } #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && PY_VERSION_HEX < 0x030500B1 static PyObject *__Pyx_Coroutine_compare(PyObject *obj, PyObject *other, int op) { PyObject* result; switch (op) { case Py_EQ: result = (other == obj) ? Py_True : Py_False; break; case Py_NE: result = (other != obj) ? Py_True : Py_False; break; default: result = Py_NotImplemented; } Py_INCREF(result); return result; } #endif static PyMethodDef __pyx_Coroutine_methods[] = { {"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O, (char*) PyDoc_STR("send(arg) -> send 'arg' into coroutine,\nreturn next iterated value or raise StopIteration.")}, {"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS, (char*) PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in coroutine,\nreturn next iterated value or raise StopIteration.")}, {"close", (PyCFunction) __Pyx_Coroutine_Close, METH_NOARGS, (char*) PyDoc_STR("close() -> raise GeneratorExit inside coroutine.")}, #if PY_VERSION_HEX < 0x030500B1 {"__await__", (PyCFunction) __Pyx_Coroutine_await, METH_NOARGS, (char*) PyDoc_STR("__await__() -> return an iterator to be used in await expression.")}, #endif {0, 0, 0, 0} }; static PyMemberDef __pyx_Coroutine_memberlist[] = { {(char *) "cr_running", T_BOOL, offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL}, {(char*) "cr_await", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY, (char*) PyDoc_STR("object being awaited, or None")}, {0, 0, 0, 0, 0} }; static PyGetSetDef __pyx_Coroutine_getsets[] = { {(char *) "__name__", (getter)__Pyx_Coroutine_get_name, (setter)__Pyx_Coroutine_set_name, (char*) PyDoc_STR("name of the coroutine"), 0}, {(char *) "__qualname__", (getter)__Pyx_Coroutine_get_qualname, (setter)__Pyx_Coroutine_set_qualname, (char*) PyDoc_STR("qualified name of the coroutine"), 0}, {0, 0, 0, 0, 0} }; #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 static __Pyx_PyAsyncMethodsStruct __pyx_Coroutine_as_async = { __Pyx_Coroutine_await, /*am_await*/ 0, /*am_aiter*/ 0, /*am_anext*/ }; #endif static PyTypeObject __pyx_CoroutineType_type = { PyVarObject_HEAD_INIT(0, 0) "coroutine", /*tp_name*/ sizeof(__pyx_CoroutineObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor) __Pyx_Coroutine_check_and_dealloc,/*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 &__pyx_Coroutine_as_async, /*tp_as_async (tp_reserved)*/ #else 0, /*tp_reserved*/ #endif 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ 0, /*tp_doc*/ (traverseproc) __Pyx_Coroutine_traverse, /*tp_traverse*/ 0, /*tp_clear*/ #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 && PY_VERSION_HEX < 0x030500B1 // in order to (mis-)use tp_reserved above, we must also implement tp_richcompare __Pyx_Coroutine_compare, /*tp_richcompare*/ #else 0, /*tp_richcompare*/ #endif offsetof(__pyx_CoroutineObject, gi_weakreflist), /*tp_weaklistoffset*/ // no tp_iter() as iterator is only available through __await__() 0, /*tp_iter*/ 0, /*tp_iternext*/ __pyx_Coroutine_methods, /*tp_methods*/ __pyx_Coroutine_memberlist, /*tp_members*/ __pyx_Coroutine_getsets, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ 0, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_del*/ #else __Pyx_Coroutine_del, /*tp_del*/ #endif 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 __Pyx_Coroutine_del, /*tp_finalize*/ #endif }; static int __pyx_Coroutine_init(void) { // on Windows, C-API functions can't be used in slots statically __pyx_CoroutineType_type.tp_getattro = PyObject_GenericGetAttr; __pyx_CoroutineType = __Pyx_FetchCommonType(&__pyx_CoroutineType_type); if (unlikely(!__pyx_CoroutineType)) return -1; __pyx_CoroutineAwaitType = __Pyx_FetchCommonType(&__pyx_CoroutineAwaitType_type); if (unlikely(!__pyx_CoroutineAwaitType)) return -1; return 0; } //////////////////// Generator //////////////////// //@requires: CoroutineBase //@requires: PatchGeneratorABC static PyMethodDef __pyx_Generator_methods[] = { {"send", (PyCFunction) __Pyx_Coroutine_Send, METH_O, (char*) PyDoc_STR("send(arg) -> send 'arg' into generator,\nreturn next yielded value or raise StopIteration.")}, {"throw", (PyCFunction) __Pyx_Coroutine_Throw, METH_VARARGS, (char*) PyDoc_STR("throw(typ[,val[,tb]]) -> raise exception in generator,\nreturn next yielded value or raise StopIteration.")}, {"close", (PyCFunction) __Pyx_Coroutine_Close, METH_NOARGS, (char*) PyDoc_STR("close() -> raise GeneratorExit inside generator.")}, {0, 0, 0, 0} }; static PyMemberDef __pyx_Generator_memberlist[] = { {(char *) "gi_running", T_BOOL, offsetof(__pyx_CoroutineObject, is_running), READONLY, NULL}, {(char*) "gi_yieldfrom", T_OBJECT, offsetof(__pyx_CoroutineObject, yieldfrom), READONLY, (char*) PyDoc_STR("object being iterated by 'yield from', or None")}, {0, 0, 0, 0, 0} }; static PyGetSetDef __pyx_Generator_getsets[] = { {(char *) "__name__", (getter)__Pyx_Coroutine_get_name, (setter)__Pyx_Coroutine_set_name, (char*) PyDoc_STR("name of the generator"), 0}, {(char *) "__qualname__", (getter)__Pyx_Coroutine_get_qualname, (setter)__Pyx_Coroutine_set_qualname, (char*) PyDoc_STR("qualified name of the generator"), 0}, {0, 0, 0, 0, 0} }; static PyTypeObject __pyx_GeneratorType_type = { PyVarObject_HEAD_INIT(0, 0) "generator", /*tp_name*/ sizeof(__pyx_CoroutineObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor) __Pyx_Coroutine_dealloc,/*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare / tp_as_async*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ 0, /*tp_doc*/ (traverseproc) __Pyx_Coroutine_traverse, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ offsetof(__pyx_CoroutineObject, gi_weakreflist), /*tp_weaklistoffset*/ 0, /*tp_iter*/ (iternextfunc) __Pyx_Generator_Next, /*tp_iternext*/ __pyx_Generator_methods, /*tp_methods*/ __pyx_Generator_memberlist, /*tp_members*/ __pyx_Generator_getsets, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ 0, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_del*/ #else __Pyx_Coroutine_del, /*tp_del*/ #endif 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 __Pyx_Coroutine_del, /*tp_finalize*/ #endif }; static int __pyx_Generator_init(void) { // on Windows, C-API functions can't be used in slots statically __pyx_GeneratorType_type.tp_getattro = PyObject_GenericGetAttr; __pyx_GeneratorType_type.tp_iter = PyObject_SelfIter; __pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type); if (unlikely(!__pyx_GeneratorType)) { return -1; } return 0; } /////////////// ReturnWithStopIteration.proto /////////////// #define __Pyx_ReturnWithStopIteration(value) \ if (value == Py_None) PyErr_SetNone(PyExc_StopIteration); else __Pyx__ReturnWithStopIteration(value) static void __Pyx__ReturnWithStopIteration(PyObject* value); /*proto*/ /////////////// ReturnWithStopIteration /////////////// //@requires: Exceptions.c::PyErrFetchRestore //@substitute: naming // 1) Instantiating an exception just to pass back a value is costly. // 2) CPython 3.3 <= x < 3.5b1 crash in yield-from when the StopIteration is not instantiated. // 3) Passing a tuple as value into PyErr_SetObject() passes its items on as arguments. // 4) If there is currently an exception being handled, we need to chain it. static void __Pyx__ReturnWithStopIteration(PyObject* value) { PyObject *exc, *args; #if CYTHON_COMPILING_IN_CPYTHON if ((PY_VERSION_HEX >= 0x03030000 && PY_VERSION_HEX < 0x030500B1) || PyTuple_Check(value)) { args = PyTuple_New(1); if (unlikely(!args)) return; Py_INCREF(value); PyTuple_SET_ITEM(args, 0, value); exc = PyType_Type.tp_call(PyExc_StopIteration, args, NULL); Py_DECREF(args); if (!exc) return; } else { // it's safe to avoid instantiating the exception Py_INCREF(value); exc = value; } if (!PyThreadState_GET()->exc_type) { // no chaining needed => avoid the overhead in PyErr_SetObject() Py_INCREF(PyExc_StopIteration); __Pyx_ErrRestore(PyExc_StopIteration, exc, NULL); return; } #else args = PyTuple_Pack(1, value); if (unlikely(!args)) return; exc = PyObject_Call(PyExc_StopIteration, args, NULL); Py_DECREF(args); if (unlikely(!exc)) return; #endif PyErr_SetObject(PyExc_StopIteration, exc); Py_DECREF(exc); } //////////////////// PatchModuleWithCoroutine.proto //////////////////// static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code); /*proto*/ //////////////////// PatchModuleWithCoroutine //////////////////// //@substitute: naming static PyObject* __Pyx_Coroutine_patch_module(PyObject* module, const char* py_code) { #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) int result; PyObject *globals, *result_obj; globals = PyDict_New(); if (unlikely(!globals)) goto ignore; result = PyDict_SetItemString(globals, "_cython_coroutine_type", #ifdef __Pyx_Coroutine_USED (PyObject*)__pyx_CoroutineType); #else Py_None); #endif if (unlikely(result < 0)) goto ignore; result = PyDict_SetItemString(globals, "_cython_generator_type", #ifdef __Pyx_Generator_USED (PyObject*)__pyx_GeneratorType); #else Py_None); #endif if (unlikely(result < 0)) goto ignore; if (unlikely(PyDict_SetItemString(globals, "_module", module) < 0)) goto ignore; if (unlikely(PyDict_SetItemString(globals, "__builtins__", $builtins_cname) < 0)) goto ignore; result_obj = PyRun_String(py_code, Py_file_input, globals, globals); if (unlikely(!result_obj)) goto ignore; Py_DECREF(result_obj); Py_DECREF(globals); return module; ignore: Py_XDECREF(globals); PyErr_WriteUnraisable(module); if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, "Cython module failed to patch module with custom type", 1) < 0)) { Py_DECREF(module); module = NULL; } #else // avoid "unused" warning py_code++; #endif return module; } //////////////////// PatchGeneratorABC.proto //////////////////// // register with Generator/Coroutine ABCs in 'collections.abc' // see https://bugs.python.org/issue24018 static int __Pyx_patch_abc(void); /*proto*/ //////////////////// PatchGeneratorABC //////////////////// //@requires: PatchModuleWithCoroutine #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) static PyObject* __Pyx_patch_abc_module(PyObject *module); /*proto*/ static PyObject* __Pyx_patch_abc_module(PyObject *module) { module = __Pyx_Coroutine_patch_module( module, CSTRING("""\ if _cython_generator_type is not None: try: Generator = _module.Generator except AttributeError: pass else: Generator.register(_cython_generator_type) if _cython_coroutine_type is not None: try: Coroutine = _module.Coroutine except AttributeError: pass else: Coroutine.register(_cython_coroutine_type) """) ); return module; } #endif static int __Pyx_patch_abc(void) { #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) static int abc_patched = 0; if (!abc_patched) { PyObject *module; module = PyImport_ImportModule((PY_VERSION_HEX >= 0x03030000) ? "collections.abc" : "collections"); if (!module) { PyErr_WriteUnraisable(NULL); if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, ((PY_VERSION_HEX >= 0x03030000) ? "Cython module failed to register with collections.abc module" : "Cython module failed to register with collections module"), 1) < 0)) { return -1; } } else { module = __Pyx_patch_abc_module(module); abc_patched = 1; if (unlikely(!module)) return -1; Py_DECREF(module); } // also register with "backports_abc" module if available, just in case module = PyImport_ImportModule("backports_abc"); if (module) { module = __Pyx_patch_abc_module(module); Py_XDECREF(module); } if (!module) { PyErr_Clear(); } } #else // avoid "unused" warning for __Pyx_Coroutine_patch_module() if (0) __Pyx_Coroutine_patch_module(NULL, NULL); #endif return 0; } //////////////////// PatchAsyncIO.proto //////////////////// // run after importing "asyncio" to patch Cython generator support into it static PyObject* __Pyx_patch_asyncio(PyObject* module); /*proto*/ //////////////////// PatchAsyncIO //////////////////// //@requires: ImportExport.c::Import //@requires: PatchModuleWithCoroutine //@requires: PatchInspect static PyObject* __Pyx_patch_asyncio(PyObject* module) { #if PY_VERSION_HEX < 0x030500B2 && \ (defined(__Pyx_Coroutine_USED) || defined(__Pyx_Generator_USED)) && \ (!defined(CYTHON_PATCH_ASYNCIO) || CYTHON_PATCH_ASYNCIO) PyObject *patch_module = NULL; static int asyncio_patched = 0; if (unlikely((!asyncio_patched) && module)) { PyObject *package; package = __Pyx_Import(PYIDENT("asyncio.coroutines"), NULL, 0); if (package) { patch_module = __Pyx_Coroutine_patch_module( PyObject_GetAttrString(package, "coroutines"), CSTRING("""\ try: coro_types = _module._COROUTINE_TYPES except AttributeError: pass else: if _cython_coroutine_type is not None and _cython_coroutine_type not in coro_types: coro_types = tuple(coro_types) + (_cython_coroutine_type,) if _cython_generator_type is not None and _cython_generator_type not in coro_types: coro_types = tuple(coro_types) + (_cython_generator_type,) _module._COROUTINE_TYPES = coro_types """) ); } else { PyErr_Clear(); #if PY_VERSION_HEX < 0x03040200 // Py3.4.1 used to have asyncio.tasks instead of asyncio.coroutines package = __Pyx_Import(PYIDENT("asyncio.tasks"), NULL, 0); if (unlikely(!package)) goto asyncio_done; patch_module = __Pyx_Coroutine_patch_module( PyObject_GetAttrString(package, "tasks"), CSTRING("""\ if hasattr(_module, 'iscoroutine'): old_types = getattr(_module.iscoroutine, '_cython_coroutine_types', None) if old_types is None or not isinstance(old_types, set): old_types = set() def cy_wrap(orig_func, type=type, cython_coroutine_types=old_types): def cy_iscoroutine(obj): return type(obj) in cython_coroutine_types or orig_func(obj) cy_iscoroutine._cython_coroutine_types = cython_coroutine_types return cy_iscoroutine _module.iscoroutine = cy_wrap(_module.iscoroutine) if _cython_coroutine_type is not None: old_types.add(_cython_coroutine_type) if _cython_generator_type is not None: old_types.add(_cython_generator_type) """) ); #endif // Py < 0x03040200 } Py_DECREF(package); if (unlikely(!patch_module)) goto ignore; #if PY_VERSION_HEX < 0x03040200 asyncio_done: PyErr_Clear(); #endif asyncio_patched = 1; #ifdef __Pyx_Generator_USED // now patch inspect.isgenerator() by looking up the imported module in the patched asyncio module { PyObject *inspect_module; if (patch_module) { inspect_module = PyObject_GetAttr(patch_module, PYIDENT("inspect")); Py_DECREF(patch_module); } else { inspect_module = __Pyx_Import(PYIDENT("inspect"), NULL, 0); } if (unlikely(!inspect_module)) goto ignore; inspect_module = __Pyx_patch_inspect(inspect_module); if (unlikely(!inspect_module)) { Py_DECREF(module); module = NULL; } Py_XDECREF(inspect_module); } #else // avoid "unused" warning for __Pyx_patch_inspect() if (0) return __Pyx_patch_inspect(module); #endif } return module; ignore: PyErr_WriteUnraisable(module); if (unlikely(PyErr_WarnEx(PyExc_RuntimeWarning, "Cython module failed to patch asyncio package with custom generator type", 1) < 0)) { Py_DECREF(module); module = NULL; } #else // avoid "unused" warning for __Pyx_Coroutine_patch_module() if (0) return __Pyx_patch_inspect(__Pyx_Coroutine_patch_module(module, NULL)); #endif return module; } //////////////////// PatchInspect.proto //////////////////// // run after importing "inspect" to patch Cython generator support into it static PyObject* __Pyx_patch_inspect(PyObject* module); /*proto*/ //////////////////// PatchInspect //////////////////// //@requires: PatchModuleWithCoroutine static PyObject* __Pyx_patch_inspect(PyObject* module) { #if defined(__Pyx_Generator_USED) && (!defined(CYTHON_PATCH_INSPECT) || CYTHON_PATCH_INSPECT) static int inspect_patched = 0; if (unlikely((!inspect_patched) && module)) { module = __Pyx_Coroutine_patch_module( module, CSTRING("""\ old_types = getattr(_module.isgenerator, '_cython_generator_types', None) if old_types is None or not isinstance(old_types, set): old_types = set() def cy_wrap(orig_func, type=type, cython_generator_types=old_types): def cy_isgenerator(obj): return type(obj) in cython_generator_types or orig_func(obj) cy_isgenerator._cython_generator_types = cython_generator_types return cy_isgenerator _module.isgenerator = cy_wrap(_module.isgenerator) old_types.add(_cython_generator_type) """) ); inspect_patched = 1; } #else // avoid "unused" warning for __Pyx_Coroutine_patch_module() if (0) return __Pyx_Coroutine_patch_module(module, NULL); #endif return module; } //////////////////// StopAsyncIteration.proto //////////////////// #define __Pyx_StopAsyncIteration_USED static PyObject *__Pyx_PyExc_StopAsyncIteration; static int __pyx_StopAsyncIteration_init(void); /*proto*/ //////////////////// StopAsyncIteration //////////////////// #if PY_VERSION_HEX < 0x030500B1 static PyTypeObject __Pyx__PyExc_StopAsyncIteration_type = { PyVarObject_HEAD_INIT(0, 0) "StopAsyncIteration", /*tp_name*/ sizeof(PyBaseExceptionObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ 0, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ #if PY_MAJOR_VERSION < 3 0, /*tp_compare*/ #else 0, /*reserved*/ #endif 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ PyDoc_STR("Signal the end from iterator.__anext__()."), /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ 0, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ 0, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ 0, /*tp_bases*/ 0, /*tp_mro*/ 0, /*tp_cache*/ 0, /*tp_subclasses*/ 0, /*tp_weaklist*/ 0, /*tp_del*/ 0, /*tp_version_tag*/ #if PY_VERSION_HEX >= 0x030400a1 0, /*tp_finalize*/ #endif }; #endif static int __pyx_StopAsyncIteration_init(void) { #if PY_VERSION_HEX >= 0x030500B1 __Pyx_PyExc_StopAsyncIteration = PyExc_StopAsyncIteration; #else PyObject *builtins = PyEval_GetBuiltins(); if (likely(builtins)) { PyObject *exc = PyMapping_GetItemString(builtins, (char*) "StopAsyncIteration"); if (exc) { __Pyx_PyExc_StopAsyncIteration = exc; return 0; } } PyErr_Clear(); __Pyx__PyExc_StopAsyncIteration_type.tp_traverse = ((PyTypeObject*)PyExc_BaseException)->tp_traverse; __Pyx__PyExc_StopAsyncIteration_type.tp_clear = ((PyTypeObject*)PyExc_BaseException)->tp_clear; __Pyx__PyExc_StopAsyncIteration_type.tp_dictoffset = ((PyTypeObject*)PyExc_BaseException)->tp_dictoffset; __Pyx__PyExc_StopAsyncIteration_type.tp_base = (PyTypeObject*)PyExc_Exception; __Pyx_PyExc_StopAsyncIteration = (PyObject*) __Pyx_FetchCommonType(&__Pyx__PyExc_StopAsyncIteration_type); if (unlikely(!__Pyx_PyExc_StopAsyncIteration)) return -1; if (builtins && unlikely(PyMapping_SetItemString(builtins, (char*) "StopAsyncIteration", __Pyx_PyExc_StopAsyncIteration) < 0)) return -1; #endif return 0; } Cython-0.23.4/Cython/Utility/CommonTypes.c0000644000175600017570000000277412606202452021546 0ustar jenkinsjenkins00000000000000/////////////// FetchCommonType.proto /////////////// static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type); /////////////// FetchCommonType /////////////// static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) { PyObject* fake_module; PyTypeObject* cached_type = NULL; fake_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI); if (!fake_module) return NULL; Py_INCREF(fake_module); cached_type = (PyTypeObject*) PyObject_GetAttrString(fake_module, type->tp_name); if (cached_type) { if (!PyType_Check((PyObject*)cached_type)) { PyErr_Format(PyExc_TypeError, "Shared Cython type %.200s is not a type object", type->tp_name); goto bad; } if (cached_type->tp_basicsize != type->tp_basicsize) { PyErr_Format(PyExc_TypeError, "Shared Cython type %.200s has the wrong size, try recompiling", type->tp_name); goto bad; } } else { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; PyErr_Clear(); if (PyType_Ready(type) < 0) goto bad; if (PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type) < 0) goto bad; Py_INCREF(type); cached_type = type; } done: Py_DECREF(fake_module); // NOTE: always returns owned reference, or NULL on error return cached_type; bad: Py_XDECREF(cached_type); cached_type = NULL; goto done; } Cython-0.23.4/Cython/Utility/Capsule.c0000644000175600017570000000077112606202452020660 0ustar jenkinsjenkins00000000000000//////////////// Capsule.proto //////////////// /* Todo: wrap the rest of the functionality in similar functions */ static CYTHON_INLINE PyObject *__pyx_capsule_create(void *p, const char *sig); //////////////// Capsule //////////////// static CYTHON_INLINE PyObject * __pyx_capsule_create(void *p, CYTHON_UNUSED const char *sig) { PyObject *cobj; #if PY_VERSION_HEX >= 0x02070000 cobj = PyCapsule_New(p, sig, NULL); #else cobj = PyCObject_FromVoidPtr(p, NULL); #endif return cobj; } Cython-0.23.4/Cython/Utility/CMath.c0000644000175600017570000000471612606202452020263 0ustar jenkinsjenkins00000000000000 /////////////// CDivisionWarning.proto /////////////// static int __Pyx_cdivision_warning(const char *, int); /* proto */ /////////////// CDivisionWarning /////////////// static int __Pyx_cdivision_warning(const char *filename, int lineno) { #if CYTHON_COMPILING_IN_PYPY // avoid compiler warnings filename++; lineno++; return PyErr_Warn(PyExc_RuntimeWarning, "division with oppositely signed operands, C and Python semantics differ"); #else return PyErr_WarnExplicit(PyExc_RuntimeWarning, "division with oppositely signed operands, C and Python semantics differ", filename, lineno, __Pyx_MODULE_NAME, NULL); #endif } /////////////// DivInt.proto /////////////// static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */ /////////////// DivInt /////////////// static CYTHON_INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) { %(type)s q = a / b; %(type)s r = a - q*b; q -= ((r != 0) & ((r ^ b) < 0)); return q; } /////////////// ModInt.proto /////////////// static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */ /////////////// ModInt /////////////// static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) { %(type)s r = a %% b; r += ((r != 0) & ((r ^ b) < 0)) * b; return r; } /////////////// ModFloat.proto /////////////// static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */ /////////////// ModFloat /////////////// static CYTHON_INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) { %(type)s r = fmod%(math_h_modifier)s(a, b); r += ((r != 0) & ((r < 0) ^ (b < 0))) * b; return r; } /////////////// IntPow.proto /////////////// static CYTHON_INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */ /////////////// IntPow /////////////// static CYTHON_INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) { %(type)s t = b; switch (e) { case 3: t *= b; case 2: t *= b; case 1: return t; case 0: return 1; } #if %(signed)s if (unlikely(e<0)) return 0; #endif t = 1; while (likely(e)) { t *= (b * (e&1)) | ((~e)&1); /* 1 or b */ b *= b; e >>= 1; } return t; } Cython-0.23.4/Cython/Utility/CConvert.pyx0000644000175600017570000001036212606202452021402 0ustar jenkinsjenkins00000000000000#################### FromPyStructUtility #################### cdef extern from *: ctypedef struct PyTypeObject: char* tp_name PyTypeObject *Py_TYPE(obj) bint PyMapping_Check(obj) object PyErr_Format(exc, const char *format, ...) @cname("{{funcname}}") cdef {{struct_name}} {{funcname}}(obj) except *: cdef {{struct_name}} result if not PyMapping_Check(obj): PyErr_Format(TypeError, b"Expected %.16s, got %.200s", b"a mapping", Py_TYPE(obj).tp_name) {{for member in var_entries:}} try: value = obj['{{member.name}}'] except KeyError: raise ValueError("No value specified for struct attribute '{{member.name}}'") result.{{member.cname}} = value {{endfor}} return result #################### FromPyUnionUtility #################### cdef extern from *: ctypedef struct PyTypeObject: char* tp_name PyTypeObject *Py_TYPE(obj) bint PyMapping_Check(obj) object PyErr_Format(exc, const char *format, ...) @cname("{{funcname}}") cdef {{struct_name}} {{funcname}}(obj) except *: cdef {{struct_name}} result cdef Py_ssize_t length if not PyMapping_Check(obj): PyErr_Format(TypeError, b"Expected %.16s, got %.200s", b"a mapping", Py_TYPE(obj).tp_name) last_found = None length = len(obj) if length: {{for member in var_entries:}} if '{{member.name}}' in obj: if last_found is not None: raise ValueError("More than one union attribute passed: '%s' and '%s'" % (last_found, '{{member.name}}')) last_found = '{{member.name}}' result.{{member.cname}} = obj['{{member.name}}'] length -= 1 if not length: return result {{endfor}} if last_found is None: raise ValueError("No value specified for any of the union attributes (%s)" % '{{", ".join(member.name for member in var_entries)}}') return result #################### cfunc.to_py #################### @cname("{{cname}}") cdef object {{cname}}({{return_type.ctype}} (*f)({{ ', '.join(arg.type_cname for arg in args) }}) {{except_clause}}): def wrap({{ ', '.join('{arg.ctype} {arg.name}'.format(arg=arg) for arg in args) }}): """wrap({{', '.join(('{arg.name}: {arg.type_displayname}'.format(arg=arg) if arg.type_displayname else arg.name) for arg in args)}}){{if return_type.type_displayname}} -> {{return_type.type_displayname}}{{endif}}""" {{'' if return_type.type.is_void else 'return '}}f({{ ', '.join(arg.name for arg in args) }}) return wrap #################### carray.from_py #################### cdef extern from *: object PyErr_Format(exc, const char *format, ...) @cname("{{cname}}") cdef int {{cname}}(object o, {{base_type}} *v, Py_ssize_t length) except -1: cdef Py_ssize_t i = length try: i = len(o) except (TypeError, OverflowError): pass if i == length: for i, item in enumerate(o): if i >= length: break v[i] = item else: i += 1 # convert index to length if i == length: return 0 PyErr_Format( IndexError, ("too many values found during array assignment, expected %zd" if i >= length else "not enough values found during array assignment, expected %zd, got %zd"), length, i) #################### carray.to_py #################### cdef extern from *: void Py_INCREF(object o) tuple PyTuple_New(Py_ssize_t size) list PyList_New(Py_ssize_t size) void PyTuple_SET_ITEM(object p, Py_ssize_t pos, object o) void PyList_SET_ITEM(object p, Py_ssize_t pos, object o) @cname("{{cname}}") cdef inline list {{cname}}({{base_type}} *v, Py_ssize_t length): cdef size_t i cdef object value l = PyList_New(length) for i in range(length): value = v[i] Py_INCREF(value) PyList_SET_ITEM(l, i, value) return l @cname("{{to_tuple_cname}}") cdef inline tuple {{to_tuple_cname}}({{base_type}} *v, Py_ssize_t length): cdef size_t i cdef object value t = PyTuple_New(length) for i in range(length): value = v[i] Py_INCREF(value) PyTuple_SET_ITEM(t, i, value) return t Cython-0.23.4/Cython/Utility/Builtins.c0000644000175600017570000003563012606202452021057 0ustar jenkinsjenkins00000000000000/* * Special implementations of built-in functions and methods. * * Optional optimisations for builtins are in Optimize.c. * * General object operations and protocols are in ObjectHandling.c. */ //////////////////// Globals.proto //////////////////// static PyObject* __Pyx_Globals(void); /*proto*/ //////////////////// Globals //////////////////// //@substitute: naming //@requires: ObjectHandling.c::GetAttr // This is a stub implementation until we have something more complete. // Currently, we only handle the most common case of a read-only dict // of Python names. Supporting cdef names in the module and write // access requires a rewrite as a dedicated class. static PyObject* __Pyx_Globals(void) { Py_ssize_t i; PyObject *names; PyObject *globals = $moddict_cname; Py_INCREF(globals); names = PyObject_Dir($module_cname); if (!names) goto bad; for (i = PyList_GET_SIZE(names)-1; i >= 0; i--) { #if CYTHON_COMPILING_IN_PYPY PyObject* name = PySequence_ITEM(names, i); if (!name) goto bad; #else PyObject* name = PyList_GET_ITEM(names, i); #endif if (!PyDict_Contains(globals, name)) { PyObject* value = __Pyx_GetAttr($module_cname, name); if (!value) { #if CYTHON_COMPILING_IN_PYPY Py_DECREF(name); #endif goto bad; } if (PyDict_SetItem(globals, name, value) < 0) { #if CYTHON_COMPILING_IN_PYPY Py_DECREF(name); #endif Py_DECREF(value); goto bad; } } #if CYTHON_COMPILING_IN_PYPY Py_DECREF(name); #endif } Py_DECREF(names); return globals; bad: Py_XDECREF(names); Py_XDECREF(globals); return NULL; } //////////////////// PyExecGlobals.proto //////////////////// static PyObject* __Pyx_PyExecGlobals(PyObject*); //////////////////// PyExecGlobals //////////////////// //@requires: Globals //@requires: PyExec static PyObject* __Pyx_PyExecGlobals(PyObject* code) { PyObject* result; PyObject* globals = __Pyx_Globals(); if (unlikely(!globals)) return NULL; result = __Pyx_PyExec2(code, globals); Py_DECREF(globals); return result; } //////////////////// PyExec.proto //////////////////// static PyObject* __Pyx_PyExec3(PyObject*, PyObject*, PyObject*); static CYTHON_INLINE PyObject* __Pyx_PyExec2(PyObject*, PyObject*); //////////////////// PyExec //////////////////// //@substitute: naming static CYTHON_INLINE PyObject* __Pyx_PyExec2(PyObject* o, PyObject* globals) { return __Pyx_PyExec3(o, globals, NULL); } static PyObject* __Pyx_PyExec3(PyObject* o, PyObject* globals, PyObject* locals) { PyObject* result; PyObject* s = 0; char *code = 0; if (!globals || globals == Py_None) { globals = $moddict_cname; } else if (!PyDict_Check(globals)) { PyErr_Format(PyExc_TypeError, "exec() arg 2 must be a dict, not %.200s", Py_TYPE(globals)->tp_name); goto bad; } if (!locals || locals == Py_None) { locals = globals; } if (PyDict_GetItem(globals, PYIDENT("__builtins__")) == NULL) { if (PyDict_SetItem(globals, PYIDENT("__builtins__"), PyEval_GetBuiltins()) < 0) goto bad; } if (PyCode_Check(o)) { if (PyCode_GetNumFree((PyCodeObject *)o) > 0) { PyErr_SetString(PyExc_TypeError, "code object passed to exec() may not contain free variables"); goto bad; } #if CYTHON_COMPILING_IN_PYPY || PY_VERSION_HEX < 0x030200B1 result = PyEval_EvalCode((PyCodeObject *)o, globals, locals); #else result = PyEval_EvalCode(o, globals, locals); #endif } else { PyCompilerFlags cf; cf.cf_flags = 0; if (PyUnicode_Check(o)) { cf.cf_flags = PyCF_SOURCE_IS_UTF8; s = PyUnicode_AsUTF8String(o); if (!s) goto bad; o = s; #if PY_MAJOR_VERSION >= 3 } else if (!PyBytes_Check(o)) { #else } else if (!PyString_Check(o)) { #endif PyErr_Format(PyExc_TypeError, "exec: arg 1 must be string, bytes or code object, got %.200s", Py_TYPE(o)->tp_name); goto bad; } #if PY_MAJOR_VERSION >= 3 code = PyBytes_AS_STRING(o); #else code = PyString_AS_STRING(o); #endif if (PyEval_MergeCompilerFlags(&cf)) { result = PyRun_StringFlags(code, Py_file_input, globals, locals, &cf); } else { result = PyRun_String(code, Py_file_input, globals, locals); } Py_XDECREF(s); } return result; bad: Py_XDECREF(s); return 0; } //////////////////// GetAttr3.proto //////////////////// static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); /*proto*/ //////////////////// GetAttr3 //////////////////// //@requires: ObjectHandling.c::GetAttr static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) { PyObject *r = __Pyx_GetAttr(o, n); if (unlikely(!r)) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad; PyErr_Clear(); r = d; Py_INCREF(d); } return r; bad: return NULL; } //////////////////// Intern.proto //////////////////// static PyObject* __Pyx_Intern(PyObject* s); /* proto */ //////////////////// Intern //////////////////// static PyObject* __Pyx_Intern(PyObject* s) { if (!(likely(PyString_CheckExact(s)))) { PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(s)->tp_name); return 0; } Py_INCREF(s); #if PY_MAJOR_VERSION >= 3 PyUnicode_InternInPlace(&s); #else PyString_InternInPlace(&s); #endif return s; } //////////////////// abs_int.proto //////////////////// static CYTHON_INLINE unsigned int __Pyx_abs_int(int x) { if (unlikely(x == -INT_MAX-1)) return ((unsigned int)INT_MAX) + 1U; return (unsigned int) abs(x); } //////////////////// abs_long.proto //////////////////// static CYTHON_INLINE unsigned long __Pyx_abs_long(long x) { if (unlikely(x == -LONG_MAX-1)) return ((unsigned long)LONG_MAX) + 1U; return (unsigned long) labs(x); } //////////////////// abs_longlong.proto //////////////////// static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_abs_longlong(PY_LONG_LONG x) { if (unlikely(x == -PY_LLONG_MAX-1)) return ((unsigned PY_LONG_LONG)PY_LLONG_MAX) + 1U; #if defined (__cplusplus) && __cplusplus >= 201103L return (unsigned PY_LONG_LONG) std::abs(x); #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L return (unsigned PY_LONG_LONG) llabs(x); #elif defined (_MSC_VER) && defined (_M_X64) // abs() is defined for long, but 64-bits type on MSVC is long long. // Use MS-specific _abs64 instead. return (unsigned PY_LONG_LONG) _abs64(x); #elif defined (__GNUC__) // gcc or clang on 64 bit windows. return (unsigned PY_LONG_LONG) __builtin_llabs(x); #else if (sizeof(PY_LONG_LONG) <= sizeof(Py_ssize_t)) return __Pyx_sst_abs(x); return (x<0) ? (unsigned PY_LONG_LONG)-x : (unsigned PY_LONG_LONG)x; #endif } //////////////////// pow2.proto //////////////////// #define __Pyx_PyNumber_Power2(a, b) PyNumber_Power(a, b, Py_None) //////////////////// object_ord.proto //////////////////// //@requires: TypeConversion.c::UnicodeAsUCS4 #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyObject_Ord(c) \ (likely(PyUnicode_Check(c)) ? (long)__Pyx_PyUnicode_AsPy_UCS4(c) : __Pyx__PyObject_Ord(c)) #else #define __Pyx_PyObject_Ord(c) __Pyx__PyObject_Ord(c) #endif static long __Pyx__PyObject_Ord(PyObject* c); /*proto*/ //////////////////// object_ord //////////////////// static long __Pyx__PyObject_Ord(PyObject* c) { Py_ssize_t size; if (PyBytes_Check(c)) { size = PyBytes_GET_SIZE(c); if (likely(size == 1)) { return (unsigned char) PyBytes_AS_STRING(c)[0]; } #if PY_MAJOR_VERSION < 3 } else if (PyUnicode_Check(c)) { return (long)__Pyx_PyUnicode_AsPy_UCS4(c); #endif #if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) } else if (PyByteArray_Check(c)) { size = PyByteArray_GET_SIZE(c); if (likely(size == 1)) { return (unsigned char) PyByteArray_AS_STRING(c)[0]; } #endif } else { // FIXME: support character buffers - but CPython doesn't support them either PyErr_Format(PyExc_TypeError, "ord() expected string of length 1, but %.200s found", c->ob_type->tp_name); return (long)(Py_UCS4)-1; } PyErr_Format(PyExc_TypeError, "ord() expected a character, but string of length %zd found", size); return (long)(Py_UCS4)-1; } //////////////////// py_dict_keys.proto //////////////////// static CYTHON_INLINE PyObject* __Pyx_PyDict_Keys(PyObject* d); /*proto*/ //////////////////// py_dict_keys //////////////////// static CYTHON_INLINE PyObject* __Pyx_PyDict_Keys(PyObject* d) { if (PY_MAJOR_VERSION >= 3) return CALL_UNBOUND_METHOD(PyDict_Type, "keys", d); else return PyDict_Keys(d); } //////////////////// py_dict_values.proto //////////////////// static CYTHON_INLINE PyObject* __Pyx_PyDict_Values(PyObject* d); /*proto*/ //////////////////// py_dict_values //////////////////// static CYTHON_INLINE PyObject* __Pyx_PyDict_Values(PyObject* d) { if (PY_MAJOR_VERSION >= 3) return CALL_UNBOUND_METHOD(PyDict_Type, "values", d); else return PyDict_Values(d); } //////////////////// py_dict_items.proto //////////////////// static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d); /*proto*/ //////////////////// py_dict_items //////////////////// static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d) { if (PY_MAJOR_VERSION >= 3) return CALL_UNBOUND_METHOD(PyDict_Type, "items", d); else return PyDict_Items(d); } //////////////////// py_dict_iterkeys.proto //////////////////// static CYTHON_INLINE PyObject* __Pyx_PyDict_IterKeys(PyObject* d); /*proto*/ //////////////////// py_dict_iterkeys //////////////////// static CYTHON_INLINE PyObject* __Pyx_PyDict_IterKeys(PyObject* d) { if (PY_MAJOR_VERSION >= 3) return CALL_UNBOUND_METHOD(PyDict_Type, "keys", d); else return CALL_UNBOUND_METHOD(PyDict_Type, "iterkeys", d); } //////////////////// py_dict_itervalues.proto //////////////////// static CYTHON_INLINE PyObject* __Pyx_PyDict_IterValues(PyObject* d); /*proto*/ //////////////////// py_dict_itervalues //////////////////// static CYTHON_INLINE PyObject* __Pyx_PyDict_IterValues(PyObject* d) { if (PY_MAJOR_VERSION >= 3) return CALL_UNBOUND_METHOD(PyDict_Type, "values", d); else return CALL_UNBOUND_METHOD(PyDict_Type, "itervalues", d); } //////////////////// py_dict_iteritems.proto //////////////////// static CYTHON_INLINE PyObject* __Pyx_PyDict_IterItems(PyObject* d); /*proto*/ //////////////////// py_dict_iteritems //////////////////// static CYTHON_INLINE PyObject* __Pyx_PyDict_IterItems(PyObject* d) { if (PY_MAJOR_VERSION >= 3) return CALL_UNBOUND_METHOD(PyDict_Type, "items", d); else return CALL_UNBOUND_METHOD(PyDict_Type, "iteritems", d); } //////////////////// py_dict_viewkeys.proto //////////////////// #if PY_VERSION_HEX < 0x02070000 #error This module uses dict views, which require Python 2.7 or later #endif static CYTHON_INLINE PyObject* __Pyx_PyDict_ViewKeys(PyObject* d); /*proto*/ //////////////////// py_dict_viewkeys //////////////////// static CYTHON_INLINE PyObject* __Pyx_PyDict_ViewKeys(PyObject* d) { if (PY_MAJOR_VERSION >= 3) return CALL_UNBOUND_METHOD(PyDict_Type, "keys", d); else return CALL_UNBOUND_METHOD(PyDict_Type, "viewkeys", d); } //////////////////// py_dict_viewvalues.proto //////////////////// #if PY_VERSION_HEX < 0x02070000 #error This module uses dict views, which require Python 2.7 or later #endif static CYTHON_INLINE PyObject* __Pyx_PyDict_ViewValues(PyObject* d); /*proto*/ //////////////////// py_dict_viewvalues //////////////////// static CYTHON_INLINE PyObject* __Pyx_PyDict_ViewValues(PyObject* d) { if (PY_MAJOR_VERSION >= 3) return CALL_UNBOUND_METHOD(PyDict_Type, "values", d); else return CALL_UNBOUND_METHOD(PyDict_Type, "viewvalues", d); } //////////////////// py_dict_viewitems.proto //////////////////// #if PY_VERSION_HEX < 0x02070000 #error This module uses dict views, which require Python 2.7 or later #endif static CYTHON_INLINE PyObject* __Pyx_PyDict_ViewItems(PyObject* d); /*proto*/ //////////////////// py_dict_viewitems //////////////////// static CYTHON_INLINE PyObject* __Pyx_PyDict_ViewItems(PyObject* d) { if (PY_MAJOR_VERSION >= 3) return CALL_UNBOUND_METHOD(PyDict_Type, "items", d); else return CALL_UNBOUND_METHOD(PyDict_Type, "viewitems", d); } //////////////////// pyfrozenset_new.proto //////////////////// //@substitute: naming static CYTHON_INLINE PyObject* __Pyx_PyFrozenSet_New(PyObject* it) { if (it) { PyObject* result; #if CYTHON_COMPILING_IN_PYPY // PyPy currently lacks PyFrozenSet_CheckExact() and PyFrozenSet_New() PyObject* args; args = PyTuple_Pack(1, it); if (unlikely(!args)) return NULL; result = PyObject_Call((PyObject*)&PyFrozenSet_Type, args, NULL); Py_DECREF(args); return result; #else if (PyFrozenSet_CheckExact(it)) { Py_INCREF(it); return it; } result = PyFrozenSet_New(it); if (unlikely(!result)) return NULL; if (likely(PySet_GET_SIZE(result))) return result; // empty frozenset is a singleton // seems wasteful, but CPython does the same Py_DECREF(result); #endif } #if CYTHON_COMPILING_IN_CPYTHON return PyFrozenSet_Type.tp_new(&PyFrozenSet_Type, $empty_tuple, NULL); #else return PyObject_Call((PyObject*)&PyFrozenSet_Type, $empty_tuple, NULL); #endif } //////////////////// PySet_Update.proto //////////////////// static CYTHON_INLINE int __Pyx_PySet_Update(PyObject* set, PyObject* it); /*proto*/ //////////////////// PySet_Update //////////////////// static CYTHON_INLINE int __Pyx_PySet_Update(PyObject* set, PyObject* it) { PyObject *retval; #if CYTHON_COMPILING_IN_CPYTHON if (PyAnySet_Check(it)) { if (PySet_GET_SIZE(it) == 0) return 0; // fast and safe case: CPython will update our result set and return it retval = PySet_Type.tp_as_number->nb_inplace_or(set, it); if (likely(retval == set)) { Py_DECREF(retval); return 0; } if (unlikely(!retval)) return -1; // unusual result, fall through to set.update() call below Py_DECREF(retval); } #endif retval = CALL_UNBOUND_METHOD(PySet_Type, "update", set, it); if (unlikely(!retval)) return -1; Py_DECREF(retval); return 0; } Cython-0.23.4/Cython/Utility/Buffer.c0000644000175600017570000006754212606202452020506 0ustar jenkinsjenkins00000000000000/////////////// BufferStructDeclare.proto /////////////// /* structs for buffer access */ typedef struct { Py_ssize_t shape, strides, suboffsets; } __Pyx_Buf_DimInfo; typedef struct { size_t refcount; Py_buffer pybuffer; } __Pyx_Buffer; typedef struct { __Pyx_Buffer *rcbuffer; char *data; __Pyx_Buf_DimInfo diminfo[{{max_dims}}]; } __Pyx_LocalBuf_ND; /////////////// BufferIndexError.proto /////////////// static void __Pyx_RaiseBufferIndexError(int axis); /*proto*/ /////////////// BufferIndexError /////////////// static void __Pyx_RaiseBufferIndexError(int axis) { PyErr_Format(PyExc_IndexError, "Out of bounds on buffer access (axis %d)", axis); } /////////////// BufferIndexErrorNogil.proto /////////////// //@requires: BufferIndexError static void __Pyx_RaiseBufferIndexErrorNogil(int axis); /*proto*/ /////////////// BufferIndexErrorNogil /////////////// static void __Pyx_RaiseBufferIndexErrorNogil(int axis) { #ifdef WITH_THREAD PyGILState_STATE gilstate = PyGILState_Ensure(); #endif __Pyx_RaiseBufferIndexError(axis); #ifdef WITH_THREAD PyGILState_Release(gilstate); #endif } /////////////// BufferFallbackError.proto /////////////// static void __Pyx_RaiseBufferFallbackError(void); /*proto*/ /////////////// BufferFallbackError /////////////// static void __Pyx_RaiseBufferFallbackError(void) { PyErr_SetString(PyExc_ValueError, "Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too!"); } /////////////// BufferFormatStructs.proto /////////////// #define IS_UNSIGNED(type) (((type) -1) > 0) /* Run-time type information about structs used with buffers */ struct __Pyx_StructField_; #define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0) typedef struct { const char* name; /* for error messages only */ struct __Pyx_StructField_* fields; size_t size; /* sizeof(type) */ size_t arraysize[8]; /* length of array in each dimension */ int ndim; char typegroup; /* _R_eal, _C_omplex, Signed _I_nt, _U_nsigned int, _S_truct, _P_ointer, _O_bject, c_H_ar */ char is_unsigned; int flags; } __Pyx_TypeInfo; typedef struct __Pyx_StructField_ { __Pyx_TypeInfo* type; const char* name; size_t offset; } __Pyx_StructField; typedef struct { __Pyx_StructField* field; size_t parent_offset; } __Pyx_BufFmt_StackElem; typedef struct { __Pyx_StructField root; __Pyx_BufFmt_StackElem* head; size_t fmt_offset; size_t new_count, enc_count; size_t struct_alignment; int is_complex; char enc_type; char new_packmode; char enc_packmode; char is_valid_array; } __Pyx_BufFmt_Context; /////////////// GetAndReleaseBuffer.proto /////////////// #if PY_MAJOR_VERSION < 3 static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags); static void __Pyx_ReleaseBuffer(Py_buffer *view); #else #define __Pyx_GetBuffer PyObject_GetBuffer #define __Pyx_ReleaseBuffer PyBuffer_Release #endif /////////////// GetAndReleaseBuffer /////////////// #if PY_MAJOR_VERSION < 3 static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags); {{for type_ptr, getbuffer, releasebuffer in types}} {{if getbuffer}} if (PyObject_TypeCheck(obj, {{type_ptr}})) return {{getbuffer}}(obj, view, flags); {{endif}} {{endfor}} PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name); return -1; } static void __Pyx_ReleaseBuffer(Py_buffer *view) { PyObject *obj = view->obj; if (!obj) return; if (PyObject_CheckBuffer(obj)) { PyBuffer_Release(view); return; } {{for type_ptr, getbuffer, releasebuffer in types}} {{if releasebuffer}} if (PyObject_TypeCheck(obj, {{type_ptr}})) { {{releasebuffer}}(obj, view); return; } {{endif}} {{endfor}} Py_DECREF(obj); view->obj = NULL; } #endif /* PY_MAJOR_VERSION < 3 */ /////////////// BufferFormatCheck.proto /////////////// {{# Buffer format string checking Buffer type checking. Utility code for checking that acquired buffers match our assumptions. We only need to check ndim and the format string; the access mode/flags is checked by the exporter. See: http://docs.python.org/3/library/struct.html http://legacy.python.org/dev/peps/pep-3118/#additions-to-the-struct-string-syntax The alignment code is copied from _struct.c in Python. }} static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack); static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); /////////////// BufferFormatCheck /////////////// static CYTHON_INLINE int __Pyx_IsLittleEndian(void) { unsigned int n = 1; return *(unsigned char*)(&n) != 0; } static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, __Pyx_BufFmt_StackElem* stack, __Pyx_TypeInfo* type) { stack[0].field = &ctx->root; stack[0].parent_offset = 0; ctx->root.type = type; ctx->root.name = "buffer dtype"; ctx->root.offset = 0; ctx->head = stack; ctx->head->field = &ctx->root; ctx->fmt_offset = 0; ctx->head->parent_offset = 0; ctx->new_packmode = '@'; ctx->enc_packmode = '@'; ctx->new_count = 1; ctx->enc_count = 0; ctx->enc_type = 0; ctx->is_complex = 0; ctx->is_valid_array = 0; ctx->struct_alignment = 0; while (type->typegroup == 'S') { ++ctx->head; ctx->head->field = type->fields; ctx->head->parent_offset = 0; type = type->fields->type; } } static int __Pyx_BufFmt_ParseNumber(const char** ts) { int count; const char* t = *ts; if (*t < '0' || *t > '9') { return -1; } else { count = *t++ - '0'; while (*t >= '0' && *t < '9') { count *= 10; count += *t++ - '0'; } } *ts = t; return count; } static int __Pyx_BufFmt_ExpectNumber(const char **ts) { int number = __Pyx_BufFmt_ParseNumber(ts); if (number == -1) /* First char was not a digit */ PyErr_Format(PyExc_ValueError,\ "Does not understand character buffer dtype format string ('%c')", **ts); return number; } static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { PyErr_Format(PyExc_ValueError, "Unexpected format string character: '%c'", ch); } static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { switch (ch) { case 'c': return "'char'"; case 'b': return "'signed char'"; case 'B': return "'unsigned char'"; case 'h': return "'short'"; case 'H': return "'unsigned short'"; case 'i': return "'int'"; case 'I': return "'unsigned int'"; case 'l': return "'long'"; case 'L': return "'unsigned long'"; case 'q': return "'long long'"; case 'Q': return "'unsigned long long'"; case 'f': return (is_complex ? "'complex float'" : "'float'"); case 'd': return (is_complex ? "'complex double'" : "'double'"); case 'g': return (is_complex ? "'complex long double'" : "'long double'"); case 'T': return "a struct"; case 'O': return "Python object"; case 'P': return "a pointer"; case 's': case 'p': return "a string"; case 0: return "end"; default: return "unparseable format string"; } } static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { switch (ch) { case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; case 'h': case 'H': return 2; case 'i': case 'I': case 'l': case 'L': return 4; case 'q': case 'Q': return 8; case 'f': return (is_complex ? 8 : 4); case 'd': return (is_complex ? 16 : 8); case 'g': { PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); return 0; } case 'O': case 'P': return sizeof(void*); default: __Pyx_BufFmt_RaiseUnexpectedChar(ch); return 0; } } static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { switch (ch) { case 'c': case 'b': case 'B': case 's': case 'p': return 1; case 'h': case 'H': return sizeof(short); case 'i': case 'I': return sizeof(int); case 'l': case 'L': return sizeof(long); #ifdef HAVE_LONG_LONG case 'q': case 'Q': return sizeof(PY_LONG_LONG); #endif case 'f': return sizeof(float) * (is_complex ? 2 : 1); case 'd': return sizeof(double) * (is_complex ? 2 : 1); case 'g': return sizeof(long double) * (is_complex ? 2 : 1); case 'O': case 'P': return sizeof(void*); default: { __Pyx_BufFmt_RaiseUnexpectedChar(ch); return 0; } } } typedef struct { char c; short x; } __Pyx_st_short; typedef struct { char c; int x; } __Pyx_st_int; typedef struct { char c; long x; } __Pyx_st_long; typedef struct { char c; float x; } __Pyx_st_float; typedef struct { char c; double x; } __Pyx_st_double; typedef struct { char c; long double x; } __Pyx_st_longdouble; typedef struct { char c; void *x; } __Pyx_st_void_p; #ifdef HAVE_LONG_LONG typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong; #endif static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) { switch (ch) { case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); #ifdef HAVE_LONG_LONG case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG); #endif case 'f': return sizeof(__Pyx_st_float) - sizeof(float); case 'd': return sizeof(__Pyx_st_double) - sizeof(double); case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); default: __Pyx_BufFmt_RaiseUnexpectedChar(ch); return 0; } } /* These are for computing the padding at the end of the struct to align on the first member of the struct. This will probably the same as above, but we don't have any guarantees. */ typedef struct { short x; char c; } __Pyx_pad_short; typedef struct { int x; char c; } __Pyx_pad_int; typedef struct { long x; char c; } __Pyx_pad_long; typedef struct { float x; char c; } __Pyx_pad_float; typedef struct { double x; char c; } __Pyx_pad_double; typedef struct { long double x; char c; } __Pyx_pad_longdouble; typedef struct { void *x; char c; } __Pyx_pad_void_p; #ifdef HAVE_LONG_LONG typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong; #endif static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) { switch (ch) { case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1; case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short); case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int); case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long); #ifdef HAVE_LONG_LONG case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG); #endif case 'f': return sizeof(__Pyx_pad_float) - sizeof(float); case 'd': return sizeof(__Pyx_pad_double) - sizeof(double); case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double); case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*); default: __Pyx_BufFmt_RaiseUnexpectedChar(ch); return 0; } } static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { switch (ch) { case 'c': return 'H'; case 'b': case 'h': case 'i': case 'l': case 'q': case 's': case 'p': return 'I'; case 'B': case 'H': case 'I': case 'L': case 'Q': return 'U'; case 'f': case 'd': case 'g': return (is_complex ? 'C' : 'R'); case 'O': return 'O'; case 'P': return 'P'; default: { __Pyx_BufFmt_RaiseUnexpectedChar(ch); return 0; } } } static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { if (ctx->head == NULL || ctx->head->field == &ctx->root) { const char* expected; const char* quote; if (ctx->head == NULL) { expected = "end"; quote = ""; } else { expected = ctx->head->field->type->name; quote = "'"; } PyErr_Format(PyExc_ValueError, "Buffer dtype mismatch, expected %s%s%s but got %s", quote, expected, quote, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); } else { __Pyx_StructField* field = ctx->head->field; __Pyx_StructField* parent = (ctx->head - 1)->field; PyErr_Format(PyExc_ValueError, "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), parent->type->name, field->name); } } static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { char group; size_t size, offset, arraysize = 1; /* printf("processing... %s\n", ctx->head->field->type->name); */ if (ctx->enc_type == 0) return 0; /* Validate array size */ if (ctx->head->field->type->arraysize[0]) { int i, ndim = 0; /* handle strings ('s' and 'p') */ if (ctx->enc_type == 's' || ctx->enc_type == 'p') { ctx->is_valid_array = ctx->head->field->type->ndim == 1; ndim = 1; if (ctx->enc_count != ctx->head->field->type->arraysize[0]) { PyErr_Format(PyExc_ValueError, "Expected a dimension of size %zu, got %zu", ctx->head->field->type->arraysize[0], ctx->enc_count); return -1; } } if (!ctx->is_valid_array) { PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d", ctx->head->field->type->ndim, ndim); return -1; } for (i = 0; i < ctx->head->field->type->ndim; i++) { arraysize *= ctx->head->field->type->arraysize[i]; } ctx->is_valid_array = 0; ctx->enc_count = 1; } group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); do { __Pyx_StructField* field = ctx->head->field; __Pyx_TypeInfo* type = field->type; if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') { size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); } else { size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); } if (ctx->enc_packmode == '@') { size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); size_t align_mod_offset; if (align_at == 0) return -1; align_mod_offset = ctx->fmt_offset % align_at; if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; if (ctx->struct_alignment == 0) ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type, ctx->is_complex); } if (type->size != size || type->typegroup != group) { if (type->typegroup == 'C' && type->fields != NULL) { /* special case -- treat as struct rather than complex number */ size_t parent_offset = ctx->head->parent_offset + field->offset; ++ctx->head; ctx->head->field = type->fields; ctx->head->parent_offset = parent_offset; continue; } if ((type->typegroup == 'H' || group == 'H') && type->size == size) { /* special case -- chars don't care about sign */ } else { __Pyx_BufFmt_RaiseExpected(ctx); return -1; } } offset = ctx->head->parent_offset + field->offset; if (ctx->fmt_offset != offset) { PyErr_Format(PyExc_ValueError, "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected", (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset); return -1; } ctx->fmt_offset += size; if (arraysize) ctx->fmt_offset += (arraysize - 1) * size; --ctx->enc_count; /* Consume from buffer string */ /* Done checking, move to next field, pushing or popping struct stack if needed */ while (1) { if (field == &ctx->root) { ctx->head = NULL; if (ctx->enc_count != 0) { __Pyx_BufFmt_RaiseExpected(ctx); return -1; } break; /* breaks both loops as ctx->enc_count == 0 */ } ctx->head->field = ++field; if (field->type == NULL) { --ctx->head; field = ctx->head->field; continue; } else if (field->type->typegroup == 'S') { size_t parent_offset = ctx->head->parent_offset + field->offset; if (field->type->fields->type == NULL) continue; /* empty struct */ field = field->type->fields; ++ctx->head; ctx->head->field = field; ctx->head->parent_offset = parent_offset; break; } else { break; } } } while (ctx->enc_count); ctx->enc_type = 0; ctx->is_complex = 0; return 0; } /* Parse an array in the format string (e.g. (1,2,3)) */ static CYTHON_INLINE PyObject * __pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp) { const char *ts = *tsp; int i = 0, number; int ndim = ctx->head->field->type->ndim; ; ++ts; if (ctx->new_count != 1) { PyErr_SetString(PyExc_ValueError, "Cannot handle repeated arrays in format string"); return NULL; } /* Process the previous element */ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; /* Parse all numbers in the format string */ while (*ts && *ts != ')') { // ignore space characters (not using isspace() due to C/C++ problem on MacOS-X) switch (*ts) { case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue; default: break; /* not a 'break' in the loop */ } number = __Pyx_BufFmt_ExpectNumber(&ts); if (number == -1) return NULL; if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i]) return PyErr_Format(PyExc_ValueError, "Expected a dimension of size %zu, got %d", ctx->head->field->type->arraysize[i], number); if (*ts != ',' && *ts != ')') return PyErr_Format(PyExc_ValueError, "Expected a comma in format string, got '%c'", *ts); if (*ts == ',') ts++; i++; } if (i != ndim) return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d", ctx->head->field->type->ndim, i); if (!*ts) { PyErr_SetString(PyExc_ValueError, "Unexpected end of format string, expected ')'"); return NULL; } ctx->is_valid_array = 1; ctx->new_count = 1; *tsp = ++ts; return Py_None; } static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { int got_Z = 0; while (1) { /* puts(ts); */ switch(*ts) { case 0: if (ctx->enc_type != 0 && ctx->head == NULL) { __Pyx_BufFmt_RaiseExpected(ctx); return NULL; } if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; if (ctx->head != NULL) { __Pyx_BufFmt_RaiseExpected(ctx); return NULL; } return ts; case ' ': case '\r': case '\n': ++ts; break; case '<': if (!__Pyx_IsLittleEndian()) { PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); return NULL; } ctx->new_packmode = '='; ++ts; break; case '>': case '!': if (__Pyx_IsLittleEndian()) { PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); return NULL; } ctx->new_packmode = '='; ++ts; break; case '=': case '@': case '^': ctx->new_packmode = *ts++; break; case 'T': /* substruct */ { const char* ts_after_sub; size_t i, struct_count = ctx->new_count; size_t struct_alignment = ctx->struct_alignment; ctx->new_count = 1; ++ts; if (*ts != '{') { PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); return NULL; } if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; ctx->enc_type = 0; /* Erase processed last struct element */ ctx->enc_count = 0; ctx->struct_alignment = 0; ++ts; ts_after_sub = ts; for (i = 0; i != struct_count; ++i) { ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); if (!ts_after_sub) return NULL; } ts = ts_after_sub; if (struct_alignment) ctx->struct_alignment = struct_alignment; } break; case '}': /* end of substruct; either repeat or move on */ { size_t alignment = ctx->struct_alignment; ++ts; if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; ctx->enc_type = 0; /* Erase processed last struct element */ if (alignment && ctx->fmt_offset % alignment) { /* Pad struct on size of the first member */ ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment); } } return ts; case 'x': if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; ctx->fmt_offset += ctx->new_count; ctx->new_count = 1; ctx->enc_count = 0; ctx->enc_type = 0; ctx->enc_packmode = ctx->new_packmode; ++ts; break; case 'Z': got_Z = 1; ++ts; if (*ts != 'f' && *ts != 'd' && *ts != 'g') { __Pyx_BufFmt_RaiseUnexpectedChar('Z'); return NULL; } /* fall through */ case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': case 'l': case 'L': case 'q': case 'Q': case 'f': case 'd': case 'g': case 'O': case 'p': if (ctx->enc_type == *ts && got_Z == ctx->is_complex && ctx->enc_packmode == ctx->new_packmode) { /* Continue pooling same type */ ctx->enc_count += ctx->new_count; ctx->new_count = 1; got_Z = 0; ++ts; break; } /* fall through */ case 's': /* 's' or new type (cannot be added to current pool) */ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; ctx->enc_count = ctx->new_count; ctx->enc_packmode = ctx->new_packmode; ctx->enc_type = *ts; ctx->is_complex = got_Z; ++ts; ctx->new_count = 1; got_Z = 0; break; case ':': ++ts; while(*ts != ':') ++ts; ++ts; break; case '(': if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL; break; default: { int number = __Pyx_BufFmt_ExpectNumber(&ts); if (number == -1) return NULL; ctx->new_count = (size_t)number; } } } } static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) { buf->buf = NULL; buf->obj = NULL; buf->strides = __Pyx_zeros; buf->shape = __Pyx_zeros; buf->suboffsets = __Pyx_minusones; } static CYTHON_INLINE int __Pyx_GetBufferAndValidate( Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack) { if (obj == Py_None || obj == NULL) { __Pyx_ZeroBuffer(buf); return 0; } buf->buf = NULL; if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail; if (buf->ndim != nd) { PyErr_Format(PyExc_ValueError, "Buffer has wrong number of dimensions (expected %d, got %d)", nd, buf->ndim); goto fail; } if (!cast) { __Pyx_BufFmt_Context ctx; __Pyx_BufFmt_Init(&ctx, stack, dtype); if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; } if ((unsigned)buf->itemsize != dtype->size) { PyErr_Format(PyExc_ValueError, "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)", buf->itemsize, (buf->itemsize > 1) ? "s" : "", dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : ""); goto fail; } if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; return 0; fail:; __Pyx_ZeroBuffer(buf); return -1; } static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { if (info->buf == NULL) return; if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; __Pyx_ReleaseBuffer(info); } /////////////// TypeInfoCompare.proto /////////////// static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b); /////////////// TypeInfoCompare /////////////// /* See if two dtypes are equal */ static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b) { int i; if (!a || !b) return 0; if (a == b) return 1; if (a->size != b->size || a->typegroup != b->typegroup || a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) { if (a->typegroup == 'H' || b->typegroup == 'H') { /* Special case for chars */ return a->size == b->size; } else { return 0; } } if (a->ndim) { /* Verify multidimensional C arrays */ for (i = 0; i < a->ndim; i++) if (a->arraysize[i] != b->arraysize[i]) return 0; } if (a->typegroup == 'S') { /* Check for packed struct */ if (a->flags != b->flags) return 0; /* compare all struct fields */ if (a->fields || b->fields) { /* Check if both have fields */ if (!(a->fields && b->fields)) return 0; /* compare */ for (i = 0; a->fields[i].type && b->fields[i].type; i++) { __Pyx_StructField *field_a = a->fields + i; __Pyx_StructField *field_b = b->fields + i; if (field_a->offset != field_b->offset || !__pyx_typeinfo_cmp(field_a->type, field_b->type)) return 0; } /* If all fields are processed, we have a match */ return !a->fields[i].type && !b->fields[i].type; } } return 1; } /////////////// TypeInfoToFormat.proto /////////////// struct __pyx_typeinfo_string { char string[3]; }; static struct __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *type); /////////////// TypeInfoToFormat /////////////// {{# See also MemoryView.pyx:BufferFormatFromTypeInfo }} static struct __pyx_typeinfo_string __Pyx_TypeInfoToFormat(__Pyx_TypeInfo *type) { struct __pyx_typeinfo_string result = { {0} }; char *buf = (char *) result.string; size_t size = type->size; switch (type->typegroup) { case 'H': *buf = 'c'; break; case 'I': case 'U': if (size == 1) *buf = (type->is_unsigned) ? 'B' : 'b'; else if (size == 2) *buf = (type->is_unsigned) ? 'H' : 'h'; else if (size == 4) *buf = (type->is_unsigned) ? 'I' : 'i'; else if (size == 8) *buf = (type->is_unsigned) ? 'Q' : 'q'; break; case 'P': *buf = 'P'; break; case 'C': { __Pyx_TypeInfo complex_type = *type; complex_type.typegroup = 'R'; complex_type.size /= 2; *buf++ = 'Z'; *buf = __Pyx_TypeInfoToFormat(&complex_type).string[0]; break; } case 'R': if (size == 4) *buf = 'f'; else if (size == 8) *buf = 'd'; else *buf = 'g'; break; } return result; } Cython-0.23.4/Cython/Tests/0000755000175600017570000000000012606202455016555 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Tests/xmlrunner.py0000644000175600017570000003471712606202452021172 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- """unittest-xml-reporting is a PyUnit-based TestRunner that can export test results to XML files that can be consumed by a wide range of tools, such as build systems, IDEs and Continuous Integration servers. This module provides the XMLTestRunner class, which is heavily based on the default TextTestRunner. This makes the XMLTestRunner very simple to use. The script below, adapted from the unittest documentation, shows how to use XMLTestRunner in a very simple way. In fact, the only difference between this script and the original one is the last line: import random import unittest import xmlrunner class TestSequenceFunctions(unittest.TestCase): def setUp(self): self.seq = range(10) def test_shuffle(self): # make sure the shuffled sequence does not lose any elements random.shuffle(self.seq) self.seq.sort() self.assertEqual(self.seq, range(10)) def test_choice(self): element = random.choice(self.seq) self.assert_(element in self.seq) def test_sample(self): self.assertRaises(ValueError, random.sample, self.seq, 20) for element in random.sample(self.seq, 5): self.assert_(element in self.seq) if __name__ == '__main__': unittest.main(testRunner=xmlrunner.XMLTestRunner(output='test-reports')) """ from __future__ import absolute_import import os import sys import time from unittest import TestResult, _TextTestResult, TextTestRunner import xml.dom.minidom try: from StringIO import StringIO except ImportError: from io import StringIO # doesn't accept 'str' in Py2 class XMLDocument(xml.dom.minidom.Document): def createCDATAOrText(self, data): if ']]>' in data: return self.createTextNode(data) return self.createCDATASection(data) class _TestInfo(object): """This class is used to keep useful information about the execution of a test method. """ # Possible test outcomes (SUCCESS, FAILURE, ERROR) = range(3) def __init__(self, test_result, test_method, outcome=SUCCESS, err=None): "Create a new instance of _TestInfo." self.test_result = test_result self.test_method = test_method self.outcome = outcome self.err = err self.stdout = test_result.stdout and test_result.stdout.getvalue().strip() or '' self.stderr = test_result.stdout and test_result.stderr.getvalue().strip() or '' def get_elapsed_time(self): """Return the time that shows how long the test method took to execute. """ return self.test_result.stop_time - self.test_result.start_time def get_description(self): "Return a text representation of the test method." return self.test_result.getDescription(self.test_method) def get_error_info(self): """Return a text representation of an exception thrown by a test method. """ if not self.err: return '' return self.test_result._exc_info_to_string( self.err, self.test_method) class _XMLTestResult(_TextTestResult): """A test result class that can express test results in a XML report. Used by XMLTestRunner. """ def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1, elapsed_times=True): "Create a new instance of _XMLTestResult." _TextTestResult.__init__(self, stream, descriptions, verbosity) self.successes = [] self.callback = None self.elapsed_times = elapsed_times self.output_patched = False def _prepare_callback(self, test_info, target_list, verbose_str, short_str): """Append a _TestInfo to the given target list and sets a callback method to be called by stopTest method. """ target_list.append(test_info) def callback(): """This callback prints the test method outcome to the stream, as well as the elapsed time. """ # Ignore the elapsed times for a more reliable unit testing if not self.elapsed_times: self.start_time = self.stop_time = 0 if self.showAll: self.stream.writeln('(%.3fs) %s' % \ (test_info.get_elapsed_time(), verbose_str)) elif self.dots: self.stream.write(short_str) self.callback = callback def _patch_standard_output(self): """Replace the stdout and stderr streams with string-based streams in order to capture the tests' output. """ if not self.output_patched: (self.old_stdout, self.old_stderr) = (sys.stdout, sys.stderr) self.output_patched = True (sys.stdout, sys.stderr) = (self.stdout, self.stderr) = \ (StringIO(), StringIO()) def _restore_standard_output(self): "Restore the stdout and stderr streams." (sys.stdout, sys.stderr) = (self.old_stdout, self.old_stderr) self.output_patched = False def startTest(self, test): "Called before execute each test method." self._patch_standard_output() self.start_time = time.time() TestResult.startTest(self, test) if self.showAll: self.stream.write(' ' + self.getDescription(test)) self.stream.write(" ... ") def stopTest(self, test): "Called after execute each test method." self._restore_standard_output() _TextTestResult.stopTest(self, test) self.stop_time = time.time() if self.callback and callable(self.callback): self.callback() self.callback = None def addSuccess(self, test): "Called when a test executes successfully." self._prepare_callback(_TestInfo(self, test), self.successes, 'OK', '.') def addFailure(self, test, err): "Called when a test method fails." self._prepare_callback(_TestInfo(self, test, _TestInfo.FAILURE, err), self.failures, 'FAIL', 'F') def addError(self, test, err): "Called when a test method raises an error." self._prepare_callback(_TestInfo(self, test, _TestInfo.ERROR, err), self.errors, 'ERROR', 'E') def printErrorList(self, flavour, errors): "Write some information about the FAIL or ERROR to the stream." for test_info in errors: if isinstance(test_info, tuple): test_info, exc_info = test_info try: t = test_info.get_elapsed_time() except AttributeError: t = 0 try: descr = test_info.get_description() except AttributeError: try: descr = test_info.getDescription() except AttributeError: descr = str(test_info) try: err_info = test_info.get_error_info() except AttributeError: err_info = str(test_info) self.stream.writeln(self.separator1) self.stream.writeln('%s [%.3fs]: %s' % (flavour, t, descr)) self.stream.writeln(self.separator2) self.stream.writeln('%s' % err_info) def _get_info_by_testcase(self): """This method organizes test results by TestCase module. This information is used during the report generation, where a XML report will be generated for each TestCase. """ tests_by_testcase = {} for tests in (self.successes, self.failures, self.errors): for test_info in tests: if not isinstance(test_info, _TestInfo): print("Unexpected test result type: %r" % (test_info,)) continue testcase = type(test_info.test_method) # Ignore module name if it is '__main__' module = testcase.__module__ + '.' if module == '__main__.': module = '' testcase_name = module + testcase.__name__ if testcase_name not in tests_by_testcase: tests_by_testcase[testcase_name] = [] tests_by_testcase[testcase_name].append(test_info) return tests_by_testcase def _report_testsuite(suite_name, tests, xml_document): "Appends the testsuite section to the XML document." testsuite = xml_document.createElement('testsuite') xml_document.appendChild(testsuite) testsuite.setAttribute('name', str(suite_name)) testsuite.setAttribute('tests', str(len(tests))) testsuite.setAttribute('time', '%.3f' % sum([e.get_elapsed_time() for e in tests])) failures = len([1 for e in tests if e.outcome == _TestInfo.FAILURE]) testsuite.setAttribute('failures', str(failures)) errors = len([1 for e in tests if e.outcome == _TestInfo.ERROR]) testsuite.setAttribute('errors', str(errors)) return testsuite _report_testsuite = staticmethod(_report_testsuite) def _report_testcase(suite_name, test_result, xml_testsuite, xml_document): "Appends a testcase section to the XML document." testcase = xml_document.createElement('testcase') xml_testsuite.appendChild(testcase) testcase.setAttribute('classname', str(suite_name)) testcase.setAttribute('name', test_result.test_method.shortDescription() or getattr(test_result.test_method, '_testMethodName', str(test_result.test_method))) testcase.setAttribute('time', '%.3f' % test_result.get_elapsed_time()) if (test_result.outcome != _TestInfo.SUCCESS): elem_name = ('failure', 'error')[test_result.outcome-1] failure = xml_document.createElement(elem_name) testcase.appendChild(failure) failure.setAttribute('type', str(test_result.err[0].__name__)) failure.setAttribute('message', str(test_result.err[1])) error_info = test_result.get_error_info() failureText = xml_document.createCDATAOrText(error_info) failure.appendChild(failureText) _report_testcase = staticmethod(_report_testcase) def _report_output(test_runner, xml_testsuite, xml_document, stdout, stderr): "Appends the system-out and system-err sections to the XML document." systemout = xml_document.createElement('system-out') xml_testsuite.appendChild(systemout) systemout_text = xml_document.createCDATAOrText(stdout) systemout.appendChild(systemout_text) systemerr = xml_document.createElement('system-err') xml_testsuite.appendChild(systemerr) systemerr_text = xml_document.createCDATAOrText(stderr) systemerr.appendChild(systemerr_text) _report_output = staticmethod(_report_output) def generate_reports(self, test_runner): "Generates the XML reports to a given XMLTestRunner object." all_results = self._get_info_by_testcase() if type(test_runner.output) == str and not \ os.path.exists(test_runner.output): os.makedirs(test_runner.output) for suite, tests in all_results.items(): doc = XMLDocument() # Build the XML file testsuite = _XMLTestResult._report_testsuite(suite, tests, doc) stdout, stderr = [], [] for test in tests: _XMLTestResult._report_testcase(suite, test, testsuite, doc) if test.stdout: stdout.extend(['*****************', test.get_description(), test.stdout]) if test.stderr: stderr.extend(['*****************', test.get_description(), test.stderr]) _XMLTestResult._report_output(test_runner, testsuite, doc, '\n'.join(stdout), '\n'.join(stderr)) xml_content = doc.toprettyxml(indent='\t') if type(test_runner.output) is str: report_file = open('%s%sTEST-%s.xml' % \ (test_runner.output, os.sep, suite), 'w') try: report_file.write(xml_content) finally: report_file.close() else: # Assume that test_runner.output is a stream test_runner.output.write(xml_content) class XMLTestRunner(TextTestRunner): """A test runner class that outputs the results in JUnit like XML files. """ def __init__(self, output='.', stream=None, descriptions=True, verbose=False, elapsed_times=True): "Create a new instance of XMLTestRunner." if stream is None: stream = sys.stderr verbosity = (1, 2)[verbose] TextTestRunner.__init__(self, stream, descriptions, verbosity) self.output = output self.elapsed_times = elapsed_times def _make_result(self): """Create the TestResult object which will be used to store information about the executed tests. """ return _XMLTestResult(self.stream, self.descriptions, \ self.verbosity, self.elapsed_times) def run(self, test): "Run the given test case or test suite." # Prepare the test execution result = self._make_result() # Print a nice header self.stream.writeln() self.stream.writeln('Running tests...') self.stream.writeln(result.separator2) # Execute tests start_time = time.time() test(result) stop_time = time.time() time_taken = stop_time - start_time # Generate reports self.stream.writeln() self.stream.writeln('Generating XML reports...') result.generate_reports(self) # Print results result.printErrors() self.stream.writeln(result.separator2) run = result.testsRun self.stream.writeln("Ran %d test%s in %.3fs" % (run, run != 1 and "s" or "", time_taken)) self.stream.writeln() # Error traces if not result.wasSuccessful(): self.stream.write("FAILED (") failed, errored = (len(result.failures), len(result.errors)) if failed: self.stream.write("failures=%d" % failed) if errored: if failed: self.stream.write(", ") self.stream.write("errors=%d" % errored) self.stream.writeln(")") else: self.stream.writeln("OK") return result Cython-0.23.4/Cython/Tests/__init__.py0000644000175600017570000000001512606202452020657 0ustar jenkinsjenkins00000000000000# empty file Cython-0.23.4/Cython/Tests/TestStringIOTree.py0000644000175600017570000000363212606202452022306 0ustar jenkinsjenkins00000000000000import unittest from Cython import StringIOTree as stringtree code = """ cdef int spam # line 1 cdef ham(): a = 1 b = 2 c = 3 d = 4 def eggs(): pass cpdef bacon(): print spam print 'scotch' print 'tea?' print 'or coffee?' # line 16 """ linemap = dict(enumerate(code.splitlines())) class TestStringIOTree(unittest.TestCase): def setUp(self): self.tree = stringtree.StringIOTree() def test_markers(self): assert not self.tree.allmarkers() def test_insertion(self): self.write_lines((1, 2, 3)) line_4_to_6_insertion_point = self.tree.insertion_point() self.write_lines((7, 8)) line_9_to_13_insertion_point = self.tree.insertion_point() self.write_lines((14, 15, 16)) line_4_insertion_point = line_4_to_6_insertion_point.insertion_point() self.write_lines((5, 6), tree=line_4_to_6_insertion_point) line_9_to_12_insertion_point = ( line_9_to_13_insertion_point.insertion_point()) self.write_line(13, tree=line_9_to_13_insertion_point) self.write_line(4, tree=line_4_insertion_point) self.write_line(9, tree=line_9_to_12_insertion_point) line_10_insertion_point = line_9_to_12_insertion_point.insertion_point() self.write_line(11, tree=line_9_to_12_insertion_point) self.write_line(10, tree=line_10_insertion_point) self.write_line(12, tree=line_9_to_12_insertion_point) self.assertEqual(self.tree.allmarkers(), list(range(1, 17))) self.assertEqual(code.strip(), self.tree.getvalue().strip()) def write_lines(self, linenos, tree=None): for lineno in linenos: self.write_line(lineno, tree=tree) def write_line(self, lineno, tree=None): if tree is None: tree = self.tree tree.markers.append(lineno) tree.write(linemap[lineno] + '\n') Cython-0.23.4/Cython/Tests/TestJediTyper.py0000644000175600017570000001556412606202452021676 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- # tag: jedi from __future__ import absolute_import import sys import os.path from textwrap import dedent from contextlib import contextmanager from tempfile import NamedTemporaryFile from Cython.Compiler.ParseTreeTransforms import NormalizeTree, InterpretCompilerDirectives from Cython.Compiler import Main, Symtab, Visitor from Cython.TestUtils import TransformTest TOOLS_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'Tools')) @contextmanager def _tempfile(code): code = dedent(code) if not isinstance(code, bytes): code = code.encode('utf8') with NamedTemporaryFile(suffix='.py') as f: f.write(code) f.seek(0) yield f def _test_typing(code, inject=False): sys.path.insert(0, TOOLS_DIR) try: import jedityper finally: sys.path.remove(TOOLS_DIR) lines = [] with _tempfile(code) as f: types = jedityper.analyse(f.name) if inject: lines = jedityper.inject_types(f.name, types) return types, lines class DeclarationsFinder(Visitor.VisitorTransform): directives = None visit_Node = Visitor.VisitorTransform.recurse_to_children def visit_CompilerDirectivesNode(self, node): if not self.directives: self.directives = [] self.directives.append(node) self.visitchildren(node) return node class TestJediTyper(TransformTest): def _test(self, code): return _test_typing(code)[0] def test_typing_global_int_loop(self): code = '''\ for i in range(10): a = i + 1 ''' types = self._test(code) self.assertIn((None, (1, 0)), types) variables = types.pop((None, (1, 0))) self.assertFalse(types) self.assertEqual({'a': set(['int']), 'i': set(['int'])}, variables) def test_typing_function_int_loop(self): code = '''\ def func(x): for i in range(x): a = i + 1 return a ''' types = self._test(code) self.assertIn(('func', (1, 0)), types) variables = types.pop(('func', (1, 0))) self.assertFalse(types) self.assertEqual({'a': set(['int']), 'i': set(['int'])}, variables) def test_conflicting_types_in_function(self): code = '''\ def func(a, b): print(a) a = 1 b += a a = 'abc' return a, str(b) print(func(1.5, 2)) ''' types = self._test(code) self.assertIn(('func', (1, 0)), types) variables = types.pop(('func', (1, 0))) self.assertFalse(types) self.assertEqual({'a': set(['float', 'int', 'str']), 'b': set(['int'])}, variables) def _test_typing_function_char_loop(self): code = '''\ def func(x): l = [] for c in x: l.append(c) return l print(func('abcdefg')) ''' types = self._test(code) self.assertIn(('func', (1, 0)), types) variables = types.pop(('func', (1, 0))) self.assertFalse(types) self.assertEqual({'a': set(['int']), 'i': set(['int'])}, variables) def test_typing_global_list(self): code = '''\ a = [x for x in range(10)] b = list(range(10)) c = a + b d = [0]*10 ''' types = self._test(code) self.assertIn((None, (1, 0)), types) variables = types.pop((None, (1, 0))) self.assertFalse(types) self.assertEqual({'a': set(['list']), 'b': set(['list']), 'c': set(['list']), 'd': set(['list'])}, variables) def test_typing_function_list(self): code = '''\ def func(x): a = [[], []] b = [0]* 10 + a c = a[0] print(func([0]*100)) ''' types = self._test(code) self.assertIn(('func', (1, 0)), types) variables = types.pop(('func', (1, 0))) self.assertFalse(types) self.assertEqual({'a': set(['list']), 'b': set(['list']), 'c': set(['list']), 'x': set(['list'])}, variables) def test_typing_global_dict(self): code = '''\ a = dict() b = {i: i**2 for i in range(10)} c = a ''' types = self._test(code) self.assertIn((None, (1, 0)), types) variables = types.pop((None, (1, 0))) self.assertFalse(types) self.assertEqual({'a': set(['dict']), 'b': set(['dict']), 'c': set(['dict'])}, variables) def test_typing_function_dict(self): code = '''\ def func(x): a = dict() b = {i: i**2 for i in range(10)} c = x print(func({1:2, 'x':7})) ''' types = self._test(code) self.assertIn(('func', (1, 0)), types) variables = types.pop(('func', (1, 0))) self.assertFalse(types) self.assertEqual({'a': set(['dict']), 'b': set(['dict']), 'c': set(['dict']), 'x': set(['dict'])}, variables) def test_typing_global_set(self): code = '''\ a = set() # b = {i for i in range(10)} # jedi does not support set comprehension yet c = a d = {1,2,3} e = a | b ''' types = self._test(code) self.assertIn((None, (1, 0)), types) variables = types.pop((None, (1, 0))) self.assertFalse(types) self.assertEqual({'a': set(['set']), 'c': set(['set']), 'd': set(['set']), 'e': set(['set'])}, variables) def test_typing_function_set(self): code = '''\ def func(x): a = set() # b = {i for i in range(10)} # jedi does not support set comprehension yet c = a d = a | b print(func({1,2,3})) ''' types = self._test(code) self.assertIn(('func', (1, 0)), types) variables = types.pop(('func', (1, 0))) self.assertFalse(types) self.assertEqual({'a': set(['set']), 'c': set(['set']), 'd': set(['set']), 'x': set(['set'])}, variables) class TestTypeInjection(TestJediTyper): """ Subtype of TestJediTyper that additionally tests type injection and compilation. """ def setUp(self): super(TestTypeInjection, self).setUp() compilation_options = Main.CompilationOptions(Main.default_options) ctx = compilation_options.create_context() transform = InterpretCompilerDirectives(ctx, ctx.compiler_directives) transform.module_scope = Symtab.ModuleScope('__main__', None, ctx) self.declarations_finder = DeclarationsFinder() self.pipeline = [NormalizeTree(None), transform, self.declarations_finder] def _test(self, code): types, lines = _test_typing(code, inject=True) tree = self.run_pipeline(self.pipeline, ''.join(lines)) directives = self.declarations_finder.directives # TODO: validate directives return types Cython-0.23.4/Cython/Tests/TestCodeWriter.py0000644000175600017570000000441412606202452022036 0ustar jenkinsjenkins00000000000000from Cython.TestUtils import CythonTest class TestCodeWriter(CythonTest): # CythonTest uses the CodeWriter heavily, so do some checking by # roundtripping Cython code through the test framework. # Note that this test is dependant upon the normal Cython parser # to generate the input trees to the CodeWriter. This save *a lot* # of time; better to spend that time writing other tests than perfecting # this one... # Whitespace is very significant in this process: # - always newline on new block (!) # - indent 4 spaces # - 1 space around every operator def t(self, codestr): self.assertCode(codestr, self.fragment(codestr).root) def test_print(self): self.t(u""" print x, y print x + y ** 2 print x, y, z, """) def test_if(self): self.t(u"if x:\n pass") def test_ifelifelse(self): self.t(u""" if x: pass elif y: pass elif z + 34 ** 34 - 2: pass else: pass """) def test_def(self): self.t(u""" def f(x, y, z): pass def f(x = 34, y = 54, z): pass """) def test_longness_and_signedness(self): self.t(u"def f(unsigned long long long long long int y):\n pass") def test_signed_short(self): self.t(u"def f(signed short int y):\n pass") def test_typed_args(self): self.t(u"def f(int x, unsigned long int y):\n pass") def test_cdef_var(self): self.t(u""" cdef int hello cdef int hello = 4, x = 3, y, z """) def test_for_loop(self): self.t(u""" for x, y, z in f(g(h(34) * 2) + 23): print x, y, z else: print 43 """) def test_inplace_assignment(self): self.t(u"x += 43") def test_attribute(self): self.t(u"a.x") if __name__ == "__main__": import unittest unittest.main() Cython-0.23.4/Cython/Tempita/0000755000175600017570000000000012606202455017056 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Tempita/compat3.py0000644000175600017570000000160712606202452020777 0ustar jenkinsjenkins00000000000000import sys __all__ = ['b', 'basestring_', 'bytes', 'unicode_', 'next', 'is_unicode'] if sys.version < "3": b = bytes = str basestring_ = basestring unicode_ = unicode else: def b(s): if isinstance(s, str): return s.encode('latin1') return bytes(s) basestring_ = (bytes, str) bytes = bytes unicode_ = str text = str if sys.version < "3": def next(obj): return obj.next() else: next = next if sys.version < "3": def is_unicode(obj): return isinstance(obj, unicode) else: def is_unicode(obj): return isinstance(obj, str) def coerce_text(v): if not isinstance(v, basestring_): if sys.version < "3": attr = '__unicode__' else: attr = '__str__' if hasattr(v, attr): return unicode(v) else: return bytes(v) return v Cython-0.23.4/Cython/Tempita/_tempita.py0000644000175600017570000011525412606202452021237 0ustar jenkinsjenkins00000000000000""" A small templating language This implements a small templating language. This language implements if/elif/else, for/continue/break, expressions, and blocks of Python code. The syntax is:: {{any expression (function calls etc)}} {{any expression | filter}} {{for x in y}}...{{endfor}} {{if x}}x{{elif y}}y{{else}}z{{endif}} {{py:x=1}} {{py: def foo(bar): return 'baz' }} {{default var = default_value}} {{# comment}} You use this with the ``Template`` class or the ``sub`` shortcut. The ``Template`` class takes the template string and the name of the template (for errors) and a default namespace. Then (like ``string.Template``) you can call the ``tmpl.substitute(**kw)`` method to make a substitution (or ``tmpl.substitute(a_dict)``). ``sub(content, **kw)`` substitutes the template immediately. You can use ``__name='tmpl.html'`` to set the name of the template. If there are syntax errors ``TemplateError`` will be raised. """ from __future__ import absolute_import import re import sys import cgi try: from urllib import quote as url_quote except ImportError: # Py3 from urllib.parse import quote as url_quote import os import tokenize from io import StringIO from ._looper import looper from .compat3 import bytes, unicode_, basestring_, next, is_unicode, coerce_text __all__ = ['TemplateError', 'Template', 'sub', 'HTMLTemplate', 'sub_html', 'html', 'bunch'] in_re = re.compile(r'\s+in\s+') var_re = re.compile(r'^[a-z_][a-z0-9_]*$', re.I) class TemplateError(Exception): """Exception raised while parsing a template """ def __init__(self, message, position, name=None): Exception.__init__(self, message) self.position = position self.name = name def __str__(self): msg = ' '.join(self.args) if self.position: msg = '%s at line %s column %s' % ( msg, self.position[0], self.position[1]) if self.name: msg += ' in %s' % self.name return msg class _TemplateContinue(Exception): pass class _TemplateBreak(Exception): pass def get_file_template(name, from_template): path = os.path.join(os.path.dirname(from_template.name), name) return from_template.__class__.from_filename( path, namespace=from_template.namespace, get_template=from_template.get_template) class Template(object): default_namespace = { 'start_braces': '{{', 'end_braces': '}}', 'looper': looper, } default_encoding = 'utf8' default_inherit = None def __init__(self, content, name=None, namespace=None, stacklevel=None, get_template=None, default_inherit=None, line_offset=0, delimeters=None): self.content = content # set delimeters if delimeters is None: delimeters = (self.default_namespace['start_braces'], self.default_namespace['end_braces']) else: #assert len(delimeters) == 2 and all([isinstance(delimeter, basestring) # for delimeter in delimeters]) self.default_namespace = self.__class__.default_namespace.copy() self.default_namespace['start_braces'] = delimeters[0] self.default_namespace['end_braces'] = delimeters[1] self.delimeters = delimeters self._unicode = is_unicode(content) if name is None and stacklevel is not None: try: caller = sys._getframe(stacklevel) except ValueError: pass else: globals = caller.f_globals lineno = caller.f_lineno if '__file__' in globals: name = globals['__file__'] if name.endswith('.pyc') or name.endswith('.pyo'): name = name[:-1] elif '__name__' in globals: name = globals['__name__'] else: name = '' if lineno: name += ':%s' % lineno self.name = name self._parsed = parse(content, name=name, line_offset=line_offset, delimeters=self.delimeters) if namespace is None: namespace = {} self.namespace = namespace self.get_template = get_template if default_inherit is not None: self.default_inherit = default_inherit def from_filename(cls, filename, namespace=None, encoding=None, default_inherit=None, get_template=get_file_template): f = open(filename, 'rb') c = f.read() f.close() if encoding: c = c.decode(encoding) return cls(content=c, name=filename, namespace=namespace, default_inherit=default_inherit, get_template=get_template) from_filename = classmethod(from_filename) def __repr__(self): return '<%s %s name=%r>' % ( self.__class__.__name__, hex(id(self))[2:], self.name) def substitute(self, *args, **kw): if args: if kw: raise TypeError( "You can only give positional *or* keyword arguments") if len(args) > 1: raise TypeError( "You can only give one positional argument") if not hasattr(args[0], 'items'): raise TypeError( "If you pass in a single argument, you must pass in a dictionary-like object (with a .items() method); you gave %r" % (args[0],)) kw = args[0] ns = kw ns['__template_name__'] = self.name if self.namespace: ns.update(self.namespace) result, defs, inherit = self._interpret(ns) if not inherit: inherit = self.default_inherit if inherit: result = self._interpret_inherit(result, defs, inherit, ns) return result def _interpret(self, ns): __traceback_hide__ = True parts = [] defs = {} self._interpret_codes(self._parsed, ns, out=parts, defs=defs) if '__inherit__' in defs: inherit = defs.pop('__inherit__') else: inherit = None return ''.join(parts), defs, inherit def _interpret_inherit(self, body, defs, inherit_template, ns): __traceback_hide__ = True if not self.get_template: raise TemplateError( 'You cannot use inheritance without passing in get_template', position=None, name=self.name) templ = self.get_template(inherit_template, self) self_ = TemplateObject(self.name) for name, value in defs.items(): setattr(self_, name, value) self_.body = body ns = ns.copy() ns['self'] = self_ return templ.substitute(ns) def _interpret_codes(self, codes, ns, out, defs): __traceback_hide__ = True for item in codes: if isinstance(item, basestring_): out.append(item) else: self._interpret_code(item, ns, out, defs) def _interpret_code(self, code, ns, out, defs): __traceback_hide__ = True name, pos = code[0], code[1] if name == 'py': self._exec(code[2], ns, pos) elif name == 'continue': raise _TemplateContinue() elif name == 'break': raise _TemplateBreak() elif name == 'for': vars, expr, content = code[2], code[3], code[4] expr = self._eval(expr, ns, pos) self._interpret_for(vars, expr, content, ns, out, defs) elif name == 'cond': parts = code[2:] self._interpret_if(parts, ns, out, defs) elif name == 'expr': parts = code[2].split('|') base = self._eval(parts[0], ns, pos) for part in parts[1:]: func = self._eval(part, ns, pos) base = func(base) out.append(self._repr(base, pos)) elif name == 'default': var, expr = code[2], code[3] if var not in ns: result = self._eval(expr, ns, pos) ns[var] = result elif name == 'inherit': expr = code[2] value = self._eval(expr, ns, pos) defs['__inherit__'] = value elif name == 'def': name = code[2] signature = code[3] parts = code[4] ns[name] = defs[name] = TemplateDef(self, name, signature, body=parts, ns=ns, pos=pos) elif name == 'comment': return else: assert 0, "Unknown code: %r" % name def _interpret_for(self, vars, expr, content, ns, out, defs): __traceback_hide__ = True for item in expr: if len(vars) == 1: ns[vars[0]] = item else: if len(vars) != len(item): raise ValueError( 'Need %i items to unpack (got %i items)' % (len(vars), len(item))) for name, value in zip(vars, item): ns[name] = value try: self._interpret_codes(content, ns, out, defs) except _TemplateContinue: continue except _TemplateBreak: break def _interpret_if(self, parts, ns, out, defs): __traceback_hide__ = True # @@: if/else/else gets through for part in parts: assert not isinstance(part, basestring_) name, pos = part[0], part[1] if name == 'else': result = True else: result = self._eval(part[2], ns, pos) if result: self._interpret_codes(part[3], ns, out, defs) break def _eval(self, code, ns, pos): __traceback_hide__ = True try: try: value = eval(code, self.default_namespace, ns) except SyntaxError as e: raise SyntaxError( 'invalid syntax in expression: %s' % code) return value except Exception as e: if getattr(e, 'args', None): arg0 = e.args[0] else: arg0 = coerce_text(e) e.args = (self._add_line_info(arg0, pos),) raise def _exec(self, code, ns, pos): __traceback_hide__ = True try: exec(code, self.default_namespace, ns) except Exception as e: if e.args: e.args = (self._add_line_info(e.args[0], pos),) else: e.args = (self._add_line_info(None, pos),) raise def _repr(self, value, pos): __traceback_hide__ = True try: if value is None: return '' if self._unicode: try: value = unicode_(value) except UnicodeDecodeError: value = bytes(value) else: if not isinstance(value, basestring_): value = coerce_text(value) if (is_unicode(value) and self.default_encoding): value = value.encode(self.default_encoding) except Exception as e: e.args = (self._add_line_info(e.args[0], pos),) raise else: if self._unicode and isinstance(value, bytes): if not self.default_encoding: raise UnicodeDecodeError( 'Cannot decode bytes value %r into unicode ' '(no default_encoding provided)' % value) try: value = value.decode(self.default_encoding) except UnicodeDecodeError as e: raise UnicodeDecodeError( e.encoding, e.object, e.start, e.end, e.reason + ' in string %r' % value) elif not self._unicode and is_unicode(value): if not self.default_encoding: raise UnicodeEncodeError( 'Cannot encode unicode value %r into bytes ' '(no default_encoding provided)' % value) value = value.encode(self.default_encoding) return value def _add_line_info(self, msg, pos): msg = "%s at line %s column %s" % ( msg, pos[0], pos[1]) if self.name: msg += " in file %s" % self.name return msg def sub(content, delimeters=None, **kw): name = kw.get('__name') tmpl = Template(content, name=name, delimeters=delimeters) return tmpl.substitute(kw) def paste_script_template_renderer(content, vars, filename=None): tmpl = Template(content, name=filename) return tmpl.substitute(vars) class bunch(dict): def __init__(self, **kw): for name, value in kw.items(): setattr(self, name, value) def __setattr__(self, name, value): self[name] = value def __getattr__(self, name): try: return self[name] except KeyError: raise AttributeError(name) def __getitem__(self, key): if 'default' in self: try: return dict.__getitem__(self, key) except KeyError: return dict.__getitem__(self, 'default') else: return dict.__getitem__(self, key) def __repr__(self): return '<%s %s>' % ( self.__class__.__name__, ' '.join(['%s=%r' % (k, v) for k, v in sorted(self.items())])) ############################################################ ## HTML Templating ############################################################ class html(object): def __init__(self, value): self.value = value def __str__(self): return self.value def __html__(self): return self.value def __repr__(self): return '<%s %r>' % ( self.__class__.__name__, self.value) def html_quote(value, force=True): if not force and hasattr(value, '__html__'): return value.__html__() if value is None: return '' if not isinstance(value, basestring_): value = coerce_text(value) if sys.version >= "3" and isinstance(value, bytes): value = cgi.escape(value.decode('latin1'), 1) value = value.encode('latin1') else: value = cgi.escape(value, 1) if sys.version < "3": if is_unicode(value): value = value.encode('ascii', 'xmlcharrefreplace') return value def url(v): v = coerce_text(v) if is_unicode(v): v = v.encode('utf8') return url_quote(v) def attr(**kw): parts = [] for name, value in sorted(kw.items()): if value is None: continue if name.endswith('_'): name = name[:-1] parts.append('%s="%s"' % (html_quote(name), html_quote(value))) return html(' '.join(parts)) class HTMLTemplate(Template): default_namespace = Template.default_namespace.copy() default_namespace.update(dict( html=html, attr=attr, url=url, html_quote=html_quote, )) def _repr(self, value, pos): if hasattr(value, '__html__'): value = value.__html__() quote = False else: quote = True plain = Template._repr(self, value, pos) if quote: return html_quote(plain) else: return plain def sub_html(content, **kw): name = kw.get('__name') tmpl = HTMLTemplate(content, name=name) return tmpl.substitute(kw) class TemplateDef(object): def __init__(self, template, func_name, func_signature, body, ns, pos, bound_self=None): self._template = template self._func_name = func_name self._func_signature = func_signature self._body = body self._ns = ns self._pos = pos self._bound_self = bound_self def __repr__(self): return '' % ( self._func_name, self._func_signature, self._template.name, self._pos) def __str__(self): return self() def __call__(self, *args, **kw): values = self._parse_signature(args, kw) ns = self._ns.copy() ns.update(values) if self._bound_self is not None: ns['self'] = self._bound_self out = [] subdefs = {} self._template._interpret_codes(self._body, ns, out, subdefs) return ''.join(out) def __get__(self, obj, type=None): if obj is None: return self return self.__class__( self._template, self._func_name, self._func_signature, self._body, self._ns, self._pos, bound_self=obj) def _parse_signature(self, args, kw): values = {} sig_args, var_args, var_kw, defaults = self._func_signature extra_kw = {} for name, value in kw.items(): if not var_kw and name not in sig_args: raise TypeError( 'Unexpected argument %s' % name) if name in sig_args: values[sig_args] = value else: extra_kw[name] = value args = list(args) sig_args = list(sig_args) while args: while sig_args and sig_args[0] in values: sig_args.pop(0) if sig_args: name = sig_args.pop(0) values[name] = args.pop(0) elif var_args: values[var_args] = tuple(args) break else: raise TypeError( 'Extra position arguments: %s' % ', '.join([repr(v) for v in args])) for name, value_expr in defaults.items(): if name not in values: values[name] = self._template._eval( value_expr, self._ns, self._pos) for name in sig_args: if name not in values: raise TypeError( 'Missing argument: %s' % name) if var_kw: values[var_kw] = extra_kw return values class TemplateObject(object): def __init__(self, name): self.__name = name self.get = TemplateObjectGetter(self) def __repr__(self): return '<%s %s>' % (self.__class__.__name__, self.__name) class TemplateObjectGetter(object): def __init__(self, template_obj): self.__template_obj = template_obj def __getattr__(self, attr): return getattr(self.__template_obj, attr, Empty) def __repr__(self): return '<%s around %r>' % (self.__class__.__name__, self.__template_obj) class _Empty(object): def __call__(self, *args, **kw): return self def __str__(self): return '' def __repr__(self): return 'Empty' def __unicode__(self): return u'' def __iter__(self): return iter(()) def __bool__(self): return False if sys.version < "3": __nonzero__ = __bool__ Empty = _Empty() del _Empty ############################################################ ## Lexing and Parsing ############################################################ def lex(s, name=None, trim_whitespace=True, line_offset=0, delimeters=None): """ Lex a string into chunks: >>> lex('hey') ['hey'] >>> lex('hey {{you}}') ['hey ', ('you', (1, 7))] >>> lex('hey {{') Traceback (most recent call last): ... TemplateError: No }} to finish last expression at line 1 column 7 >>> lex('hey }}') Traceback (most recent call last): ... TemplateError: }} outside expression at line 1 column 7 >>> lex('hey {{ {{') Traceback (most recent call last): ... TemplateError: {{ inside expression at line 1 column 10 """ if delimeters is None: delimeters = ( Template.default_namespace['start_braces'], Template.default_namespace['end_braces'] ) in_expr = False chunks = [] last = 0 last_pos = (line_offset + 1, 1) token_re = re.compile(r'%s|%s' % (re.escape(delimeters[0]), re.escape(delimeters[1]))) for match in token_re.finditer(s): expr = match.group(0) pos = find_position(s, match.end(), last, last_pos) if expr == delimeters[0] and in_expr: raise TemplateError('%s inside expression' % delimeters[0], position=pos, name=name) elif expr == delimeters[1] and not in_expr: raise TemplateError('%s outside expression' % delimeters[1], position=pos, name=name) if expr == delimeters[0]: part = s[last:match.start()] if part: chunks.append(part) in_expr = True else: chunks.append((s[last:match.start()], last_pos)) in_expr = False last = match.end() last_pos = pos if in_expr: raise TemplateError('No %s to finish last expression' % delimeters[1], name=name, position=last_pos) part = s[last:] if part: chunks.append(part) if trim_whitespace: chunks = trim_lex(chunks) return chunks statement_re = re.compile(r'^(?:if |elif |for |def |inherit |default |py:)') single_statements = ['else', 'endif', 'endfor', 'enddef', 'continue', 'break'] trail_whitespace_re = re.compile(r'\n\r?[\t ]*$') lead_whitespace_re = re.compile(r'^[\t ]*\n') def trim_lex(tokens): r""" Takes a lexed set of tokens, and removes whitespace when there is a directive on a line by itself: >>> tokens = lex('{{if x}}\nx\n{{endif}}\ny', trim_whitespace=False) >>> tokens [('if x', (1, 3)), '\nx\n', ('endif', (3, 3)), '\ny'] >>> trim_lex(tokens) [('if x', (1, 3)), 'x\n', ('endif', (3, 3)), 'y'] """ last_trim = None for i, current in enumerate(tokens): if isinstance(current, basestring_): # we don't trim this continue item = current[0] if not statement_re.search(item) and item not in single_statements: continue if not i: prev = '' else: prev = tokens[i - 1] if i + 1 >= len(tokens): next_chunk = '' else: next_chunk = tokens[i + 1] if (not isinstance(next_chunk, basestring_) or not isinstance(prev, basestring_)): continue prev_ok = not prev or trail_whitespace_re.search(prev) if i == 1 and not prev.strip(): prev_ok = True if last_trim is not None and last_trim + 2 == i and not prev.strip(): prev_ok = 'last' if (prev_ok and (not next_chunk or lead_whitespace_re.search(next_chunk) or (i == len(tokens) - 2 and not next_chunk.strip()))): if prev: if ((i == 1 and not prev.strip()) or prev_ok == 'last'): tokens[i - 1] = '' else: m = trail_whitespace_re.search(prev) # +1 to leave the leading \n on: prev = prev[:m.start() + 1] tokens[i - 1] = prev if next_chunk: last_trim = i if i == len(tokens) - 2 and not next_chunk.strip(): tokens[i + 1] = '' else: m = lead_whitespace_re.search(next_chunk) next_chunk = next_chunk[m.end():] tokens[i + 1] = next_chunk return tokens def find_position(string, index, last_index, last_pos): """Given a string and index, return (line, column)""" lines = string.count('\n', last_index, index) if lines > 0: column = index - string.rfind('\n', last_index, index) else: column = last_pos[1] + (index - last_index) return (last_pos[0] + lines, column) def parse(s, name=None, line_offset=0, delimeters=None): r""" Parses a string into a kind of AST >>> parse('{{x}}') [('expr', (1, 3), 'x')] >>> parse('foo') ['foo'] >>> parse('{{if x}}test{{endif}}') [('cond', (1, 3), ('if', (1, 3), 'x', ['test']))] >>> parse('series->{{for x in y}}x={{x}}{{endfor}}') ['series->', ('for', (1, 11), ('x',), 'y', ['x=', ('expr', (1, 27), 'x')])] >>> parse('{{for x, y in z:}}{{continue}}{{endfor}}') [('for', (1, 3), ('x', 'y'), 'z', [('continue', (1, 21))])] >>> parse('{{py:x=1}}') [('py', (1, 3), 'x=1')] >>> parse('{{if x}}a{{elif y}}b{{else}}c{{endif}}') [('cond', (1, 3), ('if', (1, 3), 'x', ['a']), ('elif', (1, 12), 'y', ['b']), ('else', (1, 23), None, ['c']))] Some exceptions:: >>> parse('{{continue}}') Traceback (most recent call last): ... TemplateError: continue outside of for loop at line 1 column 3 >>> parse('{{if x}}foo') Traceback (most recent call last): ... TemplateError: No {{endif}} at line 1 column 3 >>> parse('{{else}}') Traceback (most recent call last): ... TemplateError: else outside of an if block at line 1 column 3 >>> parse('{{if x}}{{for x in y}}{{endif}}{{endfor}}') Traceback (most recent call last): ... TemplateError: Unexpected endif at line 1 column 25 >>> parse('{{if}}{{endif}}') Traceback (most recent call last): ... TemplateError: if with no expression at line 1 column 3 >>> parse('{{for x y}}{{endfor}}') Traceback (most recent call last): ... TemplateError: Bad for (no "in") in 'x y' at line 1 column 3 >>> parse('{{py:x=1\ny=2}}') Traceback (most recent call last): ... TemplateError: Multi-line py blocks must start with a newline at line 1 column 3 """ if delimeters is None: delimeters = ( Template.default_namespace['start_braces'], Template.default_namespace['end_braces'] ) tokens = lex(s, name=name, line_offset=line_offset, delimeters=delimeters) result = [] while tokens: next_chunk, tokens = parse_expr(tokens, name) result.append(next_chunk) return result def parse_expr(tokens, name, context=()): if isinstance(tokens[0], basestring_): return tokens[0], tokens[1:] expr, pos = tokens[0] expr = expr.strip() if expr.startswith('py:'): expr = expr[3:].lstrip(' \t') if expr.startswith('\n') or expr.startswith('\r'): expr = expr.lstrip('\r\n') if '\r' in expr: expr = expr.replace('\r\n', '\n') expr = expr.replace('\r', '') expr += '\n' else: if '\n' in expr: raise TemplateError( 'Multi-line py blocks must start with a newline', position=pos, name=name) return ('py', pos, expr), tokens[1:] elif expr in ('continue', 'break'): if 'for' not in context: raise TemplateError( 'continue outside of for loop', position=pos, name=name) return (expr, pos), tokens[1:] elif expr.startswith('if '): return parse_cond(tokens, name, context) elif (expr.startswith('elif ') or expr == 'else'): raise TemplateError( '%s outside of an if block' % expr.split()[0], position=pos, name=name) elif expr in ('if', 'elif', 'for'): raise TemplateError( '%s with no expression' % expr, position=pos, name=name) elif expr in ('endif', 'endfor', 'enddef'): raise TemplateError( 'Unexpected %s' % expr, position=pos, name=name) elif expr.startswith('for '): return parse_for(tokens, name, context) elif expr.startswith('default '): return parse_default(tokens, name, context) elif expr.startswith('inherit '): return parse_inherit(tokens, name, context) elif expr.startswith('def '): return parse_def(tokens, name, context) elif expr.startswith('#'): return ('comment', pos, tokens[0][0]), tokens[1:] return ('expr', pos, tokens[0][0]), tokens[1:] def parse_cond(tokens, name, context): start = tokens[0][1] pieces = [] context = context + ('if',) while 1: if not tokens: raise TemplateError( 'Missing {{endif}}', position=start, name=name) if (isinstance(tokens[0], tuple) and tokens[0][0] == 'endif'): return ('cond', start) + tuple(pieces), tokens[1:] next_chunk, tokens = parse_one_cond(tokens, name, context) pieces.append(next_chunk) def parse_one_cond(tokens, name, context): (first, pos), tokens = tokens[0], tokens[1:] content = [] if first.endswith(':'): first = first[:-1] if first.startswith('if '): part = ('if', pos, first[3:].lstrip(), content) elif first.startswith('elif '): part = ('elif', pos, first[5:].lstrip(), content) elif first == 'else': part = ('else', pos, None, content) else: assert 0, "Unexpected token %r at %s" % (first, pos) while 1: if not tokens: raise TemplateError( 'No {{endif}}', position=pos, name=name) if (isinstance(tokens[0], tuple) and (tokens[0][0] == 'endif' or tokens[0][0].startswith('elif ') or tokens[0][0] == 'else')): return part, tokens next_chunk, tokens = parse_expr(tokens, name, context) content.append(next_chunk) def parse_for(tokens, name, context): first, pos = tokens[0] tokens = tokens[1:] context = ('for',) + context content = [] assert first.startswith('for ') if first.endswith(':'): first = first[:-1] first = first[3:].strip() match = in_re.search(first) if not match: raise TemplateError( 'Bad for (no "in") in %r' % first, position=pos, name=name) vars = first[:match.start()] if '(' in vars: raise TemplateError( 'You cannot have () in the variable section of a for loop (%r)' % vars, position=pos, name=name) vars = tuple([ v.strip() for v in first[:match.start()].split(',') if v.strip()]) expr = first[match.end():] while 1: if not tokens: raise TemplateError( 'No {{endfor}}', position=pos, name=name) if (isinstance(tokens[0], tuple) and tokens[0][0] == 'endfor'): return ('for', pos, vars, expr, content), tokens[1:] next_chunk, tokens = parse_expr(tokens, name, context) content.append(next_chunk) def parse_default(tokens, name, context): first, pos = tokens[0] assert first.startswith('default ') first = first.split(None, 1)[1] parts = first.split('=', 1) if len(parts) == 1: raise TemplateError( "Expression must be {{default var=value}}; no = found in %r" % first, position=pos, name=name) var = parts[0].strip() if ',' in var: raise TemplateError( "{{default x, y = ...}} is not supported", position=pos, name=name) if not var_re.search(var): raise TemplateError( "Not a valid variable name for {{default}}: %r" % var, position=pos, name=name) expr = parts[1].strip() return ('default', pos, var, expr), tokens[1:] def parse_inherit(tokens, name, context): first, pos = tokens[0] assert first.startswith('inherit ') expr = first.split(None, 1)[1] return ('inherit', pos, expr), tokens[1:] def parse_def(tokens, name, context): first, start = tokens[0] tokens = tokens[1:] assert first.startswith('def ') first = first.split(None, 1)[1] if first.endswith(':'): first = first[:-1] if '(' not in first: func_name = first sig = ((), None, None, {}) elif not first.endswith(')'): raise TemplateError("Function definition doesn't end with ): %s" % first, position=start, name=name) else: first = first[:-1] func_name, sig_text = first.split('(', 1) sig = parse_signature(sig_text, name, start) context = context + ('def',) content = [] while 1: if not tokens: raise TemplateError( 'Missing {{enddef}}', position=start, name=name) if (isinstance(tokens[0], tuple) and tokens[0][0] == 'enddef'): return ('def', start, func_name, sig, content), tokens[1:] next_chunk, tokens = parse_expr(tokens, name, context) content.append(next_chunk) def parse_signature(sig_text, name, pos): tokens = tokenize.generate_tokens(StringIO(sig_text).readline) sig_args = [] var_arg = None var_kw = None defaults = {} def get_token(pos=False): try: tok_type, tok_string, (srow, scol), (erow, ecol), line = next(tokens) except StopIteration: return tokenize.ENDMARKER, '' if pos: return tok_type, tok_string, (srow, scol), (erow, ecol) else: return tok_type, tok_string while 1: var_arg_type = None tok_type, tok_string = get_token() if tok_type == tokenize.ENDMARKER: break if tok_type == tokenize.OP and (tok_string == '*' or tok_string == '**'): var_arg_type = tok_string tok_type, tok_string = get_token() if tok_type != tokenize.NAME: raise TemplateError('Invalid signature: (%s)' % sig_text, position=pos, name=name) var_name = tok_string tok_type, tok_string = get_token() if tok_type == tokenize.ENDMARKER or (tok_type == tokenize.OP and tok_string == ','): if var_arg_type == '*': var_arg = var_name elif var_arg_type == '**': var_kw = var_name else: sig_args.append(var_name) if tok_type == tokenize.ENDMARKER: break continue if var_arg_type is not None: raise TemplateError('Invalid signature: (%s)' % sig_text, position=pos, name=name) if tok_type == tokenize.OP and tok_string == '=': nest_type = None unnest_type = None nest_count = 0 start_pos = end_pos = None parts = [] while 1: tok_type, tok_string, s, e = get_token(True) if start_pos is None: start_pos = s end_pos = e if tok_type == tokenize.ENDMARKER and nest_count: raise TemplateError('Invalid signature: (%s)' % sig_text, position=pos, name=name) if (not nest_count and (tok_type == tokenize.ENDMARKER or (tok_type == tokenize.OP and tok_string == ','))): default_expr = isolate_expression(sig_text, start_pos, end_pos) defaults[var_name] = default_expr sig_args.append(var_name) break parts.append((tok_type, tok_string)) if nest_count and tok_type == tokenize.OP and tok_string == nest_type: nest_count += 1 elif nest_count and tok_type == tokenize.OP and tok_string == unnest_type: nest_count -= 1 if not nest_count: nest_type = unnest_type = None elif not nest_count and tok_type == tokenize.OP and tok_string in ('(', '[', '{'): nest_type = tok_string nest_count = 1 unnest_type = {'(': ')', '[': ']', '{': '}'}[nest_type] return sig_args, var_arg, var_kw, defaults def isolate_expression(string, start_pos, end_pos): srow, scol = start_pos srow -= 1 erow, ecol = end_pos erow -= 1 lines = string.splitlines(True) if srow == erow: return lines[srow][scol:ecol] parts = [lines[srow][scol:]] parts.extend(lines[srow+1:erow]) if erow < len(lines): # It'll sometimes give (end_row_past_finish, 0) parts.append(lines[erow][:ecol]) return ''.join(parts) _fill_command_usage = """\ %prog [OPTIONS] TEMPLATE arg=value Use py:arg=value to set a Python value; otherwise all values are strings. """ def fill_command(args=None): import sys import optparse import pkg_resources import os if args is None: args = sys.argv[1:] dist = pkg_resources.get_distribution('Paste') parser = optparse.OptionParser( version=coerce_text(dist), usage=_fill_command_usage) parser.add_option( '-o', '--output', dest='output', metavar="FILENAME", help="File to write output to (default stdout)") parser.add_option( '--html', dest='use_html', action='store_true', help="Use HTML style filling (including automatic HTML quoting)") parser.add_option( '--env', dest='use_env', action='store_true', help="Put the environment in as top-level variables") options, args = parser.parse_args(args) if len(args) < 1: print('You must give a template filename') sys.exit(2) template_name = args[0] args = args[1:] vars = {} if options.use_env: vars.update(os.environ) for value in args: if '=' not in value: print('Bad argument: %r' % value) sys.exit(2) name, value = value.split('=', 1) if name.startswith('py:'): name = name[:3] value = eval(value) vars[name] = value if template_name == '-': template_content = sys.stdin.read() template_name = '' else: f = open(template_name, 'rb') template_content = f.read() f.close() if options.use_html: TemplateClass = HTMLTemplate else: TemplateClass = Template template = TemplateClass(template_content, name=template_name) result = template.substitute(vars) if options.output: f = open(options.output, 'wb') f.write(result) f.close() else: sys.stdout.write(result) if __name__ == '__main__': fill_command() Cython-0.23.4/Cython/Tempita/_looper.py0000644000175600017570000001011012606202452021055 0ustar jenkinsjenkins00000000000000""" Helper for looping over sequences, particular in templates. Often in a loop in a template it's handy to know what's next up, previously up, if this is the first or last item in the sequence, etc. These can be awkward to manage in a normal Python loop, but using the looper you can get a better sense of the context. Use like:: >>> for loop, item in looper(['a', 'b', 'c']): ... print loop.number, item ... if not loop.last: ... print '---' 1 a --- 2 b --- 3 c """ import sys from Cython.Tempita.compat3 import basestring_ __all__ = ['looper'] class looper(object): """ Helper for looping (particularly in templates) Use this like:: for loop, item in looper(seq): if loop.first: ... """ def __init__(self, seq): self.seq = seq def __iter__(self): return looper_iter(self.seq) def __repr__(self): return '<%s for %r>' % ( self.__class__.__name__, self.seq) class looper_iter(object): def __init__(self, seq): self.seq = list(seq) self.pos = 0 def __iter__(self): return self def __next__(self): if self.pos >= len(self.seq): raise StopIteration result = loop_pos(self.seq, self.pos), self.seq[self.pos] self.pos += 1 return result if sys.version < "3": next = __next__ class loop_pos(object): def __init__(self, seq, pos): self.seq = seq self.pos = pos def __repr__(self): return '' % ( self.seq[self.pos], self.pos) def index(self): return self.pos index = property(index) def number(self): return self.pos + 1 number = property(number) def item(self): return self.seq[self.pos] item = property(item) def __next__(self): try: return self.seq[self.pos + 1] except IndexError: return None __next__ = property(__next__) if sys.version < "3": next = __next__ def previous(self): if self.pos == 0: return None return self.seq[self.pos - 1] previous = property(previous) def odd(self): return not self.pos % 2 odd = property(odd) def even(self): return self.pos % 2 even = property(even) def first(self): return self.pos == 0 first = property(first) def last(self): return self.pos == len(self.seq) - 1 last = property(last) def length(self): return len(self.seq) length = property(length) def first_group(self, getter=None): """ Returns true if this item is the start of a new group, where groups mean that some attribute has changed. The getter can be None (the item itself changes), an attribute name like ``'.attr'``, a function, or a dict key or list index. """ if self.first: return True return self._compare_group(self.item, self.previous, getter) def last_group(self, getter=None): """ Returns true if this item is the end of a new group, where groups mean that some attribute has changed. The getter can be None (the item itself changes), an attribute name like ``'.attr'``, a function, or a dict key or list index. """ if self.last: return True return self._compare_group(self.item, self.__next__, getter) def _compare_group(self, item, other, getter): if getter is None: return item != other elif (isinstance(getter, basestring_) and getter.startswith('.')): getter = getter[1:] if getter.endswith('()'): getter = getter[:-2] return getattr(item, getter)() != getattr(other, getter)() else: return getattr(item, getter) != getattr(other, getter) elif hasattr(getter, '__call__'): return getter(item) != getter(other) else: return item[getter] != other[getter] Cython-0.23.4/Cython/Tempita/__init__.py0000644000175600017570000000023012606202452021157 0ustar jenkinsjenkins00000000000000# The original Tempita implements all of its templating code here. # Moved it to _tempita.py to make the compilation portable. from ._tempita import * Cython-0.23.4/Cython/Runtime/0000755000175600017570000000000012606202455017076 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Runtime/refnanny.pyx0000644000175600017570000001431412606202452021460 0ustar jenkinsjenkins00000000000000# cython: language_level=3 from cpython.ref cimport PyObject, Py_INCREF, Py_DECREF, Py_XDECREF, Py_XINCREF from cpython.exc cimport PyErr_Fetch, PyErr_Restore from cpython.pystate cimport PyThreadState_Get cimport cython loglevel = 0 reflog = [] cdef log(level, action, obj, lineno): if loglevel >= level: reflog.append((lineno, action, id(obj))) LOG_NONE, LOG_ALL = range(2) @cython.final cdef class Context(object): cdef readonly object name, filename cdef readonly dict refs cdef readonly list errors cdef readonly Py_ssize_t start def __cinit__(self, name, line=0, filename=None): self.name = name self.start = line self.filename = filename self.refs = {} # id -> (count, [lineno]) self.errors = [] cdef regref(self, obj, lineno, bint is_null): log(LOG_ALL, u'regref', u"" if is_null else obj, lineno) if is_null: self.errors.append(u"NULL argument on line %d" % lineno) return id_ = id(obj) count, linenumbers = self.refs.get(id_, (0, [])) self.refs[id_] = (count + 1, linenumbers) linenumbers.append(lineno) cdef bint delref(self, obj, lineno, bint is_null) except -1: # returns whether it is ok to do the decref operation log(LOG_ALL, u'delref', u"" if is_null else obj, lineno) if is_null: self.errors.append(u"NULL argument on line %d" % lineno) return False id_ = id(obj) count, linenumbers = self.refs.get(id_, (0, [])) if count == 0: self.errors.append(u"Too many decrefs on line %d, reference acquired on lines %r" % (lineno, linenumbers)) return False elif count == 1: del self.refs[id_] return True else: self.refs[id_] = (count - 1, linenumbers) return True cdef end(self): if self.refs: msg = u"References leaked:" for count, linenos in self.refs.itervalues(): msg += u"\n (%d) acquired on lines: %s" % (count, u", ".join([u"%d" % x for x in linenos])) self.errors.append(msg) if self.errors: return u"\n".join([u'REFNANNY: '+error for error in self.errors]) else: return None cdef void report_unraisable(object e=None): try: if e is None: import sys e = sys.exc_info()[1] print(u"refnanny raised an exception: %s" % e) except: pass # We absolutely cannot exit with an exception # All Python operations must happen after any existing # exception has been fetched, in case we are called from # exception-handling code. cdef PyObject* SetupContext(char* funcname, int lineno, char* filename) except NULL: if Context is None: # Context may be None during finalize phase. # In that case, we don't want to be doing anything fancy # like caching and resetting exceptions. return NULL cdef (PyObject*) type = NULL, value = NULL, tb = NULL, result = NULL PyThreadState_Get() PyErr_Fetch(&type, &value, &tb) try: ctx = Context(funcname, lineno, filename) Py_INCREF(ctx) result = ctx except Exception, e: report_unraisable(e) PyErr_Restore(type, value, tb) return result cdef void GOTREF(PyObject* ctx, PyObject* p_obj, int lineno): if ctx == NULL: return cdef (PyObject*) type = NULL, value = NULL, tb = NULL PyErr_Fetch(&type, &value, &tb) try: try: if p_obj is NULL: (ctx).regref(None, lineno, True) else: (ctx).regref(p_obj, lineno, False) except: report_unraisable() except: # __Pyx_GetException may itself raise errors pass PyErr_Restore(type, value, tb) cdef int GIVEREF_and_report(PyObject* ctx, PyObject* p_obj, int lineno): if ctx == NULL: return 1 cdef (PyObject*) type = NULL, value = NULL, tb = NULL cdef bint decref_ok = False PyErr_Fetch(&type, &value, &tb) try: try: if p_obj is NULL: decref_ok = (ctx).delref(None, lineno, True) else: decref_ok = (ctx).delref(p_obj, lineno, False) except: report_unraisable() except: # __Pyx_GetException may itself raise errors pass PyErr_Restore(type, value, tb) return decref_ok cdef void GIVEREF(PyObject* ctx, PyObject* p_obj, int lineno): GIVEREF_and_report(ctx, p_obj, lineno) cdef void INCREF(PyObject* ctx, PyObject* obj, int lineno): Py_XINCREF(obj) PyThreadState_Get() GOTREF(ctx, obj, lineno) cdef void DECREF(PyObject* ctx, PyObject* obj, int lineno): if GIVEREF_and_report(ctx, obj, lineno): Py_XDECREF(obj) PyThreadState_Get() cdef void FinishContext(PyObject** ctx): if ctx == NULL or ctx[0] == NULL: return cdef (PyObject*) type = NULL, value = NULL, tb = NULL cdef object errors = None cdef Context context PyThreadState_Get() PyErr_Fetch(&type, &value, &tb) try: try: context = ctx[0] errors = context.end() if errors: print(u"%s: %s()" % ( context.filename.decode('latin1'), context.name.decode('latin1'))) print(errors) context = None except: report_unraisable() except: # __Pyx_GetException may itself raise errors pass Py_XDECREF(ctx[0]) ctx[0] = NULL PyErr_Restore(type, value, tb) ctypedef struct RefNannyAPIStruct: void (*INCREF)(PyObject*, PyObject*, int) void (*DECREF)(PyObject*, PyObject*, int) void (*GOTREF)(PyObject*, PyObject*, int) void (*GIVEREF)(PyObject*, PyObject*, int) PyObject* (*SetupContext)(char*, int, char*) except NULL void (*FinishContext)(PyObject**) cdef RefNannyAPIStruct api api.INCREF = INCREF api.DECREF = DECREF api.GOTREF = GOTREF api.GIVEREF = GIVEREF api.SetupContext = SetupContext api.FinishContext = FinishContext cdef extern from "Python.h": object PyLong_FromVoidPtr(void*) RefNannyAPI = PyLong_FromVoidPtr(&api) Cython-0.23.4/Cython/Runtime/__init__.py0000644000175600017570000000001512606202452021200 0ustar jenkinsjenkins00000000000000# empty file Cython-0.23.4/Cython/Plex/0000755000175600017570000000000012606202455016363 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Plex/__init__.py0000644000175600017570000000240212606202452020467 0ustar jenkinsjenkins00000000000000#======================================================================= # # Python Lexical Analyser # #======================================================================= """ The Plex module provides lexical analysers with similar capabilities to GNU Flex. The following classes and functions are exported; see the attached docstrings for more information. Scanner For scanning a character stream under the direction of a Lexicon. Lexicon For constructing a lexical definition to be used by a Scanner. Str, Any, AnyBut, AnyChar, Seq, Alt, Opt, Rep, Rep1, Bol, Eol, Eof, Empty Regular expression constructors, for building pattern definitions for a Lexicon. State For defining scanner states when creating a Lexicon. TEXT, IGNORE, Begin Actions for associating with patterns when creating a Lexicon. """ from __future__ import absolute_import from .Actions import TEXT, IGNORE, Begin from .Lexicons import Lexicon, State from .Regexps import RE, Seq, Alt, Rep1, Empty, Str, Any, AnyBut, AnyChar, Range from .Regexps import Opt, Rep, Bol, Eol, Eof, Case, NoCase from .Scanners import Scanner Cython-0.23.4/Cython/Plex/Transitions.py0000644000175600017570000001602312606202452021251 0ustar jenkinsjenkins00000000000000# # Plex - Transition Maps # # This version represents state sets directly as dicts for speed. # from __future__ import absolute_import try: from sys import maxsize as maxint except ImportError: from sys import maxint class TransitionMap(object): """ A TransitionMap maps an input event to a set of states. An input event is one of: a range of character codes, the empty string (representing an epsilon move), or one of the special symbols BOL, EOL, EOF. For characters, this implementation compactly represents the map by means of a list: [code_0, states_0, code_1, states_1, code_2, states_2, ..., code_n-1, states_n-1, code_n] where |code_i| is a character code, and |states_i| is a set of states corresponding to characters with codes |c| in the range |code_i| <= |c| <= |code_i+1|. The following invariants hold: n >= 1 code_0 == -maxint code_n == maxint code_i < code_i+1 for i in 0..n-1 states_0 == states_n-1 Mappings for the special events '', BOL, EOL, EOF are kept separately in a dictionary. """ map = None # The list of codes and states special = None # Mapping for special events def __init__(self, map=None, special=None): if not map: map = [-maxint, {}, maxint] if not special: special = {} self.map = map self.special = special #self.check() ### def add(self, event, new_state, TupleType=tuple): """ Add transition to |new_state| on |event|. """ if type(event) is TupleType: code0, code1 = event i = self.split(code0) j = self.split(code1) map = self.map while i < j: map[i + 1][new_state] = 1 i += 2 else: self.get_special(event)[new_state] = 1 def add_set(self, event, new_set, TupleType=tuple): """ Add transitions to the states in |new_set| on |event|. """ if type(event) is TupleType: code0, code1 = event i = self.split(code0) j = self.split(code1) map = self.map while i < j: map[i + 1].update(new_set) i += 2 else: self.get_special(event).update(new_set) def get_epsilon(self, none=None): """ Return the mapping for epsilon, or None. """ return self.special.get('', none) def iteritems(self, len=len): """ Return the mapping as an iterable of ((code1, code2), state_set) and (special_event, state_set) pairs. """ result = [] map = self.map else_set = map[1] i = 0 n = len(map) - 1 code0 = map[0] while i < n: set = map[i + 1] code1 = map[i + 2] if set or else_set: result.append(((code0, code1), set)) code0 = code1 i += 2 for event, set in self.special.items(): if set: result.append((event, set)) return iter(result) items = iteritems # ------------------- Private methods -------------------- def split(self, code, len=len, maxint=maxint): """ Search the list for the position of the split point for |code|, inserting a new split point if necessary. Returns index |i| such that |code| == |map[i]|. """ # We use a funky variation on binary search. map = self.map hi = len(map) - 1 # Special case: code == map[-1] if code == maxint: return hi # General case lo = 0 # loop invariant: map[lo] <= code < map[hi] and hi - lo >= 2 while hi - lo >= 4: # Find midpoint truncated to even index mid = ((lo + hi) // 2) & ~1 if code < map[mid]: hi = mid else: lo = mid # map[lo] <= code < map[hi] and hi - lo == 2 if map[lo] == code: return lo else: map[hi:hi] = [code, map[hi - 1].copy()] #self.check() ### return hi def get_special(self, event): """ Get state set for special event, adding a new entry if necessary. """ special = self.special set = special.get(event, None) if not set: set = {} special[event] = set return set # --------------------- Conversion methods ----------------------- def __str__(self): map_strs = [] map = self.map n = len(map) i = 0 while i < n: code = map[i] if code == -maxint: code_str = "-inf" elif code == maxint: code_str = "inf" else: code_str = str(code) map_strs.append(code_str) i += 1 if i < n: map_strs.append(state_set_str(map[i])) i += 1 special_strs = {} for event, set in self.special.items(): special_strs[event] = state_set_str(set) return "[%s]+%s" % ( ','.join(map_strs), special_strs ) # --------------------- Debugging methods ----------------------- def check(self): """Check data structure integrity.""" if not self.map[-3] < self.map[-1]: print(self) assert 0 def dump(self, file): map = self.map i = 0 n = len(map) - 1 while i < n: self.dump_range(map[i], map[i + 2], map[i + 1], file) i += 2 for event, set in self.special.items(): if set: if not event: event = 'empty' self.dump_trans(event, set, file) def dump_range(self, code0, code1, set, file): if set: if code0 == -maxint: if code1 == maxint: k = "any" else: k = "< %s" % self.dump_char(code1) elif code1 == maxint: k = "> %s" % self.dump_char(code0 - 1) elif code0 == code1 - 1: k = self.dump_char(code0) else: k = "%s..%s" % (self.dump_char(code0), self.dump_char(code1 - 1)) self.dump_trans(k, set, file) def dump_char(self, code): if 0 <= code <= 255: return repr(chr(code)) else: return "chr(%d)" % code def dump_trans(self, key, set, file): file.write(" %s --> %s\n" % (key, self.dump_set(set))) def dump_set(self, set): return state_set_str(set) # # State set manipulation functions # #def merge_state_sets(set1, set2): # for state in set2.keys(): # set1[state] = 1 def state_set_str(set): return "[%s]" % ','.join(["S%d" % state.number for state in set]) Cython-0.23.4/Cython/Plex/Traditional.py0000644000175600017570000001003012606202452021176 0ustar jenkinsjenkins00000000000000#======================================================================= # # Python Lexical Analyser # # Traditional Regular Expression Syntax # #======================================================================= from __future__ import absolute_import from .Regexps import Alt, Seq, Rep, Rep1, Opt, Any, AnyBut, Bol, Eol, Char from .Errors import PlexError class RegexpSyntaxError(PlexError): pass def re(s): """ Convert traditional string representation of regular expression |s| into Plex representation. """ return REParser(s).parse_re() class REParser(object): def __init__(self, s): self.s = s self.i = -1 self.end = 0 self.next() def parse_re(self): re = self.parse_alt() if not self.end: self.error("Unexpected %s" % repr(self.c)) return re def parse_alt(self): """Parse a set of alternative regexps.""" re = self.parse_seq() if self.c == '|': re_list = [re] while self.c == '|': self.next() re_list.append(self.parse_seq()) re = Alt(*re_list) return re def parse_seq(self): """Parse a sequence of regexps.""" re_list = [] while not self.end and not self.c in "|)": re_list.append(self.parse_mod()) return Seq(*re_list) def parse_mod(self): """Parse a primitive regexp followed by *, +, ? modifiers.""" re = self.parse_prim() while not self.end and self.c in "*+?": if self.c == '*': re = Rep(re) elif self.c == '+': re = Rep1(re) else: # self.c == '?' re = Opt(re) self.next() return re def parse_prim(self): """Parse a primitive regexp.""" c = self.get() if c == '.': re = AnyBut("\n") elif c == '^': re = Bol elif c == '$': re = Eol elif c == '(': re = self.parse_alt() self.expect(')') elif c == '[': re = self.parse_charset() self.expect(']') else: if c == '\\': c = self.get() re = Char(c) return re def parse_charset(self): """Parse a charset. Does not include the surrounding [].""" char_list = [] invert = 0 if self.c == '^': invert = 1 self.next() if self.c == ']': char_list.append(']') self.next() while not self.end and self.c != ']': c1 = self.get() if self.c == '-' and self.lookahead(1) != ']': self.next() c2 = self.get() for a in range(ord(c1), ord(c2) + 1): char_list.append(chr(a)) else: char_list.append(c1) chars = ''.join(char_list) if invert: return AnyBut(chars) else: return Any(chars) def next(self): """Advance to the next char.""" s = self.s i = self.i = self.i + 1 if i < len(s): self.c = s[i] else: self.c = '' self.end = 1 def get(self): if self.end: self.error("Premature end of string") c = self.c self.next() return c def lookahead(self, n): """Look ahead n chars.""" j = self.i + n if j < len(self.s): return self.s[j] else: return '' def expect(self, c): """ Expect to find character |c| at current position. Raises an exception otherwise. """ if self.c == c: self.next() else: self.error("Missing %s" % repr(c)) def error(self, mess): """Raise exception to signal syntax error in regexp.""" raise RegexpSyntaxError("Syntax error in regexp %s at position %d: %s" % ( repr(self.s), self.i, mess)) Cython-0.23.4/Cython/Plex/Timing.py0000644000175600017570000000073012606202452020161 0ustar jenkinsjenkins00000000000000# # Get time in platform-dependent way # from __future__ import absolute_import import os from sys import platform, exit, stderr if platform == 'mac': import MacOS def time(): return MacOS.GetTicks() / 60.0 timekind = "real" elif hasattr(os, 'times'): def time(): t = os.times() return t[0] + t[1] timekind = "cpu" else: stderr.write( "Don't know how to get time on platform %s\n" % repr(platform)) exit(1) Cython-0.23.4/Cython/Plex/Scanners.py0000644000175600017570000002771512606202452020522 0ustar jenkinsjenkins00000000000000#======================================================================= # # Python Lexical Analyser # # # Scanning an input stream # #======================================================================= from __future__ import absolute_import import cython cython.declare(BOL=object, EOL=object, EOF=object, NOT_FOUND=object) from . import Errors from .Regexps import BOL, EOL, EOF NOT_FOUND = object() class Scanner(object): """ A Scanner is used to read tokens from a stream of characters using the token set specified by a Plex.Lexicon. Constructor: Scanner(lexicon, stream, name = '') See the docstring of the __init__ method for details. Methods: See the docstrings of the individual methods for more information. read() --> (value, text) Reads the next lexical token from the stream. position() --> (name, line, col) Returns the position of the last token read using the read() method. begin(state_name) Causes scanner to change state. produce(value [, text]) Causes return of a token value to the caller of the Scanner. """ # lexicon = None # Lexicon # stream = None # file-like object # name = '' # buffer = '' # buf_start_pos = 0 # position in input of start of buffer # next_pos = 0 # position in input of next char to read # cur_pos = 0 # position in input of current char # cur_line = 1 # line number of current char # cur_line_start = 0 # position in input of start of current line # start_pos = 0 # position in input of start of token # start_line = 0 # line number of start of token # start_col = 0 # position in line of start of token # text = None # text of last token read # initial_state = None # Node # state_name = '' # Name of initial state # queue = None # list of tokens to be returned # trace = 0 def __init__(self, lexicon, stream, name='', initial_pos=None): """ Scanner(lexicon, stream, name = '') |lexicon| is a Plex.Lexicon instance specifying the lexical tokens to be recognised. |stream| can be a file object or anything which implements a compatible read() method. |name| is optional, and may be the name of the file being scanned or any other identifying string. """ self.trace = 0 self.buffer = u'' self.buf_start_pos = 0 self.next_pos = 0 self.cur_pos = 0 self.cur_line = 1 self.start_pos = 0 self.start_line = 0 self.start_col = 0 self.text = None self.state_name = None self.lexicon = lexicon self.stream = stream self.name = name self.queue = [] self.initial_state = None self.begin('') self.next_pos = 0 self.cur_pos = 0 self.cur_line_start = 0 self.cur_char = BOL self.input_state = 1 if initial_pos is not None: self.cur_line, self.cur_line_start = initial_pos[1], -initial_pos[2] def read(self): """ Read the next lexical token from the stream and return a tuple (value, text), where |value| is the value associated with the token as specified by the Lexicon, and |text| is the actual string read from the stream. Returns (None, '') on end of file. """ queue = self.queue while not queue: self.text, action = self.scan_a_token() if action is None: self.produce(None) self.eof() else: value = action.perform(self, self.text) if value is not None: self.produce(value) result = queue[0] del queue[0] return result def scan_a_token(self): """ Read the next input sequence recognised by the machine and return (text, action). Returns ('', None) on end of file. """ self.start_pos = self.cur_pos self.start_line = self.cur_line self.start_col = self.cur_pos - self.cur_line_start action = self.run_machine_inlined() if action is not None: if self.trace: print("Scanner: read: Performing %s %d:%d" % ( action, self.start_pos, self.cur_pos)) text = self.buffer[ self.start_pos - self.buf_start_pos: self.cur_pos - self.buf_start_pos] return (text, action) else: if self.cur_pos == self.start_pos: if self.cur_char is EOL: self.next_char() if self.cur_char is None or self.cur_char is EOF: return (u'', None) raise Errors.UnrecognizedInput(self, self.state_name) def run_machine_inlined(self): """ Inlined version of run_machine for speed. """ state = self.initial_state cur_pos = self.cur_pos cur_line = self.cur_line cur_line_start = self.cur_line_start cur_char = self.cur_char input_state = self.input_state next_pos = self.next_pos buffer = self.buffer buf_start_pos = self.buf_start_pos buf_len = len(buffer) b_action, b_cur_pos, b_cur_line, b_cur_line_start, b_cur_char, b_input_state, b_next_pos = \ None, 0, 0, 0, u'', 0, 0 trace = self.trace while 1: if trace: #TRACE# print("State %d, %d/%d:%s -->" % ( #TRACE# state['number'], input_state, cur_pos, repr(cur_char))) #TRACE# # Begin inlined self.save_for_backup() #action = state.action #@slow action = state['action'] #@fast if action is not None: b_action, b_cur_pos, b_cur_line, b_cur_line_start, b_cur_char, b_input_state, b_next_pos = \ action, cur_pos, cur_line, cur_line_start, cur_char, input_state, next_pos # End inlined self.save_for_backup() c = cur_char #new_state = state.new_state(c) #@slow new_state = state.get(c, NOT_FOUND) #@fast if new_state is NOT_FOUND: #@fast new_state = c and state.get('else') #@fast if new_state: if trace: #TRACE# print("State %d" % new_state['number']) #TRACE# state = new_state # Begin inlined: self.next_char() if input_state == 1: cur_pos = next_pos # Begin inlined: c = self.read_char() buf_index = next_pos - buf_start_pos if buf_index < buf_len: c = buffer[buf_index] next_pos += 1 else: discard = self.start_pos - buf_start_pos data = self.stream.read(0x1000) buffer = self.buffer[discard:] + data self.buffer = buffer buf_start_pos += discard self.buf_start_pos = buf_start_pos buf_len = len(buffer) buf_index -= discard if data: c = buffer[buf_index] next_pos += 1 else: c = u'' # End inlined: c = self.read_char() if c == u'\n': cur_char = EOL input_state = 2 elif not c: cur_char = EOL input_state = 4 else: cur_char = c elif input_state == 2: cur_char = u'\n' input_state = 3 elif input_state == 3: cur_line += 1 cur_line_start = cur_pos = next_pos cur_char = BOL input_state = 1 elif input_state == 4: cur_char = EOF input_state = 5 else: # input_state = 5 cur_char = u'' # End inlined self.next_char() else: # not new_state if trace: #TRACE# print("blocked") #TRACE# # Begin inlined: action = self.back_up() if b_action is not None: (action, cur_pos, cur_line, cur_line_start, cur_char, input_state, next_pos) = \ (b_action, b_cur_pos, b_cur_line, b_cur_line_start, b_cur_char, b_input_state, b_next_pos) else: action = None break # while 1 # End inlined: action = self.back_up() self.cur_pos = cur_pos self.cur_line = cur_line self.cur_line_start = cur_line_start self.cur_char = cur_char self.input_state = input_state self.next_pos = next_pos if trace: #TRACE# if action is not None: #TRACE# print("Doing %s" % action) #TRACE# return action def next_char(self): input_state = self.input_state if self.trace: print("Scanner: next: %s [%d] %d" % (" " * 20, input_state, self.cur_pos)) if input_state == 1: self.cur_pos = self.next_pos c = self.read_char() if c == u'\n': self.cur_char = EOL self.input_state = 2 elif not c: self.cur_char = EOL self.input_state = 4 else: self.cur_char = c elif input_state == 2: self.cur_char = u'\n' self.input_state = 3 elif input_state == 3: self.cur_line += 1 self.cur_line_start = self.cur_pos = self.next_pos self.cur_char = BOL self.input_state = 1 elif input_state == 4: self.cur_char = EOF self.input_state = 5 else: # input_state = 5 self.cur_char = u'' if self.trace: print("--> [%d] %d %s" % (input_state, self.cur_pos, repr(self.cur_char))) def position(self): """ Return a tuple (name, line, col) representing the location of the last token read using the read() method. |name| is the name that was provided to the Scanner constructor; |line| is the line number in the stream (1-based); |col| is the position within the line of the first character of the token (0-based). """ return (self.name, self.start_line, self.start_col) def get_position(self): """Python accessible wrapper around position(), only for error reporting. """ return self.position() def begin(self, state_name): """Set the current state of the scanner to the named state.""" self.initial_state = ( self.lexicon.get_initial_state(state_name)) self.state_name = state_name def produce(self, value, text=None): """ Called from an action procedure, causes |value| to be returned as the token value from read(). If |text| is supplied, it is returned in place of the scanned text. produce() can be called more than once during a single call to an action procedure, in which case the tokens are queued up and returned one at a time by subsequent calls to read(), until the queue is empty, whereupon scanning resumes. """ if text is None: text = self.text self.queue.append((value, text)) def eof(self): """ Override this method if you want something to be done at end of file. """ Cython-0.23.4/Cython/Plex/Scanners.pxd0000644000175600017570000000243412606202452020654 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import import cython from Cython.Plex.Actions cimport Action cdef class Scanner: cdef public lexicon cdef public stream cdef public name cdef public unicode buffer cdef public Py_ssize_t buf_start_pos cdef public Py_ssize_t next_pos cdef public Py_ssize_t cur_pos cdef public Py_ssize_t cur_line cdef public Py_ssize_t cur_line_start cdef public Py_ssize_t start_pos cdef public Py_ssize_t start_line cdef public Py_ssize_t start_col cdef public text cdef public initial_state # int? cdef public state_name cdef public list queue cdef public bint trace cdef public cur_char cdef public long input_state cdef public level @cython.locals(input_state=long) cdef next_char(self) @cython.locals(action=Action) cpdef tuple read(self) cdef tuple scan_a_token(self) cdef tuple position(self) @cython.locals(cur_pos=long, cur_line=long, cur_line_start=long, input_state=long, next_pos=long, state=dict, buf_start_pos=long, buf_len=long, buf_index=long, trace=bint, discard=long, data=unicode, buffer=unicode) cdef run_machine_inlined(self) cdef begin(self, state) cdef produce(self, value, text = *) Cython-0.23.4/Cython/Plex/Regexps.py0000644000175600017570000003752012606202452020356 0ustar jenkinsjenkins00000000000000#======================================================================= # # Python Lexical Analyser # # Regular Expressions # #======================================================================= from __future__ import absolute_import import types try: from sys import maxsize as maxint except ImportError: from sys import maxint from . import Errors # # Constants # BOL = 'bol' EOL = 'eol' EOF = 'eof' nl_code = ord('\n') # # Helper functions # def chars_to_ranges(s): """ Return a list of character codes consisting of pairs [code1a, code1b, code2a, code2b,...] which cover all the characters in |s|. """ char_list = list(s) char_list.sort() i = 0 n = len(char_list) result = [] while i < n: code1 = ord(char_list[i]) code2 = code1 + 1 i += 1 while i < n and code2 >= ord(char_list[i]): code2 += 1 i += 1 result.append(code1) result.append(code2) return result def uppercase_range(code1, code2): """ If the range of characters from code1 to code2-1 includes any lower case letters, return the corresponding upper case range. """ code3 = max(code1, ord('a')) code4 = min(code2, ord('z') + 1) if code3 < code4: d = ord('A') - ord('a') return (code3 + d, code4 + d) else: return None def lowercase_range(code1, code2): """ If the range of characters from code1 to code2-1 includes any upper case letters, return the corresponding lower case range. """ code3 = max(code1, ord('A')) code4 = min(code2, ord('Z') + 1) if code3 < code4: d = ord('a') - ord('A') return (code3 + d, code4 + d) else: return None def CodeRanges(code_list): """ Given a list of codes as returned by chars_to_ranges, return an RE which will match a character in any of the ranges. """ re_list = [CodeRange(code_list[i], code_list[i + 1]) for i in range(0, len(code_list), 2)] return Alt(*re_list) def CodeRange(code1, code2): """ CodeRange(code1, code2) is an RE which matches any character with a code |c| in the range |code1| <= |c| < |code2|. """ if code1 <= nl_code < code2: return Alt(RawCodeRange(code1, nl_code), RawNewline, RawCodeRange(nl_code + 1, code2)) else: return RawCodeRange(code1, code2) # # Abstract classes # class RE(object): """RE is the base class for regular expression constructors. The following operators are defined on REs: re1 + re2 is an RE which matches |re1| followed by |re2| re1 | re2 is an RE which matches either |re1| or |re2| """ nullable = 1 # True if this RE can match 0 input symbols match_nl = 1 # True if this RE can match a string ending with '\n' str = None # Set to a string to override the class's __str__ result def build_machine(self, machine, initial_state, final_state, match_bol, nocase): """ This method should add states to |machine| to implement this RE, starting at |initial_state| and ending at |final_state|. If |match_bol| is true, the RE must be able to match at the beginning of a line. If nocase is true, upper and lower case letters should be treated as equivalent. """ raise NotImplementedError("%s.build_machine not implemented" % self.__class__.__name__) def build_opt(self, m, initial_state, c): """ Given a state |s| of machine |m|, return a new state reachable from |s| on character |c| or epsilon. """ s = m.new_state() initial_state.link_to(s) initial_state.add_transition(c, s) return s def __add__(self, other): return Seq(self, other) def __or__(self, other): return Alt(self, other) def __str__(self): if self.str: return self.str else: return self.calc_str() def check_re(self, num, value): if not isinstance(value, RE): self.wrong_type(num, value, "Plex.RE instance") def check_string(self, num, value): if type(value) != type(''): self.wrong_type(num, value, "string") def check_char(self, num, value): self.check_string(num, value) if len(value) != 1: raise Errors.PlexValueError("Invalid value for argument %d of Plex.%s." "Expected a string of length 1, got: %s" % ( num, self.__class__.__name__, repr(value))) def wrong_type(self, num, value, expected): if type(value) == types.InstanceType: got = "%s.%s instance" % ( value.__class__.__module__, value.__class__.__name__) else: got = type(value).__name__ raise Errors.PlexTypeError("Invalid type for argument %d of Plex.%s " "(expected %s, got %s" % ( num, self.__class__.__name__, expected, got)) # # Primitive RE constructors # ------------------------- # # These are the basic REs from which all others are built. # ## class Char(RE): ## """ ## Char(c) is an RE which matches the character |c|. ## """ ## nullable = 0 ## def __init__(self, char): ## self.char = char ## self.match_nl = char == '\n' ## def build_machine(self, m, initial_state, final_state, match_bol, nocase): ## c = self.char ## if match_bol and c != BOL: ## s1 = self.build_opt(m, initial_state, BOL) ## else: ## s1 = initial_state ## if c == '\n' or c == EOF: ## s1 = self.build_opt(m, s1, EOL) ## if len(c) == 1: ## code = ord(self.char) ## s1.add_transition((code, code+1), final_state) ## if nocase and is_letter_code(code): ## code2 = other_case_code(code) ## s1.add_transition((code2, code2+1), final_state) ## else: ## s1.add_transition(c, final_state) ## def calc_str(self): ## return "Char(%s)" % repr(self.char) def Char(c): """ Char(c) is an RE which matches the character |c|. """ if len(c) == 1: result = CodeRange(ord(c), ord(c) + 1) else: result = SpecialSymbol(c) result.str = "Char(%s)" % repr(c) return result class RawCodeRange(RE): """ RawCodeRange(code1, code2) is a low-level RE which matches any character with a code |c| in the range |code1| <= |c| < |code2|, where the range does not include newline. For internal use only. """ nullable = 0 match_nl = 0 range = None # (code, code) uppercase_range = None # (code, code) or None lowercase_range = None # (code, code) or None def __init__(self, code1, code2): self.range = (code1, code2) self.uppercase_range = uppercase_range(code1, code2) self.lowercase_range = lowercase_range(code1, code2) def build_machine(self, m, initial_state, final_state, match_bol, nocase): if match_bol: initial_state = self.build_opt(m, initial_state, BOL) initial_state.add_transition(self.range, final_state) if nocase: if self.uppercase_range: initial_state.add_transition(self.uppercase_range, final_state) if self.lowercase_range: initial_state.add_transition(self.lowercase_range, final_state) def calc_str(self): return "CodeRange(%d,%d)" % (self.code1, self.code2) class _RawNewline(RE): """ RawNewline is a low-level RE which matches a newline character. For internal use only. """ nullable = 0 match_nl = 1 def build_machine(self, m, initial_state, final_state, match_bol, nocase): if match_bol: initial_state = self.build_opt(m, initial_state, BOL) s = self.build_opt(m, initial_state, EOL) s.add_transition((nl_code, nl_code + 1), final_state) RawNewline = _RawNewline() class SpecialSymbol(RE): """ SpecialSymbol(sym) is an RE which matches the special input symbol |sym|, which is one of BOL, EOL or EOF. """ nullable = 0 match_nl = 0 sym = None def __init__(self, sym): self.sym = sym def build_machine(self, m, initial_state, final_state, match_bol, nocase): # Sequences 'bol bol' and 'bol eof' are impossible, so only need # to allow for bol if sym is eol if match_bol and self.sym == EOL: initial_state = self.build_opt(m, initial_state, BOL) initial_state.add_transition(self.sym, final_state) class Seq(RE): """Seq(re1, re2, re3...) is an RE which matches |re1| followed by |re2| followed by |re3|...""" def __init__(self, *re_list): nullable = 1 for i, re in enumerate(re_list): self.check_re(i, re) nullable = nullable and re.nullable self.re_list = re_list self.nullable = nullable i = len(re_list) match_nl = 0 while i: i -= 1 re = re_list[i] if re.match_nl: match_nl = 1 break if not re.nullable: break self.match_nl = match_nl def build_machine(self, m, initial_state, final_state, match_bol, nocase): re_list = self.re_list if len(re_list) == 0: initial_state.link_to(final_state) else: s1 = initial_state n = len(re_list) for i, re in enumerate(re_list): if i < n - 1: s2 = m.new_state() else: s2 = final_state re.build_machine(m, s1, s2, match_bol, nocase) s1 = s2 match_bol = re.match_nl or (match_bol and re.nullable) def calc_str(self): return "Seq(%s)" % ','.join(map(str, self.re_list)) class Alt(RE): """Alt(re1, re2, re3...) is an RE which matches either |re1| or |re2| or |re3|...""" def __init__(self, *re_list): self.re_list = re_list nullable = 0 match_nl = 0 nullable_res = [] non_nullable_res = [] i = 1 for re in re_list: self.check_re(i, re) if re.nullable: nullable_res.append(re) nullable = 1 else: non_nullable_res.append(re) if re.match_nl: match_nl = 1 i += 1 self.nullable_res = nullable_res self.non_nullable_res = non_nullable_res self.nullable = nullable self.match_nl = match_nl def build_machine(self, m, initial_state, final_state, match_bol, nocase): for re in self.nullable_res: re.build_machine(m, initial_state, final_state, match_bol, nocase) if self.non_nullable_res: if match_bol: initial_state = self.build_opt(m, initial_state, BOL) for re in self.non_nullable_res: re.build_machine(m, initial_state, final_state, 0, nocase) def calc_str(self): return "Alt(%s)" % ','.join(map(str, self.re_list)) class Rep1(RE): """Rep1(re) is an RE which matches one or more repetitions of |re|.""" def __init__(self, re): self.check_re(1, re) self.re = re self.nullable = re.nullable self.match_nl = re.match_nl def build_machine(self, m, initial_state, final_state, match_bol, nocase): s1 = m.new_state() s2 = m.new_state() initial_state.link_to(s1) self.re.build_machine(m, s1, s2, match_bol or self.re.match_nl, nocase) s2.link_to(s1) s2.link_to(final_state) def calc_str(self): return "Rep1(%s)" % self.re class SwitchCase(RE): """ SwitchCase(re, nocase) is an RE which matches the same strings as RE, but treating upper and lower case letters according to |nocase|. If |nocase| is true, case is ignored, otherwise it is not. """ re = None nocase = None def __init__(self, re, nocase): self.re = re self.nocase = nocase self.nullable = re.nullable self.match_nl = re.match_nl def build_machine(self, m, initial_state, final_state, match_bol, nocase): self.re.build_machine(m, initial_state, final_state, match_bol, self.nocase) def calc_str(self): if self.nocase: name = "NoCase" else: name = "Case" return "%s(%s)" % (name, self.re) # # Composite RE constructors # ------------------------- # # These REs are defined in terms of the primitive REs. # Empty = Seq() Empty.__doc__ = \ """ Empty is an RE which matches the empty string. """ Empty.str = "Empty" def Str1(s): """ Str1(s) is an RE which matches the literal string |s|. """ result = Seq(*tuple(map(Char, s))) result.str = "Str(%s)" % repr(s) return result def Str(*strs): """ Str(s) is an RE which matches the literal string |s|. Str(s1, s2, s3, ...) is an RE which matches any of |s1| or |s2| or |s3|... """ if len(strs) == 1: return Str1(strs[0]) else: result = Alt(*tuple(map(Str1, strs))) result.str = "Str(%s)" % ','.join(map(repr, strs)) return result def Any(s): """ Any(s) is an RE which matches any character in the string |s|. """ #result = apply(Alt, tuple(map(Char, s))) result = CodeRanges(chars_to_ranges(s)) result.str = "Any(%s)" % repr(s) return result def AnyBut(s): """ AnyBut(s) is an RE which matches any character (including newline) which is not in the string |s|. """ ranges = chars_to_ranges(s) ranges.insert(0, -maxint) ranges.append(maxint) result = CodeRanges(ranges) result.str = "AnyBut(%s)" % repr(s) return result AnyChar = AnyBut("") AnyChar.__doc__ = \ """ AnyChar is an RE which matches any single character (including a newline). """ AnyChar.str = "AnyChar" def Range(s1, s2=None): """ Range(c1, c2) is an RE which matches any single character in the range |c1| to |c2| inclusive. Range(s) where |s| is a string of even length is an RE which matches any single character in the ranges |s[0]| to |s[1]|, |s[2]| to |s[3]|,... """ if s2: result = CodeRange(ord(s1), ord(s2) + 1) result.str = "Range(%s,%s)" % (s1, s2) else: ranges = [] for i in range(0, len(s1), 2): ranges.append(CodeRange(ord(s1[i]), ord(s1[i + 1]) + 1)) result = Alt(*ranges) result.str = "Range(%s)" % repr(s1) return result def Opt(re): """ Opt(re) is an RE which matches either |re| or the empty string. """ result = Alt(re, Empty) result.str = "Opt(%s)" % re return result def Rep(re): """ Rep(re) is an RE which matches zero or more repetitions of |re|. """ result = Opt(Rep1(re)) result.str = "Rep(%s)" % re return result def NoCase(re): """ NoCase(re) is an RE which matches the same strings as RE, but treating upper and lower case letters as equivalent. """ return SwitchCase(re, nocase=1) def Case(re): """ Case(re) is an RE which matches the same strings as RE, but treating upper and lower case letters as distinct, i.e. it cancels the effect of any enclosing NoCase(). """ return SwitchCase(re, nocase=0) # # RE Constants # Bol = Char(BOL) Bol.__doc__ = \ """ Bol is an RE which matches the beginning of a line. """ Bol.str = "Bol" Eol = Char(EOL) Eol.__doc__ = \ """ Eol is an RE which matches the end of a line. """ Eol.str = "Eol" Eof = Char(EOF) Eof.__doc__ = \ """ Eof is an RE which matches the end of the file. """ Eof.str = "Eof" Cython-0.23.4/Cython/Plex/Machines.py0000644000175600017570000002056112606202452020465 0ustar jenkinsjenkins00000000000000#======================================================================= # # Python Lexical Analyser # # Classes for building NFAs and DFAs # #======================================================================= from __future__ import absolute_import import sys from .Transitions import TransitionMap try: from sys import maxsize as maxint except ImportError: from sys import maxint try: unichr except NameError: unichr = chr LOWEST_PRIORITY = -maxint class Machine(object): """A collection of Nodes representing an NFA or DFA.""" states = None # [Node] next_state_number = 1 initial_states = None # {(name, bol): Node} def __init__(self): self.states = [] self.initial_states = {} def __del__(self): #print "Destroying", self ### for state in self.states: state.destroy() def new_state(self): """Add a new state to the machine and return it.""" s = Node() n = self.next_state_number self.next_state_number = n + 1 s.number = n self.states.append(s) return s def new_initial_state(self, name): state = self.new_state() self.make_initial_state(name, state) return state def make_initial_state(self, name, state): self.initial_states[name] = state def get_initial_state(self, name): return self.initial_states[name] def dump(self, file): file.write("Plex.Machine:\n") if self.initial_states is not None: file.write(" Initial states:\n") for (name, state) in sorted(self.initial_states.items()): file.write(" '%s': %d\n" % (name, state.number)) for s in self.states: s.dump(file) class Node(object): """A state of an NFA or DFA.""" transitions = None # TransitionMap action = None # Action action_priority = None # integer number = 0 # for debug output epsilon_closure = None # used by nfa_to_dfa() def __init__(self): # Preinitialise the list of empty transitions, because # the nfa-to-dfa algorithm needs it #self.transitions = {'':[]} self.transitions = TransitionMap() self.action_priority = LOWEST_PRIORITY def destroy(self): #print "Destroying", self ### self.transitions = None self.action = None self.epsilon_closure = None def add_transition(self, event, new_state): self.transitions.add(event, new_state) def link_to(self, state): """Add an epsilon-move from this state to another state.""" self.add_transition('', state) def set_action(self, action, priority): """Make this an accepting state with the given action. If there is already an action, choose the action with highest priority.""" if priority > self.action_priority: self.action = action self.action_priority = priority def get_action(self): return self.action def get_action_priority(self): return self.action_priority def is_accepting(self): return self.action is not None def __str__(self): return "State %d" % self.number def dump(self, file): # Header file.write(" State %d:\n" % self.number) # Transitions # self.dump_transitions(file) self.transitions.dump(file) # Action action = self.action priority = self.action_priority if action is not None: file.write(" %s [priority %d]\n" % (action, priority)) def __lt__(self, other): return self.number < other.number class FastMachine(object): """ FastMachine is a deterministic machine represented in a way that allows fast scanning. """ initial_states = None # {state_name:state} states = None # [state] where state = {event:state, 'else':state, 'action':Action} next_number = 1 # for debugging new_state_template = { '': None, 'bol': None, 'eol': None, 'eof': None, 'else': None } def __init__(self, old_machine=None): self.initial_states = initial_states = {} self.states = [] if old_machine: self.old_to_new = old_to_new = {} for old_state in old_machine.states: new_state = self.new_state() old_to_new[old_state] = new_state for name, old_state in old_machine.initial_states.items(): initial_states[name] = old_to_new[old_state] for old_state in old_machine.states: new_state = old_to_new[old_state] for event, old_state_set in old_state.transitions.items(): if old_state_set: new_state[event] = old_to_new[old_state_set.keys()[0]] else: new_state[event] = None new_state['action'] = old_state.action def __del__(self): for state in self.states: state.clear() def new_state(self, action=None): number = self.next_number self.next_number = number + 1 result = self.new_state_template.copy() result['number'] = number result['action'] = action self.states.append(result) return result def make_initial_state(self, name, state): self.initial_states[name] = state def add_transitions(self, state, event, new_state, maxint=maxint): if type(event) is tuple: code0, code1 = event if code0 == -maxint: state['else'] = new_state elif code1 != maxint: while code0 < code1: state[unichr(code0)] = new_state code0 += 1 else: state[event] = new_state def get_initial_state(self, name): return self.initial_states[name] def dump(self, file): file.write("Plex.FastMachine:\n") file.write(" Initial states:\n") for name, state in sorted(self.initial_states.items()): file.write(" %s: %s\n" % (repr(name), state['number'])) for state in self.states: self.dump_state(state, file) def dump_state(self, state, file): # Header file.write(" State %d:\n" % state['number']) # Transitions self.dump_transitions(state, file) # Action action = state['action'] if action is not None: file.write(" %s\n" % action) def dump_transitions(self, state, file): chars_leading_to_state = {} special_to_state = {} for (c, s) in state.items(): if len(c) == 1: chars = chars_leading_to_state.get(id(s), None) if chars is None: chars = [] chars_leading_to_state[id(s)] = chars chars.append(c) elif len(c) <= 4: special_to_state[c] = s ranges_to_state = {} for state in self.states: char_list = chars_leading_to_state.get(id(state), None) if char_list: ranges = self.chars_to_ranges(char_list) ranges_to_state[ranges] = state ranges_list = ranges_to_state.keys() ranges_list.sort() for ranges in ranges_list: key = self.ranges_to_string(ranges) state = ranges_to_state[ranges] file.write(" %s --> State %d\n" % (key, state['number'])) for key in ('bol', 'eol', 'eof', 'else'): state = special_to_state.get(key, None) if state: file.write(" %s --> State %d\n" % (key, state['number'])) def chars_to_ranges(self, char_list): char_list.sort() i = 0 n = len(char_list) result = [] while i < n: c1 = ord(char_list[i]) c2 = c1 i += 1 while i < n and ord(char_list[i]) == c2 + 1: i += 1 c2 += 1 result.append((chr(c1), chr(c2))) return tuple(result) def ranges_to_string(self, range_list): return ','.join(map(self.range_to_string, range_list)) def range_to_string(self, range_tuple): (c1, c2) = range_tuple if c1 == c2: return repr(c1) else: return "%s..%s" % (repr(c1), repr(c2)) Cython-0.23.4/Cython/Plex/Lexicons.py0000644000175600017570000001537312606202452020527 0ustar jenkinsjenkins00000000000000#======================================================================= # # Python Lexical Analyser # # Lexical Analyser Specification # #======================================================================= from __future__ import absolute_import import types from . import Actions from . import DFA from . import Errors from . import Machines from . import Regexps # debug_flags for Lexicon constructor DUMP_NFA = 1 DUMP_DFA = 2 class State(object): """ This class is used as part of a Plex.Lexicon specification to introduce a user-defined state. Constructor: State(name, token_specifications) """ name = None tokens = None def __init__(self, name, tokens): self.name = name self.tokens = tokens class Lexicon(object): """ Lexicon(specification) builds a lexical analyser from the given |specification|. The specification consists of a list of specification items. Each specification item may be either: 1) A token definition, which is a tuple: (pattern, action) The |pattern| is a regular axpression built using the constructors defined in the Plex module. The |action| is the action to be performed when this pattern is recognised (see below). 2) A state definition: State(name, tokens) where |name| is a character string naming the state, and |tokens| is a list of token definitions as above. The meaning and usage of states is described below. Actions ------- The |action| in a token specication may be one of three things: 1) A function, which is called as follows: function(scanner, text) where |scanner| is the relevant Scanner instance, and |text| is the matched text. If the function returns anything other than None, that value is returned as the value of the token. If it returns None, scanning continues as if the IGNORE action were specified (see below). 2) One of the following special actions: IGNORE means that the recognised characters will be treated as white space and ignored. Scanning will continue until the next non-ignored token is recognised before returning. TEXT causes the scanned text itself to be returned as the value of the token. 3) Any other value, which is returned as the value of the token. States ------ At any given time, the scanner is in one of a number of states. Associated with each state is a set of possible tokens. When scanning, only tokens associated with the current state are recognised. There is a default state, whose name is the empty string. Token definitions which are not inside any State definition belong to the default state. The initial state of the scanner is the default state. The state can be changed in one of two ways: 1) Using Begin(state_name) as the action of a token. 2) Calling the begin(state_name) method of the Scanner. To change back to the default state, use '' as the state name. """ machine = None # Machine tables = None # StateTableMachine def __init__(self, specifications, debug=None, debug_flags=7, timings=None): if not isinstance(specifications, list): raise Errors.InvalidScanner("Scanner definition is not a list") if timings: from .Timing import time total_time = 0.0 time1 = time() nfa = Machines.Machine() default_initial_state = nfa.new_initial_state('') token_number = 1 for spec in specifications: if isinstance(spec, State): user_initial_state = nfa.new_initial_state(spec.name) for token in spec.tokens: self.add_token_to_machine( nfa, user_initial_state, token, token_number) token_number += 1 elif isinstance(spec, tuple): self.add_token_to_machine( nfa, default_initial_state, spec, token_number) token_number += 1 else: raise Errors.InvalidToken( token_number, "Expected a token definition (tuple) or State instance") if timings: time2 = time() total_time = total_time + (time2 - time1) time3 = time() if debug and (debug_flags & 1): debug.write("\n============= NFA ===========\n") nfa.dump(debug) dfa = DFA.nfa_to_dfa(nfa, debug=(debug_flags & 3) == 3 and debug) if timings: time4 = time() total_time = total_time + (time4 - time3) if debug and (debug_flags & 2): debug.write("\n============= DFA ===========\n") dfa.dump(debug) if timings: timings.write("Constructing NFA : %5.2f\n" % (time2 - time1)) timings.write("Converting to DFA: %5.2f\n" % (time4 - time3)) timings.write("TOTAL : %5.2f\n" % total_time) self.machine = dfa def add_token_to_machine(self, machine, initial_state, token_spec, token_number): try: (re, action_spec) = self.parse_token_definition(token_spec) # Disabled this -- matching empty strings can be useful #if re.nullable: # raise Errors.InvalidToken( # token_number, "Pattern can match 0 input symbols") if isinstance(action_spec, Actions.Action): action = action_spec else: try: action_spec.__call__ except AttributeError: action = Actions.Return(action_spec) else: action = Actions.Call(action_spec) final_state = machine.new_state() re.build_machine(machine, initial_state, final_state, match_bol=1, nocase=0) final_state.set_action(action, priority=-token_number) except Errors.PlexError as e: raise e.__class__("Token number %d: %s" % (token_number, e)) def parse_token_definition(self, token_spec): if not isinstance(token_spec, tuple): raise Errors.InvalidToken("Token definition is not a tuple") if len(token_spec) != 2: raise Errors.InvalidToken("Wrong number of items in token definition") pattern, action = token_spec if not isinstance(pattern, Regexps.RE): raise Errors.InvalidToken("Pattern is not an RE instance") return (pattern, action) def get_initial_state(self, name): return self.machine.get_initial_state(name) Cython-0.23.4/Cython/Plex/Errors.py0000644000175600017570000000222112606202452020203 0ustar jenkinsjenkins00000000000000#======================================================================= # # Python Lexical Analyser # # Exception classes # #======================================================================= class PlexError(Exception): message = "" class PlexTypeError(PlexError, TypeError): pass class PlexValueError(PlexError, ValueError): pass class InvalidRegex(PlexError): pass class InvalidToken(PlexError): def __init__(self, token_number, message): PlexError.__init__(self, "Token number %d: %s" % (token_number, message)) class InvalidScanner(PlexError): pass class AmbiguousAction(PlexError): message = "Two tokens with different actions can match the same string" def __init__(self): pass class UnrecognizedInput(PlexError): scanner = None position = None state_name = None def __init__(self, scanner, state_name): self.scanner = scanner self.position = scanner.get_position() self.state_name = state_name def __str__(self): return ("'%s', line %d, char %d: Token not recognised in state %r" % ( self.position + (self.state_name,))) Cython-0.23.4/Cython/Plex/DFA.py0000644000175600017570000001357412606202452017336 0ustar jenkinsjenkins00000000000000#======================================================================= # # Python Lexical Analyser # # Converting NFA to DFA # #======================================================================= from __future__ import absolute_import from . import Machines from .Machines import LOWEST_PRIORITY from .Transitions import TransitionMap def nfa_to_dfa(old_machine, debug=None): """ Given a nondeterministic Machine, return a new equivalent Machine which is deterministic. """ # We build a new machine whose states correspond to sets of states # in the old machine. Initially we add a new state corresponding to # the epsilon-closure of each initial old state. Then we give transitions # to each new state which are the union of all transitions out of any # of the corresponding old states. The new state reached on a given # character is the one corresponding to the set of states reachable # on that character from any of the old states. As new combinations of # old states are created, new states are added as needed until closure # is reached. new_machine = Machines.FastMachine() state_map = StateMap(new_machine) # Seed the process using the initial states of the old machine. # Make the corresponding new states into initial states of the new # machine with the same names. for (key, old_state) in old_machine.initial_states.items(): new_state = state_map.old_to_new(epsilon_closure(old_state)) new_machine.make_initial_state(key, new_state) # Tricky bit here: we add things to the end of this list while we're # iterating over it. The iteration stops when closure is achieved. for new_state in new_machine.states: transitions = TransitionMap() for old_state in state_map.new_to_old(new_state): for event, old_target_states in old_state.transitions.items(): if event and old_target_states: transitions.add_set(event, set_epsilon_closure(old_target_states)) for event, old_states in transitions.items(): new_machine.add_transitions(new_state, event, state_map.old_to_new(old_states)) if debug: debug.write("\n===== State Mapping =====\n") state_map.dump(debug) return new_machine def set_epsilon_closure(state_set): """ Given a set of states, return the union of the epsilon closures of its member states. """ result = {} for state1 in state_set: for state2 in epsilon_closure(state1): result[state2] = 1 return result def epsilon_closure(state): """ Return the set of states reachable from the given state by epsilon moves. """ # Cache the result result = state.epsilon_closure if result is None: result = {} state.epsilon_closure = result add_to_epsilon_closure(result, state) return result def add_to_epsilon_closure(state_set, state): """ Recursively add to |state_set| states reachable from the given state by epsilon moves. """ if not state_set.get(state, 0): state_set[state] = 1 state_set_2 = state.transitions.get_epsilon() if state_set_2: for state2 in state_set_2: add_to_epsilon_closure(state_set, state2) class StateMap(object): """ Helper class used by nfa_to_dfa() to map back and forth between sets of states from the old machine and states of the new machine. """ new_machine = None # Machine old_to_new_dict = None # {(old_state,...) : new_state} new_to_old_dict = None # {id(new_state) : old_state_set} def __init__(self, new_machine): self.new_machine = new_machine self.old_to_new_dict = {} self.new_to_old_dict = {} def old_to_new(self, old_state_set): """ Return the state of the new machine corresponding to the set of old machine states represented by |state_set|. A new state will be created if necessary. If any of the old states are accepting states, the new state will be an accepting state with the highest priority action from the old states. """ key = self.make_key(old_state_set) new_state = self.old_to_new_dict.get(key, None) if not new_state: action = self.highest_priority_action(old_state_set) new_state = self.new_machine.new_state(action) self.old_to_new_dict[key] = new_state self.new_to_old_dict[id(new_state)] = old_state_set #for old_state in old_state_set.keys(): #new_state.merge_actions(old_state) return new_state def highest_priority_action(self, state_set): best_action = None best_priority = LOWEST_PRIORITY for state in state_set: priority = state.action_priority if priority > best_priority: best_action = state.action best_priority = priority return best_action # def old_to_new_set(self, old_state_set): # """ # Return the new state corresponding to a set of old states as # a singleton set. # """ # return {self.old_to_new(old_state_set):1} def new_to_old(self, new_state): """Given a new state, return a set of corresponding old states.""" return self.new_to_old_dict[id(new_state)] def make_key(self, state_set): """ Convert a set of states into a uniquified sorted tuple suitable for use as a dictionary key. """ lst = list(state_set) lst.sort() return tuple(lst) def dump(self, file): from .Transitions import state_set_str for new_state in self.new_machine.states: old_state_set = self.new_to_old_dict[id(new_state)] file.write(" State %s <-- %s\n" % ( new_state['number'], state_set_str(old_state_set))) Cython-0.23.4/Cython/Plex/Actions.py0000644000175600017570000000472512606202452020342 0ustar jenkinsjenkins00000000000000#======================================================================= # # Python Lexical Analyser # # Actions for use in token specifications # #======================================================================= class Action(object): def perform(self, token_stream, text): pass # abstract def same_as(self, other): return self is other class Return(Action): """ Internal Plex action which causes |value| to be returned as the value of the associated token """ def __init__(self, value): self.value = value def perform(self, token_stream, text): return self.value def same_as(self, other): return isinstance(other, Return) and self.value == other.value def __repr__(self): return "Return(%s)" % repr(self.value) class Call(Action): """ Internal Plex action which causes a function to be called. """ def __init__(self, function): self.function = function def perform(self, token_stream, text): return self.function(token_stream, text) def __repr__(self): return "Call(%s)" % self.function.__name__ def same_as(self, other): return isinstance(other, Call) and self.function is other.function class Begin(Action): """ Begin(state_name) is a Plex action which causes the Scanner to enter the state |state_name|. See the docstring of Plex.Lexicon for more information. """ def __init__(self, state_name): self.state_name = state_name def perform(self, token_stream, text): token_stream.begin(self.state_name) def __repr__(self): return "Begin(%s)" % self.state_name def same_as(self, other): return isinstance(other, Begin) and self.state_name == other.state_name class Ignore(Action): """ IGNORE is a Plex action which causes its associated token to be ignored. See the docstring of Plex.Lexicon for more information. """ def perform(self, token_stream, text): return None def __repr__(self): return "IGNORE" IGNORE = Ignore() #IGNORE.__doc__ = Ignore.__doc__ class Text(Action): """ TEXT is a Plex action which causes the text of a token to be returned as the value of the token. See the docstring of Plex.Lexicon for more information. """ def perform(self, token_stream, text): return text def __repr__(self): return "TEXT" TEXT = Text() #TEXT.__doc__ = Text.__doc__ Cython-0.23.4/Cython/Plex/Actions.pxd0000644000175600017570000000111112606202452020467 0ustar jenkinsjenkins00000000000000 cdef class Action: cdef perform(self, token_stream, text) cpdef same_as(self, other) cdef class Return(Action): cdef object value cdef perform(self, token_stream, text) cpdef same_as(self, other) cdef class Call(Action): cdef object function cdef perform(self, token_stream, text) cpdef same_as(self, other) cdef class Begin(Action): cdef object state_name cdef perform(self, token_stream, text) cpdef same_as(self, other) cdef class Ignore(Action): cdef perform(self, token_stream, text) cdef class Text(Action): cdef perform(self, token_stream, text) Cython-0.23.4/Cython/Parser/0000755000175600017570000000000012606202455016707 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Parser/__init__.py0000644000175600017570000000000012606202452021003 0ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Parser/Grammar0000644000175600017570000002366312606202452020227 0ustar jenkinsjenkins00000000000000# Grammar for Cython, based on the Grammar for Python 3 # Note: This grammar is not yet used by the Cython parser and is subject to change. # Start symbols for the grammar: # single_input is a single interactive statement; # file_input is a module or sequence of commands read from an input file; # eval_input is the input for the eval() functions. # NB: compound_stmt in single_input is followed by extra NEWLINE! single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE file_input: (NEWLINE | stmt)* ENDMARKER eval_input: testlist NEWLINE* ENDMARKER decorator: '@' dotted_PY_NAME [ '(' [arglist] ')' ] NEWLINE decorators: decorator+ decorated: decorators (classdef | funcdef | async_funcdef | cdef_stmt) async_funcdef: 'async' funcdef funcdef: 'def' PY_NAME parameters ['->' test] ':' suite parameters: '(' [typedargslist] ')' typedargslist: (tfpdef ['=' (test | '*')] (',' tfpdef ['=' (test | '*')])* [',' ['*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef]] | '*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef) [',' ellipsis] tfpdef: maybe_typed_name [('not' | 'or') 'None'] [':' test] varargslist: (vfpdef ['=' test] (',' vfpdef ['=' test])* [',' ['*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef]] | '*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef) vfpdef: maybe_typed_name ['not' 'None'] stmt: simple_stmt | compound_stmt | cdef_stmt | ctypedef_stmt | DEF_stmt | IF_stmt simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | nonlocal_stmt | assert_stmt | print_stmt) expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | ('=' (yield_expr|testlist_star_expr))*) testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=') print_stmt: 'print' ( [ test (',' test)* [','] ] | '>>' test [ (',' test)+ [','] ] ) # For normal assignments, additional restrictions enforced by the interpreter del_stmt: 'del' exprlist pass_stmt: 'pass' flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt break_stmt: 'break' continue_stmt: 'continue' return_stmt: 'return' [testlist] yield_stmt: yield_expr raise_stmt: 'raise' [test ['from' test]] # raise_stmt: 'raise' [test [',' test [',' test]]] import_stmt: import_PY_NAME | import_from import_PY_NAME: ('import' | 'cimport') dotted_as_PY_NAMEs # note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS import_from: ('from' (('.' | '...')* dotted_PY_NAME | ('.' | '...')+) ('import' | 'cimport') ('*' | '(' import_as_PY_NAMEs ')' | import_as_PY_NAMEs)) import_as_PY_NAME: PY_NAME ['as' PY_NAME] dotted_as_PY_NAME: dotted_PY_NAME ['as' PY_NAME] import_as_PY_NAMEs: import_as_PY_NAME (',' import_as_PY_NAME)* [','] dotted_as_PY_NAMEs: dotted_as_PY_NAME (',' dotted_as_PY_NAME)* dotted_PY_NAME: PY_NAME ('.' PY_NAME)* global_stmt: 'global' PY_NAME (',' PY_NAME)* nonlocal_stmt: 'nonlocal' PY_NAME (',' PY_NAME)* exec_stmt: 'exec' expr ['in' test [',' test]] assert_stmt: 'assert' test [',' test] compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] while_stmt: 'while' test ':' suite ['else' ':' suite] for_stmt: 'for' exprlist ('in' testlist | for_from_clause)':' suite ['else' ':' suite] for_from_clause: 'from' expr comp_op PY_NAME comp_op expr ['by' expr] try_stmt: ('try' ':' suite ((except_clause ':' suite)+ ['else' ':' suite] ['finally' ':' suite] | 'finally' ':' suite)) with_stmt: 'with' with_item (',' with_item)* ':' suite with_item: test ['as' expr] # NB compile.c makes sure that the default except clause is last except_clause: 'except' [test [('as' | ',') test]] suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT test: or_test ['if' or_test 'else' test] | lambdef test_nocond: or_test | lambdef_nocond lambdef: 'lambda' [varargslist] ':' test lambdef_nocond: 'lambda' [varargslist] ':' test_nocond or_test: and_test ('or' and_test)* and_test: not_test ('and' not_test)* not_test: 'not' not_test | comparison comparison: expr (comp_op expr)* # <> isn't actually a valid comparison operator in Python. It's here for the # sake of a __future__ import described in PEP 401 comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' star_expr: '*' expr expr: xor_expr ('|' xor_expr)* xor_expr: and_expr ('^' and_expr)* and_expr: shift_expr ('&' shift_expr)* shift_expr: arith_expr (('<<'|'>>') arith_expr)* arith_expr: term (('+'|'-') term)* term: factor (('*'|'/'|'%'|'//') factor)* factor: ('+'|'-'|'~') factor | power | address | size_of | cast power: atom_expr ['**' factor] atom_expr: ['await'] atom trailer* atom: ('(' [yield_expr|testlist_comp] ')' | '[' [testlist_comp] ']' | '{' [dictorsetmaker] '}' | new_expr | PY_NAME | NUMBER | STRING+ | ellipsis | 'None' | 'True' | 'False') testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' (PY_NAME | 'sizeof') subscriptlist: subscript (',' subscript)* [','] subscript: test | [test] ':' [test] [sliceop] sliceop: ':' [test] exprlist: (expr|star_expr) (',' (expr|star_expr))* [','] testlist: test (',' test)* [','] dictorsetmaker: ( ((test ':' test | '**' expr) (comp_for | (',' (test ':' test | '**' expr))* [','])) | ((test | star_expr) (comp_for | (',' (test | star_expr))* [','])) ) classdef: 'class' PY_NAME ['(' [arglist] ')'] ':' suite arglist: argument (',' argument)* [','] # The reason that keywords are test nodes instead of NAME is that using NAME # results in an ambiguity. ast.c makes sure it's a NAME. # "test '=' test" is really "keyword '=' test", but we have no such token. # These need to be in a single rule to avoid grammar that is ambiguous # to our LL(1) parser. Even though 'test' includes '*expr' in star_expr, # we explicitly match '*' here, too, to give it proper precedence. # Illegal combinations and orderings are blocked in ast.c: # multiple (test comp_for) arguements are blocked; keyword unpackings # that precede iterable unpackings are blocked; etc. argument: ( test [comp_for] | test '=' test | '**' expr | star_expr ) comp_iter: comp_for | comp_if comp_for: 'for' exprlist ('in' or_test | for_from_clause) [comp_iter] comp_if: 'if' test_nocond [comp_iter] # not used in grammar, but may appear in "node" passed from Parser to Compiler encoding_decl: NAME yield_expr: 'yield' [yield_arg] yield_arg: 'from' test | testlist # Cython extensions # Accommodate to Py2 tokenizer. ellipsis: '...' | '.' '.' '.' signedness: 'unsigned' | 'signed' longness: 'char' | 'short' | 'long' | 'long' 'long' # TODO: [unsigned] double doesn't make sens, but we need long double int_type: signedness [longness] | longness | [signedness] [longness] ('int' | 'double') | 'complex' type: ['const'] (NAME ('.' PY_NAME)* | int_type | '(' type ')') ['complex'] [type_qualifiers] maybe_typed_name: ['const'] (NAME [('.' PY_NAME)* ['complex'] [type_qualifiers] NAME] | (int_type | '(' type ')') ['complex'] [type_qualifiers] NAME) teplate_params: '[' NAME (',' NAME)* ']' type_qualifiers: type_qualifier+ type_qualifier: '*' | '**' | '&' | type_index ('.' NAME [type_index])* # TODO: old buffer syntax type_index: '[' [(NUMBER | type (',' type)* | (memory_view_index (',' memory_view_index)*))] ']' memory_view_index: ':' [':'] [NUMBER] address: '&' factor cast: '<' type ['?'] '>' factor size_of: 'sizeof' '(' (type) ')' new_expr: 'new' type '(' [arglist] ')' # TODO: Restrict cdef_stmt to "top-level" statements. cdef_stmt: ('cdef' | 'cpdef') (cvar_def | cdef_type_decl | extern_block) cdef_type_decl: ctype_decl | fused | cclass ctype_decl: struct | enum | cppclass # TODO: Does the cdef/ctypedef distinction even make sense for fused? ctypedef_stmt: 'ctypedef' (cvar_decl | struct | enum | fused) # Note: these two are similar but can't be used in an or clause # as it would cause ambiguity in the LL(1) parser. # Requires a type cvar_decl: [visibility] type cname (NEWLINE | cfunc) # Allows an assignment cvar_def: [visibility] maybe_typed_name (['=' test] (',' PY_NAME ['=' test])* NEWLINE | cfunc) visibility: 'public' | 'api' | 'readonly' # TODO: Standardize gil_spec first or last. cfunc: [teplate_params] parameters [gil_spec] [exception_value] [gil_spec] (':' suite | NEWLINE) exception_value: 'except' (['?'] expr | '*' | '+' [PY_NAME]) gil_spec: 'with' ('gil' | 'nogil') | 'nogil' cname: NAME [STRING] cclass: classdef fused: 'fused' PY_NAME ':' NEWLINE INDENT ( type NEWLINE)+ DEDENT enum: 'enum' [cname] (NEWLINE | ':' enum_suite) enum_suite: NEWLINE INDENT (cname ['=' NUMBER] NEWLINE | pass_stmt NEWLINE)+ DEDENT struct: ('struct' | 'union') cname (NEWLINE | (':' struct_suite)) struct_suite: NEWLINE INDENT (cvar_decl | pass_stmt NEWLINE)+ DEDENT cppclass: 'cppclass' cname [teplate_params] [cppclass_bases] (NEWLINE | ':' cppclass_suite) cppclass_bases: '(' dotted_PY_NAME (',' dotted_PY_NAME [teplate_params])*')' cppclass_suite: NEWLINE INDENT (cvar_decl | ctype_decl | pass_stmt NEWLINE)+ DEDENT # TODO: C++ constructors, operators extern_block: 'extern' (cvar_decl | 'from' ('*' | STRING) ['namespace' STRING] [gil_spec] ':' (pass_stmt | extern_suite)) extern_suite: NEWLINE INDENT (['cdef' | 'cpdef'] (cvar_decl | cdef_type_decl) | ctypedef_stmt)+ DEDENT cy_type_kwd: 'struct' | 'union' | 'fused' | 'cppclass' | 'int' | 'double' | 'complex' cy_kwd: cy_type_kwd | signedness | longness | visibility | 'gil' | 'nogil' | 'namespace' | 'const' | 'by' | 'extern' PY_NAME: NAME | cy_kwd # TODO: Do we really want these? Don't play well with include... DEF_stmt: 'DEF' NAME '=' testlist IF_stmt: 'IF' test ':' suite ('ELIF' test ':' suite)* ['ELSE' ':' suite] Cython-0.23.4/Cython/Parser/ConcreteSyntaxTree.pyx0000644000175600017570000000507612606202452023247 0ustar jenkinsjenkins00000000000000cdef extern from "graminit.c": ctypedef struct grammar: pass cdef grammar _PyParser_Grammar cdef int Py_file_input cdef extern from "node.h": ctypedef struct node void PyNode_Free(node* n) int NCH(node* n) node* CHILD(node* n, int ix) node* RCHILD(node* n, int ix) short TYPE(node* n) char* STR(node* n) cdef extern from "parsetok.h": ctypedef struct perrdetail: pass cdef void PyParser_SetError(perrdetail *err) except * cdef node * PyParser_ParseStringFlagsFilenameEx( const char * s, const char * filename, grammar * g, int start, perrdetail * err_ret, int * flags) import distutils.sysconfig import os import re def extract_names(path): # All parse tree types are #defined in these files as ints. type_names = {} for line in open(path): if line.startswith('#define'): try: _, name, value = line.strip().split() type_names[int(value)] = name except: pass return type_names cdef dict type_names = {} cdef print_tree(node* n, indent=""): if not type_names: type_names.update(extract_names( os.path.join(distutils.sysconfig.get_python_inc(), 'token.h'))) type_names.update(extract_names( os.path.join(os.path.dirname(__file__), 'graminit.h'))) print indent, type_names.get(TYPE(n), 'unknown'), STR(n) if NCH(n) == 0 else NCH(n) indent += " " for i in range(NCH(n)): print_tree(CHILD(n, i), indent) def handle_includes(source, path): # TODO: Use include directory. def include_here(include_line): included = os.path.join(os.path.dirname(path), include_line.group(1)[1:-1]) if not os.path.exists(included): return include_line.group(0) + ' # no such path: ' + included return handle_includes(open(included).read(), path) # TODO: Proper string tokenizing. return re.sub(r'^include\s+([^\n]+[\'"])\s*(#.*)?$', include_here, source, flags=re.M) def p_module(path): cdef perrdetail err cdef int flags cdef node* n source = open(path).read() if '\ninclude ' in source: # TODO: Tokanizer needs to understand includes. source = handle_includes(source, path) path = "preparse(%s)" % path n = PyParser_ParseStringFlagsFilenameEx( source, path, &_PyParser_Grammar, Py_file_input, &err, &flags) if n: # print_tree(n) PyNode_Free(n) else: PyParser_SetError(&err) Cython-0.23.4/Cython/Includes/0000755000175600017570000000000012606202455017221 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Includes/openmp.pxd0000644000175600017570000000325712606202452021240 0ustar jenkinsjenkins00000000000000cdef extern from "omp.h": ctypedef struct omp_lock_t: pass ctypedef struct omp_nest_lock_t: pass ctypedef enum omp_sched_t: omp_sched_static = 1, omp_sched_dynamic = 2, omp_sched_guided = 3, omp_sched_auto = 4 extern void omp_set_num_threads(int) nogil extern int omp_get_num_threads() nogil extern int omp_get_max_threads() nogil extern int omp_get_thread_num() nogil extern int omp_get_num_procs() nogil extern int omp_in_parallel() nogil extern void omp_set_dynamic(int) nogil extern int omp_get_dynamic() nogil extern void omp_set_nested(int) nogil extern int omp_get_nested() nogil extern void omp_init_lock(omp_lock_t *) nogil extern void omp_destroy_lock(omp_lock_t *) nogil extern void omp_set_lock(omp_lock_t *) nogil extern void omp_unset_lock(omp_lock_t *) nogil extern int omp_test_lock(omp_lock_t *) nogil extern void omp_init_nest_lock(omp_nest_lock_t *) nogil extern void omp_destroy_nest_lock(omp_nest_lock_t *) nogil extern void omp_set_nest_lock(omp_nest_lock_t *) nogil extern void omp_unset_nest_lock(omp_nest_lock_t *) nogil extern int omp_test_nest_lock(omp_nest_lock_t *) nogil extern double omp_get_wtime() nogil extern double omp_get_wtick() nogil void omp_set_schedule(omp_sched_t, int) nogil void omp_get_schedule(omp_sched_t *, int *) nogil int omp_get_thread_limit() nogil void omp_set_max_active_levels(int) nogil int omp_get_max_active_levels() nogil int omp_get_level() nogil int omp_get_ancestor_thread_num(int) nogil int omp_get_team_size(int) nogil int omp_get_active_level() nogil Cython-0.23.4/Cython/Includes/posix/0000755000175600017570000000000012606202455020363 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Includes/posix/wait.pxd0000644000175600017570000000233212606202452022041 0ustar jenkinsjenkins00000000000000# http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/wait.h.html from posix.types cimport pid_t, id_t from posix.signal cimport siginfo_t from posix.resource cimport rusage cdef extern from "sys/wait.h" nogil: enum: WNOHANG enum: WUNTRACED enum: WCONTINUED enum: WEXITED enum: WSTOPPED enum: WNOWAIT int WEXITSTATUS(int status) int WIFCONTINUED(int status) int WIFEXITED(int status) int WIFSIGNALED(int status) int WIFSTOPPED(int status) int WSTOPSIG(int status) int WTERMSIG(int status) ctypedef int idtype_t enum: P_ALL # idtype_t values enum: P_PID enum: P_PGID pid_t wait(int *stat_loc) pid_t waitpid(pid_t pid, int *status, int options) int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options) # wait3 was in POSIX until 2008 while wait4 was never standardized. # Even so, these calls are in almost every Unix, always in sys/wait.h. # Hence, posix.wait is the least surprising place to declare them for Cython. # libc may require _XXX_SOURCE to be defined at C-compile time to provide them. pid_t wait3(int *status, int options, rusage *rusage) pid_t wait4(pid_t pid, int *status, int options, rusage *rusage) Cython-0.23.4/Cython/Includes/posix/unistd.pxd0000644000175600017570000001757312606202452022420 0ustar jenkinsjenkins00000000000000# http://www.opengroup.org/onlinepubs/009695399/basedefs/unistd.h.html from posix.types cimport gid_t, pid_t, off_t, uid_t cdef extern from "unistd.h" nogil: #:NULL enum: R_OK enum: W_OK enum: X_OK enum: F_OK enum: _CS_PATH enum: _CS_POSIX_V6_ILP32_OFF32_CFLAGS enum: _CS_POSIX_V6_ILP32_OFF32_LDFLAGS enum: _CS_POSIX_V6_ILP32_OFF32_LIBS enum: _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS enum: _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS enum: _CS_POSIX_V6_ILP32_OFFBIG_LIBS enum: _CS_POSIX_V6_LP64_OFF64_CFLAGS enum: _CS_POSIX_V6_LP64_OFF64_LDFLAGS enum: _CS_POSIX_V6_LP64_OFF64_LIBS enum: _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS enum: _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS enum: _CS_POSIX_V6_LPBIG_OFFBIG_LIBS enum: _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS enum: SEEK_SET enum: SEEK_CUR enum: SEEK_END enum: F_LOCK enum: F_TEST enum: F_TLOCK enum: F_ULOCK enum: _PC_2_SYMLINKS enum: _PC_ALLOC_SIZE_MIN enum: _PC_ASYNC_IO enum: _PC_CHOWN_RESTRICTED enum: _PC_FILESIZEBITS enum: _PC_LINK_MAX enum: _PC_MAX_CANON enum: _PC_MAX_INPUT enum: _PC_NAME_MAX enum: _PC_NO_TRUNC enum: _PC_PATH_MAX enum: _PC_PIPE_BUF enum: _PC_PRIO_IO enum: _PC_REC_INCR_XFER_SIZE enum: _PC_REC_MIN_XFER_SIZE enum: _PC_REC_XFER_ALIGN enum: _PC_SYMLINK_MAX enum: _PC_SYNC_IO enum: _PC_VDISABLE enum: _SC_2_C_BIND enum: _SC_2_C_DEV enum: _SC_2_CHAR_TERM enum: _SC_2_FORT_DEV enum: _SC_2_FORT_RUN enum: _SC_2_LOCALEDEF enum: _SC_2_PBS enum: _SC_2_PBS_ACCOUNTING enum: _SC_2_PBS_CHECKPOINT enum: _SC_2_PBS_LOCATE enum: _SC_2_PBS_MESSAGE enum: _SC_2_PBS_TRACK enum: _SC_2_SW_DEV enum: _SC_2_UPE enum: _SC_2_VERSION enum: _SC_ADVISORY_INFO enum: _SC_AIO_LISTIO_MAX enum: _SC_AIO_MAX enum: _SC_AIO_PRIO_DELTA_MAX enum: _SC_ARG_MAX enum: _SC_ASYNCHRONOUS_IO enum: _SC_ATEXIT_MAX enum: _SC_BARRIERS enum: _SC_BC_BASE_MAX enum: _SC_BC_DIM_MAX enum: _SC_BC_SCALE_MAX enum: _SC_BC_STRING_MAX enum: _SC_CHILD_MAX enum: _SC_CLK_TCK enum: _SC_CLOCK_SELECTION enum: _SC_COLL_WEIGHTS_MAX enum: _SC_CPUTIME enum: _SC_DELAYTIMER_MAX enum: _SC_EXPR_NEST_MAX enum: _SC_FSYNC enum: _SC_GETGR_R_SIZE_MAX enum: _SC_GETPW_R_SIZE_MAX enum: _SC_HOST_NAME_MAX enum: _SC_IOV_MAX enum: _SC_IPV6 enum: _SC_JOB_CONTROL enum: _SC_LINE_MAX enum: _SC_LOGIN_NAME_MAX enum: _SC_MAPPED_FILES enum: _SC_MEMLOCK enum: _SC_MEMLOCK_RANGE enum: _SC_MEMORY_PROTECTION enum: _SC_MESSAGE_PASSING enum: _SC_MONOTONIC_CLOCK enum: _SC_MQ_OPEN_MAX enum: _SC_MQ_PRIO_MAX enum: _SC_NGROUPS_MAX enum: _SC_OPEN_MAX enum: _SC_PAGE_SIZE enum: _SC_PAGESIZE enum: _SC_PRIORITIZED_IO enum: _SC_PRIORITY_SCHEDULING enum: _SC_RAW_SOCKETS enum: _SC_RE_DUP_MAX enum: _SC_READER_WRITER_LOCKS enum: _SC_REALTIME_SIGNALS enum: _SC_REGEXP enum: _SC_RTSIG_MAX enum: _SC_SAVED_IDS enum: _SC_SEM_NSEMS_MAX enum: _SC_SEM_VALUE_MAX enum: _SC_SEMAPHORES enum: _SC_SHARED_MEMORY_OBJECTS enum: _SC_SHELL enum: _SC_SIGQUEUE_MAX enum: _SC_SPAWN enum: _SC_SPIN_LOCKS enum: _SC_SPORADIC_SERVER enum: _SC_SS_REPL_MAX enum: _SC_STREAM_MAX enum: _SC_SYMLOOP_MAX enum: _SC_SYNCHRONIZED_IO enum: _SC_THREAD_ATTR_STACKADDR enum: _SC_THREAD_ATTR_STACKSIZE enum: _SC_THREAD_CPUTIME enum: _SC_THREAD_DESTRUCTOR_ITERATIONS enum: _SC_THREAD_KEYS_MAX enum: _SC_THREAD_PRIO_INHERIT enum: _SC_THREAD_PRIO_PROTECT enum: _SC_THREAD_PRIORITY_SCHEDULING enum: _SC_THREAD_PROCESS_SHARED enum: _SC_THREAD_SAFE_FUNCTIONS enum: _SC_THREAD_SPORADIC_SERVER enum: _SC_THREAD_STACK_MIN enum: _SC_THREAD_THREADS_MAX enum: _SC_THREADS enum: _SC_TIMEOUTS enum: _SC_TIMER_MAX enum: _SC_TIMERS enum: _SC_TRACE enum: _SC_TRACE_EVENT_FILTER enum: _SC_TRACE_EVENT_NAME_MAX enum: _SC_TRACE_INHERIT enum: _SC_TRACE_LOG enum: _SC_TRACE_NAME_MAX enum: _SC_TRACE_SYS_MAX enum: _SC_TRACE_USER_EVENT_MAX enum: _SC_TTY_NAME_MAX enum: _SC_TYPED_MEMORY_OBJECTS enum: _SC_TZNAME_MAX enum: _SC_V6_ILP32_OFF32 enum: _SC_V6_ILP32_OFFBIG enum: _SC_V6_LP64_OFF64 enum: _SC_V6_LPBIG_OFFBIG enum: _SC_VERSION enum: _SC_XBS5_ILP32_OFF32 enum: _SC_XBS5_ILP32_OFFBIG enum: _SC_XBS5_LP64_OFF64 enum: _SC_XBS5_LPBIG_OFFBIG enum: _SC_XOPEN_CRYPT enum: _SC_XOPEN_ENH_I18N enum: _SC_XOPEN_LEGACY enum: _SC_XOPEN_REALTIME enum: _SC_XOPEN_REALTIME_THREADS enum: _SC_XOPEN_SHM enum: _SC_XOPEN_STREAMS enum: _SC_XOPEN_UNIX enum: _SC_XOPEN_VERSION enum: STDIN_FILENO #0 enum: STDOUT_FILENO #1 enum: STDERR_FILENO #2 ctypedef unsigned useconds_t int access(const char *, int) unsigned alarm(unsigned) int chdir(const char *) int chown(const char *, uid_t, gid_t) int close(int) size_t confstr(int, char *, size_t) char *crypt(const char *, const char *) char *ctermid(char *) int dup(int) int dup2(int, int) void encrypt(char[64], int) int execl(const char *, const char *, ...) int execle(const char *, const char *, ...) int execlp(const char *, const char *, ...) int execv(const char *, char *[]) int execve(const char *, char *[], char *[]) int execvp(const char *, char *[]) void _exit(int) int fchown(int, uid_t, gid_t) int fchdir(int) int fdatasync(int) pid_t fork() long fpathconf(int, int) int fsync(int) int ftruncate(int, off_t) char *getcwd(char *, size_t) gid_t getegid() uid_t geteuid() gid_t getgid() int getgroups(int, gid_t []) long gethostid() int gethostname(char *, size_t) char *getlogin() int getlogin_r(char *, size_t) int getopt(int, char * [], const char *) pid_t getpgid(pid_t) pid_t getpgrp() pid_t getpid() pid_t getppid() pid_t getsid(pid_t) uid_t getuid() char *getwd(char *) int isatty(int) int lchown(const char *, uid_t, gid_t) int link(const char *, const char *) int lockf(int, int, off_t) off_t lseek(int, off_t, int) int nice(int) long pathconf(char *, int) int pause() int pipe(int [2]) ssize_t pread(int, void *, size_t, off_t) ssize_t pwrite(int, const void *, size_t, off_t) ssize_t read(int, void *, size_t) ssize_t readlink(const char *, char *, size_t) int rmdir(const char *) int setegid(gid_t) int seteuid(uid_t) int setgid(gid_t) int setpgid(pid_t, pid_t) pid_t setpgrp() int setregid(gid_t, gid_t) int setreuid(uid_t, uid_t) pid_t setsid() int setuid(uid_t) unsigned sleep(unsigned) void swab(const void *, void *, ssize_t) int symlink(const char *, const char *) void sync() long sysconf(int) pid_t tcgetpgrp(int) int tcsetpgrp(int, pid_t) int truncate(const char *, off_t) char *ttyname(int) int ttyname_r(int, char *, size_t) useconds_t ualarm(useconds_t, useconds_t) int unlink(const char *) int usleep(useconds_t) pid_t vfork() ssize_t write(int, const void *, size_t) char *optarg int optind int opterr int optopt Cython-0.23.4/Cython/Includes/posix/types.pxd0000644000175600017570000000217012606202452022241 0ustar jenkinsjenkins00000000000000# Note that the actual size of these types is system-dependant, and # can't be detected at C compile time. However, the generated C code # will correctly use the actual size of these types *except* for # determining promotion in binary arithmetic expressions involving # mixed types. In this case, operands are promoted to the declared # larger type, with a bias towards typedef types. Thus, with the # declarations below, long + time_t will result in a time_t whereas # long long + time_t will result in a long long which should be # acceptable for either 32-bit or 64-bit signed time_t (though admittedly # the POSIX standard doesn't even specify that time_t must be an integral # type). cdef extern from "sys/types.h": ctypedef long blkcnt_t ctypedef long blksize_t ctypedef long clockid_t ctypedef long dev_t ctypedef long gid_t ctypedef long id_t ctypedef unsigned long ino_t ctypedef long mode_t ctypedef long nlink_t ctypedef long off_t ctypedef long pid_t ctypedef long sigset_t ctypedef long suseconds_t ctypedef long time_t ctypedef long timer_t ctypedef long uid_t Cython-0.23.4/Cython/Includes/posix/time.pxd0000644000175600017570000000400012606202452022025 0ustar jenkinsjenkins00000000000000# http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/time.h.html from posix.types cimport suseconds_t, time_t, clockid_t, timer_t from posix.signal cimport sigevent cdef extern from "sys/time.h" nogil: enum: CLOCK_PROCESS_CPUTIME_ID enum: CLOCK_THREAD_CPUTIME_ID enum: CLOCK_REALTIME enum: TIMER_ABSTIME enum: CLOCK_MONOTONIC # FreeBSD-specific clocks enum: CLOCK_UPTIME enum: CLOCK_UPTIME_PRECISE enum: CLOCK_UPTIME_FAST enum: CLOCK_REALTIME_PRECISE enum: CLOCK_REALTIME_FAST enum: CLOCK_MONOTONIC_PRECISE enum: CLOCK_MONOTONIC_FAST enum: CLOCK_SECOND # Linux-specific clocks enum: CLOCK_PROCESS_CPUTIME_ID enum: CLOCK_THREAD_CPUTIME_ID enum: CLOCK_MONOTONIC_RAW enum: CLOCK_REALTIME_COARSE enum: CLOCK_MONOTONIC_COARSE enum: CLOCK_BOOTTIME enum: CLOCK_REALTIME_ALARM enum: CLOCK_BOOTTIME_ALARM enum: ITIMER_REAL enum: ITIMER_VIRTUAL enum: ITIMER_PROF cdef struct timezone: int tz_minuteswest int dsttime cdef struct timeval: time_t tv_sec suseconds_t tv_usec cdef struct timespec: time_t tv_sec long tv_nsec cdef struct itimerval: timeval it_interval timeval it_value cdef struct itimerspec: timespec it_interval timespec it_value int nanosleep(const timespec *, timespec *) int getitimer(int, itimerval *) int gettimeofday(timeval *tp, timezone *tzp) int setitimer(int, const itimerval *, itimerval *) int clock_getcpuclockid(pid_t, clockid_t *) int clock_getres(clockid_t, timespec *) int clock_gettime(clockid_t, timespec *) int clock_nanosleep(clockid_t, int, const timespec *, timespec *) int clock_settime(clockid_t, const timespec *) int timer_create(clockid_t, sigevent *, timer_t *) int timer_delete(timer_t) int timer_gettime(timer_t, itimerspec *) int timer_getoverrun(timer_t) int timer_settime(timer_t, int, const itimerspec *, itimerspec *) Cython-0.23.4/Cython/Includes/posix/strings.pxd0000644000175600017570000000056412606202452022573 0ustar jenkinsjenkins00000000000000cdef extern from "strings.h" nogil: int bcmp(const void *, const void *, size_t) void bcopy(const void *, void *, size_t) void bzero(void *, size_t) int ffs(int) char *index(const char *, int) char *rindex(const char *, int) int strcasecmp(const char *, const char *) int strncasecmp(const char *, const char *, size_t) Cython-0.23.4/Cython/Includes/posix/stdlib.pxd0000644000175600017570000000164412606202452022363 0ustar jenkinsjenkins00000000000000# POSIX additions to # http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdlib.h.html cdef extern from "stdlib.h" nogil: void _Exit(int) double drand48() double erand48(unsigned short *) int getsubopt(char **, char *const *, char **) void lcong48(unsigned short *) long lrand() char *mkdtemp(char *) int mkstemp(char *) long mrand() long nrand48(unsigned short *) int posix_memalign(void **, size_t, size_t) int posix_openpt(int) char *ptsname(int) int putenv(char *) int rand_r(unsigned *) long random() char *realpath(const char *, char *) unsigned short *seed48(unsigned short *) int setenv(const char *, const char *, int) void setkey(const char *) char *setstate(char *) void srand48(long) void srandom(unsigned) int unlockpt(int) int unsetenv(const char *) Cython-0.23.4/Cython/Includes/posix/stat.pxd0000644000175600017570000000273112606202452022053 0ustar jenkinsjenkins00000000000000from posix.types cimport (blkcnt_t, blksize_t, dev_t, gid_t, ino_t, mode_t, nlink_t, off_t, time_t, uid_t) cdef extern from "sys/stat.h" nogil: cdef struct struct_stat "stat": dev_t st_dev ino_t st_ino mode_t st_mode nlink_t st_nlink uid_t st_uid gid_t st_gid dev_t st_rdev off_t st_size blksize_t st_blksize blkcnt_t st_blocks time_t st_atime time_t st_mtime time_t st_ctime # POSIX prescribes including both and for these cdef extern from "unistd.h" nogil: int fchmod(int, mode_t) int chmod(const char *, mode_t) int fstat(int, struct_stat *) int lstat(const char *, struct_stat *) int stat(const char *, struct_stat *) # Macros for st_mode mode_t S_ISREG(mode_t) mode_t S_ISDIR(mode_t) mode_t S_ISCHR(mode_t) mode_t S_ISBLK(mode_t) mode_t S_ISFIFO(mode_t) mode_t S_ISLNK(mode_t) mode_t S_ISSOCK(mode_t) mode_t S_IFMT mode_t S_IFREG mode_t S_IFDIR mode_t S_IFCHR mode_t S_IFBLK mode_t S_IFIFO mode_t S_IFLNK mode_t S_IFSOCK # Permissions mode_t S_ISUID mode_t S_ISGID mode_t S_ISVTX mode_t S_IRWXU mode_t S_IRUSR mode_t S_IWUSR mode_t S_IXUSR mode_t S_IRWXG mode_t S_IRGRP mode_t S_IWGRP mode_t S_IXGRP mode_t S_IRWXO mode_t S_IROTH mode_t S_IWOTH mode_t S_IXOTH Cython-0.23.4/Cython/Includes/posix/signal.pxd0000644000175600017570000000327712606202452022363 0ustar jenkinsjenkins00000000000000# 7.14 Signal handling from posix.types cimport pid_t, sigset_t, uid_t cdef extern from "signal.h" nogil: cdef union sigval: int sival_int void *sival_ptr cdef struct sigevent: int sigev_notify int sigev_signo sigval sigev_value void *sigev_notify_function(sigval) ctypedef struct siginfo_t: int si_signo int si_code int si_errno pid_t si_pid uid_t si_uid void *si_addr int si_status long si_band sigval si_value cdef struct sigaction_t "sigaction": void *sa_handler(int) sigset_t sa_mask int sa_flags void sa_sigaction(int, siginfo_t *, void *) enum: SA_NOCLDSTOP enum: SIG_BLOCK enum: SIG_UNBLOCK enum: SIG_SETMASK enum: SA_ONSTACK enum: SA_RESETHAND enum: SA_RESTART enum: SA_SIGINFO enum: SA_NOCLDWAIT enum: SA_NODEFER enum: SS_ONSTACK enum: SS_DISABLE enum: MINSIGSTKSZ enum: SIGSTKSZ enum: SIGEV_NONE enum: SIGEV_SIGNAL enum: SIGEV_THREAD enum: SIGEV_THREAD_ID int kill (pid_t, int) int killpg (pid_t, int) int sigaction (int, const sigaction_t *, sigaction_t *) int sigpending (sigset_t *) int sigprocmask (int, const sigset_t *, sigset_t *) int sigsuspend (const sigset_t *) int sigaddset (sigset_t *, int) int sigdelset (sigset_t *, int) int sigemptyset (sigset_t *) int sigfillset (sigset_t *) int sigismember (const sigset_t *) Cython-0.23.4/Cython/Includes/posix/resource.pxd0000644000175600017570000000234412606202452022727 0ustar jenkinsjenkins00000000000000# http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/resource.h.html from posix.time cimport timeval from posix.types cimport id_t cdef extern from "sys/resource.h" nogil: enum: PRIO_PROCESS enum: PRIO_PGRP enum: PRIO_USER enum: RLIM_INFINITY enum: RLIM_SAVED_MAX enum: RLIM_SAVED_CUR enum: RUSAGE_SELF enum: RUSAGE_CHILDREN enum: RLIMIT_CORE enum: RLIMIT_CPU enum: RLIMIT_DATA enum: RLIMIT_FSIZE enum: RLIMIT_NOFILE enum: RLIMIT_STACK enum: RLIMIT_AS ctypedef unsigned long rlim_t cdef struct rlimit: rlim_t rlim_cur rlim_t rlim_max cdef struct rusage: timeval ru_utime timeval ru_stime long ru_maxrss long ru_ixrss long ru_idrss long ru_isrss long ru_minflt long ru_majflt long ru_nswap long ru_inblock long ru_oublock long ru_msgsnd long ru_msgrcv long ru_nsignals long ru_nvcsw long ru_nivcsw int getpriority(int, id_t) int getrlimit(int, rlimit *) int getrusage(int, rusage *) int setpriority(int, id_t, int) int setrlimit(int, const rlimit *) Cython-0.23.4/Cython/Includes/posix/mman.pxd0000644000175600017570000000531212606202452022026 0ustar jenkinsjenkins00000000000000# http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/mman.h.html from posix.types cimport off_t, mode_t cdef extern from "sys/mman.h" nogil: enum: PROT_EXEC # protection bits for mmap/mprotect enum: PROT_READ enum: PROT_WRITE enum: PROT_NONE enum: MAP_PRIVATE # flag bits for mmap enum: MAP_SHARED enum: MAP_FIXED enum: MAP_ANON # These three are not in POSIX, but are enum: MAP_ANONYMOUS # fairly common in spelling/semantics enum: MAP_STACK enum: MAP_LOCKED # Typically available only on Linux enum: MAP_HUGETLB enum: MAP_POPULATE enum: MAP_NORESERVE enum: MAP_GROWSDOWN enum: MAP_NOCORE # Typically available only on BSD enum: MAP_NOSYNC void *mmap(void *addr, size_t Len, int prot, int flags, int fd, off_t off) int munmap(void *addr, size_t Len) int mprotect(void *addr, size_t Len, int prot) enum: MS_ASYNC enum: MS_SYNC enum: MS_INVALIDATE int msync(void *addr, size_t Len, int flags) enum: POSIX_MADV_NORMAL # POSIX advice flags enum: POSIX_MADV_SEQUENTIAL enum: POSIX_MADV_RANDOM enum: POSIX_MADV_WILLNEED enum: POSIX_MADV_DONTNEED int posix_madvise(void *addr, size_t Len, int advice) enum: MCL_CURRENT enum: MCL_FUTURE int mlock(const void *addr, size_t Len) int munlock(const void *addr, size_t Len) int mlockall(int flags) int munlockall() int shm_open(const char *name, int oflag, mode_t mode) int shm_unlink(const char *name) # often available enum: MADV_REMOVE # pre-POSIX advice flags; often available enum: MADV_DONTFORK enum: MADV_DOFORK enum: MADV_HWPOISON enum: MADV_MERGEABLE, enum: MADV_UNMERGEABLE int madvise(void *addr, size_t Len, int advice) # sometimes available int mincore(void *addr, size_t Len, unsigned char *vec) # These two are Linux specific but sometimes very efficient void *mremap(void *old_addr, size_t old_len, size_t new_len, int flags, ...) int remap_file_pages(void *addr, size_t Len, int prot, size_t pgoff, int flags) # The rare but standardized typed memory option enum: POSIX_TYPED_MEM_ALLOCATE enum: POSIX_TYPED_MEM_ALLOCATE_CONTIG enum: POSIX_TYPED_MEM_MAP_ALLOCATABLE int posix_typed_mem_open(const char *name, int oflag, int tflag) int posix_mem_offset(const void *addr, size_t Len, off_t *off, size_t *contig_len, int *fildes) cdef struct posix_typed_mem_info: size_t posix_tmi_length int posix_typed_mem_get_info(int fildes, posix_typed_mem_info *info) Cython-0.23.4/Cython/Includes/posix/ioctl.pxd0000644000175600017570000000014112606202452022203 0ustar jenkinsjenkins00000000000000cdef extern from "sys/ioctl.h" nogil: enum: FIONBIO int ioctl(int fd, int request, ...) Cython-0.23.4/Cython/Includes/posix/fcntl.pxd0000644000175600017570000000222512606202452022204 0ustar jenkinsjenkins00000000000000# http://www.opengroup.org/onlinepubs/009695399/basedefs/fcntl.h.html cdef extern from "fcntl.h" nogil: enum: F_DUPFD enum: F_GETFD enum: F_SETFD enum: F_GETFL enum: F_SETFL enum: F_GETLK enum: F_SETLK enum: F_SETLKW enum: F_GETOWN enum: F_SETOWN enum: FD_CLOEXEC enum: F_RDLCK enum: F_UNLCK enum: F_WRLCK enum: SEEK_SET enum: SEEK_CUR enum: SEEK_END enum: O_CREAT enum: O_EXCL enum: O_NOCTTY enum: O_TRUNC enum: O_APPEND enum: O_DSYNC enum: O_NONBLOCK enum: O_RSYNC enum: O_SYNC enum: O_ACCMODE # O_RDONLY|O_WRONLY|O_RDWR enum: O_RDONLY enum: O_WRONLY enum: O_RDWR enum: S_IFMT enum: S_IFBLK enum: S_IFCHR enum: S_IFIFO enum: S_IFREG enum: S_IFDIR enum: S_IFLNK enum: S_IFSOCK ctypedef int mode_t ctypedef signed pid_t ctypedef signed off_t struct flock: short l_type short l_whence off_t l_start off_t l_len pid_t l_pid int creat(char *, mode_t) int fcntl(int, int, ...) int open(char *, int, ...) #int open (char *, int, mode_t) Cython-0.23.4/Cython/Includes/posix/__init__.pxd0000644000175600017570000000001512606202452022630 0ustar jenkinsjenkins00000000000000# empty file Cython-0.23.4/Cython/Includes/numpy/0000755000175600017570000000000012606202455020371 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Includes/numpy/math.pxd0000644000175600017570000001305012606202452022033 0ustar jenkinsjenkins00000000000000# NumPy math library # # This exports the functionality of the NumPy core math library, aka npymath, # which provides implementations of C99 math functions and macros for system # with a C89 library (such as MSVC). npymath is available with NumPy >=1.3, # although some functions will require later versions. The spacing function is # not in C99, but comes from Fortran. # # On the Cython side, the npymath functions are available without the "npy_" # prefix that they have in C, to make this is a drop-in replacement for # libc.math. The same is true for the constants, where possible. # # See the NumPy documentation for linking instructions. # # Complex number support and NumPy 2.0 half-precision functions are currently # not exported. # # Author: Lars Buitinck cdef extern from "numpy/npy_math.h" nogil: # Floating-point classification long double NAN "NPY_NAN" long double INFINITY "NPY_INFINITY" long double PZERO "NPY_PZERO" # positive zero long double NZERO "NPY_NZERO" # negative zero # These four are actually macros and work on any floating-point type. bint isfinite "npy_isfinite"(long double) bint isinf "npy_isinf"(long double) bint isnan "npy_isnan"(long double) bint signbit "npy_signbit"(long double) # Math constants long double E "NPY_E" long double LOG2E "NPY_LOG2E" # ln(e) / ln(2) long double LOG10E "NPY_LOG10E" # ln(e) / ln(10) long double LOGE2 "NPY_LOGE2" # ln(2) long double LOGE10 "NPY_LOGE10" # ln(10) long double PI "NPY_PI" long double PI_2 "NPY_PI_2" # pi / 2 long double PI_4 "NPY_PI_4" # pi / 4 long double NPY_1_PI # 1 / pi; NPY_ because of ident syntax long double NPY_2_PI # 2 / pi long double EULER "NPY_EULER" # Euler constant (gamma, 0.57721) # Low-level floating point manipulation (NumPy >=1.4) float copysignf "npy_copysignf"(float, float) float nextafterf "npy_nextafterf"(float x, float y) float spacingf "npy_spacingf"(float x) double copysign "npy_copysign"(double, double) double nextafter "npy_nextafter"(double x, double y) double spacing "npy_spacing"(double x) long double copysignl "npy_copysignl"(long double, long double) long double nextafterl "npy_nextafterl"(long double x, long double y) long double spacingl "npy_spacingl"(long double x) # Float C99 functions float sinf "npy_sinf"(float x) float cosf "npy_cosf"(float x) float tanf "npy_tanf"(float x) float sinhf "npy_sinhf"(float x) float coshf "npy_coshf"(float x) float tanhf "npy_tanhf"(float x) float fabsf "npy_fabsf"(float x) float floorf "npy_floorf"(float x) float ceilf "npy_ceilf"(float x) float rintf "npy_rintf"(float x) float sqrtf "npy_sqrtf"(float x) float log10f "npy_log10f"(float x) float logf "npy_logf"(float x) float expf "npy_expf"(float x) float expm1f "npy_expm1f"(float x) float asinf "npy_asinf"(float x) float acosf "npy_acosf"(float x) float atanf "npy_atanf"(float x) float asinhf "npy_asinhf"(float x) float acoshf "npy_acoshf"(float x) float atanhf "npy_atanhf"(float x) float log1pf "npy_log1pf"(float x) float exp2f "npy_exp2f"(float x) float log2f "npy_log2f"(float x) float atan2f "npy_atan2f"(float x) float hypotf "npy_hypotf"(float x) float powf "npy_powf"(float x) float fmodf "npy_fmodf"(float x) float modff "npy_modff"(float x) # Long double C99 functions long double sinl "npy_sinl"(long double x) long double cosl "npy_cosl"(long double x) long double tanl "npy_tanl"(long double x) long double sinhl "npy_sinhl"(long double x) long double coshl "npy_coshl"(long double x) long double tanhl "npy_tanhl"(long double x) long double fabsl "npy_fabsl"(long double x) long double floorl "npy_floorl"(long double x) long double ceill "npy_ceill"(long double x) long double rintl "npy_rintl"(long double x) long double sqrtl "npy_sqrtl"(long double x) long double log10l "npy_log10l"(long double x) long double logl "npy_logl"(long double x) long double expl "npy_expl"(long double x) long double expm1l "npy_expm1l"(long double x) long double asinl "npy_asinl"(long double x) long double acosl "npy_acosl"(long double x) long double atanl "npy_atanl"(long double x) long double asinhl "npy_asinhl"(long double x) long double acoshl "npy_acoshl"(long double x) long double atanhl "npy_atanhl"(long double x) long double log1pl "npy_log1pl"(long double x) long double exp2l "npy_exp2l"(long double x) long double log2l "npy_log2l"(long double x) long double atan2l "npy_atan2l"(long double x) long double hypotl "npy_hypotl"(long double x) long double powl "npy_powl"(long double x) long double fmodl "npy_fmodl"(long double x) long double modfl "npy_modfl"(long double x) # NumPy extensions float deg2radf "npy_deg2radf"(float x) float rad2degf "npy_rad2degf"(float x) float logaddexpf "npy_logaddexpf"(float x, float y) float logaddexp2f "npy_logaddexp2f"(float x, float y) double deg2rad "npy_deg2rad"(double x) double rad2deg "npy_rad2deg"(double x) double logaddexp "npy_logaddexp"(double x, double y) double logaddexp2 "npy_logaddexp2"(double x, double y) long double deg2radl "npy_deg2radl"(long double x) long double rad2degl "npy_rad2degl"(long double x) long double logaddexpl "npy_logaddexpl"(long double x, long double y) long double logaddexp2l "npy_logaddexp2l"(long double x, long double y) Cython-0.23.4/Cython/Includes/numpy/__init__.pxd0000644000175600017570000010522312606202452022645 0ustar jenkinsjenkins00000000000000# NumPy static imports for Cython # # If any of the PyArray_* functions are called, import_array must be # called first. # # This also defines backwards-compatability buffer acquisition # code for use in Python 2.x (or Python <= 2.5 when NumPy starts # implementing PEP-3118 directly). # # Because of laziness, the format string of the buffer is statically # allocated. Increase the size if this is not enough, or submit a # patch to do this properly. # # Author: Dag Sverre Seljebotn # DEF _buffer_format_string_len = 255 cimport cpython.buffer as pybuf from cpython.ref cimport Py_INCREF, Py_XDECREF from cpython.object cimport PyObject from cpython.type cimport type cimport libc.stdlib as stdlib cimport libc.stdio as stdio cdef extern from "Python.h": ctypedef int Py_intptr_t cdef extern from "numpy/arrayobject.h": ctypedef Py_intptr_t npy_intp ctypedef size_t npy_uintp cdef enum NPY_TYPES: NPY_BOOL NPY_BYTE NPY_UBYTE NPY_SHORT NPY_USHORT NPY_INT NPY_UINT NPY_LONG NPY_ULONG NPY_LONGLONG NPY_ULONGLONG NPY_FLOAT NPY_DOUBLE NPY_LONGDOUBLE NPY_CFLOAT NPY_CDOUBLE NPY_CLONGDOUBLE NPY_OBJECT NPY_STRING NPY_UNICODE NPY_VOID NPY_NTYPES NPY_NOTYPE NPY_INT8 NPY_INT16 NPY_INT32 NPY_INT64 NPY_INT128 NPY_INT256 NPY_UINT8 NPY_UINT16 NPY_UINT32 NPY_UINT64 NPY_UINT128 NPY_UINT256 NPY_FLOAT16 NPY_FLOAT32 NPY_FLOAT64 NPY_FLOAT80 NPY_FLOAT96 NPY_FLOAT128 NPY_FLOAT256 NPY_COMPLEX32 NPY_COMPLEX64 NPY_COMPLEX128 NPY_COMPLEX160 NPY_COMPLEX192 NPY_COMPLEX256 NPY_COMPLEX512 NPY_INTP ctypedef enum NPY_ORDER: NPY_ANYORDER NPY_CORDER NPY_FORTRANORDER ctypedef enum NPY_CLIPMODE: NPY_CLIP NPY_WRAP NPY_RAISE ctypedef enum NPY_SCALARKIND: NPY_NOSCALAR, NPY_BOOL_SCALAR, NPY_INTPOS_SCALAR, NPY_INTNEG_SCALAR, NPY_FLOAT_SCALAR, NPY_COMPLEX_SCALAR, NPY_OBJECT_SCALAR ctypedef enum NPY_SORTKIND: NPY_QUICKSORT NPY_HEAPSORT NPY_MERGESORT ctypedef enum NPY_SEARCHSIDE: NPY_SEARCHLEFT NPY_SEARCHRIGHT enum: NPY_C_CONTIGUOUS NPY_F_CONTIGUOUS NPY_CONTIGUOUS NPY_FORTRAN NPY_OWNDATA NPY_FORCECAST NPY_ENSURECOPY NPY_ENSUREARRAY NPY_ELEMENTSTRIDES NPY_ALIGNED NPY_NOTSWAPPED NPY_WRITEABLE NPY_UPDATEIFCOPY NPY_ARR_HAS_DESCR NPY_BEHAVED NPY_BEHAVED_NS NPY_CARRAY NPY_CARRAY_RO NPY_FARRAY NPY_FARRAY_RO NPY_DEFAULT NPY_IN_ARRAY NPY_OUT_ARRAY NPY_INOUT_ARRAY NPY_IN_FARRAY NPY_OUT_FARRAY NPY_INOUT_FARRAY NPY_UPDATE_ALL cdef enum: NPY_MAXDIMS npy_intp NPY_MAX_ELSIZE ctypedef void (*PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *, void *) ctypedef class numpy.dtype [object PyArray_Descr]: # Use PyDataType_* macros when possible, however there are no macros # for accessing some of the fields, so some are defined. cdef char kind cdef char type cdef char byteorder cdef char flags cdef int type_num cdef int itemsize "elsize" cdef int alignment cdef dict fields cdef tuple names ctypedef extern class numpy.flatiter [object PyArrayIterObject]: # Use through macros pass ctypedef extern class numpy.broadcast [object PyArrayMultiIterObject]: # Use through macros pass ctypedef struct PyArrayObject: # For use in situations where ndarray can't replace PyArrayObject*, # like PyArrayObject**. pass ctypedef class numpy.ndarray [object PyArrayObject]: cdef __cythonbufferdefaults__ = {"mode": "strided"} cdef: # Only taking a few of the most commonly used and stable fields. # One should use PyArray_* macros instead to access the C fields. char *data int ndim "nd" npy_intp *shape "dimensions" npy_intp *strides dtype descr PyObject* base # Note: This syntax (function definition in pxd files) is an # experimental exception made for __getbuffer__ and __releasebuffer__ # -- the details of this may change. def __getbuffer__(ndarray self, Py_buffer* info, int flags): # This implementation of getbuffer is geared towards Cython # requirements, and does not yet fullfill the PEP. # In particular strided access is always provided regardless # of flags if info == NULL: return cdef int copy_shape, i, ndim cdef int endian_detector = 1 cdef bint little_endian = ((&endian_detector)[0] != 0) ndim = PyArray_NDIM(self) if sizeof(npy_intp) != sizeof(Py_ssize_t): copy_shape = 1 else: copy_shape = 0 if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): raise ValueError(u"ndarray is not C contiguous") if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): raise ValueError(u"ndarray is not Fortran contiguous") info.buf = PyArray_DATA(self) info.ndim = ndim if copy_shape: # Allocate new buffer for strides and shape info. # This is allocated as one block, strides first. info.strides = stdlib.malloc(sizeof(Py_ssize_t) * ndim * 2) info.shape = info.strides + ndim for i in range(ndim): info.strides[i] = PyArray_STRIDES(self)[i] info.shape[i] = PyArray_DIMS(self)[i] else: info.strides = PyArray_STRIDES(self) info.shape = PyArray_DIMS(self) info.suboffsets = NULL info.itemsize = PyArray_ITEMSIZE(self) info.readonly = not PyArray_ISWRITEABLE(self) cdef int t cdef char* f = NULL cdef dtype descr = self.descr cdef int offset cdef bint hasfields = PyDataType_HASFIELDS(descr) if not hasfields and not copy_shape: # do not call releasebuffer info.obj = None else: # need to call releasebuffer info.obj = self if not hasfields: t = descr.type_num if ((descr.byteorder == c'>' and little_endian) or (descr.byteorder == c'<' and not little_endian)): raise ValueError(u"Non-native byte order not supported") if t == NPY_BYTE: f = "b" elif t == NPY_UBYTE: f = "B" elif t == NPY_SHORT: f = "h" elif t == NPY_USHORT: f = "H" elif t == NPY_INT: f = "i" elif t == NPY_UINT: f = "I" elif t == NPY_LONG: f = "l" elif t == NPY_ULONG: f = "L" elif t == NPY_LONGLONG: f = "q" elif t == NPY_ULONGLONG: f = "Q" elif t == NPY_FLOAT: f = "f" elif t == NPY_DOUBLE: f = "d" elif t == NPY_LONGDOUBLE: f = "g" elif t == NPY_CFLOAT: f = "Zf" elif t == NPY_CDOUBLE: f = "Zd" elif t == NPY_CLONGDOUBLE: f = "Zg" elif t == NPY_OBJECT: f = "O" else: raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) info.format = f return else: info.format = stdlib.malloc(_buffer_format_string_len) info.format[0] = c'^' # Native data types, manual alignment offset = 0 f = _util_dtypestring(descr, info.format + 1, info.format + _buffer_format_string_len, &offset) f[0] = c'\0' # Terminate format string def __releasebuffer__(ndarray self, Py_buffer* info): if PyArray_HASFIELDS(self): stdlib.free(info.format) if sizeof(npy_intp) != sizeof(Py_ssize_t): stdlib.free(info.strides) # info.shape was stored after info.strides in the same block ctypedef unsigned char npy_bool ctypedef signed char npy_byte ctypedef signed short npy_short ctypedef signed int npy_int ctypedef signed long npy_long ctypedef signed long long npy_longlong ctypedef unsigned char npy_ubyte ctypedef unsigned short npy_ushort ctypedef unsigned int npy_uint ctypedef unsigned long npy_ulong ctypedef unsigned long long npy_ulonglong ctypedef float npy_float ctypedef double npy_double ctypedef long double npy_longdouble ctypedef signed char npy_int8 ctypedef signed short npy_int16 ctypedef signed int npy_int32 ctypedef signed long long npy_int64 ctypedef signed long long npy_int96 ctypedef signed long long npy_int128 ctypedef unsigned char npy_uint8 ctypedef unsigned short npy_uint16 ctypedef unsigned int npy_uint32 ctypedef unsigned long long npy_uint64 ctypedef unsigned long long npy_uint96 ctypedef unsigned long long npy_uint128 ctypedef float npy_float32 ctypedef double npy_float64 ctypedef long double npy_float80 ctypedef long double npy_float96 ctypedef long double npy_float128 ctypedef struct npy_cfloat: double real double imag ctypedef struct npy_cdouble: double real double imag ctypedef struct npy_clongdouble: double real double imag ctypedef struct npy_complex64: double real double imag ctypedef struct npy_complex128: double real double imag ctypedef struct npy_complex160: double real double imag ctypedef struct npy_complex192: double real double imag ctypedef struct npy_complex256: double real double imag ctypedef struct PyArray_Dims: npy_intp *ptr int len void import_array() # # Macros from ndarrayobject.h # bint PyArray_CHKFLAGS(ndarray m, int flags) bint PyArray_ISCONTIGUOUS(ndarray m) bint PyArray_ISWRITEABLE(ndarray m) bint PyArray_ISALIGNED(ndarray m) int PyArray_NDIM(ndarray) bint PyArray_ISONESEGMENT(ndarray) bint PyArray_ISFORTRAN(ndarray) int PyArray_FORTRANIF(ndarray) void* PyArray_DATA(ndarray) char* PyArray_BYTES(ndarray) npy_intp* PyArray_DIMS(ndarray) npy_intp* PyArray_STRIDES(ndarray) npy_intp PyArray_DIM(ndarray, size_t) npy_intp PyArray_STRIDE(ndarray, size_t) # object PyArray_BASE(ndarray) wrong refcount semantics # dtype PyArray_DESCR(ndarray) wrong refcount semantics int PyArray_FLAGS(ndarray) npy_intp PyArray_ITEMSIZE(ndarray) int PyArray_TYPE(ndarray arr) object PyArray_GETITEM(ndarray arr, void *itemptr) int PyArray_SETITEM(ndarray arr, void *itemptr, object obj) bint PyTypeNum_ISBOOL(int) bint PyTypeNum_ISUNSIGNED(int) bint PyTypeNum_ISSIGNED(int) bint PyTypeNum_ISINTEGER(int) bint PyTypeNum_ISFLOAT(int) bint PyTypeNum_ISNUMBER(int) bint PyTypeNum_ISSTRING(int) bint PyTypeNum_ISCOMPLEX(int) bint PyTypeNum_ISPYTHON(int) bint PyTypeNum_ISFLEXIBLE(int) bint PyTypeNum_ISUSERDEF(int) bint PyTypeNum_ISEXTENDED(int) bint PyTypeNum_ISOBJECT(int) bint PyDataType_ISBOOL(dtype) bint PyDataType_ISUNSIGNED(dtype) bint PyDataType_ISSIGNED(dtype) bint PyDataType_ISINTEGER(dtype) bint PyDataType_ISFLOAT(dtype) bint PyDataType_ISNUMBER(dtype) bint PyDataType_ISSTRING(dtype) bint PyDataType_ISCOMPLEX(dtype) bint PyDataType_ISPYTHON(dtype) bint PyDataType_ISFLEXIBLE(dtype) bint PyDataType_ISUSERDEF(dtype) bint PyDataType_ISEXTENDED(dtype) bint PyDataType_ISOBJECT(dtype) bint PyDataType_HASFIELDS(dtype) bint PyArray_ISBOOL(ndarray) bint PyArray_ISUNSIGNED(ndarray) bint PyArray_ISSIGNED(ndarray) bint PyArray_ISINTEGER(ndarray) bint PyArray_ISFLOAT(ndarray) bint PyArray_ISNUMBER(ndarray) bint PyArray_ISSTRING(ndarray) bint PyArray_ISCOMPLEX(ndarray) bint PyArray_ISPYTHON(ndarray) bint PyArray_ISFLEXIBLE(ndarray) bint PyArray_ISUSERDEF(ndarray) bint PyArray_ISEXTENDED(ndarray) bint PyArray_ISOBJECT(ndarray) bint PyArray_HASFIELDS(ndarray) bint PyArray_ISVARIABLE(ndarray) bint PyArray_SAFEALIGNEDCOPY(ndarray) bint PyArray_ISNBO(char) # works on ndarray.byteorder bint PyArray_IsNativeByteOrder(char) # works on ndarray.byteorder bint PyArray_ISNOTSWAPPED(ndarray) bint PyArray_ISBYTESWAPPED(ndarray) bint PyArray_FLAGSWAP(ndarray, int) bint PyArray_ISCARRAY(ndarray) bint PyArray_ISCARRAY_RO(ndarray) bint PyArray_ISFARRAY(ndarray) bint PyArray_ISFARRAY_RO(ndarray) bint PyArray_ISBEHAVED(ndarray) bint PyArray_ISBEHAVED_RO(ndarray) bint PyDataType_ISNOTSWAPPED(dtype) bint PyDataType_ISBYTESWAPPED(dtype) bint PyArray_DescrCheck(object) bint PyArray_Check(object) bint PyArray_CheckExact(object) # Cannot be supported due to out arg: # bint PyArray_HasArrayInterfaceType(object, dtype, object, object&) # bint PyArray_HasArrayInterface(op, out) bint PyArray_IsZeroDim(object) # Cannot be supported due to ## ## in macro: # bint PyArray_IsScalar(object, verbatim work) bint PyArray_CheckScalar(object) bint PyArray_IsPythonNumber(object) bint PyArray_IsPythonScalar(object) bint PyArray_IsAnyScalar(object) bint PyArray_CheckAnyScalar(object) ndarray PyArray_GETCONTIGUOUS(ndarray) bint PyArray_SAMESHAPE(ndarray, ndarray) npy_intp PyArray_SIZE(ndarray) npy_intp PyArray_NBYTES(ndarray) object PyArray_FROM_O(object) object PyArray_FROM_OF(object m, int flags) object PyArray_FROM_OT(object m, int type) object PyArray_FROM_OTF(object m, int type, int flags) object PyArray_FROMANY(object m, int type, int min, int max, int flags) object PyArray_ZEROS(int nd, npy_intp* dims, int type, int fortran) object PyArray_EMPTY(int nd, npy_intp* dims, int type, int fortran) void PyArray_FILLWBYTE(object, int val) npy_intp PyArray_REFCOUNT(object) object PyArray_ContiguousFromAny(op, int, int min_depth, int max_depth) unsigned char PyArray_EquivArrTypes(ndarray a1, ndarray a2) bint PyArray_EquivByteorders(int b1, int b2) object PyArray_SimpleNew(int nd, npy_intp* dims, int typenum) object PyArray_SimpleNewFromData(int nd, npy_intp* dims, int typenum, void* data) #object PyArray_SimpleNewFromDescr(int nd, npy_intp* dims, dtype descr) object PyArray_ToScalar(void* data, ndarray arr) void* PyArray_GETPTR1(ndarray m, npy_intp i) void* PyArray_GETPTR2(ndarray m, npy_intp i, npy_intp j) void* PyArray_GETPTR3(ndarray m, npy_intp i, npy_intp j, npy_intp k) void* PyArray_GETPTR4(ndarray m, npy_intp i, npy_intp j, npy_intp k, npy_intp l) void PyArray_XDECREF_ERR(ndarray) # Cannot be supported due to out arg # void PyArray_DESCR_REPLACE(descr) object PyArray_Copy(ndarray) object PyArray_FromObject(object op, int type, int min_depth, int max_depth) object PyArray_ContiguousFromObject(object op, int type, int min_depth, int max_depth) object PyArray_CopyFromObject(object op, int type, int min_depth, int max_depth) object PyArray_Cast(ndarray mp, int type_num) object PyArray_Take(ndarray ap, object items, int axis) object PyArray_Put(ndarray ap, object items, object values) void PyArray_ITER_RESET(flatiter it) nogil void PyArray_ITER_NEXT(flatiter it) nogil void PyArray_ITER_GOTO(flatiter it, npy_intp* destination) nogil void PyArray_ITER_GOTO1D(flatiter it, npy_intp ind) nogil void* PyArray_ITER_DATA(flatiter it) nogil bint PyArray_ITER_NOTDONE(flatiter it) nogil void PyArray_MultiIter_RESET(broadcast multi) nogil void PyArray_MultiIter_NEXT(broadcast multi) nogil void PyArray_MultiIter_GOTO(broadcast multi, npy_intp dest) nogil void PyArray_MultiIter_GOTO1D(broadcast multi, npy_intp ind) nogil void* PyArray_MultiIter_DATA(broadcast multi, npy_intp i) nogil void PyArray_MultiIter_NEXTi(broadcast multi, npy_intp i) nogil bint PyArray_MultiIter_NOTDONE(broadcast multi) nogil # Functions from __multiarray_api.h # Functions taking dtype and returning object/ndarray are disabled # for now as they steal dtype references. I'm conservative and disable # more than is probably needed until it can be checked further. int PyArray_SetNumericOps (object) object PyArray_GetNumericOps () int PyArray_INCREF (ndarray) int PyArray_XDECREF (ndarray) void PyArray_SetStringFunction (object, int) dtype PyArray_DescrFromType (int) object PyArray_TypeObjectFromType (int) char * PyArray_Zero (ndarray) char * PyArray_One (ndarray) #object PyArray_CastToType (ndarray, dtype, int) int PyArray_CastTo (ndarray, ndarray) int PyArray_CastAnyTo (ndarray, ndarray) int PyArray_CanCastSafely (int, int) npy_bool PyArray_CanCastTo (dtype, dtype) int PyArray_ObjectType (object, int) dtype PyArray_DescrFromObject (object, dtype) #ndarray* PyArray_ConvertToCommonType (object, int *) dtype PyArray_DescrFromScalar (object) dtype PyArray_DescrFromTypeObject (object) npy_intp PyArray_Size (object) #object PyArray_Scalar (void *, dtype, object) #object PyArray_FromScalar (object, dtype) void PyArray_ScalarAsCtype (object, void *) #int PyArray_CastScalarToCtype (object, void *, dtype) #int PyArray_CastScalarDirect (object, dtype, void *, int) object PyArray_ScalarFromObject (object) #PyArray_VectorUnaryFunc * PyArray_GetCastFunc (dtype, int) object PyArray_FromDims (int, int *, int) #object PyArray_FromDimsAndDataAndDescr (int, int *, dtype, char *) #object PyArray_FromAny (object, dtype, int, int, int, object) object PyArray_EnsureArray (object) object PyArray_EnsureAnyArray (object) #object PyArray_FromFile (stdio.FILE *, dtype, npy_intp, char *) #object PyArray_FromString (char *, npy_intp, dtype, npy_intp, char *) #object PyArray_FromBuffer (object, dtype, npy_intp, npy_intp) #object PyArray_FromIter (object, dtype, npy_intp) object PyArray_Return (ndarray) #object PyArray_GetField (ndarray, dtype, int) #int PyArray_SetField (ndarray, dtype, int, object) object PyArray_Byteswap (ndarray, npy_bool) object PyArray_Resize (ndarray, PyArray_Dims *, int, NPY_ORDER) int PyArray_MoveInto (ndarray, ndarray) int PyArray_CopyInto (ndarray, ndarray) int PyArray_CopyAnyInto (ndarray, ndarray) int PyArray_CopyObject (ndarray, object) object PyArray_NewCopy (ndarray, NPY_ORDER) object PyArray_ToList (ndarray) object PyArray_ToString (ndarray, NPY_ORDER) int PyArray_ToFile (ndarray, stdio.FILE *, char *, char *) int PyArray_Dump (object, object, int) object PyArray_Dumps (object, int) int PyArray_ValidType (int) void PyArray_UpdateFlags (ndarray, int) object PyArray_New (type, int, npy_intp *, int, npy_intp *, void *, int, int, object) #object PyArray_NewFromDescr (type, dtype, int, npy_intp *, npy_intp *, void *, int, object) #dtype PyArray_DescrNew (dtype) dtype PyArray_DescrNewFromType (int) double PyArray_GetPriority (object, double) object PyArray_IterNew (object) object PyArray_MultiIterNew (int, ...) int PyArray_PyIntAsInt (object) npy_intp PyArray_PyIntAsIntp (object) int PyArray_Broadcast (broadcast) void PyArray_FillObjectArray (ndarray, object) int PyArray_FillWithScalar (ndarray, object) npy_bool PyArray_CheckStrides (int, int, npy_intp, npy_intp, npy_intp *, npy_intp *) dtype PyArray_DescrNewByteorder (dtype, char) object PyArray_IterAllButAxis (object, int *) #object PyArray_CheckFromAny (object, dtype, int, int, int, object) #object PyArray_FromArray (ndarray, dtype, int) object PyArray_FromInterface (object) object PyArray_FromStructInterface (object) #object PyArray_FromArrayAttr (object, dtype, object) #NPY_SCALARKIND PyArray_ScalarKind (int, ndarray*) int PyArray_CanCoerceScalar (int, int, NPY_SCALARKIND) object PyArray_NewFlagsObject (object) npy_bool PyArray_CanCastScalar (type, type) #int PyArray_CompareUCS4 (npy_ucs4 *, npy_ucs4 *, register size_t) int PyArray_RemoveSmallest (broadcast) int PyArray_ElementStrides (object) void PyArray_Item_INCREF (char *, dtype) void PyArray_Item_XDECREF (char *, dtype) object PyArray_FieldNames (object) object PyArray_Transpose (ndarray, PyArray_Dims *) object PyArray_TakeFrom (ndarray, object, int, ndarray, NPY_CLIPMODE) object PyArray_PutTo (ndarray, object, object, NPY_CLIPMODE) object PyArray_PutMask (ndarray, object, object) object PyArray_Repeat (ndarray, object, int) object PyArray_Choose (ndarray, object, ndarray, NPY_CLIPMODE) int PyArray_Sort (ndarray, int, NPY_SORTKIND) object PyArray_ArgSort (ndarray, int, NPY_SORTKIND) object PyArray_SearchSorted (ndarray, object, NPY_SEARCHSIDE) object PyArray_ArgMax (ndarray, int, ndarray) object PyArray_ArgMin (ndarray, int, ndarray) object PyArray_Reshape (ndarray, object) object PyArray_Newshape (ndarray, PyArray_Dims *, NPY_ORDER) object PyArray_Squeeze (ndarray) #object PyArray_View (ndarray, dtype, type) object PyArray_SwapAxes (ndarray, int, int) object PyArray_Max (ndarray, int, ndarray) object PyArray_Min (ndarray, int, ndarray) object PyArray_Ptp (ndarray, int, ndarray) object PyArray_Mean (ndarray, int, int, ndarray) object PyArray_Trace (ndarray, int, int, int, int, ndarray) object PyArray_Diagonal (ndarray, int, int, int) object PyArray_Clip (ndarray, object, object, ndarray) object PyArray_Conjugate (ndarray, ndarray) object PyArray_Nonzero (ndarray) object PyArray_Std (ndarray, int, int, ndarray, int) object PyArray_Sum (ndarray, int, int, ndarray) object PyArray_CumSum (ndarray, int, int, ndarray) object PyArray_Prod (ndarray, int, int, ndarray) object PyArray_CumProd (ndarray, int, int, ndarray) object PyArray_All (ndarray, int, ndarray) object PyArray_Any (ndarray, int, ndarray) object PyArray_Compress (ndarray, object, int, ndarray) object PyArray_Flatten (ndarray, NPY_ORDER) object PyArray_Ravel (ndarray, NPY_ORDER) npy_intp PyArray_MultiplyList (npy_intp *, int) int PyArray_MultiplyIntList (int *, int) void * PyArray_GetPtr (ndarray, npy_intp*) int PyArray_CompareLists (npy_intp *, npy_intp *, int) #int PyArray_AsCArray (object*, void *, npy_intp *, int, dtype) #int PyArray_As1D (object*, char **, int *, int) #int PyArray_As2D (object*, char ***, int *, int *, int) int PyArray_Free (object, void *) #int PyArray_Converter (object, object*) int PyArray_IntpFromSequence (object, npy_intp *, int) object PyArray_Concatenate (object, int) object PyArray_InnerProduct (object, object) object PyArray_MatrixProduct (object, object) object PyArray_CopyAndTranspose (object) object PyArray_Correlate (object, object, int) int PyArray_TypestrConvert (int, int) #int PyArray_DescrConverter (object, dtype*) #int PyArray_DescrConverter2 (object, dtype*) int PyArray_IntpConverter (object, PyArray_Dims *) #int PyArray_BufferConverter (object, chunk) int PyArray_AxisConverter (object, int *) int PyArray_BoolConverter (object, npy_bool *) int PyArray_ByteorderConverter (object, char *) int PyArray_OrderConverter (object, NPY_ORDER *) unsigned char PyArray_EquivTypes (dtype, dtype) #object PyArray_Zeros (int, npy_intp *, dtype, int) #object PyArray_Empty (int, npy_intp *, dtype, int) object PyArray_Where (object, object, object) object PyArray_Arange (double, double, double, int) #object PyArray_ArangeObj (object, object, object, dtype) int PyArray_SortkindConverter (object, NPY_SORTKIND *) object PyArray_LexSort (object, int) object PyArray_Round (ndarray, int, ndarray) unsigned char PyArray_EquivTypenums (int, int) int PyArray_RegisterDataType (dtype) int PyArray_RegisterCastFunc (dtype, int, PyArray_VectorUnaryFunc *) int PyArray_RegisterCanCast (dtype, int, NPY_SCALARKIND) #void PyArray_InitArrFuncs (PyArray_ArrFuncs *) object PyArray_IntTupleFromIntp (int, npy_intp *) int PyArray_TypeNumFromName (char *) int PyArray_ClipmodeConverter (object, NPY_CLIPMODE *) #int PyArray_OutputConverter (object, ndarray*) object PyArray_BroadcastToShape (object, npy_intp *, int) void _PyArray_SigintHandler (int) void* _PyArray_GetSigintBuf () #int PyArray_DescrAlignConverter (object, dtype*) #int PyArray_DescrAlignConverter2 (object, dtype*) int PyArray_SearchsideConverter (object, void *) object PyArray_CheckAxis (ndarray, int *, int) npy_intp PyArray_OverflowMultiplyList (npy_intp *, int) int PyArray_CompareString (char *, char *, size_t) # Typedefs that matches the runtime dtype objects in # the numpy module. # The ones that are commented out needs an IFDEF function # in Cython to enable them only on the right systems. ctypedef npy_int8 int8_t ctypedef npy_int16 int16_t ctypedef npy_int32 int32_t ctypedef npy_int64 int64_t #ctypedef npy_int96 int96_t #ctypedef npy_int128 int128_t ctypedef npy_uint8 uint8_t ctypedef npy_uint16 uint16_t ctypedef npy_uint32 uint32_t ctypedef npy_uint64 uint64_t #ctypedef npy_uint96 uint96_t #ctypedef npy_uint128 uint128_t ctypedef npy_float32 float32_t ctypedef npy_float64 float64_t #ctypedef npy_float80 float80_t #ctypedef npy_float128 float128_t ctypedef float complex complex64_t ctypedef double complex complex128_t # The int types are mapped a bit surprising -- # numpy.int corresponds to 'l' and numpy.long to 'q' ctypedef npy_long int_t ctypedef npy_longlong long_t ctypedef npy_longlong longlong_t ctypedef npy_ulong uint_t ctypedef npy_ulonglong ulong_t ctypedef npy_ulonglong ulonglong_t ctypedef npy_intp intp_t ctypedef npy_uintp uintp_t ctypedef npy_double float_t ctypedef npy_double double_t ctypedef npy_longdouble longdouble_t ctypedef npy_cfloat cfloat_t ctypedef npy_cdouble cdouble_t ctypedef npy_clongdouble clongdouble_t ctypedef npy_cdouble complex_t cdef inline object PyArray_MultiIterNew1(a): return PyArray_MultiIterNew(1, a) cdef inline object PyArray_MultiIterNew2(a, b): return PyArray_MultiIterNew(2, a, b) cdef inline object PyArray_MultiIterNew3(a, b, c): return PyArray_MultiIterNew(3, a, b, c) cdef inline object PyArray_MultiIterNew4(a, b, c, d): return PyArray_MultiIterNew(4, a, b, c, d) cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): return PyArray_MultiIterNew(5, a, b, c, d, e) cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # Recursive utility function used in __getbuffer__ to get format # string. The new location in the format string is returned. cdef dtype child cdef int endian_detector = 1 cdef bint little_endian = ((&endian_detector)[0] != 0) cdef tuple fields for childname in descr.names: fields = descr.fields[childname] child, new_offset = fields if (end - f) - (new_offset - offset[0]) < 15: raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") if ((child.byteorder == c'>' and little_endian) or (child.byteorder == c'<' and not little_endian)): raise ValueError(u"Non-native byte order not supported") # One could encode it in the format string and have Cython # complain instead, BUT: < and > in format strings also imply # standardized sizes for datatypes, and we rely on native in # order to avoid reencoding data types based on their size. # # A proper PEP 3118 exporter for other clients than Cython # must deal properly with this! # Output padding bytes while offset[0] < new_offset: f[0] = 120 # "x"; pad byte f += 1 offset[0] += 1 offset[0] += child.itemsize if not PyDataType_HASFIELDS(child): t = child.type_num if end - f < 5: raise RuntimeError(u"Format string allocated too short.") # Until ticket #99 is fixed, use integers to avoid warnings if t == NPY_BYTE: f[0] = 98 #"b" elif t == NPY_UBYTE: f[0] = 66 #"B" elif t == NPY_SHORT: f[0] = 104 #"h" elif t == NPY_USHORT: f[0] = 72 #"H" elif t == NPY_INT: f[0] = 105 #"i" elif t == NPY_UINT: f[0] = 73 #"I" elif t == NPY_LONG: f[0] = 108 #"l" elif t == NPY_ULONG: f[0] = 76 #"L" elif t == NPY_LONGLONG: f[0] = 113 #"q" elif t == NPY_ULONGLONG: f[0] = 81 #"Q" elif t == NPY_FLOAT: f[0] = 102 #"f" elif t == NPY_DOUBLE: f[0] = 100 #"d" elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg elif t == NPY_OBJECT: f[0] = 79 #"O" else: raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) f += 1 else: # Cython ignores struct boundary information ("T{...}"), # so don't output it f = _util_dtypestring(child, f, end, offset) return f # # ufunc API # cdef extern from "numpy/ufuncobject.h": ctypedef void (*PyUFuncGenericFunction) (char **, npy_intp *, npy_intp *, void *) ctypedef extern class numpy.ufunc [object PyUFuncObject]: cdef: int nin, nout, nargs int identity PyUFuncGenericFunction *functions void **data int ntypes int check_return char *name char *types char *doc void *ptr PyObject *obj PyObject *userloops cdef enum: PyUFunc_Zero PyUFunc_One PyUFunc_None UFUNC_ERR_IGNORE UFUNC_ERR_WARN UFUNC_ERR_RAISE UFUNC_ERR_CALL UFUNC_ERR_PRINT UFUNC_ERR_LOG UFUNC_MASK_DIVIDEBYZERO UFUNC_MASK_OVERFLOW UFUNC_MASK_UNDERFLOW UFUNC_MASK_INVALID UFUNC_SHIFT_DIVIDEBYZERO UFUNC_SHIFT_OVERFLOW UFUNC_SHIFT_UNDERFLOW UFUNC_SHIFT_INVALID UFUNC_FPE_DIVIDEBYZERO UFUNC_FPE_OVERFLOW UFUNC_FPE_UNDERFLOW UFUNC_FPE_INVALID UFUNC_ERR_DEFAULT UFUNC_ERR_DEFAULT2 object PyUFunc_FromFuncAndData(PyUFuncGenericFunction *, void **, char *, int, int, int, int, char *, char *, int) int PyUFunc_RegisterLoopForType(ufunc, int, PyUFuncGenericFunction, int *, void *) int PyUFunc_GenericFunction \ (ufunc, PyObject *, PyObject *, PyArrayObject **) void PyUFunc_f_f_As_d_d \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_d_d \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_f_f \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_g_g \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_F_F_As_D_D \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_F_F \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_D_D \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_G_G \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_O_O \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_ff_f_As_dd_d \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_ff_f \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_dd_d \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_gg_g \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_FF_F_As_DD_D \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_DD_D \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_FF_F \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_GG_G \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_OO_O \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_O_O_method \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_OO_O_method \ (char **, npy_intp *, npy_intp *, void *) void PyUFunc_On_Om \ (char **, npy_intp *, npy_intp *, void *) int PyUFunc_GetPyValues \ (char *, int *, int *, PyObject **) int PyUFunc_checkfperr \ (int, PyObject *, int *) void PyUFunc_clearfperr() int PyUFunc_getfperr() int PyUFunc_handlefperr \ (int, PyObject *, int, int *) int PyUFunc_ReplaceLoopBySignature \ (ufunc, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *) object PyUFunc_FromFuncAndDataAndSignature \ (PyUFuncGenericFunction *, void **, char *, int, int, int, int, char *, char *, int, char *) void import_ufunc() cdef inline void set_array_base(ndarray arr, object base): cdef PyObject* baseptr if base is None: baseptr = NULL else: Py_INCREF(base) # important to do this before decref below! baseptr = base Py_XDECREF(arr.base) arr.base = baseptr cdef inline object get_array_base(ndarray arr): if arr.base is NULL: return None else: return arr.base Cython-0.23.4/Cython/Includes/libcpp/0000755000175600017570000000000012606202455020472 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Includes/libcpp/vector.pxd0000644000175600017570000000527112606202452022513 0ustar jenkinsjenkins00000000000000cdef extern from "" namespace "std" nogil: cdef cppclass vector[T]: cppclass iterator: T& operator*() iterator operator++() iterator operator--() iterator operator+(size_t) iterator operator-(size_t) bint operator==(iterator) bint operator!=(iterator) bint operator<(iterator) bint operator>(iterator) bint operator<=(iterator) bint operator>=(iterator) cppclass reverse_iterator: T& operator*() iterator operator++() iterator operator--() iterator operator+(size_t) iterator operator-(size_t) bint operator==(reverse_iterator) bint operator!=(reverse_iterator) bint operator<(reverse_iterator) bint operator>(reverse_iterator) bint operator<=(reverse_iterator) bint operator>=(reverse_iterator) cppclass const_iterator(iterator): pass cppclass const_reverse_iterator(reverse_iterator): pass vector() except + vector(vector&) except + vector(size_t) except + vector(size_t, T&) except + #vector[input_iterator](input_iterator, input_iterator) T& operator[](size_t) #vector& operator=(vector&) bint operator==(vector&, vector&) bint operator!=(vector&, vector&) bint operator<(vector&, vector&) bint operator>(vector&, vector&) bint operator<=(vector&, vector&) bint operator>=(vector&, vector&) void assign(size_t, const T&) void assign[input_iterator](input_iterator, input_iterator) except + T& at(size_t) except + T& back() iterator begin() const_iterator const_begin "begin"() size_t capacity() void clear() bint empty() iterator end() const_iterator const_end "end"() iterator erase(iterator) iterator erase(iterator, iterator) T& front() iterator insert(iterator, const T&) except + void insert(iterator, size_t, const T&) except + void insert[Iter](iterator, Iter, Iter) except + size_t max_size() void pop_back() void push_back(T&) except + reverse_iterator rbegin() const_reverse_iterator const_rbegin "rbegin"() reverse_iterator rend() const_reverse_iterator const_rend "rend"() void reserve(size_t) void resize(size_t) except + void resize(size_t, T&) except + size_t size() void swap(vector&) # C++11 methods T* data() void shrink_to_fit() Cython-0.23.4/Cython/Includes/libcpp/utility.pxd0000644000175600017570000000065012606202452022710 0ustar jenkinsjenkins00000000000000cdef extern from "" namespace "std" nogil: cdef cppclass pair[T, U]: T first U second pair() except + pair(pair&) except + pair(T&, U&) except + bint operator==(pair&, pair&) bint operator!=(pair&, pair&) bint operator<(pair&, pair&) bint operator>(pair&, pair&) bint operator<=(pair&, pair&) bint operator>=(pair&, pair&) Cython-0.23.4/Cython/Includes/libcpp/unordered_set.pxd0000644000175600017570000000436412606202452024055 0ustar jenkinsjenkins00000000000000from .utility cimport pair cdef extern from "" namespace "std" nogil: cdef cppclass unordered_set[T]: cppclass iterator: T& operator*() iterator operator++() iterator operator--() bint operator==(iterator) bint operator!=(iterator) cppclass reverse_iterator: T& operator*() iterator operator++() iterator operator--() bint operator==(reverse_iterator) bint operator!=(reverse_iterator) cppclass const_iterator(iterator): pass cppclass const_reverse_iterator(reverse_iterator): pass unordered_set() except + unordered_set(unordered_set&) except + #unordered_set(key_compare&) #unordered_set& operator=(unordered_set&) bint operator==(unordered_set&, unordered_set&) bint operator!=(unordered_set&, unordered_set&) bint operator<(unordered_set&, unordered_set&) bint operator>(unordered_set&, unordered_set&) bint operator<=(unordered_set&, unordered_set&) bint operator>=(unordered_set&, unordered_set&) iterator begin() const_iterator const_begin "begin"() void clear() size_t count(T&) bint empty() iterator end() const_iterator const_end "end"() pair[iterator, iterator] equal_range(T&) #pair[const_iterator, const_iterator] equal_range(T&) void erase(iterator) void erase(iterator, iterator) size_t erase(T&) iterator find(T&) const_iterator const_find "find"(T&) pair[iterator, bint] insert(T&) iterator insert(iterator, T&) #void insert(input_iterator, input_iterator) #key_compare key_comp() iterator lower_bound(T&) const_iterator const_lower_bound "lower_bound"(T&) size_t max_size() reverse_iterator rbegin() const_reverse_iterator const_rbegin "rbegin"() reverse_iterator rend() const_reverse_iterator const_rend "rend"() size_t size() void swap(unordered_set&) iterator upper_bound(T&) const_iterator const_upper_bound "upper_bound"(T&) #value_compare value_comp() Cython-0.23.4/Cython/Includes/libcpp/unordered_map.pxd0000644000175600017570000000466212606202452024040 0ustar jenkinsjenkins00000000000000from .utility cimport pair cdef extern from "" namespace "std" nogil: cdef cppclass unordered_map[T, U]: cppclass iterator: pair[T, U]& operator*() iterator operator++() iterator operator--() bint operator==(iterator) bint operator!=(iterator) cppclass reverse_iterator: pair[T, U]& operator*() iterator operator++() iterator operator--() bint operator==(reverse_iterator) bint operator!=(reverse_iterator) cppclass const_iterator(iterator): pass cppclass const_reverse_iterator(reverse_iterator): pass unordered_map() except + unordered_map(unordered_map&) except + #unordered_map(key_compare&) U& operator[](T&) #unordered_map& operator=(unordered_map&) bint operator==(unordered_map&, unordered_map&) bint operator!=(unordered_map&, unordered_map&) bint operator<(unordered_map&, unordered_map&) bint operator>(unordered_map&, unordered_map&) bint operator<=(unordered_map&, unordered_map&) bint operator>=(unordered_map&, unordered_map&) U& at(T&) iterator begin() const_iterator const_begin "begin"() void clear() size_t count(T&) bint empty() iterator end() const_iterator const_end "end"() pair[iterator, iterator] equal_range(T&) #pair[const_iterator, const_iterator] equal_range(key_type&) void erase(iterator) void erase(iterator, iterator) size_t erase(T&) iterator find(T&) const_iterator const_find "find"(T&) pair[iterator, bint] insert(pair[T, U]) # XXX pair[T,U]& iterator insert(iterator, pair[T, U]) # XXX pair[T,U]& #void insert(input_iterator, input_iterator) #key_compare key_comp() iterator lower_bound(T&) const_iterator const_lower_bound "lower_bound"(T&) size_t max_size() reverse_iterator rbegin() const_reverse_iterator const_rbegin "rbegin"() reverse_iterator rend() const_reverse_iterator const_rend "rend"() size_t size() void swap(unordered_map&) iterator upper_bound(T&) const_iterator const_upper_bound "upper_bound"(T&) #value_compare value_comp() void max_load_factor(float) float max_load_factor() Cython-0.23.4/Cython/Includes/libcpp/string.pxd0000644000175600017570000000667512606202452022530 0ustar jenkinsjenkins00000000000000 # deprecated cimport for backwards compatibility: from libc.string cimport const_char cdef extern from "" namespace "std" nogil: size_t npos = -1 cdef cppclass string: string() except + string(char *) except + string(char *, size_t) except + string(string&) except + # as a string formed by a repetition of character c, n times. string(size_t, char) except + const char* c_str() const char* data() size_t size() size_t max_size() size_t length() void resize(size_t) void resize(size_t, char c) size_t capacity() void reserve(size_t) void clear() bint empty() char& at(size_t) char& operator[](size_t) int compare(string&) string& append(string&) string& append(string&, size_t, size_t) string& append(char *) string& append(char *, size_t) string& append(size_t, char) void push_back(char c) string& assign (string&) string& assign (string&, size_t, size_t) string& assign (char *, size_t) string& assign (char *) string& assign (size_t n, char c) string& insert(size_t, string&) string& insert(size_t, string&, size_t, size_t) string& insert(size_t, char* s, size_t) string& insert(size_t, char* s) string& insert(size_t, size_t, char c) size_t copy(char *, size_t, size_t) size_t find(string&) size_t find(string&, size_t) size_t find(char*, size_t pos, size_t) size_t find(char*, size_t pos) size_t find(char, size_t pos) size_t rfind(string&, size_t) size_t rfind(char* s, size_t, size_t) size_t rfind(char*, size_t pos) size_t rfind(char c, size_t) size_t rfind(char c) size_t find_first_of(string&, size_t) size_t find_first_of(char* s, size_t, size_t) size_t find_first_of(char*, size_t pos) size_t find_first_of(char c, size_t) size_t find_first_of(char c) size_t find_first_not_of(string&, size_t) size_t find_first_not_of(char* s, size_t, size_t) size_t find_first_not_of(char*, size_t pos) size_t find_first_not_of(char c, size_t) size_t find_first_not_of(char c) size_t find_last_of(string&, size_t) size_t find_last_of(char* s, size_t, size_t) size_t find_last_of(char*, size_t pos) size_t find_last_of(char c, size_t) size_t find_last_of(char c) size_t find_last_not_of(string&, size_t) size_t find_last_not_of(char* s, size_t, size_t) size_t find_last_not_of(char*, size_t pos) string substr(size_t, size_t) string substr() string substr(size_t) size_t find_last_not_of(char c, size_t) size_t find_last_not_of(char c) #string& operator= (string&) #string& operator= (char*) #string& operator= (char) string operator+ (string& rhs) string operator+ (char* rhs) bint operator==(string&) bint operator==(char*) bint operator!= (string& rhs ) bint operator!= (char* ) bint operator< (string&) bint operator< (char*) bint operator> (string&) bint operator> (char*) bint operator<= (string&) bint operator<= (char*) bint operator>= (string&) bint operator>= (char*) Cython-0.23.4/Cython/Includes/libcpp/stack.pxd0000644000175600017570000000040612606202452022311 0ustar jenkinsjenkins00000000000000cdef extern from "" namespace "std" nogil: cdef cppclass stack[T]: stack() except + stack(stack&) except + #stack(Container&) bint empty() void pop() void push(T&) size_t size() T& top() Cython-0.23.4/Cython/Includes/libcpp/set.pxd0000644000175600017570000000413012606202452021775 0ustar jenkinsjenkins00000000000000from .utility cimport pair cdef extern from "" namespace "std" nogil: cdef cppclass set[T]: cppclass iterator: T& operator*() iterator operator++() iterator operator--() bint operator==(iterator) bint operator!=(iterator) cppclass reverse_iterator: T& operator*() iterator operator++() iterator operator--() bint operator==(reverse_iterator) bint operator!=(reverse_iterator) cppclass const_iterator(iterator): pass cppclass const_reverse_iterator(reverse_iterator): pass set() except + set(set&) except + #set(key_compare&) #set& operator=(set&) bint operator==(set&, set&) bint operator!=(set&, set&) bint operator<(set&, set&) bint operator>(set&, set&) bint operator<=(set&, set&) bint operator>=(set&, set&) iterator begin() const_iterator const_begin "begin"() void clear() size_t count(const T&) bint empty() iterator end() const_iterator const_end "end"() pair[iterator, iterator] equal_range(const T&) #pair[const_iterator, const_iterator] equal_range(T&) void erase(iterator) void erase(iterator, iterator) size_t erase(T&) iterator find(T&) const_iterator const_find "find"(T&) pair[iterator, bint] insert(const T&) except + iterator insert(iterator, const T&) except + #void insert(input_iterator, input_iterator) #key_compare key_comp() iterator lower_bound(T&) const_iterator const_lower_bound "lower_bound"(T&) size_t max_size() reverse_iterator rbegin() const_reverse_iterator const_rbegin "rbegin"() reverse_iterator rend() const_reverse_iterator const_rend "rend"() size_t size() void swap(set&) iterator upper_bound(const T&) const_iterator const_upper_bound "upper_bound"(const T&) #value_compare value_comp() Cython-0.23.4/Cython/Includes/libcpp/queue.pxd0000644000175600017570000000103312606202452022325 0ustar jenkinsjenkins00000000000000cdef extern from "" namespace "std" nogil: cdef cppclass queue[T]: queue() except + queue(queue&) except + #queue(Container&) T& back() bint empty() T& front() void pop() void push(T&) size_t size() cdef cppclass priority_queue[T]: priority_queue() except + priority_queue(priority_queue&) except + #priority_queue(Container&) bint empty() void pop() void push(T&) size_t size() T& top() Cython-0.23.4/Cython/Includes/libcpp/pair.pxd0000644000175600017570000000003312606202452022133 0ustar jenkinsjenkins00000000000000from .utility cimport pair Cython-0.23.4/Cython/Includes/libcpp/memory.pxd0000644000175600017570000000452312606202452022520 0ustar jenkinsjenkins00000000000000from libcpp cimport bool, nullptr_t, nullptr cdef extern from "" namespace "std" nogil: cdef cppclass unique_ptr[T]: unique_ptr() unique_ptr(nullptr_t) unique_ptr(T*) unique_ptr(unique_ptr[T]&) # Modifiers T* release() void reset() void reset(nullptr_t) void reset(T*) void swap(unique_ptr&) # Observers T* get() T& operator*() #T* operator->() # Not Supported bool operator bool() bool operator!() bool operator==(const unique_ptr&) bool operator!=(const unique_ptr&) bool operator<(const unique_ptr&) bool operator>(const unique_ptr&) bool operator<=(const unique_ptr&) bool operator>=(const unique_ptr&) bool operator==(nullptr_t) bool operator!=(nullptr_t) # Forward Declaration not working ("Compiler crash in AnalyseDeclarationsTransform") #cdef cppclass weak_ptr[T] cdef cppclass shared_ptr[T]: shared_ptr() shared_ptr(nullptr_t) shared_ptr(T*) shared_ptr(shared_ptr[T]&) shared_ptr(shared_ptr[T]&, T*) shared_ptr(unique_ptr[T]&) #shared_ptr(weak_ptr[T]&) # Not Supported # Modifiers void reset() void reset(T*) void swap(shared_ptr&) # Observers T* get() T& operator*() #T* operator->() # Not Supported long use_count() bool unique() bool operator bool() bool operator!() #bool owner_before[Y](const weak_ptr[Y]&) # Not Supported bool owner_before[Y](const shared_ptr[Y]&) bool operator==(const shared_ptr&) bool operator!=(const shared_ptr&) bool operator<(const shared_ptr&) bool operator>(const shared_ptr&) bool operator<=(const shared_ptr&) bool operator>=(const shared_ptr&) bool operator==(nullptr_t) bool operator!=(nullptr_t) cdef cppclass weak_ptr[T]: weak_ptr() weak_ptr(weak_ptr[T]&) weak_ptr(shared_ptr[T]&) # Modifiers void reset() void swap(weak_ptr&) # Observers long use_count() bool expired() shared_ptr[T] lock() bool owner_before[Y](const weak_ptr[Y]&) bool owner_before[Y](const shared_ptr[Y]&) Cython-0.23.4/Cython/Includes/libcpp/map.pxd0000644000175600017570000000465512606202452021773 0ustar jenkinsjenkins00000000000000from .utility cimport pair cdef extern from "" namespace "std" nogil: cdef cppclass map[T, U]: cppclass iterator: pair[T, U]& operator*() iterator operator++() iterator operator--() bint operator==(iterator) bint operator!=(iterator) cppclass const_iterator: pair[const T, U]& operator*() const_iterator operator++() const_iterator operator--() bint operator==(const_iterator) bint operator!=(const_iterator) cppclass reverse_iterator: pair[T, U]& operator*() iterator operator++() iterator operator--() bint operator==(reverse_iterator) bint operator!=(reverse_iterator) cppclass const_reverse_iterator(reverse_iterator): pass map() except + map(map&) except + #map(key_compare&) U& operator[](T&) #map& operator=(map&) bint operator==(map&, map&) bint operator!=(map&, map&) bint operator<(map&, map&) bint operator>(map&, map&) bint operator<=(map&, map&) bint operator>=(map&, map&) U& at(const T&) except + iterator begin() const_iterator const_begin "begin" () void clear() size_t count(const T&) bint empty() iterator end() const_iterator const_end "end" () pair[iterator, iterator] equal_range(const T&) #pair[const_iterator, const_iterator] equal_range(key_type&) void erase(iterator) void erase(iterator, iterator) size_t erase(const T&) iterator find(const T&) const_iterator const_find "find" (const T&) pair[iterator, bint] insert(pair[T, U]) except + # XXX pair[T,U]& iterator insert(iterator, pair[T, U]) except + # XXX pair[T,U]& #void insert(input_iterator, input_iterator) #key_compare key_comp() iterator lower_bound(const T&) const_iterator const_lower_bound "lower_bound"(const T&) size_t max_size() reverse_iterator rbegin() const_reverse_iterator const_rbegin "rbegin"() reverse_iterator rend() const_reverse_iterator const_rend "rend"() size_t size() void swap(map&) iterator upper_bound(const T&) const_iterator const_upper_bound "upper_bound"(const T&) #value_compare value_comp() Cython-0.23.4/Cython/Includes/libcpp/list.pxd0000644000175600017570000000435412606202452022165 0ustar jenkinsjenkins00000000000000cdef extern from "" namespace "std" nogil: cdef cppclass list[T]: cppclass iterator: iterator() iterator(iterator &) T& operator*() iterator operator++() iterator operator--() bint operator==(iterator) bint operator!=(iterator) cppclass reverse_iterator: reverse_iterator() reverse_iterator(iterator &) T& operator*() reverse_iterator operator++() reverse_iterator operator--() bint operator==(reverse_iterator) bint operator!=(reverse_iterator) cppclass const_iterator(iterator): pass cppclass const_reverse_iterator(reverse_iterator): pass list() except + list(list&) except + list(size_t, T&) except + #list operator=(list&) bint operator==(list&, list&) bint operator!=(list&, list&) bint operator<(list&, list&) bint operator>(list&, list&) bint operator<=(list&, list&) bint operator>=(list&, list&) void assign(size_t, T&) T& back() iterator begin() const_iterator const_begin "begin"() void clear() bint empty() iterator end() const_iterator const_end "end"() iterator erase(iterator) iterator erase(iterator, iterator) T& front() iterator insert(iterator, T&) void insert(iterator, size_t, T&) size_t max_size() void merge(list&) #void merge(list&, BinPred) void pop_back() void pop_front() void push_back(T&) void push_front(T&) reverse_iterator rbegin() const_reverse_iterator const_rbegin "rbegin"() void remove(T&) #void remove_if(UnPred) reverse_iterator rend() const_reverse_iterator const_rend "rend"() void resize(size_t, T&) void reverse() size_t size() void sort() #void sort(BinPred) void splice(iterator, list&) void splice(iterator, list&, iterator) void splice(iterator, list&, iterator, iterator) void swap(list&) void unique() #void unique(BinPred) Cython-0.23.4/Cython/Includes/libcpp/deque.pxd0000644000175600017570000000377412606202452022322 0ustar jenkinsjenkins00000000000000cdef extern from "" namespace "std" nogil: cdef cppclass deque[T]: cppclass iterator: T& operator*() iterator operator++() iterator operator--() bint operator==(iterator) bint operator!=(iterator) cppclass reverse_iterator: T& operator*() iterator operator++() iterator operator--() bint operator==(reverse_iterator) bint operator!=(reverse_iterator) cppclass const_iterator(iterator): pass #cppclass const_reverse_iterator(reverse_iterator): # pass deque() except + deque(deque&) except + deque(size_t) except + deque(size_t, T&) except + #deque[input_iterator](input_iterator, input_iterator) T& operator[](size_t) #deque& operator=(deque&) bint operator==(deque&, deque&) bint operator!=(deque&, deque&) bint operator<(deque&, deque&) bint operator>(deque&, deque&) bint operator<=(deque&, deque&) bint operator>=(deque&, deque&) void assign(size_t, T&) void assign(input_iterator, input_iterator) T& at(size_t) T& back() iterator begin() const_iterator const_begin "begin"() void clear() bint empty() iterator end() const_iterator const_end "end"() iterator erase(iterator) iterator erase(iterator, iterator) T& front() iterator insert(iterator, T&) void insert(iterator, size_t, T&) void insert(iterator, input_iterator, input_iterator) size_t max_size() void pop_back() void pop_front() void push_back(T&) void push_front(T&) reverse_iterator rbegin() #const_reverse_iterator rbegin() reverse_iterator rend() #const_reverse_iterator rend() void resize(size_t) void resize(size_t, T&) size_t size() void swap(deque&) Cython-0.23.4/Cython/Includes/libcpp/complex.pxd0000644000175600017570000000570412606202452022661 0ustar jenkinsjenkins00000000000000# Note: add integer versions of the functions? cdef extern from "" namespace "std" nogil: cdef cppclass complex[T]: complex() except + complex(T, T) except + complex(complex[T]&) except + # How to make the converting constructor, i.e. convert complex[double] # to complex[float]? complex[T] operator+(complex[T]&) complex[T] operator-(complex[T]&) complex[T] operator+(complex[T]&, complex[T]&) complex[T] operator+(complex[T]&, T&) complex[T] operator+(T&, complex[T]&) complex[T] operator-(complex[T]&, complex[T]&) complex[T] operator-(complex[T]&, T&) complex[T] operator-(T&, complex[T]&) complex[T] operator*(complex[T]&, complex[T]&) complex[T] operator*(complex[T]&, T&) complex[T] operator*(T&, complex[T]&) complex[T] operator/(complex[T]&, complex[T]&) complex[T] operator/(complex[T]&, T&) complex[T] operator/(T&, complex[T]&) bint operator==(complex[T]&, complex[T]&) bint operator==(complex[T]&, T&) bint operator==(T&, complex[T]&) bint operator!=(complex[T]&, complex[T]&) bint operator!=(complex[T]&, T&) bint operator!=(T&, complex[T]&) # Access real part T real() void real(T) # Access imaginary part T imag() void imag(T) # Return real part T real[T](complex[T]&) long double real(long double) double real(double) float real(float) # Return imaginary part T imag[T](complex[T]&) long double imag(long double) double imag(double) float imag(float) T abs[T](complex[T]&) T arg[T](complex[T]&) long double arg(long double) double arg(double) float arg(float) T norm[T](complex[T]) long double norm(long double) double norm(double) float norm(float) complex[T] conj[T](complex[T]&) complex[long double] conj(long double) complex[double] conj(double) complex[float] conj(float) complex[T] proj[T](complex[T]) complex[long double] proj(long double) complex[double] proj(double) complex[float] proj(float) complex[T] polar[T](T&, T&) complex[T] ploar[T](T&) complex[T] exp[T](complex[T]&) complex[T] log[T](complex[T]&) complex[T] log10[T](complex[T]&) complex[T] pow[T](complex[T]&, complex[T]&) complex[T] pow[T](complex[T]&, T&) complex[T] pow[T](T&, complex[T]&) # There are some promotion versions too complex[T] sqrt[T](complex[T]&) complex[T] sin[T](complex[T]&) complex[T] cos[T](complex[T]&) complex[T] tan[T](complex[T]&) complex[T] asin[T](complex[T]&) complex[T] acos[T](complex[T]&) complex[T] atan[T](complex[T]&) complex[T] sinh[T](complex[T]&) complex[T] cosh[T](complex[T]&) complex[T] tanh[T](complex[T]&) complex[T] asinh[T](complex[T]&) complex[T] acosh[T](complex[T]&) complex[T] atanh[T](complex[T]&) Cython-0.23.4/Cython/Includes/libcpp/cast.pxd0000644000175600017570000000076512606202452022146 0ustar jenkinsjenkins00000000000000# Defines the standard C++ cast operators. # # Due to type restrictions, these are only defined for pointer parameters, # however that is the only case where they are significantly more interesting # than the standard C cast operator which can be written "(expression)" in # Cython. cdef extern from * nogil: cdef T dynamic_cast[T](void *) except + # nullptr may also indicate failure cdef T static_cast[T](void *) cdef T reinterpret_cast[T](void *) cdef T const_cast[T](void *) Cython-0.23.4/Cython/Includes/libcpp/algorithm.pxd0000644000175600017570000000215112606202452023171 0ustar jenkinsjenkins00000000000000from libcpp cimport bool cdef extern from "" namespace "std" nogil: # Sorting and searching bool binary_search[Iter, T](Iter first, Iter last, const T& value) bool binary_search[Iter, T, Compare](Iter first, Iter last, const T& value, Compare comp) void partial_sort[Iter](Iter first, Iter middle, Iter last) void partial_sort[Iter, Compare](Iter first, Iter middle, Iter last, Compare comp) void sort[Iter](Iter first, Iter last) void sort[Iter, Compare](Iter first, Iter last, Compare comp) # Binary heaps (priority queues) void make_heap[Iter](Iter first, Iter last) void make_heap[Iter, Compare](Iter first, Iter last, Compare comp) void pop_heap[Iter](Iter first, Iter last) void pop_heap[Iter, Compare](Iter first, Iter last, Compare comp) void push_heap[Iter](Iter first, Iter last) void push_heap[Iter, Compare](Iter first, Iter last, Compare comp) void sort_heap[Iter](Iter first, Iter last) void sort_heap[Iter, Compare](Iter first, Iter last, Compare comp) Cython-0.23.4/Cython/Includes/libcpp/__init__.pxd0000644000175600017570000000013612606202452022743 0ustar jenkinsjenkins00000000000000cdef extern from *: ctypedef bint bool ctypedef void* nullptr_t nullptr_t nullptr Cython-0.23.4/Cython/Includes/libc/0000755000175600017570000000000012606202455020132 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Includes/libc/time.pxd0000644000175600017570000000244312606202452021605 0ustar jenkinsjenkins00000000000000# http://en.wikipedia.org/wiki/C_date_and_time_functions from libc.stddef cimport wchar_t cdef extern from "time.h" nogil: ctypedef long clock_t ctypedef long time_t enum: CLOCKS_PER_SEC clock_t clock() # CPU time time_t time(time_t *) # wall clock time since Unix epoch cdef struct tm: int tm_sec int tm_min int tm_hour int tm_mday int tm_mon int tm_year int tm_wday int tm_yday int tm_isdst char *tm_zone long tm_gmtoff int daylight # global state long timezone char *tzname[2] void tzset() char *asctime(const tm *) char *asctime_r(const tm *, char *) char *ctime(const time_t *) char *ctime_r(const time_t *, char *) double difftime(time_t, time_t) tm *getdate(const char *) tm *gmtime(const time_t *) tm *gmtime_r(const time_t *, tm *) tm *localtime(const time_t *) tm *localtime_r(const time_t *, tm *) time_t mktime(tm *) size_t strftime(char *, size_t, const char *, const tm *) size_t wcsftime(wchar_t *str, size_t cnt, const wchar_t *fmt, tm *time) # POSIX not stdC char *strptime(const char *, const char *, tm *) Cython-0.23.4/Cython/Includes/libc/string.pxd0000644000175600017570000000376412606202452022164 0ustar jenkinsjenkins00000000000000# 7.21 String handling cdef extern from *: # deprecated backwards compatibility declarations ctypedef const char const_char "const char" ctypedef const signed char const_schar "const signed char" ctypedef const unsigned char const_uchar "const unsigned char" ctypedef const void const_void "const void" cdef extern from "string.h" nogil: void *memcpy (void *pto, const void *pfrom, size_t size) void *memmove (void *pto, const void *pfrom, size_t size) void *memset (void *block, int c, size_t size) int memcmp (const void *a1, const void *a2, size_t size) void *memchr (const void *block, int c, size_t size) void *memchr (const void *block, int c, size_t size) void *memrchr (const void *block, int c, size_t size) size_t strlen (const char *s) char *strcpy (char *pto, const char *pfrom) char *strncpy (char *pto, const char *pfrom, size_t size) char *strdup (const char *s) char *strndup (const char *s, size_t size) char *strcat (char *pto, const char *pfrom) char *strncat (char *pto, const char *pfrom, size_t size) int strcmp (const char *s1, const char *s2) int strcasecmp (const char *s1, const char *s2) int strncmp (const char *s1, const char *s2, size_t size) int strncasecmp (const char *s1, const char *s2, size_t n) int strcoll (const char *s1, const char *s2) size_t strxfrm (char *pto, const char *pfrom, size_t size) char *strerror (int errnum) char *strchr (const char *string, int c) char *strrchr (const char *string, int c) char *strstr (const char *haystack, const char *needle) char *strcasestr (const char *haystack, const char *needle) size_t strcspn (const char *string, const char *stopset) size_t strspn (const char *string, const char *set) char * strpbrk (const char *string, const char *stopset) char *strtok (char *newstring, const char *delimiters) char *strsep (char **string_ptr, const char *delimiter) Cython-0.23.4/Cython/Includes/libc/stdlib.pxd0000644000175600017570000000461212606202452022130 0ustar jenkinsjenkins00000000000000# 7.20 General utilities # deprecated cimports for backwards compatibility: from libc.string cimport const_char, const_void cdef extern from "stdlib.h" nogil: # 7.20.1 Numeric conversion functions int atoi (const char *string) long atol (const char *string) long long atoll (const char *string) double atof (const char *string) long strtol (const char *string, char **tailptr, int base) unsigned long int strtoul (const char *string, char **tailptr, int base) long long int strtoll (const char *string, char **tailptr, int base) unsigned long long int strtoull (const char *string, char **tailptr, int base) float strtof (const char *string, char **tailptr) double strtod (const char *string, char **tailptr) long double strtold (const char *string, char **tailptr) # 7.20.2 Pseudo-random sequence generation functions enum: RAND_MAX int rand () void srand (unsigned int seed) # 7.20.3 Memory management functions void *calloc (size_t count, size_t eltsize) void free (void *ptr) void *malloc (size_t size) void *realloc (void *ptr, size_t newsize) # 7.20.4 Communication with the environment enum: EXIT_FAILURE enum: EXIT_SUCCESS void exit (int status) void _exit (int status) int atexit (void (*function) ()) void abort () char *getenv (const char *name) int system (const char *command) #7.20.5 Searching and sorting utilities void *bsearch (const void *key, const void *array, size_t count, size_t size, int (*compare)(const void *, const void *)) void qsort (void *array, size_t count, size_t size, int (*compare)(const void *, const void *)) # 7.20.6 Integer arithmetic functions int abs (int number) long int labs (long int number) long long int llabs (long long int number) ctypedef struct div_t: int quot int rem div_t div (int numerator, int denominator) ctypedef struct ldiv_t: long int quot long int rem ldiv_t ldiv (long int numerator, long int denominator) ctypedef struct lldiv_t: long long int quot long long int rem lldiv_t lldiv (long long int numerator, long long int denominator) # 7.20.7 Multibyte/wide character conversion functions # XXX TODO # 7.20.8 Multibyte/wide string conversion functions # XXX TODO Cython-0.23.4/Cython/Includes/libc/stdio.pxd0000644000175600017570000000465212606202452021775 0ustar jenkinsjenkins00000000000000# 7.19 Input/output # deprecated cimports for backwards compatibility: from libc.string cimport const_char, const_void cdef extern from "stdio.h" nogil: ctypedef struct FILE cdef FILE *stdin cdef FILE *stdout cdef FILE *stderr enum: FOPEN_MAX enum: FILENAME_MAX FILE *fopen (const char *filename, const char *opentype) FILE *freopen (const char *filename, const char *opentype, FILE *stream) FILE *fdopen (int fdescriptor, const char *opentype) int fclose (FILE *stream) int remove (const char *filename) int rename (const char *oldname, const char *newname) FILE *tmpfile () int remove (const char *pathname) int rename (const char *oldpath, const char *newpath) enum: _IOFBF enum: _IOLBF enum: _IONBF int setvbuf (FILE *stream, char *buf, int mode, size_t size) enum: BUFSIZ void setbuf (FILE *stream, char *buf) size_t fread (void *data, size_t size, size_t count, FILE *stream) size_t fwrite (const void *data, size_t size, size_t count, FILE *stream) int fflush (FILE *stream) enum: EOF void clearerr (FILE *stream) int feof (FILE *stream) int ferror (FILE *stream) enum: SEEK_SET enum: SEEK_CUR enum: SEEK_END int fseek (FILE *stream, long int offset, int whence) void rewind (FILE *stream) long int ftell (FILE *stream) ctypedef struct fpos_t ctypedef const fpos_t const_fpos_t "const fpos_t" int fgetpos (FILE *stream, fpos_t *position) int fsetpos (FILE *stream, const fpos_t *position) int scanf (const char *template, ...) int sscanf (const char *s, const char *template, ...) int fscanf (FILE *stream, const char *template, ...) int printf (const char *template, ...) int sprintf (char *s, const char *template, ...) int snprintf (char *s, size_t size, const char *template, ...) int fprintf (FILE *stream, const char *template, ...) void perror (const char *message) char *gets (char *s) char *fgets (char *s, int count, FILE *stream) int getchar () int fgetc (FILE *stream) int getc (FILE *stream) int ungetc (int c, FILE *stream) int puts (const char *s) int fputs (const char *s, FILE *stream) int putchar (int c) int fputc (int c, FILE *stream) int putc (int c, FILE *stream) size_t getline(char **lineptr, size_t *n, FILE *stream) Cython-0.23.4/Cython/Includes/libc/stdint.pxd0000644000175600017570000000656712606202452022167 0ustar jenkinsjenkins00000000000000# Longness only used for type promotion. # Actual compile time size used for conversions. # 7.18 Integer types cdef extern from "stdint.h" nogil: # 7.18.1 Integer types # 7.18.1.1 Exact-width integer types ctypedef signed char int8_t ctypedef signed short int16_t ctypedef signed int int32_t ctypedef signed long int64_t ctypedef unsigned char uint8_t ctypedef unsigned short uint16_t ctypedef unsigned int uint32_t ctypedef unsigned long long uint64_t # 7.18.1.2 Minimum-width integer types ctypedef signed char int_least8_t ctypedef signed short int_least16_t ctypedef signed int int_least32_t ctypedef signed long int_least64_t ctypedef unsigned char uint_least8_t ctypedef unsigned short uint_least16_t ctypedef unsigned int uint_least32_t ctypedef unsigned long long uint_least64_t # 7.18.1.3 Fastest minimum-width integer types ctypedef signed char int_fast8_t ctypedef signed short int_fast16_t ctypedef signed int int_fast32_t ctypedef signed long int_fast64_t ctypedef unsigned char uint_fast8_t ctypedef unsigned short uint_fast16_t ctypedef unsigned int uint_fast32_t ctypedef unsigned long long uint_fast64_t # 7.18.1.4 Integer types capable of holding object pointers ctypedef ssize_t intptr_t ctypedef size_t uintptr_t # 7.18.1.5 Greatest-width integer types ctypedef signed long long intmax_t ctypedef unsigned long long uintmax_t # 7.18.2 Limits of specified-width integer types # 7.18.2.1 Limits of exact-width integer types int8_t INT8_MIN int16_t INT16_MIN int32_t INT32_MIN int64_t INT64_MIN int8_t INT8_MAX int16_t INT16_MAX int32_t INT32_MAX int64_t INT64_MAX uint8_t UINT8_MAX uint16_t UINT16_MAX uint32_t UINT32_MAX uint64_t UINT64_MAX #7.18.2.2 Limits of minimum-width integer types int_least8_t INT_LEAST8_MIN int_least16_t INT_LEAST16_MIN int_least32_t INT_LEAST32_MIN int_least64_t INT_LEAST64_MIN int_least8_t INT_LEAST8_MAX int_least16_t INT_LEAST16_MAX int_least32_t INT_LEAST32_MAX int_least64_t INT_LEAST64_MAX uint_least8_t UINT_LEAST8_MAX uint_least16_t UINT_LEAST16_MAX uint_least32_t UINT_LEAST32_MAX uint_least64_t UINT_LEAST64_MAX #7.18.2.3 Limits of fastest minimum-width integer types int_fast8_t INT_FAST8_MIN int_fast16_t INT_FAST16_MIN int_fast32_t INT_FAST32_MIN int_fast64_t INT_FAST64_MIN int_fast8_t INT_FAST8_MAX int_fast16_t INT_FAST16_MAX int_fast32_t INT_FAST32_MAX int_fast64_t INT_FAST64_MAX uint_fast8_t UINT_FAST8_MAX uint_fast16_t UINT_FAST16_MAX uint_fast32_t UINT_FAST32_MAX uint_fast64_t UINT_FAST64_MAX #7.18.2.4 Limits of integer types capable of holding object pointers enum: INTPTR_MIN enum: INTPTR_MAX enum: UINTPTR_MAX # 7.18.2.5 Limits of greatest-width integer types enum: INTMAX_MAX enum: INTMAX_MIN enum: UINTMAX_MAX # 7.18.3 Limits of other integer types # ptrdiff_t enum: PTRDIFF_MIN enum: PTRDIFF_MAX # sig_atomic_t enum: SIG_ATOMIC_MIN enum: SIG_ATOMIC_MAX # size_t size_t SIZE_MAX # wchar_t enum: WCHAR_MIN enum: WCHAR_MAX # wint_t enum: WINT_MIN enum: WINT_MAX Cython-0.23.4/Cython/Includes/libc/stddef.pxd0000644000175600017570000000024212606202452022113 0ustar jenkinsjenkins00000000000000# 7.17 Common definitions cdef extern from "stddef.h": ctypedef signed int ptrdiff_t ctypedef unsigned int size_t ctypedef int wchar_t Cython-0.23.4/Cython/Includes/libc/signal.pxd0000644000175600017570000000232312606202452022121 0ustar jenkinsjenkins00000000000000# 7.14 Signal handling ctypedef void (*sighandler_t)(int SIGNUM) nogil cdef extern from "signal.h" nogil: ctypedef int sig_atomic_t enum: SIGABRT enum: SIGFPE enum: SIGILL enum: SIGINT enum: SIGSEGV enum: SIGTERM sighandler_t SIG_DFL sighandler_t SIG_IGN sighandler_t SIG_ERR sighandler_t signal (int signum, sighandler_t action) int raise_"raise" (int signum) cdef extern from "signal.h" nogil: # Program Error enum: SIGFPE enum: SIGILL enum: SIGSEGV enum: SIGBUS enum: SIGABRT enum: SIGIOT enum: SIGTRAP enum: SIGEMT enum: SIGSYS # Termination enum: SIGTERM enum: SIGINT enum: SIGQUIT enum: SIGKILL enum: SIGHUP # Alarm enum: SIGALRM enum: SIGVTALRM enum: SIGPROF # Asynchronous I/O enum: SIGIO enum: SIGURG enum: SIGPOLL # Job Control enum: SIGCHLD enum: SIGCLD enum: SIGCONT enum: SIGSTOP enum: SIGTSTP enum: SIGTTIN enum: SIGTTOU # Operation Error enum: SIGPIPE enum: SIGLOST enum: SIGXCPU enum: SIGXFSZ # Miscellaneous enum: SIGUSR1 enum: SIGUSR2 enum: SIGWINCH enum: SIGINFO Cython-0.23.4/Cython/Includes/libc/setjmp.pxd0000644000175600017570000000022612606202452022146 0ustar jenkinsjenkins00000000000000cdef extern from "setjmp.h" nogil: ctypedef struct jmp_buf: pass int setjmp(jmp_buf state) void longjmp(jmp_buf state, int value) Cython-0.23.4/Cython/Includes/libc/math.pxd0000644000175600017570000000464312606202452021604 0ustar jenkinsjenkins00000000000000cdef extern from "math.h" nogil: double M_E double M_LOG2E double M_LOG10E double M_LN2 double M_LN10 double M_PI double M_PI_2 double M_PI_4 double M_1_PI double M_2_PI double M_2_SQRTPI double M_SQRT2 double M_SQRT1_2 # C99 constants float INFINITY float NAN double HUGE_VAL float HUGE_VALF long double HUGE_VALL double acos(double x) double asin(double x) double atan(double x) double atan2(double y, double x) double cos(double x) double sin(double x) double tan(double x) double cosh(double x) double sinh(double x) double tanh(double x) double acosh(double x) double asinh(double x) double atanh(double x) double hypot(double x, double y) double exp(double x) double exp2(double x) double expm1(double x) double log(double x) double logb(double x) double log2(double x) double log10(double x) double log1p(double x) int ilogb(double x) double lgamma(double x) double tgamma(double x) double frexp(double x, int* exponent) double ldexp(double x, int exponent) double modf(double x, double* iptr) double fmod(double x, double y) double remainder(double x, double y) double remquo(double x, double y, int *quot) double pow(double x, double y) double sqrt(double x) double cbrt(double x) double fabs(double x) double ceil(double x) double floor(double x) double trunc(double x) double rint(double x) double round(double x) double nearbyint(double x) double nextafter(double, double) double nexttoward(double, long double) long long llrint(double) long lrint(double) long long llround(double) long lround(double) double copysign(double, double) float copysignf(float, float) long double copysignl(long double, long double) double erf(double) float erff(float) long double erfl(long double) double erfc(double) float erfcf(float) long double erfcl(long double) double fdim(double x, double y) double fma(double x, double y) double fmax(double x, double y) double fmin(double x, double y) double scalbln(double x, long n) double scalbn(double x, int n) double nan(const char*) bint isfinite(long double) bint isinf(long double) bint isnan(long double) bint isnormal(long double) bint signbit(long double) Cython-0.23.4/Cython/Includes/libc/locale.pxd0000644000175600017570000000216212606202452022104 0ustar jenkinsjenkins00000000000000# 7.11 Localization # deprecated cimport for backwards compatibility: from libc.string cimport const_char cdef extern from "locale.h" nogil: struct lconv: char *decimal_point char *thousands_sep char *grouping char *mon_decimal_point char *mon_thousands_sep char *mon_grouping char *positive_sign char *negative_sign char *currency_symbol char frac_digits char p_cs_precedes char n_cs_precedes char p_sep_by_space char n_sep_by_space char p_sign_posn char n_sign_posn char *int_curr_symbol char int_frac_digits char int_p_cs_precedes char int_n_cs_precedes char int_p_sep_by_space char int_n_sep_by_space char int_p_sign_posn char int_n_sign_posn enum: LC_ALL enum: LC_COLLATE enum: LC_CTYPE enum: LC_MONETARY enum: LC_NUMERIC enum: LC_TIME # 7.11.1 Locale control char *setlocale (int category, const char *locale) # 7.11.2 Numeric formatting convention inquiry lconv *localeconv () Cython-0.23.4/Cython/Includes/libc/limits.pxd0000644000175600017570000000073312606202452022150 0ustar jenkinsjenkins00000000000000# 5.2.4.2.1 Sizes of integer types cdef extern from "limits.h": enum: CHAR_BIT enum: MB_LEN_MAX enum: CHAR_MIN enum: CHAR_MAX enum: SCHAR_MIN enum: SCHAR_MAX enum: UCHAR_MAX enum: SHRT_MIN enum: SHRT_MAX enum: USHRT_MAX enum: INT_MIN enum: INT_MAX enum: UINT_MAX enum: LONG_MIN enum: LONG_MAX enum: ULONG_MAX enum: LLONG_MIN enum: LLONG_MAX enum: ULLONG_MAX Cython-0.23.4/Cython/Includes/libc/float.pxd0000644000175600017570000000135012606202452021750 0ustar jenkinsjenkins00000000000000# 5.2.4.2.2 Characteristics of floating types cdef extern from "float.h": enum: FLT_RADIX enum: FLT_MANT_DIG enum: DBL_MANT_DIG enum: LDBL_MANT_DIG enum: DECIMAL_DIG enum: FLT_DIG enum: DBL_DIG enum: LDBL_DIG enum: FLT_MIN_EXP enum: DBL_MIN_EXP enum: LDBL_MIN_EXP enum: FLT_MIN_10_EXP enum: DBL_MIN_10_EXP enum: LDBL_MIN_10_EXP enum: FLT_MAX_EXP enum: DBL_MAX_EXP enum: LDBL_MAX_EXP enum: FLT_MAX_10_EXP enum: DBL_MAX_10_EXP enum: LDBL_MAX_10_EXP enum: FLT_MAX enum: DBL_MAX enum: LDBL_MAX enum: FLT_EPSILON enum: DBL_EPSILON enum: LDBL_EPSILON enum: FLT_MIN enum: DBL_MIN enum: LDBL_MIN Cython-0.23.4/Cython/Includes/libc/errno.pxd0000644000175600017570000000376012606202452021777 0ustar jenkinsjenkins00000000000000# 7.5 Errors cdef extern from "errno.h" nogil: enum: EPERM ENOENT ESRCH EINTR EIO ENXIO E2BIG ENOEXEC EBADF ECHILD EAGAIN ENOMEM EACCES EFAULT ENOTBLK EBUSY EEXIST EXDEV ENODEV ENOTDIR EISDIR EINVAL ENFILE EMFILE ENOTTY ETXTBSY EFBIG ENOSPC ESPIPE EROFS EMLINK EPIPE EDOM ERANGE EDEADLOCK ENAMETOOLONG ENOLCK ENOSYS ENOTEMPTY ELOOP ENOMSG EIDRM ECHRNG EL2NSYNC EL3HLT EL3RST ELNRNG EUNATCH ENOCSI EL2HLT EBADE EBADR EXFULL ENOANO EBADRQC EBADSLT EBFONT ENOSTR ENODATA ETIME ENOSR ENONET ENOPKG EREMOTE ENOLINK EADV ESRMNT ECOMM EPROTO EMULTIHOP EDOTDOT EBADMSG EOVERFLOW ENOTUNIQ EBADFD EREMCHG ELIBACC ELIBBAD ELIBSCN ELIBMAX ELIBEXEC EILSEQ ERESTART ESTRPIPE EUSERS ENOTSOCK EDESTADDRREQ EMSGSIZE EPROTOTYPE ENOPROTOOPT EPROTONOSUPPORT ESOCKTNOSUPPORT EOPNOTSUPP EPFNOSUPPORT EAFNOSUPPORT EADDRINUSE EADDRNOTAVAIL ENETDOWN ENETUNREACH ENETRESET ECONNABORTED ECONNRESET ENOBUFS EISCONN ENOTCONN ESHUTDOWN ETOOMANYREFS ETIMEDOUT ECONNREFUSED EHOSTDOWN EHOSTUNREACH EALREADY EINPROGRESS ESTALE EUCLEAN ENOTNAM ENAVAIL EISNAM EREMOTEIO EDQUOT int errno Cython-0.23.4/Cython/Includes/libc/__init__.pxd0000644000175600017570000000001512606202452022377 0ustar jenkinsjenkins00000000000000# empty file Cython-0.23.4/Cython/Includes/cpython/0000755000175600017570000000000012606202455020705 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Includes/cpython/weakref.pxd0000644000175600017570000000366412606202452023054 0ustar jenkinsjenkins00000000000000from .object cimport PyObject cdef extern from "Python.h": bint PyWeakref_Check(object ob) # Return true if ob is either a reference or proxy object. bint PyWeakref_CheckRef(object ob) # Return true if ob is a reference object. bint PyWeakref_CheckProxy(ob) # Return true if *ob* is a proxy object. object PyWeakref_NewRef(object ob, object callback) # Return a weak reference object for the object ob. This will # always return a new reference, but is not guaranteed to create a # new object; an existing reference object may be returned. The # second parameter, callback, can be a callable object that # receives notification when ob is garbage collected; it should # accept a single parameter, which will be the weak reference # object itself. callback may also be None or NULL. If ob is not # a weakly-referencable object, or if callback is not callable, # None, or NULL, this will return NULL and raise TypeError. object PyWeakref_NewProxy(object ob, object callback) # Return a weak reference proxy object for the object ob. This # will always return a new reference, but is not guaranteed to # create a new object; an existing proxy object may be returned. # The second parameter, callback, can be a callable object that # receives notification when ob is garbage collected; it should # accept a single parameter, which will be the weak reference # object itself. callback may also be None or NULL. If ob is not # a weakly-referencable object, or if callback is not callable, # None, or NULL, this will return NULL and raise TypeError. PyObject* PyWeakref_GetObject(object ref) # Return the referenced object from a weak reference, ref. If the # referent is no longer live, returns None. PyObject* PyWeakref_GET_OBJECT(object ref) # Similar to PyWeakref_GetObject, but implemented as a macro that # does no error checking. Cython-0.23.4/Cython/Includes/cpython/version.pxd0000644000175600017570000000151712606202452023110 0ustar jenkinsjenkins00000000000000# Python version constants # # It's better to evaluate these at runtime (i.e. C compile time) using # # if PY_MAJOR_VERSION >= 3: # do_stuff_in_Py3_0_and_later() # if PY_VERSION_HEX >= 0x02070000: # do_stuff_in_Py2_7_and_later() # # than using the IF/DEF statements, which are evaluated at Cython # compile time. This will keep your C code portable. cdef extern from *: # the complete version, e.g. 0x010502B2 == 1.5.2b2 int PY_VERSION_HEX # the individual sections as plain numbers int PY_MAJOR_VERSION int PY_MINOR_VERSION int PY_MICRO_VERSION int PY_RELEASE_LEVEL int PY_RELEASE_SERIAL # Note: PY_RELEASE_LEVEL is one of # 0xA (alpha) # 0xB (beta) # 0xC (release candidate) # 0xF (final) char PY_VERSION[] char PY_PATCHLEVEL_REVISION[] Cython-0.23.4/Cython/Includes/cpython/unicode.pxd0000644000175600017570000006221012606202452023046 0ustar jenkinsjenkins00000000000000cdef extern from *: # Return true if the object o is a Unicode object or an instance # of a Unicode subtype. Changed in version 2.2: Allowed subtypes # to be accepted. bint PyUnicode_Check(object o) # Return true if the object o is a Unicode object, but not an # instance of a subtype. New in version 2.2. bint PyUnicode_CheckExact(object o) # Return the size of the object. o has to be a PyUnicodeObject # (not checked). Py_ssize_t PyUnicode_GET_SIZE(object o) # Return the size of the object's internal buffer in bytes. o has # to be a PyUnicodeObject (not checked). Py_ssize_t PyUnicode_GET_DATA_SIZE(object o) # Return a pointer to the internal Py_UNICODE buffer of the # object. o has to be a PyUnicodeObject (not checked). Py_UNICODE* PyUnicode_AS_UNICODE(object o) # Return a pointer to the internal buffer of the object. o has to # be a PyUnicodeObject (not checked). char* PyUnicode_AS_DATA(object o) # Return 1 or 0 depending on whether ch is a whitespace character. bint Py_UNICODE_ISSPACE(Py_UNICODE ch) # Return 1 or 0 depending on whether ch is a lowercase character. bint Py_UNICODE_ISLOWER(Py_UNICODE ch) # Return 1 or 0 depending on whether ch is an uppercase character. bint Py_UNICODE_ISUPPER(Py_UNICODE ch) # Return 1 or 0 depending on whether ch is a titlecase character. bint Py_UNICODE_ISTITLE(Py_UNICODE ch) # Return 1 or 0 depending on whether ch is a linebreak character. bint Py_UNICODE_ISLINEBREAK(Py_UNICODE ch) # Return 1 or 0 depending on whether ch is a decimal character. bint Py_UNICODE_ISDECIMAL(Py_UNICODE ch) # Return 1 or 0 depending on whether ch is a digit character. bint Py_UNICODE_ISDIGIT(Py_UNICODE ch) # Return 1 or 0 depending on whether ch is a numeric character. bint Py_UNICODE_ISNUMERIC(Py_UNICODE ch) # Return 1 or 0 depending on whether ch is an alphabetic character. bint Py_UNICODE_ISALPHA(Py_UNICODE ch) # Return 1 or 0 depending on whether ch is an alphanumeric character. bint Py_UNICODE_ISALNUM(Py_UNICODE ch) # Return the character ch converted to lower case. Py_UNICODE Py_UNICODE_TOLOWER(Py_UNICODE ch) # Return the character ch converted to upper case. Py_UNICODE Py_UNICODE_TOUPPER(Py_UNICODE ch) # Return the character ch converted to title case. Py_UNICODE Py_UNICODE_TOTITLE(Py_UNICODE ch) # Return the character ch converted to a decimal positive # integer. Return -1 if this is not possible. This macro does not # raise exceptions. int Py_UNICODE_TODECIMAL(Py_UNICODE ch) # Return the character ch converted to a single digit # integer. Return -1 if this is not possible. This macro does not # raise exceptions. int Py_UNICODE_TODIGIT(Py_UNICODE ch) # Return the character ch converted to a double. Return -1.0 if # this is not possible. This macro does not raise exceptions. double Py_UNICODE_TONUMERIC(Py_UNICODE ch) # To create Unicode objects and access their basic sequence # properties, use these APIs: # Create a Unicode Object from the Py_UNICODE buffer u of the # given size. u may be NULL which causes the contents to be # undefined. It is the user's responsibility to fill in the needed # data. The buffer is copied into the new object. If the buffer is # not NULL, the return value might be a shared object. Therefore, # modification of the resulting Unicode object is only allowed # when u is NULL. unicode PyUnicode_FromUnicode(Py_UNICODE *u, Py_ssize_t size) # Create a Unicode Object from the given Unicode code point ordinal. # # The ordinal must be in range(0x10000) on narrow Python builds # (UCS2), and range(0x110000) on wide builds (UCS4). A ValueError # is raised in case it is not. unicode PyUnicode_FromOrdinal(int ordinal) # Return a read-only pointer to the Unicode object's internal # Py_UNICODE buffer, NULL if unicode is not a Unicode object. Py_UNICODE* PyUnicode_AsUnicode(object o) except NULL # Return the length of the Unicode object. Py_ssize_t PyUnicode_GetSize(object o) except -1 # Coerce an encoded object obj to an Unicode object and return a # reference with incremented refcount. # String and other char buffer compatible objects are decoded # according to the given encoding and using the error handling # defined by errors. Both can be NULL to have the interface use # the default values (see the next section for details). # All other objects, including Unicode objects, cause a TypeError # to be set. object PyUnicode_FromEncodedObject(object o, char *encoding, char *errors) # Shortcut for PyUnicode_FromEncodedObject(obj, NULL, "strict") # which is used throughout the interpreter whenever coercion to # Unicode is needed. object PyUnicode_FromObject(object obj) # If the platform supports wchar_t and provides a header file # wchar.h, Python can interface directly to this type using the # following functions. Support is optimized if Python's own # Py_UNICODE type is identical to the system's wchar_t. #ctypedef int wchar_t # Create a Unicode object from the wchar_t buffer w of the given # size. Return NULL on failure. #PyObject* PyUnicode_FromWideChar(wchar_t *w, Py_ssize_t size) #Py_ssize_t PyUnicode_AsWideChar(object o, wchar_t *w, Py_ssize_t size) # Unicode Methods # Concat two strings giving a new Unicode string. # Return value: New reference. unicode PyUnicode_Concat(object left, object right) # Split a string giving a list of Unicode strings. If sep is NULL, # splitting will be done at all whitespace substrings. Otherwise, # splits occur at the given separator. At most maxsplit splits will # be done. If negative, no limit is set. Separators are not included # in the resulting list. # Return value: New reference. list PyUnicode_Split(object s, object sep, Py_ssize_t maxsplit) # Split a Unicode string at line breaks, returning a list of Unicode # strings. CRLF is considered to be one line break. If keepend is 0, # the Line break characters are not included in the resulting strings. # Return value: New reference. list PyUnicode_Splitlines(object s, bint keepend) # Translate a string by applying a character mapping table to it and # return the resulting Unicode object. # # The mapping table must map Unicode ordinal integers to Unicode ordinal # integers or None (causing deletion of the character). # # Mapping tables need only provide the __getitem__() interface; # dictionaries and sequences work well. Unmapped character ordinals (ones # which cause a LookupError) are left untouched and are copied as-is. # # errors has the usual meaning for codecs. It may be NULL which indicates # to use the default error handling. # Return value: New reference. unicode PyUnicode_Translate(object str, object table, const char *errors) # Join a sequence of strings using the given separator and return the # resulting Unicode string. # Return value: New reference. unicode PyUnicode_Join(object separator, object seq) # Return 1 if substr matches str[start:end] at the given tail end # (direction == -1 means to do a prefix match, direction == 1 a # suffix match), 0 otherwise. # Return -1 if an error occurred. Py_ssize_t PyUnicode_Tailmatch(object str, object substr, Py_ssize_t start, Py_ssize_t end, int direction) except -1 # Return the first position of substr in str[start:end] using the given # direction (direction == 1 means to do a forward search, direction == -1 # a backward search). The return value is the index of the first match; # a value of -1 indicates that no match was found, and -2 indicates that an # error occurred and an exception has been set. Py_ssize_t PyUnicode_Find(object str, object substr, Py_ssize_t start, Py_ssize_t end, int direction) except -2 # Return the first position of the character ch in str[start:end] using # the given direction (direction == 1 means to do a forward search, # direction == -1 a backward search). The return value is the index of # the first match; a value of -1 indicates that no match was found, and # -2 indicates that an error occurred and an exception has been set. # New in version 3.3. Py_ssize_t PyUnicode_FindChar(object str, Py_UCS4 ch, Py_ssize_t start, Py_ssize_t end, int direction) except -2 # Return the number of non-overlapping occurrences of substr in # str[start:end]. Return -1 if an error occurred. Py_ssize_t PyUnicode_Count(object str, object substr, Py_ssize_t start, Py_ssize_t end) except -1 # Replace at most maxcount occurrences of substr in str with replstr and # return the resulting Unicode object. maxcount == -1 means replace all # occurrences. # Return value: New reference. unicode PyUnicode_Replace(object str, object substr, object replstr, Py_ssize_t maxcount) # Compare two strings and return -1, 0, 1 for less than, # equal, and greater than, respectively. int PyUnicode_Compare(object left, object right) except? -1 # Compare a unicode object, uni, with string and return -1, 0, 1 for less than, # equal, and greater than, respectively. It is best to pass only ASCII-encoded # strings, but the function interprets the input string as ISO-8859-1 if it # contains non-ASCII characters. int PyUnicode_CompareWithASCIIString(object uni, char *string) except? -1 # Rich compare two unicode strings and return one of the following: # # NULL in case an exception was raised # Py_True or Py_False for successful comparisons # Py_NotImplemented in case the type combination is unknown # # Note that Py_EQ and Py_NE comparisons can cause a UnicodeWarning in case # the conversion of the arguments to Unicode fails with a UnicodeDecodeError. # # Possible values for op are Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, and Py_LE. object PyUnicode_RichCompare(object left, object right, int op) # Return a new string object from format and args; this is analogous to # format % args. # Return value: New reference. unicode PyUnicode_Format(object format, object args) # Check whether element is contained in container and return true or false # accordingly. # # element has to coerce to a one element Unicode string. -1 is returned # if there was an error. int PyUnicode_Contains(object container, object element) except -1 # Intern the argument *string in place. The argument must be the address # of a pointer variable pointing to a Python unicode string object. If # there is an existing interned string that is the same as *string, it sets # *string to it (decrementing the reference count of the old string object # and incrementing the reference count of the interned string object), # otherwise it leaves *string alone and interns it (incrementing its reference # count). (Clarification: even though there is a lot of talk about reference # counts, think of this function as reference-count-neutral; you own the object # after the call if and only if you owned it before the call.) #void PyUnicode_InternInPlace(PyObject **string) # A combination of PyUnicode_FromString() and PyUnicode_InternInPlace(), # returning either a new unicode string object that has been interned, or # a new ("owned") reference to an earlier interned string object with the # same value. unicode PyUnicode_InternFromString(const char *v) # Codecs # Create a Unicode object by decoding size bytes of the encoded # string s. encoding and errors have the same meaning as the # parameters of the same name in the unicode() builtin # function. The codec to be used is looked up using the Python # codec registry. Return NULL if an exception was raised by the # codec. object PyUnicode_Decode(char *s, Py_ssize_t size, char *encoding, char *errors) # Encode the Py_UNICODE buffer of the given size and return a # Python string object. encoding and errors have the same meaning # as the parameters of the same name in the Unicode encode() # method. The codec to be used is looked up using the Python codec # registry. Return NULL if an exception was raised by the codec. object PyUnicode_Encode(Py_UNICODE *s, Py_ssize_t size, char *encoding, char *errors) # Encode a Unicode object and return the result as Python string # object. encoding and errors have the same meaning as the # parameters of the same name in the Unicode encode() method. The # codec to be used is looked up using the Python codec # registry. Return NULL if an exception was raised by the codec. object PyUnicode_AsEncodedString(object unicode, char *encoding, char *errors) # These are the UTF-8 codec APIs: # Create a Unicode object by decoding size bytes of the UTF-8 # encoded string s. Return NULL if an exception was raised by the # codec. unicode PyUnicode_DecodeUTF8(char *s, Py_ssize_t size, char *errors) # If consumed is NULL, behave like PyUnicode_DecodeUTF8(). If # consumed is not NULL, trailing incomplete UTF-8 byte sequences # will not be treated as an error. Those bytes will not be decoded # and the number of bytes that have been decoded will be stored in # consumed. New in version 2.4. unicode PyUnicode_DecodeUTF8Stateful(char *s, Py_ssize_t size, char *errors, Py_ssize_t *consumed) # Encode the Py_UNICODE buffer of the given size using UTF-8 and # return a Python string object. Return NULL if an exception was # raised by the codec. bytes PyUnicode_EncodeUTF8(Py_UNICODE *s, Py_ssize_t size, char *errors) # Encode a Unicode objects using UTF-8 and return the result as Python string object. Error handling is ``strict''. Return NULL if an exception was raised by the codec. bytes PyUnicode_AsUTF8String(object unicode) # These are the UTF-16 codec APIs: # Decode length bytes from a UTF-16 encoded buffer string and # return the corresponding Unicode object. errors (if non-NULL) # defines the error handling. It defaults to ``strict''. # # If byteorder is non-NULL, the decoder starts decoding using the # given byte order: # # *byteorder == -1: little endian # *byteorder == 0: native order # *byteorder == 1: big endian # # and then switches if the first two bytes of the input data are a # byte order mark (BOM) and the specified byte order is native # order. This BOM is not copied into the resulting Unicode # string. After completion, *byteorder is set to the current byte # order at the. # # If byteorder is NULL, the codec starts in native order mode. unicode PyUnicode_DecodeUTF16(char *s, Py_ssize_t size, char *errors, int *byteorder) # If consumed is NULL, behave like PyUnicode_DecodeUTF16(). If # consumed is not NULL, PyUnicode_DecodeUTF16Stateful() will not # treat trailing incomplete UTF-16 byte sequences (such as an odd # number of bytes or a split surrogate pair) as an error. Those # bytes will not be decoded and the number of bytes that have been # decoded will be stored in consumed. New in version 2.4. unicode PyUnicode_DecodeUTF16Stateful(char *s, Py_ssize_t size, char *errors, int *byteorder, Py_ssize_t *consumed) # Return a Python string object holding the UTF-16 encoded value # of the Unicode data in s. If byteorder is not 0, output is # written according to the following byte order: # # byteorder == -1: little endian # byteorder == 0: native byte order (writes a BOM mark) # byteorder == 1: big endian # # If byteorder is 0, the output string will always start with the # Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark # is prepended. # # If Py_UNICODE_WIDE is defined, a single Py_UNICODE value may get # represented as a surrogate pair. If it is not defined, each # Py_UNICODE values is interpreted as an UCS-2 character. bytes PyUnicode_EncodeUTF16(Py_UNICODE *s, Py_ssize_t size, char *errors, int byteorder) # Return a Python string using the UTF-16 encoding in native byte # order. The string always starts with a BOM mark. Error handling # is ``strict''. Return NULL if an exception was raised by the # codec. bytes PyUnicode_AsUTF16String(object unicode) # These are the ``Unicode Escape'' codec APIs: # Create a Unicode object by decoding size bytes of the # Unicode-Escape encoded string s. Return NULL if an exception was # raised by the codec. object PyUnicode_DecodeUnicodeEscape(char *s, Py_ssize_t size, char *errors) # Encode the Py_UNICODE buffer of the given size using # Unicode-Escape and return a Python string object. Return NULL if # an exception was raised by the codec. object PyUnicode_EncodeUnicodeEscape(Py_UNICODE *s, Py_ssize_t size) # Encode a Unicode objects using Unicode-Escape and return the # result as Python string object. Error handling is # ``strict''. Return NULL if an exception was raised by the codec. object PyUnicode_AsUnicodeEscapeString(object unicode) # These are the ``Raw Unicode Escape'' codec APIs: # Create a Unicode object by decoding size bytes of the # Raw-Unicode-Escape encoded string s. Return NULL if an exception # was raised by the codec. object PyUnicode_DecodeRawUnicodeEscape(char *s, Py_ssize_t size, char *errors) # Encode the Py_UNICODE buffer of the given size using # Raw-Unicode-Escape and return a Python string object. Return # NULL if an exception was raised by the codec. object PyUnicode_EncodeRawUnicodeEscape(Py_UNICODE *s, Py_ssize_t size, char *errors) # Encode a Unicode objects using Raw-Unicode-Escape and return the # result as Python string object. Error handling is # ``strict''. Return NULL if an exception was raised by the codec. object PyUnicode_AsRawUnicodeEscapeString(object unicode) # These are the Latin-1 codec APIs: Latin-1 corresponds to the first 256 Unicode ordinals and only these are accepted by the codecs during encoding. # Create a Unicode object by decoding size bytes of the Latin-1 # encoded string s. Return NULL if an exception was raised by the # codec. unicode PyUnicode_DecodeLatin1(char *s, Py_ssize_t size, char *errors) # Encode the Py_UNICODE buffer of the given size using Latin-1 and # return a Python bytes object. Return NULL if an exception was # raised by the codec. bytes PyUnicode_EncodeLatin1(Py_UNICODE *s, Py_ssize_t size, char *errors) # Encode a Unicode objects using Latin-1 and return the result as # Python bytes object. Error handling is ``strict''. Return NULL # if an exception was raised by the codec. bytes PyUnicode_AsLatin1String(object unicode) # These are the ASCII codec APIs. Only 7-bit ASCII data is # accepted. All other codes generate errors. # Create a Unicode object by decoding size bytes of the ASCII # encoded string s. Return NULL if an exception was raised by the # codec. unicode PyUnicode_DecodeASCII(char *s, Py_ssize_t size, char *errors) # Encode the Py_UNICODE buffer of the given size using ASCII and # return a Python bytes object. Return NULL if an exception was # raised by the codec. bytes PyUnicode_EncodeASCII(Py_UNICODE *s, Py_ssize_t size, char *errors) # Encode a Unicode objects using ASCII and return the result as # Python bytes object. Error handling is ``strict''. Return NULL # if an exception was raised by the codec. bytes PyUnicode_AsASCIIString(object o) # These are the mapping codec APIs: # # This codec is special in that it can be used to implement many # different codecs (and this is in fact what was done to obtain most # of the standard codecs included in the encodings package). The codec # uses mapping to encode and decode characters. # # Decoding mappings must map single string characters to single # Unicode characters, integers (which are then interpreted as Unicode # ordinals) or None (meaning "undefined mapping" and causing an # error). # # Encoding mappings must map single Unicode characters to single # string characters, integers (which are then interpreted as Latin-1 # ordinals) or None (meaning "undefined mapping" and causing an # error). # # The mapping objects provided must only support the __getitem__ # mapping interface. # # If a character lookup fails with a LookupError, the character is # copied as-is meaning that its ordinal value will be interpreted as # Unicode or Latin-1 ordinal resp. Because of this, mappings only need # to contain those mappings which map characters to different code # points. # Create a Unicode object by decoding size bytes of the encoded # string s using the given mapping object. Return NULL if an # exception was raised by the codec. If mapping is NULL latin-1 # decoding will be done. Else it can be a dictionary mapping byte # or a unicode string, which is treated as a lookup table. Byte # values greater that the length of the string and U+FFFE # "characters" are treated as "undefined mapping". Changed in # version 2.4: Allowed unicode string as mapping argument. object PyUnicode_DecodeCharmap(char *s, Py_ssize_t size, object mapping, char *errors) # Encode the Py_UNICODE buffer of the given size using the given # mapping object and return a Python string object. Return NULL if # an exception was raised by the codec. # # Deprecated since version 3.3, will be removed in version 4.0. object PyUnicode_EncodeCharmap(Py_UNICODE *s, Py_ssize_t size, object mapping, char *errors) # Encode a Unicode objects using the given mapping object and # return the result as Python string object. Error handling is # ``strict''. Return NULL if an exception was raised by the codec. object PyUnicode_AsCharmapString(object o, object mapping) # The following codec API is special in that maps Unicode to Unicode. # Translate a Py_UNICODE buffer of the given length by applying a # character mapping table to it and return the resulting Unicode # object. Return NULL when an exception was raised by the codec. # # The mapping table must map Unicode ordinal integers to Unicode # ordinal integers or None (causing deletion of the character). # # Mapping tables need only provide the __getitem__() interface; # dictionaries and sequences work well. Unmapped character # ordinals (ones which cause a LookupError) are left untouched and # are copied as-is. # # Deprecated since version 3.3, will be removed in version 4.0. object PyUnicode_TranslateCharmap(Py_UNICODE *s, Py_ssize_t size, object table, char *errors) # These are the MBCS codec APIs. They are currently only available on # Windows and use the Win32 MBCS converters to implement the # conversions. Note that MBCS (or DBCS) is a class of encodings, not # just one. The target encoding is defined by the user settings on the # machine running the codec. # Create a Unicode object by decoding size bytes of the MBCS # encoded string s. Return NULL if an exception was raised by the # codec. unicode PyUnicode_DecodeMBCS(char *s, Py_ssize_t size, char *errors) # If consumed is NULL, behave like PyUnicode_DecodeMBCS(). If # consumed is not NULL, PyUnicode_DecodeMBCSStateful() will not # decode trailing lead byte and the number of bytes that have been # decoded will be stored in consumed. New in version 2.5. # NOTE: Python 2.x uses 'int' values for 'size' and 'consumed' (changed in 3.0) unicode PyUnicode_DecodeMBCSStateful(char *s, Py_ssize_t size, char *errors, Py_ssize_t *consumed) # Encode the Py_UNICODE buffer of the given size using MBCS and # return a Python string object. Return NULL if an exception was # raised by the codec. bytes PyUnicode_EncodeMBCS(Py_UNICODE *s, Py_ssize_t size, char *errors) # Encode a Unicode objects using MBCS and return the result as # Python string object. Error handling is ``strict''. Return NULL # if an exception was raised by the codec. bytes PyUnicode_AsMBCSString(object o) # Encode the Unicode object using the specified code page and return # a Python bytes object. Return NULL if an exception was raised by the # codec. Use CP_ACP code page to get the MBCS encoder. # # New in version 3.3. bytes PyUnicode_EncodeCodePage(int code_page, object unicode, const char *errors) # Py_UCS4 helpers (new in CPython 3.3) # These utility functions work on strings of Py_UCS4 characters and # otherwise behave like the C standard library functions with the same name. size_t Py_UCS4_strlen(const Py_UCS4 *u) Py_UCS4* Py_UCS4_strcpy(Py_UCS4 *s1, const Py_UCS4 *s2) Py_UCS4* Py_UCS4_strncpy(Py_UCS4 *s1, const Py_UCS4 *s2, size_t n) Py_UCS4* Py_UCS4_strcat(Py_UCS4 *s1, const Py_UCS4 *s2) int Py_UCS4_strcmp(const Py_UCS4 *s1, const Py_UCS4 *s2) int Py_UCS4_strncmp(const Py_UCS4 *s1, const Py_UCS4 *s2, size_t n) Py_UCS4* Py_UCS4_strchr(const Py_UCS4 *s, Py_UCS4 c) Py_UCS4* Py_UCS4_strrchr(const Py_UCS4 *s, Py_UCS4 c) Cython-0.23.4/Cython/Includes/cpython/type.pxd0000644000175600017570000000344712606202452022410 0ustar jenkinsjenkins00000000000000 cdef extern from "Python.h": # The C structure of the objects used to describe built-in types. ############################################################################ # 7.1.1 Type Objects ############################################################################ ctypedef class __builtin__.type [object PyTypeObject]: pass # PyObject* PyType_Type # This is the type object for type objects; it is the same object # as type and types.TypeType in the Python layer. bint PyType_Check(object o) # Return true if the object o is a type object, including # instances of types derived from the standard type object. Return # false in all other cases. bint PyType_CheckExact(object o) # Return true if the object o is a type object, but not a subtype # of the standard type object. Return false in all other # cases. bint PyType_HasFeature(object o, int feature) # Return true if the type object o sets the feature feature. Type # features are denoted by single bit flags. bint PyType_IS_GC(object o) # Return true if the type object includes support for the cycle # detector; this tests the type flag Py_TPFLAGS_HAVE_GC. bint PyType_IsSubtype(type a, type b) # Return true if a is a subtype of b. object PyType_GenericAlloc(object type, Py_ssize_t nitems) # Return value: New reference. object PyType_GenericNew(type type, object args, object kwds) # Return value: New reference. bint PyType_Ready(type type) except -1 # Finalize a type object. This should be called on all type # objects to finish their initialization. This function is # responsible for adding inherited slots from a type's base # class. Return 0 on success, or return -1 and sets an exception # on error. Cython-0.23.4/Cython/Includes/cpython/tuple.pxd0000644000175600017570000000617412606202452022560 0ustar jenkinsjenkins00000000000000from .object cimport PyObject cdef extern from "Python.h": ############################################################################ # Tuples ############################################################################ bint PyTuple_Check(object p) # Return true if p is a tuple object or an instance of a subtype # of the tuple type. bint PyTuple_CheckExact(object p) # Return true if p is a tuple object, but not an instance of a subtype of the tuple type. tuple PyTuple_New(Py_ssize_t len) # Return value: New reference. # Return a new tuple object of size len, or NULL on failure. tuple PyTuple_Pack(Py_ssize_t n, ...) # Return value: New reference. # Return a new tuple object of size n, or NULL on failure. The # tuple values are initialized to the subsequent n C arguments # pointing to Python objects. "PyTuple_Pack(2, a, b)" is # equivalent to "Py_BuildValue("(OO)", a, b)". Py_ssize_t PyTuple_Size(object p) except -1 # Take a pointer to a tuple object, and return the size of that tuple. Py_ssize_t PyTuple_GET_SIZE(object p) # Return the size of the tuple p, which must be non-NULL and point # to a tuple; no error checking is performed. PyObject* PyTuple_GetItem(object p, Py_ssize_t pos) except NULL # Return value: Borrowed reference. # Return the object at position pos in the tuple pointed to by # p. If pos is out of bounds, return NULL and sets an IndexError # exception. PyObject* PyTuple_GET_ITEM(object p, Py_ssize_t pos) # Return value: Borrowed reference. # Like PyTuple_GetItem(), but does no checking of its arguments. tuple PyTuple_GetSlice(object p, Py_ssize_t low, Py_ssize_t high) # Return value: New reference. # Take a slice of the tuple pointed to by p from low to high and return it as a new tuple. int PyTuple_SetItem(object p, Py_ssize_t pos, object o) # Insert a reference to object o at position pos of the tuple # pointed to by p. Return 0 on success. Note: This function # ``steals'' a reference to o. void PyTuple_SET_ITEM(object p, Py_ssize_t pos, object o) # Like PyTuple_SetItem(), but does no error checking, and should # only be used to fill in brand new tuples. Note: This function # ``steals'' a reference to o. int _PyTuple_Resize(PyObject **p, Py_ssize_t newsize) except -1 # Can be used to resize a tuple. newsize will be the new length of # the tuple. Because tuples are supposed to be immutable, this # should only be used if there is only one reference to the # object. Do not use this if the tuple may already be known to # some other part of the code. The tuple will always grow or # shrink at the end. Think of this as destroying the old tuple and # creating a new one, only more efficiently. Returns 0 on # success. Client code should never assume that the resulting # value of *p will be the same as before calling this function. If # the object referenced by *p is replaced, the original *p is # destroyed. On failure, returns -1 and sets *p to NULL, and # raises MemoryError or SystemError. Cython-0.23.4/Cython/Includes/cpython/string.pxd0000644000175600017570000002333012606202452022726 0ustar jenkinsjenkins00000000000000from .object cimport PyObject cdef extern from "Python.h": ctypedef struct va_list ############################################################################ # 7.3.1 String Objects ############################################################################ # These functions raise TypeError when expecting a string # parameter and are called with a non-string parameter. # PyStringObject # This subtype of PyObject represents a Python string object. # PyTypeObject PyString_Type # This instance of PyTypeObject represents the Python string type; # it is the same object as str and types.StringType in the Python # layer. bint PyString_Check(object o) # Return true if the object o is a string object or an instance of # a subtype of the string type. bint PyString_CheckExact(object o) # Return true if the object o is a string object, but not an instance of a subtype of the string type. object PyString_FromString(char *v) # Return value: New reference. # Return a new string object with the value v on success, and NULL # on failure. The parameter v must not be NULL; it will not be # checked. object PyString_FromStringAndSize(char *v, Py_ssize_t len) # Return value: New reference. # Return a new string object with the value v and length len on # success, and NULL on failure. If v is NULL, the contents of the # string are uninitialized. object PyString_FromFormat(char *format, ...) # Return value: New reference. # Take a C printf()-style format string and a variable number of # arguments, calculate the size of the resulting Python string and # return a string with the values formatted into it. The variable # arguments must be C types and must correspond exactly to the # format characters in the format string. The following format # characters are allowed: # Format Characters Type Comment # %% n/a The literal % character. # %c int A single character, represented as an C int. # %d int Exactly equivalent to printf("%d"). # %u unsigned int Exactly equivalent to printf("%u"). # %ld long Exactly equivalent to printf("%ld"). # %lu unsigned long Exactly equivalent to printf("%lu"). # %zd Py_ssize_t Exactly equivalent to printf("%zd"). # %zu size_t Exactly equivalent to printf("%zu"). # %i int Exactly equivalent to printf("%i"). # %x int Exactly equivalent to printf("%x"). # %s char* A null-terminated C character array. # %p void* The hex representation of a C pointer. # Mostly equivalent to printf("%p") except that it is guaranteed to # start with the literal 0x regardless of what the platform's printf # yields. # An unrecognized format character causes all the rest of the # format string to be copied as-is to the result string, and any # extra arguments discarded. object PyString_FromFormatV(char *format, va_list vargs) # Return value: New reference. # Identical to PyString_FromFormat() except that it takes exactly two arguments. Py_ssize_t PyString_Size(object string) except -1 # Return the length of the string in string object string. Py_ssize_t PyString_GET_SIZE(object string) # Macro form of PyString_Size() but without error checking. char* PyString_AsString(object string) except NULL # Return a NUL-terminated representation of the contents of # string. The pointer refers to the internal buffer of string, not # a copy. The data must not be modified in any way, unless the # string was just created using PyString_FromStringAndSize(NULL, # size). It must not be deallocated. If string is a Unicode # object, this function computes the default encoding of string # and operates on that. If string is not a string object at all, # PyString_AsString() returns NULL and raises TypeError. char* PyString_AS_STRING(object string) # Macro form of PyString_AsString() but without error # checking. Only string objects are supported; no Unicode objects # should be passed. int PyString_AsStringAndSize(object obj, char **buffer, Py_ssize_t *length) except -1 # Return a NULL-terminated representation of the contents of the # object obj through the output variables buffer and length. # # The function accepts both string and Unicode objects as # input. For Unicode objects it returns the default encoded # version of the object. If length is NULL, the resulting buffer # may not contain NUL characters; if it does, the function returns # -1 and a TypeError is raised. # The buffer refers to an internal string buffer of obj, not a # copy. The data must not be modified in any way, unless the # string was just created using PyString_FromStringAndSize(NULL, # size). It must not be deallocated. If string is a Unicode # object, this function computes the default encoding of string # and operates on that. If string is not a string object at all, # PyString_AsStringAndSize() returns -1 and raises TypeError. void PyString_Concat(PyObject **string, object newpart) # Create a new string object in *string containing the contents of # newpart appended to string; the caller will own the new # reference. The reference to the old value of string will be # stolen. If the new string cannot be created, the old reference # to string will still be discarded and the value of *string will # be set to NULL; the appropriate exception will be set. void PyString_ConcatAndDel(PyObject **string, object newpart) # Create a new string object in *string containing the contents of # newpart appended to string. This version decrements the # reference count of newpart. int _PyString_Resize(PyObject **string, Py_ssize_t newsize) except -1 # A way to resize a string object even though it is # ``immutable''. Only use this to build up a brand new string # object; don't use this if the string may already be known in # other parts of the code. It is an error to call this function if # the refcount on the input string object is not one. Pass the # address of an existing string object as an lvalue (it may be # written into), and the new size desired. On success, *string # holds the resized string object and 0 is returned; the address # in *string may differ from its input value. If the reallocation # fails, the original string object at *string is deallocated, # *string is set to NULL, a memory exception is set, and -1 is # returned. object PyString_Format(object format, object args) # Return value: New reference. Return a new string object from # format and args. Analogous to format % args. The args argument # must be a tuple. void PyString_InternInPlace(PyObject **string) # Intern the argument *string in place. The argument must be the # address of a pointer variable pointing to a Python string # object. If there is an existing interned string that is the same # as *string, it sets *string to it (decrementing the reference # count of the old string object and incrementing the reference # count of the interned string object), otherwise it leaves # *string alone and interns it (incrementing its reference # count). (Clarification: even though there is a lot of talk about # reference counts, think of this function as # reference-count-neutral; you own the object after the call if # and only if you owned it before the call.) object PyString_InternFromString(char *v) # Return value: New reference. # A combination of PyString_FromString() and # PyString_InternInPlace(), returning either a new string object # that has been interned, or a new (``owned'') reference to an # earlier interned string object with the same value. object PyString_Decode(char *s, Py_ssize_t size, char *encoding, char *errors) # Return value: New reference. # Create an object by decoding size bytes of the encoded buffer s # using the codec registered for encoding. encoding and errors # have the same meaning as the parameters of the same name in the # unicode() built-in function. The codec to be used is looked up # using the Python codec registry. Return NULL if an exception was # raised by the codec. object PyString_AsDecodedObject(object str, char *encoding, char *errors) # Return value: New reference. # Decode a string object by passing it to the codec registered for # encoding and return the result as Python object. encoding and # errors have the same meaning as the parameters of the same name # in the string encode() method. The codec to be used is looked up # using the Python codec registry. Return NULL if an exception was # raised by the codec. object PyString_Encode(char *s, Py_ssize_t size, char *encoding, char *errors) # Return value: New reference. # Encode the char buffer of the given size by passing it to the # codec registered for encoding and return a Python # object. encoding and errors have the same meaning as the # parameters of the same name in the string encode() method. The # codec to be used is looked up using the Python codec # registry. Return NULL if an exception was raised by the codec. object PyString_AsEncodedObject(object str, char *encoding, char *errors) # Return value: New reference. # Encode a string object using the codec registered for encoding # and return the result as Python object. encoding and errors have # the same meaning as the parameters of the same name in the # string encode() method. The codec to be used is looked up using # the Python codec registry. Return NULL if an exception was # raised by the codec. Cython-0.23.4/Cython/Includes/cpython/slice.pxd0000644000175600017570000000410112606202452022512 0ustar jenkinsjenkins00000000000000cdef extern from "Python.h": # PyTypeObject PySlice_Type # # The type object for slice objects. This is the same as slice and types.SliceType bint PySlice_Check(object ob) # # Return true if ob is a slice object; ob must not be NULL. slice PySlice_New(object start, object stop, object step) # # Return a new slice object with the given values. The start, stop, and step # parameters are used as the values of the slice object attributes of the same # names. Any of the values may be NULL, in which case the None will be used # for the corresponding attribute. Return NULL if the new object could not be # allocated. int PySlice_GetIndices(object slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step) except? -1 # # Retrieve the start, stop and step indices from the slice object slice, # assuming a sequence of length length. Treats indices greater than length # as errors. # # Returns 0 on success and -1 on error with no exception set (unless one # of the indices was not None and failed to be converted to an integer, # in which case -1 is returned with an exception set). # # You probably do not want to use this function. # # Changed in version 3.2: The parameter type for the slice parameter was # PySliceObject* before. int PySlice_GetIndicesEx(object slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength) except -1 # # Usable replacement for PySlice_GetIndices(). Retrieve the start, stop, and step # indices from the slice object slice assuming a sequence of length length, and # store the length of the slice in slicelength. Out of bounds indices are clipped # in a manner consistent with the handling of normal slices. # # Returns 0 on success and -1 on error with exception set. # # Changed in version 3.2: The parameter type for the slice parameter was # PySliceObject* before. Cython-0.23.4/Cython/Includes/cpython/set.pxd0000644000175600017570000001206312606202452022214 0ustar jenkinsjenkins00000000000000cdef extern from "Python.h": ############################################################################ # 7.5.14 Set Objects ############################################################################ # This section details the public API for set and frozenset # objects. Any functionality not listed below is best accessed # using the either the abstract object protocol (including # PyObject_CallMethod(), PyObject_RichCompareBool(), # PyObject_Hash(), PyObject_Repr(), PyObject_IsTrue(), # PyObject_Print(), and PyObject_GetIter()) or the abstract number # protocol (including PyNumber_Add(), PyNumber_Subtract(), # PyNumber_Or(), PyNumber_Xor(), PyNumber_InPlaceAdd(), # PyNumber_InPlaceSubtract(), PyNumber_InPlaceOr(), and # PyNumber_InPlaceXor()). # PySetObject # This subtype of PyObject is used to hold the internal data for # both set and frozenset objects. It is like a PyDictObject in # that it is a fixed size for small sets (much like tuple storage) # and will point to a separate, variable sized block of memory for # medium and large sized sets (much like list storage). None of # the fields of this structure should be considered public and are # subject to change. All access should be done through the # documented API rather than by manipulating the values in the # structure. # PyTypeObject PySet_Type # This is an instance of PyTypeObject representing the Python set type. # PyTypeObject PyFrozenSet_Type # This is an instance of PyTypeObject representing the Python frozenset type. # The following type check macros work on pointers to any Python # object. Likewise, the constructor functions work with any # iterable Python object. bint PyAnySet_Check(object p) # Return true if p is a set object, a frozenset object, or an # instance of a subtype. bint PyAnySet_CheckExact(object p) # Return true if p is a set object or a frozenset object but not # an instance of a subtype. bint PyFrozenSet_CheckExact(object p) # Return true if p is a frozenset object but not an instance of a subtype. object PySet_New(object iterable) # Return value: New reference. # Return a new set containing objects returned by the # iterable. The iterable may be NULL to create a new empty # set. Return the new set on success or NULL on failure. Raise # TypeError if iterable is not actually iterable. The constructor # is also useful for copying a set (c=set(s)). object PyFrozenSet_New(object iterable) # Return value: New reference. # Return a new frozenset containing objects returned by the # iterable. The iterable may be NULL to create a new empty # frozenset. Return the new set on success or NULL on # failure. Raise TypeError if iterable is not actually iterable. # The following functions and macros are available for instances # of set or frozenset or instances of their subtypes. Py_ssize_t PySet_Size(object anyset) except -1 # Return the length of a set or frozenset object. Equivalent to # "len(anyset)". Raises a PyExc_SystemError if anyset is not a # set, frozenset, or an instance of a subtype. Py_ssize_t PySet_GET_SIZE(object anyset) # Macro form of PySet_Size() without error checking. bint PySet_Contains(object anyset, object key) except -1 # Return 1 if found, 0 if not found, and -1 if an error is # encountered. Unlike the Python __contains__() method, this # function does not automatically convert unhashable sets into # temporary frozensets. Raise a TypeError if the key is # unhashable. Raise PyExc_SystemError if anyset is not a set, # frozenset, or an instance of a subtype. # The following functions are available for instances of set or # its subtypes but not for instances of frozenset or its subtypes. int PySet_Add(object set, object key) except -1 # Add key to a set instance. Does not apply to frozenset # instances. Return 0 on success or -1 on failure. Raise a # TypeError if the key is unhashable. Raise a MemoryError if there # is no room to grow. Raise a SystemError if set is an not an # instance of set or its subtype. bint PySet_Discard(object set, object key) except -1 # Return 1 if found and removed, 0 if not found (no action taken), # and -1 if an error is encountered. Does not raise KeyError for # missing keys. Raise a TypeError if the key is unhashable. Unlike # the Python discard() method, this function does not # automatically convert unhashable sets into temporary # frozensets. Raise PyExc_SystemError if set is an not an instance # of set or its subtype. object PySet_Pop(object set) # Return value: New reference. # Return a new reference to an arbitrary object in the set, and # removes the object from the set. Return NULL on failure. Raise # KeyError if the set is empty. Raise a SystemError if set is an # not an instance of set or its subtype. int PySet_Clear(object set) # Empty an existing set of all elements. Cython-0.23.4/Cython/Includes/cpython/sequence.pxd0000644000175600017570000001357012606202452023235 0ustar jenkinsjenkins00000000000000from .object cimport PyObject cdef extern from "Python.h": ############################################################################ # 6.3 Sequence Protocol ############################################################################ bint PySequence_Check(object o) # Return 1 if the object provides sequence protocol, and 0 # otherwise. This function always succeeds. Py_ssize_t PySequence_Size(object o) except -1 # Returns the number of objects in sequence o on success, and -1 # on failure. For objects that do not provide sequence protocol, # this is equivalent to the Python expression "len(o)". Py_ssize_t PySequence_Length(object o) except -1 # Alternate name for PySequence_Size(). object PySequence_Concat(object o1, object o2) # Return value: New reference. # Return the concatenation of o1 and o2 on success, and NULL on # failure. This is the equivalent of the Python expression "o1 + # o2". object PySequence_Repeat(object o, Py_ssize_t count) # Return value: New reference. # Return the result of repeating sequence object o count times, or # NULL on failure. This is the equivalent of the Python expression # "o * count". object PySequence_InPlaceConcat(object o1, object o2) # Return value: New reference. # Return the concatenation of o1 and o2 on success, and NULL on # failure. The operation is done in-place when o1 supports # it. This is the equivalent of the Python expression "o1 += o2". object PySequence_InPlaceRepeat(object o, Py_ssize_t count) # Return value: New reference. # Return the result of repeating sequence object o count times, or # NULL on failure. The operation is done in-place when o supports # it. This is the equivalent of the Python expression "o *= # count". object PySequence_GetItem(object o, Py_ssize_t i) # Return value: New reference. # Return the ith element of o, or NULL on failure. This is the # equivalent of the Python expression "o[i]". object PySequence_GetSlice(object o, Py_ssize_t i1, Py_ssize_t i2) # Return value: New reference. # Return the slice of sequence object o between i1 and i2, or NULL # on failure. This is the equivalent of the Python expression # "o[i1:i2]". int PySequence_SetItem(object o, Py_ssize_t i, object v) except -1 # Assign object v to the ith element of o. Returns -1 on # failure. This is the equivalent of the Python statement "o[i] = # v". This function does not steal a reference to v. int PySequence_DelItem(object o, Py_ssize_t i) except -1 # Delete the ith element of object o. Returns -1 on failure. This # is the equivalent of the Python statement "del o[i]". int PySequence_SetSlice(object o, Py_ssize_t i1, Py_ssize_t i2, object v) except -1 # Assign the sequence object v to the slice in sequence object o # from i1 to i2. This is the equivalent of the Python statement # "o[i1:i2] = v". int PySequence_DelSlice(object o, Py_ssize_t i1, Py_ssize_t i2) except -1 # Delete the slice in sequence object o from i1 to i2. Returns -1 # on failure. This is the equivalent of the Python statement "del # o[i1:i2]". int PySequence_Count(object o, object value) except -1 # Return the number of occurrences of value in o, that is, return # the number of keys for which o[key] == value. On failure, return # -1. This is equivalent to the Python expression # "o.count(value)". int PySequence_Contains(object o, object value) except -1 # Determine if o contains value. If an item in o is equal to # value, return 1, otherwise return 0. On error, return -1. This # is equivalent to the Python expression "value in o". Py_ssize_t PySequence_Index(object o, object value) except -1 # Return the first index i for which o[i] == value. On error, # return -1. This is equivalent to the Python expression # "o.index(value)". object PySequence_List(object o) # Return value: New reference. # Return a list object with the same contents as the arbitrary # sequence o. The returned list is guaranteed to be new. object PySequence_Tuple(object o) # Return value: New reference. # Return a tuple object with the same contents as the arbitrary # sequence o or NULL on failure. If o is a tuple, a new reference # will be returned, otherwise a tuple will be constructed with the # appropriate contents. This is equivalent to the Python # expression "tuple(o)". object PySequence_Fast(object o, char *m) # Return value: New reference. # Returns the sequence o as a tuple, unless it is already a tuple # or list, in which case o is returned. Use # PySequence_Fast_GET_ITEM() to access the members of the # result. Returns NULL on failure. If the object is not a # sequence, raises TypeError with m as the message text. PyObject* PySequence_Fast_GET_ITEM(object o, Py_ssize_t i) # Return value: Borrowed reference. # Return the ith element of o, assuming that o was returned by # PySequence_Fast(), o is not NULL, and that i is within bounds. PyObject** PySequence_Fast_ITEMS(object o) # Return the underlying array of PyObject pointers. Assumes that o # was returned by PySequence_Fast() and o is not NULL. object PySequence_ITEM(object o, Py_ssize_t i) # Return value: New reference. # Return the ith element of o or NULL on failure. Macro form of # PySequence_GetItem() but without checking that # PySequence_Check(o) is true and without adjustment for negative # indices. Py_ssize_t PySequence_Fast_GET_SIZE(object o) # Returns the length of o, assuming that o was returned by # PySequence_Fast() and that o is not NULL. The size can also be # gotten by calling PySequence_Size() on o, but # PySequence_Fast_GET_SIZE() is faster because it can assume o is # a list or tuple. Cython-0.23.4/Cython/Includes/cpython/ref.pxd0000644000175600017570000000477512606202452022210 0ustar jenkinsjenkins00000000000000from .object cimport PyObject, PyTypeObject, Py_TYPE # legacy imports for re-export cdef extern from "Python.h": ##################################################################### # 3. Reference Counts ##################################################################### # The macros in this section are used for managing reference counts of Python objects. void Py_INCREF(object o) # Increment the reference count for object o. The object must not # be NULL; if you aren't sure that it isn't NULL, use # Py_XINCREF(). void Py_XINCREF(PyObject* o) # Increment the reference count for object o. The object may be NULL, in which case the macro has no effect. void Py_DECREF(object o) # Decrement the reference count for object o. The object must not # be NULL; if you aren't sure that it isn't NULL, use # Py_XDECREF(). If the reference count reaches zero, the object's # type's deallocation function (which must not be NULL) is # invoked. # Warning: The deallocation function can cause arbitrary Python # code to be invoked (e.g. when a class instance with a __del__() # method is deallocated). While exceptions in such code are not # propagated, the executed code has free access to all Python # global variables. This means that any object that is reachable # from a global variable should be in a consistent state before # Py_DECREF() is invoked. For example, code to delete an object # from a list should copy a reference to the deleted object in a # temporary variable, update the list data structure, and then # call Py_DECREF() for the temporary variable. void Py_XDECREF(PyObject* o) # Decrement the reference count for object o. The object may be # NULL, in which case the macro has no effect; otherwise the # effect is the same as for Py_DECREF(), and the same warning # applies. void Py_CLEAR(PyObject* o) # Decrement the reference count for object o. The object may be # NULL, in which case the macro has no effect; otherwise the # effect is the same as for Py_DECREF(), except that the argument # is also set to NULL. The warning for Py_DECREF() does not apply # with respect to the object passed because the macro carefully # uses a temporary variable and sets the argument to NULL before # decrementing its reference count. # It is a good idea to use this macro whenever decrementing the # value of a variable that might be traversed during garbage # collection. Cython-0.23.4/Cython/Includes/cpython/pythread.pxd0000644000175600017570000000216712606202452023245 0ustar jenkinsjenkins00000000000000 cdef extern from "pythread.h": ctypedef void *PyThread_type_lock ctypedef void *PyThread_type_sema void PyThread_init_thread() long PyThread_start_new_thread(void (*)(void *), void *) void PyThread_exit_thread() long PyThread_get_thread_ident() PyThread_type_lock PyThread_allocate_lock() void PyThread_free_lock(PyThread_type_lock) int PyThread_acquire_lock(PyThread_type_lock, int mode) nogil void PyThread_release_lock(PyThread_type_lock) nogil enum: # 'mode' in PyThread_acquire_lock() WAIT_LOCK # 1 NOWAIT_LOCK # 0 ctypedef enum PyLockStatus: # return values of PyThread_acquire_lock() in CPython 3.2+ PY_LOCK_FAILURE = 0 PY_LOCK_ACQUIRED = 1 PY_LOCK_INTR size_t PyThread_get_stacksize() int PyThread_set_stacksize(size_t) # Thread Local Storage (TLS) API int PyThread_create_key() void PyThread_delete_key(int) int PyThread_set_key_value(int, void *) void * PyThread_get_key_value(int) void PyThread_delete_key_value(int key) # Cleanup after a fork void PyThread_ReInitTLS() Cython-0.23.4/Cython/Includes/cpython/pystate.pxd0000644000175600017570000000664312606202452023121 0ustar jenkinsjenkins00000000000000# Thread and interpreter state structures and their interfaces from .object cimport PyObject cdef extern from "Python.h": # We make these an opague types. If the user wants specific attributes, # they can be declared manually. ctypedef struct PyInterpreterState: pass ctypedef struct PyThreadState: pass ctypedef struct PyFrameObject: pass # This is not actually a struct, but make sure it can never be coerced to # an int or used in arithmetic expressions ctypedef struct PyGILState_STATE # The type of the trace function registered using PyEval_SetProfile() and # PyEval_SetTrace(). # Py_tracefunc return -1 when raising an exception, or 0 for success. ctypedef int (*Py_tracefunc)(PyObject *, PyFrameObject *, int, PyObject *) # The following values are used for 'what' for tracefunc functions enum: PyTrace_CALL PyTrace_EXCEPTION PyTrace_LINE PyTrace_RETURN PyTrace_C_CALL PyTrace_C_EXCEPTION PyTrace_C_RETURN PyInterpreterState * PyInterpreterState_New() void PyInterpreterState_Clear(PyInterpreterState *) void PyInterpreterState_Delete(PyInterpreterState *) PyThreadState * PyThreadState_New(PyInterpreterState *) void PyThreadState_Clear(PyThreadState *) void PyThreadState_Delete(PyThreadState *) PyThreadState * PyThreadState_Get() PyThreadState * PyThreadState_Swap(PyThreadState *) PyObject * PyThreadState_GetDict() int PyThreadState_SetAsyncExc(long, PyObject *) # Ensure that the current thread is ready to call the Python # C API, regardless of the current state of Python, or of its # thread lock. This may be called as many times as desired # by a thread so long as each call is matched with a call to # PyGILState_Release(). In general, other thread-state APIs may # be used between _Ensure() and _Release() calls, so long as the # thread-state is restored to its previous state before the Release(). # For example, normal use of the Py_BEGIN_ALLOW_THREADS/ # Py_END_ALLOW_THREADS macros are acceptable. # The return value is an opaque "handle" to the thread state when # PyGILState_Ensure() was called, and must be passed to # PyGILState_Release() to ensure Python is left in the same state. Even # though recursive calls are allowed, these handles can *not* be shared - # each unique call to PyGILState_Ensure must save the handle for its # call to PyGILState_Release. # When the function returns, the current thread will hold the GIL. # Failure is a fatal error. PyGILState_STATE PyGILState_Ensure() # Release any resources previously acquired. After this call, Python's # state will be the same as it was prior to the corresponding # PyGILState_Ensure() call (but generally this state will be unknown to # the caller, hence the use of the GILState API.) # Every call to PyGILState_Ensure must be matched by a call to # PyGILState_Release on the same thread. void PyGILState_Release(PyGILState_STATE) # Routines for advanced debuggers, requested by David Beazley. # Don't use unless you know what you are doing! PyInterpreterState * PyInterpreterState_Head() PyInterpreterState * PyInterpreterState_Next(PyInterpreterState *) PyThreadState * PyInterpreterState_ThreadHead(PyInterpreterState *) PyThreadState * PyThreadState_Next(PyThreadState *) Cython-0.23.4/Cython/Includes/cpython/pycapsule.pxd0000644000175600017570000001313112606202452023423 0ustar jenkinsjenkins00000000000000 # available since Python 3.1! # note all char* in the below functions are actually const char* cdef extern from "Python.h": ctypedef struct PyCapsule_Type # This subtype of PyObject represents an opaque value, useful for # C extension modules who need to pass an opaque value (as a void* # pointer) through Python code to other C code. It is often used # to make a C function pointer defined in one module available to # other modules, so the regular import mechanism can be used to # access C APIs defined in dynamically loaded modules. ctypedef void (*PyCapsule_Destructor)(object o) # The type of a destructor callback for a capsule. # # See PyCapsule_New() for the semantics of PyCapsule_Destructor # callbacks. bint PyCapsule_CheckExact(object o) # Return true if its argument is a PyCapsule. object PyCapsule_New(void *pointer, char *name, PyCapsule_Destructor destructor) # Return value: New reference. # # Create a PyCapsule encapsulating the pointer. The pointer # argument may not be NULL. # # On failure, set an exception and return NULL. # # The name string may either be NULL or a pointer to a valid C # string. If non-NULL, this string must outlive the # capsule. (Though it is permitted to free it inside the # destructor.) # # If the destructor argument is not NULL, it will be called with # the capsule as its argument when it is destroyed. # # If this capsule will be stored as an attribute of a module, the # name should be specified as modulename.attributename. This will # enable other modules to import the capsule using # PyCapsule_Import(). void* PyCapsule_GetPointer(object capsule, char *name) except? NULL # Retrieve the pointer stored in the capsule. On failure, set an # exception and return NULL. # # The name parameter must compare exactly to the name stored in # the capsule. If the name stored in the capsule is NULL, the name # passed in must also be NULL. Python uses the C function strcmp() # to compare capsule names. PyCapsule_Destructor PyCapsule_GetDestructor(object capsule) except? NULL # Return the current destructor stored in the capsule. On failure, # set an exception and return NULL. # # It is legal for a capsule to have a NULL destructor. This makes # a NULL return code somewhat ambiguous; use PyCapsule_IsValid() # or PyErr_Occurred() to disambiguate. char* PyCapsule_GetName(object capsule) except? NULL # Return the current name stored in the capsule. On failure, set # an exception and return NULL. # # It is legal for a capsule to have a NULL name. This makes a NULL # return code somewhat ambiguous; use PyCapsule_IsValid() or # PyErr_Occurred() to disambiguate. void* PyCapsule_GetContext(object capsule) except? NULL # Return the current context stored in the capsule. On failure, # set an exception and return NULL. # # It is legal for a capsule to have a NULL context. This makes a # NULL return code somewhat ambiguous; use PyCapsule_IsValid() or # PyErr_Occurred() to disambiguate. bint PyCapsule_IsValid(object capsule, char *name) # Determines whether or not capsule is a valid capsule. A valid # capsule is non-NULL, passes PyCapsule_CheckExact(), has a # non-NULL pointer stored in it, and its internal name matches the # name parameter. (See PyCapsule_GetPointer() for information on # how capsule names are compared.) # # In other words, if PyCapsule_IsValid() returns a true value, # calls to any of the accessors (any function starting with # PyCapsule_Get()) are guaranteed to succeed. # # Return a nonzero value if the object is valid and matches the # name passed in. Return 0 otherwise. This function will not fail. int PyCapsule_SetPointer(object capsule, void *pointer) except -1 # Set the void pointer inside capsule to pointer. The pointer may # not be NULL. # # Return 0 on success. Return nonzero and set an exception on # failure. int PyCapsule_SetDestructor(object capsule, PyCapsule_Destructor destructor) except -1 # Set the destructor inside capsule to destructor. # # Return 0 on success. Return nonzero and set an exception on # failure. int PyCapsule_SetName(object capsule, char *name) except -1 # Set the name inside capsule to name. If non-NULL, the name must # outlive the capsule. If the previous name stored in the capsule # was not NULL, no attempt is made to free it. # # Return 0 on success. Return nonzero and set an exception on # failure. int PyCapsule_SetContext(object capsule, void *context) except -1 # Set the context pointer inside capsule to context. Return 0 on # success. Return nonzero and set an exception on failure. void* PyCapsule_Import(char *name, int no_block) except? NULL # Import a pointer to a C object from a capsule attribute in a # module. The name parameter should specify the full name to the # attribute, as in module.attribute. The name stored in the # capsule must match this string exactly. If no_block is true, # import the module without blocking (using # PyImport_ImportModuleNoBlock()). If no_block is false, import # the module conventionally (using PyImport_ImportModule()). # # Return the capsule’s internal pointer on success. On failure, # set an exception and return NULL. However, if PyCapsule_Import() # failed to import the module, and no_block was true, no exception # is set. Cython-0.23.4/Cython/Includes/cpython/oldbuffer.pxd0000644000175600017570000000554412606202452023377 0ustar jenkinsjenkins00000000000000# Legacy Python 2 buffer interface. # # These functions are no longer available in Python 3, use the new # buffer interface instead. cdef extern from "Python.h": cdef enum _: Py_END_OF_BUFFER # This constant may be passed as the size parameter to # PyBuffer_FromObject() or PyBuffer_FromReadWriteObject(). It # indicates that the new PyBufferObject should refer to base object # from the specified offset to the end of its exported # buffer. Using this enables the caller to avoid querying the base # object for its length. bint PyBuffer_Check(object p) # Return true if the argument has type PyBuffer_Type. object PyBuffer_FromObject(object base, Py_ssize_t offset, Py_ssize_t size) # Return value: New reference. # # Return a new read-only buffer object. This raises TypeError if # base doesn't support the read-only buffer protocol or doesn't # provide exactly one buffer segment, or it raises ValueError if # offset is less than zero. The buffer will hold a reference to the # base object, and the buffer's contents will refer to the base # object's buffer interface, starting as position offset and # extending for size bytes. If size is Py_END_OF_BUFFER, then the # new buffer's contents extend to the length of the base object's # exported buffer data. object PyBuffer_FromReadWriteObject(object base, Py_ssize_t offset, Py_ssize_t size) # Return value: New reference. # # Return a new writable buffer object. Parameters and exceptions # are similar to those for PyBuffer_FromObject(). If the base # object does not export the writeable buffer protocol, then # TypeError is raised. object PyBuffer_FromMemory(void *ptr, Py_ssize_t size) # Return value: New reference. # # Return a new read-only buffer object that reads from a specified # location in memory, with a specified size. The caller is # responsible for ensuring that the memory buffer, passed in as # ptr, is not deallocated while the returned buffer object # exists. Raises ValueError if size is less than zero. Note that # Py_END_OF_BUFFER may not be passed for the size parameter; # ValueError will be raised in that case. object PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size) # Return value: New reference. # # Similar to PyBuffer_FromMemory(), but the returned buffer is # writable. object PyBuffer_New(Py_ssize_t size) # Return value: New reference. # # Return a new writable buffer object that maintains its own memory # buffer of size bytes. ValueError is returned if size is not zero # or positive. Note that the memory buffer (as returned by # PyObject_AsWriteBuffer()) is not specifically aligned. Cython-0.23.4/Cython/Includes/cpython/object.pxd0000644000175600017570000004262412606202452022675 0ustar jenkinsjenkins00000000000000from libc.stdio cimport FILE cimport cpython.type cdef extern from "Python.h": ctypedef struct PyObject # forward declaration ctypedef object (*newfunc)(cpython.type.type, object, object) # (type, args, kwargs) ctypedef object (*unaryfunc)(object) ctypedef object (*binaryfunc)(object, object) ctypedef object (*ternaryfunc)(object, object, object) ctypedef int (*inquiry)(object) ctypedef Py_ssize_t (*lenfunc)(object) ctypedef object (*ssizeargfunc)(object, Py_ssize_t) ctypedef object (*ssizessizeargfunc)(object, Py_ssize_t, Py_ssize_t) ctypedef int (*ssizeobjargproc)(object, Py_ssize_t, object) ctypedef int (*ssizessizeobjargproc)(object, Py_ssize_t, Py_ssize_t, object) ctypedef int (*objobjargproc)(object, object, object) ctypedef int (*objobjproc)(object, object) ctypedef Py_hash_t (*hashfunc)(object) ctypedef object (*reprfunc)(object) ctypedef int (*cmpfunc)(object, object) ctypedef object (*richcmpfunc)(object, object, int) # The following functions use 'PyObject*' as first argument instead of 'object' to prevent # accidental reference counting when calling them during a garbage collection run. ctypedef void (*destructor)(PyObject*) ctypedef int (*visitproc)(PyObject*, void *) ctypedef int (*traverseproc)(PyObject*, visitproc, void*) ctypedef struct PyTypeObject: const char* tp_name const char* tp_doc Py_ssize_t tp_basicsize Py_ssize_t tp_itemsize Py_ssize_t tp_dictoffset unsigned long tp_flags newfunc tp_new destructor tp_dealloc traverseproc tp_traverse inquiry tp_clear ternaryfunc tp_call hashfunc tp_hash reprfunc tp_str reprfunc tp_repr cmpfunc tp_compare richcmpfunc tp_richcompare PyTypeObject* tp_base ctypedef struct PyObject: Py_ssize_t ob_refcnt PyTypeObject *ob_type cdef PyTypeObject *Py_TYPE(object) void* PyObject_Malloc(size_t) void* PyObject_Realloc(void *, size_t) void PyObject_Free(void *) ##################################################################### # 6.1 Object Protocol ##################################################################### int PyObject_Print(object o, FILE *fp, int flags) except -1 # Print an object o, on file fp. Returns -1 on error. The flags # argument is used to enable certain printing options. The only # option currently supported is Py_PRINT_RAW; if given, the str() # of the object is written instead of the repr(). bint PyObject_HasAttrString(object o, char *attr_name) # Returns 1 if o has the attribute attr_name, and 0 # otherwise. This is equivalent to the Python expression # "hasattr(o, attr_name)". This function always succeeds. object PyObject_GetAttrString(object o, char *attr_name) # Return value: New reference. Retrieve an attribute named # attr_name from object o. Returns the attribute value on success, # or NULL on failure. This is the equivalent of the Python # expression "o.attr_name". bint PyObject_HasAttr(object o, object attr_name) # Returns 1 if o has the attribute attr_name, and 0 # otherwise. This is equivalent to the Python expression # "hasattr(o, attr_name)". This function always succeeds. object PyObject_GetAttr(object o, object attr_name) # Return value: New reference. Retrieve an attribute named # attr_name from object o. Returns the attribute value on success, # or NULL on failure. This is the equivalent of the Python # expression "o.attr_name". int PyObject_SetAttrString(object o, char *attr_name, object v) except -1 # Set the value of the attribute named attr_name, for object o, to # the value v. Returns -1 on failure. This is the equivalent of # the Python statement "o.attr_name = v". int PyObject_SetAttr(object o, object attr_name, object v) except -1 # Set the value of the attribute named attr_name, for object o, to # the value v. Returns -1 on failure. This is the equivalent of # the Python statement "o.attr_name = v". int PyObject_DelAttrString(object o, char *attr_name) except -1 # Delete attribute named attr_name, for object o. Returns -1 on # failure. This is the equivalent of the Python statement: "del # o.attr_name". int PyObject_DelAttr(object o, object attr_name) except -1 # Delete attribute named attr_name, for object o. Returns -1 on # failure. This is the equivalent of the Python statement "del # o.attr_name". int Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, Py_GE object PyObject_RichCompare(object o1, object o2, int opid) # Return value: New reference. # Compare the values of o1 and o2 using the operation specified by # opid, which must be one of Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, or # Py_GE, corresponding to <, <=, ==, !=, >, or >= # respectively. This is the equivalent of the Python expression # "o1 op o2", where op is the operator corresponding to # opid. Returns the value of the comparison on success, or NULL on # failure. bint PyObject_RichCompareBool(object o1, object o2, int opid) except -1 # Compare the values of o1 and o2 using the operation specified by # opid, which must be one of Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, or # Py_GE, corresponding to <, <=, ==, !=, >, or >= # respectively. Returns -1 on error, 0 if the result is false, 1 # otherwise. This is the equivalent of the Python expression "o1 # op o2", where op is the operator corresponding to opid. int PyObject_Cmp(object o1, object o2, int *result) except -1 # Compare the values of o1 and o2 using a routine provided by o1, # if one exists, otherwise with a routine provided by o2. The # result of the comparison is returned in result. Returns -1 on # failure. This is the equivalent of the Python statement "result # = cmp(o1, o2)". int PyObject_Compare(object o1, object o2) except * # Compare the values of o1 and o2 using a routine provided by o1, # if one exists, otherwise with a routine provided by o2. Returns # the result of the comparison on success. On error, the value # returned is undefined; use PyErr_Occurred() to detect an # error. This is equivalent to the Python expression "cmp(o1, # o2)". object PyObject_Repr(object o) # Return value: New reference. # Compute a string representation of object o. Returns the string # representation on success, NULL on failure. This is the # equivalent of the Python expression "repr(o)". Called by the # repr() built-in function and by reverse quotes. object PyObject_Str(object o) # Return value: New reference. # Compute a string representation of object o. Returns the string # representation on success, NULL on failure. This is the # equivalent of the Python expression "str(o)". Called by the # str() built-in function and by the print statement. object PyObject_Unicode(object o) # Return value: New reference. # Compute a Unicode string representation of object o. Returns the # Unicode string representation on success, NULL on failure. This # is the equivalent of the Python expression "unicode(o)". Called # by the unicode() built-in function. bint PyObject_IsInstance(object inst, object cls) except -1 # Returns 1 if inst is an instance of the class cls or a subclass # of cls, or 0 if not. On error, returns -1 and sets an # exception. If cls is a type object rather than a class object, # PyObject_IsInstance() returns 1 if inst is of type cls. If cls # is a tuple, the check will be done against every entry in # cls. The result will be 1 when at least one of the checks # returns 1, otherwise it will be 0. If inst is not a class # instance and cls is neither a type object, nor a class object, # nor a tuple, inst must have a __class__ attribute -- the class # relationship of the value of that attribute with cls will be # used to determine the result of this function. # Subclass determination is done in a fairly straightforward way, # but includes a wrinkle that implementors of extensions to the # class system may want to be aware of. If A and B are class # objects, B is a subclass of A if it inherits from A either # directly or indirectly. If either is not a class object, a more # general mechanism is used to determine the class relationship of # the two objects. When testing if B is a subclass of A, if A is # B, PyObject_IsSubclass() returns true. If A and B are different # objects, B's __bases__ attribute is searched in a depth-first # fashion for A -- the presence of the __bases__ attribute is # considered sufficient for this determination. bint PyObject_IsSubclass(object derived, object cls) except -1 # Returns 1 if the class derived is identical to or derived from # the class cls, otherwise returns 0. In case of an error, returns # -1. If cls is a tuple, the check will be done against every # entry in cls. The result will be 1 when at least one of the # checks returns 1, otherwise it will be 0. If either derived or # cls is not an actual class object (or tuple), this function uses # the generic algorithm described above. New in version # 2.1. Changed in version 2.3: Older versions of Python did not # support a tuple as the second argument. bint PyCallable_Check(object o) # Determine if the object o is callable. Return 1 if the object is # callable and 0 otherwise. This function always succeeds. object PyObject_Call(object callable_object, object args, object kw) # Return value: New reference. # Call a callable Python object callable_object, with arguments # given by the tuple args, and named arguments given by the # dictionary kw. If no named arguments are needed, kw may be # NULL. args must not be NULL, use an empty tuple if no arguments # are needed. Returns the result of the call on success, or NULL # on failure. This is the equivalent of the Python expression # "apply(callable_object, args, kw)" or "callable_object(*args, # **kw)". object PyObject_CallObject(object callable_object, object args) # Return value: New reference. # Call a callable Python object callable_object, with arguments # given by the tuple args. If no arguments are needed, then args # may be NULL. Returns the result of the call on success, or NULL # on failure. This is the equivalent of the Python expression # "apply(callable_object, args)" or "callable_object(*args)". object PyObject_CallFunction(object callable, char *format, ...) # Return value: New reference. # Call a callable Python object callable, with a variable number # of C arguments. The C arguments are described using a # Py_BuildValue() style format string. The format may be NULL, # indicating that no arguments are provided. Returns the result of # the call on success, or NULL on failure. This is the equivalent # of the Python expression "apply(callable, args)" or # "callable(*args)". Note that if you only pass object args, # PyObject_CallFunctionObjArgs is a faster alternative. object PyObject_CallMethod(object o, char *method, char *format, ...) # Return value: New reference. # Call the method named method of object o with a variable number # of C arguments. The C arguments are described by a # Py_BuildValue() format string that should produce a tuple. The # format may be NULL, indicating that no arguments are # provided. Returns the result of the call on success, or NULL on # failure. This is the equivalent of the Python expression # "o.method(args)". Note that if you only pass object args, # PyObject_CallMethodObjArgs is a faster alternative. #object PyObject_CallFunctionObjArgs(object callable, ..., NULL) object PyObject_CallFunctionObjArgs(object callable, ...) # Return value: New reference. # Call a callable Python object callable, with a variable number # of PyObject* arguments. The arguments are provided as a variable # number of parameters followed by NULL. Returns the result of the # call on success, or NULL on failure. #PyObject* PyObject_CallMethodObjArgs(object o, object name, ..., NULL) object PyObject_CallMethodObjArgs(object o, object name, ...) # Return value: New reference. # Calls a method of the object o, where the name of the method is # given as a Python string object in name. It is called with a # variable number of PyObject* arguments. The arguments are # provided as a variable number of parameters followed by # NULL. Returns the result of the call on success, or NULL on # failure. long PyObject_Hash(object o) except? -1 # Compute and return the hash value of an object o. On failure, # return -1. This is the equivalent of the Python expression # "hash(o)". bint PyObject_IsTrue(object o) except -1 # Returns 1 if the object o is considered to be true, and 0 # otherwise. This is equivalent to the Python expression "not not # o". On failure, return -1. bint PyObject_Not(object o) except -1 # Returns 0 if the object o is considered to be true, and 1 # otherwise. This is equivalent to the Python expression "not # o". On failure, return -1. object PyObject_Type(object o) # Return value: New reference. # When o is non-NULL, returns a type object corresponding to the # object type of object o. On failure, raises SystemError and # returns NULL. This is equivalent to the Python expression # type(o). This function increments the reference count of the # return value. There's really no reason to use this function # instead of the common expression o->ob_type, which returns a # pointer of type PyTypeObject*, except when the incremented # reference count is needed. bint PyObject_TypeCheck(object o, PyTypeObject *type) # Return true if the object o is of type type or a subtype of # type. Both parameters must be non-NULL. Py_ssize_t PyObject_Length(object o) except -1 Py_ssize_t PyObject_Size(object o) except -1 # Return the length of object o. If the object o provides either # the sequence and mapping protocols, the sequence length is # returned. On error, -1 is returned. This is the equivalent to # the Python expression "len(o)". object PyObject_GetItem(object o, object key) # Return value: New reference. # Return element of o corresponding to the object key or NULL on # failure. This is the equivalent of the Python expression # "o[key]". int PyObject_SetItem(object o, object key, object v) except -1 # Map the object key to the value v. Returns -1 on failure. This # is the equivalent of the Python statement "o[key] = v". int PyObject_DelItem(object o, object key) except -1 # Delete the mapping for key from o. Returns -1 on failure. This # is the equivalent of the Python statement "del o[key]". int PyObject_AsFileDescriptor(object o) except -1 # Derives a file-descriptor from a Python object. If the object is # an integer or long integer, its value is returned. If not, the # object's fileno() method is called if it exists; the method must # return an integer or long integer, which is returned as the file # descriptor value. Returns -1 on failure. object PyObject_Dir(object o) # Return value: New reference. # This is equivalent to the Python expression "dir(o)", returning # a (possibly empty) list of strings appropriate for the object # argument, or NULL if there was an error. If the argument is # NULL, this is like the Python "dir()", returning the names of # the current locals; in this case, if no execution frame is # active then NULL is returned but PyErr_Occurred() will return # false. object PyObject_GetIter(object o) # Return value: New reference. # This is equivalent to the Python expression "iter(o)". It # returns a new iterator for the object argument, or the object # itself if the object is already an iterator. Raises TypeError # and returns NULL if the object cannot be iterated. Py_ssize_t Py_SIZE(object o) object PyObject_Format(object obj, object format_spec) # Takes an arbitrary object and returns the result of calling # obj.__format__(format_spec). # Added in Py2.6 # Type flags (tp_flags of PyTypeObject) long Py_TPFLAGS_HAVE_GETCHARBUFFER long Py_TPFLAGS_HAVE_SEQUENCE_IN long Py_TPFLAGS_HAVE_INPLACEOPS long Py_TPFLAGS_CHECKTYPES long Py_TPFLAGS_HAVE_RICHCOMPARE long Py_TPFLAGS_HAVE_WEAKREFS long Py_TPFLAGS_HAVE_ITER long Py_TPFLAGS_HAVE_CLASS long Py_TPFLAGS_HEAPTYPE long Py_TPFLAGS_BASETYPE long Py_TPFLAGS_READY long Py_TPFLAGS_READYING long Py_TPFLAGS_HAVE_GC long Py_TPFLAGS_HAVE_STACKLESS_EXTENSION long Py_TPFLAGS_HAVE_INDEX long Py_TPFLAGS_HAVE_VERSION_TAG long Py_TPFLAGS_VALID_VERSION_TAG long Py_TPFLAGS_IS_ABSTRACT long Py_TPFLAGS_HAVE_NEWBUFFER long Py_TPFLAGS_INT_SUBCLASS long Py_TPFLAGS_LONG_SUBCLASS long Py_TPFLAGS_LIST_SUBCLASS long Py_TPFLAGS_TUPLE_SUBCLASS long Py_TPFLAGS_STRING_SUBCLASS long Py_TPFLAGS_UNICODE_SUBCLASS long Py_TPFLAGS_DICT_SUBCLASS long Py_TPFLAGS_BASE_EXC_SUBCLASS long Py_TPFLAGS_TYPE_SUBCLASS long Py_TPFLAGS_DEFAULT_EXTERNAL long Py_TPFLAGS_DEFAULT_CORE long Py_TPFLAGS_DEFAULT Cython-0.23.4/Cython/Includes/cpython/number.pxd0000644000175600017570000002606312606202452022716 0ustar jenkinsjenkins00000000000000from .object cimport PyObject cdef extern from "Python.h": ##################################################################### # 6.2 Number Protocol ##################################################################### bint PyNumber_Check(object o) # Returns 1 if the object o provides numeric protocols, and false # otherwise. This function always succeeds. object PyNumber_Add(object o1, object o2) # Return value: New reference. # Returns the result of adding o1 and o2, or NULL on failure. This # is the equivalent of the Python expression "o1 + o2". object PyNumber_Subtract(object o1, object o2) # Return value: New reference. # Returns the result of subtracting o2 from o1, or NULL on # failure. This is the equivalent of the Python expression "o1 - # o2". object PyNumber_Multiply(object o1, object o2) # Return value: New reference. # Returns the result of multiplying o1 and o2, or NULL on # failure. This is the equivalent of the Python expression "o1 * # o2". object PyNumber_Divide(object o1, object o2) # Return value: New reference. # Returns the result of dividing o1 by o2, or NULL on # failure. This is the equivalent of the Python expression "o1 / # o2". object PyNumber_FloorDivide(object o1, object o2) # Return value: New reference. # Return the floor of o1 divided by o2, or NULL on failure. This # is equivalent to the ``classic'' division of integers. object PyNumber_TrueDivide(object o1, object o2) # Return value: New reference. # Return a reasonable approximation for the mathematical value of # o1 divided by o2, or NULL on failure. The return value is # ``approximate'' because binary floating point numbers are # approximate; it is not possible to represent all real numbers in # base two. This function can return a floating point value when # passed two integers. object PyNumber_Remainder(object o1, object o2) # Return value: New reference. # Returns the remainder of dividing o1 by o2, or NULL on # failure. This is the equivalent of the Python expression "o1 % # o2". object PyNumber_Divmod(object o1, object o2) # Return value: New reference. # See the built-in function divmod(). Returns NULL on # failure. This is the equivalent of the Python expression # "divmod(o1, o2)". object PyNumber_Power(object o1, object o2, object o3) # Return value: New reference. # See the built-in function pow(). Returns NULL on failure. This # is the equivalent of the Python expression "pow(o1, o2, o3)", # where o3 is optional. If o3 is to be ignored, pass Py_None in # its place (passing NULL for o3 would cause an illegal memory # access). object PyNumber_Negative(object o) # Return value: New reference. # Returns the negation of o on success, or NULL on failure. This # is the equivalent of the Python expression "-o". object PyNumber_Positive(object o) # Return value: New reference. # Returns o on success, or NULL on failure. This is the equivalent # of the Python expression "+o". object PyNumber_Absolute(object o) # Return value: New reference. # Returns the absolute value of o, or NULL on failure. This is the # equivalent of the Python expression "abs(o)". object PyNumber_Invert(object o) # Return value: New reference. # Returns the bitwise negation of o on success, or NULL on # failure. This is the equivalent of the Python expression "~o". object PyNumber_Lshift(object o1, object o2) # Return value: New reference. # Returns the result of left shifting o1 by o2 on success, or NULL # on failure. This is the equivalent of the Python expression "o1 # << o2". object PyNumber_Rshift(object o1, object o2) # Return value: New reference. # Returns the result of right shifting o1 by o2 on success, or # NULL on failure. This is the equivalent of the Python expression # "o1 >> o2". object PyNumber_And(object o1, object o2) # Return value: New reference. # Returns the ``bitwise and'' of o1 and o2 on success and NULL on # failure. This is the equivalent of the Python expression "o1 & # o2". object PyNumber_Xor(object o1, object o2) # Return value: New reference. # Returns the ``bitwise exclusive or'' of o1 by o2 on success, or # NULL on failure. This is the equivalent of the Python expression # "o1 ^ o2". object PyNumber_Or(object o1, object o2) # Return value: New reference. # Returns the ``bitwise or'' of o1 and o2 on success, or NULL on failure. This is the equivalent of the Python expression "o1 | o2". object PyNumber_InPlaceAdd(object o1, object o2) # Return value: New reference. # Returns the result of adding o1 and o2, or NULL on failure. The # operation is done in-place when o1 supports it. This is the # equivalent of the Python statement "o1 += o2". object PyNumber_InPlaceSubtract(object o1, object o2) # Return value: New reference. # Returns the result of subtracting o2 from o1, or NULL on # failure. The operation is done in-place when o1 supports # it. This is the equivalent of the Python statement "o1 -= o2". object PyNumber_InPlaceMultiply(object o1, object o2) # Return value: New reference. # Returns the result of multiplying o1 and o2, or NULL on # failure. The operation is done in-place when o1 supports # it. This is the equivalent of the Python statement "o1 *= o2". object PyNumber_InPlaceDivide(object o1, object o2) # Return value: New reference. # Returns the result of dividing o1 by o2, or NULL on failure. The # operation is done in-place when o1 supports it. This is the # equivalent of the Python statement "o1 /= o2". object PyNumber_InPlaceFloorDivide(object o1, object o2) # Return value: New reference. # Returns the mathematical floor of dividing o1 by o2, or NULL on # failure. The operation is done in-place when o1 supports # it. This is the equivalent of the Python statement "o1 //= # o2". object PyNumber_InPlaceTrueDivide(object o1, object o2) # Return value: New reference. # Return a reasonable approximation for the mathematical value of # o1 divided by o2, or NULL on failure. The return value is # ``approximate'' because binary floating point numbers are # approximate; it is not possible to represent all real numbers in # base two. This function can return a floating point value when # passed two integers. The operation is done in-place when o1 # supports it. object PyNumber_InPlaceRemainder(object o1, object o2) # Return value: New reference. # Returns the remainder of dividing o1 by o2, or NULL on # failure. The operation is done in-place when o1 supports # it. This is the equivalent of the Python statement "o1 %= o2". object PyNumber_InPlacePower(object o1, object o2, object o3) # Return value: New reference. # See the built-in function pow(). Returns NULL on failure. The # operation is done in-place when o1 supports it. This is the # equivalent of the Python statement "o1 **= o2" when o3 is # Py_None, or an in-place variant of "pow(o1, o2, o3)" # otherwise. If o3 is to be ignored, pass Py_None in its place # (passing NULL for o3 would cause an illegal memory access). object PyNumber_InPlaceLshift(object o1, object o2) # Return value: New reference. # Returns the result of left shifting o1 by o2 on success, or NULL # on failure. The operation is done in-place when o1 supports # it. This is the equivalent of the Python statement "o1 <<= o2". object PyNumber_InPlaceRshift(object o1, object o2) # Return value: New reference. # Returns the result of right shifting o1 by o2 on success, or # NULL on failure. The operation is done in-place when o1 supports # it. This is the equivalent of the Python statement "o1 >>= o2". object PyNumber_InPlaceAnd(object o1, object o2) # Return value: New reference. # Returns the ``bitwise and'' of o1 and o2 on success and NULL on # failure. The operation is done in-place when o1 supports # it. This is the equivalent of the Python statement "o1 &= o2". object PyNumber_InPlaceXor(object o1, object o2) # Return value: New reference. # Returns the ``bitwise exclusive or'' of o1 by o2 on success, or # NULL on failure. The operation is done in-place when o1 supports # it. This is the equivalent of the Python statement "o1 ^= o2". object PyNumber_InPlaceOr(object o1, object o2) # Return value: New reference. # Returns the ``bitwise or'' of o1 and o2 on success, or NULL on # failure. The operation is done in-place when o1 supports # it. This is the equivalent of the Python statement "o1 |= o2". int PyNumber_Coerce(PyObject **p1, PyObject **p2) except -1 # This function takes the addresses of two variables of type # PyObject*. If the objects pointed to by *p1 and *p2 have the # same type, increment their reference count and return 0 # (success). If the objects can be converted to a common numeric # type, replace *p1 and *p2 by their converted value (with 'new' # reference counts), and return 0. If no conversion is possible, # or if some other error occurs, return -1 (failure) and don't # increment the reference counts. The call PyNumber_Coerce(&o1, # &o2) is equivalent to the Python statement "o1, o2 = coerce(o1, # o2)". object PyNumber_Int(object o) # Return value: New reference. # Returns the o converted to an integer object on success, or NULL # on failure. If the argument is outside the integer range a long # object will be returned instead. This is the equivalent of the # Python expression "int(o)". object PyNumber_Long(object o) # Return value: New reference. # Returns the o converted to a long integer object on success, or # NULL on failure. This is the equivalent of the Python expression # "long(o)". object PyNumber_Float(object o) # Return value: New reference. # Returns the o converted to a float object on success, or NULL on # failure. This is the equivalent of the Python expression # "float(o)". object PyNumber_Index(object o) # Returns the o converted to a Python int or long on success or # NULL with a TypeError exception raised on failure. Py_ssize_t PyNumber_AsSsize_t(object o, object exc) except? -1 # Returns o converted to a Py_ssize_t value if o can be # interpreted as an integer. If o can be converted to a Python int # or long but the attempt to convert to a Py_ssize_t value would # raise an OverflowError, then the exc argument is the type of # exception that will be raised (usually IndexError or # OverflowError). If exc is NULL, then the exception is cleared # and the value is clipped to PY_SSIZE_T_MIN for a negative # integer or PY_SSIZE_T_MAX for a positive integer. bint PyIndex_Check(object) # Returns True if o is an index integer (has the nb_index slot of # the tp_as_number structure filled in). Cython-0.23.4/Cython/Includes/cpython/module.pxd0000644000175600017570000002052712606202452022712 0ustar jenkinsjenkins00000000000000from .object cimport PyObject cdef extern from "Python.h": ctypedef struct _inittab ##################################################################### # 5.3 Importing Modules ##################################################################### object PyImport_ImportModule(char *name) # Return value: New reference. # This is a simplified interface to PyImport_ImportModuleEx() # below, leaving the globals and locals arguments set to # NULL. When the name argument contains a dot (when it specifies a # submodule of a package), the fromlist argument is set to the # list ['*'] so that the return value is the named module rather # than the top-level package containing it as would otherwise be # the case. (Unfortunately, this has an additional side effect # when name in fact specifies a subpackage instead of a submodule: # the submodules specified in the package's __all__ variable are # loaded.) Return a new reference to the imported module, or NULL # with an exception set on failure. object PyImport_ImportModuleEx(char *name, object globals, object locals, object fromlist) # Return value: New reference. # Import a module. This is best described by referring to the # built-in Python function __import__(), as the standard # __import__() function calls this function directly. # The return value is a new reference to the imported module or # top-level package, or NULL with an exception set on failure # (before Python 2.4, the module may still be created in this # case). Like for __import__(), the return value when a submodule # of a package was requested is normally the top-level package, # unless a non-empty fromlist was given. Changed in version 2.4: # failing imports remove incomplete module objects. object PyImport_Import(object name) # Return value: New reference. # This is a higher-level interface that calls the current ``import # hook function''. It invokes the __import__() function from the # __builtins__ of the current globals. This means that the import # is done using whatever import hooks are installed in the current # environment, e.g. by rexec or ihooks. object PyImport_ReloadModule(object m) # Return value: New reference. # Reload a module. This is best described by referring to the # built-in Python function reload(), as the standard reload() # function calls this function directly. Return a new reference to # the reloaded module, or NULL with an exception set on failure # (the module still exists in this case). PyObject* PyImport_AddModule(char *name) except NULL # Return value: Borrowed reference. # Return the module object corresponding to a module name. The # name argument may be of the form package.module. First check the # modules dictionary if there's one there, and if not, create a # new one and insert it in the modules dictionary. Return NULL # with an exception set on failure. Note: This function does not # load or import the module; if the module wasn't already loaded, # you will get an empty module object. Use PyImport_ImportModule() # or one of its variants to import a module. Package structures # implied by a dotted name for name are not created if not already # present. object PyImport_ExecCodeModule(char *name, object co) # Return value: New reference. # Given a module name (possibly of the form package.module) and a # code object read from a Python bytecode file or obtained from # the built-in function compile(), load the module. Return a new # reference to the module object, or NULL with an exception set if # an error occurred. Name is removed from sys.modules in error # cases, and even if name was already in sys.modules on entry to # PyImport_ExecCodeModule(). Leaving incompletely initialized # modules in sys.modules is dangerous, as imports of such modules # have no way to know that the module object is an unknown (and # probably damaged with respect to the module author's intents) # state. # This function will reload the module if it was already # imported. See PyImport_ReloadModule() for the intended way to # reload a module. # If name points to a dotted name of the form package.module, any # package structures not already created will still not be # created. long PyImport_GetMagicNumber() # Return the magic number for Python bytecode files (a.k.a. .pyc # and .pyo files). The magic number should be present in the first # four bytes of the bytecode file, in little-endian byte order. PyObject* PyImport_GetModuleDict() except NULL # Return value: Borrowed reference. # Return the dictionary used for the module administration # (a.k.a. sys.modules). Note that this is a per-interpreter # variable. int PyImport_ImportFrozenModule(char *name) except -1 # Load a frozen module named name. Return 1 for success, 0 if the # module is not found, and -1 with an exception set if the # initialization failed. To access the imported module on a # successful load, use PyImport_ImportModule(). (Note the misnomer # -- this function would reload the module if it was already # imported.) int PyImport_ExtendInittab(_inittab *newtab) except -1 # Add a collection of modules to the table of built-in # modules. The newtab array must end with a sentinel entry which # contains NULL for the name field; failure to provide the # sentinel value can result in a memory fault. Returns 0 on # success or -1 if insufficient memory could be allocated to # extend the internal table. In the event of failure, no modules # are added to the internal table. This should be called before # Py_Initialize(). ##################################################################### # 7.5.5 Module Objects ##################################################################### # PyTypeObject PyModule_Type # # This instance of PyTypeObject represents the Python module # type. This is exposed to Python programs as types.ModuleType. bint PyModule_Check(object p) # Return true if p is a module object, or a subtype of a module # object. bint PyModule_CheckExact(object p) # Return true if p is a module object, but not a subtype of PyModule_Type. object PyModule_New(char *name) # Return value: New reference. # Return a new module object with the __name__ attribute set to # name. Only the module's __doc__ and __name__ attributes are # filled in; the caller is responsible for providing a __file__ # attribute. PyObject* PyModule_GetDict(object module) except NULL # Return value: Borrowed reference. # Return the dictionary object that implements module's namespace; # this object is the same as the __dict__ attribute of the module # object. This function never fails. It is recommended extensions # use other PyModule_*() and PyObject_*() functions rather than # directly manipulate a module's __dict__. char* PyModule_GetName(object module) except NULL # Return module's __name__ value. If the module does not provide # one, or if it is not a string, SystemError is raised and NULL is # returned. char* PyModule_GetFilename(object module) except NULL # Return the name of the file from which module was loaded using # module's __file__ attribute. If this is not defined, or if it is # not a string, raise SystemError and return NULL. int PyModule_AddObject(object module, char *name, object value) except -1 # Add an object to module as name. This is a convenience function # which can be used from the module's initialization # function. This steals a reference to value. Return -1 on error, # 0 on success. int PyModule_AddIntConstant(object module, char *name, long value) except -1 # Add an integer constant to module as name. This convenience # function can be used from the module's initialization # function. Return -1 on error, 0 on success. int PyModule_AddStringConstant(object module, char *name, char *value) except -1 # Add a string constant to module as name. This convenience # function can be used from the module's initialization # function. The string value must be null-terminated. Return -1 on # error, 0 on success. Cython-0.23.4/Cython/Includes/cpython/method.pxd0000644000175600017570000000422412606202452022701 0ustar jenkinsjenkins00000000000000from .object cimport PyObject cdef extern from "Python.h": ############################################################################ # 7.5.4 Method Objects ############################################################################ # There are some useful functions that are useful for working with method objects. # PyTypeObject PyMethod_Type # This instance of PyTypeObject represents the Python method type. This is exposed to Python programs as types.MethodType. bint PyMethod_Check(object o) # Return true if o is a method object (has type # PyMethod_Type). The parameter must not be NULL. object PyMethod_New(object func, object self, object cls) # Return value: New reference. # Return a new method object, with func being any callable object; # this is the function that will be called when the method is # called. If this method should be bound to an instance, self # should be the instance and class should be the class of self, # otherwise self should be NULL and class should be the class # which provides the unbound method.. PyObject* PyMethod_Class(object meth) except NULL # Return value: Borrowed reference. # Return the class object from which the method meth was created; # if this was created from an instance, it will be the class of # the instance. PyObject* PyMethod_GET_CLASS(object meth) # Return value: Borrowed reference. # Macro version of PyMethod_Class() which avoids error checking. PyObject* PyMethod_Function(object meth) except NULL # Return value: Borrowed reference. # Return the function object associated with the method meth. PyObject* PyMethod_GET_FUNCTION(object meth) # Return value: Borrowed reference. # Macro version of PyMethod_Function() which avoids error checking. PyObject* PyMethod_Self(object meth) except? NULL # Return value: Borrowed reference. # Return the instance associated with the method meth if it is bound, otherwise return NULL. PyObject* PyMethod_GET_SELF(object meth) # Return value: Borrowed reference. # Macro version of PyMethod_Self() which avoids error checking. Cython-0.23.4/Cython/Includes/cpython/mem.pxd0000644000175600017570000000717312606202452022205 0ustar jenkinsjenkins00000000000000cdef extern from "Python.h": ##################################################################### # 9.2 Memory Interface ##################################################################### # You are definitely *supposed* to use these: "In most situations, # however, it is recommended to allocate memory from the Python # heap specifically because the latter is under control of the # Python memory manager. For example, this is required when the # interpreter is extended with new object types written in # C. Another reason for using the Python heap is the desire to # inform the Python memory manager about the memory needs of the # extension module. Even when the requested memory is used # exclusively for internal, highly-specific purposes, delegating # all memory requests to the Python memory manager causes the # interpreter to have a more accurate image of its memory # footprint as a whole. Consequently, under certain circumstances, # the Python memory manager may or may not trigger appropriate # actions, like garbage collection, memory compaction or other # preventive procedures. Note that by using the C library # allocator as shown in the previous example, the allocated memory # for the I/O buffer escapes completely the Python memory # manager." # The following function sets, modeled after the ANSI C standard, # but specifying behavior when requesting zero bytes, are # available for allocating and releasing memory from the Python # heap: void* PyMem_Malloc(size_t n) # Allocates n bytes and returns a pointer of type void* to the # allocated memory, or NULL if the request fails. Requesting zero # bytes returns a distinct non-NULL pointer if possible, as if # PyMem_Malloc(1) had been called instead. The memory will not # have been initialized in any way. void* PyMem_Realloc(void *p, size_t n) # Resizes the memory block pointed to by p to n bytes. The # contents will be unchanged to the minimum of the old and the new # sizes. If p is NULL, the call is equivalent to PyMem_Malloc(n); # else if n is equal to zero, the memory block is resized but is # not freed, and the returned pointer is non-NULL. Unless p is # NULL, it must have been returned by a previous call to # PyMem_Malloc() or PyMem_Realloc(). void PyMem_Free(void *p) # Frees the memory block pointed to by p, which must have been # returned by a previous call to PyMem_Malloc() or # PyMem_Realloc(). Otherwise, or if PyMem_Free(p) has been called # before, undefined behavior occurs. If p is NULL, no operation is # performed. # The following type-oriented macros are provided for # convenience. Note that TYPE refers to any C type. # TYPE* PyMem_New(TYPE, size_t n) # Same as PyMem_Malloc(), but allocates (n * sizeof(TYPE)) bytes # of memory. Returns a pointer cast to TYPE*. The memory will not # have been initialized in any way. # TYPE* PyMem_Resize(void *p, TYPE, size_t n) # Same as PyMem_Realloc(), but the memory block is resized to (n * # sizeof(TYPE)) bytes. Returns a pointer cast to TYPE*. void PyMem_Del(void *p) # Same as PyMem_Free(). # In addition, the following macro sets are provided for calling # the Python memory allocator directly, without involving the C # API functions listed above. However, note that their use does # not preserve binary compatibility across Python versions and is # therefore deprecated in extension modules. # PyMem_MALLOC(), PyMem_REALLOC(), PyMem_FREE(). # PyMem_NEW(), PyMem_RESIZE(), PyMem_DEL(). Cython-0.23.4/Cython/Includes/cpython/mapping.pxd0000644000175600017570000000520512606202452023054 0ustar jenkinsjenkins00000000000000cdef extern from "Python.h": ############################################################################ # 6.4 Mapping Protocol ############################################################################ bint PyMapping_Check(object o) # Return 1 if the object provides mapping protocol, and 0 # otherwise. This function always succeeds. Py_ssize_t PyMapping_Length(object o) except -1 # Returns the number of keys in object o on success, and -1 on # failure. For objects that do not provide mapping protocol, this # is equivalent to the Python expression "len(o)". int PyMapping_DelItemString(object o, char *key) except -1 # Remove the mapping for object key from the object o. Return -1 # on failure. This is equivalent to the Python statement "del # o[key]". int PyMapping_DelItem(object o, object key) except -1 # Remove the mapping for object key from the object o. Return -1 # on failure. This is equivalent to the Python statement "del # o[key]". bint PyMapping_HasKeyString(object o, char *key) # On success, return 1 if the mapping object has the key key and 0 # otherwise. This is equivalent to the Python expression # "o.has_key(key)". This function always succeeds. bint PyMapping_HasKey(object o, object key) # Return 1 if the mapping object has the key key and 0 # otherwise. This is equivalent to the Python expression # "o.has_key(key)". This function always succeeds. object PyMapping_Keys(object o) # Return value: New reference. # On success, return a list of the keys in object o. On failure, # return NULL. This is equivalent to the Python expression # "o.keys()". object PyMapping_Values(object o) # Return value: New reference. # On success, return a list of the values in object o. On failure, # return NULL. This is equivalent to the Python expression # "o.values()". object PyMapping_Items(object o) # Return value: New reference. # On success, return a list of the items in object o, where each # item is a tuple containing a key-value pair. On failure, return # NULL. This is equivalent to the Python expression "o.items()". object PyMapping_GetItemString(object o, char *key) # Return value: New reference. # Return element of o corresponding to the object key or NULL on # failure. This is the equivalent of the Python expression # "o[key]". int PyMapping_SetItemString(object o, char *key, object v) except -1 # Map the object key to the value v in object o. Returns -1 on # failure. This is the equivalent of the Python statement "o[key] # = v". Cython-0.23.4/Cython/Includes/cpython/long.pxd0000644000175600017570000001220212606202452022353 0ustar jenkinsjenkins00000000000000 cdef extern from "Python.h": ctypedef long long PY_LONG_LONG ctypedef unsigned long long uPY_LONG_LONG "unsigned PY_LONG_LONG" ############################################################################ # 7.2.3 Long Integer Objects ############################################################################ # PyLongObject # # This subtype of PyObject represents a Python long integer object. # PyTypeObject PyLong_Type # # This instance of PyTypeObject represents the Python long integer # type. This is the same object as long and types.LongType. bint PyLong_Check(object p) # Return true if its argument is a PyLongObject or a subtype of PyLongObject. bint PyLong_CheckExact(object p) # Return true if its argument is a PyLongObject, but not a subtype of PyLongObject. object PyLong_FromLong(long v) # Return value: New reference. # Return a new PyLongObject object from v, or NULL on failure. object PyLong_FromUnsignedLong(unsigned long v) # Return value: New reference. # Return a new PyLongObject object from a C unsigned long, or NULL on failure. object PyLong_FromLongLong(PY_LONG_LONG v) # Return value: New reference. # Return a new PyLongObject object from a C long long, or NULL on failure. object PyLong_FromUnsignedLongLong(uPY_LONG_LONG v) # Return value: New reference. # Return a new PyLongObject object from a C unsigned long long, or NULL on failure. object PyLong_FromDouble(double v) # Return value: New reference. # Return a new PyLongObject object from the integer part of v, or NULL on failure. object PyLong_FromString(char *str, char **pend, int base) # Return value: New reference. # Return a new PyLongObject based on the string value in str, # which is interpreted according to the radix in base. If pend is # non-NULL, *pend will point to the first character in str which # follows the representation of the number. If base is 0, the # radix will be determined based on the leading characters of str: # if str starts with '0x' or '0X', radix 16 will be used; if str # starts with '0', radix 8 will be used; otherwise radix 10 will # be used. If base is not 0, it must be between 2 and 36, # inclusive. Leading spaces are ignored. If there are no digits, # ValueError will be raised. object PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base) # Return value: New reference. # Convert a sequence of Unicode digits to a Python long integer # value. The first parameter, u, points to the first character of # the Unicode string, length gives the number of characters, and # base is the radix for the conversion. The radix must be in the # range [2, 36]; if it is out of range, ValueError will be # raised. object PyLong_FromVoidPtr(void *p) # Return value: New reference. # Create a Python integer or long integer from the pointer p. The # pointer value can be retrieved from the resulting value using # PyLong_AsVoidPtr(). If the integer is larger than LONG_MAX, a # positive long integer is returned. long PyLong_AsLong(object pylong) except? -1 # Return a C long representation of the contents of pylong. If # pylong is greater than LONG_MAX, an OverflowError is raised. unsigned long PyLong_AsUnsignedLong(object pylong) except? -1 # Return a C unsigned long representation of the contents of # pylong. If pylong is greater than ULONG_MAX, an OverflowError is # raised. PY_LONG_LONG PyLong_AsLongLong(object pylong) except? -1 # Return a C long long from a Python long integer. If pylong # cannot be represented as a long long, an OverflowError will be # raised. uPY_LONG_LONG PyLong_AsUnsignedLongLong(object pylong) except? -1 #unsigned PY_LONG_LONG PyLong_AsUnsignedLongLong(object pylong) # Return a C unsigned long long from a Python long integer. If # pylong cannot be represented as an unsigned long long, an # OverflowError will be raised if the value is positive, or a # TypeError will be raised if the value is negative. unsigned long PyLong_AsUnsignedLongMask(object io) except? -1 # Return a C unsigned long from a Python long integer, without # checking for overflow. uPY_LONG_LONG PyLong_AsUnsignedLongLongMask(object io) except? -1 #unsigned PY_LONG_LONG PyLong_AsUnsignedLongLongMask(object io) # Return a C unsigned long long from a Python long integer, # without checking for overflow. double PyLong_AsDouble(object pylong) except? -1.0 # Return a C double representation of the contents of pylong. If # pylong cannot be approximately represented as a double, an # OverflowError exception is raised and -1.0 will be returned. void* PyLong_AsVoidPtr(object pylong) except? NULL # Convert a Python integer or long integer pylong to a C void # pointer. If pylong cannot be converted, an OverflowError will be # raised. This is only assured to produce a usable void pointer # for values created with PyLong_FromVoidPtr(). For values outside # 0..LONG_MAX, both signed and unsigned integers are acccepted. Cython-0.23.4/Cython/Includes/cpython/list.pxd0000644000175600017570000000776412606202452022410 0ustar jenkinsjenkins00000000000000from .object cimport PyObject cdef extern from "Python.h": ############################################################################ # Lists ############################################################################ list PyList_New(Py_ssize_t len) # Return a new list of length len on success, or NULL on failure. # # Note: If length is greater than zero, the returned list object's # items are set to NULL. Thus you cannot use abstract API # functions such as PySequence_SetItem() or expose the object to # Python code before setting all items to a real object with # PyList_SetItem(). bint PyList_Check(object p) # Return true if p is a list object or an instance of a subtype of # the list type. bint PyList_CheckExact(object p) # Return true if p is a list object, but not an instance of a # subtype of the list type. Py_ssize_t PyList_Size(object list) except -1 # Return the length of the list object in list; this is equivalent # to "len(list)" on a list object. Py_ssize_t PyList_GET_SIZE(object list) # Macro form of PyList_Size() without error checking. PyObject* PyList_GetItem(object list, Py_ssize_t index) except NULL # Return value: Borrowed reference. # Return the object at position pos in the list pointed to by # p. The position must be positive, indexing from the end of the # list is not supported. If pos is out of bounds, return NULL and # set an IndexError exception. PyObject* PyList_GET_ITEM(object list, Py_ssize_t i) # Return value: Borrowed reference. # Macro form of PyList_GetItem() without error checking. int PyList_SetItem(object list, Py_ssize_t index, object item) except -1 # Set the item at index index in list to item. Return 0 on success # or -1 on failure. Note: This function ``steals'' a reference to # item and discards a reference to an item already in the list at # the affected position. void PyList_SET_ITEM(object list, Py_ssize_t i, object o) # Macro form of PyList_SetItem() without error checking. This is # normally only used to fill in new lists where there is no # previous content. Note: This function ``steals'' a reference to # item, and, unlike PyList_SetItem(), does not discard a reference # to any item that it being replaced; any reference in list at # position i will be *leaked*. int PyList_Insert(object list, Py_ssize_t index, object item) except -1 # Insert the item item into list list in front of index # index. Return 0 if successful; return -1 and set an exception if # unsuccessful. Analogous to list.insert(index, item). int PyList_Append(object list, object item) except -1 # Append the object item at the end of list list. Return 0 if # successful; return -1 and set an exception if # unsuccessful. Analogous to list.append(item). list PyList_GetSlice(object list, Py_ssize_t low, Py_ssize_t high) # Return value: New reference. # Return a list of the objects in list containing the objects # between low and high. Return NULL and set an exception if # unsuccessful. Analogous to list[low:high]. int PyList_SetSlice(object list, Py_ssize_t low, Py_ssize_t high, object itemlist) except -1 # Set the slice of list between low and high to the contents of # itemlist. Analogous to list[low:high] = itemlist. The itemlist # may be NULL, indicating the assignment of an empty list (slice # deletion). Return 0 on success, -1 on failure. int PyList_Sort(object list) except -1 # Sort the items of list in place. Return 0 on success, -1 on # failure. This is equivalent to "list.sort()". int PyList_Reverse(object list) except -1 # Reverse the items of list in place. Return 0 on success, -1 on # failure. This is the equivalent of "list.reverse()". tuple PyList_AsTuple(object list) # Return value: New reference. # Return a new tuple object containing the contents of list; # equivalent to "tuple(list)". Cython-0.23.4/Cython/Includes/cpython/iterator.pxd0000644000175600017570000000244712606202452023257 0ustar jenkinsjenkins00000000000000cdef extern from "Python.h": ############################################################################ # 6.5 Iterator Protocol ############################################################################ bint PyIter_Check(object o) # Return true if the object o supports the iterator protocol. object PyIter_Next(object o) # Return value: New reference. # Return the next value from the iteration o. If the object is an # iterator, this retrieves the next value from the iteration, and # returns NULL with no exception set if there are no remaining # items. If the object is not an iterator, TypeError is raised, or # if there is an error in retrieving the item, returns NULL and # passes along the exception. # To write a loop which iterates over an iterator, the C code should look something like this: # PyObject *iterator = PyObject_GetIter(obj); # PyObject *item; # if (iterator == NULL) { # /* propagate error */ # } # while (item = PyIter_Next(iterator)) { # /* do something with item */ # ... # /* release reference when done */ # Py_DECREF(item); # } # Py_DECREF(iterator); # if (PyErr_Occurred()) { # /* propagate error */ # } # else { # /* continue doing useful work */ # } Cython-0.23.4/Cython/Includes/cpython/int.pxd0000644000175600017570000001004312606202452022207 0ustar jenkinsjenkins00000000000000cdef extern from "Python.h": ctypedef unsigned long long PY_LONG_LONG ############################################################################ # Integer Objects ############################################################################ # PyTypeObject PyInt_Type # This instance of PyTypeObject represents the Python plain # integer type. This is the same object as int and types.IntType. bint PyInt_Check(object o) # Return true if o is of type PyInt_Type or a subtype of # PyInt_Type. bint PyInt_CheckExact(object o) # Return true if o is of type PyInt_Type, but not a subtype of # PyInt_Type. object PyInt_FromString(char *str, char **pend, int base) # Return value: New reference. # Return a new PyIntObject or PyLongObject based on the string # value in str, which is interpreted according to the radix in # base. If pend is non-NULL, *pend will point to the first # character in str which follows the representation of the # number. If base is 0, the radix will be determined based on the # leading characters of str: if str starts with '0x' or '0X', # radix 16 will be used; if str starts with '0', radix 8 will be # used; otherwise radix 10 will be used. If base is not 0, it must # be between 2 and 36, inclusive. Leading spaces are ignored. If # there are no digits, ValueError will be raised. If the string # represents a number too large to be contained within the # machine's long int type and overflow warnings are being # suppressed, a PyLongObject will be returned. If overflow # warnings are not being suppressed, NULL will be returned in this # case. object PyInt_FromLong(long ival) # Return value: New reference. # Create a new integer object with a value of ival. # The current implementation keeps an array of integer objects for # all integers between -5 and 256, when you create an int in that # range you actually just get back a reference to the existing # object. So it should be possible to change the value of 1. I # suspect the behaviour of Python in this case is undefined. :-) object PyInt_FromSsize_t(Py_ssize_t ival) # Return value: New reference. # Create a new integer object with a value of ival. If the value # is larger than LONG_MAX or smaller than LONG_MIN, a long integer # object is returned. object PyInt_FromSize_t(size_t ival) # Return value: New reference. # Create a new integer object with a value of ival. If the value # exceeds LONG_MAX, a long integer object is returned. long PyInt_AsLong(object io) except? -1 # Will first attempt to cast the object to a PyIntObject, if it is # not already one, and then return its value. If there is an # error, -1 is returned, and the caller should check # PyErr_Occurred() to find out whether there was an error, or # whether the value just happened to be -1. long PyInt_AS_LONG(object io) # Return the value of the object io. No error checking is performed. unsigned long PyInt_AsUnsignedLongMask(object io) except? -1 # Will first attempt to cast the object to a PyIntObject or # PyLongObject, if it is not already one, and then return its # value as unsigned long. This function does not check for # overflow. PY_LONG_LONG PyInt_AsUnsignedLongLongMask(object io) except? -1 # Will first attempt to cast the object to a PyIntObject or # PyLongObject, if it is not already one, and then return its # value as unsigned long long, without checking for overflow. Py_ssize_t PyInt_AsSsize_t(object io) except? -1 # Will first attempt to cast the object to a PyIntObject or # PyLongObject, if it is not already one, and then return its # value as Py_ssize_t. long PyInt_GetMax() # Return the system's idea of the largest integer it can handle # (LONG_MAX, as defined in the system header files). int PyInt_ClearFreeList() # Clear the integer free list. Return the number of items that could not be freed. # New in version 2.6. Cython-0.23.4/Cython/Includes/cpython/instance.pxd0000644000175600017570000000173112606202452023225 0ustar jenkinsjenkins00000000000000cdef extern from "Python.h": ############################################################################ # 7.5.2 Instance Objects ############################################################################ # PyTypeObject PyInstance_Type # # Type object for class instances. int PyInstance_Check(object obj) # Return true if obj is an instance. object PyInstance_New(object cls, object arg, object kw) # Return value: New reference. # Create a new instance of a specific class. The parameters arg # and kw are used as the positional and keyword parameters to the # object's constructor. object PyInstance_NewRaw(object cls, object dict) # Return value: New reference. # Create a new instance of a specific class without calling its # constructor. class is the class of new object. The dict # parameter will be used as the object's __dict__; if NULL, a new # dictionary will be created for the instance. Cython-0.23.4/Cython/Includes/cpython/getargs.pxd0000644000175600017570000000140712606202452023055 0ustar jenkinsjenkins00000000000000 cdef extern from "Python.h": ##################################################################### # 5.5 Parsing arguments and building values ##################################################################### ctypedef struct va_list int PyArg_ParseTuple(object args, char *format, ...) except 0 int PyArg_VaParse(object args, char *format, va_list vargs) except 0 int PyArg_ParseTupleAndKeywords(object args, object kw, char *format, char *keywords[], ...) except 0 int PyArg_VaParseTupleAndKeywords(object args, object kw, char *format, char *keywords[], va_list vargs) except 0 int PyArg_Parse(object args, char *format, ...) except 0 int PyArg_UnpackTuple(object args, char *name, Py_ssize_t min, Py_ssize_t max, ...) except 0 Cython-0.23.4/Cython/Includes/cpython/function.pxd0000644000175600017570000000515712606202452023254 0ustar jenkinsjenkins00000000000000from .object cimport PyObject cdef extern from "Python.h": ############################################################################ # 7.5.3 Function Objects ############################################################################ # There are a few functions specific to Python functions. # PyFunctionObject # # The C structure used for functions. # PyTypeObject PyFunction_Type # # This is an instance of PyTypeObject and represents the Python # function type. It is exposed to Python programmers as # types.FunctionType. bint PyFunction_Check(object o) # Return true if o is a function object (has type # PyFunction_Type). The parameter must not be NULL. object PyFunction_New(object code, object globals) # Return value: New reference. # Return a new function object associated with the code object # code. globals must be a dictionary with the global variables # accessible to the function. # The function's docstring, name and __module__ are retrieved from # the code object, the argument defaults and closure are set to # NULL. PyObject* PyFunction_GetCode(object op) except? NULL # Return value: Borrowed reference. # Return the code object associated with the function object op. PyObject* PyFunction_GetGlobals(object op) except? NULL # Return value: Borrowed reference. # Return the globals dictionary associated with the function object op. PyObject* PyFunction_GetModule(object op) except? NULL # Return value: Borrowed reference. # Return the __module__ attribute of the function object op. This # is normally a string containing the module name, but can be set # to any other object by Python code. PyObject* PyFunction_GetDefaults(object op) except? NULL # Return value: Borrowed reference. # Return the argument default values of the function object # op. This can be a tuple of arguments or NULL. int PyFunction_SetDefaults(object op, object defaults) except -1 # Set the argument default values for the function object # op. defaults must be Py_None or a tuple. # Raises SystemError and returns -1 on failure. PyObject* PyFunction_GetClosure(object op) except? NULL # Return value: Borrowed reference. # Return the closure associated with the function object op. This # can be NULL or a tuple of cell objects. int PyFunction_SetClosure(object op, object closure) except -1 # Set the closure associated with the function object op. closure # must be Py_None or a tuple of cell objects. # Raises SystemError and returns -1 on failure. Cython-0.23.4/Cython/Includes/cpython/float.pxd0000644000175600017570000000262012606202452022524 0ustar jenkinsjenkins00000000000000cdef extern from "Python.h": ############################################################################ # 7.2.3 ############################################################################ # PyFloatObject # # This subtype of PyObject represents a Python floating point object. # PyTypeObject PyFloat_Type # # This instance of PyTypeObject represents the Python floating # point type. This is the same object as float and # types.FloatType. bint PyFloat_Check(object p) # Return true if its argument is a PyFloatObject or a subtype of # PyFloatObject. bint PyFloat_CheckExact(object p) # Return true if its argument is a PyFloatObject, but not a # subtype of PyFloatObject. object PyFloat_FromString(object str, char **pend) # Return value: New reference. # Create a PyFloatObject object based on the string value in str, # or NULL on failure. The pend argument is ignored. It remains # only for backward compatibility. object PyFloat_FromDouble(double v) # Return value: New reference. # Create a PyFloatObject object from v, or NULL on failure. double PyFloat_AsDouble(object pyfloat) except? -1 # Return a C double representation of the contents of pyfloat. double PyFloat_AS_DOUBLE(object pyfloat) # Return a C double representation of the contents of pyfloat, but # without error checking. Cython-0.23.4/Cython/Includes/cpython/exc.pxd0000644000175600017570000003163212606202452022203 0ustar jenkinsjenkins00000000000000from .object cimport PyObject cdef extern from "Python.h": ##################################################################### # 3. Exception Handling ##################################################################### # The functions described in this chapter will let you handle and # raise Python exceptions. It is important to understand some of # the basics of Python exception handling. It works somewhat like # the Unix errno variable: there is a global indicator (per # thread) of the last error that occurred. Most functions don't # clear this on success, but will set it to indicate the cause of # the error on failure. Most functions also return an error # indicator, usually NULL if they are supposed to return a # pointer, or -1 if they return an integer (exception: the # PyArg_*() functions return 1 for success and 0 for failure). # When a function must fail because some function it called # failed, it generally doesn't set the error indicator; the # function it called already set it. It is responsible for either # handling the error and clearing the exception or returning after # cleaning up any resources it holds (such as object references or # memory allocations); it should not continue normally if it is # not prepared to handle the error. If returning due to an error, # it is important to indicate to the caller that an error has been # set. If the error is not handled or carefully propagated, # additional calls into the Python/C API may not behave as # intended and may fail in mysterious ways. # The error indicator consists of three Python objects # corresponding to the Python variables sys.exc_type, # sys.exc_value and sys.exc_traceback. API functions exist to # interact with the error indicator in various ways. There is a # separate error indicator for each thread. void PyErr_Print() # Print a standard traceback to sys.stderr and clear the error # indicator. Call this function only when the error indicator is # set. (Otherwise it will cause a fatal error!) PyObject* PyErr_Occurred() # Return value: Borrowed reference. # Test whether the error indicator is set. If set, return the # exception type (the first argument to the last call to one of # the PyErr_Set*() functions or to PyErr_Restore()). If not set, # return NULL. You do not own a reference to the return value, so # you do not need to Py_DECREF() it. Note: Do not compare the # return value to a specific exception; use # PyErr_ExceptionMatches() instead, shown below. (The comparison # could easily fail since the exception may be an instance instead # of a class, in the case of a class exception, or it may the a # subclass of the expected exception.) bint PyErr_ExceptionMatches(object exc) # Equivalent to "PyErr_GivenExceptionMatches(PyErr_Occurred(), # exc)". This should only be called when an exception is actually # set; a memory access violation will occur if no exception has # been raised. bint PyErr_GivenExceptionMatches(object given, object exc) # Return true if the given exception matches the exception in # exc. If exc is a class object, this also returns true when given # is an instance of a subclass. If exc is a tuple, all exceptions # in the tuple (and recursively in subtuples) are searched for a # match. If given is NULL, a memory access violation will occur. void PyErr_NormalizeException(PyObject** exc, PyObject** val, PyObject** tb) # Under certain circumstances, the values returned by # PyErr_Fetch() below can be ``unnormalized'', meaning that *exc # is a class object but *val is not an instance of the same # class. This function can be used to instantiate the class in # that case. If the values are already normalized, nothing # happens. The delayed normalization is implemented to improve # performance. void PyErr_Clear() # Clear the error indicator. If the error indicator is not set, there is no effect. void PyErr_Fetch(PyObject** ptype, PyObject** pvalue, PyObject** ptraceback) # Retrieve the error indicator into three variables whose # addresses are passed. If the error indicator is not set, set all # three variables to NULL. If it is set, it will be cleared and # you own a reference to each object retrieved. The value and # traceback object may be NULL even when the type object is # not. Note: This function is normally only used by code that # needs to handle exceptions or by code that needs to save and # restore the error indicator temporarily. void PyErr_Restore(PyObject* type, PyObject* value, PyObject* traceback) # Set the error indicator from the three objects. If the error # indicator is already set, it is cleared first. If the objects # are NULL, the error indicator is cleared. Do not pass a NULL # type and non-NULL value or traceback. The exception type should # be a class. Do not pass an invalid exception type or # value. (Violating these rules will cause subtle problems later.) # This call takes away a reference to each object: you must own a # reference to each object before the call and after the call you # no longer own these references. (If you don't understand this, # don't use this function. I warned you.) Note: This function is # normally only used by code that needs to save and restore the # error indicator temporarily; use PyErr_Fetch() to save the # current exception state. void PyErr_SetString(object type, char *message) # This is the most common way to set the error indicator. The # first argument specifies the exception type; it is normally one # of the standard exceptions, e.g. PyExc_RuntimeError. You need # not increment its reference count. The second argument is an # error message; it is converted to a string object. void PyErr_SetObject(object type, object value) # This function is similar to PyErr_SetString() but lets you # specify an arbitrary Python object for the ``value'' of the # exception. PyObject* PyErr_Format(object exception, char *format, ...) except NULL # Return value: Always NULL. # This function sets the error indicator and returns # NULL. exception should be a Python exception (class, not an # instance). format should be a string, containing format codes, # similar to printf(). The width.precision before a format code is # parsed, but the width part is ignored. void PyErr_SetNone(object type) # This is a shorthand for "PyErr_SetObject(type, Py_None)". int PyErr_BadArgument() except 0 # This is a shorthand for "PyErr_SetString(PyExc_TypeError, # message)", where message indicates that a built-in operation was # invoked with an illegal argument. It is mostly for internal use. PyObject* PyErr_NoMemory() except NULL # Return value: Always NULL. # This is a shorthand for "PyErr_SetNone(PyExc_MemoryError)"; it # returns NULL so an object allocation function can write "return # PyErr_NoMemory();" when it runs out of memory. PyObject* PyErr_SetFromErrno(object type) except NULL # Return value: Always NULL. # This is a convenience function to raise an exception when a C # library function has returned an error and set the C variable # errno. It constructs a tuple object whose first item is the # integer errno value and whose second item is the corresponding # error message (gotten from strerror()), and then calls # "PyErr_SetObject(type, object)". On Unix, when the errno value # is EINTR, indicating an interrupted system call, this calls # PyErr_CheckSignals(), and if that set the error indicator, # leaves it set to that. The function always returns NULL, so a # wrapper function around a system call can write "return # PyErr_SetFromErrno(type);" when the system call returns an # error. PyObject* PyErr_SetFromErrnoWithFilename(object type, char *filename) except NULL # Return value: Always NULL. Similar to PyErr_SetFromErrno(), # with the additional behavior that if filename is not NULL, it is # passed to the constructor of type as a third parameter. In the # case of exceptions such as IOError and OSError, this is used to # define the filename attribute of the exception instance. PyObject* PyErr_SetFromWindowsErr(int ierr) except NULL # Return value: Always NULL. This is a convenience function to # raise WindowsError. If called with ierr of 0, the error code # returned by a call to GetLastError() is used instead. It calls # the Win32 function FormatMessage() to retrieve the Windows # description of error code given by ierr or GetLastError(), then # it constructs a tuple object whose first item is the ierr value # and whose second item is the corresponding error message (gotten # from FormatMessage()), and then calls # "PyErr_SetObject(PyExc_WindowsError, object)". This function # always returns NULL. Availability: Windows. PyObject* PyErr_SetExcFromWindowsErr(object type, int ierr) except NULL # Return value: Always NULL. Similar to # PyErr_SetFromWindowsErr(), with an additional parameter # specifying the exception type to be raised. Availability: # Windows. New in version 2.3. PyObject* PyErr_SetFromWindowsErrWithFilename(int ierr, char *filename) except NULL # Return value: Always NULL. Similar to # PyErr_SetFromWindowsErr(), with the additional behavior that if # filename is not NULL, it is passed to the constructor of # WindowsError as a third parameter. Availability: Windows. PyObject* PyErr_SetExcFromWindowsErrWithFilename(object type, int ierr, char *filename) except NULL # Return value: Always NULL. # Similar to PyErr_SetFromWindowsErrWithFilename(), with an # additional parameter specifying the exception type to be # raised. Availability: Windows. void PyErr_BadInternalCall() # This is a shorthand for "PyErr_SetString(PyExc_TypeError, # message)", where message indicates that an internal operation # (e.g. a Python/C API function) was invoked with an illegal # argument. It is mostly for internal use. int PyErr_WarnEx(object category, char *message, int stacklevel) except -1 # Issue a warning message. The category argument is a warning # category (see below) or NULL; the message argument is a message # string. stacklevel is a positive number giving a number of stack # frames; the warning will be issued from the currently executing # line of code in that stack frame. A stacklevel of 1 is the # function calling PyErr_WarnEx(), 2 is the function above that, # and so forth. int PyErr_WarnExplicit(object category, char *message, char *filename, int lineno, char *module, object registry) except -1 # Issue a warning message with explicit control over all warning # attributes. This is a straightforward wrapper around the Python # function warnings.warn_explicit(), see there for more # information. The module and registry arguments may be set to # NULL to get the default effect described there. int PyErr_CheckSignals() except -1 # This function interacts with Python's signal handling. It checks # whether a signal has been sent to the processes and if so, # invokes the corresponding signal handler. If the signal module # is supported, this can invoke a signal handler written in # Python. In all cases, the default effect for SIGINT is to raise # the KeyboardInterrupt exception. If an exception is raised the # error indicator is set and the function returns 1; otherwise the # function returns 0. The error indicator may or may not be # cleared if it was previously set. void PyErr_SetInterrupt() nogil # This function simulates the effect of a SIGINT signal arriving # -- the next time PyErr_CheckSignals() is called, # KeyboardInterrupt will be raised. It may be called without # holding the interpreter lock. object PyErr_NewException(char *name, object base, object dict) # Return value: New reference. # This utility function creates and returns a new exception # object. The name argument must be the name of the new exception, # a C string of the form module.class. The base and dict arguments # are normally NULL. This creates a class object derived from # Exception (accessible in C as PyExc_Exception). void PyErr_WriteUnraisable(object obj) # This utility function prints a warning message to sys.stderr # when an exception has been set but it is impossible for the # interpreter to actually raise the exception. It is used, for # example, when an exception occurs in an __del__() method. # # The function is called with a single argument obj that # identifies the context in which the unraisable exception # occurred. The repr of obj will be printed in the warning # message. Cython-0.23.4/Cython/Includes/cpython/dict.pxd0000644000175600017570000001531312606202452022345 0ustar jenkinsjenkins00000000000000from .object cimport PyObject cdef extern from "Python.h": ############################################################################ # 7.4.1 Dictionary Objects ############################################################################ # PyDictObject # # This subtype of PyObject represents a Python dictionary object # (i.e. the 'dict' type). # PyTypeObject PyDict_Type # # This instance of PyTypeObject represents the Python dictionary # type. This is exposed to Python programs as dict and # types.DictType. bint PyDict_Check(object p) # Return true if p is a dict object or an instance of a subtype of # the dict type. bint PyDict_CheckExact(object p) # Return true if p is a dict object, but not an instance of a # subtype of the dict type. dict PyDict_New() # Return value: New reference. # Return a new empty dictionary, or NULL on failure. object PyDictProxy_New(object dict) # Return value: New reference. # Return a proxy object for a mapping which enforces read-only # behavior. This is normally used to create a proxy to prevent # modification of the dictionary for non-dynamic class types. void PyDict_Clear(object p) # Empty an existing dictionary of all key-value pairs. int PyDict_Contains(object p, object key) except -1 # Determine if dictionary p contains key. If an item in p is # matches key, return 1, otherwise return 0. On error, return # -1. This is equivalent to the Python expression "key in p". dict PyDict_Copy(object p) # Return value: New reference. # Return a new dictionary that contains the same key-value pairs as p. int PyDict_SetItem(object p, object key, object val) except -1 # Insert value into the dictionary p with a key of key. key must # be hashable; if it isn't, TypeError will be raised. Return 0 on # success or -1 on failure. int PyDict_SetItemString(object p, char *key, object val) except -1 # Insert value into the dictionary p using key as a key. key # should be a char*. The key object is created using # PyString_FromString(key). Return 0 on success or -1 on failure. int PyDict_DelItem(object p, object key) except -1 # Remove the entry in dictionary p with key key. key must be # hashable; if it isn't, TypeError is raised. Return 0 on success # or -1 on failure. int PyDict_DelItemString(object p, char *key) except -1 # Remove the entry in dictionary p which has a key specified by # the string key. Return 0 on success or -1 on failure. PyObject* PyDict_GetItem(object p, object key) # Return value: Borrowed reference. # Return the object from dictionary p which has a key key. Return # NULL if the key key is not present, but without setting an # exception. PyObject* PyDict_GetItemString(object p, char *key) # Return value: Borrowed reference. # This is the same as PyDict_GetItem(), but key is specified as a # char*, rather than a PyObject*. list PyDict_Items(object p) # Return value: New reference. # Return a PyListObject containing all the items from the # dictionary, as in the dictionary method items() (see the Python # Library Reference). list PyDict_Keys(object p) # Return value: New reference. # Return a PyListObject containing all the keys from the # dictionary, as in the dictionary method keys() (see the Python # Library Reference). list PyDict_Values(object p) # Return value: New reference. # Return a PyListObject containing all the values from the # dictionary p, as in the dictionary method values() (see the # Python Library Reference). Py_ssize_t PyDict_Size(object p) except -1 # Return the number of items in the dictionary. This is equivalent # to "len(p)" on a dictionary. int PyDict_Next(object p, Py_ssize_t *ppos, PyObject* *pkey, PyObject* *pvalue) # Iterate over all key-value pairs in the dictionary p. The int # referred to by ppos must be initialized to 0 prior to the first # call to this function to start the iteration; the function # returns true for each pair in the dictionary, and false once all # pairs have been reported. The parameters pkey and pvalue should # either point to PyObject* variables that will be filled in with # each key and value, respectively, or may be NULL. Any references # returned through them are borrowed. ppos should not be altered # during iteration. Its value represents offsets within the # internal dictionary structure, and since the structure is # sparse, the offsets are not consecutive. # For example: # #object key, *value; #int pos = 0; # #while (PyDict_Next(self->dict, &pos, &key, &value)) { # /* do something interesting with the values... */ # ... #} # The dictionary p should not be mutated during iteration. It is # safe (since Python 2.1) to modify the values of the keys as you # iterate over the dictionary, but only so long as the set of keys # does not change. For example: # object key, *value; # int pos = 0; # while (PyDict_Next(self->dict, &pos, &key, &value)) { # int i = PyInt_AS_LONG(value) + 1; # object o = PyInt_FromLong(i); # if (o == NULL) # return -1; # if (PyDict_SetItem(self->dict, key, o) < 0) { # Py_DECREF(o); # return -1; # } # Py_DECREF(o); # } int PyDict_Merge(object a, object b, int override) except -1 # Iterate over mapping object b adding key-value pairs to # dictionary a. b may be a dictionary, or any object supporting # PyMapping_Keys() and PyObject_GetItem(). If override is true, # existing pairs in a will be replaced if a matching key is found # in b, otherwise pairs will only be added if there is not a # matching key in a. Return 0 on success or -1 if an exception was # raised. int PyDict_Update(object a, object b) except -1 # This is the same as PyDict_Merge(a, b, 1) in C, or a.update(b) # in Python. Return 0 on success or -1 if an exception was raised. int PyDict_MergeFromSeq2(object a, object seq2, int override) except -1 # Update or merge into dictionary a, from the key-value pairs in # seq2. seq2 must be an iterable object producing iterable objects # of length 2, viewed as key-value pairs. In case of duplicate # keys, the last wins if override is true, else the first # wins. Return 0 on success or -1 if an exception was # raised. Equivalent Python (except for the return value): # #def PyDict_MergeFromSeq2(a, seq2, override): # for key, value in seq2: # if override or key not in a: # a[key] = value Cython-0.23.4/Cython/Includes/cpython/datetime.pxd0000644000175600017570000001525612606202452023224 0ustar jenkinsjenkins00000000000000from cpython.object cimport PyObject cdef extern from "Python.h": ctypedef struct PyTypeObject: pass cdef extern from "datetime.h": ctypedef extern class datetime.date[object PyDateTime_Date]: pass ctypedef extern class datetime.time[object PyDateTime_Time]: pass ctypedef extern class datetime.datetime[object PyDateTime_DateTime]: pass ctypedef extern class datetime.timedelta[object PyDateTime_Delta]: pass ctypedef extern class datetime.tzinfo[object PyDateTime_TZInfo]: pass ctypedef struct PyDateTime_Date: pass ctypedef struct PyDateTime_Time: char hastzinfo PyObject *tzinfo ctypedef struct PyDateTime_DateTime: char hastzinfo PyObject *tzinfo ctypedef struct PyDateTime_Delta: int days int seconds int microseconds # Define structure for C API. ctypedef struct PyDateTime_CAPI: # type objects PyTypeObject *DateType PyTypeObject *DateTimeType PyTypeObject *TimeType PyTypeObject *DeltaType PyTypeObject *TZInfoType # constructors object (*Date_FromDate)(int, int, int, PyTypeObject*) object (*DateTime_FromDateAndTime)(int, int, int, int, int, int, int, object, PyTypeObject*) object (*Time_FromTime)(int, int, int, int, object, PyTypeObject*) object (*Delta_FromDelta)(int, int, int, int, PyTypeObject*) # constructors for the DB API object (*DateTime_FromTimestamp)(object, object, object) object (*Date_FromTimestamp)(object, object) # Check type of the object. bint PyDate_Check(object op) bint PyDate_CheckExact(object op) bint PyDateTime_Check(object op) bint PyDateTime_CheckExact(object op) bint PyTime_Check(object op) bint PyTime_CheckExact(object op) bint PyDelta_Check(object op) bint PyDelta_CheckExact(object op) bint PyTZInfo_Check(object op) bint PyTZInfo_CheckExact(object op) # Getters for date and datetime (C macros). int PyDateTime_GET_YEAR(object o) int PyDateTime_GET_MONTH(object o) int PyDateTime_GET_DAY(object o) # Getters for datetime (C macros). int PyDateTime_DATE_GET_HOUR(object o) int PyDateTime_DATE_GET_MINUTE(object o) int PyDateTime_DATE_GET_SECOND(object o) int PyDateTime_DATE_GET_MICROSECOND(object o) # Getters for time (C macros). int PyDateTime_TIME_GET_HOUR(object o) int PyDateTime_TIME_GET_MINUTE(object o) int PyDateTime_TIME_GET_SECOND(object o) int PyDateTime_TIME_GET_MICROSECOND(object o) # Getters for timedelta (C macros). #int PyDateTime_DELTA_GET_DAYS(object o) #int PyDateTime_DELTA_GET_SECONDS(object o) #int PyDateTime_DELTA_GET_MICROSECONDS(object o) # PyDateTime CAPI object. PyDateTime_CAPI *PyDateTimeAPI void PyDateTime_IMPORT() # Datetime C API initialization function. # You have to call it before any usage of DateTime CAPI functions. cdef inline void import_datetime(): PyDateTime_IMPORT # Create date object using DateTime CAPI factory function. # Note, there are no range checks for any of the arguments. cdef inline object date_new(int year, int month, int day): return PyDateTimeAPI.Date_FromDate(year, month, day, PyDateTimeAPI.DateType) # Create time object using DateTime CAPI factory function # Note, there are no range checks for any of the arguments. cdef inline object time_new(int hour, int minute, int second, int microsecond, object tz): return PyDateTimeAPI.Time_FromTime(hour, minute, second, microsecond, tz, PyDateTimeAPI.TimeType) # Create datetime object using DateTime CAPI factory function. # Note, there are no range checks for any of the arguments. cdef inline object datetime_new(int year, int month, int day, int hour, int minute, int second, int microsecond, object tz): return PyDateTimeAPI.DateTime_FromDateAndTime(year, month, day, hour, minute, second, microsecond, tz, PyDateTimeAPI.DateTimeType) # Create timedelta object using DateTime CAPI factory function. # Note, there are no range checks for any of the arguments. cdef inline object timedelta_new(int days, int seconds, int useconds): return PyDateTimeAPI.Delta_FromDelta(days, seconds, useconds, 1, PyDateTimeAPI.DeltaType) # More recognizable getters for date/time/datetime/timedelta. # There are no setters because datetime.h hasn't them. # This is because of immutable nature of these objects by design. # If you would change time/date/datetime/timedelta object you need to recreate. # Get tzinfo of time cdef inline object time_tzinfo(object o): if (o).hastzinfo: return (o).tzinfo else: return None # Get tzinfo of datetime cdef inline object datetime_tzinfo(object o): if (o).hastzinfo: return (o).tzinfo else: return None # Get year of date cdef inline int date_year(object o): return PyDateTime_GET_YEAR(o) # Get month of date cdef inline int date_month(object o): return PyDateTime_GET_MONTH(o) # Get day of date cdef inline int date_day(object o): return PyDateTime_GET_DAY(o) # Get year of datetime cdef inline int datetime_year(object o): return PyDateTime_GET_YEAR(o) # Get month of datetime cdef inline int datetime_month(object o): return PyDateTime_GET_MONTH(o) # Get day of datetime cdef inline int datetime_day(object o): return PyDateTime_GET_DAY(o) # Get hour of time cdef inline int time_hour(object o): return PyDateTime_TIME_GET_HOUR(o) # Get minute of time cdef inline int time_minute(object o): return PyDateTime_TIME_GET_MINUTE(o) # Get second of time cdef inline int time_second(object o): return PyDateTime_TIME_GET_SECOND(o) # Get microsecond of time cdef inline int time_microsecond(object o): return PyDateTime_TIME_GET_MICROSECOND(o) # Get hour of datetime cdef inline int datetime_hour(object o): return PyDateTime_DATE_GET_HOUR(o) # Get minute of datetime cdef inline int datetime_minute(object o): return PyDateTime_DATE_GET_MINUTE(o) # Get second of datetime cdef inline int datetime_second(object o): return PyDateTime_DATE_GET_SECOND(o) # Get microsecond of datetime cdef inline int datetime_microsecond(object o): return PyDateTime_DATE_GET_MICROSECOND(o) # Get days of timedelta cdef inline int timedelta_days(object o): return (o).days # Get seconds of timedelta cdef inline int timedelta_seconds(object o): return (o).seconds # Get microseconds of timedelta cdef inline int timedelta_microseconds(object o): return (o).microseconds Cython-0.23.4/Cython/Includes/cpython/complex.pxd0000644000175600017570000000336112606202452023071 0ustar jenkinsjenkins00000000000000 cdef extern from "Python.h": ctypedef struct Py_complex: double imag double real ############################################################################ # 7.2.5.2 Complex Numbers as Python Objects ############################################################################ # PyComplexObject # This subtype of PyObject represents a Python complex number object. ctypedef class __builtin__.complex [object PyComplexObject]: cdef Py_complex cval # not making these available to keep them read-only: #cdef double imag "cval.imag" #cdef double real "cval.real" # PyTypeObject PyComplex_Type # This instance of PyTypeObject represents the Python complex # number type. It is the same object as complex and # types.ComplexType. bint PyComplex_Check(object p) # Return true if its argument is a PyComplexObject or a subtype of # PyComplexObject. bint PyComplex_CheckExact(object p) # Return true if its argument is a PyComplexObject, but not a subtype of PyComplexObject. object PyComplex_FromCComplex(Py_complex v) # Return value: New reference. # Create a new Python complex number object from a C Py_complex value. object PyComplex_FromDoubles(double real, double imag) # Return value: New reference. # Return a new PyComplexObject object from real and imag. double PyComplex_RealAsDouble(object op) except? -1 # Return the real part of op as a C double. double PyComplex_ImagAsDouble(object op) except? -1 # Return the imaginary part of op as a C double. Py_complex PyComplex_AsCComplex(object op) # Return the Py_complex value of the complex number op. # # Returns (-1+0i) in case of an error Cython-0.23.4/Cython/Includes/cpython/cobject.pxd0000644000175600017570000000276412606202452023041 0ustar jenkinsjenkins00000000000000 cdef extern from "Python.h": ########################################################################### # Warning: # # The CObject API is deprecated as of Python 3.1. Please switch to # the new Capsules API. ########################################################################### int PyCObject_Check(object p) # Return true if its argument is a PyCObject. object PyCObject_FromVoidPtr(void* cobj, void (*destr)(void *)) # Return value: New reference. # # Create a PyCObject from the void * cobj. The destr function will # be called when the object is reclaimed, unless it is NULL. object PyCObject_FromVoidPtrAndDesc(void* cobj, void* desc, void (*destr)(void *, void *)) # Return value: New reference. # # Create a PyCObject from the void * cobj. The destr function will # be called when the object is reclaimed. The desc argument can be # used to pass extra callback data for the destructor function. void* PyCObject_AsVoidPtr(object self) except? NULL # Return the object void * that the PyCObject self was created with. void* PyCObject_GetDesc(object self) except? NULL # Return the description void * that the PyCObject self was created with. int PyCObject_SetVoidPtr(object self, void* cobj) except 0 # Set the void pointer inside self to cobj. The PyCObject must not # have an associated destructor. Return true on success, false on # failure. Cython-0.23.4/Cython/Includes/cpython/bytes.pxd0000644000175600017570000002326212606202452022552 0ustar jenkinsjenkins00000000000000from .object cimport PyObject cdef extern from "Python.h": ctypedef struct va_list ############################################################################ # 7.3.1 String Objects ############################################################################ # These functions raise TypeError when expecting a string # parameter and are called with a non-string parameter. # PyStringObject # This subtype of PyObject represents a Python bytes object. # PyTypeObject PyBytes_Type # This instance of PyTypeObject represents the Python bytes type; # it is the same object as bytes and types.BytesType in the Python # layer. bint PyBytes_Check(object o) # Return true if the object o is a string object or an instance of # a subtype of the string type. bint PyBytes_CheckExact(object o) # Return true if the object o is a string object, but not an instance of a subtype of the string type. bytes PyBytes_FromString(char *v) # Return value: New reference. # Return a new string object with the value v on success, and NULL # on failure. The parameter v must not be NULL; it will not be # checked. bytes PyBytes_FromStringAndSize(char *v, Py_ssize_t len) # Return value: New reference. # Return a new string object with the value v and length len on # success, and NULL on failure. If v is NULL, the contents of the # string are uninitialized. bytes PyBytes_FromFormat(char *format, ...) # Return value: New reference. # Take a C printf()-style format string and a variable number of # arguments, calculate the size of the resulting Python string and # return a string with the values formatted into it. The variable # arguments must be C types and must correspond exactly to the # format characters in the format string. The following format # characters are allowed: # Format Characters Type Comment # %% n/a The literal % character. # %c int A single character, represented as an C int. # %d int Exactly equivalent to printf("%d"). # %u unsigned int Exactly equivalent to printf("%u"). # %ld long Exactly equivalent to printf("%ld"). # %lu unsigned long Exactly equivalent to printf("%lu"). # %zd Py_ssize_t Exactly equivalent to printf("%zd"). # %zu size_t Exactly equivalent to printf("%zu"). # %i int Exactly equivalent to printf("%i"). # %x int Exactly equivalent to printf("%x"). # %s char* A null-terminated C character array. # %p void* The hex representation of a C pointer. # Mostly equivalent to printf("%p") except that it is guaranteed to # start with the literal 0x regardless of what the platform's printf # yields. # An unrecognized format character causes all the rest of the # format string to be copied as-is to the result string, and any # extra arguments discarded. bytes PyBytes_FromFormatV(char *format, va_list vargs) # Return value: New reference. # Identical to PyBytes_FromFormat() except that it takes exactly two arguments. Py_ssize_t PyBytes_Size(object string) except -1 # Return the length of the string in string object string. Py_ssize_t PyBytes_GET_SIZE(object string) # Macro form of PyBytes_Size() but without error checking. char* PyBytes_AsString(object string) except NULL # Return a NUL-terminated representation of the contents of # string. The pointer refers to the internal buffer of string, not # a copy. The data must not be modified in any way, unless the # string was just created using PyBytes_FromStringAndSize(NULL, # size). It must not be deallocated. If string is a Unicode # object, this function computes the default encoding of string # and operates on that. If string is not a string object at all, # PyBytes_AsString() returns NULL and raises TypeError. char* PyBytes_AS_STRING(object string) # Macro form of PyBytes_AsString() but without error # checking. Only string objects are supported; no Unicode objects # should be passed. int PyBytes_AsStringAndSize(object obj, char **buffer, Py_ssize_t *length) except -1 # Return a NULL-terminated representation of the contents of the # object obj through the output variables buffer and length. # # The function accepts both string and Unicode objects as # input. For Unicode objects it returns the default encoded # version of the object. If length is NULL, the resulting buffer # may not contain NUL characters; if it does, the function returns # -1 and a TypeError is raised. # The buffer refers to an internal string buffer of obj, not a # copy. The data must not be modified in any way, unless the # string was just created using PyBytes_FromStringAndSize(NULL, # size). It must not be deallocated. If string is a Unicode # object, this function computes the default encoding of string # and operates on that. If string is not a string object at all, # PyBytes_AsStringAndSize() returns -1 and raises TypeError. void PyBytes_Concat(PyObject **string, object newpart) # Create a new string object in *string containing the contents of # newpart appended to string; the caller will own the new # reference. The reference to the old value of string will be # stolen. If the new string cannot be created, the old reference # to string will still be discarded and the value of *string will # be set to NULL; the appropriate exception will be set. void PyBytes_ConcatAndDel(PyObject **string, object newpart) # Create a new string object in *string containing the contents of # newpart appended to string. This version decrements the # reference count of newpart. int _PyBytes_Resize(PyObject **string, Py_ssize_t newsize) except -1 # A way to resize a string object even though it is # ``immutable''. Only use this to build up a brand new string # object; don't use this if the string may already be known in # other parts of the code. It is an error to call this function if # the refcount on the input string object is not one. Pass the # address of an existing string object as an lvalue (it may be # written into), and the new size desired. On success, *string # holds the resized string object and 0 is returned; the address # in *string may differ from its input value. If the reallocation # fails, the original string object at *string is deallocated, # *string is set to NULL, a memory exception is set, and -1 is # returned. bytes PyBytes_Format(object format, object args) # Return value: New reference. Return a new string object from # format and args. Analogous to format % args. The args argument # must be a tuple. void PyBytes_InternInPlace(PyObject **string) # Intern the argument *string in place. The argument must be the # address of a pointer variable pointing to a Python string # object. If there is an existing interned string that is the same # as *string, it sets *string to it (decrementing the reference # count of the old string object and incrementing the reference # count of the interned string object), otherwise it leaves # *string alone and interns it (incrementing its reference # count). (Clarification: even though there is a lot of talk about # reference counts, think of this function as # reference-count-neutral; you own the object after the call if # and only if you owned it before the call.) bytes PyBytes_InternFromString(char *v) # Return value: New reference. # A combination of PyBytes_FromString() and # PyBytes_InternInPlace(), returning either a new string object # that has been interned, or a new (``owned'') reference to an # earlier interned string object with the same value. object PyBytes_Decode(char *s, Py_ssize_t size, char *encoding, char *errors) # Return value: New reference. # Create an object by decoding size bytes of the encoded buffer s # using the codec registered for encoding. encoding and errors # have the same meaning as the parameters of the same name in the # unicode() built-in function. The codec to be used is looked up # using the Python codec registry. Return NULL if an exception was # raised by the codec. object PyBytes_AsDecodedObject(object str, char *encoding, char *errors) # Return value: New reference. # Decode a string object by passing it to the codec registered for # encoding and return the result as Python object. encoding and # errors have the same meaning as the parameters of the same name # in the string encode() method. The codec to be used is looked up # using the Python codec registry. Return NULL if an exception was # raised by the codec. object PyBytes_Encode(char *s, Py_ssize_t size, char *encoding, char *errors) # Return value: New reference. # Encode the char buffer of the given size by passing it to the # codec registered for encoding and return a Python # object. encoding and errors have the same meaning as the # parameters of the same name in the string encode() method. The # codec to be used is looked up using the Python codec # registry. Return NULL if an exception was raised by the codec. object PyBytes_AsEncodedObject(object str, char *encoding, char *errors) # Return value: New reference. # Encode a string object using the codec registered for encoding # and return the result as Python object. encoding and errors have # the same meaning as the parameters of the same name in the # string encode() method. The codec to be used is looked up using # the Python codec registry. Return NULL if an exception was # raised by the codec. Cython-0.23.4/Cython/Includes/cpython/buffer.pxd0000644000175600017570000001133712606202452022675 0ustar jenkinsjenkins00000000000000# Please see the Python header files (object.h/abstract.h) for docs cdef extern from "Python.h": cdef enum: PyBUF_SIMPLE, PyBUF_WRITABLE, PyBUF_WRITEABLE, # backwards compatability PyBUF_FORMAT, PyBUF_ND, PyBUF_STRIDES, PyBUF_C_CONTIGUOUS, PyBUF_F_CONTIGUOUS, PyBUF_ANY_CONTIGUOUS, PyBUF_INDIRECT, PyBUF_CONTIG, PyBUF_CONTIG_RO, PyBUF_STRIDED, PyBUF_STRIDED_RO, PyBUF_RECORDS, PyBUF_RECORDS_RO, PyBUF_FULL, PyBUF_FULL_RO, PyBUF_READ, PyBUF_WRITE, PyBUF_SHADOW bint PyObject_CheckBuffer(object obj) # Return 1 if obj supports the buffer interface otherwise 0. int PyObject_GetBuffer(object obj, Py_buffer *view, int flags) except -1 # Export obj into a Py_buffer, view. These arguments must never be # NULL. The flags argument is a bit field indicating what kind of # buffer the caller is prepared to deal with and therefore what # kind of buffer the exporter is allowed to return. The buffer # interface allows for complicated memory sharing possibilities, # but some caller may not be able to handle all the complexity but # may want to see if the exporter will let them take a simpler # view to its memory. # Some exporters may not be able to share memory in every possible # way and may need to raise errors to signal to some consumers # that something is just not possible. These errors should be a # BufferError unless there is another error that is actually # causing the problem. The exporter can use flags information to # simplify how much of the Py_buffer structure is filled in with # non-default values and/or raise an error if the object can’t # support a simpler view of its memory. # 0 is returned on success and -1 on error. void PyBuffer_Release(Py_buffer *view) # Release the buffer view. This should be called when the buffer # is no longer being used as it may free memory from it. void* PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices) # ?? Py_ssize_t PyBuffer_SizeFromFormat(char *) # actually const char # Return the implied ~Py_buffer.itemsize from the struct-stype # ~Py_buffer.format int PyBuffer_ToContiguous(void *buf, Py_buffer *view, Py_ssize_t len, char fort) # ?? int PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort) # ?? int PyObject_CopyToObject(object obj, void *buf, Py_ssize_t len, char fortran) except -1 # Copy len bytes of data pointed to by the contiguous chunk of # memory pointed to by buf into the buffer exported by obj. The # buffer must of course be writable. Return 0 on success and # return -1 and raise an error on failure. If the object does not # have a writable buffer, then an error is raised. If fortran is # 'F', then if the object is multi-dimensional, then the data will # be copied into the array in Fortran-style (first dimension # varies the fastest). If fortran is 'C', then the data will be # copied into the array in C-style (last dimension varies the # fastest). If fortran is 'A', then it does not matter and the # copy will be made in whatever way is more efficient. int PyObject_CopyData(object dest, object src) except -1 # Copy the data from the src buffer to the buffer of destination bint PyBuffer_IsContiguous(Py_buffer *view, char fort) # Return 1 if the memory defined by the view is C-style (fortran # is 'C') or Fortran-style (fortran is 'F') contiguous or either # one (fortran is 'A'). Return 0 otherwise. void PyBuffer_FillContiguousStrides(int ndims, Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t itemsize, char fort) # Fill the strides array with byte-strides of a contiguous # (Fortran-style if fort is 'F' or C-style otherwise) array of the # given shape with the given number of bytes per element. int PyBuffer_FillInfo(Py_buffer *view, object exporter, void *buf, Py_ssize_t len, int readonly, int flags) except -1 # Fill in a buffer-info structure, view, correctly for an exporter # that can only share a contiguous chunk of memory of “unsigned # bytes†of the given length. Return 0 on success and -1 (with # raising an error) on error. # DEPRECATED HERE: do not cimport from here, cimport from cpython.object instead object PyObject_Format(object obj, object format_spec) # Takes an arbitrary object and returns the result of calling # obj.__format__(format_spec). Cython-0.23.4/Cython/Includes/cpython/bool.pxd0000644000175600017570000000251712606202452022357 0ustar jenkinsjenkins00000000000000 cdef extern from "Python.h": ############################################################################ # 7.2.2 Boolean Objects ############################################################################ ctypedef class __builtin__.bool [object PyBoolObject]: pass # Booleans in Python are implemented as a subclass of # integers. There are only two booleans, Py_False and Py_True. As # such, the normal creation and deletion functions don't apply to # booleans. The following macros are available, however. bint PyBool_Check(object o) # Return true if o is of type PyBool_Type. #PyObject* Py_False # The Python False object. This object has no methods. It needs to # be treated just like any other object with respect to reference # counts. #PyObject* Py_True # The Python True object. This object has no methods. It needs to # be treated just like any other object with respect to reference # counts. # Py_RETURN_FALSE # Return Py_False from a function, properly incrementing its reference count. # Py_RETURN_TRUE # Return Py_True from a function, properly incrementing its reference count. object PyBool_FromLong(long v) # Return value: New reference. # Return a new reference to Py_True or Py_False depending on the truth value of v. Cython-0.23.4/Cython/Includes/cpython/array.pxd0000644000175600017570000001353512606202452022544 0ustar jenkinsjenkins00000000000000""" array.pxd Cython interface to Python's array.array module. * 1D contiguous data view * tools for fast array creation, maximum C-speed and handiness * suitable as allround light weight auto-array within Cython code too Usage: >>> cimport array Usage through Cython buffer interface (Py2.3+): >>> def f(arg1, unsigned i, double dx) ... array.array[double] a = arg1 ... a[i] += dx Fast C-level new_array(_zeros), resize_array, copy_array, Py_SIZE(obj), zero_array cdef array.array[double] k = array.copy(d) cdef array.array[double] n = array.array(d, Py_SIZE(d) * 2 ) cdef array.array[double] m = array.zeros_like(FLOAT_TEMPLATE) array.resize(f, 200000) Zero overhead with naked data pointer views by union: _f, _d, _i, _c, _u, ... => Original C array speed + Python dynamic memory management cdef array.array a = inarray if a._d[2] += 0.66 # use as double array without extra casting float *subview = vector._f + 10 # starting from 10th element unsigned char *subview_buffer = vector._B + 4 Suitable as lightweight arrays intra Cython without speed penalty. Replacement for C stack/malloc arrays; no trouble with refcounting, mem.leaks; seamless Python compatibility, buffer() optional last changes: 2009-05-15 rk : 2009-12-06 bp : 2012-05-02 andreasvc : (see revision control) """ from libc.string cimport strcat, strncat, \ memset, memchr, memcmp, memcpy, memmove from cpython.object cimport Py_SIZE from cpython.ref cimport PyTypeObject, Py_TYPE from cpython.exc cimport PyErr_BadArgument from cpython.mem cimport PyMem_Malloc, PyMem_Free cdef extern from *: # Hard-coded utility code hack. ctypedef class array.array [object arrayobject] ctypedef object GETF(array a, Py_ssize_t ix) ctypedef object SETF(array a, Py_ssize_t ix, object o) ctypedef struct arraydescr: # [object arraydescr]: int typecode int itemsize GETF getitem # PyObject * (*getitem)(struct arrayobject *, Py_ssize_t); SETF setitem # int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *); ctypedef union __data_union: # views of ob_item: float* as_floats # direct float pointer access to buffer double* as_doubles # double ... int* as_ints unsigned int *as_uints unsigned char *as_uchars signed char *as_schars char *as_chars unsigned long *as_ulongs long *as_longs short *as_shorts unsigned short *as_ushorts Py_UNICODE *as_pyunicodes void *as_voidptr ctypedef class array.array [object arrayobject]: cdef __cythonbufferdefaults__ = {'ndim' : 1, 'mode':'c'} cdef: Py_ssize_t ob_size arraydescr* ob_descr # struct arraydescr *ob_descr; __data_union data def __getbuffer__(self, Py_buffer* info, int flags): # This implementation of getbuffer is geared towards Cython # requirements, and does not yet fullfill the PEP. # In particular strided access is always provided regardless # of flags item_count = Py_SIZE(self) info.suboffsets = NULL info.buf = self.data.as_chars info.readonly = 0 info.ndim = 1 info.itemsize = self.ob_descr.itemsize # e.g. sizeof(float) info.len = info.itemsize * item_count info.shape = PyMem_Malloc(sizeof(Py_ssize_t) + 2) if not info.shape: raise MemoryError() info.shape[0] = item_count # constant regardless of resizing info.strides = &info.itemsize info.format = (info.shape + 1) info.format[0] = self.ob_descr.typecode info.format[1] = 0 info.obj = self def __releasebuffer__(self, Py_buffer* info): PyMem_Free(info.shape) array newarrayobject(PyTypeObject* type, Py_ssize_t size, arraydescr *descr) # fast resize/realloc # not suitable for small increments; reallocation 'to the point' int resize(array self, Py_ssize_t n) except -1 # efficient for small increments (not in Py2.3-) int resize_smart(array self, Py_ssize_t n) except -1 cdef inline array clone(array template, Py_ssize_t length, bint zero): """ fast creation of a new array, given a template array. type will be same as template. if zero is true, new array will be initialized with zeroes.""" op = newarrayobject(Py_TYPE(template), length, template.ob_descr) if zero and op is not None: memset(op.data.as_chars, 0, length * op.ob_descr.itemsize) return op cdef inline array copy(array self): """ make a copy of an array. """ op = newarrayobject(Py_TYPE(self), Py_SIZE(self), self.ob_descr) memcpy(op.data.as_chars, self.data.as_chars, Py_SIZE(op) * op.ob_descr.itemsize) return op cdef inline int extend_buffer(array self, char* stuff, Py_ssize_t n) except -1: """ efficent appending of new stuff of same type (e.g. of same array type) n: number of elements (not number of bytes!) """ cdef Py_ssize_t itemsize = self.ob_descr.itemsize cdef Py_ssize_t origsize = Py_SIZE(self) resize_smart(self, origsize + n) memcpy(self.data.as_chars + origsize * itemsize, stuff, n * itemsize) return 0 cdef inline int extend(array self, array other) except -1: """ extend array with data from another array; types must match. """ if self.ob_descr.typecode != other.ob_descr.typecode: PyErr_BadArgument() return extend_buffer(self, other.data.as_chars, Py_SIZE(other)) cdef inline void zero(array self): """ set all elements of array to zero. """ memset(self.data.as_chars, 0, Py_SIZE(self) * self.ob_descr.itemsize) Cython-0.23.4/Cython/Includes/cpython/__init__.pxd0000644000175600017570000002007412606202452023161 0ustar jenkinsjenkins00000000000000##################################################################### # # These are the Cython pxd files for (most of) the Python/C API. # # REFERENCE COUNTING: # # JUST TO SCARE YOU: # If you are going to use any of the Python/C API in your Cython # program, you might be responsible for doing reference counting. # Read http://docs.python.org/api/refcounts.html which is so # important I've copied it below. # # For all the declaration below, whenver the Py_ function returns # a *new reference* to a PyObject*, the return type is "object". # When the function returns a borrowed reference, the return # type is PyObject*. When Cython sees "object" as a return type # it doesn't increment the reference count. When it sees PyObject* # in order to use the result you must explicitly cast to , # and when you do that Cython increments the reference count wether # you want it to or not, forcing you to an explicit DECREF (or leak memory). # To avoid this we make the above convention. Note, you can # always locally override this convention by putting something like # # cdef extern from "Python.h": # PyObject* PyNumber_Add(PyObject *o1, PyObject *o2) # # in your .pyx file or into a cimported .pxd file. You just have to # use the one from the right (pxd-)namespace then. # # Cython automatically takes care of reference counting for anything # of type object. # ## More precisely, I think the correct convention for ## using the Python/C API from Cython is as follows. ## ## (1) Declare all input arguments as type "object". This way no explicit ## casting is needed, and moreover Cython doesn't generate ## any funny reference counting. ## (2) Declare output as object if a new reference is returned. ## (3) Declare output as PyObject* if a borrowed reference is returned. ## ## This way when you call objects, no cast is needed, and if the api ## calls returns a new reference (which is about 95% of them), then ## you can just assign to a variable of type object. With borrowed ## references if you do an explicit typecast to , Cython generates an ## INCREF and DECREF so you have to be careful. However, you got a ## borrowed reference in this case, so there's got to be another reference ## to your object, so you're OK, as long as you relealize this ## and use the result of an explicit cast to as a borrowed ## reference (and you can call Py_INCREF if you want to turn it ## into another reference for some reason). # # "The reference count is important because today's computers have # a finite (and often severely limited) memory size; it counts how # many different places there are that have a reference to an # object. Such a place could be another object, or a global (or # static) C variable, or a local variable in some C function. When # an object's reference count becomes zero, the object is # deallocated. If it contains references to other objects, their # reference count is decremented. Those other objects may be # deallocated in turn, if this decrement makes their reference # count become zero, and so on. (There's an obvious problem with # objects that reference each other here; for now, the solution is # ``don't do that.'') # # Reference counts are always manipulated explicitly. The normal # way is to use the macro Py_INCREF() to increment an object's # reference count by one, and Py_DECREF() to decrement it by # one. The Py_DECREF() macro is considerably more complex than the # incref one, since it must check whether the reference count # becomes zero and then cause the object's deallocator to be # called. The deallocator is a function pointer contained in the # object's type structure. The type-specific deallocator takes # care of decrementing the reference counts for other objects # contained in the object if this is a compound object type, such # as a list, as well as performing any additional finalization # that's needed. There's no chance that the reference count can # overflow; at least as many bits are used to hold the reference # count as there are distinct memory locations in virtual memory # (assuming sizeof(long) >= sizeof(char*)). Thus, the reference # count increment is a simple operation. # # It is not necessary to increment an object's reference count for # every local variable that contains a pointer to an object. In # theory, the object's reference count goes up by one when the # variable is made to point to it and it goes down by one when the # variable goes out of scope. However, these two cancel each other # out, so at the end the reference count hasn't changed. The only # real reason to use the reference count is to prevent the object # from being deallocated as long as our variable is pointing to # it. If we know that there is at least one other reference to the # object that lives at least as long as our variable, there is no # need to increment the reference count temporarily. An important # situation where this arises is in objects that are passed as # arguments to C functions in an extension module that are called # from Python; the call mechanism guarantees to hold a reference # to every argument for the duration of the call. # # However, a common pitfall is to extract an object from a list # and hold on to it for a while without incrementing its reference # count. Some other operation might conceivably remove the object # from the list, decrementing its reference count and possible # deallocating it. The real danger is that innocent-looking # operations may invoke arbitrary Python code which could do this; # there is a code path which allows control to flow back to the # user from a Py_DECREF(), so almost any operation is potentially # dangerous. # # A safe approach is to always use the generic operations # (functions whose name begins with "PyObject_", "PyNumber_", # "PySequence_" or "PyMapping_"). These operations always # increment the reference count of the object they return. This # leaves the caller with the responsibility to call Py_DECREF() # when they are done with the result; this soon becomes second # nature. # # Now you should read http://docs.python.org/api/refcountDetails.html # just to be sure you understand what is going on. # ################################################################# ################################################################# # BIG FAT DEPRECATION WARNING ################################################################# # Do NOT cimport any names directly from the cpython package, # despite of the star-imports below. They will be removed at # some point. # Instead, use the correct sub-module to draw your cimports from. # # A direct cimport from the package will make your code depend on # all of the existing declarations. This may have side-effects # and reduces the portability of your code. ################################################################# # START OF DEPRECATED SECTION ################################################################# from cpython.version cimport * from cpython.ref cimport * from cpython.exc cimport * from cpython.module cimport * from cpython.mem cimport * from cpython.tuple cimport * from cpython.list cimport * from cpython.object cimport * from cpython.sequence cimport * from cpython.mapping cimport * from cpython.iterator cimport * from cpython.type cimport * from cpython.number cimport * from cpython.int cimport * from cpython.bool cimport * from cpython.long cimport * from cpython.float cimport * from cpython.complex cimport * from cpython.string cimport * from cpython.unicode cimport * from cpython.dict cimport * from cpython.instance cimport * from cpython.function cimport * from cpython.method cimport * from cpython.weakref cimport * from cpython.getargs cimport * from cpython.pythread cimport * from cpython.pystate cimport * # Python <= 2.x from cpython.cobject cimport * from cpython.oldbuffer cimport * # Python >= 2.4 from cpython.set cimport * # Python >= 2.6 from cpython.buffer cimport * from cpython.bytes cimport * # Python >= 3.0 from cpython.pycapsule cimport * ################################################################# # END OF DEPRECATED SECTION ################################################################# Cython-0.23.4/Cython/Includes/Deprecated/0000755000175600017570000000000012606202455021261 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Includes/Deprecated/stl.pxd0000644000175600017570000000421312606202452022575 0ustar jenkinsjenkins00000000000000cdef extern from "" namespace std: cdef cppclass vector[TYPE]: #constructors __init__() __init__(vector&) __init__(int) __init__(int, TYPE&) __init__(iterator, iterator) #operators TYPE& __getitem__(int) TYPE& __setitem__(int, TYPE&) vector __new__(vector&) bool __eq__(vector&, vector&) bool __ne__(vector&, vector&) bool __lt__(vector&, vector&) bool __gt__(vector&, vector&) bool __le__(vector&, vector&) bool __ge__(vector&, vector&) #others void assign(int, TYPE) #void assign(iterator, iterator) TYPE& at(int) TYPE& back() iterator begin() int capacity() void clear() bool empty() iterator end() iterator erase(iterator) iterator erase(iterator, iterator) TYPE& front() iterator insert(iterator, TYPE&) void insert(iterator, int, TYPE&) void insert(iterator, iterator) int max_size() void pop_back() void push_back(TYPE&) iterator rbegin() iterator rend() void reserve(int) void resize(int) void resize(int, TYPE&) #void resize(size_type num, const TYPE& = TYPE()) int size() void swap(container&) cdef extern from "" namespace std: cdef cppclass deque[TYPE]: #constructors __init__() __init__(deque&) __init__(int) __init__(int, TYPE&) __init__(iterator, iterator) #operators TYPE& operator[]( size_type index ); const TYPE& operator[]( size_type index ) const; deque __new__(deque&); bool __eq__(deque&, deque&); bool __ne__(deque&, deque&); bool __lt__(deque&, deque&); bool __gt__(deque&, deque&); bool __le__(deque&, deque&); bool __ge__(deque&, deque&); #others void assign(int, TYPE&) void assign(iterator, iterator) TYPE& at(int) TYPE& back() iterator begin() void clear() bool empty() iterator end() iterator erase(iterator) iterator erase(iterator, iterator) TYPE& front() iterator insert(iterator, TYPE&) void insert(iterator, int, TYPE&) void insert(iterator, iterator, iterator) int max_size() void pop_back() void pop_front() void push_back(TYPE&) void push_front(TYPE&) iterator rbegin() iterator rend() void resize(int) void resize(int, TYPE&) int size() void swap(container&) Cython-0.23.4/Cython/Includes/Deprecated/stdlib.pxd0000644000175600017570000000010112606202452023244 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from libc.stdlib cimport * Cython-0.23.4/Cython/Includes/Deprecated/stdio.pxd0000644000175600017570000000010012606202452023104 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from libc.stdio cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_weakref.pxd0000644000175600017570000000010512606202452025014 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.weakref cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_version.pxd0000644000175600017570000000010512606202452025055 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.version cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_unicode.pxd0000644000175600017570000000010512606202452025016 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.unicode cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_type.pxd0000644000175600017570000000010212606202452024346 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.type cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_tuple.pxd0000644000175600017570000000010312606202452024517 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.tuple cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_string.pxd0000644000175600017570000000010412606202452024675 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.string cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_set.pxd0000644000175600017570000000010112606202452024157 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.set cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_sequence.pxd0000644000175600017570000000010612606202452025201 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.sequence cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_ref.pxd0000644000175600017570000000010112606202452024140 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.ref cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_pycapsule.pxd0000644000175600017570000000010712606202452025377 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.pycapsule cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_oldbuffer.pxd0000644000175600017570000000010712606202452025342 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.oldbuffer cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_object.pxd0000644000175600017570000000010412606202452024635 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.object cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_number.pxd0000644000175600017570000000010412606202452024657 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.number cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_module.pxd0000644000175600017570000000010412606202452024654 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.module cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_method.pxd0000644000175600017570000000010412606202452024647 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.method cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_mem.pxd0000644000175600017570000000010112606202452024142 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.mem cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_mapping.pxd0000644000175600017570000000010512606202452025023 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.mapping cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_long.pxd0000644000175600017570000000010212606202452024324 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.long cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_list.pxd0000644000175600017570000000010212606202452024340 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.list cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_iterator.pxd0000644000175600017570000000010612606202452025222 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.iterator cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_int.pxd0000644000175600017570000000010112606202452024156 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.int cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_instance.pxd0000644000175600017570000000010612606202452025175 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.instance cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_getargs.pxd0000644000175600017570000000010512606202452025024 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.getargs cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_function.pxd0000644000175600017570000000010612606202452025216 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.function cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_float.pxd0000644000175600017570000000010312606202452024473 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.float cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_exc.pxd0000644000175600017570000000010112606202452024143 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.exc cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_dict.pxd0000644000175600017570000000010212606202452024310 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.dict cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_complex.pxd0000644000175600017570000000010512606202452025037 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.complex cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_cobject.pxd0000644000175600017570000000010512606202452025001 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.cobject cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_bytes.pxd0000644000175600017570000000010312606202452024514 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.bytes cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_buffer.pxd0000644000175600017570000000010412606202452024640 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.buffer cimport * Cython-0.23.4/Cython/Includes/Deprecated/python_bool.pxd0000644000175600017570000000010212606202452024320 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython.bool cimport * Cython-0.23.4/Cython/Includes/Deprecated/python2.5.pxd0000644000175600017570000011566412606202452023556 0ustar jenkinsjenkins00000000000000# From: Eric Huss # # Here is my latest copy. It does not cover 100% of the API. It should be # current up to 2.5. # # -Eric # XXX: # - Need to support "long long" definitions that are different for different platforms. # - Support unicode platform dependencies. # - Add unicode calls. # - Add setobject calls. cdef extern from "stdio.h": ctypedef struct FILE: pass cdef extern from "Python.h": # XXX: This is platform dependent. ctypedef unsigned short Py_UNICODE ctypedef struct PyTypeObject: pass ctypedef struct PyObject: Py_ssize_t ob_refcnt PyTypeObject * ob_type ############################################################################################### # bool ############################################################################################### PyObject * Py_False PyObject * Py_True PyTypeObject PyBool_Type int PyBool_Check (object) # Always succeeds. object PyBool_FromLong (long) ############################################################################################### # buffer ############################################################################################### PyTypeObject PyBuffer_Type int Py_END_OF_BUFFER int PyBuffer_Check (object) # Always succeeds. object PyBuffer_FromMemory (void *, Py_ssize_t) object PyBuffer_FromObject (object, Py_ssize_t, Py_ssize_t) object PyBuffer_FromReadWriteMemory (void *, Py_ssize_t) object PyBuffer_FromReadWriteObject (object, Py_ssize_t, Py_ssize_t) object PyBuffer_New (Py_ssize_t) int PyObject_AsCharBuffer (object, char **, Py_ssize_t *) except -1 int PyObject_AsReadBuffer (object, void **, Py_ssize_t *) except -1 int PyObject_AsWriteBuffer (object, void **, Py_ssize_t *) except -1 int PyObject_CheckReadBuffer (object) # Always succeeds. ############################################################################################### # cobject ############################################################################################### PyTypeObject PyCObject_Type int PyCObject_Check(object) # Always succeeds. object PyCObject_FromVoidPtr(void *, void (*)(void*)) object PyCObject_FromVoidPtrAndDesc(void *, void *, void (*)(void*,void*)) void * PyCObject_AsVoidPtr(object) except NULL void * PyCObject_GetDesc(object) except NULL void * PyCObject_Import(char *, char *) except NULL ############################################################################################### # compile ############################################################################################### ctypedef struct PyCodeObject: int co_argcount int co_nlocals int co_stacksize int co_flags PyObject *co_code PyObject *co_consts PyObject *co_names PyObject *co_varnames PyObject *co_freevars PyObject *co_cellvars PyObject *co_filename PyObject *co_name int co_firstlineno PyObject *co_lnotab int PyCode_Addr2Line(PyCodeObject *, int) ############################################################################################### # complex ############################################################################################### ctypedef struct Py_complex: double real double imag PyTypeObject PyComplex_Type Py_complex PyComplex_AsCComplex (object) # Always succeeds. int PyComplex_Check (object) # Always succeeds. int PyComplex_CheckExact (object) # Always succeeds. object PyComplex_FromCComplex (Py_complex) object PyComplex_FromDoubles (double, double) double PyComplex_ImagAsDouble (object) except? -1 double PyComplex_RealAsDouble (object) except? -1 Py_complex _Py_c_diff (Py_complex, Py_complex) Py_complex _Py_c_neg (Py_complex) Py_complex _Py_c_pow (Py_complex, Py_complex) Py_complex _Py_c_prod (Py_complex, Py_complex) Py_complex _Py_c_quot (Py_complex, Py_complex) Py_complex _Py_c_sum (Py_complex, Py_complex) ############################################################################################### # dict ############################################################################################### PyTypeObject PyDict_Type int PyDict_Check (object) # Always succeeds. int PyDict_CheckExact (object) # Always succeeds. void PyDict_Clear (object) int PyDict_Contains (object, object) except -1 object PyDict_Copy (object) int PyDict_DelItem (object, object) except -1 int PyDict_DelItemString (object, char *) except -1 object PyDict_Items (object) object PyDict_Keys (object) int PyDict_Merge (object, object, int) except -1 int PyDict_MergeFromSeq2 (object, object, int) except -1 object PyDict_New () # XXX: Pyrex doesn't support pointer to a python object? #int PyDict_Next (object, Py_ssize_t *, object *, object *) # Always succeeds. int PyDict_SetItem (object, object, object) except -1 int PyDict_SetItemString (object, char *, object) except -1 Py_ssize_t PyDict_Size (object) except -1 int PyDict_Update (object, object) except -1 object PyDict_Values (object) # XXX: Borrowed reference. No exception on NULL. #object PyDict_GetItem (object, object) # XXX: Borrowed reference. No exception on NULL #object PyDict_GetItemString (object, char *) ############################################################################################### # float ############################################################################################### PyTypeObject PyFloat_Type int _PyFloat_Pack4 (double, unsigned char *, int) except -1 int _PyFloat_Pack8 (double, unsigned char *, int) except -1 double _PyFloat_Unpack4 (unsigned char *, int) except? -1 double _PyFloat_Unpack8 (unsigned char *, int) except? -1 double PyFloat_AS_DOUBLE (object) double PyFloat_AsDouble (object) except? -1 void PyFloat_AsReprString (char*, object) void PyFloat_AsString (char*, object) int PyFloat_Check (object) # Always succeeds. int PyFloat_CheckExact (object) # Always succeeds. object PyFloat_FromDouble (double) object PyFloat_FromString (object, char**) ############################################################################################### # frame ############################################################################################### ctypedef struct PyFrameObject: PyFrameObject *f_back PyCodeObject *f_code PyObject *f_builtins PyObject *f_globals PyObject *f_locals PyObject *f_trace PyObject *f_exc_type PyObject *f_exc_value PyObject *f_exc_traceback int f_lasti int f_lineno int f_restricted int f_iblock int f_nlocals int f_ncells int f_nfreevars int f_stacksize ############################################################################################### # int ############################################################################################### PyTypeObject PyInt_Type long PyInt_AS_LONG (object) # Always succeeds. long PyInt_AsLong (object) except? -1 Py_ssize_t PyInt_AsSsize_t (object) except? -1 unsigned long long PyInt_AsUnsignedLongLongMask (object) except? -1 unsigned long PyInt_AsUnsignedLongMask (object) except? -1 int PyInt_Check (object) # Always succeeds. int PyInt_CheckExact (object) # Always succeeds. object PyInt_FromLong (long) object PyInt_FromSsize_t (Py_ssize_t) object PyInt_FromString (char*, char**, int) object PyInt_FromUnicode (Py_UNICODE*, Py_ssize_t, int) long PyInt_GetMax () # Always succeeds. ############################################################################################### # iterator ############################################################################################### int PyIter_Check (object) # Always succeeds. object PyIter_Next (object) ############################################################################################### # list ############################################################################################### PyTypeObject PyList_Type int PyList_Append (object, object) except -1 object PyList_AsTuple (object) int PyList_Check (object) # Always succeeds. int PyList_CheckExact (object) # Always succeeds. int PyList_GET_SIZE (object) # Always suceeds. object PyList_GetSlice (object, Py_ssize_t, Py_ssize_t) int PyList_Insert (object, Py_ssize_t, object) except -1 object PyList_New (Py_ssize_t) int PyList_Reverse (object) except -1 int PyList_SetSlice (object, Py_ssize_t, Py_ssize_t, object) except -1 Py_ssize_t PyList_Size (object) except -1 int PyList_Sort (object) except -1 ############################################################################################### # long ############################################################################################### PyTypeObject PyLong_Type int _PyLong_AsByteArray (object, unsigned char *, size_t, int, int) except -1 object _PyLong_FromByteArray (unsigned char *, size_t, int, int) size_t _PyLong_NumBits (object) except -1 int _PyLong_Sign (object) # No error. long PyLong_AsLong (object) except? -1 long long PyLong_AsLongLong (object) except? -1 unsigned long PyLong_AsUnsignedLong (object) except? -1 unsigned long PyLong_AsUnsignedLongMask (object) except? -1 unsigned long long PyLong_AsUnsignedLongLong (object) except? -1 unsigned long long PyLong_AsUnsignedLongLongMask (object) except? -1 int PyLong_Check (object) # Always succeeds. int PyLong_CheckExact (object) # Always succeeds. object PyLong_FromDouble (double) object PyLong_FromLong (long) object PyLong_FromLongLong (long long) object PyLong_FromUnsignedLong (unsigned long) object PyLong_FromUnsignedLongLong (unsigned long long) double PyLong_AsDouble (object) except? -1 object PyLong_FromVoidPtr (void *) void * PyLong_AsVoidPtr (object) except NULL object PyLong_FromString (char *, char **, int) object PyLong_FromUnicode (Py_UNICODE*, Py_ssize_t, int) ############################################################################################### # mapping ############################################################################################### int PyMapping_Check (object) # Always succeeds. int PyMapping_DelItem (object, object) except -1 int PyMapping_DelItemString (object, char *) except -1 object PyMapping_GetItemString (object, char *) int PyMapping_HasKey (object, object) # Always succeeds. int PyMapping_HasKeyString (object, char *) # Always succeeds. object PyMapping_Items (object) object PyMapping_Keys (object) Py_ssize_t PyMapping_Length (object) except -1 int PyMapping_SetItemString (object, char *, object) except -1 Py_ssize_t PyMapping_Size (object) except -1 object PyMapping_Values (object) ############################################################################################### # mem ############################################################################################### void PyMem_Free (void * p) void * PyMem_Malloc (size_t n) void * PyMem_Realloc (void *, size_t) ############################################################################################### # modsupport ############################################################################################### object Py_BuildValue (char *, ...) object Py_VaBuildValue (char *, va_list) ############################################################################################### # number ############################################################################################### object PyNumber_Absolute (object) object PyNumber_Add (object, object) object PyNumber_And (object, object) Py_ssize_t PyNumber_AsSsize_t (object, object) except? -1 int PyNumber_Check (object) # Always succeeds. # XXX: Pyrex doesn't support pointer to python object? #int PyNumber_Coerce (object*, object*) except -1 object PyNumber_Divide (object, object) object PyNumber_Divmod (object, object) object PyNumber_Float (object) object PyNumber_FloorDivide (object, object) object PyNumber_InPlaceAdd (object, object) object PyNumber_InPlaceAnd (object, object) object PyNumber_InPlaceDivide (object, object) object PyNumber_InPlaceFloorDivide (object, object) object PyNumber_InPlaceLshift (object, object) object PyNumber_InPlaceMultiply (object, object) object PyNumber_InPlaceOr (object, object) object PyNumber_InPlacePower (object, object, object) object PyNumber_InPlaceRemainder (object, object) object PyNumber_InPlaceRshift (object, object) object PyNumber_InPlaceSubtract (object, object) object PyNumber_InPlaceTrueDivide (object, object) object PyNumber_InPlaceXor (object, object) object PyNumber_Int (object) object PyNumber_Invert (object) object PyNumber_Long (object) object PyNumber_Lshift (object, object) object PyNumber_Multiply (object, object) object PyNumber_Negative (object) object PyNumber_Or (object, object) object PyNumber_Positive (object) object PyNumber_Power (object, object, object) object PyNumber_Remainder (object, object) object PyNumber_Rshift (object, object) object PyNumber_Subtract (object, object) object PyNumber_TrueDivide (object, object) object PyNumber_Xor (object, object) ############################################################################################### # object ############################################################################################### int PyCallable_Check (object) # Always succeeds. int PyObject_AsFileDescriptor (object) except -1 object PyObject_Call (object, object, object) object PyObject_CallFunction (object, char *, ...) object PyObject_CallFunctionObjArgs (object, ...) object PyObject_CallMethod (object, char *, char *, ...) object PyObject_CallMethodObjArgs (object, object, ...) object PyObject_CallObject (object, object) int PyObject_Cmp (object, object, int *result) except -1 # Use PyObject_Cmp instead. #int PyObject_Compare (object, object) int PyObject_DelAttr (object, object) except -1 int PyObject_DelAttrString (object, char *) except -1 int PyObject_DelItem (object, object) except -1 int PyObject_DelItemString (object, char *) except -1 object PyObject_Dir (object) object PyObject_GetAttr (object, object) object PyObject_GetAttrString (object, char *) object PyObject_GetItem (object, object) object PyObject_GetIter (object) int PyObject_HasAttr (object, object) # Always succeeds. int PyObject_HasAttrString (object, char *) # Always succeeds. long PyObject_Hash (object) except -1 int PyObject_IsInstance (object, object) except -1 int PyObject_IsSubclass (object, object) except -1 int PyObject_IsTrue (object) except -1 Py_ssize_t PyObject_Length (object) except -1 int PyObject_Not (object) except -1 int PyObject_Print (object, FILE *, int) except -1 object PyObject_Repr (object) object PyObject_RichCompare (object, object, int) int PyObject_RichCompareBool (object, object, int) except -1 int PyObject_SetAttr (object, object, object) except -1 int PyObject_SetAttrString (object, char *, object) except -1 int PyObject_SetItem (object, object, object) except -1 Py_ssize_t PyObject_Size (object) except -1 object PyObject_Str (object) object PyObject_Type (object) int PyObject_TypeCheck (object, object) # Always succeeds. object PyObject_Unicode (object) ############################################################################################### # pyerrors ############################################################################################### int PyErr_BadArgument () void PyErr_BadInternalCall () int PyErr_CheckSignals () void PyErr_Clear () int PyErr_ExceptionMatches (object) object PyErr_Format (object, char *, ...) int PyErr_GivenExceptionMatches (object, object) object PyErr_NoMemory () object PyErr_Occurred () void PyErr_Restore (object, object, object) object PyErr_SetFromErrno (object) object PyErr_SetFromErrnoWithFilename (object, char *) object PyErr_SetFromErrnoWithFilenameObject (object, object) void PyErr_SetInterrupt () void PyErr_SetNone (object) void PyErr_SetObject (object, object) void PyErr_SetString (object, char *) int PyErr_Warn (object, char *) int PyErr_WarnExplicit (object, char *, char *, int, char *, object) void PyErr_WriteUnraisable (object) ############################################################################################### # pyeval # Be extremely careful with these functions. ############################################################################################### ctypedef struct PyThreadState: PyFrameObject * frame int recursion_depth void * curexc_type, * curexc_value, * curexc_traceback void * exc_type, * exc_value, * exc_traceback void PyEval_AcquireLock () void PyEval_ReleaseLock () void PyEval_AcquireThread (PyThreadState *) void PyEval_ReleaseThread (PyThreadState *) PyThreadState* PyEval_SaveThread () void PyEval_RestoreThread (PyThreadState *) ############################################################################################### # pystate # Be extremely careful with these functions. Read PEP 311 for more detail. ############################################################################################### ctypedef int PyGILState_STATE PyGILState_STATE PyGILState_Ensure () void PyGILState_Release (PyGILState_STATE) ctypedef struct PyInterpreterState: pass PyThreadState* PyThreadState_New (PyInterpreterState *) void PyThreadState_Clear (PyThreadState *) void PyThreadState_Delete (PyThreadState *) PyThreadState* PyThreadState_Get () PyThreadState* PyThreadState_Swap (PyThreadState *tstate) # XXX: Borrowed reference. #object PyThreadState_GetDict () ############################################################################################### # run # Functions for embedded interpreters are not included. ############################################################################################### ctypedef struct PyCompilerFlags: int cf_flags ctypedef struct _node: pass ctypedef void (*PyOS_sighandler_t)(int) void PyErr_Display (object, object, object) void PyErr_Print () void PyErr_PrintEx (int) char * PyOS_Readline (FILE *, FILE *, char *) PyOS_sighandler_t PyOS_getsig (int) PyOS_sighandler_t PyOS_setsig (int, PyOS_sighandler_t) _node * PyParser_SimpleParseFile (FILE *, char *, int) except NULL _node * PyParser_SimpleParseFileFlags (FILE *, char *, int, int) except NULL _node * PyParser_SimpleParseString (char *, int) except NULL _node * PyParser_SimpleParseStringFlagsFilename(char *, char *, int, int) except NULL _node * PyParser_SimpleParseStringFlags (char *, int, int) except NULL int PyRun_AnyFile (FILE *, char *) except -1 int PyRun_AnyFileEx (FILE *, char *, int) except -1 int PyRun_AnyFileExFlags (FILE *, char *, int, PyCompilerFlags *) except -1 int PyRun_AnyFileFlags (FILE *, char *, PyCompilerFlags *) except -1 object PyRun_File (FILE *, char *, int, object, object) object PyRun_FileEx (FILE *, char *, int, object, object, int) object PyRun_FileExFlags (FILE *, char *, int, object, object, int, PyCompilerFlags *) object PyRun_FileFlags (FILE *, char *, int, object, object, PyCompilerFlags *) int PyRun_InteractiveLoop (FILE *, char *) except -1 int PyRun_InteractiveLoopFlags (FILE *, char *, PyCompilerFlags *) except -1 int PyRun_InteractiveOne (FILE *, char *) except -1 int PyRun_InteractiveOneFlags (FILE *, char *, PyCompilerFlags *) except -1 int PyRun_SimpleFile (FILE *, char *) except -1 int PyRun_SimpleFileEx (FILE *, char *, int) except -1 int PyRun_SimpleFileExFlags (FILE *, char *, int, PyCompilerFlags *) except -1 int PyRun_SimpleString (char *) except -1 int PyRun_SimpleStringFlags (char *, PyCompilerFlags *) except -1 object PyRun_String (char *, int, object, object) object PyRun_StringFlags (char *, int, object, object, PyCompilerFlags *) int Py_AtExit (void (*func)()) object Py_CompileString (char *, char *, int) object Py_CompileStringFlags (char *, char *, int, PyCompilerFlags *) void Py_Exit (int) int Py_FdIsInteractive (FILE *, char *) # Always succeeds. char * Py_GetBuildInfo () char * Py_GetCompiler () char * Py_GetCopyright () char * Py_GetExecPrefix () char * Py_GetPath () char * Py_GetPlatform () char * Py_GetPrefix () char * Py_GetProgramFullPath () char * Py_GetProgramName () char * Py_GetPythonHome () char * Py_GetVersion () ############################################################################################### # sequence ############################################################################################### int PySequence_Check (object) # Always succeeds. object PySequence_Concat (object, object) int PySequence_Contains (object, object) except -1 Py_ssize_t PySequence_Count (object, object) except -1 int PySequence_DelItem (object, Py_ssize_t) except -1 int PySequence_DelSlice (object, Py_ssize_t, Py_ssize_t) except -1 object PySequence_Fast (object, char *) int PySequence_Fast_GET_SIZE (object) object PySequence_GetItem (object, Py_ssize_t) object PySequence_GetSlice (object, Py_ssize_t, Py_ssize_t) object PySequence_ITEM (object, int) int PySequence_In (object, object) except -1 object PySequence_InPlaceConcat (object, object) object PySequence_InPlaceRepeat (object, Py_ssize_t) Py_ssize_t PySequence_Index (object, object) except -1 Py_ssize_t PySequence_Length (object) except -1 object PySequence_List (object) object PySequence_Repeat (object, Py_ssize_t) int PySequence_SetItem (object, Py_ssize_t, object) except -1 int PySequence_SetSlice (object, Py_ssize_t, Py_ssize_t, object) except -1 Py_ssize_t PySequence_Size (object) except -1 object PySequence_Tuple (object) ############################################################################################### # string ############################################################################################### PyTypeObject PyString_Type # Pyrex cannot support resizing because you have no choice but to use # realloc which may call free() on the object, and there's no way to tell # Pyrex to "forget" reference counting for the object. #int _PyString_Resize (object *, Py_ssize_t) except -1 char * PyString_AS_STRING (object) # Always succeeds. object PyString_AsDecodedObject (object, char *, char *) object PyString_AsEncodedObject (object, char *, char *) object PyString_AsEncodedString (object, char *, char *) char * PyString_AsString (object) except NULL int PyString_AsStringAndSize (object, char **, Py_ssize_t *) except -1 int PyString_Check (object) # Always succeeds. int PyString_CHECK_INTERNED (object) # Always succeeds. int PyString_CheckExact (object) # Always succeeds. # XXX: Pyrex doesn't support pointer to a python object? #void PyString_Concat (object *, object) # XXX: Pyrex doesn't support pointer to a python object? #void PyString_ConcatAndDel (object *, object) object PyString_Decode (char *, int, char *, char *) object PyString_DecodeEscape (char *, int, char *, int, char *) object PyString_Encode (char *, int, char *, char *) object PyString_Format (object, object) object PyString_FromFormat (char*, ...) object PyString_FromFormatV (char*, va_list) object PyString_FromString (char *) object PyString_FromStringAndSize (char *, Py_ssize_t) Py_ssize_t PyString_GET_SIZE (object) # Always succeeds. object PyString_InternFromString (char *) # XXX: Pyrex doesn't support pointer to a python object? #void PyString_InternImmortal (object*) # XXX: Pyrex doesn't support pointer to a python object? #void PyString_InternInPlace (object*) object PyString_Repr (object, int) Py_ssize_t PyString_Size (object) except -1 # Disgusting hack to access internal object values. ctypedef struct PyStringObject: int ob_refcnt PyTypeObject * ob_type int ob_size long ob_shash int ob_sstate char * ob_sval ############################################################################################### # tuple ############################################################################################### PyTypeObject PyTuple_Type # See PyString_Resize note about resizing. #int _PyTuple_Resize (object*, Py_ssize_t) except -1 int PyTuple_Check (object) # Always succeeds. int PyTuple_CheckExact (object) # Always succeeds. Py_ssize_t PyTuple_GET_SIZE (object) # Always succeeds. object PyTuple_GetSlice (object, Py_ssize_t, Py_ssize_t) object PyTuple_New (Py_ssize_t) object PyTuple_Pack (Py_ssize_t, ...) Py_ssize_t PyTuple_Size (object) except -1 ############################################################################################### # Dangerous things! # Do not use these unless you really, really know what you are doing. ############################################################################################### void Py_INCREF (object) void Py_XINCREF (object) void Py_DECREF (object) void Py_XDECREF (object) void Py_CLEAR (object) # XXX: Stolen reference. void PyTuple_SET_ITEM (object, Py_ssize_t, value) # XXX: Borrowed reference. object PyTuple_GET_ITEM (object, Py_ssize_t) # XXX: Borrowed reference. object PyTuple_GetItem (object, Py_ssize_t) # XXX: Stolen reference. int PyTuple_SetItem (object, Py_ssize_t, object) except -1 # XXX: Steals reference. int PyList_SetItem (object, Py_ssize_t, object) except -1 # XXX: Borrowed reference object PyList_GetItem (object, Py_ssize_t) # XXX: Borrowed reference, no NULL on error. object PyList_GET_ITEM (object, Py_ssize_t) # XXX: Stolen reference. void PyList_SET_ITEM (object, Py_ssize_t, object) # XXX: Borrowed reference. object PySequence_Fast_GET_ITEM (object, Py_ssize_t) # First parameter _must_ be a PyStringObject. object _PyString_Join (object, object) Cython-0.23.4/Cython/Includes/Deprecated/python.pxd0000644000175600017570000000007512606202452023316 0ustar jenkinsjenkins00000000000000# Present for backwards compatability from cpython cimport * Cython-0.23.4/Cython/Distutils/0000755000175600017570000000000012606202455017437 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Distutils/extension.py0000644000175600017570000001114212606202452022021 0ustar jenkinsjenkins00000000000000"""Pyrex.Distutils.extension Provides a modified Extension class, that understands how to describe Pyrex extension modules in setup scripts.""" __revision__ = "$Id:$" import sys import distutils.extension as _Extension try: import warnings except ImportError: warnings = None class Extension(_Extension.Extension): # When adding arguments to this constructor, be sure to update # user_options.extend in build_ext.py. def __init__(self, name, sources, include_dirs=None, define_macros=None, undef_macros=None, library_dirs=None, libraries=None, runtime_library_dirs=None, extra_objects=None, extra_compile_args=None, extra_link_args=None, export_symbols=None, #swig_opts=None, depends=None, language=None, cython_include_dirs=None, cython_directives=None, cython_create_listing=False, cython_line_directives=False, cython_cplus=False, cython_c_in_temp=False, cython_gen_pxi=False, cython_gdb=False, no_c_in_traceback=False, cython_compile_time_env=None, **kw): # Translate pyrex_X to cython_X for backwards compatibility. had_pyrex_options = False for key in list(kw): if key.startswith('pyrex_'): had_pyrex_options = True kw['cython' + key[5:]] = kw.pop(key) if had_pyrex_options: Extension.__init__( self, name, sources, include_dirs=include_dirs, define_macros=define_macros, undef_macros=undef_macros, library_dirs=library_dirs, libraries=libraries, runtime_library_dirs=runtime_library_dirs, extra_objects=extra_objects, extra_compile_args=extra_compile_args, extra_link_args=extra_link_args, export_symbols=export_symbols, #swig_opts=swig_opts, depends=depends, language=language, no_c_in_traceback=no_c_in_traceback, **kw) return _Extension.Extension.__init__( self, name, sources, include_dirs=include_dirs, define_macros=define_macros, undef_macros=undef_macros, library_dirs=library_dirs, libraries=libraries, runtime_library_dirs=runtime_library_dirs, extra_objects=extra_objects, extra_compile_args=extra_compile_args, extra_link_args=extra_link_args, export_symbols=export_symbols, #swig_opts=swig_opts, depends=depends, language=language, **kw) self.cython_include_dirs = cython_include_dirs or [] self.cython_directives = cython_directives or {} self.cython_create_listing = cython_create_listing self.cython_line_directives = cython_line_directives self.cython_cplus = cython_cplus self.cython_c_in_temp = cython_c_in_temp self.cython_gen_pxi = cython_gen_pxi self.cython_gdb = cython_gdb self.no_c_in_traceback = no_c_in_traceback self.cython_compile_time_env = cython_compile_time_env # class Extension read_setup_file = _Extension.read_setup_file # reuse and extend original docstring from base class (if we can) if sys.version_info[0] < 3 and _Extension.Extension.__doc__: # -OO discards docstrings Extension.__doc__ = _Extension.Extension.__doc__ + """\ cython_include_dirs : [string] list of directories to search for Pyrex header files (.pxd) (in Unix form for portability) cython_directives : {string:value} dict of compiler directives cython_create_listing_file : boolean write pyrex error messages to a listing (.lis) file. cython_line_directives : boolean emit pyx line numbers for debugging/profiling cython_cplus : boolean use the C++ compiler for compiling and linking. cython_c_in_temp : boolean put generated C files in temp directory. cython_gen_pxi : boolean generate .pxi file for public declarations cython_gdb : boolean generate Cython debug information for this extension for cygdb no_c_in_traceback : boolean emit the c file and line number from the traceback for exceptions """ Cython-0.23.4/Cython/Distutils/build_ext.py0000644000175600017570000003112712606202452021771 0ustar jenkinsjenkins00000000000000"""Cython.Distutils.build_ext Implements a version of the Distutils 'build_ext' command, for building Cython extension modules.""" # This module should be kept compatible with Python 2.3. __revision__ = "$Id:$" import sys import os from distutils.errors import DistutilsPlatformError from distutils.dep_util import newer, newer_group from distutils import log from distutils.command import build_ext as _build_ext from distutils import sysconfig try: from __builtin__ import basestring except ImportError: basestring = str extension_name_re = _build_ext.extension_name_re show_compilers = _build_ext.show_compilers class Optimization(object): def __init__(self): self.flags = ( 'OPT', 'CFLAGS', 'CPPFLAGS', 'EXTRA_CFLAGS', 'BASECFLAGS', 'PY_CFLAGS', ) self.state = sysconfig.get_config_vars(*self.flags) self.config_vars = sysconfig.get_config_vars() def disable_optimization(self): "disable optimization for the C or C++ compiler" badoptions = ('-O1', '-O2', '-O3') for flag, option in zip(self.flags, self.state): if option is not None: L = [opt for opt in option.split() if opt not in badoptions] self.config_vars[flag] = ' '.join(L) def restore_state(self): "restore the original state" for flag, option in zip(self.flags, self.state): if option is not None: self.config_vars[flag] = option optimization = Optimization() class build_ext(_build_ext.build_ext): description = "build C/C++ and Cython extensions (compile/link to build directory)" sep_by = _build_ext.build_ext.sep_by user_options = _build_ext.build_ext.user_options boolean_options = _build_ext.build_ext.boolean_options help_options = _build_ext.build_ext.help_options # Add the pyrex specific data. user_options.extend([ ('cython-cplus', None, "generate C++ source files"), ('cython-create-listing', None, "write errors to a listing file"), ('cython-line-directives', None, "emit source line directives"), ('cython-include-dirs=', None, "path to the Cython include files" + sep_by), ('cython-c-in-temp', None, "put generated C files in temp directory"), ('cython-gen-pxi', None, "generate .pxi file for public declarations"), ('cython-directives=', None, "compiler directive overrides"), ('cython-gdb', None, "generate debug information for cygdb"), ('cython-compile-time-env', None, "cython compile time environment"), # For backwards compatibility. ('pyrex-cplus', None, "generate C++ source files"), ('pyrex-create-listing', None, "write errors to a listing file"), ('pyrex-line-directives', None, "emit source line directives"), ('pyrex-include-dirs=', None, "path to the Cython include files" + sep_by), ('pyrex-c-in-temp', None, "put generated C files in temp directory"), ('pyrex-gen-pxi', None, "generate .pxi file for public declarations"), ('pyrex-directives=', None, "compiler directive overrides"), ('pyrex-gdb', None, "generate debug information for cygdb"), ]) boolean_options.extend([ 'cython-cplus', 'cython-create-listing', 'cython-line-directives', 'cython-c-in-temp', 'cython-gdb', # For backwards compatibility. 'pyrex-cplus', 'pyrex-create-listing', 'pyrex-line-directives', 'pyrex-c-in-temp', 'pyrex-gdb', ]) def initialize_options(self): _build_ext.build_ext.initialize_options(self) self.cython_cplus = 0 self.cython_create_listing = 0 self.cython_line_directives = 0 self.cython_include_dirs = None self.cython_directives = None self.cython_c_in_temp = 0 self.cython_gen_pxi = 0 self.cython_gdb = False self.no_c_in_traceback = 0 self.cython_compile_time_env = None def __getattr__(self, name): if name[:6] == 'pyrex_': return getattr(self, 'cython_' + name[6:]) else: return _build_ext.build_ext.__getattr__(self, name) def __setattr__(self, name, value): if name[:6] == 'pyrex_': return setattr(self, 'cython_' + name[6:], value) else: # _build_ext.build_ext.__setattr__(self, name, value) self.__dict__[name] = value def finalize_options (self): _build_ext.build_ext.finalize_options(self) if self.cython_include_dirs is None: self.cython_include_dirs = [] elif isinstance(self.cython_include_dirs, basestring): self.cython_include_dirs = \ self.cython_include_dirs.split(os.pathsep) if self.cython_directives is None: self.cython_directives = {} # finalize_options () def run(self): # We have one shot at this before build_ext initializes the compiler. # If --pyrex-gdb is in effect as a command line option or as option # of any Extension module, disable optimization for the C or C++ # compiler. if self.cython_gdb or [1 for ext in self.extensions if getattr(ext, 'cython_gdb', False)]: optimization.disable_optimization() _build_ext.build_ext.run(self) def build_extensions(self): # First, sanity-check the 'extensions' list self.check_extensions_list(self.extensions) for ext in self.extensions: ext.sources = self.cython_sources(ext.sources, ext) self.build_extension(ext) def cython_sources(self, sources, extension): """ Walk the list of source files in 'sources', looking for Cython source files (.pyx and .py). Run Cython on all that are found, and return a modified 'sources' list with Cython source files replaced by the generated C (or C++) files. """ try: from Cython.Compiler.Main \ import CompilationOptions, \ default_options as cython_default_options, \ compile as cython_compile from Cython.Compiler.Errors import PyrexError except ImportError: e = sys.exc_info()[1] print("failed to import Cython: %s" % e) raise DistutilsPlatformError("Cython does not appear to be installed") new_sources = [] cython_sources = [] cython_targets = {} # Setup create_list and cplus from the extension options if # Cython.Distutils.extension.Extension is used, otherwise just # use what was parsed from the command-line or the configuration file. # cplus will also be set to true is extension.language is equal to # 'C++' or 'c++'. #try: # create_listing = self.cython_create_listing or \ # extension.cython_create_listing # cplus = self.cython_cplus or \ # extension.cython_cplus or \ # (extension.language != None and \ # extension.language.lower() == 'c++') #except AttributeError: # create_listing = self.cython_create_listing # cplus = self.cython_cplus or \ # (extension.language != None and \ # extension.language.lower() == 'c++') create_listing = self.cython_create_listing or \ getattr(extension, 'cython_create_listing', 0) line_directives = self.cython_line_directives or \ getattr(extension, 'cython_line_directives', 0) no_c_in_traceback = self.no_c_in_traceback or \ getattr(extension, 'no_c_in_traceback', 0) cplus = self.cython_cplus or getattr(extension, 'cython_cplus', 0) or \ (extension.language and extension.language.lower() == 'c++') cython_gen_pxi = self.cython_gen_pxi or getattr(extension, 'cython_gen_pxi', 0) cython_gdb = self.cython_gdb or getattr(extension, 'cython_gdb', False) cython_compile_time_env = self.cython_compile_time_env or \ getattr(extension, 'cython_compile_time_env', None) # Set up the include_path for the Cython compiler: # 1. Start with the command line option. # 2. Add in any (unique) paths from the extension # cython_include_dirs (if Cython.Distutils.extension is used). # 3. Add in any (unique) paths from the extension include_dirs includes = self.cython_include_dirs try: for i in extension.cython_include_dirs: if not i in includes: includes.append(i) except AttributeError: pass for i in extension.include_dirs: if not i in includes: includes.append(i) # Set up Cython compiler directives: # 1. Start with the command line option. # 2. Add in any (unique) entries from the extension # cython_directives (if Cython.Distutils.extension is used). directives = self.cython_directives if hasattr(extension, "cython_directives"): directives.update(extension.cython_directives) # Set the target_ext to '.c'. Cython will change this to '.cpp' if # needed. if cplus: target_ext = '.cpp' else: target_ext = '.c' # Decide whether to drop the generated C files into the temp dir # or the source tree. if not self.inplace and (self.cython_c_in_temp or getattr(extension, 'cython_c_in_temp', 0)): target_dir = os.path.join(self.build_temp, "pyrex") for package_name in extension.name.split('.')[:-1]: target_dir = os.path.join(target_dir, package_name) else: target_dir = None newest_dependency = None for source in sources: (base, ext) = os.path.splitext(os.path.basename(source)) if ext == ".py": # FIXME: we might want to special case this some more ext = '.pyx' if ext == ".pyx": # Cython source file output_dir = target_dir or os.path.dirname(source) new_sources.append(os.path.join(output_dir, base + target_ext)) cython_sources.append(source) cython_targets[source] = new_sources[-1] elif ext == '.pxi' or ext == '.pxd': if newest_dependency is None \ or newer(source, newest_dependency): newest_dependency = source else: new_sources.append(source) if not cython_sources: return new_sources module_name = extension.name for source in cython_sources: target = cython_targets[source] depends = [source] + list(extension.depends or ()) if(source[-4:].lower()==".pyx" and os.path.isfile(source[:-3]+"pxd")): depends += [source[:-3]+"pxd"] rebuild = self.force or newer_group(depends, target, 'newer') if not rebuild and newest_dependency is not None: rebuild = newer(newest_dependency, target) if rebuild: log.info("cythoning %s to %s", source, target) self.mkpath(os.path.dirname(target)) if self.inplace: output_dir = os.curdir else: output_dir = self.build_lib options = CompilationOptions(cython_default_options, use_listing_file = create_listing, include_path = includes, compiler_directives = directives, output_file = target, cplus = cplus, emit_linenums = line_directives, c_line_in_traceback = not no_c_in_traceback, generate_pxi = cython_gen_pxi, output_dir = output_dir, gdb_debug = cython_gdb, compile_time_env = cython_compile_time_env) result = cython_compile(source, options=options, full_module_name=module_name) else: log.info("skipping '%s' Cython extension (up-to-date)", target) return new_sources # cython_sources () # class build_ext Cython-0.23.4/Cython/Distutils/__init__.py0000644000175600017570000000014212606202452021542 0ustar jenkinsjenkins00000000000000from Cython.Distutils.build_ext import build_ext from Cython.Distutils.extension import Extension Cython-0.23.4/Cython/Debugger/0000755000175600017570000000000012606202455017177 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Debugger/libpython.py0000644000175600017570000024446612606202452021576 0ustar jenkinsjenkins00000000000000#!/usr/bin/python # NOTE: this file is taken from the Python source distribution # It can be found under Tools/gdb/libpython.py. It is shipped with Cython # because it's not installed as a python module, and because changes are only # merged into new python versions (v3.2+). ''' From gdb 7 onwards, gdb's build can be configured --with-python, allowing gdb to be extended with Python code e.g. for library-specific data visualizations, such as for the C++ STL types. Documentation on this API can be seen at: http://sourceware.org/gdb/current/onlinedocs/gdb/Python-API.html This python module deals with the case when the process being debugged (the "inferior process" in gdb parlance) is itself python, or more specifically, linked against libpython. In this situation, almost every item of data is a (PyObject*), and having the debugger merely print their addresses is not very enlightening. This module embeds knowledge about the implementation details of libpython so that we can emit useful visualizations e.g. a string, a list, a dict, a frame giving file/line information and the state of local variables In particular, given a gdb.Value corresponding to a PyObject* in the inferior process, we can generate a "proxy value" within the gdb process. For example, given a PyObject* in the inferior process that is in fact a PyListObject* holding three PyObject* that turn out to be PyStringObject* instances, we can generate a proxy value within the gdb process that is a list of strings: ["foo", "bar", "baz"] Doing so can be expensive for complicated graphs of objects, and could take some time, so we also have a "write_repr" method that writes a representation of the data to a file-like object. This allows us to stop the traversal by having the file-like object raise an exception if it gets too much data. With both "proxyval" and "write_repr" we keep track of the set of all addresses visited so far in the traversal, to avoid infinite recursion due to cycles in the graph of object references. We try to defer gdb.lookup_type() invocations for python types until as late as possible: for a dynamically linked python binary, when the process starts in the debugger, the libpython.so hasn't been dynamically loaded yet, so none of the type names are known to the debugger The module also extends gdb with some python-specific commands. ''' try: input = raw_input except NameError: pass import os import re import sys import struct import locale import atexit import warnings import tempfile import textwrap import itertools import gdb try: xrange except NameError: xrange = range if sys.version_info[0] < 3: # I think this is the only way to fix this bug :'( # http://sourceware.org/bugzilla/show_bug.cgi?id=12285 out, err = sys.stdout, sys.stderr reload(sys).setdefaultencoding('UTF-8') sys.stdout = out sys.stderr = err # Look up the gdb.Type for some standard types: _type_char_ptr = gdb.lookup_type('char').pointer() # char* _type_unsigned_char_ptr = gdb.lookup_type('unsigned char').pointer() _type_void_ptr = gdb.lookup_type('void').pointer() # void* SIZEOF_VOID_P = _type_void_ptr.sizeof Py_TPFLAGS_HEAPTYPE = (1 << 9) Py_TPFLAGS_INT_SUBCLASS = (1 << 23) Py_TPFLAGS_LONG_SUBCLASS = (1 << 24) Py_TPFLAGS_LIST_SUBCLASS = (1 << 25) Py_TPFLAGS_TUPLE_SUBCLASS = (1 << 26) Py_TPFLAGS_STRING_SUBCLASS = (1 << 27) Py_TPFLAGS_BYTES_SUBCLASS = (1 << 27) Py_TPFLAGS_UNICODE_SUBCLASS = (1 << 28) Py_TPFLAGS_DICT_SUBCLASS = (1 << 29) Py_TPFLAGS_BASE_EXC_SUBCLASS = (1 << 30) Py_TPFLAGS_TYPE_SUBCLASS = (1 << 31) MAX_OUTPUT_LEN = 1024 hexdigits = "0123456789abcdef" ENCODING = locale.getpreferredencoding() class NullPyObjectPtr(RuntimeError): pass def safety_limit(val): # Given a integer value from the process being debugged, limit it to some # safety threshold so that arbitrary breakage within said process doesn't # break the gdb process too much (e.g. sizes of iterations, sizes of lists) return min(val, 1000) def safe_range(val): # As per range, but don't trust the value too much: cap it to a safety # threshold in case the data was corrupted return range(safety_limit(val)) def write_unicode(file, text): # Write a byte or unicode string to file. Unicode strings are encoded to # ENCODING encoding with 'backslashreplace' error handler to avoid # UnicodeEncodeError. if not isinstance(text, str): text = text.encode(ENCODING, 'backslashreplace') file.write(text) def os_fsencode(filename): if isinstance(filename, str): # only encode in Py2 return filename encoding = sys.getfilesystemencoding() if encoding == 'mbcs': # mbcs doesn't support surrogateescape return filename.encode(encoding) encoded = [] for char in filename: # surrogateescape error handler if 0xDC80 <= ord(char) <= 0xDCFF: byte = chr(ord(char) - 0xDC00) else: byte = char.encode(encoding) encoded.append(byte) return ''.join(encoded) class StringTruncated(RuntimeError): pass class TruncatedStringIO(object): '''Similar to cStringIO, but can truncate the output by raising a StringTruncated exception''' def __init__(self, maxlen=None): self._val = '' self.maxlen = maxlen def write(self, data): if self.maxlen: if len(data) + len(self._val) > self.maxlen: # Truncation: self._val += data[0:self.maxlen - len(self._val)] raise StringTruncated() self._val += data def getvalue(self): return self._val # pretty printer lookup all_pretty_typenames = set() class PrettyPrinterTrackerMeta(type): def __init__(self, name, bases, dict): super(PrettyPrinterTrackerMeta, self).__init__(name, bases, dict) all_pretty_typenames.add(self._typename) # Class decorator that adds a metaclass and recreates the class with it. # Copied from 'six'. See Cython/Utils.py. def _add_metaclass(metaclass): """Class decorator for creating a class with a metaclass.""" def wrapper(cls): orig_vars = cls.__dict__.copy() slots = orig_vars.get('__slots__') if slots is not None: if isinstance(slots, str): slots = [slots] for slots_var in slots: orig_vars.pop(slots_var) orig_vars.pop('__dict__', None) orig_vars.pop('__weakref__', None) return metaclass(cls.__name__, cls.__bases__, orig_vars) return wrapper @_add_metaclass(PrettyPrinterTrackerMeta) class PyObjectPtr(object): """ Class wrapping a gdb.Value that's a either a (PyObject*) within the inferior process, or some subclass pointer e.g. (PyStringObject*) There will be a subclass for every refined PyObject type that we care about. Note that at every stage the underlying pointer could be NULL, point to corrupt data, etc; this is the debugger, after all. """ _typename = 'PyObject' def __init__(self, gdbval, cast_to=None): if cast_to: self._gdbval = gdbval.cast(cast_to) else: self._gdbval = gdbval def field(self, name): ''' Get the gdb.Value for the given field within the PyObject, coping with some python 2 versus python 3 differences. Various libpython types are defined using the "PyObject_HEAD" and "PyObject_VAR_HEAD" macros. In Python 2, this these are defined so that "ob_type" and (for a var object) "ob_size" are fields of the type in question. In Python 3, this is defined as an embedded PyVarObject type thus: PyVarObject ob_base; so that the "ob_size" field is located insize the "ob_base" field, and the "ob_type" is most easily accessed by casting back to a (PyObject*). ''' if self.is_null(): raise NullPyObjectPtr(self) if name == 'ob_type': pyo_ptr = self._gdbval.cast(PyObjectPtr.get_gdb_type()) return pyo_ptr.dereference()[name] if name == 'ob_size': pyo_ptr = self._gdbval.cast(PyVarObjectPtr.get_gdb_type()) return pyo_ptr.dereference()[name] # General case: look it up inside the object: return self._gdbval.dereference()[name] def pyop_field(self, name): ''' Get a PyObjectPtr for the given PyObject* field within this PyObject, coping with some python 2 versus python 3 differences. ''' return PyObjectPtr.from_pyobject_ptr(self.field(name)) def write_field_repr(self, name, out, visited): ''' Extract the PyObject* field named "name", and write its representation to file-like object "out" ''' field_obj = self.pyop_field(name) field_obj.write_repr(out, visited) def get_truncated_repr(self, maxlen): ''' Get a repr-like string for the data, but truncate it at "maxlen" bytes (ending the object graph traversal as soon as you do) ''' out = TruncatedStringIO(maxlen) try: self.write_repr(out, set()) except StringTruncated: # Truncation occurred: return out.getvalue() + '...(truncated)' # No truncation occurred: return out.getvalue() def type(self): return PyTypeObjectPtr(self.field('ob_type')) def is_null(self): return 0 == int(self._gdbval) def is_optimized_out(self): ''' Is the value of the underlying PyObject* visible to the debugger? This can vary with the precise version of the compiler used to build Python, and the precise version of gdb. See e.g. https://bugzilla.redhat.com/show_bug.cgi?id=556975 with PyEval_EvalFrameEx's "f" ''' return self._gdbval.is_optimized_out def safe_tp_name(self): try: return self.type().field('tp_name').string() except NullPyObjectPtr: # NULL tp_name? return 'unknown' except RuntimeError: # Can't even read the object at all? return 'unknown' def proxyval(self, visited): ''' Scrape a value from the inferior process, and try to represent it within the gdb process, whilst (hopefully) avoiding crashes when the remote data is corrupt. Derived classes will override this. For example, a PyIntObject* with ob_ival 42 in the inferior process should result in an int(42) in this process. visited: a set of all gdb.Value pyobject pointers already visited whilst generating this value (to guard against infinite recursion when visiting object graphs with loops). Analogous to Py_ReprEnter and Py_ReprLeave ''' class FakeRepr(object): """ Class representing a non-descript PyObject* value in the inferior process for when we don't have a custom scraper, intended to have a sane repr(). """ def __init__(self, tp_name, address): self.tp_name = tp_name self.address = address def __repr__(self): # For the NULL pointer, we have no way of knowing a type, so # special-case it as per # http://bugs.python.org/issue8032#msg100882 if self.address == 0: return '0x0' return '<%s at remote 0x%x>' % (self.tp_name, self.address) return FakeRepr(self.safe_tp_name(), int(self._gdbval)) def write_repr(self, out, visited): ''' Write a string representation of the value scraped from the inferior process to "out", a file-like object. ''' # Default implementation: generate a proxy value and write its repr # However, this could involve a lot of work for complicated objects, # so for derived classes we specialize this return out.write(repr(self.proxyval(visited))) @classmethod def subclass_from_type(cls, t): ''' Given a PyTypeObjectPtr instance wrapping a gdb.Value that's a (PyTypeObject*), determine the corresponding subclass of PyObjectPtr to use Ideally, we would look up the symbols for the global types, but that isn't working yet: (gdb) python print gdb.lookup_symbol('PyList_Type')[0].value Traceback (most recent call last): File "", line 1, in NotImplementedError: Symbol type not yet supported in Python scripts. Error while executing Python code. For now, we use tp_flags, after doing some string comparisons on the tp_name for some special-cases that don't seem to be visible through flags ''' try: tp_name = t.field('tp_name').string() tp_flags = int(t.field('tp_flags')) except RuntimeError: # Handle any kind of error e.g. NULL ptrs by simply using the base # class return cls #print 'tp_flags = 0x%08x' % tp_flags #print 'tp_name = %r' % tp_name name_map = {'bool': PyBoolObjectPtr, 'classobj': PyClassObjectPtr, 'instance': PyInstanceObjectPtr, 'NoneType': PyNoneStructPtr, 'frame': PyFrameObjectPtr, 'set' : PySetObjectPtr, 'frozenset' : PySetObjectPtr, 'builtin_function_or_method' : PyCFunctionObjectPtr, } if tp_name in name_map: return name_map[tp_name] if tp_flags & (Py_TPFLAGS_HEAPTYPE|Py_TPFLAGS_TYPE_SUBCLASS): return PyTypeObjectPtr if tp_flags & Py_TPFLAGS_INT_SUBCLASS: return PyIntObjectPtr if tp_flags & Py_TPFLAGS_LONG_SUBCLASS: return PyLongObjectPtr if tp_flags & Py_TPFLAGS_LIST_SUBCLASS: return PyListObjectPtr if tp_flags & Py_TPFLAGS_TUPLE_SUBCLASS: return PyTupleObjectPtr if tp_flags & Py_TPFLAGS_STRING_SUBCLASS: try: gdb.lookup_type('PyBytesObject') return PyBytesObjectPtr except RuntimeError: return PyStringObjectPtr if tp_flags & Py_TPFLAGS_UNICODE_SUBCLASS: return PyUnicodeObjectPtr if tp_flags & Py_TPFLAGS_DICT_SUBCLASS: return PyDictObjectPtr if tp_flags & Py_TPFLAGS_BASE_EXC_SUBCLASS: return PyBaseExceptionObjectPtr # Use the base class: return cls @classmethod def from_pyobject_ptr(cls, gdbval): ''' Try to locate the appropriate derived class dynamically, and cast the pointer accordingly. ''' try: p = PyObjectPtr(gdbval) cls = cls.subclass_from_type(p.type()) return cls(gdbval, cast_to=cls.get_gdb_type()) except RuntimeError as exc: # Handle any kind of error e.g. NULL ptrs by simply using the base # class pass return cls(gdbval) @classmethod def get_gdb_type(cls): return gdb.lookup_type(cls._typename).pointer() def as_address(self): return int(self._gdbval) class PyVarObjectPtr(PyObjectPtr): _typename = 'PyVarObject' class ProxyAlreadyVisited(object): ''' Placeholder proxy to use when protecting against infinite recursion due to loops in the object graph. Analogous to the values emitted by the users of Py_ReprEnter and Py_ReprLeave ''' def __init__(self, rep): self._rep = rep def __repr__(self): return self._rep def _write_instance_repr(out, visited, name, pyop_attrdict, address): '''Shared code for use by old-style and new-style classes: write a representation to file-like object "out"''' out.write('<') out.write(name) # Write dictionary of instance attributes: if isinstance(pyop_attrdict, PyDictObjectPtr): out.write('(') first = True for pyop_arg, pyop_val in pyop_attrdict.items(): if not first: out.write(', ') first = False out.write(pyop_arg.proxyval(visited)) out.write('=') pyop_val.write_repr(out, visited) out.write(')') out.write(' at remote 0x%x>' % address) class InstanceProxy(object): def __init__(self, cl_name, attrdict, address): self.cl_name = cl_name self.attrdict = attrdict self.address = address def __repr__(self): if isinstance(self.attrdict, dict): kwargs = ', '.join("%s=%r" % (arg, val) for arg, val in self.attrdict.items()) return '<%s(%s) at remote 0x%x>' % ( self.cl_name, kwargs, self.address) else: return '<%s at remote 0x%x>' % ( self.cl_name, self.address) def _PyObject_VAR_SIZE(typeobj, nitems): return ( ( typeobj.field('tp_basicsize') + nitems * typeobj.field('tp_itemsize') + (SIZEOF_VOID_P - 1) ) & ~(SIZEOF_VOID_P - 1) ).cast(gdb.lookup_type('size_t')) class PyTypeObjectPtr(PyObjectPtr): _typename = 'PyTypeObject' def get_attr_dict(self): ''' Get the PyDictObject ptr representing the attribute dictionary (or None if there's a problem) ''' try: typeobj = self.type() dictoffset = int_from_int(typeobj.field('tp_dictoffset')) if dictoffset != 0: if dictoffset < 0: type_PyVarObject_ptr = gdb.lookup_type('PyVarObject').pointer() tsize = int_from_int(self._gdbval.cast(type_PyVarObject_ptr)['ob_size']) if tsize < 0: tsize = -tsize size = _PyObject_VAR_SIZE(typeobj, tsize) dictoffset += size assert dictoffset > 0 assert dictoffset % SIZEOF_VOID_P == 0 dictptr = self._gdbval.cast(_type_char_ptr) + dictoffset PyObjectPtrPtr = PyObjectPtr.get_gdb_type().pointer() dictptr = dictptr.cast(PyObjectPtrPtr) return PyObjectPtr.from_pyobject_ptr(dictptr.dereference()) except RuntimeError: # Corrupt data somewhere; fail safe pass # Not found, or some kind of error: return None def proxyval(self, visited): ''' Support for new-style classes. Currently we just locate the dictionary using a transliteration to python of _PyObject_GetDictPtr, ignoring descriptors ''' # Guard against infinite loops: if self.as_address() in visited: return ProxyAlreadyVisited('<...>') visited.add(self.as_address()) pyop_attr_dict = self.get_attr_dict() if pyop_attr_dict: attr_dict = pyop_attr_dict.proxyval(visited) else: attr_dict = {} tp_name = self.safe_tp_name() # New-style class: return InstanceProxy(tp_name, attr_dict, int(self._gdbval)) def write_repr(self, out, visited): # Guard against infinite loops: if self.as_address() in visited: out.write('<...>') return visited.add(self.as_address()) try: tp_name = self.field('tp_name').string() except RuntimeError: tp_name = 'unknown' out.write('' % (tp_name, self.as_address())) # pyop_attrdict = self.get_attr_dict() # _write_instance_repr(out, visited, # self.safe_tp_name(), pyop_attrdict, self.as_address()) class ProxyException(Exception): def __init__(self, tp_name, args): self.tp_name = tp_name self.args = args def __repr__(self): return '%s%r' % (self.tp_name, self.args) class PyBaseExceptionObjectPtr(PyObjectPtr): """ Class wrapping a gdb.Value that's a PyBaseExceptionObject* i.e. an exception within the process being debugged. """ _typename = 'PyBaseExceptionObject' def proxyval(self, visited): # Guard against infinite loops: if self.as_address() in visited: return ProxyAlreadyVisited('(...)') visited.add(self.as_address()) arg_proxy = self.pyop_field('args').proxyval(visited) return ProxyException(self.safe_tp_name(), arg_proxy) def write_repr(self, out, visited): # Guard against infinite loops: if self.as_address() in visited: out.write('(...)') return visited.add(self.as_address()) out.write(self.safe_tp_name()) self.write_field_repr('args', out, visited) class PyClassObjectPtr(PyObjectPtr): """ Class wrapping a gdb.Value that's a PyClassObject* i.e. a instance within the process being debugged. """ _typename = 'PyClassObject' class BuiltInFunctionProxy(object): def __init__(self, ml_name): self.ml_name = ml_name def __repr__(self): return "" % self.ml_name class BuiltInMethodProxy(object): def __init__(self, ml_name, pyop_m_self): self.ml_name = ml_name self.pyop_m_self = pyop_m_self def __repr__(self): return '' % ( self.ml_name, self.pyop_m_self.safe_tp_name(), self.pyop_m_self.as_address()) class PyCFunctionObjectPtr(PyObjectPtr): """ Class wrapping a gdb.Value that's a PyCFunctionObject* (see Include/methodobject.h and Objects/methodobject.c) """ _typename = 'PyCFunctionObject' def proxyval(self, visited): m_ml = self.field('m_ml') # m_ml is a (PyMethodDef*) ml_name = m_ml['ml_name'].string() pyop_m_self = self.pyop_field('m_self') if pyop_m_self.is_null(): return BuiltInFunctionProxy(ml_name) else: return BuiltInMethodProxy(ml_name, pyop_m_self) class PyCodeObjectPtr(PyObjectPtr): """ Class wrapping a gdb.Value that's a PyCodeObject* i.e. a instance within the process being debugged. """ _typename = 'PyCodeObject' def addr2line(self, addrq): ''' Get the line number for a given bytecode offset Analogous to PyCode_Addr2Line; translated from pseudocode in Objects/lnotab_notes.txt ''' co_lnotab = self.pyop_field('co_lnotab').proxyval(set()) # Initialize lineno to co_firstlineno as per PyCode_Addr2Line # not 0, as lnotab_notes.txt has it: lineno = int_from_int(self.field('co_firstlineno')) addr = 0 for addr_incr, line_incr in zip(co_lnotab[::2], co_lnotab[1::2]): addr += ord(addr_incr) if addr > addrq: return lineno lineno += ord(line_incr) return lineno class PyDictObjectPtr(PyObjectPtr): """ Class wrapping a gdb.Value that's a PyDictObject* i.e. a dict instance within the process being debugged. """ _typename = 'PyDictObject' def iteritems(self): ''' Yields a sequence of (PyObjectPtr key, PyObjectPtr value) pairs, analagous to dict.items() ''' for i in safe_range(self.field('ma_mask') + 1): ep = self.field('ma_table') + i pyop_value = PyObjectPtr.from_pyobject_ptr(ep['me_value']) if not pyop_value.is_null(): pyop_key = PyObjectPtr.from_pyobject_ptr(ep['me_key']) yield (pyop_key, pyop_value) items = iteritems def proxyval(self, visited): # Guard against infinite loops: if self.as_address() in visited: return ProxyAlreadyVisited('{...}') visited.add(self.as_address()) result = {} for pyop_key, pyop_value in self.items(): proxy_key = pyop_key.proxyval(visited) proxy_value = pyop_value.proxyval(visited) result[proxy_key] = proxy_value return result def write_repr(self, out, visited): # Guard against infinite loops: if self.as_address() in visited: out.write('{...}') return visited.add(self.as_address()) out.write('{') first = True for pyop_key, pyop_value in self.items(): if not first: out.write(', ') first = False pyop_key.write_repr(out, visited) out.write(': ') pyop_value.write_repr(out, visited) out.write('}') class PyInstanceObjectPtr(PyObjectPtr): _typename = 'PyInstanceObject' def proxyval(self, visited): # Guard against infinite loops: if self.as_address() in visited: return ProxyAlreadyVisited('<...>') visited.add(self.as_address()) # Get name of class: in_class = self.pyop_field('in_class') cl_name = in_class.pyop_field('cl_name').proxyval(visited) # Get dictionary of instance attributes: in_dict = self.pyop_field('in_dict').proxyval(visited) # Old-style class: return InstanceProxy(cl_name, in_dict, int(self._gdbval)) def write_repr(self, out, visited): # Guard against infinite loops: if self.as_address() in visited: out.write('<...>') return visited.add(self.as_address()) # Old-style class: # Get name of class: in_class = self.pyop_field('in_class') cl_name = in_class.pyop_field('cl_name').proxyval(visited) # Get dictionary of instance attributes: pyop_in_dict = self.pyop_field('in_dict') _write_instance_repr(out, visited, cl_name, pyop_in_dict, self.as_address()) class PyIntObjectPtr(PyObjectPtr): _typename = 'PyIntObject' def proxyval(self, visited): result = int_from_int(self.field('ob_ival')) return result class PyListObjectPtr(PyObjectPtr): _typename = 'PyListObject' def __getitem__(self, i): # Get the gdb.Value for the (PyObject*) with the given index: field_ob_item = self.field('ob_item') return field_ob_item[i] def proxyval(self, visited): # Guard against infinite loops: if self.as_address() in visited: return ProxyAlreadyVisited('[...]') visited.add(self.as_address()) result = [PyObjectPtr.from_pyobject_ptr(self[i]).proxyval(visited) for i in safe_range(int_from_int(self.field('ob_size')))] return result def write_repr(self, out, visited): # Guard against infinite loops: if self.as_address() in visited: out.write('[...]') return visited.add(self.as_address()) out.write('[') for i in safe_range(int_from_int(self.field('ob_size'))): if i > 0: out.write(', ') element = PyObjectPtr.from_pyobject_ptr(self[i]) element.write_repr(out, visited) out.write(']') class PyLongObjectPtr(PyObjectPtr): _typename = 'PyLongObject' def proxyval(self, visited): ''' Python's Include/longobjrep.h has this declaration: struct _longobject { PyObject_VAR_HEAD digit ob_digit[1]; }; with this description: The absolute value of a number is equal to SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i) Negative numbers are represented with ob_size < 0; zero is represented by ob_size == 0. where SHIFT can be either: #define PyLong_SHIFT 30 #define PyLong_SHIFT 15 ''' ob_size = int(self.field('ob_size')) if ob_size == 0: return int(0) ob_digit = self.field('ob_digit') if gdb.lookup_type('digit').sizeof == 2: SHIFT = 15 else: SHIFT = 30 digits = [ob_digit[i] * (1 << (SHIFT*i)) for i in safe_range(abs(ob_size))] result = sum(digits) if ob_size < 0: result = -result return result def write_repr(self, out, visited): # Write this out as a Python 3 int literal, i.e. without the "L" suffix proxy = self.proxyval(visited) out.write("%s" % proxy) class PyBoolObjectPtr(PyLongObjectPtr): """ Class wrapping a gdb.Value that's a PyBoolObject* i.e. one of the two instances (Py_True/Py_False) within the process being debugged. """ _typename = 'PyBoolObject' def proxyval(self, visited): castto = gdb.lookup_type('PyLongObject').pointer() self._gdbval = self._gdbval.cast(castto) return bool(PyLongObjectPtr(self._gdbval).proxyval(visited)) class PyNoneStructPtr(PyObjectPtr): """ Class wrapping a gdb.Value that's a PyObject* pointing to the singleton (we hope) _Py_NoneStruct with ob_type PyNone_Type """ _typename = 'PyObject' def proxyval(self, visited): return None class PyFrameObjectPtr(PyObjectPtr): _typename = 'PyFrameObject' def __init__(self, gdbval, cast_to=None): PyObjectPtr.__init__(self, gdbval, cast_to) if not self.is_optimized_out(): self.co = PyCodeObjectPtr.from_pyobject_ptr(self.field('f_code')) self.co_name = self.co.pyop_field('co_name') self.co_filename = self.co.pyop_field('co_filename') self.f_lineno = int_from_int(self.field('f_lineno')) self.f_lasti = int_from_int(self.field('f_lasti')) self.co_nlocals = int_from_int(self.co.field('co_nlocals')) self.co_varnames = PyTupleObjectPtr.from_pyobject_ptr(self.co.field('co_varnames')) def iter_locals(self): ''' Yield a sequence of (name,value) pairs of PyObjectPtr instances, for the local variables of this frame ''' if self.is_optimized_out(): return f_localsplus = self.field('f_localsplus') for i in safe_range(self.co_nlocals): pyop_value = PyObjectPtr.from_pyobject_ptr(f_localsplus[i]) if not pyop_value.is_null(): pyop_name = PyObjectPtr.from_pyobject_ptr(self.co_varnames[i]) yield (pyop_name, pyop_value) def iter_globals(self): ''' Yield a sequence of (name,value) pairs of PyObjectPtr instances, for the global variables of this frame ''' if self.is_optimized_out(): return pyop_globals = self.pyop_field('f_globals') return iter(pyop_globals.items()) def iter_builtins(self): ''' Yield a sequence of (name,value) pairs of PyObjectPtr instances, for the builtin variables ''' if self.is_optimized_out(): return pyop_builtins = self.pyop_field('f_builtins') return iter(pyop_builtins.items()) def get_var_by_name(self, name): ''' Look for the named local variable, returning a (PyObjectPtr, scope) pair where scope is a string 'local', 'global', 'builtin' If not found, return (None, None) ''' for pyop_name, pyop_value in self.iter_locals(): if name == pyop_name.proxyval(set()): return pyop_value, 'local' for pyop_name, pyop_value in self.iter_globals(): if name == pyop_name.proxyval(set()): return pyop_value, 'global' for pyop_name, pyop_value in self.iter_builtins(): if name == pyop_name.proxyval(set()): return pyop_value, 'builtin' return None, None def filename(self): '''Get the path of the current Python source file, as a string''' if self.is_optimized_out(): return '(frame information optimized out)' return self.co_filename.proxyval(set()) def current_line_num(self): '''Get current line number as an integer (1-based) Translated from PyFrame_GetLineNumber and PyCode_Addr2Line See Objects/lnotab_notes.txt ''' if self.is_optimized_out(): return None f_trace = self.field('f_trace') if int(f_trace) != 0: # we have a non-NULL f_trace: return self.f_lineno else: #try: return self.co.addr2line(self.f_lasti) #except ValueError: # return self.f_lineno def current_line(self): '''Get the text of the current source line as a string, with a trailing newline character''' if self.is_optimized_out(): return '(frame information optimized out)' filename = self.filename() with open(os_fsencode(filename), 'r') as f: all_lines = f.readlines() # Convert from 1-based current_line_num to 0-based list offset: return all_lines[self.current_line_num()-1] def write_repr(self, out, visited): if self.is_optimized_out(): out.write('(frame information optimized out)') return out.write('Frame 0x%x, for file %s, line %i, in %s (' % (self.as_address(), self.co_filename.proxyval(visited), self.current_line_num(), self.co_name.proxyval(visited))) first = True for pyop_name, pyop_value in self.iter_locals(): if not first: out.write(', ') first = False out.write(pyop_name.proxyval(visited)) out.write('=') pyop_value.write_repr(out, visited) out.write(')') class PySetObjectPtr(PyObjectPtr): _typename = 'PySetObject' def proxyval(self, visited): # Guard against infinite loops: if self.as_address() in visited: return ProxyAlreadyVisited('%s(...)' % self.safe_tp_name()) visited.add(self.as_address()) members = [] table = self.field('table') for i in safe_range(self.field('mask')+1): setentry = table[i] key = setentry['key'] if key != 0: key_proxy = PyObjectPtr.from_pyobject_ptr(key).proxyval(visited) if key_proxy != '': members.append(key_proxy) if self.safe_tp_name() == 'frozenset': return frozenset(members) else: return set(members) def write_repr(self, out, visited): # Emulate Python 3's set_repr tp_name = self.safe_tp_name() # Guard against infinite loops: if self.as_address() in visited: out.write('(...)') return visited.add(self.as_address()) # Python 3's set_repr special-cases the empty set: if not self.field('used'): out.write(tp_name) out.write('()') return # Python 3 uses {} for set literals: if tp_name != 'set': out.write(tp_name) out.write('(') out.write('{') first = True table = self.field('table') for i in safe_range(self.field('mask')+1): setentry = table[i] key = setentry['key'] if key != 0: pyop_key = PyObjectPtr.from_pyobject_ptr(key) key_proxy = pyop_key.proxyval(visited) # FIXME! if key_proxy != '': if not first: out.write(', ') first = False pyop_key.write_repr(out, visited) out.write('}') if tp_name != 'set': out.write(')') class PyBytesObjectPtr(PyObjectPtr): _typename = 'PyBytesObject' def __str__(self): field_ob_size = self.field('ob_size') field_ob_sval = self.field('ob_sval') return ''.join(struct.pack('b', field_ob_sval[i]) for i in safe_range(field_ob_size)) def proxyval(self, visited): return str(self) def write_repr(self, out, visited, py3=True): # Write this out as a Python 3 bytes literal, i.e. with a "b" prefix # Get a PyStringObject* within the Python 2 gdb process: proxy = self.proxyval(visited) # Transliteration of Python 3's Objects/bytesobject.c:PyBytes_Repr # to Python 2 code: quote = "'" if "'" in proxy and not '"' in proxy: quote = '"' if py3: out.write('b') out.write(quote) for byte in proxy: if byte == quote or byte == '\\': out.write('\\') out.write(byte) elif byte == '\t': out.write('\\t') elif byte == '\n': out.write('\\n') elif byte == '\r': out.write('\\r') elif byte < ' ' or ord(byte) >= 0x7f: out.write('\\x') out.write(hexdigits[(ord(byte) & 0xf0) >> 4]) out.write(hexdigits[ord(byte) & 0xf]) else: out.write(byte) out.write(quote) class PyStringObjectPtr(PyBytesObjectPtr): _typename = 'PyStringObject' def write_repr(self, out, visited): return super(PyStringObjectPtr, self).write_repr(out, visited, py3=False) class PyTupleObjectPtr(PyObjectPtr): _typename = 'PyTupleObject' def __getitem__(self, i): # Get the gdb.Value for the (PyObject*) with the given index: field_ob_item = self.field('ob_item') return field_ob_item[i] def proxyval(self, visited): # Guard against infinite loops: if self.as_address() in visited: return ProxyAlreadyVisited('(...)') visited.add(self.as_address()) result = tuple([PyObjectPtr.from_pyobject_ptr(self[i]).proxyval(visited) for i in safe_range(int_from_int(self.field('ob_size')))]) return result def write_repr(self, out, visited): # Guard against infinite loops: if self.as_address() in visited: out.write('(...)') return visited.add(self.as_address()) out.write('(') for i in safe_range(int_from_int(self.field('ob_size'))): if i > 0: out.write(', ') element = PyObjectPtr.from_pyobject_ptr(self[i]) element.write_repr(out, visited) if self.field('ob_size') == 1: out.write(',)') else: out.write(')') def _unichr_is_printable(char): # Logic adapted from Python 3's Tools/unicode/makeunicodedata.py if char == u" ": return True import unicodedata return unicodedata.category(char) not in ("C", "Z") if sys.maxunicode >= 0x10000: try: _unichr = unichr except NameError: _unichr = chr else: # Needed for proper surrogate support if sizeof(Py_UNICODE) is 2 in gdb def _unichr(x): if x < 0x10000: return unichr(x) x -= 0x10000 ch1 = 0xD800 | (x >> 10) ch2 = 0xDC00 | (x & 0x3FF) return unichr(ch1) + unichr(ch2) class PyUnicodeObjectPtr(PyObjectPtr): _typename = 'PyUnicodeObject' def char_width(self): _type_Py_UNICODE = gdb.lookup_type('Py_UNICODE') return _type_Py_UNICODE.sizeof def proxyval(self, visited): # From unicodeobject.h: # Py_ssize_t length; /* Length of raw Unicode data in buffer */ # Py_UNICODE *str; /* Raw Unicode buffer */ field_length = int(self.field('length')) field_str = self.field('str') # Gather a list of ints from the Py_UNICODE array; these are either # UCS-2 or UCS-4 code points: if self.char_width() > 2: Py_UNICODEs = [int(field_str[i]) for i in safe_range(field_length)] else: # A more elaborate routine if sizeof(Py_UNICODE) is 2 in the # inferior process: we must join surrogate pairs. Py_UNICODEs = [] i = 0 limit = safety_limit(field_length) while i < limit: ucs = int(field_str[i]) i += 1 if ucs < 0xD800 or ucs >= 0xDC00 or i == field_length: Py_UNICODEs.append(ucs) continue # This could be a surrogate pair. ucs2 = int(field_str[i]) if ucs2 < 0xDC00 or ucs2 > 0xDFFF: continue code = (ucs & 0x03FF) << 10 code |= ucs2 & 0x03FF code += 0x00010000 Py_UNICODEs.append(code) i += 1 # Convert the int code points to unicode characters, and generate a # local unicode instance. # This splits surrogate pairs if sizeof(Py_UNICODE) is 2 here (in gdb). result = u''.join([_unichr(ucs) for ucs in Py_UNICODEs]) return result def write_repr(self, out, visited): # Get a PyUnicodeObject* within the Python 2 gdb process: proxy = self.proxyval(visited) # Transliteration of Python 3's Object/unicodeobject.c:unicode_repr # to Python 2: try: gdb.parse_and_eval('PyString_Type') except RuntimeError: # Python 3, don't write 'u' as prefix pass else: # Python 2, write the 'u' out.write('u') if "'" in proxy and '"' not in proxy: quote = '"' else: quote = "'" out.write(quote) i = 0 while i < len(proxy): ch = proxy[i] i += 1 # Escape quotes and backslashes if ch == quote or ch == '\\': out.write('\\') out.write(ch) # Map special whitespace to '\t', \n', '\r' elif ch == '\t': out.write('\\t') elif ch == '\n': out.write('\\n') elif ch == '\r': out.write('\\r') # Map non-printable US ASCII to '\xhh' */ elif ch < ' ' or ch == 0x7F: out.write('\\x') out.write(hexdigits[(ord(ch) >> 4) & 0x000F]) out.write(hexdigits[ord(ch) & 0x000F]) # Copy ASCII characters as-is elif ord(ch) < 0x7F: out.write(ch) # Non-ASCII characters else: ucs = ch ch2 = None if sys.maxunicode < 0x10000: # If sizeof(Py_UNICODE) is 2 here (in gdb), join # surrogate pairs before calling _unichr_is_printable. if (i < len(proxy) and 0xD800 <= ord(ch) < 0xDC00 \ and 0xDC00 <= ord(proxy[i]) <= 0xDFFF): ch2 = proxy[i] ucs = ch + ch2 i += 1 # Unfortuately, Python 2's unicode type doesn't seem # to expose the "isprintable" method printable = _unichr_is_printable(ucs) if printable: try: ucs.encode(ENCODING) except UnicodeEncodeError: printable = False # Map Unicode whitespace and control characters # (categories Z* and C* except ASCII space) if not printable: if ch2 is not None: # Match Python 3's representation of non-printable # wide characters. code = (ord(ch) & 0x03FF) << 10 code |= ord(ch2) & 0x03FF code += 0x00010000 else: code = ord(ucs) # Map 8-bit characters to '\\xhh' if code <= 0xff: out.write('\\x') out.write(hexdigits[(code >> 4) & 0x000F]) out.write(hexdigits[code & 0x000F]) # Map 21-bit characters to '\U00xxxxxx' elif code >= 0x10000: out.write('\\U') out.write(hexdigits[(code >> 28) & 0x0000000F]) out.write(hexdigits[(code >> 24) & 0x0000000F]) out.write(hexdigits[(code >> 20) & 0x0000000F]) out.write(hexdigits[(code >> 16) & 0x0000000F]) out.write(hexdigits[(code >> 12) & 0x0000000F]) out.write(hexdigits[(code >> 8) & 0x0000000F]) out.write(hexdigits[(code >> 4) & 0x0000000F]) out.write(hexdigits[code & 0x0000000F]) # Map 16-bit characters to '\uxxxx' else: out.write('\\u') out.write(hexdigits[(code >> 12) & 0x000F]) out.write(hexdigits[(code >> 8) & 0x000F]) out.write(hexdigits[(code >> 4) & 0x000F]) out.write(hexdigits[code & 0x000F]) else: # Copy characters as-is out.write(ch) if ch2 is not None: out.write(ch2) out.write(quote) def __unicode__(self): return self.proxyval(set()) def __str__(self): # In Python 3, everything is unicode (including attributes of e.g. # code objects, such as function names). The Python 2 debugger code # uses PyUnicodePtr objects to format strings etc, whereas with a # Python 2 debuggee we'd get PyStringObjectPtr instances with __str__. # Be compatible with that. return unicode(self).encode('UTF-8') def int_from_int(gdbval): return int(str(gdbval)) def stringify(val): # TODO: repr() puts everything on one line; pformat can be nicer, but # can lead to v.long results; this function isolates the choice if True: return repr(val) else: from pprint import pformat return pformat(val) class PyObjectPtrPrinter: "Prints a (PyObject*)" def __init__ (self, gdbval): self.gdbval = gdbval def to_string (self): pyop = PyObjectPtr.from_pyobject_ptr(self.gdbval) if True: return pyop.get_truncated_repr(MAX_OUTPUT_LEN) else: # Generate full proxy value then stringify it. # Doing so could be expensive proxyval = pyop.proxyval(set()) return stringify(proxyval) def pretty_printer_lookup(gdbval): type = gdbval.type.unqualified() if type.code == gdb.TYPE_CODE_PTR: type = type.target().unqualified() if str(type) in all_pretty_typenames: return PyObjectPtrPrinter(gdbval) """ During development, I've been manually invoking the code in this way: (gdb) python import sys sys.path.append('/home/david/coding/python-gdb') import libpython end then reloading it after each edit like this: (gdb) python reload(libpython) The following code should ensure that the prettyprinter is registered if the code is autoloaded by gdb when visiting libpython.so, provided that this python file is installed to the same path as the library (or its .debug file) plus a "-gdb.py" suffix, e.g: /usr/lib/libpython2.6.so.1.0-gdb.py /usr/lib/debug/usr/lib/libpython2.6.so.1.0.debug-gdb.py """ def register(obj): if obj is None: obj = gdb # Wire up the pretty-printer obj.pretty_printers.append(pretty_printer_lookup) register(gdb.current_objfile()) # Unfortunately, the exact API exposed by the gdb module varies somewhat # from build to build # See http://bugs.python.org/issue8279?#msg102276 class Frame(object): ''' Wrapper for gdb.Frame, adding various methods ''' def __init__(self, gdbframe): self._gdbframe = gdbframe def older(self): older = self._gdbframe.older() if older: return Frame(older) else: return None def newer(self): newer = self._gdbframe.newer() if newer: return Frame(newer) else: return None def select(self): '''If supported, select this frame and return True; return False if unsupported Not all builds have a gdb.Frame.select method; seems to be present on Fedora 12 onwards, but absent on Ubuntu buildbot''' if not hasattr(self._gdbframe, 'select'): print ('Unable to select frame: ' 'this build of gdb does not expose a gdb.Frame.select method') return False self._gdbframe.select() return True def get_index(self): '''Calculate index of frame, starting at 0 for the newest frame within this thread''' index = 0 # Go down until you reach the newest frame: iter_frame = self while iter_frame.newer(): index += 1 iter_frame = iter_frame.newer() return index def is_evalframeex(self): '''Is this a PyEval_EvalFrameEx frame?''' if self._gdbframe.name() == 'PyEval_EvalFrameEx': ''' I believe we also need to filter on the inline struct frame_id.inline_depth, only regarding frames with an inline depth of 0 as actually being this function So we reject those with type gdb.INLINE_FRAME ''' if self._gdbframe.type() == gdb.NORMAL_FRAME: # We have a PyEval_EvalFrameEx frame: return True return False def read_var(self, varname): """ read_var with respect to code blocks (gdbframe.read_var works with respect to the most recent block) Apparently this function doesn't work, though, as it seems to read variables in other frames also sometimes. """ block = self._gdbframe.block() var = None while block and var is None: try: var = self._gdbframe.read_var(varname, block) except ValueError: pass block = block.superblock return var def get_pyop(self): try: # self.read_var does not always work properly, so select our frame # and restore the previously selected frame selected_frame = gdb.selected_frame() self._gdbframe.select() f = gdb.parse_and_eval('f') selected_frame.select() except RuntimeError: return None else: return PyFrameObjectPtr.from_pyobject_ptr(f) @classmethod def get_selected_frame(cls): _gdbframe = gdb.selected_frame() if _gdbframe: return Frame(_gdbframe) return None @classmethod def get_selected_python_frame(cls): '''Try to obtain the Frame for the python code in the selected frame, or None''' frame = cls.get_selected_frame() while frame: if frame.is_evalframeex(): return frame frame = frame.older() # Not found: return None def print_summary(self): if self.is_evalframeex(): pyop = self.get_pyop() if pyop: line = pyop.get_truncated_repr(MAX_OUTPUT_LEN) write_unicode(sys.stdout, '#%i %s\n' % (self.get_index(), line)) sys.stdout.write(pyop.current_line()) else: sys.stdout.write('#%i (unable to read python frame information)\n' % self.get_index()) else: sys.stdout.write('#%i\n' % self.get_index()) class PyList(gdb.Command): '''List the current Python source code, if any Use py-list START to list at a different line number within the python source. Use py-list START, END to list a specific range of lines within the python source. ''' def __init__(self): gdb.Command.__init__ (self, "py-list", gdb.COMMAND_FILES, gdb.COMPLETE_NONE) def invoke(self, args, from_tty): import re start = None end = None m = re.match(r'\s*(\d+)\s*', args) if m: start = int(m.group(0)) end = start + 10 m = re.match(r'\s*(\d+)\s*,\s*(\d+)\s*', args) if m: start, end = map(int, m.groups()) frame = Frame.get_selected_python_frame() if not frame: print('Unable to locate python frame') return pyop = frame.get_pyop() if not pyop: print('Unable to read information on python frame') return filename = pyop.filename() lineno = pyop.current_line_num() if start is None: start = lineno - 5 end = lineno + 5 if start<1: start = 1 with open(os_fsencode(filename), 'r') as f: all_lines = f.readlines() # start and end are 1-based, all_lines is 0-based; # so [start-1:end] as a python slice gives us [start, end] as a # closed interval for i, line in enumerate(all_lines[start-1:end]): linestr = str(i+start) # Highlight current line: if i + start == lineno: linestr = '>' + linestr sys.stdout.write('%4s %s' % (linestr, line)) # ...and register the command: PyList() def move_in_stack(move_up): '''Move up or down the stack (for the py-up/py-down command)''' frame = Frame.get_selected_python_frame() while frame: if move_up: iter_frame = frame.older() else: iter_frame = frame.newer() if not iter_frame: break if iter_frame.is_evalframeex(): # Result: if iter_frame.select(): iter_frame.print_summary() return frame = iter_frame if move_up: print('Unable to find an older python frame') else: print('Unable to find a newer python frame') class PyUp(gdb.Command): 'Select and print the python stack frame that called this one (if any)' def __init__(self): gdb.Command.__init__ (self, "py-up", gdb.COMMAND_STACK, gdb.COMPLETE_NONE) def invoke(self, args, from_tty): move_in_stack(move_up=True) class PyDown(gdb.Command): 'Select and print the python stack frame called by this one (if any)' def __init__(self): gdb.Command.__init__ (self, "py-down", gdb.COMMAND_STACK, gdb.COMPLETE_NONE) def invoke(self, args, from_tty): move_in_stack(move_up=False) # Not all builds of gdb have gdb.Frame.select if hasattr(gdb.Frame, 'select'): PyUp() PyDown() class PyBacktrace(gdb.Command): 'Display the current python frame and all the frames within its call stack (if any)' def __init__(self): gdb.Command.__init__ (self, "py-bt", gdb.COMMAND_STACK, gdb.COMPLETE_NONE) def invoke(self, args, from_tty): frame = Frame.get_selected_python_frame() while frame: if frame.is_evalframeex(): frame.print_summary() frame = frame.older() PyBacktrace() class PyPrint(gdb.Command): 'Look up the given python variable name, and print it' def __init__(self): gdb.Command.__init__ (self, "py-print", gdb.COMMAND_DATA, gdb.COMPLETE_NONE) def invoke(self, args, from_tty): name = str(args) frame = Frame.get_selected_python_frame() if not frame: print('Unable to locate python frame') return pyop_frame = frame.get_pyop() if not pyop_frame: print('Unable to read information on python frame') return pyop_var, scope = pyop_frame.get_var_by_name(name) if pyop_var: print('%s %r = %s' % ( scope, name, pyop_var.get_truncated_repr(MAX_OUTPUT_LEN))) else: print('%r not found' % name) PyPrint() class PyLocals(gdb.Command): 'Look up the given python variable name, and print it' def invoke(self, args, from_tty): name = str(args) frame = Frame.get_selected_python_frame() if not frame: print('Unable to locate python frame') return pyop_frame = frame.get_pyop() if not pyop_frame: print('Unable to read information on python frame') return namespace = self.get_namespace(pyop_frame) namespace = [(name.proxyval(set()), val) for name, val in namespace] if namespace: name, val = max(namespace, key=lambda item: len(item[0])) max_name_length = len(name) for name, pyop_value in namespace: value = pyop_value.get_truncated_repr(MAX_OUTPUT_LEN) print('%-*s = %s' % (max_name_length, name, value)) def get_namespace(self, pyop_frame): return pyop_frame.iter_locals() class PyGlobals(PyLocals): 'List all the globals in the currently select Python frame' def get_namespace(self, pyop_frame): return pyop_frame.iter_globals() PyLocals("py-locals", gdb.COMMAND_DATA, gdb.COMPLETE_NONE) PyGlobals("py-globals", gdb.COMMAND_DATA, gdb.COMPLETE_NONE) class PyNameEquals(gdb.Function): def _get_pycurframe_attr(self, attr): frame = Frame(gdb.selected_frame()) if frame.is_evalframeex(): pyframe = frame.get_pyop() if pyframe is None: warnings.warn("Use a Python debug build, Python breakpoints " "won't work otherwise.") return None return getattr(pyframe, attr).proxyval(set()) return None def invoke(self, funcname): attr = self._get_pycurframe_attr('co_name') return attr is not None and attr == funcname.string() PyNameEquals("pyname_equals") class PyModEquals(PyNameEquals): def invoke(self, modname): attr = self._get_pycurframe_attr('co_filename') if attr is not None: filename, ext = os.path.splitext(os.path.basename(attr)) return filename == modname.string() return False PyModEquals("pymod_equals") class PyBreak(gdb.Command): """ Set a Python breakpoint. Examples: Break on any function or method named 'func' in module 'modname' py-break modname.func Break on any function or method named 'func' py-break func """ def invoke(self, funcname, from_tty): if '.' in funcname: modname, dot, funcname = funcname.rpartition('.') cond = '$pyname_equals("%s") && $pymod_equals("%s")' % (funcname, modname) else: cond = '$pyname_equals("%s")' % funcname gdb.execute('break PyEval_EvalFrameEx if ' + cond) PyBreak("py-break", gdb.COMMAND_RUNNING, gdb.COMPLETE_NONE) class _LoggingState(object): """ State that helps to provide a reentrant gdb.execute() function. """ def __init__(self): self.fd, self.filename = tempfile.mkstemp() self.file = os.fdopen(self.fd, 'r+') _execute("set logging file %s" % self.filename) self.file_position_stack = [] atexit.register(os.close, self.fd) atexit.register(os.remove, self.filename) def __enter__(self): if not self.file_position_stack: _execute("set logging redirect on") _execute("set logging on") _execute("set pagination off") self.file_position_stack.append(os.fstat(self.fd).st_size) return self def getoutput(self): gdb.flush() self.file.seek(self.file_position_stack[-1]) result = self.file.read() return result def __exit__(self, exc_type, exc_val, tb): startpos = self.file_position_stack.pop() self.file.seek(startpos) self.file.truncate() if not self.file_position_stack: _execute("set logging off") _execute("set logging redirect off") _execute("set pagination on") def execute(command, from_tty=False, to_string=False): """ Replace gdb.execute() with this function and have it accept a 'to_string' argument (new in 7.2). Have it properly capture stderr also. Ensure reentrancy. """ if to_string: with _logging_state as state: _execute(command, from_tty) return state.getoutput() else: _execute(command, from_tty) _execute = gdb.execute gdb.execute = execute _logging_state = _LoggingState() def get_selected_inferior(): """ Return the selected inferior in gdb. """ # Woooh, another bug in gdb! Is there an end in sight? # http://sourceware.org/bugzilla/show_bug.cgi?id=12212 return gdb.inferiors()[0] selected_thread = gdb.selected_thread() for inferior in gdb.inferiors(): for thread in inferior.threads(): if thread == selected_thread: return inferior def source_gdb_script(script_contents, to_string=False): """ Source a gdb script with script_contents passed as a string. This is useful to provide defines for py-step and py-next to make them repeatable (this is not possible with gdb.execute()). See http://sourceware.org/bugzilla/show_bug.cgi?id=12216 """ fd, filename = tempfile.mkstemp() f = os.fdopen(fd, 'w') f.write(script_contents) f.close() gdb.execute("source %s" % filename, to_string=to_string) os.remove(filename) def register_defines(): source_gdb_script(textwrap.dedent("""\ define py-step -py-step end define py-next -py-next end document py-step %s end document py-next %s end """) % (PyStep.__doc__, PyNext.__doc__)) def stackdepth(frame): "Tells the stackdepth of a gdb frame." depth = 0 while frame: frame = frame.older() depth += 1 return depth class ExecutionControlCommandBase(gdb.Command): """ Superclass for language specific execution control. Language specific features should be implemented by lang_info using the LanguageInfo interface. 'name' is the name of the command. """ def __init__(self, name, lang_info): super(ExecutionControlCommandBase, self).__init__( name, gdb.COMMAND_RUNNING, gdb.COMPLETE_NONE) self.lang_info = lang_info def install_breakpoints(self): all_locations = itertools.chain( self.lang_info.static_break_functions(), self.lang_info.runtime_break_functions()) for location in all_locations: result = gdb.execute('break %s' % location, to_string=True) yield re.search(r'Breakpoint (\d+)', result).group(1) def delete_breakpoints(self, breakpoint_list): for bp in breakpoint_list: gdb.execute("delete %s" % bp) def filter_output(self, result): reflags = re.MULTILINE output_on_halt = [ (r'^Program received signal .*', reflags|re.DOTALL), (r'.*[Ww]arning.*', 0), (r'^Program exited .*', reflags), ] output_always = [ # output when halting on a watchpoint (r'^(Old|New) value = .*', reflags), # output from the 'display' command (r'^\d+: \w+ = .*', reflags), ] def filter_output(regexes): output = [] for regex, flags in regexes: for match in re.finditer(regex, result, flags): output.append(match.group(0)) return '\n'.join(output) # Filter the return value output of the 'finish' command match_finish = re.search(r'^Value returned is \$\d+ = (.*)', result, re.MULTILINE) if match_finish: finish_output = 'Value returned: %s\n' % match_finish.group(1) else: finish_output = '' return (filter_output(output_on_halt), finish_output + filter_output(output_always)) def stopped(self): return get_selected_inferior().pid == 0 def finish_executing(self, result): """ After doing some kind of code running in the inferior, print the line of source code or the result of the last executed gdb command (passed in as the `result` argument). """ output_on_halt, output_always = self.filter_output(result) if self.stopped(): print(output_always) print(output_on_halt) else: frame = gdb.selected_frame() source_line = self.lang_info.get_source_line(frame) if self.lang_info.is_relevant_function(frame): raised_exception = self.lang_info.exc_info(frame) if raised_exception: print(raised_exception) if source_line: if output_always.rstrip(): print(output_always.rstrip()) print(source_line) else: print(result) def _finish(self): """ Execute until the function returns (or until something else makes it stop) """ if gdb.selected_frame().older() is not None: return gdb.execute('finish', to_string=True) else: # outermost frame, continue return gdb.execute('cont', to_string=True) def _finish_frame(self): """ Execute until the function returns to a relevant caller. """ while True: result = self._finish() try: frame = gdb.selected_frame() except RuntimeError: break hitbp = re.search(r'Breakpoint (\d+)', result) is_relevant = self.lang_info.is_relevant_function(frame) if hitbp or is_relevant or self.stopped(): break return result def finish(self, *args): "Implements the finish command." result = self._finish_frame() self.finish_executing(result) def step(self, stepinto, stepover_command='next'): """ Do a single step or step-over. Returns the result of the last gdb command that made execution stop. This implementation, for stepping, sets (conditional) breakpoints for all functions that are deemed relevant. It then does a step over until either something halts execution, or until the next line is reached. If, however, stepover_command is given, it should be a string gdb command that continues execution in some way. The idea is that the caller has set a (conditional) breakpoint or watchpoint that can work more efficiently than the step-over loop. For Python this means setting a watchpoint for f->f_lasti, which means we can then subsequently "finish" frames. We want f->f_lasti instead of f->f_lineno, because the latter only works properly with local trace functions, see PyFrameObjectPtr.current_line_num and PyFrameObjectPtr.addr2line. """ if stepinto: breakpoint_list = list(self.install_breakpoints()) beginframe = gdb.selected_frame() if self.lang_info.is_relevant_function(beginframe): # If we start in a relevant frame, initialize stuff properly. If # we don't start in a relevant frame, the loop will halt # immediately. So don't call self.lang_info.lineno() as it may # raise for irrelevant frames. beginline = self.lang_info.lineno(beginframe) if not stepinto: depth = stackdepth(beginframe) newframe = beginframe while True: if self.lang_info.is_relevant_function(newframe): result = gdb.execute(stepover_command, to_string=True) else: result = self._finish_frame() if self.stopped(): break newframe = gdb.selected_frame() is_relevant_function = self.lang_info.is_relevant_function(newframe) try: framename = newframe.name() except RuntimeError: framename = None m = re.search(r'Breakpoint (\d+)', result) if m: if is_relevant_function and m.group(1) in breakpoint_list: # although we hit a breakpoint, we still need to check # that the function, in case hit by a runtime breakpoint, # is in the right context break if newframe != beginframe: # new function if not stepinto: # see if we returned to the caller newdepth = stackdepth(newframe) is_relevant_function = (newdepth < depth and is_relevant_function) if is_relevant_function: break else: # newframe equals beginframe, check for a difference in the # line number lineno = self.lang_info.lineno(newframe) if lineno and lineno != beginline: break if stepinto: self.delete_breakpoints(breakpoint_list) self.finish_executing(result) def run(self, args, from_tty): self.finish_executing(gdb.execute('run ' + args, to_string=True)) def cont(self, *args): self.finish_executing(gdb.execute('cont', to_string=True)) class LanguageInfo(object): """ This class defines the interface that ExecutionControlCommandBase needs to provide language-specific execution control. Classes that implement this interface should implement: lineno(frame) Tells the current line number (only called for a relevant frame). If lineno is a false value it is not checked for a difference. is_relevant_function(frame) tells whether we care about frame 'frame' get_source_line(frame) get the line of source code for the current line (only called for a relevant frame). If the source code cannot be retrieved this function should return None exc_info(frame) -- optional tells whether an exception was raised, if so, it should return a string representation of the exception value, None otherwise. static_break_functions() returns an iterable of function names that are considered relevant and should halt step-into execution. This is needed to provide a performing step-into runtime_break_functions() -- optional list of functions that we should break into depending on the context """ def exc_info(self, frame): "See this class' docstring." def runtime_break_functions(self): """ Implement this if the list of step-into functions depends on the context. """ return () class PythonInfo(LanguageInfo): def pyframe(self, frame): pyframe = Frame(frame).get_pyop() if pyframe: return pyframe else: raise gdb.RuntimeError( "Unable to find the Python frame, run your code with a debug " "build (configure with --with-pydebug or compile with -g).") def lineno(self, frame): return self.pyframe(frame).current_line_num() def is_relevant_function(self, frame): return Frame(frame).is_evalframeex() def get_source_line(self, frame): try: pyframe = self.pyframe(frame) return '%4d %s' % (pyframe.current_line_num(), pyframe.current_line().rstrip()) except IOError: return None def exc_info(self, frame): try: tstate = frame.read_var('tstate').dereference() if gdb.parse_and_eval('tstate->frame == f'): # tstate local variable initialized, check for an exception inf_type = tstate['curexc_type'] inf_value = tstate['curexc_value'] if inf_type: return 'An exception was raised: %s' % (inf_value,) except (ValueError, RuntimeError): # Could not read the variable tstate or it's memory, it's ok pass def static_break_functions(self): yield 'PyEval_EvalFrameEx' class PythonStepperMixin(object): """ Make this a mixin so CyStep can also inherit from this and use a CythonCodeStepper at the same time. """ def python_step(self, stepinto): """ Set a watchpoint on the Python bytecode instruction pointer and try to finish the frame """ output = gdb.execute('watch f->f_lasti', to_string=True) watchpoint = int(re.search(r'[Ww]atchpoint (\d+):', output).group(1)) self.step(stepinto=stepinto, stepover_command='finish') gdb.execute('delete %s' % watchpoint) class PyStep(ExecutionControlCommandBase, PythonStepperMixin): "Step through Python code." stepinto = True def invoke(self, args, from_tty): self.python_step(stepinto=self.stepinto) class PyNext(PyStep): "Step-over Python code." stepinto = False class PyFinish(ExecutionControlCommandBase): "Execute until function returns to a caller." invoke = ExecutionControlCommandBase.finish class PyRun(ExecutionControlCommandBase): "Run the program." invoke = ExecutionControlCommandBase.run class PyCont(ExecutionControlCommandBase): invoke = ExecutionControlCommandBase.cont def _pointervalue(gdbval): """ Return the value of the pionter as a Python int. gdbval.type must be a pointer type """ # don't convert with int() as it will raise a RuntimeError if gdbval.address is not None: return int(gdbval.address) else: # the address attribute is None sometimes, in which case we can # still convert the pointer to an int return int(gdbval) def pointervalue(gdbval): pointer = _pointervalue(gdbval) try: if pointer < 0: raise gdb.GdbError("Negative pointer value, presumably a bug " "in gdb, aborting.") except RuntimeError: # work around yet another bug in gdb where you get random behaviour # and tracebacks pass return pointer def get_inferior_unicode_postfix(): try: gdb.parse_and_eval('PyUnicode_FromEncodedObject') except RuntimeError: try: gdb.parse_and_eval('PyUnicodeUCS2_FromEncodedObject') except RuntimeError: return 'UCS4' else: return 'UCS2' else: return '' class PythonCodeExecutor(object): Py_single_input = 256 Py_file_input = 257 Py_eval_input = 258 def malloc(self, size): chunk = (gdb.parse_and_eval("(void *) malloc((size_t) %d)" % size)) pointer = pointervalue(chunk) if pointer == 0: raise gdb.GdbError("No memory could be allocated in the inferior.") return pointer def alloc_string(self, string): pointer = self.malloc(len(string)) get_selected_inferior().write_memory(pointer, string) return pointer def alloc_pystring(self, string): stringp = self.alloc_string(string) PyString_FromStringAndSize = 'PyString_FromStringAndSize' try: gdb.parse_and_eval(PyString_FromStringAndSize) except RuntimeError: # Python 3 PyString_FromStringAndSize = ('PyUnicode%s_FromStringAndSize' % (get_inferior_unicode_postfix(),)) try: result = gdb.parse_and_eval( '(PyObject *) %s((char *) %d, (size_t) %d)' % ( PyString_FromStringAndSize, stringp, len(string))) finally: self.free(stringp) pointer = pointervalue(result) if pointer == 0: raise gdb.GdbError("Unable to allocate Python string in " "the inferior.") return pointer def free(self, pointer): gdb.parse_and_eval("free((void *) %d)" % pointer) def incref(self, pointer): "Increment the reference count of a Python object in the inferior." gdb.parse_and_eval('Py_IncRef((PyObject *) %d)' % pointer) def xdecref(self, pointer): "Decrement the reference count of a Python object in the inferior." # Py_DecRef is like Py_XDECREF, but a function. So we don't have # to check for NULL. This should also decref all our allocated # Python strings. gdb.parse_and_eval('Py_DecRef((PyObject *) %d)' % pointer) def evalcode(self, code, input_type, global_dict=None, local_dict=None): """ Evaluate python code `code` given as a string in the inferior and return the result as a gdb.Value. Returns a new reference in the inferior. Of course, executing any code in the inferior may be dangerous and may leave the debuggee in an unsafe state or terminate it alltogether. """ if '\0' in code: raise gdb.GdbError("String contains NUL byte.") code += '\0' pointer = self.alloc_string(code) globalsp = pointervalue(global_dict) localsp = pointervalue(local_dict) if globalsp == 0 or localsp == 0: raise gdb.GdbError("Unable to obtain or create locals or globals.") code = """ PyRun_String( (char *) %(code)d, (int) %(start)d, (PyObject *) %(globals)s, (PyObject *) %(locals)d) """ % dict(code=pointer, start=input_type, globals=globalsp, locals=localsp) with FetchAndRestoreError(): try: pyobject_return_value = gdb.parse_and_eval(code) finally: self.free(pointer) return pyobject_return_value class FetchAndRestoreError(PythonCodeExecutor): """ Context manager that fetches the error indicator in the inferior and restores it on exit. """ def __init__(self): self.sizeof_PyObjectPtr = gdb.lookup_type('PyObject').pointer().sizeof self.pointer = self.malloc(self.sizeof_PyObjectPtr * 3) type = self.pointer value = self.pointer + self.sizeof_PyObjectPtr traceback = self.pointer + self.sizeof_PyObjectPtr * 2 self.errstate = type, value, traceback def __enter__(self): gdb.parse_and_eval("PyErr_Fetch(%d, %d, %d)" % self.errstate) def __exit__(self, *args): if gdb.parse_and_eval("(int) PyErr_Occurred()"): gdb.parse_and_eval("PyErr_Print()") pyerr_restore = ("PyErr_Restore(" "(PyObject *) *%d," "(PyObject *) *%d," "(PyObject *) *%d)") try: gdb.parse_and_eval(pyerr_restore % self.errstate) finally: self.free(self.pointer) class FixGdbCommand(gdb.Command): def __init__(self, command, actual_command): super(FixGdbCommand, self).__init__(command, gdb.COMMAND_DATA, gdb.COMPLETE_NONE) self.actual_command = actual_command def fix_gdb(self): """ It seems that invoking either 'cy exec' and 'py-exec' work perfectly fine, but after this gdb's python API is entirely broken. Maybe some uncleared exception value is still set? sys.exc_clear() didn't help. A demonstration: (gdb) cy exec 'hello' 'hello' (gdb) python gdb.execute('cont') RuntimeError: Cannot convert value to int. Error while executing Python code. (gdb) python gdb.execute('cont') [15148 refs] Program exited normally. """ warnings.filterwarnings('ignore', r'.*', RuntimeWarning, re.escape(__name__)) try: int(gdb.parse_and_eval("(void *) 0")) == 0 except RuntimeError: pass # warnings.resetwarnings() def invoke(self, args, from_tty): self.fix_gdb() try: gdb.execute('%s %s' % (self.actual_command, args)) except RuntimeError as e: raise gdb.GdbError(str(e)) self.fix_gdb() def _evalcode_python(executor, code, input_type): """ Execute Python code in the most recent stack frame. """ global_dict = gdb.parse_and_eval('PyEval_GetGlobals()') local_dict = gdb.parse_and_eval('PyEval_GetLocals()') if (pointervalue(global_dict) == 0 or pointervalue(local_dict) == 0): raise gdb.GdbError("Unable to find the locals or globals of the " "most recent Python function (relative to the " "selected frame).") return executor.evalcode(code, input_type, global_dict, local_dict) class PyExec(gdb.Command): def readcode(self, expr): if expr: return expr, PythonCodeExecutor.Py_single_input else: lines = [] while True: try: line = input('>') except EOFError: break else: if line.rstrip() == 'end': break lines.append(line) return '\n'.join(lines), PythonCodeExecutor.Py_file_input def invoke(self, expr, from_tty): expr, input_type = self.readcode(expr) executor = PythonCodeExecutor() executor.xdecref(_evalcode_python(executor, input_type, global_dict, local_dict)) gdb.execute('set breakpoint pending on') if hasattr(gdb, 'GdbError'): # Wrap py-step and py-next in gdb defines to make them repeatable. py_step = PyStep('-py-step', PythonInfo()) py_next = PyNext('-py-next', PythonInfo()) register_defines() py_finish = PyFinish('py-finish', PythonInfo()) py_run = PyRun('py-run', PythonInfo()) py_cont = PyCont('py-cont', PythonInfo()) py_exec = FixGdbCommand('py-exec', '-py-exec') _py_exec = PyExec("-py-exec", gdb.COMMAND_DATA, gdb.COMPLETE_NONE) else: warnings.warn("Use gdb 7.2 or higher to use the py-exec command.") Cython-0.23.4/Cython/Debugger/libcython.py0000644000175600017570000012667312606202452021560 0ustar jenkinsjenkins00000000000000""" GDB extension that adds Cython support. """ from __future__ import print_function try: input = raw_input except NameError: pass import sys import textwrap import traceback import functools import itertools import collections import gdb try: from lxml import etree have_lxml = True except ImportError: have_lxml = False try: # Python 2.5 from xml.etree import cElementTree as etree except ImportError: try: # Python 2.5 from xml.etree import ElementTree as etree except ImportError: try: # normal cElementTree install import cElementTree as etree except ImportError: # normal ElementTree install import elementtree.ElementTree as etree try: import pygments.lexers import pygments.formatters except ImportError: pygments = None sys.stderr.write("Install pygments for colorized source code.\n") if hasattr(gdb, 'string_to_argv'): from gdb import string_to_argv else: from shlex import split as string_to_argv from Cython.Debugger import libpython # C or Python type CObject = 'CObject' PythonObject = 'PythonObject' _data_types = dict(CObject=CObject, PythonObject=PythonObject) _filesystemencoding = sys.getfilesystemencoding() or 'UTF-8' # decorators def dont_suppress_errors(function): "*sigh*, readline" @functools.wraps(function) def wrapper(*args, **kwargs): try: return function(*args, **kwargs) except Exception: traceback.print_exc() raise return wrapper def default_selected_gdb_frame(err=True): def decorator(function): @functools.wraps(function) def wrapper(self, frame=None, *args, **kwargs): try: frame = frame or gdb.selected_frame() except RuntimeError: raise gdb.GdbError("No frame is currently selected.") if err and frame.name() is None: raise NoFunctionNameInFrameError() return function(self, frame, *args, **kwargs) return wrapper return decorator def require_cython_frame(function): @functools.wraps(function) @require_running_program def wrapper(self, *args, **kwargs): frame = kwargs.get('frame') or gdb.selected_frame() if not self.is_cython_function(frame): raise gdb.GdbError('Selected frame does not correspond with a ' 'Cython function we know about.') return function(self, *args, **kwargs) return wrapper def dispatch_on_frame(c_command, python_command=None): def decorator(function): @functools.wraps(function) def wrapper(self, *args, **kwargs): is_cy = self.is_cython_function() is_py = self.is_python_function() if is_cy or (is_py and not python_command): function(self, *args, **kwargs) elif is_py: gdb.execute(python_command) elif self.is_relevant_function(): gdb.execute(c_command) else: raise gdb.GdbError("Not a function cygdb knows about. " "Use the normal GDB commands instead.") return wrapper return decorator def require_running_program(function): @functools.wraps(function) def wrapper(*args, **kwargs): try: gdb.selected_frame() except RuntimeError: raise gdb.GdbError("No frame is currently selected.") return function(*args, **kwargs) return wrapper def gdb_function_value_to_unicode(function): @functools.wraps(function) def wrapper(self, string, *args, **kwargs): if isinstance(string, gdb.Value): string = string.string() return function(self, string, *args, **kwargs) return wrapper # Classes that represent the debug information # Don't rename the parameters of these classes, they come directly from the XML class CythonModule(object): def __init__(self, module_name, filename, c_filename): self.name = module_name self.filename = filename self.c_filename = c_filename self.globals = {} # {cython_lineno: min(c_linenos)} self.lineno_cy2c = {} # {c_lineno: cython_lineno} self.lineno_c2cy = {} self.functions = {} class CythonVariable(object): def __init__(self, name, cname, qualified_name, type, lineno): self.name = name self.cname = cname self.qualified_name = qualified_name self.type = type self.lineno = int(lineno) class CythonFunction(CythonVariable): def __init__(self, module, name, cname, pf_cname, qualified_name, lineno, type=CObject, is_initmodule_function="False"): super(CythonFunction, self).__init__(name, cname, qualified_name, type, lineno) self.module = module self.pf_cname = pf_cname self.is_initmodule_function = is_initmodule_function == "True" self.locals = {} self.arguments = [] self.step_into_functions = set() # General purpose classes class CythonBase(object): @default_selected_gdb_frame(err=False) def is_cython_function(self, frame): return frame.name() in self.cy.functions_by_cname @default_selected_gdb_frame(err=False) def is_python_function(self, frame): """ Tells if a frame is associated with a Python function. If we can't read the Python frame information, don't regard it as such. """ if frame.name() == 'PyEval_EvalFrameEx': pyframe = libpython.Frame(frame).get_pyop() return pyframe and not pyframe.is_optimized_out() return False @default_selected_gdb_frame() def get_c_function_name(self, frame): return frame.name() @default_selected_gdb_frame() def get_c_lineno(self, frame): return frame.find_sal().line @default_selected_gdb_frame() def get_cython_function(self, frame): result = self.cy.functions_by_cname.get(frame.name()) if result is None: raise NoCythonFunctionInFrameError() return result @default_selected_gdb_frame() def get_cython_lineno(self, frame): """ Get the current Cython line number. Returns 0 if there is no correspondence between the C and Cython code. """ cyfunc = self.get_cython_function(frame) return cyfunc.module.lineno_c2cy.get(self.get_c_lineno(frame), 0) @default_selected_gdb_frame() def get_source_desc(self, frame): filename = lineno = lexer = None if self.is_cython_function(frame): filename = self.get_cython_function(frame).module.filename lineno = self.get_cython_lineno(frame) if pygments: lexer = pygments.lexers.CythonLexer(stripall=False) elif self.is_python_function(frame): pyframeobject = libpython.Frame(frame).get_pyop() if not pyframeobject: raise gdb.GdbError( 'Unable to read information on python frame') filename = pyframeobject.filename() lineno = pyframeobject.current_line_num() if pygments: lexer = pygments.lexers.PythonLexer(stripall=False) else: symbol_and_line_obj = frame.find_sal() if not symbol_and_line_obj or not symbol_and_line_obj.symtab: filename = None lineno = 0 else: filename = symbol_and_line_obj.symtab.fullname() lineno = symbol_and_line_obj.line if pygments: lexer = pygments.lexers.CLexer(stripall=False) return SourceFileDescriptor(filename, lexer), lineno @default_selected_gdb_frame() def get_source_line(self, frame): source_desc, lineno = self.get_source_desc() return source_desc.get_source(lineno) @default_selected_gdb_frame() def is_relevant_function(self, frame): """ returns whether we care about a frame on the user-level when debugging Cython code """ name = frame.name() older_frame = frame.older() if self.is_cython_function(frame) or self.is_python_function(frame): return True elif older_frame and self.is_cython_function(older_frame): # check for direct C function call from a Cython function cython_func = self.get_cython_function(older_frame) return name in cython_func.step_into_functions return False @default_selected_gdb_frame(err=False) def print_stackframe(self, frame, index, is_c=False): """ Print a C, Cython or Python stack frame and the line of source code if available. """ # do this to prevent the require_cython_frame decorator from # raising GdbError when calling self.cy.cy_cvalue.invoke() selected_frame = gdb.selected_frame() frame.select() try: source_desc, lineno = self.get_source_desc(frame) except NoFunctionNameInFrameError: print('#%-2d Unknown Frame (compile with -g)' % index) return if not is_c and self.is_python_function(frame): pyframe = libpython.Frame(frame).get_pyop() if pyframe is None or pyframe.is_optimized_out(): # print this python function as a C function return self.print_stackframe(frame, index, is_c=True) func_name = pyframe.co_name func_cname = 'PyEval_EvalFrameEx' func_args = [] elif self.is_cython_function(frame): cyfunc = self.get_cython_function(frame) f = lambda arg: self.cy.cy_cvalue.invoke(arg, frame=frame) func_name = cyfunc.name func_cname = cyfunc.cname func_args = [] # [(arg, f(arg)) for arg in cyfunc.arguments] else: source_desc, lineno = self.get_source_desc(frame) func_name = frame.name() func_cname = func_name func_args = [] try: gdb_value = gdb.parse_and_eval(func_cname) except RuntimeError: func_address = 0 else: # Seriously? Why is the address not an int? func_address = int(str(gdb_value.address).split()[0], 0) a = ', '.join('%s=%s' % (name, val) for name, val in func_args) sys.stdout.write('#%-2d 0x%016x in %s(%s)' % (index, func_address, func_name, a)) if source_desc.filename is not None: sys.stdout.write(' at %s:%s' % (source_desc.filename, lineno)) sys.stdout.write('\n') try: sys.stdout.write(' ' + source_desc.get_source(lineno)) except gdb.GdbError: pass selected_frame.select() def get_remote_cython_globals_dict(self): m = gdb.parse_and_eval('__pyx_m') try: PyModuleObject = gdb.lookup_type('PyModuleObject') except RuntimeError: raise gdb.GdbError(textwrap.dedent("""\ Unable to lookup type PyModuleObject, did you compile python with debugging support (-g)?""")) m = m.cast(PyModuleObject.pointer()) return m['md_dict'] def get_cython_globals_dict(self): """ Get the Cython globals dict where the remote names are turned into local strings. """ remote_dict = self.get_remote_cython_globals_dict() pyobject_dict = libpython.PyObjectPtr.from_pyobject_ptr(remote_dict) result = {} seen = set() for k, v in pyobject_dict.items(): result[k.proxyval(seen)] = v return result def print_gdb_value(self, name, value, max_name_length=None, prefix=''): if libpython.pretty_printer_lookup(value): typename = '' else: typename = '(%s) ' % (value.type,) if max_name_length is None: print('%s%s = %s%s' % (prefix, name, typename, value)) else: print('%s%-*s = %s%s' % (prefix, max_name_length, name, typename, value)) def is_initialized(self, cython_func, local_name): cyvar = cython_func.locals[local_name] cur_lineno = self.get_cython_lineno() if '->' in cyvar.cname: # Closed over free variable if cur_lineno > cython_func.lineno: if cyvar.type == PythonObject: return int(gdb.parse_and_eval(cyvar.cname)) return True return False return cur_lineno > cyvar.lineno class SourceFileDescriptor(object): def __init__(self, filename, lexer, formatter=None): self.filename = filename self.lexer = lexer self.formatter = formatter def valid(self): return self.filename is not None def lex(self, code): if pygments and self.lexer and parameters.colorize_code: bg = parameters.terminal_background.value if self.formatter is None: formatter = pygments.formatters.TerminalFormatter(bg=bg) else: formatter = self.formatter return pygments.highlight(code, self.lexer, formatter) return code def _get_source(self, start, stop, lex_source, mark_line, lex_entire): with open(self.filename) as f: # to provide "correct" colouring, the entire code needs to be # lexed. However, this makes a lot of things terribly slow, so # we decide not to. Besides, it's unlikely to matter. if lex_source and lex_entire: f = self.lex(f.read()).splitlines() slice = itertools.islice(f, start - 1, stop - 1) for idx, line in enumerate(slice): if start + idx == mark_line: prefix = '>' else: prefix = ' ' if lex_source and not lex_entire: line = self.lex(line) yield '%s %4d %s' % (prefix, start + idx, line.rstrip()) def get_source(self, start, stop=None, lex_source=True, mark_line=0, lex_entire=False): exc = gdb.GdbError('Unable to retrieve source code') if not self.filename: raise exc start = max(start, 1) if stop is None: stop = start + 1 try: return '\n'.join( self._get_source(start, stop, lex_source, mark_line, lex_entire)) except IOError: raise exc # Errors class CyGDBError(gdb.GdbError): """ Base class for Cython-command related erorrs """ def __init__(self, *args): args = args or (self.msg,) super(CyGDBError, self).__init__(*args) class NoCythonFunctionInFrameError(CyGDBError): """ raised when the user requests the current cython function, which is unavailable """ msg = "Current function is a function cygdb doesn't know about" class NoFunctionNameInFrameError(NoCythonFunctionInFrameError): """ raised when the name of the C function could not be determined in the current C stack frame """ msg = ('C function name could not be determined in the current C stack ' 'frame') # Parameters class CythonParameter(gdb.Parameter): """ Base class for cython parameters """ def __init__(self, name, command_class, parameter_class, default=None): self.show_doc = self.set_doc = self.__class__.__doc__ super(CythonParameter, self).__init__(name, command_class, parameter_class) if default is not None: self.value = default def __bool__(self): return bool(self.value) __nonzero__ = __bool__ # Python 2 class CompleteUnqualifiedFunctionNames(CythonParameter): """ Have 'cy break' complete unqualified function or method names. """ class ColorizeSourceCode(CythonParameter): """ Tell cygdb whether to colorize source code. """ class TerminalBackground(CythonParameter): """ Tell cygdb about the user's terminal background (light or dark). """ class CythonParameters(object): """ Simple container class that might get more functionality in the distant future (mostly to remind us that we're dealing with parameters). """ def __init__(self): self.complete_unqualified = CompleteUnqualifiedFunctionNames( 'cy_complete_unqualified', gdb.COMMAND_BREAKPOINTS, gdb.PARAM_BOOLEAN, True) self.colorize_code = ColorizeSourceCode( 'cy_colorize_code', gdb.COMMAND_FILES, gdb.PARAM_BOOLEAN, True) self.terminal_background = TerminalBackground( 'cy_terminal_background_color', gdb.COMMAND_FILES, gdb.PARAM_STRING, "dark") parameters = CythonParameters() # Commands class CythonCommand(gdb.Command, CythonBase): """ Base class for Cython commands """ command_class = gdb.COMMAND_NONE @classmethod def _register(cls, clsname, args, kwargs): if not hasattr(cls, 'completer_class'): return cls(clsname, cls.command_class, *args, **kwargs) else: return cls(clsname, cls.command_class, cls.completer_class, *args, **kwargs) @classmethod def register(cls, *args, **kwargs): alias = getattr(cls, 'alias', None) if alias: cls._register(cls.alias, args, kwargs) return cls._register(cls.name, args, kwargs) class CyCy(CythonCommand): """ Invoke a Cython command. Available commands are: cy import cy break cy step cy next cy run cy cont cy finish cy up cy down cy select cy bt / cy backtrace cy list cy print cy set cy locals cy globals cy exec """ name = 'cy' command_class = gdb.COMMAND_NONE completer_class = gdb.COMPLETE_COMMAND def __init__(self, name, command_class, completer_class): # keep the signature 2.5 compatible (i.e. do not use f(*a, k=v) super(CythonCommand, self).__init__(name, command_class, completer_class, prefix=True) commands = dict( # GDB commands import_ = CyImport.register(), break_ = CyBreak.register(), step = CyStep.register(), next = CyNext.register(), run = CyRun.register(), cont = CyCont.register(), finish = CyFinish.register(), up = CyUp.register(), down = CyDown.register(), select = CySelect.register(), bt = CyBacktrace.register(), list = CyList.register(), print_ = CyPrint.register(), locals = CyLocals.register(), globals = CyGlobals.register(), exec_ = libpython.FixGdbCommand('cy exec', '-cy-exec'), _exec = CyExec.register(), set = CySet.register(), # GDB functions cy_cname = CyCName('cy_cname'), cy_cvalue = CyCValue('cy_cvalue'), cy_lineno = CyLine('cy_lineno'), cy_eval = CyEval('cy_eval'), ) for command_name, command in commands.items(): command.cy = self setattr(self, command_name, command) self.cy = self # Cython module namespace self.cython_namespace = {} # maps (unique) qualified function names (e.g. # cythonmodule.ClassName.method_name) to the CythonFunction object self.functions_by_qualified_name = {} # unique cnames of Cython functions self.functions_by_cname = {} # map function names like method_name to a list of all such # CythonFunction objects self.functions_by_name = collections.defaultdict(list) class CyImport(CythonCommand): """ Import debug information outputted by the Cython compiler Example: cy import FILE... """ name = 'cy import' command_class = gdb.COMMAND_STATUS completer_class = gdb.COMPLETE_FILENAME def invoke(self, args, from_tty): args = args.encode(_filesystemencoding) for arg in string_to_argv(args): try: f = open(arg) except OSError as e: raise gdb.GdbError('Unable to open file %r: %s' % (args, e.args[1])) t = etree.parse(f) for module in t.getroot(): cython_module = CythonModule(**module.attrib) self.cy.cython_namespace[cython_module.name] = cython_module for variable in module.find('Globals'): d = variable.attrib cython_module.globals[d['name']] = CythonVariable(**d) for function in module.find('Functions'): cython_function = CythonFunction(module=cython_module, **function.attrib) # update the global function mappings name = cython_function.name qname = cython_function.qualified_name self.cy.functions_by_name[name].append(cython_function) self.cy.functions_by_qualified_name[ cython_function.qualified_name] = cython_function self.cy.functions_by_cname[ cython_function.cname] = cython_function d = cython_module.functions[qname] = cython_function for local in function.find('Locals'): d = local.attrib cython_function.locals[d['name']] = CythonVariable(**d) for step_into_func in function.find('StepIntoFunctions'): d = step_into_func.attrib cython_function.step_into_functions.add(d['name']) cython_function.arguments.extend( funcarg.tag for funcarg in function.find('Arguments')) for marker in module.find('LineNumberMapping'): cython_lineno = int(marker.attrib['cython_lineno']) c_linenos = list(map(int, marker.attrib['c_linenos'].split())) cython_module.lineno_cy2c[cython_lineno] = min(c_linenos) for c_lineno in c_linenos: cython_module.lineno_c2cy[c_lineno] = cython_lineno class CyBreak(CythonCommand): """ Set a breakpoint for Cython code using Cython qualified name notation, e.g.: cy break cython_modulename.ClassName.method_name... or normal notation: cy break function_or_method_name... or for a line number: cy break cython_module:lineno... Set a Python breakpoint: Break on any function or method named 'func' in module 'modname' cy break -p modname.func... Break on any function or method named 'func' cy break -p func... """ name = 'cy break' command_class = gdb.COMMAND_BREAKPOINTS def _break_pyx(self, name): modulename, _, lineno = name.partition(':') lineno = int(lineno) if modulename: cython_module = self.cy.cython_namespace[modulename] else: cython_module = self.get_cython_function().module if lineno in cython_module.lineno_cy2c: c_lineno = cython_module.lineno_cy2c[lineno] breakpoint = '%s:%s' % (cython_module.c_filename, c_lineno) gdb.execute('break ' + breakpoint) else: raise gdb.GdbError("Not a valid line number. " "Does it contain actual code?") def _break_funcname(self, funcname): func = self.cy.functions_by_qualified_name.get(funcname) if func and func.is_initmodule_function: func = None break_funcs = [func] if not func: funcs = self.cy.functions_by_name.get(funcname) or [] funcs = [f for f in funcs if not f.is_initmodule_function] if not funcs: gdb.execute('break ' + funcname) return if len(funcs) > 1: # multiple functions, let the user pick one print('There are multiple such functions:') for idx, func in enumerate(funcs): print('%3d) %s' % (idx, func.qualified_name)) while True: try: result = input( "Select a function, press 'a' for all " "functions or press 'q' or '^D' to quit: ") except EOFError: return else: if result.lower() == 'q': return elif result.lower() == 'a': break_funcs = funcs break elif (result.isdigit() and 0 <= int(result) < len(funcs)): break_funcs = [funcs[int(result)]] break else: print('Not understood...') else: break_funcs = [funcs[0]] for func in break_funcs: gdb.execute('break %s' % func.cname) if func.pf_cname: gdb.execute('break %s' % func.pf_cname) def invoke(self, function_names, from_tty): argv = string_to_argv(function_names.encode('UTF-8')) if function_names.startswith('-p'): argv = argv[1:] python_breakpoints = True else: python_breakpoints = False for funcname in argv: if python_breakpoints: gdb.execute('py-break %s' % funcname) elif ':' in funcname: self._break_pyx(funcname) else: self._break_funcname(funcname) @dont_suppress_errors def complete(self, text, word): # Filter init-module functions (breakpoints can be set using # modulename:linenumber). names = [n for n, L in self.cy.functions_by_name.items() if any(not f.is_initmodule_function for f in L)] qnames = [n for n, f in self.cy.functions_by_qualified_name.items() if not f.is_initmodule_function] if parameters.complete_unqualified: all_names = itertools.chain(qnames, names) else: all_names = qnames words = text.strip().split() if not words or '.' not in words[-1]: # complete unqualified seen = set(text[:-len(word)].split()) return [n for n in all_names if n.startswith(word) and n not in seen] # complete qualified name lastword = words[-1] compl = [n for n in qnames if n.startswith(lastword)] if len(lastword) > len(word): # readline sees something (e.g. a '.') as a word boundary, so don't # "recomplete" this prefix strip_prefix_length = len(lastword) - len(word) compl = [n[strip_prefix_length:] for n in compl] return compl class CythonInfo(CythonBase, libpython.PythonInfo): """ Implementation of the interface dictated by libpython.LanguageInfo. """ def lineno(self, frame): # Take care of the Python and Cython levels. We need to care for both # as we can't simply dispath to 'py-step', since that would work for # stepping through Python code, but it would not step back into Cython- # related code. The C level should be dispatched to the 'step' command. if self.is_cython_function(frame): return self.get_cython_lineno(frame) return super(CythonInfo, self).lineno(frame) def get_source_line(self, frame): try: line = super(CythonInfo, self).get_source_line(frame) except gdb.GdbError: return None else: return line.strip() or None def exc_info(self, frame): if self.is_python_function: return super(CythonInfo, self).exc_info(frame) def runtime_break_functions(self): if self.is_cython_function(): return self.get_cython_function().step_into_functions return () def static_break_functions(self): result = ['PyEval_EvalFrameEx'] result.extend(self.cy.functions_by_cname) return result class CythonExecutionControlCommand(CythonCommand, libpython.ExecutionControlCommandBase): @classmethod def register(cls): return cls(cls.name, cython_info) class CyStep(CythonExecutionControlCommand, libpython.PythonStepperMixin): "Step through Cython, Python or C code." name = 'cy -step' stepinto = True def invoke(self, args, from_tty): if self.is_python_function(): self.python_step(self.stepinto) elif not self.is_cython_function(): if self.stepinto: command = 'step' else: command = 'next' self.finish_executing(gdb.execute(command, to_string=True)) else: self.step(stepinto=self.stepinto) class CyNext(CyStep): "Step-over Cython, Python or C code." name = 'cy -next' stepinto = False class CyRun(CythonExecutionControlCommand): """ Run a Cython program. This is like the 'run' command, except that it displays Cython or Python source lines as well """ name = 'cy run' invoke = CythonExecutionControlCommand.run class CyCont(CythonExecutionControlCommand): """ Continue a Cython program. This is like the 'run' command, except that it displays Cython or Python source lines as well. """ name = 'cy cont' invoke = CythonExecutionControlCommand.cont class CyFinish(CythonExecutionControlCommand): """ Execute until the function returns. """ name = 'cy finish' invoke = CythonExecutionControlCommand.finish class CyUp(CythonCommand): """ Go up a Cython, Python or relevant C frame. """ name = 'cy up' _command = 'up' def invoke(self, *args): try: gdb.execute(self._command, to_string=True) while not self.is_relevant_function(gdb.selected_frame()): gdb.execute(self._command, to_string=True) except RuntimeError as e: raise gdb.GdbError(*e.args) frame = gdb.selected_frame() index = 0 while frame: frame = frame.older() index += 1 self.print_stackframe(index=index - 1) class CyDown(CyUp): """ Go down a Cython, Python or relevant C frame. """ name = 'cy down' _command = 'down' class CySelect(CythonCommand): """ Select a frame. Use frame numbers as listed in `cy backtrace`. This command is useful because `cy backtrace` prints a reversed backtrace. """ name = 'cy select' def invoke(self, stackno, from_tty): try: stackno = int(stackno) except ValueError: raise gdb.GdbError("Not a valid number: %r" % (stackno,)) frame = gdb.selected_frame() while frame.newer(): frame = frame.newer() stackdepth = libpython.stackdepth(frame) try: gdb.execute('select %d' % (stackdepth - stackno - 1,)) except RuntimeError as e: raise gdb.GdbError(*e.args) class CyBacktrace(CythonCommand): 'Print the Cython stack' name = 'cy bt' alias = 'cy backtrace' command_class = gdb.COMMAND_STACK completer_class = gdb.COMPLETE_NONE @require_running_program def invoke(self, args, from_tty): # get the first frame frame = gdb.selected_frame() while frame.older(): frame = frame.older() print_all = args == '-a' index = 0 while frame: try: is_relevant = self.is_relevant_function(frame) except CyGDBError: is_relevant = False if print_all or is_relevant: self.print_stackframe(frame, index) index += 1 frame = frame.newer() class CyList(CythonCommand): """ List Cython source code. To disable to customize colouring see the cy_* parameters. """ name = 'cy list' command_class = gdb.COMMAND_FILES completer_class = gdb.COMPLETE_NONE # @dispatch_on_frame(c_command='list') def invoke(self, _, from_tty): sd, lineno = self.get_source_desc() source = sd.get_source(lineno - 5, lineno + 5, mark_line=lineno, lex_entire=True) print(source) class CyPrint(CythonCommand): """ Print a Cython variable using 'cy-print x' or 'cy-print module.function.x' """ name = 'cy print' command_class = gdb.COMMAND_DATA def invoke(self, name, from_tty, max_name_length=None): if self.is_python_function(): return gdb.execute('py-print ' + name) elif self.is_cython_function(): value = self.cy.cy_cvalue.invoke(name.lstrip('*')) for c in name: if c == '*': value = value.dereference() else: break self.print_gdb_value(name, value, max_name_length) else: gdb.execute('print ' + name) def complete(self): if self.is_cython_function(): f = self.get_cython_function() return list(itertools.chain(f.locals, f.globals)) else: return [] sortkey = lambda item: item[0].lower() class CyLocals(CythonCommand): """ List the locals from the current Cython frame. """ name = 'cy locals' command_class = gdb.COMMAND_STACK completer_class = gdb.COMPLETE_NONE @dispatch_on_frame(c_command='info locals', python_command='py-locals') def invoke(self, args, from_tty): cython_function = self.get_cython_function() if cython_function.is_initmodule_function: self.cy.globals.invoke(args, from_tty) return local_cython_vars = cython_function.locals max_name_length = len(max(local_cython_vars, key=len)) for name, cyvar in sorted(local_cython_vars.items(), key=sortkey): if self.is_initialized(self.get_cython_function(), cyvar.name): value = gdb.parse_and_eval(cyvar.cname) if not value.is_optimized_out: self.print_gdb_value(cyvar.name, value, max_name_length, '') class CyGlobals(CyLocals): """ List the globals from the current Cython module. """ name = 'cy globals' command_class = gdb.COMMAND_STACK completer_class = gdb.COMPLETE_NONE @dispatch_on_frame(c_command='info variables', python_command='py-globals') def invoke(self, args, from_tty): global_python_dict = self.get_cython_globals_dict() module_globals = self.get_cython_function().module.globals max_globals_len = 0 max_globals_dict_len = 0 if module_globals: max_globals_len = len(max(module_globals, key=len)) if global_python_dict: max_globals_dict_len = len(max(global_python_dict)) max_name_length = max(max_globals_len, max_globals_dict_len) seen = set() print('Python globals:') for k, v in sorted(global_python_dict.items(), key=sortkey): v = v.get_truncated_repr(libpython.MAX_OUTPUT_LEN) seen.add(k) print(' %-*s = %s' % (max_name_length, k, v)) print('C globals:') for name, cyvar in sorted(module_globals.items(), key=sortkey): if name not in seen: try: value = gdb.parse_and_eval(cyvar.cname) except RuntimeError: pass else: if not value.is_optimized_out: self.print_gdb_value(cyvar.name, value, max_name_length, ' ') class EvaluateOrExecuteCodeMixin(object): """ Evaluate or execute Python code in a Cython or Python frame. The 'evalcode' method evaluations Python code, prints a traceback if an exception went uncaught, and returns any return value as a gdb.Value (NULL on exception). """ def _fill_locals_dict(self, executor, local_dict_pointer): "Fill a remotely allocated dict with values from the Cython C stack" cython_func = self.get_cython_function() for name, cyvar in cython_func.locals.items(): if cyvar.type == PythonObject and self.is_initialized(cython_func, name): try: val = gdb.parse_and_eval(cyvar.cname) except RuntimeError: continue else: if val.is_optimized_out: continue pystringp = executor.alloc_pystring(name) code = ''' (PyObject *) PyDict_SetItem( (PyObject *) %d, (PyObject *) %d, (PyObject *) %s) ''' % (local_dict_pointer, pystringp, cyvar.cname) try: if gdb.parse_and_eval(code) < 0: gdb.parse_and_eval('PyErr_Print()') raise gdb.GdbError("Unable to execute Python code.") finally: # PyDict_SetItem doesn't steal our reference executor.xdecref(pystringp) def _find_first_cython_or_python_frame(self): frame = gdb.selected_frame() while frame: if (self.is_cython_function(frame) or self.is_python_function(frame)): frame.select() return frame frame = frame.older() raise gdb.GdbError("There is no Cython or Python frame on the stack.") def _evalcode_cython(self, executor, code, input_type): with libpython.FetchAndRestoreError(): # get the dict of Cython globals and construct a dict in the # inferior with Cython locals global_dict = gdb.parse_and_eval( '(PyObject *) PyModule_GetDict(__pyx_m)') local_dict = gdb.parse_and_eval('(PyObject *) PyDict_New()') try: self._fill_locals_dict(executor, libpython.pointervalue(local_dict)) result = executor.evalcode(code, input_type, global_dict, local_dict) finally: executor.xdecref(libpython.pointervalue(local_dict)) return result def evalcode(self, code, input_type): """ Evaluate `code` in a Python or Cython stack frame using the given `input_type`. """ frame = self._find_first_cython_or_python_frame() executor = libpython.PythonCodeExecutor() if self.is_python_function(frame): return libpython._evalcode_python(executor, code, input_type) return self._evalcode_cython(executor, code, input_type) class CyExec(CythonCommand, libpython.PyExec, EvaluateOrExecuteCodeMixin): """ Execute Python code in the nearest Python or Cython frame. """ name = '-cy-exec' command_class = gdb.COMMAND_STACK completer_class = gdb.COMPLETE_NONE def invoke(self, expr, from_tty): expr, input_type = self.readcode(expr) executor = libpython.PythonCodeExecutor() executor.xdecref(self.evalcode(expr, executor.Py_single_input)) class CySet(CythonCommand): """ Set a Cython variable to a certain value cy set my_cython_c_variable = 10 cy set my_cython_py_variable = $cy_eval("{'doner': 'kebab'}") This is equivalent to set $cy_value("my_cython_variable") = 10 """ name = 'cy set' command_class = gdb.COMMAND_DATA completer_class = gdb.COMPLETE_NONE @require_cython_frame def invoke(self, expr, from_tty): name_and_expr = expr.split('=', 1) if len(name_and_expr) != 2: raise gdb.GdbError("Invalid expression. Use 'cy set var = expr'.") varname, expr = name_and_expr cname = self.cy.cy_cname.invoke(varname.strip()) gdb.execute("set %s = %s" % (cname, expr)) # Functions class CyCName(gdb.Function, CythonBase): """ Get the C name of a Cython variable in the current context. Examples: print $cy_cname("function") print $cy_cname("Class.method") print $cy_cname("module.function") """ @require_cython_frame @gdb_function_value_to_unicode def invoke(self, cyname, frame=None): frame = frame or gdb.selected_frame() cname = None if self.is_cython_function(frame): cython_function = self.get_cython_function(frame) if cyname in cython_function.locals: cname = cython_function.locals[cyname].cname elif cyname in cython_function.module.globals: cname = cython_function.module.globals[cyname].cname else: qname = '%s.%s' % (cython_function.module.name, cyname) if qname in cython_function.module.functions: cname = cython_function.module.functions[qname].cname if not cname: cname = self.cy.functions_by_qualified_name.get(cyname) if not cname: raise gdb.GdbError('No such Cython variable: %s' % cyname) return cname class CyCValue(CyCName): """ Get the value of a Cython variable. """ @require_cython_frame @gdb_function_value_to_unicode def invoke(self, cyname, frame=None): globals_dict = self.get_cython_globals_dict() cython_function = self.get_cython_function(frame) if self.is_initialized(cython_function, cyname): cname = super(CyCValue, self).invoke(cyname, frame=frame) return gdb.parse_and_eval(cname) elif cyname in globals_dict: return globals_dict[cyname]._gdbval else: raise gdb.GdbError("Variable %s is not initialized." % cyname) class CyLine(gdb.Function, CythonBase): """ Get the current Cython line. """ @require_cython_frame def invoke(self): return self.get_cython_lineno() class CyEval(gdb.Function, CythonBase, EvaluateOrExecuteCodeMixin): """ Evaluate Python code in the nearest Python or Cython frame and return """ @gdb_function_value_to_unicode def invoke(self, python_expression): input_type = libpython.PythonCodeExecutor.Py_eval_input return self.evalcode(python_expression, input_type) cython_info = CythonInfo() cy = CyCy.register() cython_info.cy = cy def register_defines(): libpython.source_gdb_script(textwrap.dedent("""\ define cy step cy -step end define cy next cy -next end document cy step %s end document cy next %s end """) % (CyStep.__doc__, CyNext.__doc__)) register_defines() Cython-0.23.4/Cython/Debugger/__init__.py0000644000175600017570000000001512606202452021301 0ustar jenkinsjenkins00000000000000# empty file Cython-0.23.4/Cython/Debugger/DebugWriter.py0000644000175600017570000000423712606202452021777 0ustar jenkinsjenkins00000000000000from __future__ import with_statement import os import sys import errno try: from lxml import etree have_lxml = True except ImportError: have_lxml = False try: # Python 2.5 from xml.etree import cElementTree as etree except ImportError: try: # Python 2.5 from xml.etree import ElementTree as etree except ImportError: try: # normal cElementTree install import cElementTree as etree except ImportError: try: # normal ElementTree install import elementtree.ElementTree as etree except ImportError: etree = None from Cython.Compiler import Errors class CythonDebugWriter(object): """ Class to output debugging information for cygdb It writes debug information to cython_debug/cython_debug_info_ in the build directory. """ def __init__(self, output_dir): if etree is None: raise Errors.NoElementTreeInstalledException() self.output_dir = os.path.join(output_dir or os.curdir, 'cython_debug') self.tb = etree.TreeBuilder() # set by Cython.Compiler.ParseTreeTransforms.DebugTransform self.module_name = None self.start('cython_debug', attrs=dict(version='1.0')) def start(self, name, attrs=None): self.tb.start(name, attrs or {}) def end(self, name): self.tb.end(name) def serialize(self): self.tb.end('Module') self.tb.end('cython_debug') xml_root_element = self.tb.close() try: os.makedirs(self.output_dir) except OSError as e: if e.errno != errno.EEXIST: raise et = etree.ElementTree(xml_root_element) kw = {} if have_lxml: kw['pretty_print'] = True fn = "cython_debug_info_" + self.module_name et.write(os.path.join(self.output_dir, fn), encoding="UTF-8", **kw) interpreter_path = os.path.join(self.output_dir, 'interpreter') with open(interpreter_path, 'w') as f: f.write(sys.executable) Cython-0.23.4/Cython/Debugger/Cygdb.py0000644000175600017570000001272312606202452020603 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python """ The Cython debugger The current directory should contain a directory named 'cython_debug', or a path to the cython project directory should be given (the parent directory of cython_debug). Additional gdb args can be provided only if a path to the project directory is given. """ import os import sys import glob import tempfile import textwrap import subprocess import optparse import logging logger = logging.getLogger(__name__) def make_command_file(path_to_debug_info, prefix_code='', no_import=False): if not no_import: pattern = os.path.join(path_to_debug_info, 'cython_debug', 'cython_debug_info_*') debug_files = glob.glob(pattern) if not debug_files: sys.exit('%s.\nNo debug files were found in %s. Aborting.' % ( usage, os.path.abspath(path_to_debug_info))) fd, tempfilename = tempfile.mkstemp() f = os.fdopen(fd, 'w') try: f.write(prefix_code) f.write(textwrap.dedent('''\ # This is a gdb command file # See https://sourceware.org/gdb/onlinedocs/gdb/Command-Files.html set breakpoint pending on set print pretty on python # Activate virtualenv, if we were launched from one import os virtualenv = os.getenv('VIRTUAL_ENV') if virtualenv: path_to_activate_this_py = os.path.join(virtualenv, 'bin', 'activate_this.py') print("gdb command file: Activating virtualenv: %s; path_to_activate_this_py: %s" % ( virtualenv, path_to_activate_this_py)) with open(path_to_activate_this_py) as f: exec(f.read(), dict(__file__=path_to_activate_this_py)) from Cython.Debugger import libcython, libpython end ''')) if no_import: # don't do this, this overrides file command in .gdbinit # f.write("file %s\n" % sys.executable) pass else: path = os.path.join(path_to_debug_info, "cython_debug", "interpreter") interpreter_file = open(path) try: interpreter = interpreter_file.read() finally: interpreter_file.close() f.write("file %s\n" % interpreter) f.write('\n'.join('cy import %s\n' % fn for fn in debug_files)) f.write(textwrap.dedent('''\ python import sys try: gdb.lookup_type('PyModuleObject') except RuntimeError: sys.stderr.write( 'Python was not compiled with debug symbols (or it was ' 'stripped). Some functionality may not work (properly).\\n') end source .cygdbinit ''')) finally: f.close() return tempfilename usage = "Usage: cygdb [options] [PATH [-- GDB_ARGUMENTS]]" def main(path_to_debug_info=None, gdb_argv=None, no_import=False): """ Start the Cython debugger. This tells gdb to import the Cython and Python extensions (libcython.py and libpython.py) and it enables gdb's pending breakpoints. path_to_debug_info is the path to the Cython build directory gdb_argv is the list of options to gdb no_import tells cygdb whether it should import debug information """ parser = optparse.OptionParser(usage=usage) parser.add_option("--gdb-executable", dest="gdb", default='gdb', help="gdb executable to use [default: gdb]") parser.add_option("--verbose", "-v", dest="verbosity", action="count", default=0, help="Verbose mode. Multiple -v options increase the verbosity") (options, args) = parser.parse_args() if path_to_debug_info is None: if len(args) > 1: path_to_debug_info = args[0] else: path_to_debug_info = os.curdir if gdb_argv is None: gdb_argv = args[1:] if path_to_debug_info == '--': no_import = True logging_level = logging.WARN if options.verbosity == 1: logging_level = logging.INFO if options.verbosity >= 2: logging_level = logging.DEBUG logging.basicConfig(level=logging_level) logger.info("verbosity = %r", options.verbosity) logger.debug("options = %r; args = %r", options, args) logger.debug("Done parsing command-line options. path_to_debug_info = %r, gdb_argv = %r", path_to_debug_info, gdb_argv) tempfilename = make_command_file(path_to_debug_info, no_import=no_import) logger.info("Launching %s with command file: %s and gdb_argv: %s", options.gdb, tempfilename, gdb_argv) logger.debug('Command file (%s) contains: """\n%s"""', tempfilename, open(tempfilename).read()) logger.info("Spawning %s...", options.gdb) p = subprocess.Popen([options.gdb, '-command', tempfilename] + gdb_argv) logger.info("Spawned %s (pid %d)", options.gdb, p.pid) while True: try: logger.debug("Waiting for gdb (pid %d) to exit...", p.pid) ret = p.wait() logger.debug("Wait for gdb (pid %d) to exit is done. Returned: %r", p.pid, ret) except KeyboardInterrupt: pass else: break logger.debug("Removing temp command file: %s", tempfilename) os.remove(tempfilename) logger.debug("Removed temp command file: %s", tempfilename) Cython-0.23.4/Cython/Debugger/Tests/0000755000175600017570000000000012606202455020301 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Debugger/Tests/test_libpython_in_gdb.py0000644000175600017570000000762312606202452025231 0ustar jenkinsjenkins00000000000000# -*- coding: UTF-8 -*- """ Test libpython.py. This is already partly tested by test_libcython_in_gdb and Lib/test/test_gdb.py in the Python source. These tests are run in gdb and called from test_libcython_in_gdb.main() """ import os import sys import gdb from Cython.Debugger import libcython from Cython.Debugger import libpython from . import test_libcython_in_gdb from .test_libcython_in_gdb import _debug, inferior_python_version class TestPrettyPrinters(test_libcython_in_gdb.DebugTestCase): """ Test whether types of Python objects are correctly inferred and that the right libpython.PySomeTypeObjectPtr classes are instantiated. Also test whether values are appropriately formatted (don't be too laborious as Lib/test/test_gdb.py already covers this extensively). Don't take care of decreffing newly allocated objects as a new interpreter is started for every test anyway. """ def setUp(self): super(TestPrettyPrinters, self).setUp() self.break_and_run('b = c = d = 0') def get_pyobject(self, code): value = gdb.parse_and_eval(code) assert libpython.pointervalue(value) != 0 return value def pyobject_fromcode(self, code, gdbvar=None): if gdbvar is not None: d = {'varname':gdbvar, 'code':code} gdb.execute('set $%(varname)s = %(code)s' % d) code = '$' + gdbvar return libpython.PyObjectPtr.from_pyobject_ptr(self.get_pyobject(code)) def get_repr(self, pyobject): return pyobject.get_truncated_repr(libpython.MAX_OUTPUT_LEN) def alloc_bytestring(self, string, gdbvar=None): if inferior_python_version < (3, 0): funcname = 'PyString_FromStringAndSize' else: funcname = 'PyBytes_FromStringAndSize' assert '"' not in string # ensure double quotes code = '(PyObject *) %s("%s", %d)' % (funcname, string, len(string)) return self.pyobject_fromcode(code, gdbvar=gdbvar) def alloc_unicodestring(self, string, gdbvar=None): self.alloc_bytestring(string.encode('UTF-8'), gdbvar='_temp') postfix = libpython.get_inferior_unicode_postfix() funcname = 'PyUnicode%s_FromEncodedObject' % (postfix,) return self.pyobject_fromcode( '(PyObject *) %s($_temp, "UTF-8", "strict")' % funcname, gdbvar=gdbvar) def test_bytestring(self): bytestring = self.alloc_bytestring("spam") if inferior_python_version < (3, 0): bytestring_class = libpython.PyStringObjectPtr expected = repr("spam") else: bytestring_class = libpython.PyBytesObjectPtr expected = "b'spam'" self.assertEqual(type(bytestring), bytestring_class) self.assertEqual(self.get_repr(bytestring), expected) def test_unicode(self): unicode_string = self.alloc_unicodestring(u"spam ἄλφα") expected = "'spam ἄλφα'" if inferior_python_version < (3, 0): expected = 'u' + expected self.assertEqual(type(unicode_string), libpython.PyUnicodeObjectPtr) self.assertEqual(self.get_repr(unicode_string), expected) def test_int(self): if inferior_python_version < (3, 0): intval = self.pyobject_fromcode('PyInt_FromLong(100)') self.assertEqual(type(intval), libpython.PyIntObjectPtr) self.assertEqual(self.get_repr(intval), '100') def test_long(self): longval = self.pyobject_fromcode('PyLong_FromLong(200)', gdbvar='longval') assert gdb.parse_and_eval('$longval->ob_type == &PyLong_Type') self.assertEqual(type(longval), libpython.PyLongObjectPtr) self.assertEqual(self.get_repr(longval), '200') def test_frame_type(self): frame = self.pyobject_fromcode('PyEval_GetFrame()') self.assertEqual(type(frame), libpython.PyFrameObjectPtr) Cython-0.23.4/Cython/Debugger/Tests/test_libcython_in_gdb.py0000644000175600017570000003670112606202452025213 0ustar jenkinsjenkins00000000000000""" Tests that run inside GDB. Note: debug information is already imported by the file generated by Cython.Debugger.Cygdb.make_command_file() """ from __future__ import absolute_import import os import re import sys import trace import inspect import warnings import unittest import textwrap import tempfile import functools import traceback import itertools from test import test_support import gdb from .. import libcython from .. import libpython from . import TestLibCython as test_libcython from ...Utils import add_metaclass # for some reason sys.argv is missing in gdb sys.argv = ['gdb'] def print_on_call_decorator(func): @functools.wraps(func) def wrapper(self, *args, **kwargs): _debug(type(self).__name__, func.__name__) try: return func(self, *args, **kwargs) except Exception as e: _debug("An exception occurred:", traceback.format_exc(e)) raise return wrapper class TraceMethodCallMeta(type): def __init__(self, name, bases, dict): for func_name, func in dict.items(): if inspect.isfunction(func): setattr(self, func_name, print_on_call_decorator(func)) @add_metaclass(TraceMethodCallMeta) class DebugTestCase(unittest.TestCase): """ Base class for test cases. On teardown it kills the inferior and unsets all breakpoints. """ def __init__(self, name): super(DebugTestCase, self).__init__(name) self.cy = libcython.cy self.module = libcython.cy.cython_namespace['codefile'] self.spam_func, self.spam_meth = libcython.cy.functions_by_name['spam'] self.ham_func = libcython.cy.functions_by_qualified_name[ 'codefile.ham'] self.eggs_func = libcython.cy.functions_by_qualified_name[ 'codefile.eggs'] def read_var(self, varname, cast_to=None): result = gdb.parse_and_eval('$cy_cvalue("%s")' % varname) if cast_to: result = cast_to(result) return result def local_info(self): return gdb.execute('info locals', to_string=True) def lineno_equals(self, source_line=None, lineno=None): if source_line is not None: lineno = test_libcython.source_to_lineno[source_line] frame = gdb.selected_frame() self.assertEqual(libcython.cython_info.lineno(frame), lineno) def break_and_run(self, source_line): break_lineno = test_libcython.source_to_lineno[source_line] gdb.execute('cy break codefile:%d' % break_lineno, to_string=True) gdb.execute('run', to_string=True) def tearDown(self): gdb.execute('delete breakpoints', to_string=True) try: gdb.execute('kill inferior 1', to_string=True) except RuntimeError: pass gdb.execute('set args -c "import codefile"') class TestDebugInformationClasses(DebugTestCase): def test_CythonModule(self): "test that debug information was parsed properly into data structures" self.assertEqual(self.module.name, 'codefile') global_vars = ('c_var', 'python_var', '__name__', '__builtins__', '__doc__', '__file__') assert set(global_vars).issubset(self.module.globals) def test_CythonVariable(self): module_globals = self.module.globals c_var = module_globals['c_var'] python_var = module_globals['python_var'] self.assertEqual(c_var.type, libcython.CObject) self.assertEqual(python_var.type, libcython.PythonObject) self.assertEqual(c_var.qualified_name, 'codefile.c_var') def test_CythonFunction(self): self.assertEqual(self.spam_func.qualified_name, 'codefile.spam') self.assertEqual(self.spam_meth.qualified_name, 'codefile.SomeClass.spam') self.assertEqual(self.spam_func.module, self.module) assert self.eggs_func.pf_cname, (self.eggs_func, self.eggs_func.pf_cname) assert not self.ham_func.pf_cname assert not self.spam_func.pf_cname assert not self.spam_meth.pf_cname self.assertEqual(self.spam_func.type, libcython.CObject) self.assertEqual(self.ham_func.type, libcython.CObject) self.assertEqual(self.spam_func.arguments, ['a']) self.assertEqual(self.spam_func.step_into_functions, set(['puts', 'some_c_function'])) expected_lineno = test_libcython.source_to_lineno['def spam(a=0):'] self.assertEqual(self.spam_func.lineno, expected_lineno) self.assertEqual(sorted(self.spam_func.locals), list('abcd')) class TestParameters(unittest.TestCase): def test_parameters(self): gdb.execute('set cy_colorize_code on') assert libcython.parameters.colorize_code gdb.execute('set cy_colorize_code off') assert not libcython.parameters.colorize_code class TestBreak(DebugTestCase): def test_break(self): breakpoint_amount = len(gdb.breakpoints() or ()) gdb.execute('cy break codefile.spam') self.assertEqual(len(gdb.breakpoints()), breakpoint_amount + 1) bp = gdb.breakpoints()[-1] self.assertEqual(bp.type, gdb.BP_BREAKPOINT) assert self.spam_func.cname in bp.location assert bp.enabled def test_python_break(self): gdb.execute('cy break -p join') assert 'def join(' in gdb.execute('cy run', to_string=True) def test_break_lineno(self): beginline = 'import os' nextline = 'cdef int c_var = 12' self.break_and_run(beginline) self.lineno_equals(beginline) step_result = gdb.execute('cy step', to_string=True) self.lineno_equals(nextline) assert step_result.rstrip().endswith(nextline) class TestKilled(DebugTestCase): def test_abort(self): gdb.execute("set args -c 'import os; os.abort()'") output = gdb.execute('cy run', to_string=True) assert 'abort' in output.lower() class DebugStepperTestCase(DebugTestCase): def step(self, varnames_and_values, source_line=None, lineno=None): gdb.execute(self.command) for varname, value in varnames_and_values: self.assertEqual(self.read_var(varname), value, self.local_info()) self.lineno_equals(source_line, lineno) class TestStep(DebugStepperTestCase): """ Test stepping. Stepping happens in the code found in Cython/Debugger/Tests/codefile. """ def test_cython_step(self): gdb.execute('cy break codefile.spam') gdb.execute('run', to_string=True) self.lineno_equals('def spam(a=0):') gdb.execute('cy step', to_string=True) self.lineno_equals('b = c = d = 0') self.command = 'cy step' self.step([('b', 0)], source_line='b = 1') self.step([('b', 1), ('c', 0)], source_line='c = 2') self.step([('c', 2)], source_line='int(10)') self.step([], source_line='puts("spam")') gdb.execute('cont', to_string=True) self.assertEqual(len(gdb.inferiors()), 1) self.assertEqual(gdb.inferiors()[0].pid, 0) def test_c_step(self): self.break_and_run('some_c_function()') gdb.execute('cy step', to_string=True) self.assertEqual(gdb.selected_frame().name(), 'some_c_function') def test_python_step(self): self.break_and_run('os.path.join("foo", "bar")') result = gdb.execute('cy step', to_string=True) curframe = gdb.selected_frame() self.assertEqual(curframe.name(), 'PyEval_EvalFrameEx') pyframe = libpython.Frame(curframe).get_pyop() # With Python 3 inferiors, pyframe.co_name will return a PyUnicodePtr, # be compatible frame_name = pyframe.co_name.proxyval(set()) self.assertEqual(frame_name, 'join') assert re.match(r'\d+ def join\(', result), result class TestNext(DebugStepperTestCase): def test_cython_next(self): self.break_and_run('c = 2') lines = ( 'int(10)', 'puts("spam")', 'os.path.join("foo", "bar")', 'some_c_function()', ) for line in lines: gdb.execute('cy next') self.lineno_equals(line) class TestLocalsGlobals(DebugTestCase): def test_locals(self): self.break_and_run('int(10)') result = gdb.execute('cy locals', to_string=True) assert 'a = 0', repr(result) assert 'b = (int) 1', result assert 'c = (int) 2' in result, repr(result) def test_globals(self): self.break_and_run('int(10)') result = gdb.execute('cy globals', to_string=True) assert '__name__ ' in result, repr(result) assert '__doc__ ' in result, repr(result) assert 'os ' in result, repr(result) assert 'c_var ' in result, repr(result) assert 'python_var ' in result, repr(result) class TestBacktrace(DebugTestCase): def test_backtrace(self): libcython.parameters.colorize_code.value = False self.break_and_run('os.path.join("foo", "bar")') def match_backtrace_output(result): assert re.search(r'\#\d+ *0x.* in spam\(\) at .*codefile\.pyx:22', result), result assert 'os.path.join("foo", "bar")' in result, result result = gdb.execute('cy bt', to_string=True) match_backtrace_output(result) result = gdb.execute('cy bt -a', to_string=True) match_backtrace_output(result) # Apparently not everyone has main() # assert re.search(r'\#0 *0x.* in main\(\)', result), result class TestFunctions(DebugTestCase): def test_functions(self): self.break_and_run('c = 2') result = gdb.execute('print $cy_cname("b")', to_string=True) assert re.search('__pyx_.*b', result), result result = gdb.execute('print $cy_lineno()', to_string=True) supposed_lineno = test_libcython.source_to_lineno['c = 2'] assert str(supposed_lineno) in result, (supposed_lineno, result) result = gdb.execute('print $cy_cvalue("b")', to_string=True) assert '= 1' in result class TestPrint(DebugTestCase): def test_print(self): self.break_and_run('c = 2') result = gdb.execute('cy print b', to_string=True) self.assertEqual('b = (int) 1\n', result) class TestUpDown(DebugTestCase): def test_updown(self): self.break_and_run('os.path.join("foo", "bar")') gdb.execute('cy step') self.assertRaises(RuntimeError, gdb.execute, 'cy down') result = gdb.execute('cy up', to_string=True) assert 'spam()' in result assert 'os.path.join("foo", "bar")' in result class TestExec(DebugTestCase): def setUp(self): super(TestExec, self).setUp() self.fd, self.tmpfilename = tempfile.mkstemp() self.tmpfile = os.fdopen(self.fd, 'r+') def tearDown(self): super(TestExec, self).tearDown() try: self.tmpfile.close() finally: os.remove(self.tmpfilename) def eval_command(self, command): gdb.execute('cy exec open(%r, "w").write(str(%s))' % (self.tmpfilename, command)) return self.tmpfile.read().strip() def test_cython_exec(self): self.break_and_run('os.path.join("foo", "bar")') # test normal behaviour self.assertEqual("[0]", self.eval_command('[a]')) # test multiline code result = gdb.execute(textwrap.dedent('''\ cy exec pass "nothing" end ''')) result = self.tmpfile.read().rstrip() self.assertEqual('', result) def test_python_exec(self): self.break_and_run('os.path.join("foo", "bar")') gdb.execute('cy step') gdb.execute('cy exec some_random_var = 14') self.assertEqual('14', self.eval_command('some_random_var')) class CySet(DebugTestCase): def test_cyset(self): self.break_and_run('os.path.join("foo", "bar")') gdb.execute('cy set a = $cy_eval("{None: []}")') stringvalue = self.read_var("a", cast_to=str) self.assertEqual(stringvalue, "{None: []}") class TestCyEval(DebugTestCase): "Test the $cy_eval() gdb function." def test_cy_eval(self): # This function leaks a few objects in the GDB python process. This # is no biggie self.break_and_run('os.path.join("foo", "bar")') result = gdb.execute('print $cy_eval("None")', to_string=True) assert re.match(r'\$\d+ = None\n', result), result result = gdb.execute('print $cy_eval("[a]")', to_string=True) assert re.match(r'\$\d+ = \[0\]', result), result class TestClosure(DebugTestCase): def break_and_run_func(self, funcname): gdb.execute('cy break ' + funcname) gdb.execute('cy run') def test_inner(self): self.break_and_run_func('inner') self.assertEqual('', gdb.execute('cy locals', to_string=True)) # Allow the Cython-generated code to initialize the scope variable gdb.execute('cy step') self.assertEqual(str(self.read_var('a')), "'an object'") print_result = gdb.execute('cy print a', to_string=True).strip() self.assertEqual(print_result, "a = 'an object'") def test_outer(self): self.break_and_run_func('outer') self.assertEqual('', gdb.execute('cy locals', to_string=True)) # Initialize scope with 'a' uninitialized gdb.execute('cy step') self.assertEqual('', gdb.execute('cy locals', to_string=True)) # Initialize 'a' to 1 gdb.execute('cy step') print_result = gdb.execute('cy print a', to_string=True).strip() self.assertEqual(print_result, "a = 'an object'") _do_debug = os.environ.get('GDB_DEBUG') if _do_debug: _debug_file = open('/dev/tty', 'w') def _debug(*messages): if _do_debug: messages = itertools.chain([sys._getframe(1).f_code.co_name, ':'], messages) _debug_file.write(' '.join(str(msg) for msg in messages) + '\n') def run_unittest_in_module(modulename): try: gdb.lookup_type('PyModuleObject') except RuntimeError: msg = ("Unable to run tests, Python was not compiled with " "debugging information. Either compile python with " "-g or get a debug build (configure with --with-pydebug).") warnings.warn(msg) os._exit(1) else: m = __import__(modulename, fromlist=['']) tests = inspect.getmembers(m, inspect.isclass) # test_support.run_unittest(tests) test_loader = unittest.TestLoader() suite = unittest.TestSuite( [test_loader.loadTestsFromTestCase(cls) for name, cls in tests]) result = unittest.TextTestRunner(verbosity=1).run(suite) return result.wasSuccessful() def runtests(): """ Run the libcython and libpython tests. Ensure that an appropriate status is returned to the parent test process. """ from Cython.Debugger.Tests import test_libpython_in_gdb success_libcython = run_unittest_in_module(__name__) success_libpython = run_unittest_in_module(test_libpython_in_gdb.__name__) if not success_libcython or not success_libpython: sys.exit(2) def main(version, trace_code=False): global inferior_python_version inferior_python_version = version if trace_code: tracer = trace.Trace(count=False, trace=True, outfile=sys.stderr, ignoredirs=[sys.prefix, sys.exec_prefix]) tracer.runfunc(runtests) else: runtests() Cython-0.23.4/Cython/Debugger/Tests/codefile0000644000175600017570000000120512606202452021771 0ustar jenkinsjenkins00000000000000cdef extern from "stdio.h": int puts(char *s) cdef extern: void some_c_function() import os cdef int c_var = 12 python_var = 13 def spam(a=0): cdef: int b, c b = c = d = 0 b = 1 c = 2 int(10) puts("spam") os.path.join("foo", "bar") some_c_function() cpdef eggs(): pass cdef ham(): pass cdef class SomeClass(object): def spam(self): pass def outer(): cdef object a = "an object" def inner(): b = 2 # access closed over variables print a, b return inner outer()() spam() print "bye!" def use_ham(): ham() Cython-0.23.4/Cython/Debugger/Tests/cfuncs.c0000644000175600017570000000010712606202452021721 0ustar jenkinsjenkins00000000000000void some_c_function(void) { int a, b, c; a = 1; b = 2; } Cython-0.23.4/Cython/Debugger/Tests/__init__.py0000644000175600017570000000001512606202452022403 0ustar jenkinsjenkins00000000000000# empty file Cython-0.23.4/Cython/Debugger/Tests/TestLibCython.py0000644000175600017570000002031612606202452023405 0ustar jenkinsjenkins00000000000000 import os import re import sys import shutil import warnings import textwrap import unittest import tempfile import subprocess #import distutils.core #from distutils import sysconfig from distutils import ccompiler import runtests import Cython.Distutils.extension import Cython.Distutils.build_ext from Cython.Debugger import Cygdb as cygdb root = os.path.dirname(os.path.abspath(__file__)) codefile = os.path.join(root, 'codefile') cfuncs_file = os.path.join(root, 'cfuncs.c') with open(codefile) as f: source_to_lineno = dict((line.strip(), i + 1) for i, line in enumerate(f)) # Cython.Distutils.__init__ imports build_ext from build_ext which means we # can't access the module anymore. Get it from sys.modules instead. build_ext = sys.modules['Cython.Distutils.build_ext'] have_gdb = None def test_gdb(): global have_gdb if have_gdb is not None: return have_gdb have_gdb = False try: p = subprocess.Popen(['gdb', '-nx', '--version'], stdout=subprocess.PIPE) except OSError: # gdb not found gdb_version = None else: stdout, _ = p.communicate() # Based on Lib/test/test_gdb.py regex = "GNU gdb [^\d]*(\d+)\.(\d+)" gdb_version = re.match(regex, stdout.decode('ascii', 'ignore')) if gdb_version: gdb_version_number = list(map(int, gdb_version.groups())) if gdb_version_number >= [7, 2]: have_gdb = True with tempfile.NamedTemporaryFile(mode='w+') as python_version_script: python_version_script.write( 'python import sys; print("%s %s" % sys.version_info[:2])') python_version_script.flush() p = subprocess.Popen(['gdb', '-batch', '-x', python_version_script.name], stdout=subprocess.PIPE) stdout, _ = p.communicate() try: internal_python_version = list(map(int, stdout.decode('ascii', 'ignore').split())) if internal_python_version < [2, 6]: have_gdb = False except ValueError: have_gdb = False if not have_gdb: warnings.warn('Skipping gdb tests, need gdb >= 7.2 with Python >= 2.6') return have_gdb class DebuggerTestCase(unittest.TestCase): def setUp(self): """ Run gdb and have cygdb import the debug information from the code defined in TestParseTreeTransforms's setUp method """ if not test_gdb(): return self.tempdir = tempfile.mkdtemp() self.destfile = os.path.join(self.tempdir, 'codefile.pyx') self.debug_dest = os.path.join(self.tempdir, 'cython_debug', 'cython_debug_info_codefile') self.cfuncs_destfile = os.path.join(self.tempdir, 'cfuncs') self.cwd = os.getcwd() try: os.chdir(self.tempdir) shutil.copy(codefile, self.destfile) shutil.copy(cfuncs_file, self.cfuncs_destfile + '.c') compiler = ccompiler.new_compiler() compiler.compile(['cfuncs.c'], debug=True, extra_postargs=['-fPIC']) opts = dict( test_directory=self.tempdir, module='codefile', ) optimization_disabler = build_ext.Optimization() cython_compile_testcase = runtests.CythonCompileTestCase( workdir=self.tempdir, # we clean up everything (not only compiled files) cleanup_workdir=False, tags=runtests.parse_tags(codefile), **opts ) new_stderr = open(os.devnull, 'w') stderr = sys.stderr sys.stderr = new_stderr optimization_disabler.disable_optimization() try: cython_compile_testcase.run_cython( targetdir=self.tempdir, incdir=None, annotate=False, extra_compile_options={ 'gdb_debug':True, 'output_dir':self.tempdir, }, **opts ) cython_compile_testcase.run_distutils( incdir=None, workdir=self.tempdir, extra_extension_args={'extra_objects':['cfuncs.o']}, **opts ) finally: optimization_disabler.restore_state() sys.stderr = stderr new_stderr.close() # ext = Cython.Distutils.extension.Extension( # 'codefile', # ['codefile.pyx'], # cython_gdb=True, # extra_objects=['cfuncs.o']) # # distutils.core.setup( # script_args=['build_ext', '--inplace'], # ext_modules=[ext], # cmdclass=dict(build_ext=Cython.Distutils.build_ext) # ) except: os.chdir(self.cwd) raise def tearDown(self): if not test_gdb(): return os.chdir(self.cwd) shutil.rmtree(self.tempdir) class GdbDebuggerTestCase(DebuggerTestCase): def setUp(self): if not test_gdb(): return super(GdbDebuggerTestCase, self).setUp() prefix_code = textwrap.dedent('''\ python import os import sys import traceback def excepthook(type, value, tb): traceback.print_exception(type, value, tb) sys.stderr.flush() sys.stdout.flush() os._exit(1) sys.excepthook = excepthook # Have tracebacks end up on sys.stderr (gdb replaces sys.stderr # with an object that calls gdb.write()) sys.stderr = sys.__stderr__ end ''') code = textwrap.dedent('''\ python from Cython.Debugger.Tests import test_libcython_in_gdb test_libcython_in_gdb.main(version=%r) end ''' % (sys.version_info[:2],)) self.gdb_command_file = cygdb.make_command_file(self.tempdir, prefix_code) with open(self.gdb_command_file, 'a') as f: f.write(code) args = ['gdb', '-batch', '-x', self.gdb_command_file, '-n', '--args', sys.executable, '-c', 'import codefile'] paths = [] path = os.environ.get('PYTHONPATH') if path: paths.append(path) paths.append(os.path.dirname(os.path.dirname( os.path.abspath(Cython.__file__)))) env = dict(os.environ, PYTHONPATH=os.pathsep.join(paths)) self.p = subprocess.Popen( args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) def tearDown(self): if not test_gdb(): return try: super(GdbDebuggerTestCase, self).tearDown() if self.p: try: self.p.stdout.close() except: pass try: self.p.stderr.close() except: pass self.p.wait() finally: os.remove(self.gdb_command_file) class TestAll(GdbDebuggerTestCase): def test_all(self): if not test_gdb(): return out, err = self.p.communicate() out = out.decode('UTF-8') err = err.decode('UTF-8') exit_status = self.p.returncode if exit_status == 1: sys.stderr.write(out) sys.stderr.write(err) elif exit_status >= 2: border = u'*' * 30 start = u'%s v INSIDE GDB v %s' % (border, border) stderr = u'%s v STDERR v %s' % (border, border) end = u'%s ^ INSIDE GDB ^ %s' % (border, border) errmsg = u'\n%s\n%s%s\n%s%s' % (start, out, stderr, err, end) sys.stderr.write(errmsg) # FIXME: re-enable this to make the test fail on internal failures #self.assertEqual(exit_status, 0) if __name__ == '__main__': unittest.main() Cython-0.23.4/Cython/Compiler/0000755000175600017570000000000012606202455017225 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Compiler/__init__.py0000644000175600017570000000001512606202452021327 0ustar jenkinsjenkins00000000000000# empty file Cython-0.23.4/Cython/Compiler/Visitor.py0000644000175600017570000007040412606202452021240 0ustar jenkinsjenkins00000000000000# cython: infer_types=True # # Tree visitor and transform framework # from __future__ import absolute_import, print_function import sys import inspect from . import TypeSlots from . import Builtin from . import Nodes from . import ExprNodes from . import Errors from . import DebugFlags from . import Future import cython cython.declare(_PRINTABLE=tuple) if sys.version_info[0] >= 3: _PRINTABLE = (bytes, str, int, float) else: _PRINTABLE = (str, unicode, long, int, float) class TreeVisitor(object): """ Base class for writing visitors for a Cython tree, contains utilities for recursing such trees using visitors. Each node is expected to have a child_attrs iterable containing the names of attributes containing child nodes or lists of child nodes. Lists are not considered part of the tree structure (i.e. contained nodes are considered direct children of the parent node). visit_children visits each of the children of a given node (see the visit_children documentation). When recursing the tree using visit_children, an attribute access_path is maintained which gives information about the current location in the tree as a stack of tuples: (parent_node, attrname, index), representing the node, attribute and optional list index that was taken in each step in the path to the current node. Example: >>> class SampleNode(object): ... child_attrs = ["head", "body"] ... def __init__(self, value, head=None, body=None): ... self.value = value ... self.head = head ... self.body = body ... def __repr__(self): return "SampleNode(%s)" % self.value ... >>> tree = SampleNode(0, SampleNode(1), [SampleNode(2), SampleNode(3)]) >>> class MyVisitor(TreeVisitor): ... def visit_SampleNode(self, node): ... print("in %s %s" % (node.value, self.access_path)) ... self.visitchildren(node) ... print("out %s" % node.value) ... >>> MyVisitor().visit(tree) in 0 [] in 1 [(SampleNode(0), 'head', None)] out 1 in 2 [(SampleNode(0), 'body', 0)] out 2 in 3 [(SampleNode(0), 'body', 1)] out 3 out 0 """ def __init__(self): super(TreeVisitor, self).__init__() self.dispatch_table = {} self.access_path = [] def dump_node(self, node, indent=0): ignored = list(node.child_attrs or []) + [u'child_attrs', u'pos', u'gil_message', u'cpp_message', u'subexprs'] values = [] pos = getattr(node, 'pos', None) if pos: source = pos[0] if source: import os.path source = os.path.basename(source.get_description()) values.append(u'%s:%s:%s' % (source, pos[1], pos[2])) attribute_names = dir(node) attribute_names.sort() for attr in attribute_names: if attr in ignored: continue if attr.startswith(u'_') or attr.endswith(u'_'): continue try: value = getattr(node, attr) except AttributeError: continue if value is None or value == 0: continue elif isinstance(value, list): value = u'[...]/%d' % len(value) elif not isinstance(value, _PRINTABLE): continue else: value = repr(value) values.append(u'%s = %s' % (attr, value)) return u'%s(%s)' % (node.__class__.__name__, u',\n '.join(values)) def _find_node_path(self, stacktrace): import os.path last_traceback = stacktrace nodes = [] while hasattr(stacktrace, 'tb_frame'): frame = stacktrace.tb_frame node = frame.f_locals.get(u'self') if isinstance(node, Nodes.Node): code = frame.f_code method_name = code.co_name pos = (os.path.basename(code.co_filename), frame.f_lineno) nodes.append((node, method_name, pos)) last_traceback = stacktrace stacktrace = stacktrace.tb_next return (last_traceback, nodes) def _raise_compiler_error(self, child, e): import sys trace = [''] for parent, attribute, index in self.access_path: node = getattr(parent, attribute) if index is None: index = '' else: node = node[index] index = u'[%d]' % index trace.append(u'%s.%s%s = %s' % ( parent.__class__.__name__, attribute, index, self.dump_node(node))) stacktrace, called_nodes = self._find_node_path(sys.exc_info()[2]) last_node = child for node, method_name, pos in called_nodes: last_node = node trace.append(u"File '%s', line %d, in %s: %s" % ( pos[0], pos[1], method_name, self.dump_node(node))) raise Errors.CompilerCrash( getattr(last_node, 'pos', None), self.__class__.__name__, u'\n'.join(trace), e, stacktrace) @cython.final def find_handler(self, obj): # to resolve, try entire hierarchy cls = type(obj) pattern = "visit_%s" mro = inspect.getmro(cls) handler_method = None for mro_cls in mro: handler_method = getattr(self, pattern % mro_cls.__name__, None) if handler_method is not None: return handler_method print(type(self), cls) if self.access_path: print(self.access_path) print(self.access_path[-1][0].pos) print(self.access_path[-1][0].__dict__) raise RuntimeError("Visitor %r does not accept object: %s" % (self, obj)) def visit(self, obj): return self._visit(obj) @cython.final def _visit(self, obj): try: try: handler_method = self.dispatch_table[type(obj)] except KeyError: handler_method = self.find_handler(obj) self.dispatch_table[type(obj)] = handler_method return handler_method(obj) except Errors.CompileError: raise except Errors.AbortError: raise except Exception as e: if DebugFlags.debug_no_exception_intercept: raise self._raise_compiler_error(obj, e) @cython.final def _visitchild(self, child, parent, attrname, idx): self.access_path.append((parent, attrname, idx)) result = self._visit(child) self.access_path.pop() return result def visitchildren(self, parent, attrs=None): return self._visitchildren(parent, attrs) @cython.final @cython.locals(idx=int) def _visitchildren(self, parent, attrs): """ Visits the children of the given parent. If parent is None, returns immediately (returning None). The return value is a dictionary giving the results for each child (mapping the attribute name to either the return value or a list of return values (in the case of multiple children in an attribute)). """ if parent is None: return None result = {} for attr in parent.child_attrs: if attrs is not None and attr not in attrs: continue child = getattr(parent, attr) if child is not None: if type(child) is list: childretval = [self._visitchild(x, parent, attr, idx) for idx, x in enumerate(child)] else: childretval = self._visitchild(child, parent, attr, None) assert not isinstance(childretval, list), 'Cannot insert list here: %s in %r' % (attr, parent) result[attr] = childretval return result class VisitorTransform(TreeVisitor): """ A tree transform is a base class for visitors that wants to do stream processing of the structure (rather than attributes etc.) of a tree. It implements __call__ to simply visit the argument node. It requires the visitor methods to return the nodes which should take the place of the visited node in the result tree (which can be the same or one or more replacement). Specifically, if the return value from a visitor method is: - [] or None; the visited node will be removed (set to None if an attribute and removed if in a list) - A single node; the visited node will be replaced by the returned node. - A list of nodes; the visited nodes will be replaced by all the nodes in the list. This will only work if the node was already a member of a list; if it was not, an exception will be raised. (Typically you want to ensure that you are within a StatListNode or similar before doing this.) """ def visitchildren(self, parent, attrs=None): result = self._visitchildren(parent, attrs) for attr, newnode in result.items(): if type(newnode) is not list: setattr(parent, attr, newnode) else: # Flatten the list one level and remove any None newlist = [] for x in newnode: if x is not None: if type(x) is list: newlist += x else: newlist.append(x) setattr(parent, attr, newlist) return result def recurse_to_children(self, node): self.visitchildren(node) return node def __call__(self, root): return self._visit(root) class CythonTransform(VisitorTransform): """ Certain common conventions and utilities for Cython transforms. - Sets up the context of the pipeline in self.context - Tracks directives in effect in self.current_directives """ def __init__(self, context): super(CythonTransform, self).__init__() self.context = context def __call__(self, node): from . import ModuleNode if isinstance(node, ModuleNode.ModuleNode): self.current_directives = node.directives return super(CythonTransform, self).__call__(node) def visit_CompilerDirectivesNode(self, node): old = self.current_directives self.current_directives = node.directives self.visitchildren(node) self.current_directives = old return node def visit_Node(self, node): self.visitchildren(node) return node class ScopeTrackingTransform(CythonTransform): # Keeps track of type of scopes #scope_type: can be either of 'module', 'function', 'cclass', 'pyclass', 'struct' #scope_node: the node that owns the current scope def visit_ModuleNode(self, node): self.scope_type = 'module' self.scope_node = node self.visitchildren(node) return node def visit_scope(self, node, scope_type): prev = self.scope_type, self.scope_node self.scope_type = scope_type self.scope_node = node self.visitchildren(node) self.scope_type, self.scope_node = prev return node def visit_CClassDefNode(self, node): return self.visit_scope(node, 'cclass') def visit_PyClassDefNode(self, node): return self.visit_scope(node, 'pyclass') def visit_FuncDefNode(self, node): return self.visit_scope(node, 'function') def visit_CStructOrUnionDefNode(self, node): return self.visit_scope(node, 'struct') class EnvTransform(CythonTransform): """ This transformation keeps a stack of the environments. """ def __call__(self, root): self.env_stack = [] self.enter_scope(root, root.scope) return super(EnvTransform, self).__call__(root) def current_env(self): return self.env_stack[-1][1] def current_scope_node(self): return self.env_stack[-1][0] def global_scope(self): return self.current_env().global_scope() def enter_scope(self, node, scope): self.env_stack.append((node, scope)) def exit_scope(self): self.env_stack.pop() def visit_FuncDefNode(self, node): self.enter_scope(node, node.local_scope) self.visitchildren(node) self.exit_scope() return node def visit_GeneratorBodyDefNode(self, node): self.visitchildren(node) return node def visit_ClassDefNode(self, node): self.enter_scope(node, node.scope) self.visitchildren(node) self.exit_scope() return node def visit_CStructOrUnionDefNode(self, node): self.enter_scope(node, node.scope) self.visitchildren(node) self.exit_scope() return node def visit_ScopedExprNode(self, node): if node.expr_scope: self.enter_scope(node, node.expr_scope) self.visitchildren(node) self.exit_scope() else: self.visitchildren(node) return node def visit_CArgDeclNode(self, node): # default arguments are evaluated in the outer scope if node.default: attrs = [ attr for attr in node.child_attrs if attr != 'default' ] self.visitchildren(node, attrs) self.enter_scope(node, self.current_env().outer_scope) self.visitchildren(node, ('default',)) self.exit_scope() else: self.visitchildren(node) return node class NodeRefCleanupMixin(object): """ Clean up references to nodes that were replaced. NOTE: this implementation assumes that the replacement is done first, before hitting any further references during normal tree traversal. This needs to be arranged by calling "self.visitchildren()" at a proper place in the transform and by ordering the "child_attrs" of nodes appropriately. """ def __init__(self, *args): super(NodeRefCleanupMixin, self).__init__(*args) self._replacements = {} def visit_CloneNode(self, node): arg = node.arg if arg not in self._replacements: self.visitchildren(arg) node.arg = self._replacements.get(arg, arg) return node def visit_ResultRefNode(self, node): expr = node.expression if expr is None or expr not in self._replacements: self.visitchildren(node) expr = node.expression if expr is not None: node.expression = self._replacements.get(expr, expr) return node def replace(self, node, replacement): self._replacements[node] = replacement return replacement find_special_method_for_binary_operator = { '<': '__lt__', '<=': '__le__', '==': '__eq__', '!=': '__ne__', '>=': '__ge__', '>': '__gt__', '+': '__add__', '&': '__and__', '/': '__div__', '//': '__floordiv__', '<<': '__lshift__', '%': '__mod__', '*': '__mul__', '|': '__or__', '**': '__pow__', '>>': '__rshift__', '-': '__sub__', '^': '__xor__', 'in': '__contains__', }.get find_special_method_for_unary_operator = { 'not': '__not__', '~': '__inv__', '-': '__neg__', '+': '__pos__', }.get class MethodDispatcherTransform(EnvTransform): """ Base class for transformations that want to intercept on specific builtin functions or methods of builtin types, including special methods triggered by Python operators. Must run after declaration analysis when entries were assigned. Naming pattern for handler methods is as follows: * builtin functions: _handle_(general|simple|any)_function_NAME * builtin methods: _handle_(general|simple|any)_method_TYPENAME_METHODNAME """ # only visit call nodes and Python operations def visit_GeneralCallNode(self, node): self.visitchildren(node) function = node.function if not function.type.is_pyobject: return node arg_tuple = node.positional_args if not isinstance(arg_tuple, ExprNodes.TupleNode): return node keyword_args = node.keyword_args if keyword_args and not isinstance(keyword_args, ExprNodes.DictNode): # can't handle **kwargs return node args = arg_tuple.args return self._dispatch_to_handler(node, function, args, keyword_args) def visit_SimpleCallNode(self, node): self.visitchildren(node) function = node.function if function.type.is_pyobject: arg_tuple = node.arg_tuple if not isinstance(arg_tuple, ExprNodes.TupleNode): return node args = arg_tuple.args else: args = node.args return self._dispatch_to_handler(node, function, args, None) def visit_PrimaryCmpNode(self, node): if node.cascade: # not currently handled below self.visitchildren(node) return node return self._visit_binop_node(node) def visit_BinopNode(self, node): return self._visit_binop_node(node) def _visit_binop_node(self, node): self.visitchildren(node) # FIXME: could special case 'not_in' special_method_name = find_special_method_for_binary_operator(node.operator) if special_method_name: operand1, operand2 = node.operand1, node.operand2 if special_method_name == '__contains__': operand1, operand2 = operand2, operand1 elif special_method_name == '__div__': if Future.division in self.current_env().global_scope().context.future_directives: special_method_name = '__truediv__' obj_type = operand1.type if obj_type.is_builtin_type: type_name = obj_type.name else: type_name = "object" # safety measure node = self._dispatch_to_method_handler( special_method_name, None, False, type_name, node, None, [operand1, operand2], None) return node def visit_UnopNode(self, node): self.visitchildren(node) special_method_name = find_special_method_for_unary_operator(node.operator) if special_method_name: operand = node.operand obj_type = operand.type if obj_type.is_builtin_type: type_name = obj_type.name else: type_name = "object" # safety measure node = self._dispatch_to_method_handler( special_method_name, None, False, type_name, node, None, [operand], None) return node ### dispatch to specific handlers def _find_handler(self, match_name, has_kwargs): call_type = has_kwargs and 'general' or 'simple' handler = getattr(self, '_handle_%s_%s' % (call_type, match_name), None) if handler is None: handler = getattr(self, '_handle_any_%s' % match_name, None) return handler def _delegate_to_assigned_value(self, node, function, arg_list, kwargs): assignment = function.cf_state[0] value = assignment.rhs if value.is_name: if not value.entry or len(value.entry.cf_assignments) > 1: # the variable might have been reassigned => play safe return node elif value.is_attribute and value.obj.is_name: if not value.obj.entry or len(value.obj.entry.cf_assignments) > 1: # the underlying variable might have been reassigned => play safe return node else: return node return self._dispatch_to_handler( node, value, arg_list, kwargs) def _dispatch_to_handler(self, node, function, arg_list, kwargs): if function.is_name: # we only consider functions that are either builtin # Python functions or builtins that were already replaced # into a C function call (defined in the builtin scope) if not function.entry: return node is_builtin = ( function.entry.is_builtin or function.entry is self.current_env().builtin_scope().lookup_here(function.name)) if not is_builtin: if function.cf_state and function.cf_state.is_single: # we know the value of the variable # => see if it's usable instead return self._delegate_to_assigned_value( node, function, arg_list, kwargs) return node function_handler = self._find_handler( "function_%s" % function.name, kwargs) if function_handler is None: return self._handle_function(node, function.name, function, arg_list, kwargs) if kwargs: return function_handler(node, function, arg_list, kwargs) else: return function_handler(node, function, arg_list) elif function.is_attribute: attr_name = function.attribute if function.type.is_pyobject: self_arg = function.obj elif node.self and function.entry: entry = function.entry.as_variable if not entry or not entry.is_builtin: return node # C implementation of a Python builtin method - see if we find further matches self_arg = node.self arg_list = arg_list[1:] # drop CloneNode of self argument else: return node obj_type = self_arg.type is_unbound_method = False if obj_type.is_builtin_type: if (obj_type is Builtin.type_type and self_arg.is_name and arg_list and arg_list[0].type.is_pyobject): # calling an unbound method like 'list.append(L,x)' # (ignoring 'type.mro()' here ...) type_name = self_arg.name self_arg = None is_unbound_method = True else: type_name = obj_type.name else: type_name = "object" # safety measure return self._dispatch_to_method_handler( attr_name, self_arg, is_unbound_method, type_name, node, function, arg_list, kwargs) else: return node def _dispatch_to_method_handler(self, attr_name, self_arg, is_unbound_method, type_name, node, function, arg_list, kwargs): method_handler = self._find_handler( "method_%s_%s" % (type_name, attr_name), kwargs) if method_handler is None: if (attr_name in TypeSlots.method_name_to_slot or attr_name == '__new__'): method_handler = self._find_handler( "slot%s" % attr_name, kwargs) if method_handler is None: return self._handle_method( node, type_name, attr_name, function, arg_list, is_unbound_method, kwargs) if self_arg is not None: arg_list = [self_arg] + list(arg_list) if kwargs: result = method_handler( node, function, arg_list, is_unbound_method, kwargs) else: result = method_handler( node, function, arg_list, is_unbound_method) return result def _handle_function(self, node, function_name, function, arg_list, kwargs): """Fallback handler""" return node def _handle_method(self, node, type_name, attr_name, function, arg_list, is_unbound_method, kwargs): """Fallback handler""" return node class RecursiveNodeReplacer(VisitorTransform): """ Recursively replace all occurrences of a node in a subtree by another node. """ def __init__(self, orig_node, new_node): super(RecursiveNodeReplacer, self).__init__() self.orig_node, self.new_node = orig_node, new_node def visit_CloneNode(self, node): if node is self.orig_node: return self.new_node if node.arg is self.orig_node: node.arg = self.new_node return node def visit_Node(self, node): self.visitchildren(node) if node is self.orig_node: return self.new_node else: return node def recursively_replace_node(tree, old_node, new_node): replace_in = RecursiveNodeReplacer(old_node, new_node) replace_in(tree) class NodeFinder(TreeVisitor): """ Find out if a node appears in a subtree. """ def __init__(self, node): super(NodeFinder, self).__init__() self.node = node self.found = False def visit_Node(self, node): if self.found: pass # short-circuit elif node is self.node: self.found = True else: self._visitchildren(node, None) def tree_contains(tree, node): finder = NodeFinder(node) finder.visit(tree) return finder.found # Utils def replace_node(ptr, value): """Replaces a node. ptr is of the form used on the access path stack (parent, attrname, listidx|None) """ parent, attrname, listidx = ptr if listidx is None: setattr(parent, attrname, value) else: getattr(parent, attrname)[listidx] = value class PrintTree(TreeVisitor): """Prints a representation of the tree to standard output. Subclass and override repr_of to provide more information about nodes. """ def __init__(self, start=None, end=None): TreeVisitor.__init__(self) self._indent = "" if start is not None or end is not None: self._line_range = (start or 0, end or 2**30) else: self._line_range = None def indent(self): self._indent += " " def unindent(self): self._indent = self._indent[:-2] def __call__(self, tree, phase=None): print("Parse tree dump at phase '%s'" % phase) self.visit(tree) return tree # Don't do anything about process_list, the defaults gives # nice-looking name[idx] nodes which will visually appear # under the parent-node, not displaying the list itself in # the hierarchy. def visit_Node(self, node): self._print_node(node) self.indent() self.visitchildren(node) self.unindent() return node def visit_CloneNode(self, node): self._print_node(node) self.indent() line = node.pos[1] if self._line_range is None or self._line_range[0] <= line <= self._line_range[1]: print("%s- %s: %s" % (self._indent, 'arg', self.repr_of(node.arg))) self.indent() self.visitchildren(node.arg) self.unindent() self.unindent() return node def _print_node(self, node): line = node.pos[1] if self._line_range is None or self._line_range[0] <= line <= self._line_range[1]: if len(self.access_path) == 0: name = "(root)" else: parent, attr, idx = self.access_path[-1] if idx is not None: name = "%s[%d]" % (attr, idx) else: name = attr print("%s- %s: %s" % (self._indent, name, self.repr_of(node))) def repr_of(self, node): if node is None: return "(none)" else: result = node.__class__.__name__ if isinstance(node, ExprNodes.NameNode): result += "(type=%s, name=\"%s\")" % (repr(node.type), node.name) elif isinstance(node, Nodes.DefNode): result += "(name=\"%s\")" % node.name elif isinstance(node, ExprNodes.ExprNode): t = node.type result += "(type=%s)" % repr(t) elif node.pos: pos = node.pos path = pos[0].get_description() if '/' in path: path = path.split('/')[-1] if '\\' in path: path = path.split('\\')[-1] result += "(pos=(%s:%s:%s))" % (path, pos[1], pos[2]) return result if __name__ == "__main__": import doctest doctest.testmod() Cython-0.23.4/Cython/Compiler/Visitor.pxd0000644000175600017570000000312512606202452021377 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import cimport cython cdef class TreeVisitor: cdef public list access_path cdef dict dispatch_table cpdef visit(self, obj) cdef _visit(self, obj) cdef find_handler(self, obj) cdef _visitchild(self, child, parent, attrname, idx) cdef dict _visitchildren(self, parent, attrs) cpdef visitchildren(self, parent, attrs=*) cdef class VisitorTransform(TreeVisitor): cpdef visitchildren(self, parent, attrs=*) cpdef recurse_to_children(self, node) cdef class CythonTransform(VisitorTransform): cdef public context cdef public current_directives cdef class ScopeTrackingTransform(CythonTransform): cdef public scope_type cdef public scope_node cdef visit_scope(self, node, scope_type) cdef class EnvTransform(CythonTransform): cdef public list env_stack cdef class MethodDispatcherTransform(EnvTransform): @cython.final cdef _visit_binop_node(self, node) @cython.final cdef _find_handler(self, match_name, bint has_kwargs) @cython.final cdef _delegate_to_assigned_value(self, node, function, arg_list, kwargs) @cython.final cdef _dispatch_to_handler(self, node, function, arg_list, kwargs) @cython.final cdef _dispatch_to_method_handler(self, attr_name, self_arg, is_unbound_method, type_name, node, function, arg_list, kwargs) cdef class RecursiveNodeReplacer(VisitorTransform): cdef public orig_node cdef public new_node cdef class NodeFinder(TreeVisitor): cdef node cdef public bint found Cython-0.23.4/Cython/Compiler/Version.py0000644000175600017570000000026512606202452021224 0ustar jenkinsjenkins00000000000000# for backwards compatibility from __future__ import absolute_import from .. import __version__ as version # For 'generated by' header line in C files. watermark = str(version) Cython-0.23.4/Cython/Compiler/UtilityCode.py0000644000175600017570000002000312606202452022025 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import from .TreeFragment import parse_from_strings, StringParseContext from . import Symtab from . import Naming from . import Code class NonManglingModuleScope(Symtab.ModuleScope): cpp = False def __init__(self, prefix, *args, **kw): self.prefix = prefix self.cython_scope = None Symtab.ModuleScope.__init__(self, *args, **kw) def add_imported_entry(self, name, entry, pos): entry.used = True return super(NonManglingModuleScope, self).add_imported_entry( name, entry, pos) def mangle(self, prefix, name=None): if name: if prefix in (Naming.typeobj_prefix, Naming.func_prefix, Naming.var_prefix, Naming.pyfunc_prefix): # Functions, classes etc. gets a manually defined prefix easily # manually callable instead (the one passed to CythonUtilityCode) prefix = self.prefix return "%s%s" % (prefix, name) else: return Symtab.ModuleScope.mangle(self, prefix) class CythonUtilityCodeContext(StringParseContext): scope = None def find_module(self, module_name, relative_to=None, pos=None, need_pxd=True, absolute_fallback=True): if relative_to: raise AssertionError("Relative imports not supported in utility code.") if module_name != self.module_name: if module_name not in self.modules: raise AssertionError("Only the cython cimport is supported.") else: return self.modules[module_name] if self.scope is None: self.scope = NonManglingModuleScope( self.prefix, module_name, parent_module=None, context=self) return self.scope class CythonUtilityCode(Code.UtilityCodeBase): """ Utility code written in the Cython language itself. The @cname decorator can set the cname for a function, method of cdef class. Functions decorated with @cname('c_func_name') get the given cname. For cdef classes the rules are as follows: obj struct -> _obj obj type ptr -> _type methods -> _ For methods the cname decorator is optional, but without the decorator the methods will not be prototyped. See Cython.Compiler.CythonScope and tests/run/cythonscope.pyx for examples. """ is_cython_utility = True def __init__(self, impl, name="__pyxutil", prefix="", requires=None, file=None, from_scope=None, context=None, compiler_directives=None, outer_module_scope=None): # 1) We need to delay the parsing/processing, so that all modules can be # imported without import loops # 2) The same utility code object can be used for multiple source files; # while the generated node trees can be altered in the compilation of a # single file. # Hence, delay any processing until later. if context is not None: impl = Code.sub_tempita(impl, context, file, name) self.impl = impl self.name = name self.file = file self.prefix = prefix self.requires = requires or [] self.from_scope = from_scope self.outer_module_scope = outer_module_scope self.compiler_directives = compiler_directives def __eq__(self, other): if isinstance(other, CythonUtilityCode): return self._equality_params() == other._equality_params() else: return False def _equality_params(self): outer_scope = self.outer_module_scope while isinstance(outer_scope, NonManglingModuleScope): outer_scope = outer_scope.outer_scope return self.impl, outer_scope, self.compiler_directives def __hash__(self): return hash(self.impl) def get_tree(self, entries_only=False, cython_scope=None): from .AnalysedTreeTransforms import AutoTestDictTransform # The AutoTestDictTransform creates the statement "__test__ = {}", # which when copied into the main ModuleNode overwrites # any __test__ in user code; not desired excludes = [AutoTestDictTransform] from . import Pipeline, ParseTreeTransforms context = CythonUtilityCodeContext( self.name, compiler_directives=self.compiler_directives) context.prefix = self.prefix context.cython_scope = cython_scope #context = StringParseContext(self.name) tree = parse_from_strings( self.name, self.impl, context=context, allow_struct_enum_decorator=True) pipeline = Pipeline.create_pipeline(context, 'pyx', exclude_classes=excludes) if entries_only: p = [] for t in pipeline: p.append(t) if isinstance(p, ParseTreeTransforms.AnalyseDeclarationsTransform): break pipeline = p transform = ParseTreeTransforms.CnameDirectivesTransform(context) # InterpretCompilerDirectives already does a cdef declarator check #before = ParseTreeTransforms.DecoratorTransform before = ParseTreeTransforms.InterpretCompilerDirectives pipeline = Pipeline.insert_into_pipeline(pipeline, transform, before=before) if self.from_scope: def scope_transform(module_node): module_node.scope.merge_in(self.from_scope) return module_node transform = ParseTreeTransforms.AnalyseDeclarationsTransform pipeline = Pipeline.insert_into_pipeline(pipeline, scope_transform, before=transform) if self.outer_module_scope: # inject outer module between utility code module and builtin module def scope_transform(module_node): module_node.scope.outer_scope = self.outer_module_scope return module_node transform = ParseTreeTransforms.AnalyseDeclarationsTransform pipeline = Pipeline.insert_into_pipeline(pipeline, scope_transform, before=transform) (err, tree) = Pipeline.run_pipeline(pipeline, tree, printtree=False) assert not err, err return tree def put_code(self, output): pass @classmethod def load_as_string(cls, util_code_name, from_file=None, **kwargs): """ Load a utility code as a string. Returns (proto, implementation) """ util = cls.load(util_code_name, from_file, **kwargs) return util.proto, util.impl # keep line numbers => no lstrip() def declare_in_scope(self, dest_scope, used=False, cython_scope=None, whitelist=None): """ Declare all entries from the utility code in dest_scope. Code will only be included for used entries. If module_name is given, declare the type entries with that name. """ tree = self.get_tree(entries_only=True, cython_scope=cython_scope) entries = tree.scope.entries entries.pop('__name__') entries.pop('__file__') entries.pop('__builtins__') entries.pop('__doc__') for name, entry in entries.items(): entry.utility_code_definition = self entry.used = used original_scope = tree.scope dest_scope.merge_in(original_scope, merge_unused=True, whitelist=whitelist) tree.scope = dest_scope for dep in self.requires: if dep.is_cython_utility: dep.declare_in_scope(dest_scope) return original_scope def declare_declarations_in_scope(declaration_string, env, private_type=True, *args, **kwargs): """ Declare some declarations given as Cython code in declaration_string in scope env. """ CythonUtilityCode(declaration_string, *args, **kwargs).declare_in_scope(env) Cython-0.23.4/Cython/Compiler/UtilNodes.py0000644000175600017570000002725212606202452021512 0ustar jenkinsjenkins00000000000000# # Nodes used as utilities and support for transforms etc. # These often make up sets including both Nodes and ExprNodes # so it is convenient to have them in a seperate module. # from __future__ import absolute_import from . import Nodes from . import ExprNodes from .Nodes import Node from .ExprNodes import AtomicExprNode from .PyrexTypes import c_ptr_type class TempHandle(object): # THIS IS DEPRECATED, USE LetRefNode instead temp = None needs_xdecref = False def __init__(self, type, needs_cleanup=None): self.type = type if needs_cleanup is None: self.needs_cleanup = type.is_pyobject else: self.needs_cleanup = needs_cleanup def ref(self, pos): return TempRefNode(pos, handle=self, type=self.type) def cleanup_ref(self, pos): return CleanupTempRefNode(pos, handle=self, type=self.type) class TempRefNode(AtomicExprNode): # THIS IS DEPRECATED, USE LetRefNode instead # handle TempHandle def analyse_types(self, env): assert self.type == self.handle.type return self def analyse_target_types(self, env): assert self.type == self.handle.type return self def analyse_target_declaration(self, env): pass def calculate_result_code(self): result = self.handle.temp if result is None: result = "" # might be called and overwritten return result def generate_result_code(self, code): pass def generate_assignment_code(self, rhs, code, overloaded_assignment=False): if self.type.is_pyobject: rhs.make_owned_reference(code) # TODO: analyse control flow to see if this is necessary code.put_xdecref(self.result(), self.ctype()) code.putln('%s = %s;' % ( self.result(), rhs.result() if overloaded_assignment else rhs.result_as(self.ctype()), )) rhs.generate_post_assignment_code(code) rhs.free_temps(code) class CleanupTempRefNode(TempRefNode): # THIS IS DEPRECATED, USE LetRefNode instead # handle TempHandle def generate_assignment_code(self, rhs, code, overloaded_assignment=False): pass def generate_execution_code(self, code): if self.type.is_pyobject: code.put_decref_clear(self.result(), self.type) self.handle.needs_cleanup = False class TempsBlockNode(Node): # THIS IS DEPRECATED, USE LetNode instead """ Creates a block which allocates temporary variables. This is used by transforms to output constructs that need to make use of a temporary variable. Simply pass the types of the needed temporaries to the constructor. The variables can be referred to using a TempRefNode (which can be constructed by calling get_ref_node). """ # temps [TempHandle] # body StatNode child_attrs = ["body"] def generate_execution_code(self, code): for handle in self.temps: handle.temp = code.funcstate.allocate_temp( handle.type, manage_ref=handle.needs_cleanup) self.body.generate_execution_code(code) for handle in self.temps: if handle.needs_cleanup: if handle.needs_xdecref: code.put_xdecref_clear(handle.temp, handle.type) else: code.put_decref_clear(handle.temp, handle.type) code.funcstate.release_temp(handle.temp) def analyse_declarations(self, env): self.body.analyse_declarations(env) def analyse_expressions(self, env): self.body = self.body.analyse_expressions(env) return self def generate_function_definitions(self, env, code): self.body.generate_function_definitions(env, code) def annotate(self, code): self.body.annotate(code) class ResultRefNode(AtomicExprNode): # A reference to the result of an expression. The result_code # must be set externally (usually a temp name). subexprs = [] lhs_of_first_assignment = False def __init__(self, expression=None, pos=None, type=None, may_hold_none=True, is_temp=False): self.expression = expression self.pos = None self.may_hold_none = may_hold_none if expression is not None: self.pos = expression.pos if hasattr(expression, "type"): self.type = expression.type if pos is not None: self.pos = pos if type is not None: self.type = type if is_temp: self.is_temp = True assert self.pos is not None def clone_node(self): # nothing to do here return self def type_dependencies(self, env): if self.expression: return self.expression.type_dependencies(env) else: return () def update_expression(self, expression): self.expression = expression if hasattr(expression, "type"): self.type = expression.type def analyse_types(self, env): if self.expression is not None: self.type = self.expression.type return self def infer_type(self, env): if self.type is not None: return self.type if self.expression is not None: if self.expression.type is not None: return self.expression.type return self.expression.infer_type(env) assert False, "cannot infer type of ResultRefNode" def may_be_none(self): if not self.type.is_pyobject: return False return self.may_hold_none def _DISABLED_may_be_none(self): # not sure if this is safe - the expression may not be the # only value that gets assigned if self.expression is not None: return self.expression.may_be_none() if self.type is not None: return self.type.is_pyobject return True # play safe def is_simple(self): return True def result(self): try: return self.result_code except AttributeError: if self.expression is not None: self.result_code = self.expression.result() return self.result_code def generate_evaluation_code(self, code): pass def generate_result_code(self, code): pass def generate_disposal_code(self, code): pass def generate_assignment_code(self, rhs, code, overloaded_assignment=False): if self.type.is_pyobject: rhs.make_owned_reference(code) if not self.lhs_of_first_assignment: code.put_decref(self.result(), self.ctype()) code.putln('%s = %s;' % ( self.result(), rhs.result() if overloaded_assignment else rhs.result_as(self.ctype()), )) rhs.generate_post_assignment_code(code) rhs.free_temps(code) def allocate_temps(self, env): pass def release_temp(self, env): pass def free_temps(self, code): pass class LetNodeMixin: def set_temp_expr(self, lazy_temp): self.lazy_temp = lazy_temp self.temp_expression = lazy_temp.expression def setup_temp_expr(self, code): self.temp_expression.generate_evaluation_code(code) self.temp_type = self.temp_expression.type if self.temp_type.is_array: self.temp_type = c_ptr_type(self.temp_type.base_type) self._result_in_temp = self.temp_expression.result_in_temp() if self._result_in_temp: self.temp = self.temp_expression.result() else: self.temp_expression.make_owned_reference(code) self.temp = code.funcstate.allocate_temp( self.temp_type, manage_ref=True) code.putln("%s = %s;" % (self.temp, self.temp_expression.result())) self.temp_expression.generate_disposal_code(code) self.temp_expression.free_temps(code) self.lazy_temp.result_code = self.temp def teardown_temp_expr(self, code): if self._result_in_temp: self.temp_expression.generate_disposal_code(code) self.temp_expression.free_temps(code) else: if self.temp_type.is_pyobject: code.put_decref_clear(self.temp, self.temp_type) code.funcstate.release_temp(self.temp) class EvalWithTempExprNode(ExprNodes.ExprNode, LetNodeMixin): # A wrapper around a subexpression that moves an expression into a # temp variable and provides it to the subexpression. subexprs = ['temp_expression', 'subexpression'] def __init__(self, lazy_temp, subexpression): self.set_temp_expr(lazy_temp) self.pos = subexpression.pos self.subexpression = subexpression # if called after type analysis, we already know the type here self.type = self.subexpression.type def infer_type(self, env): return self.subexpression.infer_type(env) def result(self): return self.subexpression.result() def analyse_types(self, env): self.temp_expression = self.temp_expression.analyse_types(env) self.lazy_temp.update_expression(self.temp_expression) # overwrite in case it changed self.subexpression = self.subexpression.analyse_types(env) self.type = self.subexpression.type return self def free_subexpr_temps(self, code): self.subexpression.free_temps(code) def generate_subexpr_disposal_code(self, code): self.subexpression.generate_disposal_code(code) def generate_evaluation_code(self, code): self.setup_temp_expr(code) self.subexpression.generate_evaluation_code(code) self.teardown_temp_expr(code) LetRefNode = ResultRefNode class LetNode(Nodes.StatNode, LetNodeMixin): # Implements a local temporary variable scope. Imagine this # syntax being present: # let temp = VALUE: # BLOCK (can modify temp) # if temp is an object, decref # # Usually used after analysis phase, but forwards analysis methods # to its children child_attrs = ['temp_expression', 'body'] def __init__(self, lazy_temp, body): self.set_temp_expr(lazy_temp) self.pos = body.pos self.body = body def analyse_declarations(self, env): self.temp_expression.analyse_declarations(env) self.body.analyse_declarations(env) def analyse_expressions(self, env): self.temp_expression = self.temp_expression.analyse_expressions(env) self.body = self.body.analyse_expressions(env) return self def generate_execution_code(self, code): self.setup_temp_expr(code) self.body.generate_execution_code(code) self.teardown_temp_expr(code) def generate_function_definitions(self, env, code): self.temp_expression.generate_function_definitions(env, code) self.body.generate_function_definitions(env, code) class TempResultFromStatNode(ExprNodes.ExprNode): # An ExprNode wrapper around a StatNode that executes the StatNode # body. Requires a ResultRefNode that it sets up to refer to its # own temp result. The StatNode must assign a value to the result # node, which then becomes the result of this node. subexprs = [] child_attrs = ['body'] def __init__(self, result_ref, body): self.result_ref = result_ref self.pos = body.pos self.body = body self.type = result_ref.type self.is_temp = 1 def analyse_declarations(self, env): self.body.analyse_declarations(env) def analyse_types(self, env): self.body = self.body.analyse_expressions(env) return self def generate_result_code(self, code): self.result_ref.result_code = self.result() self.body.generate_execution_code(code) Cython-0.23.4/Cython/Compiler/TypeSlots.py0000644000175600017570000010410612606202452021544 0ustar jenkinsjenkins00000000000000# # Tables describing slots in the CPython type object # and associated know-how. # from __future__ import absolute_import from . import Naming from . import PyrexTypes from . import StringEncoding invisible = ['__cinit__', '__dealloc__', '__richcmp__', '__nonzero__', '__bool__'] class Signature(object): # Method slot signature descriptor. # # has_dummy_arg boolean # has_generic_args boolean # fixed_arg_format string # ret_format string # error_value string # # The formats are strings made up of the following # characters: # # 'O' Python object # 'T' Python object of the type of 'self' # 'v' void # 'p' void * # 'P' void ** # 'i' int # 'b' bint # 'I' int * # 'l' long # 'f' float # 'd' double # 'h' Py_hash_t # 'z' Py_ssize_t # 'Z' Py_ssize_t * # 's' char * # 'S' char ** # 'r' int used only to signal exception # 'B' Py_buffer * # '-' dummy 'self' argument (not used) # '*' rest of args passed as generic Python # arg tuple and kw dict (must be last # char in format string) format_map = { 'O': PyrexTypes.py_object_type, 'v': PyrexTypes.c_void_type, 'p': PyrexTypes.c_void_ptr_type, 'P': PyrexTypes.c_void_ptr_ptr_type, 'i': PyrexTypes.c_int_type, 'b': PyrexTypes.c_bint_type, 'I': PyrexTypes.c_int_ptr_type, 'l': PyrexTypes.c_long_type, 'f': PyrexTypes.c_float_type, 'd': PyrexTypes.c_double_type, 'h': PyrexTypes.c_py_hash_t_type, 'z': PyrexTypes.c_py_ssize_t_type, 'Z': PyrexTypes.c_py_ssize_t_ptr_type, 's': PyrexTypes.c_char_ptr_type, 'S': PyrexTypes.c_char_ptr_ptr_type, 'r': PyrexTypes.c_returncode_type, 'B': PyrexTypes.c_py_buffer_ptr_type, # 'T', '-' and '*' are handled otherwise # and are not looked up in here } type_to_format_map = dict( (type_, format_) for format_, type_ in format_map.items()) error_value_map = { 'O': "NULL", 'T': "NULL", 'i': "-1", 'b': "-1", 'l': "-1", 'r': "-1", 'h': "-1", 'z': "-1", } def __init__(self, arg_format, ret_format): self.has_dummy_arg = 0 self.has_generic_args = 0 if arg_format[:1] == '-': self.has_dummy_arg = 1 arg_format = arg_format[1:] if arg_format[-1:] == '*': self.has_generic_args = 1 arg_format = arg_format[:-1] self.fixed_arg_format = arg_format self.ret_format = ret_format self.error_value = self.error_value_map.get(ret_format, None) self.exception_check = ret_format != 'r' and self.error_value is not None self.is_staticmethod = False def num_fixed_args(self): return len(self.fixed_arg_format) def is_self_arg(self, i): # argument is 'self' for methods or 'class' for classmethods return self.fixed_arg_format[i] == 'T' def returns_self_type(self): # return type is same as 'self' argument type return self.ret_format == 'T' def fixed_arg_type(self, i): return self.format_map[self.fixed_arg_format[i]] def return_type(self): return self.format_map[self.ret_format] def format_from_type(self, arg_type): if arg_type.is_pyobject: arg_type = PyrexTypes.py_object_type return self.type_to_format_map[arg_type] def exception_value(self): return self.error_value_map.get(self.ret_format) def function_type(self, self_arg_override=None): # Construct a C function type descriptor for this signature args = [] for i in range(self.num_fixed_args()): if self_arg_override is not None and self.is_self_arg(i): assert isinstance(self_arg_override, PyrexTypes.CFuncTypeArg) args.append(self_arg_override) else: arg_type = self.fixed_arg_type(i) args.append(PyrexTypes.CFuncTypeArg("", arg_type, None)) if self_arg_override is not None and self.returns_self_type(): ret_type = self_arg_override.type else: ret_type = self.return_type() exc_value = self.exception_value() return PyrexTypes.CFuncType( ret_type, args, exception_value=exc_value, exception_check=self.exception_check) def method_flags(self): if self.ret_format == "O": full_args = self.fixed_arg_format if self.has_dummy_arg: full_args = "O" + full_args if full_args in ["O", "T"]: if self.has_generic_args: return [method_varargs, method_keywords] else: return [method_noargs] elif full_args in ["OO", "TO"] and not self.has_generic_args: return [method_onearg] if self.is_staticmethod: return [method_varargs, method_keywords] return None class SlotDescriptor(object): # Abstract base class for type slot descriptors. # # 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_inherited Is inherited by subtypes (see PyType_Ready()) # py3 Indicates presence of slot in Python 3 # py2 Indicates presence of slot in Python 2 # ifdef Full #ifdef string that slot is wrapped in. Using this causes py3, py2 and flags to be ignored.) def __init__(self, slot_name, dynamic=False, inherited=False, py3=True, py2=True, ifdef=None): self.slot_name = slot_name self.is_initialised_dynamically = dynamic self.is_inherited = inherited self.ifdef = ifdef self.py3 = py3 self.py2 = py2 def preprocessor_guard_code(self): ifdef = self.ifdef py2 = self.py2 py3 = self.py3 guard = None if ifdef: guard = ("#if %s" % ifdef) elif not py3 or py3 == '': guard = ("#if PY_MAJOR_VERSION < 3") elif not py2: guard = ("#if PY_MAJOR_VERSION >= 3") return guard def generate(self, scope, code): preprocessor_guard = self.preprocessor_guard_code() if preprocessor_guard: code.putln(preprocessor_guard) end_pypy_guard = False if self.is_initialised_dynamically: value = "0" else: value = self.slot_code(scope) if value == "0" and self.is_inherited: # PyPy currently has a broken PyType_Ready() that fails to # inherit some slots. To work around this, we explicitly # set inherited slots here, but only in PyPy since CPython # handles this better than we do. inherited_value = value current_scope = scope while (inherited_value == "0" and current_scope.parent_type and current_scope.parent_type.base_type and current_scope.parent_type.base_type.scope): current_scope = current_scope.parent_type.base_type.scope inherited_value = self.slot_code(current_scope) if inherited_value != "0": code.putln("#if CYTHON_COMPILING_IN_PYPY") code.putln("%s, /*%s*/" % (inherited_value, self.slot_name)) code.putln("#else") end_pypy_guard = True code.putln("%s, /*%s*/" % (value, self.slot_name)) if end_pypy_guard: code.putln("#endif") if self.py3 == '': code.putln("#else") code.putln("0, /*reserved*/") if preprocessor_guard: code.putln("#endif") # Some C implementations have trouble statically # initialising a global with a pointer to an extern # function, so we initialise some of the type slots # in the module init function instead. def generate_dynamic_init_code(self, scope, code): if self.is_initialised_dynamically: value = self.slot_code(scope) if value != "0": code.putln("%s.%s = %s;" % ( scope.parent_type.typeobj_cname, self.slot_name, value ) ) class FixedSlot(SlotDescriptor): # Descriptor for a type slot with a fixed value. # # value string def __init__(self, slot_name, value, py3=True, py2=True, ifdef=None): SlotDescriptor.__init__(self, slot_name, py3=py3, py2=py2, ifdef=ifdef) self.value = value def slot_code(self, scope): return self.value class EmptySlot(FixedSlot): # Descriptor for a type slot whose value is always 0. def __init__(self, slot_name, py3=True, py2=True, ifdef=None): FixedSlot.__init__(self, slot_name, "0", py3=py3, py2=py2, ifdef=ifdef) class MethodSlot(SlotDescriptor): # Type slot descriptor for a user-definable method. # # signature Signature # method_name string The __xxx__ name of the method # alternatives [string] Alternative list of __xxx__ names for the method def __init__(self, signature, slot_name, method_name, fallback=None, py3=True, py2=True, ifdef=None, inherited=True): SlotDescriptor.__init__(self, slot_name, py3=py3, py2=py2, ifdef=ifdef, inherited=inherited) self.signature = signature self.slot_name = slot_name self.method_name = method_name self.alternatives = [] method_name_to_slot[method_name] = self # if fallback: self.alternatives.append(fallback) for alt in (self.py2, self.py3): if isinstance(alt, (tuple, list)): slot_name, method_name = alt self.alternatives.append(method_name) method_name_to_slot[method_name] = self def slot_code(self, scope): entry = scope.lookup_here(self.method_name) if entry and entry.func_cname: return entry.func_cname for method_name in self.alternatives: entry = scope.lookup_here(method_name) if entry and entry.func_cname: return entry.func_cname return "0" class InternalMethodSlot(SlotDescriptor): # Type slot descriptor for a method which is always # synthesized by Cython. # # slot_name string Member name of the slot in the type object def __init__(self, slot_name, **kargs): SlotDescriptor.__init__(self, slot_name, **kargs) def slot_code(self, scope): return scope.mangle_internal(self.slot_name) class GCDependentSlot(InternalMethodSlot): # Descriptor for a slot whose value depends on whether # the type participates in GC. def __init__(self, slot_name, **kargs): InternalMethodSlot.__init__(self, slot_name, **kargs) def slot_code(self, scope): if not scope.needs_gc(): return "0" if not scope.has_cyclic_pyobject_attrs: # if the type does not have GC relevant object attributes, it can # delegate GC methods to its parent - iff the parent functions # are defined in the same module parent_type_scope = scope.parent_type.base_type.scope if scope.parent_scope is parent_type_scope.parent_scope: entry = scope.parent_scope.lookup_here(scope.parent_type.base_type.name) if entry.visibility != 'extern': return self.slot_code(parent_type_scope) return InternalMethodSlot.slot_code(self, scope) class GCClearReferencesSlot(GCDependentSlot): def slot_code(self, scope): if scope.needs_tp_clear(): return GCDependentSlot.slot_code(self, scope) return "0" class ConstructorSlot(InternalMethodSlot): # Descriptor for tp_new and tp_dealloc. def __init__(self, slot_name, method, **kargs): InternalMethodSlot.__init__(self, slot_name, **kargs) self.method = method def slot_code(self, scope): if (self.slot_name != 'tp_new' and scope.parent_type.base_type and not scope.has_pyobject_attrs and not scope.has_memoryview_attrs and not scope.has_cpp_class_attrs and not scope.lookup_here(self.method)): # if the type does not have object attributes, it can # delegate GC methods to its parent - iff the parent # functions are defined in the same module parent_type_scope = scope.parent_type.base_type.scope if scope.parent_scope is parent_type_scope.parent_scope: entry = scope.parent_scope.lookup_here(scope.parent_type.base_type.name) if entry.visibility != 'extern': return self.slot_code(parent_type_scope) return InternalMethodSlot.slot_code(self, scope) class SyntheticSlot(InternalMethodSlot): # Type slot descriptor for a synthesized method which # dispatches to one or more user-defined methods depending # on its arguments. If none of the relevant methods are # defined, the method will not be synthesized and an # alternative default value will be placed in the type # slot. def __init__(self, slot_name, user_methods, default_value, **kargs): InternalMethodSlot.__init__(self, slot_name, **kargs) self.user_methods = user_methods self.default_value = default_value def slot_code(self, scope): if scope.defines_any(self.user_methods): return InternalMethodSlot.slot_code(self, scope) else: return self.default_value class TypeFlagsSlot(SlotDescriptor): # Descriptor for the type flags slot. def slot_code(self, scope): value = "Py_TPFLAGS_DEFAULT" if scope.directives['type_version_tag']: # it's not in 'Py_TPFLAGS_DEFAULT' in Py2 value += "|Py_TPFLAGS_HAVE_VERSION_TAG" else: # it's enabled in 'Py_TPFLAGS_DEFAULT' in Py3 value = "(%s&~Py_TPFLAGS_HAVE_VERSION_TAG)" % value value += "|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER" if not scope.parent_type.is_final_type: value += "|Py_TPFLAGS_BASETYPE" if scope.needs_gc(): value += "|Py_TPFLAGS_HAVE_GC" return value class DocStringSlot(SlotDescriptor): # Descriptor for the docstring slot. def slot_code(self, scope): if scope.doc is not None: if scope.doc.is_unicode: doc = scope.doc.utf8encode() else: doc = scope.doc.byteencode() return '"%s"' % StringEncoding.escape_byte_string(doc) else: return "0" class SuiteSlot(SlotDescriptor): # Descriptor for a substructure of the type object. # # sub_slots [SlotDescriptor] def __init__(self, sub_slots, slot_type, slot_name, ifdef=None): SlotDescriptor.__init__(self, slot_name, ifdef=ifdef) self.sub_slots = sub_slots self.slot_type = slot_type substructures.append(self) def is_empty(self, scope): for slot in self.sub_slots: if slot.slot_code(scope) != "0": return False return True def substructure_cname(self, scope): return "%s%s_%s" % (Naming.pyrex_prefix, self.slot_name, scope.class_name) def slot_code(self, scope): if not self.is_empty(scope): return "&%s" % self.substructure_cname(scope) return "0" def generate_substructure(self, scope, code): if not self.is_empty(scope): code.putln("") if self.ifdef: code.putln("#if %s" % self.ifdef) code.putln( "static %s %s = {" % ( self.slot_type, self.substructure_cname(scope))) for slot in self.sub_slots: slot.generate(scope, code) code.putln("};") if self.ifdef: code.putln("#endif") substructures = [] # List of all SuiteSlot instances class MethodTableSlot(SlotDescriptor): # Slot descriptor for the method table. def slot_code(self, scope): if scope.pyfunc_entries: return scope.method_table_cname else: return "0" class MemberTableSlot(SlotDescriptor): # Slot descriptor for the table of Python-accessible attributes. def slot_code(self, scope): return "0" class GetSetSlot(SlotDescriptor): # Slot descriptor for the table of attribute get & set methods. def slot_code(self, scope): if scope.property_entries: return scope.getset_table_cname else: return "0" class BaseClassSlot(SlotDescriptor): # Slot descriptor for the base class slot. def __init__(self, name): SlotDescriptor.__init__(self, name, dynamic = 1) def generate_dynamic_init_code(self, scope, code): base_type = scope.parent_type.base_type if base_type: code.putln("%s.%s = %s;" % ( scope.parent_type.typeobj_cname, self.slot_name, base_type.typeptr_cname)) # The following dictionary maps __xxx__ method names to slot descriptors. method_name_to_slot = {} ## The following slots are (or could be) initialised with an ## extern function pointer. # #slots_initialised_from_extern = ( # "tp_free", #) #------------------------------------------------------------------------------------------ # # Utility functions for accessing slot table data structures # #------------------------------------------------------------------------------------------ def get_special_method_signature(name): # Given a method name, if it is a special method, # return its signature, else return None. slot = method_name_to_slot.get(name) if slot: return slot.signature else: return None def get_property_accessor_signature(name): # Return signature of accessor for an extension type # property, else None. return property_accessor_signatures.get(name) def get_base_slot_function(scope, slot): # Returns the function implementing this slot in the baseclass. # This is useful for enabling the compiler to optimize calls # that recursively climb the class hierarchy. base_type = scope.parent_type.base_type if scope.parent_scope is base_type.scope.parent_scope: parent_slot = slot.slot_code(base_type.scope) if parent_slot != '0': entry = scope.parent_scope.lookup_here(scope.parent_type.base_type.name) if entry.visibility != 'extern': return parent_slot return None def get_slot_function(scope, slot): # Returns the function implementing this slot in the baseclass. # This is useful for enabling the compiler to optimize calls # that recursively climb the class hierarchy. slot_code = slot.slot_code(scope) if slot_code != '0': entry = scope.parent_scope.lookup_here(scope.parent_type.name) if entry.visibility != 'extern': return slot_code return None #------------------------------------------------------------------------------------------ # # Signatures for generic Python functions and methods. # #------------------------------------------------------------------------------------------ pyfunction_signature = Signature("-*", "O") pymethod_signature = Signature("T*", "O") #------------------------------------------------------------------------------------------ # # Signatures for simple Python functions. # #------------------------------------------------------------------------------------------ pyfunction_noargs = Signature("-", "O") pyfunction_onearg = Signature("-O", "O") #------------------------------------------------------------------------------------------ # # Signatures for the various kinds of function that # can appear in the type object and its substructures. # #------------------------------------------------------------------------------------------ unaryfunc = Signature("T", "O") # typedef PyObject * (*unaryfunc)(PyObject *); binaryfunc = Signature("OO", "O") # typedef PyObject * (*binaryfunc)(PyObject *, PyObject *); ibinaryfunc = Signature("TO", "O") # typedef PyObject * (*binaryfunc)(PyObject *, PyObject *); ternaryfunc = Signature("OOO", "O") # typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *); iternaryfunc = Signature("TOO", "O") # typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *); callfunc = Signature("T*", "O") # typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *); inquiry = Signature("T", "i") # typedef int (*inquiry)(PyObject *); lenfunc = Signature("T", "z") # typedef Py_ssize_t (*lenfunc)(PyObject *); # typedef int (*coercion)(PyObject **, PyObject **); intargfunc = Signature("Ti", "O") # typedef PyObject *(*intargfunc)(PyObject *, int); ssizeargfunc = Signature("Tz", "O") # typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t); intintargfunc = Signature("Tii", "O") # typedef PyObject *(*intintargfunc)(PyObject *, int, int); ssizessizeargfunc = Signature("Tzz", "O") # typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t); intobjargproc = Signature("TiO", 'r') # typedef int(*intobjargproc)(PyObject *, int, PyObject *); ssizeobjargproc = Signature("TzO", 'r') # typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *); intintobjargproc = Signature("TiiO", 'r') # typedef int(*intintobjargproc)(PyObject *, int, int, PyObject *); ssizessizeobjargproc = Signature("TzzO", 'r') # typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *); intintargproc = Signature("Tii", 'r') ssizessizeargproc = Signature("Tzz", 'r') objargfunc = Signature("TO", "O") objobjargproc = Signature("TOO", 'r') # typedef int (*objobjargproc)(PyObject *, PyObject *, PyObject *); readbufferproc = Signature("TzP", "z") # typedef Py_ssize_t (*readbufferproc)(PyObject *, Py_ssize_t, void **); writebufferproc = Signature("TzP", "z") # typedef Py_ssize_t (*writebufferproc)(PyObject *, Py_ssize_t, void **); segcountproc = Signature("TZ", "z") # typedef Py_ssize_t (*segcountproc)(PyObject *, Py_ssize_t *); charbufferproc = Signature("TzS", "z") # typedef Py_ssize_t (*charbufferproc)(PyObject *, Py_ssize_t, char **); objargproc = Signature("TO", 'r') # typedef int (*objobjproc)(PyObject *, PyObject *); # typedef int (*visitproc)(PyObject *, void *); # typedef int (*traverseproc)(PyObject *, visitproc, void *); destructor = Signature("T", "v") # typedef void (*destructor)(PyObject *); # printfunc = Signature("TFi", 'r') # typedef int (*printfunc)(PyObject *, FILE *, int); # typedef PyObject *(*getattrfunc)(PyObject *, char *); getattrofunc = Signature("TO", "O") # typedef PyObject *(*getattrofunc)(PyObject *, PyObject *); # typedef int (*setattrfunc)(PyObject *, char *, PyObject *); setattrofunc = Signature("TOO", 'r') # typedef int (*setattrofunc)(PyObject *, PyObject *, PyObject *); delattrofunc = Signature("TO", 'r') cmpfunc = Signature("TO", "i") # typedef int (*cmpfunc)(PyObject *, PyObject *); reprfunc = Signature("T", "O") # typedef PyObject *(*reprfunc)(PyObject *); hashfunc = Signature("T", "h") # typedef Py_hash_t (*hashfunc)(PyObject *); # typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int); richcmpfunc = Signature("OOi", "O") # typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int); getiterfunc = Signature("T", "O") # typedef PyObject *(*getiterfunc) (PyObject *); iternextfunc = Signature("T", "O") # typedef PyObject *(*iternextfunc) (PyObject *); descrgetfunc = Signature("TOO", "O") # typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *); descrsetfunc = Signature("TOO", 'r') # typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *); descrdelfunc = Signature("TO", 'r') initproc = Signature("T*", 'r') # typedef int (*initproc)(PyObject *, PyObject *, PyObject *); # typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *); # typedef PyObject *(*allocfunc)(struct _typeobject *, int); getbufferproc = Signature("TBi", "r") # typedef int (*getbufferproc)(PyObject *, Py_buffer *, int); releasebufferproc = Signature("TB", "v") # typedef void (*releasebufferproc)(PyObject *, Py_buffer *); #------------------------------------------------------------------------------------------ # # Signatures for accessor methods of properties. # #------------------------------------------------------------------------------------------ property_accessor_signatures = { '__get__': Signature("T", "O"), '__set__': Signature("TO", 'r'), '__del__': Signature("T", 'r') } #------------------------------------------------------------------------------------------ # # Descriptor tables for the slots of the various type object # substructures, in the order they appear in the structure. # #------------------------------------------------------------------------------------------ PyNumberMethods_Py3_GUARD = "PY_MAJOR_VERSION < 3 || CYTHON_COMPILING_IN_PYPY" PyNumberMethods = ( MethodSlot(binaryfunc, "nb_add", "__add__"), MethodSlot(binaryfunc, "nb_subtract", "__sub__"), MethodSlot(binaryfunc, "nb_multiply", "__mul__"), MethodSlot(binaryfunc, "nb_divide", "__div__", ifdef = PyNumberMethods_Py3_GUARD), MethodSlot(binaryfunc, "nb_remainder", "__mod__"), MethodSlot(binaryfunc, "nb_divmod", "__divmod__"), MethodSlot(ternaryfunc, "nb_power", "__pow__"), MethodSlot(unaryfunc, "nb_negative", "__neg__"), MethodSlot(unaryfunc, "nb_positive", "__pos__"), MethodSlot(unaryfunc, "nb_absolute", "__abs__"), MethodSlot(inquiry, "nb_nonzero", "__nonzero__", py3 = ("nb_bool", "__bool__")), MethodSlot(unaryfunc, "nb_invert", "__invert__"), MethodSlot(binaryfunc, "nb_lshift", "__lshift__"), MethodSlot(binaryfunc, "nb_rshift", "__rshift__"), MethodSlot(binaryfunc, "nb_and", "__and__"), MethodSlot(binaryfunc, "nb_xor", "__xor__"), MethodSlot(binaryfunc, "nb_or", "__or__"), EmptySlot("nb_coerce", ifdef = PyNumberMethods_Py3_GUARD), MethodSlot(unaryfunc, "nb_int", "__int__", fallback="__long__"), MethodSlot(unaryfunc, "nb_long", "__long__", fallback="__int__", py3 = ""), MethodSlot(unaryfunc, "nb_float", "__float__"), MethodSlot(unaryfunc, "nb_oct", "__oct__", ifdef = PyNumberMethods_Py3_GUARD), MethodSlot(unaryfunc, "nb_hex", "__hex__", ifdef = PyNumberMethods_Py3_GUARD), # Added in release 2.0 MethodSlot(ibinaryfunc, "nb_inplace_add", "__iadd__"), MethodSlot(ibinaryfunc, "nb_inplace_subtract", "__isub__"), MethodSlot(ibinaryfunc, "nb_inplace_multiply", "__imul__"), MethodSlot(ibinaryfunc, "nb_inplace_divide", "__idiv__", ifdef = PyNumberMethods_Py3_GUARD), MethodSlot(ibinaryfunc, "nb_inplace_remainder", "__imod__"), MethodSlot(ibinaryfunc, "nb_inplace_power", "__ipow__"), # actually ternaryfunc!!! MethodSlot(ibinaryfunc, "nb_inplace_lshift", "__ilshift__"), MethodSlot(ibinaryfunc, "nb_inplace_rshift", "__irshift__"), MethodSlot(ibinaryfunc, "nb_inplace_and", "__iand__"), MethodSlot(ibinaryfunc, "nb_inplace_xor", "__ixor__"), MethodSlot(ibinaryfunc, "nb_inplace_or", "__ior__"), # Added in release 2.2 # The following require the Py_TPFLAGS_HAVE_CLASS flag MethodSlot(binaryfunc, "nb_floor_divide", "__floordiv__"), MethodSlot(binaryfunc, "nb_true_divide", "__truediv__"), MethodSlot(ibinaryfunc, "nb_inplace_floor_divide", "__ifloordiv__"), MethodSlot(ibinaryfunc, "nb_inplace_true_divide", "__itruediv__"), # Added in release 2.5 MethodSlot(unaryfunc, "nb_index", "__index__"), # Added in release 3.5 MethodSlot(binaryfunc, "nb_matrix_multiply", "__matmul__", ifdef="PY_VERSION_HEX >= 0x03050000"), MethodSlot(ibinaryfunc, "nb_inplace_matrix_multiply", "__imatmul__", ifdef="PY_VERSION_HEX >= 0x03050000"), ) PySequenceMethods = ( MethodSlot(lenfunc, "sq_length", "__len__"), EmptySlot("sq_concat"), # nb_add used instead EmptySlot("sq_repeat"), # nb_multiply used instead SyntheticSlot("sq_item", ["__getitem__"], "0"), #EmptySlot("sq_item"), # mp_subscript used instead MethodSlot(ssizessizeargfunc, "sq_slice", "__getslice__"), EmptySlot("sq_ass_item"), # mp_ass_subscript used instead SyntheticSlot("sq_ass_slice", ["__setslice__", "__delslice__"], "0"), MethodSlot(cmpfunc, "sq_contains", "__contains__"), EmptySlot("sq_inplace_concat"), # nb_inplace_add used instead EmptySlot("sq_inplace_repeat"), # nb_inplace_multiply used instead ) PyMappingMethods = ( MethodSlot(lenfunc, "mp_length", "__len__"), MethodSlot(objargfunc, "mp_subscript", "__getitem__"), SyntheticSlot("mp_ass_subscript", ["__setitem__", "__delitem__"], "0"), ) PyBufferProcs = ( MethodSlot(readbufferproc, "bf_getreadbuffer", "__getreadbuffer__", py3 = False), MethodSlot(writebufferproc, "bf_getwritebuffer", "__getwritebuffer__", py3 = False), MethodSlot(segcountproc, "bf_getsegcount", "__getsegcount__", py3 = False), MethodSlot(charbufferproc, "bf_getcharbuffer", "__getcharbuffer__", py3 = False), MethodSlot(getbufferproc, "bf_getbuffer", "__getbuffer__"), MethodSlot(releasebufferproc, "bf_releasebuffer", "__releasebuffer__") ) PyAsyncMethods = ( MethodSlot(unaryfunc, "am_await", "__await__"), MethodSlot(unaryfunc, "am_aiter", "__aiter__"), MethodSlot(unaryfunc, "am_anext", "__anext__"), ) #------------------------------------------------------------------------------------------ # # The main slot table. This table contains descriptors for all the # top-level type slots, beginning with tp_dealloc, in the order they # appear in the type object. # #------------------------------------------------------------------------------------------ slot_table = ( ConstructorSlot("tp_dealloc", '__dealloc__'), EmptySlot("tp_print"), #MethodSlot(printfunc, "tp_print", "__print__"), EmptySlot("tp_getattr"), EmptySlot("tp_setattr"), # tp_compare (Py2) / tp_reserved (Py3<3.5) / tp_as_async (Py3.5+) is always used as tp_as_async in Py3 MethodSlot(cmpfunc, "tp_compare", "__cmp__", ifdef="PY_MAJOR_VERSION < 3"), SuiteSlot(PyAsyncMethods, "__Pyx_PyAsyncMethodsStruct", "tp_as_async", ifdef="PY_MAJOR_VERSION >= 3"), MethodSlot(reprfunc, "tp_repr", "__repr__"), SuiteSlot(PyNumberMethods, "PyNumberMethods", "tp_as_number"), SuiteSlot(PySequenceMethods, "PySequenceMethods", "tp_as_sequence"), SuiteSlot(PyMappingMethods, "PyMappingMethods", "tp_as_mapping"), MethodSlot(hashfunc, "tp_hash", "__hash__", inherited=False), # Py3 checks for __richcmp__ MethodSlot(callfunc, "tp_call", "__call__"), MethodSlot(reprfunc, "tp_str", "__str__"), SyntheticSlot("tp_getattro", ["__getattr__","__getattribute__"], "0"), #"PyObject_GenericGetAttr"), SyntheticSlot("tp_setattro", ["__setattr__", "__delattr__"], "0"), #"PyObject_GenericSetAttr"), SuiteSlot(PyBufferProcs, "PyBufferProcs", "tp_as_buffer"), TypeFlagsSlot("tp_flags"), DocStringSlot("tp_doc"), GCDependentSlot("tp_traverse"), GCClearReferencesSlot("tp_clear"), # Later -- synthesize a method to split into separate ops? MethodSlot(richcmpfunc, "tp_richcompare", "__richcmp__", inherited=False), # Py3 checks for __hash__ EmptySlot("tp_weaklistoffset"), MethodSlot(getiterfunc, "tp_iter", "__iter__"), MethodSlot(iternextfunc, "tp_iternext", "__next__"), MethodTableSlot("tp_methods"), MemberTableSlot("tp_members"), GetSetSlot("tp_getset"), BaseClassSlot("tp_base"), #EmptySlot("tp_base"), EmptySlot("tp_dict"), SyntheticSlot("tp_descr_get", ["__get__"], "0"), SyntheticSlot("tp_descr_set", ["__set__", "__delete__"], "0"), EmptySlot("tp_dictoffset"), MethodSlot(initproc, "tp_init", "__init__"), EmptySlot("tp_alloc"), #FixedSlot("tp_alloc", "PyType_GenericAlloc"), InternalMethodSlot("tp_new"), EmptySlot("tp_free"), EmptySlot("tp_is_gc"), EmptySlot("tp_bases"), EmptySlot("tp_mro"), EmptySlot("tp_cache"), EmptySlot("tp_subclasses"), EmptySlot("tp_weaklist"), EmptySlot("tp_del"), EmptySlot("tp_version_tag"), EmptySlot("tp_finalize", ifdef="PY_VERSION_HEX >= 0x030400a1"), ) #------------------------------------------------------------------------------------------ # # Descriptors for special methods which don't appear directly # in the type object or its substructures. These methods are # called from slot functions synthesized by Cython. # #------------------------------------------------------------------------------------------ MethodSlot(initproc, "", "__cinit__") MethodSlot(destructor, "", "__dealloc__") MethodSlot(objobjargproc, "", "__setitem__") MethodSlot(objargproc, "", "__delitem__") MethodSlot(ssizessizeobjargproc, "", "__setslice__") MethodSlot(ssizessizeargproc, "", "__delslice__") MethodSlot(getattrofunc, "", "__getattr__") MethodSlot(setattrofunc, "", "__setattr__") MethodSlot(delattrofunc, "", "__delattr__") MethodSlot(descrgetfunc, "", "__get__") MethodSlot(descrsetfunc, "", "__set__") MethodSlot(descrdelfunc, "", "__delete__") # Method flags for python-exposed methods. method_noargs = "METH_NOARGS" method_onearg = "METH_O" method_varargs = "METH_VARARGS" method_keywords = "METH_KEYWORDS" method_coexist = "METH_COEXIST" Cython-0.23.4/Cython/Compiler/TypeInference.py0000644000175600017570000005107312606202452022342 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import from .Errors import error, message from . import ExprNodes from . import Nodes from . import Builtin from . import PyrexTypes from .. import Utils from .PyrexTypes import py_object_type, unspecified_type from .Visitor import CythonTransform, EnvTransform try: reduce except NameError: from functools import reduce class TypedExprNode(ExprNodes.ExprNode): # Used for declaring assignments of a specified type without a known entry. subexprs = [] def __init__(self, type, pos=None): super(TypedExprNode, self).__init__(pos, type=type) object_expr = TypedExprNode(py_object_type) class MarkParallelAssignments(EnvTransform): # Collects assignments inside parallel blocks prange, with parallel. # Perhaps it's better to move it to ControlFlowAnalysis. # tells us whether we're in a normal loop in_loop = False parallel_errors = False def __init__(self, context): # Track the parallel block scopes (with parallel, for i in prange()) self.parallel_block_stack = [] super(MarkParallelAssignments, self).__init__(context) def mark_assignment(self, lhs, rhs, inplace_op=None): if isinstance(lhs, (ExprNodes.NameNode, Nodes.PyArgDeclNode)): if lhs.entry is None: # TODO: This shouldn't happen... return if self.parallel_block_stack: parallel_node = self.parallel_block_stack[-1] previous_assignment = parallel_node.assignments.get(lhs.entry) # If there was a previous assignment to the variable, keep the # previous assignment position if previous_assignment: pos, previous_inplace_op = previous_assignment if (inplace_op and previous_inplace_op and inplace_op != previous_inplace_op): # x += y; x *= y t = (inplace_op, previous_inplace_op) error(lhs.pos, "Reduction operator '%s' is inconsistent " "with previous reduction operator '%s'" % t) else: pos = lhs.pos parallel_node.assignments[lhs.entry] = (pos, inplace_op) parallel_node.assigned_nodes.append(lhs) elif isinstance(lhs, ExprNodes.SequenceNode): for i, arg in enumerate(lhs.args): if not rhs or arg.is_starred: item_node = None else: item_node = rhs.inferable_item_node(i) self.mark_assignment(arg, item_node) else: # Could use this info to infer cdef class attributes... pass def visit_WithTargetAssignmentStatNode(self, node): self.mark_assignment(node.lhs, node.with_node.enter_call) self.visitchildren(node) return node def visit_SingleAssignmentNode(self, node): self.mark_assignment(node.lhs, node.rhs) self.visitchildren(node) return node def visit_CascadedAssignmentNode(self, node): for lhs in node.lhs_list: self.mark_assignment(lhs, node.rhs) self.visitchildren(node) return node def visit_InPlaceAssignmentNode(self, node): self.mark_assignment(node.lhs, node.create_binop_node(), node.operator) self.visitchildren(node) return node def visit_ForInStatNode(self, node): # TODO: Remove redundancy with range optimization... is_special = False sequence = node.iterator.sequence target = node.target if isinstance(sequence, ExprNodes.SimpleCallNode): function = sequence.function if sequence.self is None and function.is_name: entry = self.current_env().lookup(function.name) if not entry or entry.is_builtin: if function.name == 'reversed' and len(sequence.args) == 1: sequence = sequence.args[0] elif function.name == 'enumerate' and len(sequence.args) == 1: if target.is_sequence_constructor and len(target.args) == 2: iterator = sequence.args[0] if iterator.is_name: iterator_type = iterator.infer_type(self.current_env()) if iterator_type.is_builtin_type: # assume that builtin types have a length within Py_ssize_t self.mark_assignment( target.args[0], ExprNodes.IntNode(target.pos, value='PY_SSIZE_T_MAX', type=PyrexTypes.c_py_ssize_t_type)) target = target.args[1] sequence = sequence.args[0] if isinstance(sequence, ExprNodes.SimpleCallNode): function = sequence.function if sequence.self is None and function.is_name: entry = self.current_env().lookup(function.name) if not entry or entry.is_builtin: if function.name in ('range', 'xrange'): is_special = True for arg in sequence.args[:2]: self.mark_assignment(target, arg) if len(sequence.args) > 2: self.mark_assignment( target, ExprNodes.binop_node(node.pos, '+', sequence.args[0], sequence.args[2])) if not is_special: # A for-loop basically translates to subsequent calls to # __getitem__(), so using an IndexNode here allows us to # naturally infer the base type of pointers, C arrays, # Python strings, etc., while correctly falling back to an # object type when the base type cannot be handled. self.mark_assignment(target, ExprNodes.IndexNode( node.pos, base=sequence, index=ExprNodes.IntNode(target.pos, value='PY_SSIZE_T_MAX', type=PyrexTypes.c_py_ssize_t_type))) self.visitchildren(node) return node def visit_ForFromStatNode(self, node): self.mark_assignment(node.target, node.bound1) if node.step is not None: self.mark_assignment(node.target, ExprNodes.binop_node(node.pos, '+', node.bound1, node.step)) self.visitchildren(node) return node def visit_WhileStatNode(self, node): self.visitchildren(node) return node def visit_ExceptClauseNode(self, node): if node.target is not None: self.mark_assignment(node.target, object_expr) self.visitchildren(node) return node def visit_FromCImportStatNode(self, node): pass # Can't be assigned to... def visit_FromImportStatNode(self, node): for name, target in node.items: if name != "*": self.mark_assignment(target, object_expr) self.visitchildren(node) return node def visit_DefNode(self, node): # use fake expressions with the right result type if node.star_arg: self.mark_assignment( node.star_arg, TypedExprNode(Builtin.tuple_type, node.pos)) if node.starstar_arg: self.mark_assignment( node.starstar_arg, TypedExprNode(Builtin.dict_type, node.pos)) EnvTransform.visit_FuncDefNode(self, node) return node def visit_DelStatNode(self, node): for arg in node.args: self.mark_assignment(arg, arg) self.visitchildren(node) return node def visit_ParallelStatNode(self, node): if self.parallel_block_stack: node.parent = self.parallel_block_stack[-1] else: node.parent = None nested = False if node.is_prange: if not node.parent: node.is_parallel = True else: node.is_parallel = (node.parent.is_prange or not node.parent.is_parallel) nested = node.parent.is_prange else: node.is_parallel = True # Note: nested with parallel() blocks are handled by # ParallelRangeTransform! # nested = node.parent nested = node.parent and node.parent.is_prange self.parallel_block_stack.append(node) nested = nested or len(self.parallel_block_stack) > 2 if not self.parallel_errors and nested and not node.is_prange: error(node.pos, "Only prange() may be nested") self.parallel_errors = True if node.is_prange: child_attrs = node.child_attrs node.child_attrs = ['body', 'target', 'args'] self.visitchildren(node) node.child_attrs = child_attrs self.parallel_block_stack.pop() if node.else_clause: node.else_clause = self.visit(node.else_clause) else: self.visitchildren(node) self.parallel_block_stack.pop() self.parallel_errors = False return node def visit_YieldExprNode(self, node): if self.parallel_block_stack: error(node.pos, "Yield not allowed in parallel sections") return node def visit_ReturnStatNode(self, node): node.in_parallel = bool(self.parallel_block_stack) return node class MarkOverflowingArithmetic(CythonTransform): # It may be possible to integrate this with the above for # performance improvements (though likely not worth it). might_overflow = False def __call__(self, root): self.env_stack = [] self.env = root.scope return super(MarkOverflowingArithmetic, self).__call__(root) def visit_safe_node(self, node): self.might_overflow, saved = False, self.might_overflow self.visitchildren(node) self.might_overflow = saved return node def visit_neutral_node(self, node): self.visitchildren(node) return node def visit_dangerous_node(self, node): self.might_overflow, saved = True, self.might_overflow self.visitchildren(node) self.might_overflow = saved return node def visit_FuncDefNode(self, node): self.env_stack.append(self.env) self.env = node.local_scope self.visit_safe_node(node) self.env = self.env_stack.pop() return node def visit_NameNode(self, node): if self.might_overflow: entry = node.entry or self.env.lookup(node.name) if entry: entry.might_overflow = True return node def visit_BinopNode(self, node): if node.operator in '&|^': return self.visit_neutral_node(node) else: return self.visit_dangerous_node(node) visit_UnopNode = visit_neutral_node visit_UnaryMinusNode = visit_dangerous_node visit_InPlaceAssignmentNode = visit_dangerous_node visit_Node = visit_safe_node def visit_assignment(self, lhs, rhs): if (isinstance(rhs, ExprNodes.IntNode) and isinstance(lhs, ExprNodes.NameNode) and Utils.long_literal(rhs.value)): entry = lhs.entry or self.env.lookup(lhs.name) if entry: entry.might_overflow = True def visit_SingleAssignmentNode(self, node): self.visit_assignment(node.lhs, node.rhs) self.visitchildren(node) return node def visit_CascadedAssignmentNode(self, node): for lhs in node.lhs_list: self.visit_assignment(lhs, node.rhs) self.visitchildren(node) return node class PyObjectTypeInferer(object): """ If it's not declared, it's a PyObject. """ def infer_types(self, scope): """ Given a dict of entries, map all unspecified types to a specified type. """ for name, entry in scope.entries.items(): if entry.type is unspecified_type: entry.type = py_object_type class SimpleAssignmentTypeInferer(object): """ Very basic type inference. Note: in order to support cross-closure type inference, this must be applies to nested scopes in top-down order. """ def set_entry_type(self, entry, entry_type): entry.type = entry_type for e in entry.all_entries(): e.type = entry_type def infer_types(self, scope): enabled = scope.directives['infer_types'] verbose = scope.directives['infer_types.verbose'] if enabled == True: spanning_type = aggressive_spanning_type elif enabled is None: # safe mode spanning_type = safe_spanning_type else: for entry in scope.entries.values(): if entry.type is unspecified_type: self.set_entry_type(entry, py_object_type) return # Set of assignemnts assignments = set() assmts_resolved = set() dependencies = {} assmt_to_names = {} for name, entry in scope.entries.items(): for assmt in entry.cf_assignments: names = assmt.type_dependencies() assmt_to_names[assmt] = names assmts = set() for node in names: assmts.update(node.cf_state) dependencies[assmt] = assmts if entry.type is unspecified_type: assignments.update(entry.cf_assignments) else: assmts_resolved.update(entry.cf_assignments) def infer_name_node_type(node): types = [assmt.inferred_type for assmt in node.cf_state] if not types: node_type = py_object_type else: entry = node.entry node_type = spanning_type( types, entry.might_overflow, entry.pos) node.inferred_type = node_type def infer_name_node_type_partial(node): types = [assmt.inferred_type for assmt in node.cf_state if assmt.inferred_type is not None] if not types: return entry = node.entry return spanning_type(types, entry.might_overflow, entry.pos) def resolve_assignments(assignments): resolved = set() for assmt in assignments: deps = dependencies[assmt] # All assignments are resolved if assmts_resolved.issuperset(deps): for node in assmt_to_names[assmt]: infer_name_node_type(node) # Resolve assmt inferred_type = assmt.infer_type() assmts_resolved.add(assmt) resolved.add(assmt) assignments.difference_update(resolved) return resolved def partial_infer(assmt): partial_types = [] for node in assmt_to_names[assmt]: partial_type = infer_name_node_type_partial(node) if partial_type is None: return False partial_types.append((node, partial_type)) for node, partial_type in partial_types: node.inferred_type = partial_type assmt.infer_type() return True partial_assmts = set() def resolve_partial(assignments): # try to handle circular references partials = set() for assmt in assignments: if assmt in partial_assmts: continue if partial_infer(assmt): partials.add(assmt) assmts_resolved.add(assmt) partial_assmts.update(partials) return partials # Infer assignments while True: if not resolve_assignments(assignments): if not resolve_partial(assignments): break inferred = set() # First pass for entry in scope.entries.values(): if entry.type is not unspecified_type: continue entry_type = py_object_type if assmts_resolved.issuperset(entry.cf_assignments): types = [assmt.inferred_type for assmt in entry.cf_assignments] if types and all(types): entry_type = spanning_type( types, entry.might_overflow, entry.pos) inferred.add(entry) self.set_entry_type(entry, entry_type) def reinfer(): dirty = False for entry in inferred: types = [assmt.infer_type() for assmt in entry.cf_assignments] new_type = spanning_type(types, entry.might_overflow, entry.pos) if new_type != entry.type: self.set_entry_type(entry, new_type) dirty = True return dirty # types propagation while reinfer(): pass if verbose: for entry in inferred: message(entry.pos, "inferred '%s' to be of type '%s'" % ( entry.name, entry.type)) def find_spanning_type(type1, type2): if type1 is type2: result_type = type1 elif type1 is PyrexTypes.c_bint_type or type2 is PyrexTypes.c_bint_type: # type inference can break the coercion back to a Python bool # if it returns an arbitrary int type here return py_object_type else: result_type = PyrexTypes.spanning_type(type1, type2) if result_type in (PyrexTypes.c_double_type, PyrexTypes.c_float_type, Builtin.float_type): # Python's float type is just a C double, so it's safe to # use the C type instead return PyrexTypes.c_double_type return result_type def simply_type(result_type, pos): if result_type.is_reference: result_type = result_type.ref_base_type if result_type.is_const: result_type = result_type.const_base_type if result_type.is_cpp_class: result_type.check_nullary_constructor(pos) if result_type.is_array: result_type = PyrexTypes.c_ptr_type(result_type.base_type) return result_type def aggressive_spanning_type(types, might_overflow, pos): return simply_type(reduce(find_spanning_type, types), pos) def safe_spanning_type(types, might_overflow, pos): result_type = simply_type(reduce(find_spanning_type, types), pos) if result_type.is_pyobject: # In theory, any specific Python type is always safe to # infer. However, inferring str can cause some existing code # to break, since we are also now much more strict about # coercion from str to char *. See trac #553. if result_type.name == 'str': return py_object_type else: return result_type elif result_type is PyrexTypes.c_double_type: # Python's float type is just a C double, so it's safe to use # the C type instead return result_type elif result_type is PyrexTypes.c_bint_type: # find_spanning_type() only returns 'bint' for clean boolean # operations without other int types, so this is safe, too return result_type elif result_type.is_ptr: # Any pointer except (signed|unsigned|) char* can't implicitly # become a PyObject, and inferring char* is now accepted, too. return result_type elif result_type.is_cpp_class: # These can't implicitly become Python objects either. return result_type elif result_type.is_struct: # Though we have struct -> object for some structs, this is uncommonly # used, won't arise in pure Python, and there shouldn't be side # effects, so I'm declaring this safe. return result_type # TODO: double complex should be OK as well, but we need # to make sure everything is supported. elif (result_type.is_int or result_type.is_enum) and not might_overflow: return result_type return py_object_type def get_type_inferer(): return SimpleAssignmentTypeInferer() Cython-0.23.4/Cython/Compiler/TreePath.py0000644000175600017570000001612012606202452021310 0ustar jenkinsjenkins00000000000000""" A simple XPath-like language for tree traversal. This works by creating a filter chain of generator functions. Each function selects a part of the expression, e.g. a child node, a specific descendant or a node that holds an attribute. """ from __future__ import absolute_import import re import operator path_tokenizer = re.compile( "(" "'[^']*'|\"[^\"]*\"|" "//?|" "\(\)|" "==?|" "[/.*\[\]\(\)@])|" "([^/\[\]\(\)@=\s]+)|" "\s+" ).findall def iterchildren(node, attr_name): # returns an iterable of all child nodes of that name child = getattr(node, attr_name) if child is not None: if type(child) is list: return child else: return [child] else: return () def _get_first_or_none(it): try: try: _next = it.next except AttributeError: return next(it) else: return _next() except StopIteration: return None def type_name(node): return node.__class__.__name__.split('.')[-1] def parse_func(next, token): name = token[1] token = next() if token[0] != '(': raise ValueError("Expected '(' after function name '%s'" % name) predicate = handle_predicate(next, token) return name, predicate def handle_func_not(next, token): """ not(...) """ name, predicate = parse_func(next, token) def select(result): for node in result: if _get_first_or_none(predicate([node])) is None: yield node return select def handle_name(next, token): """ /NodeName/ or func(...) """ name = token[1] if name in functions: return functions[name](next, token) def select(result): for node in result: for attr_name in node.child_attrs: for child in iterchildren(node, attr_name): if type_name(child) == name: yield child return select def handle_star(next, token): """ /*/ """ def select(result): for node in result: for name in node.child_attrs: for child in iterchildren(node, name): yield child return select def handle_dot(next, token): """ /./ """ def select(result): return result return select def handle_descendants(next, token): """ //... """ token = next() if token[0] == "*": def iter_recursive(node): for name in node.child_attrs: for child in iterchildren(node, name): yield child for c in iter_recursive(child): yield c elif not token[0]: node_name = token[1] def iter_recursive(node): for name in node.child_attrs: for child in iterchildren(node, name): if type_name(child) == node_name: yield child for c in iter_recursive(child): yield c else: raise ValueError("Expected node name after '//'") def select(result): for node in result: for child in iter_recursive(node): yield child return select def handle_attribute(next, token): token = next() if token[0]: raise ValueError("Expected attribute name") name = token[1] value = None try: token = next() except StopIteration: pass else: if token[0] == '=': value = parse_path_value(next) readattr = operator.attrgetter(name) if value is None: def select(result): for node in result: try: attr_value = readattr(node) except AttributeError: continue if attr_value is not None: yield attr_value else: def select(result): for node in result: try: attr_value = readattr(node) except AttributeError: continue if attr_value == value: yield attr_value return select def parse_path_value(next): token = next() value = token[0] if value: if value[:1] == "'" or value[:1] == '"': return value[1:-1] try: return int(value) except ValueError: pass else: name = token[1].lower() if name == 'true': return True elif name == 'false': return False raise ValueError("Invalid attribute predicate: '%s'" % value) def handle_predicate(next, token): token = next() selector = [] while token[0] != ']': selector.append( operations[token[0]](next, token) ) try: token = next() except StopIteration: break else: if token[0] == "/": token = next() if not token[0] and token[1] == 'and': return logical_and(selector, handle_predicate(next, token)) def select(result): for node in result: subresult = iter((node,)) for select in selector: subresult = select(subresult) predicate_result = _get_first_or_none(subresult) if predicate_result is not None: yield node return select def logical_and(lhs_selects, rhs_select): def select(result): for node in result: subresult = iter((node,)) for select in lhs_selects: subresult = select(subresult) predicate_result = _get_first_or_none(subresult) subresult = iter((node,)) if predicate_result is not None: for result_node in rhs_select(subresult): yield node return select operations = { "@": handle_attribute, "": handle_name, "*": handle_star, ".": handle_dot, "//": handle_descendants, "[": handle_predicate, } functions = { 'not' : handle_func_not } def _build_path_iterator(path): # parse pattern stream = iter([ (special,text) for (special,text) in path_tokenizer(path) if special or text ]) try: _next = stream.next except AttributeError: # Python 3 def _next(): return next(stream) token = _next() selector = [] while 1: try: selector.append(operations[token[0]](_next, token)) except StopIteration: raise ValueError("invalid path") try: token = _next() if token[0] == "/": token = _next() except StopIteration: break return selector # main module API def iterfind(node, path): selector_chain = _build_path_iterator(path) result = iter((node,)) for select in selector_chain: result = select(result) return result def find_first(node, path): return _get_first_or_none(iterfind(node, path)) def find_all(node, path): return list(iterfind(node, path)) Cython-0.23.4/Cython/Compiler/TreeFragment.py0000644000175600017570000002152512606202452022164 0ustar jenkinsjenkins00000000000000# # TreeFragments - parsing of strings to trees # """ Support for parsing strings into code trees. """ from __future__ import absolute_import import re from io import StringIO from .Scanning import PyrexScanner, StringSourceDescriptor from .Symtab import ModuleScope from . import PyrexTypes from .Visitor import VisitorTransform from .Nodes import Node, StatListNode from .ExprNodes import NameNode from .StringEncoding import _unicode from . import Parsing from . import Main from . import UtilNodes class StringParseContext(Main.Context): def __init__(self, name, include_directories=None, compiler_directives=None): if include_directories is None: include_directories = [] if compiler_directives is None: compiler_directives = {} Main.Context.__init__(self, include_directories, compiler_directives, create_testscope=False) self.module_name = name def find_module(self, module_name, relative_to=None, pos=None, need_pxd=1, absolute_fallback=True): if module_name not in (self.module_name, 'cython'): raise AssertionError("Not yet supporting any cimports/includes from string code snippets") return ModuleScope(module_name, parent_module=None, context=self) def parse_from_strings(name, code, pxds={}, level=None, initial_pos=None, context=None, allow_struct_enum_decorator=False): """ Utility method to parse a (unicode) string of code. This is mostly used for internal Cython compiler purposes (creating code snippets that transforms should emit, as well as unit testing). code - a unicode string containing Cython (module-level) code name - a descriptive name for the code source (to use in error messages etc.) RETURNS The tree, i.e. a ModuleNode. The ModuleNode's scope attribute is set to the scope used when parsing. """ if context is None: context = StringParseContext(name) # Since source files carry an encoding, it makes sense in this context # to use a unicode string so that code fragments don't have to bother # with encoding. This means that test code passed in should not have an # encoding header. assert isinstance(code, _unicode), "unicode code snippets only please" encoding = "UTF-8" module_name = name if initial_pos is None: initial_pos = (name, 1, 0) code_source = StringSourceDescriptor(name, code) scope = context.find_module(module_name, pos=initial_pos, need_pxd=False) buf = StringIO(code) scanner = PyrexScanner(buf, code_source, source_encoding = encoding, scope = scope, context = context, initial_pos = initial_pos) ctx = Parsing.Ctx(allow_struct_enum_decorator=allow_struct_enum_decorator) if level is None: tree = Parsing.p_module(scanner, 0, module_name, ctx=ctx) tree.scope = scope tree.is_pxd = False else: tree = Parsing.p_code(scanner, level=level, ctx=ctx) tree.scope = scope return tree class TreeCopier(VisitorTransform): def visit_Node(self, node): if node is None: return node else: c = node.clone_node() self.visitchildren(c) return c class ApplyPositionAndCopy(TreeCopier): def __init__(self, pos): super(ApplyPositionAndCopy, self).__init__() self.pos = pos def visit_Node(self, node): copy = super(ApplyPositionAndCopy, self).visit_Node(node) copy.pos = self.pos return copy class TemplateTransform(VisitorTransform): """ Makes a copy of a template tree while doing substitutions. A dictionary "substitutions" should be passed in when calling the transform; mapping names to replacement nodes. Then replacement happens like this: - If an ExprStatNode contains a single NameNode, whose name is a key in the substitutions dictionary, the ExprStatNode is replaced with a copy of the tree given in the dictionary. It is the responsibility of the caller that the replacement node is a valid statement. - If a single NameNode is otherwise encountered, it is replaced if its name is listed in the substitutions dictionary in the same way. It is the responsibility of the caller to make sure that the replacement nodes is a valid expression. Also a list "temps" should be passed. Any names listed will be transformed into anonymous, temporary names. Currently supported for tempnames is: NameNode (various function and class definition nodes etc. should be added to this) Each replacement node gets the position of the substituted node recursively applied to every member node. """ temp_name_counter = 0 def __call__(self, node, substitutions, temps, pos): self.substitutions = substitutions self.pos = pos tempmap = {} temphandles = [] for temp in temps: TemplateTransform.temp_name_counter += 1 handle = UtilNodes.TempHandle(PyrexTypes.py_object_type) tempmap[temp] = handle temphandles.append(handle) self.tempmap = tempmap result = super(TemplateTransform, self).__call__(node) if temps: result = UtilNodes.TempsBlockNode(self.get_pos(node), temps=temphandles, body=result) return result def get_pos(self, node): if self.pos: return self.pos else: return node.pos def visit_Node(self, node): if node is None: return None else: c = node.clone_node() if self.pos is not None: c.pos = self.pos self.visitchildren(c) return c def try_substitution(self, node, key): sub = self.substitutions.get(key) if sub is not None: pos = self.pos if pos is None: pos = node.pos return ApplyPositionAndCopy(pos)(sub) else: return self.visit_Node(node) # make copy as usual def visit_NameNode(self, node): temphandle = self.tempmap.get(node.name) if temphandle: # Replace name with temporary return temphandle.ref(self.get_pos(node)) else: return self.try_substitution(node, node.name) def visit_ExprStatNode(self, node): # If an expression-as-statement consists of only a replaceable # NameNode, we replace the entire statement, not only the NameNode if isinstance(node.expr, NameNode): return self.try_substitution(node, node.expr.name) else: return self.visit_Node(node) def copy_code_tree(node): return TreeCopier()(node) _match_indent = re.compile(u"^ *").match def strip_common_indent(lines): """Strips empty lines and common indentation from the list of strings given in lines""" # TODO: Facilitate textwrap.indent instead lines = [x for x in lines if x.strip() != u""] minindent = min([len(_match_indent(x).group(0)) for x in lines]) lines = [x[minindent:] for x in lines] return lines class TreeFragment(object): def __init__(self, code, name=None, pxds={}, temps=[], pipeline=[], level=None, initial_pos=None): if not name: name = "(tree fragment)" if isinstance(code, _unicode): def fmt(x): return u"\n".join(strip_common_indent(x.split(u"\n"))) fmt_code = fmt(code) fmt_pxds = {} for key, value in pxds.items(): fmt_pxds[key] = fmt(value) mod = t = parse_from_strings(name, fmt_code, fmt_pxds, level=level, initial_pos=initial_pos) if level is None: t = t.body # Make sure a StatListNode is at the top if not isinstance(t, StatListNode): t = StatListNode(pos=mod.pos, stats=[t]) for transform in pipeline: if transform is None: continue t = transform(t) self.root = t elif isinstance(code, Node): if pxds != {}: raise NotImplementedError() self.root = code else: raise ValueError("Unrecognized code format (accepts unicode and Node)") self.temps = temps def copy(self): return copy_code_tree(self.root) def substitute(self, nodes={}, temps=[], pos = None): return TemplateTransform()(self.root, substitutions = nodes, temps = self.temps + temps, pos = pos) class SetPosTransform(VisitorTransform): def __init__(self, pos): super(SetPosTransform, self).__init__() self.pos = pos def visit_Node(self, node): node.pos = self.pos self.visitchildren(node) return node Cython-0.23.4/Cython/Compiler/Symtab.py0000644000175600017570000030142212606202452021035 0ustar jenkinsjenkins00000000000000# # Symbol Table # from __future__ import absolute_import import copy import re try: import __builtin__ as builtins except ImportError: # Py3 import builtins from .Errors import warning, error, InternalError from .StringEncoding import EncodedString from . import Options, Naming from . import PyrexTypes from .PyrexTypes import py_object_type, unspecified_type from .TypeSlots import \ pyfunction_signature, pymethod_signature, \ get_special_method_signature, get_property_accessor_signature from . import Code iso_c99_keywords = set( ['auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do', 'double', 'else', 'enum', 'extern', 'float', 'for', 'goto', 'if', 'int', 'long', 'register', 'return', 'short', 'signed', 'sizeof', 'static', 'struct', 'switch', 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while', '_Bool', '_Complex'', _Imaginary', 'inline', 'restrict']) def c_safe_identifier(cname): # There are some C limitations on struct entry names. if ((cname[:2] == '__' and not (cname.startswith(Naming.pyrex_prefix) or cname == '__weakref__')) or cname in iso_c99_keywords): cname = Naming.pyrex_prefix + cname return cname class BufferAux(object): writable_needed = False def __init__(self, buflocal_nd_var, rcbuf_var): self.buflocal_nd_var = buflocal_nd_var self.rcbuf_var = rcbuf_var def __repr__(self): return "" % self.__dict__ class Entry(object): # A symbol table entry in a Scope or ModuleNamespace. # # name string Python name of entity # cname string C name of entity # type PyrexType Type of entity # doc string Doc string # init string Initial value # visibility 'private' or 'public' or 'extern' # is_builtin boolean Is an entry in the Python builtins dict # is_cglobal boolean Is a C global variable # is_pyglobal boolean Is a Python module-level variable # or class attribute during # class construction # is_member boolean Is an assigned class member # is_pyclass_attr boolean Is a name in a Python class namespace # is_variable boolean Is a variable # is_cfunction boolean Is a C function # is_cmethod boolean Is a C method of an extension type # is_builtin_cmethod boolean Is a C method of a builtin type (implies is_cmethod) # is_unbound_cmethod boolean Is an unbound C method of an extension type # is_final_cmethod boolean Is non-overridable C method # is_inline_cmethod boolean Is inlined C method # is_anonymous boolean Is a anonymous pyfunction entry # is_type boolean Is a type definition # is_cclass boolean Is an extension class # is_cpp_class boolean Is a C++ class # is_const boolean Is a constant # is_property boolean Is a property of an extension type: # doc_cname string or None C const holding the docstring # getter_cname string C func for getting property # setter_cname string C func for setting or deleting property # is_self_arg boolean Is the "self" arg of an exttype method # is_arg boolean Is the arg of a method # is_local boolean Is a local variable # in_closure boolean Is referenced in an inner scope # is_readonly boolean Can't be assigned to # func_cname string C func implementing Python func # func_modifiers [string] C function modifiers ('inline') # pos position Source position where declared # namespace_cname string If is_pyglobal, the C variable # holding its home namespace # pymethdef_cname string PyMethodDef structure # signature Signature Arg & return types for Python func # as_variable Entry Alternative interpretation of extension # type name or builtin C function as a variable # xdecref_cleanup boolean Use Py_XDECREF for error cleanup # in_cinclude boolean Suppress C declaration code # enum_values [Entry] For enum types, list of values # qualified_name string "modname.funcname" or "modname.classname" # or "modname.classname.funcname" # is_declared_generic boolean Is declared as PyObject * even though its # type is an extension type # as_module None Module scope, if a cimported module # is_inherited boolean Is an inherited attribute of an extension type # pystring_cname string C name of Python version of string literal # is_interned boolean For string const entries, value is interned # is_identifier boolean For string const entries, value is an identifier # used boolean # is_special boolean Is a special method or property accessor # of an extension type # defined_in_pxd boolean Is defined in a .pxd file (not just declared) # api boolean Generate C API for C class or function # utility_code string Utility code needed when this entry is used # # buffer_aux BufferAux or None Extra information needed for buffer variables # inline_func_in_pxd boolean Hacky special case for inline function in pxd file. # Ideally this should not be necesarry. # might_overflow boolean In an arithmetic expression that could cause # overflow (used for type inference). # utility_code_definition For some Cython builtins, the utility code # which contains the definition of the entry. # Currently only supported for CythonScope entries. # error_on_uninitialized Have Control Flow issue an error when this entry is # used uninitialized # cf_used boolean Entry is used # is_fused_specialized boolean Whether this entry of a cdef or def function # is a specialization # TODO: utility_code and utility_code_definition serves the same purpose... inline_func_in_pxd = False borrowed = 0 init = "" visibility = 'private' is_builtin = 0 is_cglobal = 0 is_pyglobal = 0 is_member = 0 is_pyclass_attr = 0 is_variable = 0 is_cfunction = 0 is_cmethod = 0 is_builtin_cmethod = False is_unbound_cmethod = 0 is_final_cmethod = 0 is_inline_cmethod = 0 is_anonymous = 0 is_type = 0 is_cclass = 0 is_cpp_class = 0 is_const = 0 is_property = 0 doc_cname = None getter_cname = None setter_cname = None is_self_arg = 0 is_arg = 0 is_local = 0 in_closure = 0 from_closure = 0 is_declared_generic = 0 is_readonly = 0 pyfunc_cname = None func_cname = None func_modifiers = [] final_func_cname = None doc = None as_variable = None xdecref_cleanup = 0 in_cinclude = 0 as_module = None is_inherited = 0 pystring_cname = None is_identifier = 0 is_interned = 0 used = 0 is_special = 0 defined_in_pxd = 0 is_implemented = 0 api = 0 utility_code = None is_overridable = 0 buffer_aux = None prev_entry = None might_overflow = 0 fused_cfunction = None is_fused_specialized = False utility_code_definition = None needs_property = False in_with_gil_block = 0 from_cython_utility_code = None error_on_uninitialized = False cf_used = True outer_entry = None def __init__(self, name, cname, type, pos = None, init = None): self.name = name self.cname = cname self.type = type self.pos = pos self.init = init self.overloaded_alternatives = [] self.cf_assignments = [] self.cf_references = [] self.inner_entries = [] self.defining_entry = self def __repr__(self): return "%s(<%x>, name=%s, type=%s)" % (type(self).__name__, id(self), self.name, self.type) def redeclared(self, pos): error(pos, "'%s' does not match previous declaration" % self.name) error(self.pos, "Previous declaration is here") def all_alternatives(self): return [self] + self.overloaded_alternatives def all_entries(self): return [self] + self.inner_entries class InnerEntry(Entry): """ An entry in a closure scope that represents the real outer Entry. """ from_closure = True def __init__(self, outer_entry, scope): Entry.__init__(self, outer_entry.name, outer_entry.cname, outer_entry.type, outer_entry.pos) self.outer_entry = outer_entry self.scope = scope # share state with (outermost) defining entry outermost_entry = outer_entry while outermost_entry.outer_entry: outermost_entry = outermost_entry.outer_entry self.defining_entry = outermost_entry self.inner_entries = outermost_entry.inner_entries self.cf_assignments = outermost_entry.cf_assignments self.cf_references = outermost_entry.cf_references self.overloaded_alternatives = outermost_entry.overloaded_alternatives self.inner_entries.append(self) def __getattr__(self, name): if name.startswith('__'): # we wouldn't have been called if it was there raise AttributeError(name) return getattr(self.defining_entry, name) def all_entries(self): return self.defining_entry.all_entries() class Scope(object): # name string Unqualified name # outer_scope Scope or None Enclosing scope # entries {string : Entry} Python name to entry, non-types # const_entries [Entry] Constant entries # type_entries [Entry] Struct/union/enum/typedef/exttype entries # sue_entries [Entry] Struct/union/enum entries # arg_entries [Entry] Function argument entries # var_entries [Entry] User-defined variable entries # pyfunc_entries [Entry] Python function entries # cfunc_entries [Entry] C function entries # c_class_entries [Entry] All extension type entries # cname_to_entry {string : Entry} Temp cname to entry mapping # return_type PyrexType or None Return type of function owning scope # is_builtin_scope boolean Is the builtin scope of Python/Cython # is_py_class_scope boolean Is a Python class scope # is_c_class_scope boolean Is an extension type scope # is_closure_scope boolean Is a closure scope # is_passthrough boolean Outer scope is passed directly # is_cpp_class_scope boolean Is a C++ class scope # is_property_scope boolean Is a extension type property scope # scope_prefix string Disambiguator for C names # in_cinclude boolean Suppress C declaration code # qualified_name string "modname" or "modname.classname" # Python strings in this scope # nogil boolean In a nogil section # directives dict Helper variable for the recursive # analysis, contains directive values. # is_internal boolean Is only used internally (simpler setup) is_builtin_scope = 0 is_py_class_scope = 0 is_c_class_scope = 0 is_closure_scope = 0 is_passthrough = 0 is_cpp_class_scope = 0 is_property_scope = 0 is_module_scope = 0 is_internal = 0 scope_prefix = "" in_cinclude = 0 nogil = 0 fused_to_specific = None def __init__(self, name, outer_scope, parent_scope): # The outer_scope is the next scope in the lookup chain. # The parent_scope is used to derive the qualified name of this scope. self.name = name self.outer_scope = outer_scope self.parent_scope = parent_scope mangled_name = "%d%s_" % (len(name), name.replace('.', '_dot_')) qual_scope = self.qualifying_scope() if qual_scope: self.qualified_name = qual_scope.qualify_name(name) self.scope_prefix = qual_scope.scope_prefix + mangled_name else: self.qualified_name = EncodedString(name) self.scope_prefix = mangled_name self.entries = {} self.const_entries = [] self.type_entries = [] self.sue_entries = [] self.arg_entries = [] self.var_entries = [] self.pyfunc_entries = [] self.cfunc_entries = [] self.c_class_entries = [] self.defined_c_classes = [] self.imported_c_classes = {} self.cname_to_entry = {} self.string_to_entry = {} self.identifier_to_entry = {} self.num_to_entry = {} self.obj_to_entry = {} self.buffer_entries = [] self.lambda_defs = [] self.return_type = None self.id_counters = {} def __deepcopy__(self, memo): return self def merge_in(self, other, merge_unused=True, whitelist=None): # Use with care... entries = [] for name, entry in other.entries.items(): if not whitelist or name in whitelist: if entry.used or merge_unused: entries.append((name, entry)) self.entries.update(entries) for attr in ('const_entries', 'type_entries', 'sue_entries', 'arg_entries', 'var_entries', 'pyfunc_entries', 'cfunc_entries', 'c_class_entries'): self_entries = getattr(self, attr) names = set(e.name for e in self_entries) for entry in getattr(other, attr): if (entry.used or merge_unused) and entry.name not in names: self_entries.append(entry) def __str__(self): return "<%s %s>" % (self.__class__.__name__, self.qualified_name) def qualifying_scope(self): return self.parent_scope def mangle(self, prefix, name = None): if name: return "%s%s%s" % (prefix, self.scope_prefix, name) else: return self.parent_scope.mangle(prefix, self.name) def mangle_internal(self, name): # Mangle an internal name so as not to clash with any # user-defined name in this scope. prefix = "%s%s_" % (Naming.pyrex_prefix, name) return self.mangle(prefix) #return self.parent_scope.mangle(prefix, self.name) def mangle_class_private_name(self, name): if self.parent_scope: return self.parent_scope.mangle_class_private_name(name) return name def next_id(self, name=None): # Return a cname fragment that is unique for this module counters = self.global_scope().id_counters try: count = counters[name] + 1 except KeyError: count = 0 counters[name] = count if name: if not count: # unique names don't need a suffix, reoccurrences will get one return name return '%s%d' % (name, count) else: return '%d' % count def global_scope(self): """ Return the module-level scope containing this scope. """ return self.outer_scope.global_scope() def builtin_scope(self): """ Return the module-level scope containing this scope. """ return self.outer_scope.builtin_scope() def declare(self, name, cname, type, pos, visibility, shadow = 0, is_type = 0, create_wrapper = 0): # Create new entry, and add to dictionary if # name is not None. Reports a warning if already # declared. if type.is_buffer and not isinstance(self, LocalScope): # and not is_type: error(pos, 'Buffer types only allowed as function local variables') if not self.in_cinclude and cname and re.match("^_[_A-Z]+$", cname): # See http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html#Reserved-Names warning(pos, "'%s' is a reserved name in C." % cname, -1) entries = self.entries if name and name in entries and not shadow: old_type = entries[name].type if self.is_cpp_class_scope and type.is_cfunction and old_type.is_cfunction and type != old_type: # C++ method overrides are ok pass elif visibility == 'extern': warning(pos, "'%s' redeclared " % name, 0) elif visibility != 'ignore': error(pos, "'%s' redeclared " % name) entry = Entry(name, cname, type, pos = pos) entry.in_cinclude = self.in_cinclude entry.create_wrapper = create_wrapper if name: entry.qualified_name = self.qualify_name(name) # if name in entries and self.is_cpp(): # entries[name].overloaded_alternatives.append(entry) # else: # entries[name] = entry if not shadow: entries[name] = entry if type.is_memoryviewslice: from . import MemoryView entry.init = MemoryView.memslice_entry_init entry.scope = self entry.visibility = visibility return entry def qualify_name(self, name): return EncodedString("%s.%s" % (self.qualified_name, name)) def declare_const(self, name, type, value, pos, cname = None, visibility = 'private', api = 0, create_wrapper = 0): # Add an entry for a named constant. if not cname: if self.in_cinclude or (visibility == 'public' or api): cname = name else: cname = self.mangle(Naming.enum_prefix, name) entry = self.declare(name, cname, type, pos, visibility, create_wrapper = create_wrapper) entry.is_const = 1 entry.value_node = value return entry def declare_type(self, name, type, pos, cname = None, visibility = 'private', api = 0, defining = 1, shadow = 0, template = 0): # Add an entry for a type definition. if not cname: cname = name entry = self.declare(name, cname, type, pos, visibility, shadow, is_type=True) entry.is_type = 1 entry.api = api if defining: self.type_entries.append(entry) if not template: type.entry = entry # here we would set as_variable to an object representing this type return entry def declare_typedef(self, name, base_type, pos, cname = None, visibility = 'private', api = 0): if not cname: if self.in_cinclude or (visibility == 'public' or api): cname = name else: cname = self.mangle(Naming.type_prefix, name) try: type = PyrexTypes.create_typedef_type(name, base_type, cname, (visibility == 'extern')) except ValueError as e: error(pos, e.args[0]) type = PyrexTypes.error_type entry = self.declare_type(name, type, pos, cname, visibility = visibility, api = api) type.qualified_name = entry.qualified_name return entry def declare_struct_or_union(self, name, kind, scope, typedef_flag, pos, cname = None, visibility = 'private', api = 0, packed = False): # Add an entry for a struct or union definition. if not cname: if self.in_cinclude or (visibility == 'public' or api): cname = name else: cname = self.mangle(Naming.type_prefix, name) entry = self.lookup_here(name) if not entry: type = PyrexTypes.CStructOrUnionType( name, kind, scope, typedef_flag, cname, packed) entry = self.declare_type(name, type, pos, cname, visibility = visibility, api = api, defining = scope is not None) self.sue_entries.append(entry) type.entry = entry else: if not (entry.is_type and entry.type.is_struct_or_union and entry.type.kind == kind): warning(pos, "'%s' redeclared " % name, 0) elif scope and entry.type.scope: warning(pos, "'%s' already defined (ignoring second definition)" % name, 0) else: self.check_previous_typedef_flag(entry, typedef_flag, pos) self.check_previous_visibility(entry, visibility, pos) if scope: entry.type.scope = scope self.type_entries.append(entry) return entry def declare_cpp_class(self, name, scope, pos, cname = None, base_classes = (), visibility = 'extern', templates = None): if cname is None: if self.in_cinclude or (visibility != 'private'): cname = name else: cname = self.mangle(Naming.type_prefix, name) base_classes = list(base_classes) entry = self.lookup_here(name) if not entry: type = PyrexTypes.CppClassType( name, scope, cname, base_classes, templates = templates) entry = self.declare_type(name, type, pos, cname, visibility = visibility, defining = scope is not None) self.sue_entries.append(entry) else: if not (entry.is_type and entry.type.is_cpp_class): error(pos, "'%s' redeclared " % name) return None elif scope and entry.type.scope: warning(pos, "'%s' already defined (ignoring second definition)" % name, 0) else: if scope: entry.type.scope = scope self.type_entries.append(entry) if base_classes: if entry.type.base_classes and entry.type.base_classes != base_classes: error(pos, "Base type does not match previous declaration") else: entry.type.base_classes = base_classes if templates or entry.type.templates: if templates != entry.type.templates: error(pos, "Template parameters do not match previous declaration") def declare_inherited_attributes(entry, base_classes): for base_class in base_classes: if base_class is PyrexTypes.error_type: continue if base_class.scope is None: error(pos, "Cannot inherit from incomplete type") else: declare_inherited_attributes(entry, base_class.base_classes) entry.type.scope.declare_inherited_cpp_attributes(base_class.scope) if scope: declare_inherited_attributes(entry, base_classes) scope.declare_var(name="this", cname="this", type=PyrexTypes.CPtrType(entry.type), pos=entry.pos) if self.is_cpp_class_scope: entry.type.namespace = self.outer_scope.lookup(self.name).type return entry def check_previous_typedef_flag(self, entry, typedef_flag, pos): if typedef_flag != entry.type.typedef_flag: error(pos, "'%s' previously declared using '%s'" % ( entry.name, ("cdef", "ctypedef")[entry.type.typedef_flag])) def check_previous_visibility(self, entry, visibility, pos): if entry.visibility != visibility: error(pos, "'%s' previously declared as '%s'" % ( entry.name, entry.visibility)) def declare_enum(self, name, pos, cname, typedef_flag, visibility = 'private', api = 0, create_wrapper = 0): if name: if not cname: if self.in_cinclude or (visibility == 'public' or api): cname = name else: cname = self.mangle(Naming.type_prefix, name) type = PyrexTypes.CEnumType(name, cname, typedef_flag) else: type = PyrexTypes.c_anon_enum_type entry = self.declare_type(name, type, pos, cname = cname, visibility = visibility, api = api) entry.create_wrapper = create_wrapper entry.enum_values = [] self.sue_entries.append(entry) return entry def declare_tuple_type(self, pos, components): return self.outer_scope.declare_tuple_type(pos, components) def declare_var(self, name, type, pos, cname = None, visibility = 'private', api = 0, in_pxd = 0, is_cdef = 0): # Add an entry for a variable. if not cname: if visibility != 'private' or api: cname = name else: cname = self.mangle(Naming.var_prefix, name) if type.is_cpp_class and visibility != 'extern': type.check_nullary_constructor(pos) entry = self.declare(name, cname, type, pos, visibility) entry.is_variable = 1 if in_pxd and visibility != 'extern': entry.defined_in_pxd = 1 entry.used = 1 if api: entry.api = 1 entry.used = 1 return entry def declare_builtin(self, name, pos): return self.outer_scope.declare_builtin(name, pos) def _declare_pyfunction(self, name, pos, visibility='extern', entry=None): if entry and not entry.type.is_cfunction: error(pos, "'%s' already declared" % name) error(entry.pos, "Previous declaration is here") entry = self.declare_var(name, py_object_type, pos, visibility=visibility) entry.signature = pyfunction_signature self.pyfunc_entries.append(entry) return entry def declare_pyfunction(self, name, pos, allow_redefine=False, visibility='extern'): # Add an entry for a Python function. entry = self.lookup_here(name) if not allow_redefine: return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry) if entry: if entry.type.is_unspecified: entry.type = py_object_type elif entry.type is not py_object_type: return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry) else: # declare entry stub self.declare_var(name, py_object_type, pos, visibility=visibility) entry = self.declare_var(None, py_object_type, pos, cname=name, visibility='private') entry.name = EncodedString(name) entry.qualified_name = self.qualify_name(name) entry.signature = pyfunction_signature entry.is_anonymous = True return entry def declare_lambda_function(self, lambda_name, pos): # Add an entry for an anonymous Python function. func_cname = self.mangle(Naming.lambda_func_prefix + u'funcdef_', lambda_name) pymethdef_cname = self.mangle(Naming.lambda_func_prefix + u'methdef_', lambda_name) qualified_name = self.qualify_name(lambda_name) entry = self.declare(None, func_cname, py_object_type, pos, 'private') entry.name = lambda_name entry.qualified_name = qualified_name entry.pymethdef_cname = pymethdef_cname entry.func_cname = func_cname entry.signature = pyfunction_signature entry.is_anonymous = True return entry def add_lambda_def(self, def_node): self.lambda_defs.append(def_node) def register_pyfunction(self, entry): self.pyfunc_entries.append(entry) def declare_cfunction(self, name, type, pos, cname=None, visibility='private', api=0, in_pxd=0, defining=0, modifiers=(), utility_code=None, overridable=False): # Add an entry for a C function. if not cname: if visibility != 'private' or api: cname = name else: cname = self.mangle(Naming.func_prefix, name) entry = self.lookup_here(name) if entry: if not in_pxd and visibility != entry.visibility and visibility == 'extern': # Previously declared, but now extern => treat this # as implementing the function, using the new cname defining = True visibility = entry.visibility entry.cname = cname entry.func_cname = cname if visibility != 'private' and visibility != entry.visibility: warning(pos, "Function '%s' previously declared as '%s', now as '%s'" % (name, entry.visibility, visibility), 1) if overridable != entry.is_overridable: warning(pos, "Function '%s' previously declared as '%s'" % ( name, 'cpdef' if overridable else 'cdef'), 1) if not entry.type.same_as(type): if visibility == 'extern' and entry.visibility == 'extern': can_override = False if self.is_cpp(): can_override = True elif cname: # if all alternatives have different cnames, # it's safe to allow signature overrides for alt_entry in entry.all_alternatives(): if not alt_entry.cname or cname == alt_entry.cname: break # cname not unique! else: can_override = True if can_override: temp = self.add_cfunction(name, type, pos, cname, visibility, modifiers) temp.overloaded_alternatives = entry.all_alternatives() entry = temp else: warning(pos, "Function signature does not match previous declaration", 1) entry.type = type else: error(pos, "Function signature does not match previous declaration") else: entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers) entry.func_cname = cname entry.is_overridable = overridable if in_pxd and visibility != 'extern': entry.defined_in_pxd = 1 if api: entry.api = 1 if not defining and not in_pxd and visibility != 'extern': error(pos, "Non-extern C function '%s' declared but not defined" % name) if defining: entry.is_implemented = True if modifiers: entry.func_modifiers = modifiers if utility_code: assert not entry.utility_code, "duplicate utility code definition in entry %s (%s)" % (name, cname) entry.utility_code = utility_code if overridable: # names of cpdef functions can be used as variables and can be assigned to var_entry = Entry(name, cname, py_object_type) # FIXME: cname? var_entry.is_variable = 1 var_entry.is_pyglobal = 1 var_entry.scope = entry.scope entry.as_variable = var_entry type.entry = entry return entry def add_cfunction(self, name, type, pos, cname, visibility, modifiers): # Add a C function entry without giving it a func_cname. entry = self.declare(name, cname, type, pos, visibility) entry.is_cfunction = 1 if modifiers: entry.func_modifiers = modifiers self.cfunc_entries.append(entry) return entry def find(self, name, pos): # Look up name, report error if not found. entry = self.lookup(name) if entry: return entry else: error(pos, "'%s' is not declared" % name) def find_imported_module(self, path, pos): # Look up qualified name, must be a module, report error if not found. # Path is a list of names. scope = self for name in path: entry = scope.find(name, pos) if not entry: return None if entry.as_module: scope = entry.as_module else: error(pos, "'%s' is not a cimported module" % '.'.join(path)) return None return scope def lookup(self, name): # Look up name in this scope or an enclosing one. # Return None if not found. return (self.lookup_here(name) or (self.outer_scope and self.outer_scope.lookup(name)) or None) def lookup_here(self, name): # Look up in this scope only, return None if not found. return self.entries.get(name, None) def lookup_target(self, name): # Look up name in this scope only. Declare as Python # variable if not found. entry = self.lookup_here(name) if not entry: entry = self.declare_var(name, py_object_type, None) return entry def lookup_type(self, name): entry = self.lookup(name) if entry and entry.is_type: if entry.type.is_fused and self.fused_to_specific: return entry.type.specialize(self.fused_to_specific) return entry.type def lookup_operator(self, operator, operands): if operands[0].type.is_cpp_class: obj_type = operands[0].type method = obj_type.scope.lookup("operator%s" % operator) if method is not None: res = PyrexTypes.best_match(operands[1:], method.all_alternatives()) if res is not None: return res function = self.lookup("operator%s" % operator) if function is None: return None return PyrexTypes.best_match(operands, function.all_alternatives()) def lookup_operator_for_types(self, pos, operator, types): from .Nodes import Node class FakeOperand(Node): pass operands = [FakeOperand(pos, type=type) for type in types] return self.lookup_operator(operator, operands) def use_utility_code(self, new_code): self.global_scope().use_utility_code(new_code) def generate_library_function_declarations(self, code): # Generate extern decls for C library funcs used. pass def defines_any(self, names): # Test whether any of the given names are # defined in this scope. for name in names: if name in self.entries: return 1 return 0 def infer_types(self): from .TypeInference import get_type_inferer get_type_inferer().infer_types(self) def is_cpp(self): outer = self.outer_scope if outer is None: return False else: return outer.is_cpp() def add_include_file(self, filename): self.outer_scope.add_include_file(filename) class PreImportScope(Scope): namespace_cname = Naming.preimport_cname def __init__(self): Scope.__init__(self, Options.pre_import, None, None) def declare_builtin(self, name, pos): entry = self.declare(name, name, py_object_type, pos, 'private') entry.is_variable = True entry.is_pyglobal = True return entry class BuiltinScope(Scope): # The builtin namespace. is_builtin_scope = True def __init__(self): if Options.pre_import is None: Scope.__init__(self, "__builtin__", None, None) else: Scope.__init__(self, "__builtin__", PreImportScope(), None) self.type_names = {} for name, definition in sorted(self.builtin_entries.items()): cname, type = definition 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): if not hasattr(builtins, name): if self.outer_scope is not None: return self.outer_scope.declare_builtin(name, pos) else: if Options.error_on_unknown_names: error(pos, "undeclared name not builtin: %s" % name) else: warning(pos, "undeclared name not builtin: %s" % name, 2) def declare_builtin_cfunction(self, name, type, cname, python_equiv=None, utility_code=None): # If python_equiv == "*", the Python equivalent has the same name # as the entry, otherwise it has the name specified by python_equiv. name = EncodedString(name) entry = self.declare_cfunction(name, type, None, cname, visibility='extern', utility_code=utility_code) if python_equiv: if python_equiv == "*": python_equiv = name else: python_equiv = EncodedString(python_equiv) var_entry = Entry(python_equiv, python_equiv, py_object_type) var_entry.is_variable = 1 var_entry.is_builtin = 1 var_entry.utility_code = utility_code var_entry.scope = entry.scope entry.as_variable = var_entry return entry def declare_builtin_type(self, name, cname, utility_code = None, objstruct_cname = None): name = EncodedString(name) type = PyrexTypes.BuiltinObjectType(name, cname, objstruct_cname) scope = CClassScope(name, outer_scope=None, visibility='extern') scope.directives = {} if name == 'bool': type.is_final_type = True type.set_scope(scope) self.type_names[name] = 1 entry = self.declare_type(name, type, None, visibility='extern') entry.utility_code = utility_code var_entry = Entry(name = entry.name, type = self.lookup('type').type, # make sure "type" is the first type declared... pos = entry.pos, cname = entry.type.typeptr_cname) var_entry.is_variable = 1 var_entry.is_cglobal = 1 var_entry.is_readonly = 1 var_entry.is_builtin = 1 var_entry.utility_code = utility_code if Options.cache_builtins: var_entry.is_const = True entry.as_variable = var_entry return type def builtin_scope(self): return self builtin_entries = { "type": ["((PyObject*)&PyType_Type)", py_object_type], "bool": ["((PyObject*)&PyBool_Type)", py_object_type], "int": ["((PyObject*)&PyInt_Type)", py_object_type], "long": ["((PyObject*)&PyLong_Type)", py_object_type], "float": ["((PyObject*)&PyFloat_Type)", py_object_type], "complex":["((PyObject*)&PyComplex_Type)", py_object_type], "bytes": ["((PyObject*)&PyBytes_Type)", py_object_type], "bytearray": ["((PyObject*)&PyByteArray_Type)", py_object_type], "str": ["((PyObject*)&PyString_Type)", py_object_type], "unicode":["((PyObject*)&PyUnicode_Type)", py_object_type], "tuple": ["((PyObject*)&PyTuple_Type)", py_object_type], "list": ["((PyObject*)&PyList_Type)", py_object_type], "dict": ["((PyObject*)&PyDict_Type)", py_object_type], "set": ["((PyObject*)&PySet_Type)", py_object_type], "frozenset": ["((PyObject*)&PyFrozenSet_Type)", py_object_type], "slice": ["((PyObject*)&PySlice_Type)", py_object_type], # "file": ["((PyObject*)&PyFile_Type)", py_object_type], # not in Py3 "None": ["Py_None", py_object_type], "False": ["Py_False", py_object_type], "True": ["Py_True", py_object_type], } const_counter = 1 # As a temporary solution for compiling code in pxds class ModuleScope(Scope): # module_name string Python name of the module # module_cname string C name of Python module object # #module_dict_cname string C name of module dict object # method_table_cname string C name of method table # doc string Module doc string # doc_cname string C name of module doc string # utility_code_list [UtilityCode] Queuing utility codes for forwarding to Code.py # python_include_files [string] Standard Python headers to be included # include_files [string] Other C headers to be included # string_to_entry {string : Entry} Map string const to entry # identifier_to_entry {string : Entry} Map identifier string const to entry # context Context # parent_module Scope Parent in the import namespace # module_entries {string : Entry} For cimport statements # type_names {string : 1} Set of type names (used during parsing) # included_files [string] Cython sources included with 'include' # pxd_file_loaded boolean Corresponding .pxd file has been processed # cimported_modules [ModuleScope] Modules imported with cimport # types_imported {PyrexType} Set of types for which import code generated # has_import_star boolean Module contains import * # cpp boolean Compiling a C++ file # is_cython_builtin boolean Is this the Cython builtin scope (or a child scope) # is_package boolean Is this a package module? (__init__) is_module_scope = 1 has_import_star = 0 is_cython_builtin = 0 def __init__(self, name, parent_module, context): from . import Builtin self.parent_module = parent_module outer_scope = Builtin.builtin_scope Scope.__init__(self, name, outer_scope, parent_module) if name == "__init__": # Treat Spam/__init__.pyx specially, so that when Python loads # Spam/__init__.so, initSpam() is defined. self.module_name = parent_module.module_name self.is_package = True else: self.module_name = name self.is_package = False self.module_name = EncodedString(self.module_name) self.context = context self.module_cname = Naming.module_cname self.module_dict_cname = Naming.moddict_cname self.method_table_cname = Naming.methtable_cname self.doc = "" self.doc_cname = Naming.moddoc_cname self.utility_code_list = [] self.module_entries = {} self.python_include_files = ["Python.h"] self.include_files = [] self.type_names = dict(outer_scope.type_names) self.pxd_file_loaded = 0 self.cimported_modules = [] self.types_imported = set() self.included_files = [] self.has_extern_class = 0 self.cached_builtins = [] self.undeclared_cached_builtins = [] self.namespace_cname = self.module_cname self._cached_tuple_types = {} for var_name in ['__builtins__', '__name__', '__file__', '__doc__', '__path__']: self.declare_var(EncodedString(var_name), py_object_type, None) def qualifying_scope(self): return self.parent_module def global_scope(self): return self def lookup(self, name, language_level=None): entry = self.lookup_here(name) if entry is not None: return entry if language_level is None: language_level = self.context.language_level if self.context is not None else 3 return self.outer_scope.lookup(name, language_level=language_level) def declare_tuple_type(self, pos, components): components = tuple(components) try: ttype = self._cached_tuple_types[components] except KeyError: ttype = self._cached_tuple_types[components] = PyrexTypes.c_tuple_type(components) cname = ttype.cname entry = self.lookup_here(cname) if not entry: scope = StructOrUnionScope(cname) for ix, component in enumerate(components): scope.declare_var(name="f%s" % ix, type=component, pos=pos) struct_entry = self.declare_struct_or_union( cname + '_struct', 'struct', scope, typedef_flag=True, pos=pos, cname=cname) self.type_entries.remove(struct_entry) ttype.struct_entry = struct_entry entry = self.declare_type(cname, ttype, pos, cname) ttype.entry = entry return entry def declare_builtin(self, name, pos): if not hasattr(builtins, name) \ and name not in Code.non_portable_builtins_map \ and name not in Code.uncachable_builtins: if self.has_import_star: entry = self.declare_var(name, py_object_type, pos) return entry else: if Options.error_on_unknown_names: error(pos, "undeclared name not builtin: %s" % name) else: warning(pos, "undeclared name not builtin: %s" % name, 2) # unknown - assume it's builtin and look it up at runtime entry = self.declare(name, None, py_object_type, pos, 'private') entry.is_builtin = 1 return entry if Options.cache_builtins: for entry in self.cached_builtins: if entry.name == name: return entry entry = self.declare(None, None, py_object_type, pos, 'private') if Options.cache_builtins and name not in Code.uncachable_builtins: entry.is_builtin = 1 entry.is_const = 1 # cached entry.name = name entry.cname = Naming.builtin_prefix + name self.cached_builtins.append(entry) self.undeclared_cached_builtins.append(entry) else: entry.is_builtin = 1 entry.name = name return entry def find_module(self, module_name, pos, relative_level=-1): # Find a module in the import namespace, interpreting # relative imports relative to this module's parent. # Finds and parses the module's .pxd file if the module # has not been referenced before. relative_to = None absolute_fallback = False if relative_level is not None and relative_level > 0: # explicit relative cimport # error of going beyond top-level is handled in cimport node relative_to = self while relative_level > 0 and relative_to: relative_to = relative_to.parent_module relative_level -= 1 elif relative_level != 0: # -1 or None: try relative cimport first, then absolute relative_to = self.parent_module absolute_fallback = True module_scope = self.global_scope() return module_scope.context.find_module( module_name, relative_to=relative_to, pos=pos, absolute_fallback=absolute_fallback) def find_submodule(self, name): # Find and return scope for a submodule of this module, # creating a new empty one if necessary. Doesn't parse .pxd. if '.' in name: name, submodule = name.split('.', 1) else: submodule = None scope = self.lookup_submodule(name) if not scope: scope = ModuleScope(name, parent_module=self, context=self.context) self.module_entries[name] = scope if submodule: scope = scope.find_submodule(submodule) return scope def lookup_submodule(self, name): # Return scope for submodule of this module, or None. if '.' in name: name, submodule = name.split('.', 1) else: submodule = None module = self.module_entries.get(name, None) if submodule and module is not None: module = module.lookup_submodule(submodule) return module def add_include_file(self, filename): if filename not in self.python_include_files \ and filename not in self.include_files: self.include_files.append(filename) def add_imported_module(self, scope): if scope not in self.cimported_modules: for filename in scope.include_files: self.add_include_file(filename) self.cimported_modules.append(scope) for m in scope.cimported_modules: self.add_imported_module(m) def add_imported_entry(self, name, entry, pos): if entry not in self.entries: self.entries[name] = entry else: warning(pos, "'%s' redeclared " % name, 0) def declare_module(self, name, scope, pos): # Declare a cimported module. This is represented as a # Python module-level variable entry with a module # scope attached to it. Reports an error and returns # None if previously declared as something else. entry = self.lookup_here(name) if entry: if entry.is_pyglobal and entry.as_module is scope: return entry # Already declared as the same module if not (entry.is_pyglobal and not entry.as_module): # SAGE -- I put this here so Pyrex # cimport's work across directories. # Currently it tries to multiply define # every module appearing in an import list. # It shouldn't be an error for a module # name to appear again, and indeed the generated # code compiles fine. return entry else: entry = self.declare_var(name, py_object_type, pos) entry.as_module = scope self.add_imported_module(scope) return entry def declare_var(self, name, type, pos, cname = None, visibility = 'private', api = 0, in_pxd = 0, is_cdef = 0): # Add an entry for a global variable. If it is a Python # object type, and not declared with cdef, it will live # in the module dictionary, otherwise it will be a C # global variable. if not visibility in ('private', 'public', 'extern'): error(pos, "Module-level variable cannot be declared %s" % visibility) if not is_cdef: if type is unspecified_type: type = py_object_type if not (type.is_pyobject and not type.is_extension_type): raise InternalError( "Non-cdef global variable is not a generic Python object") if not cname: defining = not in_pxd if visibility == 'extern' or (visibility == 'public' and defining): cname = name else: cname = self.mangle(Naming.var_prefix, name) entry = self.lookup_here(name) if entry and entry.defined_in_pxd: #if visibility != 'private' and visibility != entry.visibility: # warning(pos, "Variable '%s' previously declared as '%s'" % (name, entry.visibility), 1) if not entry.type.same_as(type): if visibility == 'extern' and entry.visibility == 'extern': warning(pos, "Variable '%s' type does not match previous declaration" % name, 1) entry.type = type #else: # error(pos, "Variable '%s' type does not match previous declaration" % name) if entry.visibility != "private": mangled_cname = self.mangle(Naming.var_prefix, name) if entry.cname == mangled_cname: cname = name entry.cname = name if not entry.is_implemented: entry.is_implemented = True return entry entry = Scope.declare_var(self, name, type, pos, cname=cname, visibility=visibility, api=api, in_pxd=in_pxd, is_cdef=is_cdef) if is_cdef: entry.is_cglobal = 1 if entry.type.is_pyobject: entry.init = 0 self.var_entries.append(entry) else: entry.is_pyglobal = 1 if Options.cimport_from_pyx: entry.used = 1 return entry def declare_cfunction(self, name, type, pos, cname=None, visibility='private', api=0, in_pxd=0, defining=0, modifiers=(), utility_code=None, overridable=False): # Add an entry for a C function. if not cname: if visibility == 'extern' or (visibility == 'public' and defining): cname = name else: cname = self.mangle(Naming.func_prefix, name) if visibility == 'extern' and type.optional_arg_count: error(pos, "Extern functions cannot have default arguments values.") entry = self.lookup_here(name) if entry and entry.defined_in_pxd: if entry.visibility != "private": mangled_cname = self.mangle(Naming.var_prefix, name) if entry.cname == mangled_cname: cname = name entry.cname = cname entry.func_cname = cname entry = Scope.declare_cfunction( self, name, type, pos, cname=cname, visibility=visibility, api=api, in_pxd=in_pxd, defining=defining, modifiers=modifiers, utility_code=utility_code, overridable=overridable) return entry def declare_global(self, name, pos): entry = self.lookup_here(name) if not entry: self.declare_var(name, py_object_type, pos) def use_utility_code(self, new_code): if new_code is not None: self.utility_code_list.append(new_code) def declare_c_class(self, name, pos, defining = 0, implementing = 0, module_name = None, base_type = None, objstruct_cname = None, typeobj_cname = None, typeptr_cname = None, visibility = 'private', typedef_flag = 0, api = 0, buffer_defaults = None, shadow = 0): # If this is a non-extern typedef class, expose the typedef, but use # the non-typedef struct internally to avoid needing forward # declarations for anonymous structs. if typedef_flag and visibility != 'extern': if not (visibility == 'public' or api): warning(pos, "ctypedef only valid for 'extern' , 'public', and 'api'", 2) objtypedef_cname = objstruct_cname typedef_flag = 0 else: objtypedef_cname = None # # Look for previous declaration as a type # entry = self.lookup_here(name) if entry and not shadow: type = entry.type if not (entry.is_type and type.is_extension_type): entry = None # Will cause redeclaration and produce an error else: scope = type.scope if typedef_flag and (not scope or scope.defined): self.check_previous_typedef_flag(entry, typedef_flag, pos) if (scope and scope.defined) or (base_type and type.base_type): if base_type and base_type is not type.base_type: error(pos, "Base type does not match previous declaration") if base_type and not type.base_type: type.base_type = base_type # # Make a new entry if needed # if not entry or shadow: type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type, visibility == 'extern') type.pos = pos type.buffer_defaults = buffer_defaults if objtypedef_cname is not None: type.objtypedef_cname = objtypedef_cname if visibility == 'extern': type.module_name = module_name else: type.module_name = self.qualified_name if typeptr_cname: type.typeptr_cname = typeptr_cname else: type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name) entry = self.declare_type(name, type, pos, visibility = visibility, defining = 0, shadow = shadow) entry.is_cclass = True if objstruct_cname: type.objstruct_cname = objstruct_cname elif not entry.in_cinclude: type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name) else: error(entry.pos, "Object name required for 'public' or 'extern' C class") self.attach_var_entry_to_c_class(entry) self.c_class_entries.append(entry) # # Check for re-definition and create scope if needed # if not type.scope: if defining or implementing: scope = CClassScope(name = name, outer_scope = self, visibility = visibility) scope.directives = self.directives.copy() if base_type and base_type.scope: scope.declare_inherited_c_attributes(base_type.scope) type.set_scope(scope) self.type_entries.append(entry) else: if defining and type.scope.defined: error(pos, "C class '%s' already defined" % name) elif implementing and type.scope.implemented: error(pos, "C class '%s' already implemented" % name) # # Fill in options, checking for compatibility with any previous declaration # if defining: entry.defined_in_pxd = 1 if implementing: # So that filenames in runtime exceptions refer to entry.pos = pos # the .pyx file and not the .pxd file if visibility != 'private' and entry.visibility != visibility: error(pos, "Class '%s' previously declared as '%s'" % (name, entry.visibility)) if api: entry.api = 1 if objstruct_cname: if type.objstruct_cname and type.objstruct_cname != objstruct_cname: error(pos, "Object struct name differs from previous declaration") type.objstruct_cname = objstruct_cname if typeobj_cname: if type.typeobj_cname and type.typeobj_cname != typeobj_cname: error(pos, "Type object name differs from previous declaration") type.typeobj_cname = typeobj_cname if self.directives.get('final'): entry.type.is_final_type = True # cdef classes are always exported, but we need to set it to # distinguish between unused Cython utility code extension classes entry.used = True # # Return new or existing entry # return entry def allocate_vtable_names(self, entry): # If extension type has a vtable, allocate vtable struct and # slot names for it. type = entry.type if type.base_type and type.base_type.vtabslot_cname: #print "...allocating vtabslot_cname because base type has one" ### type.vtabslot_cname = "%s.%s" % ( Naming.obj_base_cname, type.base_type.vtabslot_cname) 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" ### type.vtabslot_cname = Naming.vtabslot_cname if type.vtabslot_cname: #print "...allocating other vtable related cnames" ### type.vtabstruct_cname = self.mangle(Naming.vtabstruct_prefix, entry.name) type.vtabptr_cname = self.mangle(Naming.vtabptr_prefix, entry.name) def check_c_classes_pxd(self): # Performs post-analysis checking and finishing up of extension types # being implemented in this module. This is called only for the .pxd. # # Checks all extension types declared in this scope to # make sure that: # # * The extension type is fully declared # # Also allocates a name for the vtable if needed. # for entry in self.c_class_entries: # Check defined if not entry.type.scope: error(entry.pos, "C class '%s' is declared but not defined" % entry.name) def check_c_class(self, entry): type = entry.type name = entry.name visibility = entry.visibility # Check defined if not type.scope: error(entry.pos, "C class '%s' is declared but not defined" % name) # Generate typeobj_cname if visibility != 'extern' and not type.typeobj_cname: type.typeobj_cname = self.mangle(Naming.typeobj_prefix, name) ## Generate typeptr_cname #type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name) # Check C methods defined if type.scope: for method_entry in type.scope.cfunc_entries: if not method_entry.is_inherited and not method_entry.func_cname: error(method_entry.pos, "C method '%s' is declared but not defined" % method_entry.name) # Allocate vtable name if necessary if type.vtabslot_cname: #print "ModuleScope.check_c_classes: allocating vtable cname for", self ### type.vtable_cname = self.mangle(Naming.vtable_prefix, entry.name) def check_c_classes(self): # Performs post-analysis checking and finishing up of extension types # being implemented in this module. This is called only for the main # .pyx file scope, not for cimported .pxd scopes. # # Checks all extension types declared in this scope to # make sure that: # # * The extension type is implemented # * All required object and type names have been specified or generated # * All non-inherited C methods are implemented # # Also allocates a name for the vtable if needed. # debug_check_c_classes = 0 if debug_check_c_classes: print("Scope.check_c_classes: checking scope " + self.qualified_name) for entry in self.c_class_entries: if debug_check_c_classes: print("...entry %s %s" % (entry.name, entry)) print("......type = ", entry.type) print("......visibility = ", entry.visibility) self.check_c_class(entry) def check_c_functions(self): # Performs post-analysis checking making sure all # defined c functions are actually implemented. for name, entry in self.entries.items(): if entry.is_cfunction: if (entry.defined_in_pxd and entry.scope is self and entry.visibility != 'extern' and not entry.in_cinclude and not entry.is_implemented): error(entry.pos, "Non-extern C function '%s' declared but not defined" % name) def attach_var_entry_to_c_class(self, entry): # The name of an extension class has to serve as both a type # name and a variable name holding the type object. It is # represented in the symbol table by a type entry with a # variable entry attached to it. For the variable entry, # we use a read-only C global variable whose name is an # expression that refers to the type object. from . import Builtin var_entry = Entry(name = entry.name, type = Builtin.type_type, pos = entry.pos, cname = entry.type.typeptr_cname) var_entry.is_variable = 1 var_entry.is_cglobal = 1 var_entry.is_readonly = 1 entry.as_variable = var_entry def is_cpp(self): return self.cpp def infer_types(self): from .TypeInference import PyObjectTypeInferer PyObjectTypeInferer().infer_types(self) class LocalScope(Scope): # Does the function have a 'with gil:' block? has_with_gil_block = False # Transient attribute, used for symbol table variable declarations _in_with_gil_block = False def __init__(self, name, outer_scope, parent_scope = None): if parent_scope is None: parent_scope = outer_scope Scope.__init__(self, name, outer_scope, parent_scope) def mangle(self, prefix, name): return prefix + name def declare_arg(self, name, type, pos): # Add an entry for an argument of a function. cname = self.mangle(Naming.var_prefix, name) entry = self.declare(name, cname, type, pos, 'private') entry.is_variable = 1 if type.is_pyobject: entry.init = "0" entry.is_arg = 1 #entry.borrowed = 1 # Not using borrowed arg refs for now self.arg_entries.append(entry) return entry def declare_var(self, name, type, pos, cname = None, visibility = 'private', api = 0, in_pxd = 0, is_cdef = 0): # Add an entry for a local variable. if visibility in ('public', 'readonly'): error(pos, "Local variable cannot be declared %s" % visibility) entry = Scope.declare_var(self, name, type, pos, cname=cname, visibility=visibility, api=api, in_pxd=in_pxd, is_cdef=is_cdef) if type.is_pyobject: entry.init = "0" entry.is_local = 1 entry.in_with_gil_block = self._in_with_gil_block self.var_entries.append(entry) return entry def declare_global(self, name, pos): # Pull entry from global scope into local scope. if self.lookup_here(name): warning(pos, "'%s' redeclared ", 0) else: entry = self.global_scope().lookup_target(name) self.entries[name] = entry def declare_nonlocal(self, name, pos): # Pull entry from outer scope into local scope orig_entry = self.lookup_here(name) if orig_entry and orig_entry.scope is self and not orig_entry.from_closure: error(pos, "'%s' redeclared as nonlocal" % name) else: entry = self.lookup(name) if entry is None or not entry.from_closure: error(pos, "no binding for nonlocal '%s' found" % name) def lookup(self, name): # Look up name in this scope or an enclosing one. # Return None if not found. entry = Scope.lookup(self, name) if entry is not None: if entry.scope is not self and entry.scope.is_closure_scope: if hasattr(entry.scope, "scope_class"): raise InternalError("lookup() after scope class created.") # The actual c fragment for the different scopes differs # on the outside and inside, so we make a new entry entry.in_closure = True inner_entry = InnerEntry(entry, self) inner_entry.is_variable = True self.entries[name] = inner_entry return inner_entry return entry def mangle_closure_cnames(self, outer_scope_cname): for entry in self.entries.values(): if entry.from_closure: cname = entry.outer_entry.cname if self.is_passthrough: entry.cname = cname else: if cname.startswith(Naming.cur_scope_cname): cname = cname[len(Naming.cur_scope_cname)+2:] entry.cname = "%s->%s" % (outer_scope_cname, cname) elif entry.in_closure: entry.original_cname = entry.cname entry.cname = "%s->%s" % (Naming.cur_scope_cname, entry.cname) class GeneratorExpressionScope(Scope): """Scope for generator expressions and comprehensions. As opposed to generators, these can be easily inlined in some cases, so all we really need is a scope that holds the loop variable(s). """ def __init__(self, outer_scope): name = outer_scope.global_scope().next_id(Naming.genexpr_id_ref) Scope.__init__(self, name, outer_scope, outer_scope) self.directives = outer_scope.directives self.genexp_prefix = "%s%d%s" % (Naming.pyrex_prefix, len(name), name) def mangle(self, prefix, name): return '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(prefix, name)) def declare_var(self, name, type, pos, cname = None, visibility = 'private', api = 0, in_pxd = 0, is_cdef = True): if type is unspecified_type: # if the outer scope defines a type for this variable, inherit it outer_entry = self.outer_scope.lookup(name) if outer_entry and outer_entry.is_variable: type = outer_entry.type # may still be 'unspecified_type' ! # the parent scope needs to generate code for the variable, but # this scope must hold its name exclusively cname = '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(Naming.var_prefix, name or self.next_id())) entry = self.declare(name, cname, type, pos, visibility) entry.is_variable = 1 entry.is_local = 1 self.var_entries.append(entry) self.entries[name] = entry return entry def declare_pyfunction(self, name, pos, allow_redefine=False): return self.outer_scope.declare_pyfunction( name, pos, allow_redefine) def declare_lambda_function(self, func_cname, pos): return self.outer_scope.declare_lambda_function(func_cname, pos) def add_lambda_def(self, def_node): return self.outer_scope.add_lambda_def(def_node) class ClosureScope(LocalScope): is_closure_scope = True def __init__(self, name, scope_name, outer_scope, parent_scope=None): LocalScope.__init__(self, name, outer_scope, parent_scope) self.closure_cname = "%s%s" % (Naming.closure_scope_prefix, scope_name) # def mangle_closure_cnames(self, scope_var): # for entry in self.entries.values() + self.temp_entries: # entry.in_closure = 1 # LocalScope.mangle_closure_cnames(self, scope_var) # def mangle(self, prefix, name): # return "%s->%s" % (self.cur_scope_cname, name) # return "%s->%s" % (self.closure_cname, name) def declare_pyfunction(self, name, pos, allow_redefine=False): return LocalScope.declare_pyfunction(self, name, pos, allow_redefine, visibility='private') class StructOrUnionScope(Scope): # Namespace of a C struct or union. def __init__(self, name="?"): Scope.__init__(self, name, None, None) def declare_var(self, name, type, pos, cname = None, visibility = 'private', api = 0, in_pxd = 0, is_cdef = 0, allow_pyobject = 0): # Add an entry for an attribute. if not cname: cname = name if visibility == 'private': cname = c_safe_identifier(cname) if type.is_cfunction: type = PyrexTypes.CPtrType(type) entry = self.declare(name, cname, type, pos, visibility) entry.is_variable = 1 self.var_entries.append(entry) if type.is_pyobject and not allow_pyobject: error(pos, "C struct/union member cannot be a Python object") if visibility != 'private': error(pos, "C struct/union member cannot be declared %s" % visibility) return entry def declare_cfunction(self, name, type, pos, cname=None, visibility='private', api=0, in_pxd=0, defining=0, modifiers=(), overridable=False): # currently no utility code ... if overridable: error(pos, "C struct/union member cannot be declared 'cpdef'") return self.declare_var(name, type, pos, cname=cname, visibility=visibility) class ClassScope(Scope): # Abstract base class for namespace of # Python class or extension type. # # class_name string Python name of the class # scope_prefix string Additional prefix for names # declared in the class # doc string or None Doc string def __init__(self, name, outer_scope): Scope.__init__(self, name, outer_scope, outer_scope) self.class_name = name self.doc = None def lookup(self, name): entry = Scope.lookup(self, name) if entry: return entry if name == "classmethod": # We don't want to use the builtin classmethod here 'cause it won't do the # right thing in this scope (as the class members aren't still functions). # Don't want to add a cfunction to this scope 'cause that would mess with # the type definition, so we just return the right entry. entry = Entry( "classmethod", "__Pyx_Method_ClassMethod", PyrexTypes.CFuncType( py_object_type, [PyrexTypes.CFuncTypeArg("", py_object_type, None)], 0, 0)) entry.utility_code_definition = Code.UtilityCode.load_cached("ClassMethod", "CythonFunction.c") entry.is_cfunction = 1 return entry class PyClassScope(ClassScope): # Namespace of a Python class. # # class_obj_cname string C variable holding class object is_py_class_scope = 1 def mangle_class_private_name(self, name): return self.mangle_special_name(name) def mangle_special_name(self, name): if name and name.startswith('__') and not name.endswith('__'): name = EncodedString('_%s%s' % (self.class_name.lstrip('_'), name)) return name def lookup_here(self, name): name = self.mangle_special_name(name) return ClassScope.lookup_here(self, name) def declare_var(self, name, type, pos, cname = None, visibility = 'private', api = 0, in_pxd = 0, is_cdef = 0): name = self.mangle_special_name(name) if type is unspecified_type: type = py_object_type # Add an entry for a class attribute. entry = Scope.declare_var(self, name, type, pos, cname=cname, visibility=visibility, api=api, in_pxd=in_pxd, is_cdef=is_cdef) entry.is_pyglobal = 1 entry.is_pyclass_attr = 1 return entry def declare_nonlocal(self, name, pos): # Pull entry from outer scope into local scope orig_entry = self.lookup_here(name) if orig_entry and orig_entry.scope is self and not orig_entry.from_closure: error(pos, "'%s' redeclared as nonlocal" % name) else: entry = self.lookup(name) if entry is None: error(pos, "no binding for nonlocal '%s' found" % name) else: # FIXME: this works, but it's unclear if it's the # right thing to do self.entries[name] = entry def declare_global(self, name, pos): # Pull entry from global scope into local scope. if self.lookup_here(name): warning(pos, "'%s' redeclared ", 0) else: entry = self.global_scope().lookup_target(name) self.entries[name] = entry def add_default_value(self, type): return self.outer_scope.add_default_value(type) class CClassScope(ClassScope): # Namespace of an extension type. # # parent_type CClassType # #typeobj_cname string or None # #objstruct_cname string # method_table_cname string # getset_table_cname string # has_pyobject_attrs boolean Any PyObject attributes? # has_memoryview_attrs boolean Any memory view attributes? # has_cpp_class_attrs boolean Any (non-pointer) C++ attributes? # has_cyclic_pyobject_attrs boolean Any PyObject attributes that may need GC? # property_entries [Entry] # defined boolean Defined in .pxd file # implemented boolean Defined in .pyx file # inherited_var_entries [Entry] Adapted var entries from base class is_c_class_scope = 1 has_pyobject_attrs = False has_memoryview_attrs = False has_cpp_class_attrs = False has_cyclic_pyobject_attrs = False defined = False implemented = False def __init__(self, name, outer_scope, visibility): ClassScope.__init__(self, name, outer_scope) if visibility != 'extern': self.method_table_cname = outer_scope.mangle(Naming.methtab_prefix, name) self.getset_table_cname = outer_scope.mangle(Naming.gstab_prefix, name) self.property_entries = [] self.inherited_var_entries = [] def needs_gc(self): # If the type or any of its base types have Python-valued # C attributes, then it needs to participate in GC. if self.has_cyclic_pyobject_attrs: return True base_type = self.parent_type.base_type if base_type and base_type.scope is not None: return base_type.scope.needs_gc() elif self.parent_type.is_builtin_type: return not self.parent_type.is_gc_simple return False def needs_tp_clear(self): """ Do we need to generate an implementation for the tp_clear slot? Can be disabled to keep references for the __dealloc__ cleanup function. """ return self.needs_gc() and not self.directives.get('no_gc_clear', False) def get_refcounted_entries(self, include_weakref=False, include_gc_simple=True): py_attrs = [] py_buffers = [] memoryview_slices = [] for entry in self.var_entries: if entry.type.is_pyobject: if include_weakref or entry.name != "__weakref__": if include_gc_simple or not entry.type.is_gc_simple: py_attrs.append(entry) elif entry.type == PyrexTypes.c_py_buffer_type: py_buffers.append(entry) elif entry.type.is_memoryviewslice: memoryview_slices.append(entry) have_entries = py_attrs or py_buffers or memoryview_slices return have_entries, (py_attrs, py_buffers, memoryview_slices) def declare_var(self, name, type, pos, cname = None, visibility = 'private', api = 0, in_pxd = 0, is_cdef = 0): if is_cdef: # Add an entry for an attribute. if self.defined: error(pos, "C attributes cannot be added in implementation part of" " extension type defined in a pxd") if get_special_method_signature(name): error(pos, "The name '%s' is reserved for a special method." % name) if not cname: cname = name if visibility == 'private': cname = c_safe_identifier(cname) if type.is_cpp_class and visibility != 'extern': type.check_nullary_constructor(pos) self.use_utility_code(Code.UtilityCode("#include ")) entry = self.declare(name, cname, type, pos, visibility) entry.is_variable = 1 self.var_entries.append(entry) if type.is_memoryviewslice: self.has_memoryview_attrs = True elif type.is_cpp_class: self.has_cpp_class_attrs = True elif type.is_pyobject and name != '__weakref__': self.has_pyobject_attrs = True if (not type.is_builtin_type or not type.scope or type.scope.needs_gc()): self.has_cyclic_pyobject_attrs = True if visibility not in ('private', 'public', 'readonly'): error(pos, "Attribute of extension type cannot be declared %s" % visibility) if visibility in ('public', 'readonly'): # If the field is an external typedef, we cannot be sure about the type, # so do conversion ourself rather than rely on the CPython mechanism (through # a property; made in AnalyseDeclarationsTransform). entry.needs_property = True if name == "__weakref__": error(pos, "Special attribute __weakref__ cannot be exposed to Python") if not (type.is_pyobject or type.can_coerce_to_pyobject(self)): # we're not testing for coercion *from* Python here - that would fail later error(pos, "C attribute of type '%s' cannot be accessed from Python" % type) else: entry.needs_property = False return entry else: if type is unspecified_type: type = py_object_type # Add an entry for a class attribute. entry = Scope.declare_var(self, name, type, pos, cname=cname, visibility=visibility, api=api, in_pxd=in_pxd, is_cdef=is_cdef) entry.is_member = 1 entry.is_pyglobal = 1 # xxx: is_pyglobal changes behaviour in so many places that # I keep it in for now. is_member should be enough # later on self.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname return entry def declare_pyfunction(self, name, pos, allow_redefine=False): # Add an entry for a method. if name in ('__eq__', '__ne__', '__lt__', '__gt__', '__le__', '__ge__'): error(pos, "Special method %s must be implemented via __richcmp__" % name) if name == "__new__": error(pos, "__new__ method of extension type will change semantics " "in a future version of Pyrex and Cython. Use __cinit__ instead.") entry = self.declare_var(name, py_object_type, pos, visibility='extern') special_sig = get_special_method_signature(name) if special_sig: # Special methods get put in the method table with a particular # signature declared in advance. entry.signature = special_sig entry.is_special = 1 else: entry.signature = pymethod_signature entry.is_special = 0 self.pyfunc_entries.append(entry) return entry def lookup_here(self, name): if name == "__new__": name = EncodedString("__cinit__") entry = ClassScope.lookup_here(self, name) if entry and entry.is_builtin_cmethod: if not self.parent_type.is_builtin_type: # For subtypes of builtin types, we can only return # optimised C methods if the type if final. # Otherwise, subtypes may choose to override the # method, but the optimisation would prevent the # subtype method from being called. if not self.parent_type.is_final_type: return None return entry def declare_cfunction(self, name, type, pos, cname=None, visibility='private', api=0, in_pxd=0, defining=0, modifiers=(), utility_code=None, overridable=False): if get_special_method_signature(name) and not self.parent_type.is_builtin_type: error(pos, "Special methods must be declared with 'def', not 'cdef'") args = type.args if not type.is_static_method: if not args: error(pos, "C method has no self argument") elif not self.parent_type.assignable_from(args[0].type): error(pos, "Self argument (%s) of C method '%s' does not match parent type (%s)" % (args[0].type, name, self.parent_type)) entry = self.lookup_here(name) if cname is None: cname = c_safe_identifier(name) if entry: if not entry.is_cfunction: warning(pos, "'%s' redeclared " % name, 0) else: if defining and entry.func_cname: error(pos, "'%s' already defined" % name) #print "CClassScope.declare_cfunction: checking signature" ### if entry.is_final_cmethod and entry.is_inherited: error(pos, "Overriding final methods is not allowed") elif type.same_c_signature_as(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil: pass elif type.compatible_signature_with(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil: entry = self.add_cfunction(name, type, pos, cname, visibility='ignore', modifiers=modifiers) defining = 1 else: error(pos, "Signature not compatible with previous declaration") error(entry.pos, "Previous declaration is here") else: if self.defined: error(pos, "C method '%s' not previously declared in definition part of" " extension type" % name) entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers) if defining: entry.func_cname = self.mangle(Naming.func_prefix, name) entry.utility_code = utility_code type.entry = entry if u'inline' in modifiers: entry.is_inline_cmethod = True if (self.parent_type.is_final_type or entry.is_inline_cmethod or self.directives.get('final')): entry.is_final_cmethod = True entry.final_func_cname = entry.func_cname return entry def add_cfunction(self, name, type, pos, cname, visibility, modifiers): # Add a cfunction entry without giving it a func_cname. prev_entry = self.lookup_here(name) entry = ClassScope.add_cfunction(self, name, type, pos, cname, visibility, modifiers) entry.is_cmethod = 1 entry.prev_entry = prev_entry return entry def declare_builtin_cfunction(self, name, type, cname, utility_code = None): # overridden methods of builtin types still have their Python # equivalent that must be accessible to support bound methods name = EncodedString(name) entry = self.declare_cfunction(name, type, None, cname, visibility='extern', utility_code=utility_code) var_entry = Entry(name, name, py_object_type) var_entry.is_variable = 1 var_entry.is_builtin = 1 var_entry.utility_code = utility_code entry.as_variable = var_entry return entry def declare_property(self, name, doc, pos): entry = self.lookup_here(name) if entry is None: entry = self.declare(name, name, py_object_type, pos, 'private') entry.is_property = 1 entry.doc = doc entry.scope = PropertyScope(name, outer_scope = self.global_scope(), parent_scope = self) entry.scope.parent_type = self.parent_type self.property_entries.append(entry) return entry def declare_inherited_c_attributes(self, base_scope): # Declare entries for all the C attributes of an # inherited type, with cnames modified appropriately # to work with this type. def adapt(cname): return "%s.%s" % (Naming.obj_base_cname, base_entry.cname) entries = base_scope.inherited_var_entries + base_scope.var_entries for base_entry in entries: entry = self.declare( base_entry.name, adapt(base_entry.cname), base_entry.type, None, 'private') entry.is_variable = 1 self.inherited_var_entries.append(entry) # If the class defined in a pxd, specific entries have not been added. # Ensure now that the parent (base) scope has specific entries # Iterate over a copy as get_all_specialized_function_types() will mutate for base_entry in base_scope.cfunc_entries[:]: if base_entry.type.is_fused: base_entry.type.get_all_specialized_function_types() for base_entry in base_scope.cfunc_entries: cname = base_entry.cname var_entry = base_entry.as_variable is_builtin = var_entry and var_entry.is_builtin if not is_builtin: cname = adapt(cname) entry = self.add_cfunction(base_entry.name, base_entry.type, base_entry.pos, cname, base_entry.visibility, base_entry.func_modifiers) entry.is_inherited = 1 if base_entry.is_final_cmethod: entry.is_final_cmethod = True entry.is_inline_cmethod = base_entry.is_inline_cmethod if (self.parent_scope == base_scope.parent_scope or entry.is_inline_cmethod): entry.final_func_cname = base_entry.final_func_cname if is_builtin: entry.is_builtin_cmethod = True entry.as_variable = var_entry if base_entry.utility_code: entry.utility_code = base_entry.utility_code class CppClassScope(Scope): # Namespace of a C++ class. is_cpp_class_scope = 1 default_constructor = None type = None def __init__(self, name, outer_scope, templates=None): Scope.__init__(self, name, outer_scope, None) self.directives = outer_scope.directives self.inherited_var_entries = [] if templates is not None: for T in templates: template_entry = self.declare( T, T, PyrexTypes.TemplatePlaceholderType(T), None, 'extern') template_entry.is_type = 1 def declare_var(self, name, type, pos, cname = None, visibility = 'extern', api = 0, in_pxd = 0, is_cdef = 0, allow_pyobject = 0, defining = 0): # Add an entry for an attribute. if not cname: cname = name entry = self.lookup_here(name) if defining and entry is not None: if not entry.type.same_as(type): error(pos, "Function signature does not match previous declaration") else: entry = self.declare(name, cname, type, pos, visibility) entry.is_variable = 1 if type.is_cfunction and self.type: if not self.type.get_fused_types(): entry.func_cname = "%s::%s" % (self.type.empty_declaration_code(), cname) if name != "this" and (defining or name != ""): self.var_entries.append(entry) if type.is_pyobject and not allow_pyobject: error(pos, "C++ class member cannot be a Python object") return entry def declare_cfunction(self, name, type, pos, cname=None, visibility='extern', api=0, in_pxd=0, defining=0, modifiers=(), utility_code=None, overridable=False): if name in (self.name.split('::')[-1], '__init__') and cname is None: cname = self.type.cname name = '' type.return_type = PyrexTypes.InvisibleVoidType() elif name == '__dealloc__' and cname is None: cname = "~%s" % self.type.cname name = '' type.return_type = PyrexTypes.InvisibleVoidType() prev_entry = self.lookup_here(name) entry = self.declare_var(name, type, pos, defining=defining, cname=cname, visibility=visibility) if prev_entry and not defining: entry.overloaded_alternatives = prev_entry.all_alternatives() entry.utility_code = utility_code type.entry = entry return entry def declare_inherited_cpp_attributes(self, base_scope): # Declare entries for all the C++ attributes of an # inherited type, with cnames modified appropriately # to work with this type. for base_entry in \ base_scope.inherited_var_entries + base_scope.var_entries: #contructor is not inherited if base_entry.name == "": continue #print base_entry.name, self.entries if base_entry.name in self.entries: base_entry.name # FIXME: is there anything to do in this case? entry = self.declare(base_entry.name, base_entry.cname, base_entry.type, None, 'extern') entry.is_variable = 1 self.inherited_var_entries.append(entry) for base_entry in base_scope.cfunc_entries: entry = self.declare_cfunction(base_entry.name, base_entry.type, base_entry.pos, base_entry.cname, base_entry.visibility, api=0, modifiers=base_entry.func_modifiers, utility_code=base_entry.utility_code) entry.is_inherited = 1 def specialize(self, values, type_entry): scope = CppClassScope(self.name, self.outer_scope) scope.type = type_entry for entry in self.entries.values(): if entry.is_type: scope.declare_type(entry.name, entry.type.specialize(values), entry.pos, entry.cname, template=1) elif entry.type.is_cfunction: for e in entry.all_alternatives(): scope.declare_cfunction(e.name, e.type.specialize(values), e.pos, e.cname, utility_code=e.utility_code) else: scope.declare_var(entry.name, entry.type.specialize(values), entry.pos, entry.cname, entry.visibility) return scope class PropertyScope(Scope): # Scope holding the __get__, __set__ and __del__ methods for # a property of an extension type. # # parent_type PyExtensionType The type to which the property belongs is_property_scope = 1 def declare_pyfunction(self, name, pos, allow_redefine=False): # Add an entry for a method. signature = get_property_accessor_signature(name) if signature: entry = self.declare(name, name, py_object_type, pos, 'private') entry.is_special = 1 entry.signature = signature return entry else: error(pos, "Only __get__, __set__ and __del__ methods allowed " "in a property declaration") return None class CConstScope(Scope): def __init__(self, const_base_type_scope): Scope.__init__( self, 'const_' + const_base_type_scope.name, const_base_type_scope.outer_scope, const_base_type_scope.parent_scope) self.const_base_type_scope = const_base_type_scope def lookup_here(self, name): entry = self.const_base_type_scope.lookup_here(name) if entry is not None: entry = copy.copy(entry) entry.type = PyrexTypes.c_const_type(entry.type) return entry class TemplateScope(Scope): def __init__(self, name, outer_scope): Scope.__init__(self, name, outer_scope, None) self.directives = outer_scope.directives Cython-0.23.4/Cython/Compiler/StringEncoding.py0000644000175600017570000002243712606202452022521 0ustar jenkinsjenkins00000000000000# # Cython -- encoding related tools # from __future__ import absolute_import import re import sys if sys.version_info[0] >= 3: _unicode, _str, _bytes, _unichr = str, str, bytes, chr IS_PYTHON3 = True else: _unicode, _str, _bytes, _unichr = unicode, str, str, unichr IS_PYTHON3 = False empty_bytes = _bytes() empty_unicode = _unicode() join_bytes = empty_bytes.join class UnicodeLiteralBuilder(object): """Assemble a unicode string. """ def __init__(self): self.chars = [] def append(self, characters): if isinstance(characters, _bytes): # this came from a Py2 string literal in the parser code characters = characters.decode("ASCII") assert isinstance(characters, _unicode), str(type(characters)) self.chars.append(characters) if sys.maxunicode == 65535: def append_charval(self, char_number): if char_number > 65535: # wide Unicode character on narrow platform => replace # by surrogate pair char_number -= 0x10000 self.chars.append( _unichr((char_number // 1024) + 0xD800) ) self.chars.append( _unichr((char_number % 1024) + 0xDC00) ) else: self.chars.append( _unichr(char_number) ) else: def append_charval(self, char_number): self.chars.append( _unichr(char_number) ) def append_uescape(self, char_number, escape_string): self.append_charval(char_number) def getstring(self): return EncodedString(u''.join(self.chars)) def getstrings(self): return (None, self.getstring()) class BytesLiteralBuilder(object): """Assemble a byte string or char value. """ def __init__(self, target_encoding): self.chars = [] self.target_encoding = target_encoding def append(self, characters): if isinstance(characters, _unicode): characters = characters.encode(self.target_encoding) assert isinstance(characters, _bytes), str(type(characters)) self.chars.append(characters) def append_charval(self, char_number): self.chars.append( _unichr(char_number).encode('ISO-8859-1') ) def append_uescape(self, char_number, escape_string): self.append(escape_string) def getstring(self): # this *must* return a byte string! return bytes_literal(join_bytes(self.chars), self.target_encoding) def getchar(self): # this *must* return a byte string! return self.getstring() def getstrings(self): return (self.getstring(), None) class StrLiteralBuilder(object): """Assemble both a bytes and a unicode representation of a string. """ def __init__(self, target_encoding): self._bytes = BytesLiteralBuilder(target_encoding) self._unicode = UnicodeLiteralBuilder() def append(self, characters): self._bytes.append(characters) self._unicode.append(characters) def append_charval(self, char_number): self._bytes.append_charval(char_number) self._unicode.append_charval(char_number) def append_uescape(self, char_number, escape_string): self._bytes.append(escape_string) self._unicode.append_charval(char_number) def getstrings(self): return (self._bytes.getstring(), self._unicode.getstring()) class EncodedString(_unicode): # unicode string subclass to keep track of the original encoding. # 'encoding' is None for unicode strings and the source encoding # otherwise encoding = None def __deepcopy__(self, memo): return self def byteencode(self): assert self.encoding is not None return self.encode(self.encoding) def utf8encode(self): assert self.encoding is None return self.encode("UTF-8") @property def is_unicode(self): return self.encoding is None def contains_surrogates(self): return string_contains_surrogates(self) def as_utf8_string(self): return bytes_literal(self.utf8encode(), 'utf8') def string_contains_surrogates(ustring): """ Check if the unicode string contains surrogate code points on a CPython platform with wide (UCS-4) or narrow (UTF-16) Unicode, i.e. characters that would be spelled as two separate code units on a narrow platform. """ for c in map(ord, ustring): if c > 65535: # can only happen on wide platforms return True if 0xD800 <= c <= 0xDFFF: return True return False class BytesLiteral(_bytes): # bytes subclass that is compatible with EncodedString encoding = None def __deepcopy__(self, memo): return self def byteencode(self): if IS_PYTHON3: return _bytes(self) else: # fake-recode the string to make it a plain bytes object return self.decode('ISO-8859-1').encode('ISO-8859-1') def utf8encode(self): assert False, "this is not a unicode string: %r" % self def __str__(self): """Fake-decode the byte string to unicode to support % formatting of unicode strings. """ return self.decode('ISO-8859-1') is_unicode = False def bytes_literal(s, encoding): assert isinstance(s, bytes) s = BytesLiteral(s) s.encoding = encoding return s char_from_escape_sequence = { r'\a' : u'\a', r'\b' : u'\b', r'\f' : u'\f', r'\n' : u'\n', r'\r' : u'\r', r'\t' : u'\t', r'\v' : u'\v', }.get _c_special = ('\\', '??', '"') + tuple(map(chr, range(32))) def _to_escape_sequence(s): if s in '\n\r\t': return repr(s)[1:-1] elif s == '"': return r'\"' elif s == '\\': return r'\\' else: # within a character sequence, oct passes much better than hex return ''.join(['\\%03o' % ord(c) for c in s]) def _build_specials_replacer(): subexps = [] replacements = {} for special in _c_special: regexp = ''.join(['[%s]' % c.replace('\\', '\\\\') for c in special]) subexps.append(regexp) replacements[special.encode('ASCII')] = _to_escape_sequence(special).encode('ASCII') sub = re.compile(('(%s)' % '|'.join(subexps)).encode('ASCII')).sub def replace_specials(m): return replacements[m.group(1)] def replace(s): return sub(replace_specials, s) return replace _replace_specials = _build_specials_replacer() def escape_char(c): if IS_PYTHON3: c = c.decode('ISO-8859-1') if c in '\n\r\t\\': return repr(c)[1:-1] elif c == "'": return "\\'" n = ord(c) if n < 32 or n > 127: # hex works well for characters return "\\x%02X" % n else: return c def escape_byte_string(s): """Escape a byte string so that it can be written into C code. Note that this returns a Unicode string instead which, when encoded as ISO-8859-1, will result in the correct byte sequence being written. """ s = _replace_specials(s) try: return s.decode("ASCII") # trial decoding: plain ASCII => done except UnicodeDecodeError: pass if IS_PYTHON3: s_new = bytearray() append, extend = s_new.append, s_new.extend for b in s: if b >= 128: extend(('\\%3o' % b).encode('ASCII')) else: append(b) return s_new.decode('ISO-8859-1') else: l = [] append = l.append for c in s: o = ord(c) if o >= 128: append('\\%3o' % o) else: append(c) return join_bytes(l).decode('ISO-8859-1') def split_string_literal(s, limit=2000): # MSVC can't handle long string literals. if len(s) < limit: return s else: start = 0 chunks = [] while start < len(s): end = start + limit if len(s) > end-4 and '\\' in s[end-4:end]: end -= 4 - s[end-4:end].find('\\') # just before the backslash while s[end-1] == '\\': end -= 1 if end == start: # must have been a long line of backslashes end = start + limit - (limit % 2) - 4 break chunks.append(s[start:end]) start = end return '""'.join(chunks) def encode_pyunicode_string(s): """Create Py_UNICODE[] representation of a given unicode string. """ s = list(map(ord, s)) + [0] if sys.maxunicode >= 0x10000: # Wide build or Py3.3 utf16, utf32 = [], s for code_point in s: if code_point >= 0x10000: # outside of BMP high, low = divmod(code_point - 0x10000, 1024) utf16.append(high + 0xD800) utf16.append(low + 0xDC00) else: utf16.append(code_point) else: utf16, utf32 = s, [] for code_unit in s: if 0xDC00 <= code_unit <= 0xDFFF and utf32 and 0xD800 <= utf32[-1] <= 0xDBFF: high, low = utf32[-1], code_unit utf32[-1] = ((high & 0x3FF) << 10) + (low & 0x3FF) + 0x10000 else: utf32.append(code_unit) if utf16 == utf32: utf16 = [] return ",".join(map(_unicode, utf16)), ",".join(map(_unicode, utf32)) Cython-0.23.4/Cython/Compiler/Scanning.py0000644000175600017570000004077512606202452021351 0ustar jenkinsjenkins00000000000000# cython: infer_types=True, language_level=3, py2_import=True # # Cython Scanner # from __future__ import absolute_import import cython cython.declare(make_lexicon=object, lexicon=object, print_function=object, error=object, warning=object, os=object, platform=object) import os import platform from .. import Utils from ..Plex.Scanners import Scanner from ..Plex.Errors import UnrecognizedInput from .Errors import error, warning from .Lexicon import any_string_prefix, make_lexicon, IDENT from .Future import print_function debug_scanner = 0 trace_scanner = 0 scanner_debug_flags = 0 scanner_dump_file = None lexicon = None def get_lexicon(): global lexicon if not lexicon: lexicon = make_lexicon() return lexicon #------------------------------------------------------------------ py_reserved_words = [ "global", "nonlocal", "def", "class", "print", "del", "pass", "break", "continue", "return", "raise", "import", "exec", "try", "except", "finally", "while", "if", "elif", "else", "for", "in", "assert", "and", "or", "not", "is", "in", "lambda", "from", "yield", "with", "nonlocal", ] pyx_reserved_words = py_reserved_words + [ "include", "ctypedef", "cdef", "cpdef", "cimport", "DEF", "IF", "ELIF", "ELSE" ] class Method(object): def __init__(self, name): self.name = name self.__name__ = name # for Plex tracing def __call__(self, stream, text): return getattr(stream, self.name)(text) #------------------------------------------------------------------ class CompileTimeScope(object): def __init__(self, outer = None): self.entries = {} self.outer = outer def declare(self, name, value): self.entries[name] = value def update(self, other): self.entries.update(other) def lookup_here(self, name): return self.entries[name] def __contains__(self, name): return name in self.entries def lookup(self, name): try: return self.lookup_here(name) except KeyError: outer = self.outer if outer: return outer.lookup(name) else: raise def initial_compile_time_env(): benv = CompileTimeScope() names = ('UNAME_SYSNAME', 'UNAME_NODENAME', 'UNAME_RELEASE', 'UNAME_VERSION', 'UNAME_MACHINE') for name, value in zip(names, platform.uname()): benv.declare(name, value) try: import __builtin__ as builtins except ImportError: import builtins names = ('False', 'True', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'chr', 'cmp', 'complex', 'dict', 'divmod', 'enumerate', 'filter', 'float', 'format', 'frozenset', 'hash', 'hex', 'int', 'len', 'list', 'long', 'map', 'max', 'min', 'oct', 'ord', 'pow', 'range', 'repr', 'reversed', 'round', 'set', 'slice', 'sorted', 'str', 'sum', 'tuple', 'xrange', 'zip') for name in names: try: benv.declare(name, getattr(builtins, name)) except AttributeError: # ignore, likely Py3 pass denv = CompileTimeScope(benv) return denv #------------------------------------------------------------------ class SourceDescriptor(object): """ A SourceDescriptor should be considered immutable. """ _file_type = 'pyx' _escaped_description = None _cmp_name = '' def __str__(self): assert False # To catch all places where a descriptor is used directly as a filename def set_file_type_from_name(self, filename): name, ext = os.path.splitext(filename) self._file_type = ext in ('.pyx', '.pxd', '.py') and ext[1:] or 'pyx' def is_cython_file(self): return self._file_type in ('pyx', 'pxd') def is_python_file(self): return self._file_type == 'py' def get_escaped_description(self): if self._escaped_description is None: self._escaped_description = \ self.get_description().encode('ASCII', 'replace').decode("ASCII") return self._escaped_description def __gt__(self, other): # this is only used to provide some sort of order try: return self._cmp_name > other._cmp_name except AttributeError: return False def __lt__(self, other): # this is only used to provide some sort of order try: return self._cmp_name < other._cmp_name except AttributeError: return False def __le__(self, other): # this is only used to provide some sort of order try: return self._cmp_name <= other._cmp_name except AttributeError: return False class FileSourceDescriptor(SourceDescriptor): """ Represents a code source. A code source is a more generic abstraction for a "filename" (as sometimes the code doesn't come from a file). Instances of code sources are passed to Scanner.__init__ as the optional name argument and will be passed back when asking for the position()-tuple. """ def __init__(self, filename, path_description=None): filename = Utils.decode_filename(filename) self.path_description = path_description or filename self.filename = filename self.set_file_type_from_name(filename) self._cmp_name = filename self._lines = {} def get_lines(self, encoding=None, error_handling=None): # we cache the lines only the second time this is called, in # order to save memory when they are only used once key = (encoding, error_handling) try: lines = self._lines[key] if lines is not None: return lines except KeyError: pass with Utils.open_source_file(self.filename, encoding=encoding, error_handling=error_handling) as f: lines = list(f) if key in self._lines: self._lines[key] = lines else: # do not cache the first access, but remember that we # already read it once self._lines[key] = None return lines def get_description(self): try: return os.path.relpath(self.path_description) except ValueError: # path not under current directory => use complete file path return self.path_description def get_error_description(self): path = self.filename cwd = Utils.decode_filename(os.getcwd() + os.path.sep) if path.startswith(cwd): return path[len(cwd):] return path def get_filenametable_entry(self): return self.filename def __eq__(self, other): return isinstance(other, FileSourceDescriptor) and self.filename == other.filename def __hash__(self): return hash(self.filename) def __repr__(self): return "" % self.filename class StringSourceDescriptor(SourceDescriptor): """ Instances of this class can be used instead of a filenames if the code originates from a string object. """ filename = None def __init__(self, name, code): self.name = name #self.set_file_type_from_name(name) self.codelines = [x + "\n" for x in code.split("\n")] self._cmp_name = name def get_lines(self, encoding=None, error_handling=None): if not encoding: return self.codelines else: return [ line.encode(encoding, error_handling).decode(encoding) for line in self.codelines ] def get_description(self): return self.name get_error_description = get_description def get_filenametable_entry(self): return "stringsource" def __hash__(self): return id(self) # Do not hash on the name, an identical string source should be the # same object (name is often defaulted in other places) # return hash(self.name) def __eq__(self, other): return isinstance(other, StringSourceDescriptor) and self.name == other.name def __repr__(self): return "" % self.name #------------------------------------------------------------------ class PyrexScanner(Scanner): # context Context Compilation context # included_files [string] Files included with 'include' statement # compile_time_env dict Environment for conditional compilation # compile_time_eval boolean In a true conditional compilation context # compile_time_expr boolean In a compile-time expression context def __init__(self, file, filename, parent_scanner=None, scope=None, context=None, source_encoding=None, parse_comments=True, initial_pos=None): Scanner.__init__(self, get_lexicon(), file, filename, initial_pos) if parent_scanner: self.context = parent_scanner.context self.included_files = parent_scanner.included_files self.compile_time_env = parent_scanner.compile_time_env self.compile_time_eval = parent_scanner.compile_time_eval self.compile_time_expr = parent_scanner.compile_time_expr else: self.context = context self.included_files = scope.included_files self.compile_time_env = initial_compile_time_env() self.compile_time_eval = 1 self.compile_time_expr = 0 if getattr(context.options, 'compile_time_env', None): self.compile_time_env.update(context.options.compile_time_env) self.parse_comments = parse_comments self.source_encoding = source_encoding if filename.is_python_file(): self.in_python_file = True self.keywords = set(py_reserved_words) else: self.in_python_file = False self.keywords = set(pyx_reserved_words) self.trace = trace_scanner self.indentation_stack = [0] self.indentation_char = None self.bracket_nesting_level = 0 self.async_enabled = 0 self.begin('INDENT') self.sy = '' self.next() def commentline(self, text): if self.parse_comments: self.produce('commentline', text) def current_level(self): return self.indentation_stack[-1] def open_bracket_action(self, text): self.bracket_nesting_level += 1 return text def close_bracket_action(self, text): self.bracket_nesting_level -= 1 return text def newline_action(self, text): if self.bracket_nesting_level == 0: self.begin('INDENT') self.produce('NEWLINE', '') string_states = { "'": 'SQ_STRING', '"': 'DQ_STRING', "'''": 'TSQ_STRING', '"""': 'TDQ_STRING' } def begin_string_action(self, text): while text[:1] in any_string_prefix: text = text[1:] self.begin(self.string_states[text]) self.produce('BEGIN_STRING') def end_string_action(self, text): self.begin('') self.produce('END_STRING') def unclosed_string_action(self, text): self.end_string_action(text) self.error("Unclosed string literal") def indentation_action(self, text): self.begin('') # Indentation within brackets should be ignored. #if self.bracket_nesting_level > 0: # return # Check that tabs and spaces are being used consistently. if text: c = text[0] #print "Scanner.indentation_action: indent with", repr(c) ### if self.indentation_char is None: self.indentation_char = c #print "Scanner.indentation_action: setting indent_char to", repr(c) else: if self.indentation_char != c: self.error("Mixed use of tabs and spaces") if text.replace(c, "") != "": self.error("Mixed use of tabs and spaces") # Figure out how many indents/dedents to do current_level = self.current_level() new_level = len(text) #print "Changing indent level from", current_level, "to", new_level ### if new_level == current_level: return elif new_level > current_level: #print "...pushing level", new_level ### self.indentation_stack.append(new_level) self.produce('INDENT', '') else: while new_level < self.current_level(): #print "...popping level", self.indentation_stack[-1] ### self.indentation_stack.pop() self.produce('DEDENT', '') #print "...current level now", self.current_level() ### if new_level != self.current_level(): self.error("Inconsistent indentation") def eof_action(self, text): while len(self.indentation_stack) > 1: self.produce('DEDENT', '') self.indentation_stack.pop() self.produce('EOF', '') def next(self): try: sy, systring = self.read() except UnrecognizedInput: self.error("Unrecognized character") return # just a marker, error() always raises if sy == IDENT: if systring in self.keywords: if systring == u'print' and print_function in self.context.future_directives: self.keywords.discard('print') elif systring == u'exec' and self.context.language_level >= 3: self.keywords.discard('exec') else: sy = systring systring = self.context.intern_ustring(systring) self.sy = sy self.systring = systring if False: # debug_scanner: _, line, col = self.position() if not self.systring or self.sy == self.systring: t = self.sy else: t = "%s %s" % (self.sy, self.systring) print("--- %3d %2d %s" % (line, col, t)) def peek(self): saved = self.sy, self.systring self.next() next = self.sy, self.systring self.unread(*next) self.sy, self.systring = saved return next def put_back(self, sy, systring): self.unread(self.sy, self.systring) self.sy = sy self.systring = systring def unread(self, token, value): # This method should be added to Plex self.queue.insert(0, (token, value)) def error(self, message, pos=None, fatal=True): if pos is None: pos = self.position() if self.sy == 'INDENT': error(pos, "Possible inconsistent indentation") err = error(pos, message) if fatal: raise err def expect(self, what, message=None): if self.sy == what: self.next() else: self.expected(what, message) def expect_keyword(self, what, message=None): if self.sy == IDENT and self.systring == what: self.next() else: self.expected(what, message) def expected(self, what, message = None): if message: self.error(message) else: if self.sy == IDENT: found = self.systring else: found = self.sy self.error("Expected '%s', found '%s'" % (what, found)) def expect_indent(self): self.expect('INDENT', "Expected an increase in indentation level") def expect_dedent(self): self.expect('DEDENT', "Expected a decrease in indentation level") def expect_newline(self, message="Expected a newline", ignore_semicolon=False): # Expect either a newline or end of file useless_trailing_semicolon = None if ignore_semicolon and self.sy == ';': useless_trailing_semicolon = self.position() self.next() if self.sy != 'EOF': self.expect('NEWLINE', message) if useless_trailing_semicolon is not None: warning(useless_trailing_semicolon, "useless trailing semicolon") def enter_async(self): self.async_enabled += 1 if self.async_enabled == 1: self.keywords.add('async') self.keywords.add('await') def exit_async(self): assert self.async_enabled > 0 self.async_enabled -= 1 if not self.async_enabled: self.keywords.discard('await') self.keywords.discard('async') if self.sy in ('async', 'await'): self.sy, self.systring = IDENT, self.context.intern_ustring(self.sy) Cython-0.23.4/Cython/Compiler/Scanning.pxd0000644000175600017570000000367712606202452021514 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import import cython from ..Plex.Scanners cimport Scanner cdef unicode any_string_prefix, IDENT cdef get_lexicon() cdef initial_compile_time_env() cdef class Method: cdef object name cdef readonly object __name__ # for tracing the scanner @cython.final cdef class CompileTimeScope: cdef public dict entries cdef public CompileTimeScope outer cdef declare(self, name, value) cdef lookup_here(self, name) cpdef lookup(self, name) @cython.final cdef class PyrexScanner(Scanner): cdef public context cdef public list included_files cdef public CompileTimeScope compile_time_env cdef public bint compile_time_eval cdef public bint compile_time_expr cdef public bint parse_comments cdef public bint in_python_file cdef public source_encoding cdef set keywords cdef public list indentation_stack cdef public indentation_char cdef public int bracket_nesting_level cdef bint async_enabled cdef public sy cdef public systring cdef long current_level(self) #cpdef commentline(self, text) #cpdef open_bracket_action(self, text) #cpdef close_bracket_action(self, text) #cpdef newline_action(self, text) #cpdef begin_string_action(self, text) #cpdef end_string_action(self, text) #cpdef unclosed_string_action(self, text) @cython.locals(current_level=cython.long, new_level=cython.long) cpdef indentation_action(self, text) #cpdef eof_action(self, text) cdef next(self) cdef peek(self) #cpdef put_back(self, sy, systring) #cdef unread(self, token, value) cdef bint expect(self, what, message = *) except -2 cdef expect_keyword(self, what, message = *) cdef expected(self, what, message = *) cdef expect_indent(self) cdef expect_dedent(self) cdef expect_newline(self, message=*, bint ignore_semicolon=*) cdef int enter_async(self) except -1 cdef int exit_async(self) except -1 Cython-0.23.4/Cython/Compiler/PyrexTypes.py0000644000175600017570000046470512606202452021750 0ustar jenkinsjenkins00000000000000# # Cython/Python language types # from __future__ import absolute_import import copy import re try: reduce except NameError: from functools import reduce from .Code import UtilityCode, LazyUtilityCode, TempitaUtilityCode from . import StringEncoding from . import Naming from .Errors import error class BaseType(object): # # Base class for all Cython types including pseudo-types. # List of attribute names of any subtypes subtypes = [] _empty_declaration = None def can_coerce_to_pyobject(self, env): return False def cast_code(self, expr_code): return "((%s)%s)" % (self.empty_declaration_code(), expr_code) def empty_declaration_code(self): if self._empty_declaration is None: self._empty_declaration = self.declaration_code('') return self._empty_declaration def specialization_name(self): # This is not entirely robust. safe = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789' all = [] for c in self.empty_declaration_code().replace("unsigned ", "unsigned_").replace("long long", "long_long").replace(" ", "__"): if c in safe: all.append(c) else: all.append('_%x_' % ord(c)) return ''.join(all) def base_declaration_code(self, base_code, entity_code): if entity_code: return "%s %s" % (base_code, entity_code) else: return base_code def __deepcopy__(self, memo): """ Types never need to be copied, if we do copy, Unfortunate Things Will Happen! """ return self def get_fused_types(self, result=None, seen=None, subtypes=None): subtypes = subtypes or self.subtypes if not subtypes: return None if result is None: result = [] seen = set() for attr in subtypes: list_or_subtype = getattr(self, attr) if list_or_subtype: if isinstance(list_or_subtype, BaseType): list_or_subtype.get_fused_types(result, seen) else: for subtype in list_or_subtype: subtype.get_fused_types(result, seen) return result def specialize_fused(self, env): if env.fused_to_specific: return self.specialize(env.fused_to_specific) return self @property def is_fused(self): """ Whether this type or any of its subtypes is a fused type """ # Add this indirection for the is_fused property to allow overriding # get_fused_types in subclasses. return self.get_fused_types() def deduce_template_params(self, actual): """ Deduce any template params in this (argument) type given the actual argument type. http://en.cppreference.com/w/cpp/language/function_template#Template_argument_deduction """ if self == actual: return {} else: return None def __lt__(self, other): """ For sorting. The sorting order should correspond to the preference of conversion from Python types. Override to provide something sensible. This is only implemented so that python 3 doesn't trip """ return id(type(self)) < id(type(other)) def py_type_name(self): """ Return the name of the Python type that can coerce to this type. """ def typeof_name(self): """ Return the string with which fused python functions can be indexed. """ if self.is_builtin_type or self.py_type_name() == 'object': index_name = self.py_type_name() else: index_name = str(self) return index_name def check_for_null_code(self, cname): """ Return the code for a NULL-check in case an UnboundLocalError should be raised if an entry of this type is referenced before assignment. Returns None if no check should be performed. """ return None def invalid_value(self): """ Returns the most invalid value an object of this type can assume as a C expression string. Returns None if no such value exists. """ class PyrexType(BaseType): # # Base class for all Cython types # # is_pyobject boolean Is a Python object type # is_extension_type boolean Is a Python extension type # is_final_type boolean Is a final extension type # is_numeric boolean Is a C numeric type # is_int boolean Is a C integer type # is_float boolean Is a C floating point type # is_complex boolean Is a C complex type # is_void boolean Is the C void type # is_array boolean Is a C array type # is_ptr boolean Is a C pointer type # is_null_ptr boolean Is the type of NULL # is_reference boolean Is a C reference type # is_const boolean Is a C const type. # is_cfunction boolean Is a C function type # is_struct_or_union boolean Is a C struct or union type # is_struct boolean Is a C struct type # is_enum boolean Is a C enum type # is_typedef boolean Is a typedef type # is_string boolean Is a C char * type # is_pyunicode_ptr boolean Is a C PyUNICODE * type # is_cpp_string boolean Is a C++ std::string type # is_unicode_char boolean Is either Py_UCS4 or Py_UNICODE # is_returncode boolean Is used only to signal exceptions # is_error boolean Is the dummy error type # is_buffer boolean Is buffer access type # has_attributes boolean Has C dot-selectable attributes # default_value string Initial value # entry Entry The Entry for this type # # declaration_code(entity_code, # for_display = 0, dll_linkage = None, pyrex = 0) # Returns a code fragment for the declaration of an entity # of this type, given a code fragment for the entity. # * If for_display, this is for reading by a human in an error # message; otherwise it must be valid C code. # * If dll_linkage is not None, it must be 'DL_EXPORT' or # 'DL_IMPORT', and will be added to the base type part of # the declaration. # * If pyrex = 1, this is for use in a 'cdef extern' # statement of a Cython include file. # # assignable_from(src_type) # Tests whether a variable of this type can be # assigned a value of type src_type. # # same_as(other_type) # Tests whether this type represents the same type # as other_type. # # as_argument_type(): # Coerces array and C function types into pointer type for use as # a formal argument type. # is_pyobject = 0 is_unspecified = 0 is_extension_type = 0 is_final_type = 0 is_builtin_type = 0 is_numeric = 0 is_int = 0 is_float = 0 is_complex = 0 is_void = 0 is_array = 0 is_ptr = 0 is_null_ptr = 0 is_reference = 0 is_const = 0 is_cfunction = 0 is_struct_or_union = 0 is_cpp_class = 0 is_cpp_string = 0 is_struct = 0 is_enum = 0 is_typedef = 0 is_string = 0 is_pyunicode_ptr = 0 is_unicode_char = 0 is_returncode = 0 is_error = 0 is_buffer = 0 is_ctuple = 0 is_memoryviewslice = 0 has_attributes = 0 default_value = "" def resolve(self): # If a typedef, returns the base type. return self def specialize(self, values): # TODO(danilo): Override wherever it makes sense. return self def literal_code(self, value): # Returns a C code fragment representing a literal # value of this type. return str(value) def __str__(self): return self.declaration_code("", for_display = 1).strip() def same_as(self, other_type, **kwds): return self.same_as_resolved_type(other_type.resolve(), **kwds) def same_as_resolved_type(self, other_type): return self == other_type or other_type is error_type def subtype_of(self, other_type): return self.subtype_of_resolved_type(other_type.resolve()) def subtype_of_resolved_type(self, other_type): return self.same_as(other_type) def assignable_from(self, src_type): return self.assignable_from_resolved_type(src_type.resolve()) def assignable_from_resolved_type(self, src_type): return self.same_as(src_type) def as_argument_type(self): return self def is_complete(self): # A type is incomplete if it is an unsized array, # a struct whose attributes are not defined, etc. return 1 def is_simple_buffer_dtype(self): return (self.is_int or self.is_float or self.is_complex or self.is_pyobject or self.is_extension_type or self.is_ptr) def struct_nesting_depth(self): # Returns the number levels of nested structs. This is # used for constructing a stack for walking the run-time # type information of the struct. return 1 def global_init_code(self, entry, code): # abstract pass def needs_nonecheck(self): return 0 def public_decl(base_code, dll_linkage): if dll_linkage: return "%s(%s)" % (dll_linkage, base_code) else: return base_code def create_typedef_type(name, base_type, cname, is_external=0): is_fused = base_type.is_fused if base_type.is_complex or is_fused: if is_external: if is_fused: msg = "Fused" else: msg = "Complex" raise ValueError("%s external typedefs not supported" % msg) return base_type else: return CTypedefType(name, base_type, cname, is_external) class CTypedefType(BaseType): # # Pseudo-type defined with a ctypedef statement in a # 'cdef extern from' block. # Delegates most attribute lookups to the base type. # (Anything not defined here or in the BaseType is delegated.) # # qualified_name string # typedef_name string # typedef_cname string # typedef_base_type PyrexType # typedef_is_external bool is_typedef = 1 typedef_is_external = 0 to_py_utility_code = None from_py_utility_code = None subtypes = ['typedef_base_type'] def __init__(self, name, base_type, cname, is_external=0): assert not base_type.is_complex self.typedef_name = name self.typedef_cname = cname self.typedef_base_type = base_type self.typedef_is_external = is_external def invalid_value(self): return self.typedef_base_type.invalid_value() def resolve(self): return self.typedef_base_type.resolve() def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): if pyrex or for_display: base_code = self.typedef_name else: base_code = public_decl(self.typedef_cname, dll_linkage) return self.base_declaration_code(base_code, entity_code) def as_argument_type(self): return self def cast_code(self, expr_code): # If self is really an array (rather than pointer), we can't cast. # For example, the gmp mpz_t. if self.typedef_base_type.is_array: base_type = self.typedef_base_type.base_type return CPtrType(base_type).cast_code(expr_code) else: return BaseType.cast_code(self, expr_code) def __repr__(self): return "" % self.typedef_cname def __str__(self): return self.typedef_name def _create_utility_code(self, template_utility_code, template_function_name): type_name = type_identifier(self.typedef_cname) utility_code = template_utility_code.specialize( type = self.typedef_cname, TypeName = type_name) function_name = template_function_name % type_name return utility_code, function_name def create_to_py_utility_code(self, env): if self.typedef_is_external: if not self.to_py_utility_code: base_type = self.typedef_base_type if type(base_type) is CIntType: self.to_py_function = "__Pyx_PyInt_From_" + self.specialization_name() env.use_utility_code(TempitaUtilityCode.load_cached( "CIntToPy", "TypeConversion.c", context={"TYPE": self.empty_declaration_code(), "TO_PY_FUNCTION": self.to_py_function})) return True elif base_type.is_float: pass # XXX implement! elif base_type.is_complex: pass # XXX implement! pass if self.to_py_utility_code: env.use_utility_code(self.to_py_utility_code) return True # delegation return self.typedef_base_type.create_to_py_utility_code(env) def create_from_py_utility_code(self, env): if self.typedef_is_external: if not self.from_py_utility_code: base_type = self.typedef_base_type if type(base_type) is CIntType: self.from_py_function = "__Pyx_PyInt_As_" + self.specialization_name() env.use_utility_code(TempitaUtilityCode.load_cached( "CIntFromPy", "TypeConversion.c", context={"TYPE": self.empty_declaration_code(), "FROM_PY_FUNCTION": self.from_py_function})) return True elif base_type.is_float: pass # XXX implement! elif base_type.is_complex: pass # XXX implement! if self.from_py_utility_code: env.use_utility_code(self.from_py_utility_code) return True # delegation return self.typedef_base_type.create_from_py_utility_code(env) def to_py_call_code(self, source_code, result_code, result_type, to_py_function=None): if to_py_function is None: to_py_function = self.to_py_function return self.typedef_base_type.to_py_call_code( source_code, result_code, result_type, to_py_function) def from_py_call_code(self, source_code, result_code, error_pos, code, from_py_function=None, error_condition=None): if from_py_function is None: from_py_function = self.from_py_function if error_condition is None: error_condition = self.error_condition(result_code) return self.typedef_base_type.from_py_call_code( source_code, result_code, error_pos, code, from_py_function, error_condition) def overflow_check_binop(self, binop, env, const_rhs=False): env.use_utility_code(UtilityCode.load("Common", "Overflow.c")) type = self.empty_declaration_code() name = self.specialization_name() if binop == "lshift": env.use_utility_code(TempitaUtilityCode.load_cached( "LeftShift", "Overflow.c", context={'TYPE': type, 'NAME': name, 'SIGNED': self.signed})) else: if const_rhs: binop += "_const" _load_overflow_base(env) env.use_utility_code(TempitaUtilityCode.load_cached( "SizeCheck", "Overflow.c", context={'TYPE': type, 'NAME': name})) env.use_utility_code(TempitaUtilityCode.load_cached( "Binop", "Overflow.c", context={'TYPE': type, 'NAME': name, 'BINOP': binop})) return "__Pyx_%s_%s_checking_overflow" % (binop, name) def error_condition(self, result_code): if self.typedef_is_external: if self.exception_value: condition = "(%s == (%s)%s)" % ( result_code, self.typedef_cname, self.exception_value) if self.exception_check: condition += " && PyErr_Occurred()" return condition # delegation return self.typedef_base_type.error_condition(result_code) def __getattr__(self, name): return getattr(self.typedef_base_type, name) def py_type_name(self): return self.typedef_base_type.py_type_name() def can_coerce_to_pyobject(self, env): return self.typedef_base_type.can_coerce_to_pyobject(env) class MemoryViewSliceType(PyrexType): is_memoryviewslice = 1 has_attributes = 1 scope = None # These are special cased in Defnode from_py_function = None to_py_function = None exception_value = None exception_check = True subtypes = ['dtype'] def __init__(self, base_dtype, axes): """ MemoryViewSliceType(base, axes) Base is the C base type; axes is a list of (access, packing) strings, where access is one of 'full', 'direct' or 'ptr' and packing is one of 'contig', 'strided' or 'follow'. There is one (access, packing) tuple for each dimension. the access specifiers determine whether the array data contains pointers that need to be dereferenced along that axis when retrieving/setting: 'direct' -- No pointers stored in this dimension. 'ptr' -- Pointer stored in this dimension. 'full' -- Check along this dimension, don't assume either. the packing specifiers specify how the array elements are layed-out in memory. 'contig' -- The data are contiguous in memory along this dimension. At most one dimension may be specified as 'contig'. 'strided' -- The data aren't contiguous along this dimenison. 'follow' -- Used for C/Fortran contiguous arrays, a 'follow' dimension has its stride automatically computed from extents of the other dimensions to ensure C or Fortran memory layout. C-contiguous memory has 'direct' as the access spec, 'contig' as the *last* axis' packing spec and 'follow' for all other packing specs. Fortran-contiguous memory has 'direct' as the access spec, 'contig' as the *first* axis' packing spec and 'follow' for all other packing specs. """ from . import MemoryView self.dtype = base_dtype self.axes = axes self.ndim = len(axes) self.flags = MemoryView.get_buf_flags(self.axes) self.is_c_contig, self.is_f_contig = MemoryView.is_cf_contig(self.axes) assert not (self.is_c_contig and self.is_f_contig) self.mode = MemoryView.get_mode(axes) self.writable_needed = False if not self.dtype.is_fused: self.dtype_name = MemoryView.mangle_dtype_name(self.dtype) def __hash__(self): return hash(self.__class__) ^ hash(self.dtype) ^ hash(tuple(self.axes)) def __eq__(self, other): if isinstance(other, BaseType): return self.same_as_resolved_type(other) else: return False def same_as_resolved_type(self, other_type): return ((other_type.is_memoryviewslice and self.dtype.same_as(other_type.dtype) and self.axes == other_type.axes) or other_type is error_type) def needs_nonecheck(self): return True def is_complete(self): # incomplete since the underlying struct doesn't have a cython.memoryview object. return 0 def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): # XXX: we put these guards in for now... assert not pyrex assert not dll_linkage from . import MemoryView return self.base_declaration_code( MemoryView.memviewslice_cname, entity_code) def attributes_known(self): if self.scope is None: from . import Symtab self.scope = scope = Symtab.CClassScope( 'mvs_class_'+self.specialization_suffix(), None, visibility='extern') scope.parent_type = self scope.directives = {} scope.declare_var('_data', c_char_ptr_type, None, cname='data', is_cdef=1) return True def declare_attribute(self, attribute, env, pos): from . import MemoryView, Options scope = self.scope if attribute == 'shape': scope.declare_var('shape', c_array_type(c_py_ssize_t_type, Options.buffer_max_dims), pos, cname='shape', is_cdef=1) elif attribute == 'strides': scope.declare_var('strides', c_array_type(c_py_ssize_t_type, Options.buffer_max_dims), pos, cname='strides', is_cdef=1) elif attribute == 'suboffsets': scope.declare_var('suboffsets', c_array_type(c_py_ssize_t_type, Options.buffer_max_dims), pos, cname='suboffsets', is_cdef=1) elif attribute in ("copy", "copy_fortran"): ndim = len(self.axes) to_axes_c = [('direct', 'contig')] to_axes_f = [('direct', 'contig')] if ndim - 1: to_axes_c = [('direct', 'follow')]*(ndim-1) + to_axes_c to_axes_f = to_axes_f + [('direct', 'follow')]*(ndim-1) to_memview_c = MemoryViewSliceType(self.dtype, to_axes_c) to_memview_f = MemoryViewSliceType(self.dtype, to_axes_f) for to_memview, cython_name in [(to_memview_c, "copy"), (to_memview_f, "copy_fortran")]: entry = scope.declare_cfunction(cython_name, CFuncType(self, [CFuncTypeArg("memviewslice", self, None)]), pos=pos, defining=1, cname=MemoryView.copy_c_or_fortran_cname(to_memview)) #entry.utility_code_definition = \ env.use_utility_code(MemoryView.get_copy_new_utility(pos, self, to_memview)) MemoryView.use_cython_array_utility_code(env) elif attribute in ("is_c_contig", "is_f_contig"): # is_c_contig and is_f_contig functions for (c_or_f, cython_name) in (('c', 'is_c_contig'), ('f', 'is_f_contig')): is_contig_name = \ MemoryView.get_is_contig_func_name(c_or_f, self.ndim) cfunctype = CFuncType( return_type=c_bint_type, args=[CFuncTypeArg("memviewslice", self, None)], exception_value="-1", ) entry = scope.declare_cfunction(cython_name, cfunctype, pos=pos, defining=1, cname=is_contig_name) entry.utility_code_definition = MemoryView.get_is_contig_utility( attribute == 'is_c_contig', self.ndim) return True def specialization_name(self): return super(MemoryViewSliceType,self).specialization_name() \ + '_' + self.specialization_suffix() def specialization_suffix(self): return "%s_%s" % (self.axes_to_name(), self.dtype_name) def can_coerce_to_pyobject(self, env): return True def check_for_null_code(self, cname): return cname + '.memview' def create_from_py_utility_code(self, env): from . import MemoryView, Buffer # We don't have 'code', so use a LazyUtilityCode with a callback. def lazy_utility_callback(code): context['dtype_typeinfo'] = Buffer.get_type_information_cname(code, self.dtype) return TempitaUtilityCode.load( "ObjectToMemviewSlice", "MemoryView_C.c", context=context) env.use_utility_code(Buffer.acquire_utility_code) env.use_utility_code(MemoryView.memviewslice_init_code) env.use_utility_code(LazyUtilityCode(lazy_utility_callback)) if self.is_c_contig: c_or_f_flag = "__Pyx_IS_C_CONTIG" elif self.is_f_contig: c_or_f_flag = "__Pyx_IS_F_CONTIG" else: c_or_f_flag = "0" suffix = self.specialization_suffix() funcname = "__Pyx_PyObject_to_MemoryviewSlice_" + suffix context = dict( MemoryView.context, buf_flag = self.flags, ndim = self.ndim, axes_specs = ', '.join(self.axes_to_code()), dtype_typedecl = self.dtype.empty_declaration_code(), struct_nesting_depth = self.dtype.struct_nesting_depth(), c_or_f_flag = c_or_f_flag, funcname = funcname, ) self.from_py_function = funcname return True def create_to_py_utility_code(self, env): self._dtype_to_py_func, self._dtype_from_py_func = self.dtype_object_conversion_funcs(env) return True def to_py_call_code(self, source_code, result_code, result_type, to_py_function=None): assert self._dtype_to_py_func assert self._dtype_from_py_func to_py_func = "(PyObject *(*)(char *)) " + self._dtype_to_py_func from_py_func = "(int (*)(char *, PyObject *)) " + self._dtype_from_py_func tup = (result_code, source_code, self.ndim, to_py_func, from_py_func, self.dtype.is_pyobject) return "%s = __pyx_memoryview_fromslice(%s, %s, %s, %s, %d);" % tup def dtype_object_conversion_funcs(self, env): get_function = "__pyx_memview_get_%s" % self.dtype_name set_function = "__pyx_memview_set_%s" % self.dtype_name context = dict( get_function = get_function, set_function = set_function, ) if self.dtype.is_pyobject: utility_name = "MemviewObjectToObject" else: to_py = self.dtype.create_to_py_utility_code(env) from_py = self.dtype.create_from_py_utility_code(env) if not (to_py or from_py): return "NULL", "NULL" if not self.dtype.to_py_function: get_function = "NULL" if not self.dtype.from_py_function: set_function = "NULL" utility_name = "MemviewDtypeToObject" error_condition = (self.dtype.error_condition('value') or 'PyErr_Occurred()') context.update( to_py_function = self.dtype.to_py_function, from_py_function = self.dtype.from_py_function, dtype = self.dtype.empty_declaration_code(), error_condition = error_condition, ) utility = TempitaUtilityCode.load_cached( utility_name, "MemoryView_C.c", context=context) env.use_utility_code(utility) return get_function, set_function def axes_to_code(self): """Return a list of code constants for each axis""" from . import MemoryView d = MemoryView._spec_to_const return ["(%s | %s)" % (d[a], d[p]) for a, p in self.axes] def axes_to_name(self): """Return an abbreviated name for our axes""" from . import MemoryView d = MemoryView._spec_to_abbrev return "".join(["%s%s" % (d[a], d[p]) for a, p in self.axes]) def error_condition(self, result_code): return "!%s.memview" % result_code def __str__(self): from . import MemoryView axes_code_list = [] for idx, (access, packing) in enumerate(self.axes): flag = MemoryView.get_memoryview_flag(access, packing) if flag == "strided": axes_code_list.append(":") else: if flag == 'contiguous': have_follow = [p for a, p in self.axes[idx - 1:idx + 2] if p == 'follow'] if have_follow or self.ndim == 1: flag = '1' axes_code_list.append("::" + flag) if self.dtype.is_pyobject: dtype_name = self.dtype.name else: dtype_name = self.dtype return "%s[%s]" % (dtype_name, ", ".join(axes_code_list)) def specialize(self, values): """This does not validate the base type!!""" dtype = self.dtype.specialize(values) if dtype is not self.dtype: return MemoryViewSliceType(dtype, self.axes) return self def cast_code(self, expr_code): return expr_code class BufferType(BaseType): # # Delegates most attribute lookups to the base type. # (Anything not defined here or in the BaseType is delegated.) # # dtype PyrexType # ndim int # mode str # negative_indices bool # cast bool # is_buffer bool # writable bool is_buffer = 1 writable = True subtypes = ['dtype'] def __init__(self, base, dtype, ndim, mode, negative_indices, cast): self.base = base self.dtype = dtype self.ndim = ndim self.buffer_ptr_type = CPtrType(dtype) self.mode = mode self.negative_indices = negative_indices self.cast = cast def as_argument_type(self): return self def specialize(self, values): dtype = self.dtype.specialize(values) if dtype is not self.dtype: return BufferType(self.base, dtype, self.ndim, self.mode, self.negative_indices, self.cast) return self def __getattr__(self, name): return getattr(self.base, name) def __repr__(self): return "" % self.base def __str__(self): # avoid ', ', as fused functions split the signature string on ', ' cast_str = '' if self.cast: cast_str = ',cast=True' return "%s[%s,ndim=%d%s]" % (self.base, self.dtype, self.ndim, cast_str) def assignable_from(self, other_type): if other_type.is_buffer: return (self.same_as(other_type, compare_base=False) and self.base.assignable_from(other_type.base)) return self.base.assignable_from(other_type) def same_as(self, other_type, compare_base=True): if not other_type.is_buffer: return other_type.same_as(self.base) return (self.dtype.same_as(other_type.dtype) and self.ndim == other_type.ndim and self.mode == other_type.mode and self.cast == other_type.cast and (not compare_base or self.base.same_as(other_type.base))) class PyObjectType(PyrexType): # # Base class for all Python object types (reference-counted). # # buffer_defaults dict or None Default options for bu name = "object" is_pyobject = 1 default_value = "0" buffer_defaults = None is_extern = False is_subclassed = False is_gc_simple = False def __str__(self): return "Python object" def __repr__(self): return "" def can_coerce_to_pyobject(self, env): return True def default_coerced_ctype(self): """The default C type that this Python type coerces to, or None.""" return None def assignable_from(self, src_type): # except for pointers, conversion will be attempted return not src_type.is_ptr or src_type.is_string or src_type.is_pyunicode_ptr def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): if pyrex or for_display: base_code = "object" else: base_code = public_decl("PyObject", dll_linkage) entity_code = "*%s" % entity_code return self.base_declaration_code(base_code, entity_code) def as_pyobject(self, cname): if (not self.is_complete()) or self.is_extension_type: return "(PyObject *)" + cname else: return cname def py_type_name(self): return "object" def __lt__(self, other): """ Make sure we sort highest, as instance checking on py_type_name ('object') is always true """ return False def global_init_code(self, entry, code): code.put_init_var_to_py_none(entry, nanny=False) def check_for_null_code(self, cname): return cname builtin_types_that_cannot_create_refcycles = set([ 'bool', 'int', 'long', 'float', 'complex', 'bytearray', 'bytes', 'unicode', 'str', 'basestring' ]) class BuiltinObjectType(PyObjectType): # objstruct_cname string Name of PyObject struct is_builtin_type = 1 has_attributes = 1 base_type = None module_name = '__builtin__' # fields that let it look like an extension type vtabslot_cname = None vtabstruct_cname = None vtabptr_cname = None typedef_flag = True is_external = True decl_type = 'PyObject' def __init__(self, name, cname, objstruct_cname=None): self.name = name self.cname = cname self.typeptr_cname = "(&%s)" % cname self.objstruct_cname = objstruct_cname self.is_gc_simple = name in builtin_types_that_cannot_create_refcycles if name == 'type': # Special case the type type, as many C API calls (and other # libraries) actually expect a PyTypeObject* for type arguments. self.decl_type = objstruct_cname def set_scope(self, scope): self.scope = scope if scope: scope.parent_type = self def __str__(self): return "%s object" % self.name def __repr__(self): return "<%s>"% self.cname def default_coerced_ctype(self): if self.name in ('bytes', 'bytearray'): return c_char_ptr_type elif self.name == 'bool': return c_bint_type elif self.name == 'float': return c_double_type return None def assignable_from(self, src_type): if isinstance(src_type, BuiltinObjectType): if self.name == 'basestring': return src_type.name in ('str', 'unicode', 'basestring') else: return src_type.name == self.name elif src_type.is_extension_type: # FIXME: This is an ugly special case that we currently # keep supporting. It allows users to specify builtin # types as external extension types, while keeping them # compatible with the real builtin types. We already # generate a warning for it. Big TODO: remove! return (src_type.module_name == '__builtin__' and src_type.name == self.name) else: return True def typeobj_is_available(self): return True def attributes_known(self): return True def subtype_of(self, type): return type.is_pyobject and type.assignable_from(self) def type_check_function(self, exact=True): type_name = self.name if type_name == 'str': type_check = 'PyString_Check' elif type_name == 'basestring': type_check = '__Pyx_PyBaseString_Check' elif type_name == 'bytearray': type_check = 'PyByteArray_Check' elif type_name == 'frozenset': type_check = 'PyFrozenSet_Check' else: type_check = 'Py%s_Check' % type_name.capitalize() if exact and type_name not in ('bool', 'slice'): type_check += 'Exact' return type_check def isinstance_code(self, arg): return '%s(%s)' % (self.type_check_function(exact=False), arg) def type_test_code(self, arg, notnone=False, exact=True): type_check = self.type_check_function(exact=exact) check = 'likely(%s(%s))' % (type_check, arg) if not notnone: check += '||((%s) == Py_None)' % arg if self.name == 'basestring': name = '(PY_MAJOR_VERSION < 3 ? "basestring" : "str")' space_for_name = 16 else: name = '"%s"' % self.name # avoid wasting too much space but limit number of different format strings space_for_name = (len(self.name) // 16 + 1) * 16 error = '(PyErr_Format(PyExc_TypeError, "Expected %%.%ds, got %%.200s", %s, Py_TYPE(%s)->tp_name), 0)' % ( space_for_name, name, arg) return check + '||' + error def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): if pyrex or for_display: base_code = self.name else: base_code = public_decl(self.decl_type, dll_linkage) entity_code = "*%s" % entity_code return self.base_declaration_code(base_code, entity_code) def as_pyobject(self, cname): if self.decl_type == 'PyObject': return cname else: return "(PyObject *)" + cname def cast_code(self, expr_code, to_object_struct = False): return "((%s*)%s)" % ( to_object_struct and self.objstruct_cname or self.decl_type, # self.objstruct_cname may be None expr_code) def py_type_name(self): return self.name class PyExtensionType(PyObjectType): # # A Python extension type. # # name string # scope CClassScope Attribute namespace # visibility string # typedef_flag boolean # base_type PyExtensionType or None # module_name string or None Qualified name of defining module # objstruct_cname string Name of PyObject struct # objtypedef_cname string Name of PyObject struct typedef # typeobj_cname string or None C code fragment referring to type object # typeptr_cname string or None Name of pointer to external type object # vtabslot_cname string Name of C method table member # vtabstruct_cname string Name of C method table struct # vtabptr_cname string Name of pointer to C method table # vtable_cname string Name of C method table definition # defered_declarations [thunk] Used to declare class hierarchies in order is_extension_type = 1 has_attributes = 1 objtypedef_cname = None def __init__(self, name, typedef_flag, base_type, is_external=0): self.name = name self.scope = None self.typedef_flag = typedef_flag if base_type is not None: base_type.is_subclassed = True self.base_type = base_type self.module_name = None self.objstruct_cname = None self.typeobj_cname = None self.typeptr_cname = None self.vtabslot_cname = None self.vtabstruct_cname = None self.vtabptr_cname = None self.vtable_cname = None self.is_external = is_external self.defered_declarations = [] def set_scope(self, scope): self.scope = scope if scope: scope.parent_type = self def needs_nonecheck(self): return True def subtype_of_resolved_type(self, other_type): if other_type.is_extension_type or other_type.is_builtin_type: return self is other_type or ( self.base_type and self.base_type.subtype_of(other_type)) else: return other_type is py_object_type def typeobj_is_available(self): # Do we have a pointer to the type object? return self.typeptr_cname def typeobj_is_imported(self): # If we don't know the C name of the type object but we do # know which module it's defined in, it will be imported. return self.typeobj_cname is None and self.module_name is not None def assignable_from(self, src_type): if self == src_type: return True if isinstance(src_type, PyExtensionType): if src_type.base_type is not None: return self.assignable_from(src_type.base_type) if isinstance(src_type, BuiltinObjectType): # FIXME: This is an ugly special case that we currently # keep supporting. It allows users to specify builtin # types as external extension types, while keeping them # compatible with the real builtin types. We already # generate a warning for it. Big TODO: remove! return (self.module_name == '__builtin__' and self.name == src_type.name) return False def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0, deref = 0): if pyrex or for_display: base_code = self.name else: if self.typedef_flag: objstruct = self.objstruct_cname else: objstruct = "struct %s" % self.objstruct_cname base_code = public_decl(objstruct, dll_linkage) if deref: assert not entity_code else: entity_code = "*%s" % entity_code return self.base_declaration_code(base_code, entity_code) def type_test_code(self, py_arg, notnone=False): none_check = "((%s) == Py_None)" % py_arg type_check = "likely(__Pyx_TypeTest(%s, %s))" % ( py_arg, self.typeptr_cname) if notnone: return type_check else: return "likely(%s || %s)" % (none_check, type_check) def attributes_known(self): return self.scope is not None def __str__(self): return self.name def __repr__(self): return "" % (self.scope.class_name, ("", " typedef")[self.typedef_flag]) def py_type_name(self): if not self.module_name: return self.name return "__import__(%r, None, None, ['']).%s" % (self.module_name, self.name) class CType(PyrexType): # # Base class for all C types (non-reference-counted). # # to_py_function string C function for converting to Python object # from_py_function string C function for constructing from Python object # to_py_function = None from_py_function = None exception_value = None exception_check = 1 def create_to_py_utility_code(self, env): return self.to_py_function is not None def create_from_py_utility_code(self, env): return self.from_py_function is not None def can_coerce_to_pyobject(self, env): return self.create_to_py_utility_code(env) def error_condition(self, result_code): conds = [] if self.is_string or self.is_pyunicode_ptr: conds.append("(!%s)" % result_code) elif self.exception_value is not None: conds.append("(%s == (%s)%s)" % (result_code, self.sign_and_name(), self.exception_value)) if self.exception_check: conds.append("PyErr_Occurred()") if len(conds) > 0: return " && ".join(conds) else: return 0 def to_py_call_code(self, source_code, result_code, result_type, to_py_function=None): func = self.to_py_function if to_py_function is None else to_py_function assert func if self.is_string or self.is_cpp_string: if result_type.is_builtin_type: result_type_name = result_type.name if result_type_name in ('bytes', 'str', 'unicode'): func = func.replace("Object", result_type_name.title(), 1) elif result_type_name == 'bytearray': func = func.replace("Object", "ByteArray", 1) return '%s = %s(%s)' % ( result_code, func, source_code or 'NULL') def from_py_call_code(self, source_code, result_code, error_pos, code, from_py_function=None, error_condition=None): return '%s = %s(%s); %s' % ( result_code, from_py_function or self.from_py_function, source_code, code.error_goto_if(error_condition or self.error_condition(result_code), error_pos)) class CConstType(BaseType): is_const = 1 def __init__(self, const_base_type): self.const_base_type = const_base_type if const_base_type.has_attributes and const_base_type.scope is not None: from . import Symtab self.scope = Symtab.CConstScope(const_base_type.scope) def __repr__(self): return "" % repr(self.const_base_type) def __str__(self): return self.declaration_code("", for_display=1) def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): if for_display or pyrex: return "const " + self.const_base_type.declaration_code(entity_code, for_display, dll_linkage, pyrex) else: return self.const_base_type.declaration_code("const %s" % entity_code, for_display, dll_linkage, pyrex) def specialize(self, values): base_type = self.const_base_type.specialize(values) if base_type == self.const_base_type: return self else: return CConstType(base_type) def deduce_template_params(self, actual): return self.const_base_type.deduce_template_params(actual) def can_coerce_to_pyobject(self, env): return self.const_base_type.can_coerce_to_pyobject(env) def create_to_py_utility_code(self, env): if self.const_base_type.create_to_py_utility_code(env): self.to_py_function = self.const_base_type.to_py_function return True def __getattr__(self, name): return getattr(self.const_base_type, name) class FusedType(CType): """ Represents a Fused Type. All it needs to do is keep track of the types it aggregates, as it will be replaced with its specific version wherever needed. See http://wiki.cython.org/enhancements/fusedtypes types [PyrexType] is the list of types to be fused name str the name of the ctypedef """ is_fused = 1 exception_check = 0 def __init__(self, types, name=None): # Use list rather than set to preserve order (list should be short). flattened_types = [] for t in types: if t.is_fused: # recursively merge in subtypes for subtype in t.types: if subtype not in flattened_types: flattened_types.append(subtype) elif t not in flattened_types: flattened_types.append(t) self.types = flattened_types self.name = name def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): if pyrex or for_display: return self.name raise Exception("This may never happen, please report a bug") def __repr__(self): return 'FusedType(name=%r)' % self.name def specialize(self, values): return values[self] def get_fused_types(self, result=None, seen=None): if result is None: return [self] if self not in seen: result.append(self) seen.add(self) class CVoidType(CType): # # C "void" type # is_void = 1 to_py_function = "__Pyx_void_to_None" def __repr__(self): return "" def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): if pyrex or for_display: base_code = "void" else: base_code = public_decl("void", dll_linkage) return self.base_declaration_code(base_code, entity_code) def is_complete(self): return 0 class InvisibleVoidType(CVoidType): # # For use with C++ constructors and destructors return types. # Acts like void, but does not print out a declaration. # def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): if pyrex or for_display: base_code = "[void]" else: base_code = public_decl("", dll_linkage) return self.base_declaration_code(base_code, entity_code) class CNumericType(CType): # # Base class for all C numeric types. # # rank integer Relative size # signed integer 0 = unsigned, 1 = unspecified, 2 = explicitly signed # is_numeric = 1 default_value = "0" has_attributes = True scope = None sign_words = ("unsigned ", "", "signed ") def __init__(self, rank, signed = 1): self.rank = rank if rank > 0 and signed == SIGNED: # Signed is meaningless for anything but char, and complicates # type promotion. signed = 1 self.signed = signed def sign_and_name(self): s = self.sign_words[self.signed] n = rank_to_type_name[self.rank] return s + n def __repr__(self): return "" % self.sign_and_name() def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): type_name = self.sign_and_name() if pyrex or for_display: base_code = type_name.replace('PY_LONG_LONG', 'long long') else: base_code = public_decl(type_name, dll_linkage) return self.base_declaration_code(base_code, entity_code) def attributes_known(self): if self.scope is None: from . import Symtab self.scope = scope = Symtab.CClassScope( '', None, visibility="extern") scope.parent_type = self scope.directives = {} scope.declare_cfunction( "conjugate", CFuncType(self, [CFuncTypeArg("self", self, None)], nogil=True), pos=None, defining=1, cname=" ") return True def __lt__(self, other): """Sort based on rank, preferring signed over unsigned""" if other.is_numeric: return self.rank > other.rank and self.signed >= other.signed # Prefer numeric types over others return True def py_type_name(self): if self.rank <= 4: return "(int, long)" return "float" class ForbidUseClass: def __repr__(self): raise RuntimeError() def __str__(self): raise RuntimeError() ForbidUse = ForbidUseClass() class CIntType(CNumericType): is_int = 1 typedef_flag = 0 to_py_function = None from_py_function = None exception_value = -1 def can_coerce_to_pyobject(self, env): return True def create_to_py_utility_code(self, env): if type(self).to_py_function is None: self.to_py_function = "__Pyx_PyInt_From_" + self.specialization_name() env.use_utility_code(TempitaUtilityCode.load_cached( "CIntToPy", "TypeConversion.c", context={"TYPE": self.empty_declaration_code(), "TO_PY_FUNCTION": self.to_py_function})) return True def create_from_py_utility_code(self, env): if type(self).from_py_function is None: self.from_py_function = "__Pyx_PyInt_As_" + self.specialization_name() env.use_utility_code(TempitaUtilityCode.load_cached( "CIntFromPy", "TypeConversion.c", context={"TYPE": self.empty_declaration_code(), "FROM_PY_FUNCTION": self.from_py_function})) return True def get_to_py_type_conversion(self): if self.rank < list(rank_to_type_name).index('int'): # This assumes sizeof(short) < sizeof(int) return "PyInt_FromLong" else: # Py{Int|Long}_From[Unsigned]Long[Long] Prefix = "Int" SignWord = "" TypeName = "Long" if not self.signed: Prefix = "Long" SignWord = "Unsigned" if self.rank >= list(rank_to_type_name).index('PY_LONG_LONG'): Prefix = "Long" TypeName = "LongLong" return "Py%s_From%s%s" % (Prefix, SignWord, TypeName) def assignable_from_resolved_type(self, src_type): return src_type.is_int or src_type.is_enum or src_type is error_type def invalid_value(self): if rank_to_type_name[int(self.rank)] == 'char': return "'?'" else: # We do not really know the size of the type, so return # a 32-bit literal and rely on casting to final type. It will # be negative for signed ints, which is good. return "0xbad0bad0" def overflow_check_binop(self, binop, env, const_rhs=False): env.use_utility_code(UtilityCode.load("Common", "Overflow.c")) type = self.empty_declaration_code() name = self.specialization_name() if binop == "lshift": env.use_utility_code(TempitaUtilityCode.load_cached( "LeftShift", "Overflow.c", context={'TYPE': type, 'NAME': name, 'SIGNED': self.signed})) else: if const_rhs: binop += "_const" if type in ('int', 'long', 'long long'): env.use_utility_code(TempitaUtilityCode.load_cached( "BaseCaseSigned", "Overflow.c", context={'INT': type, 'NAME': name})) elif type in ('unsigned int', 'unsigned long', 'unsigned long long'): env.use_utility_code(TempitaUtilityCode.load_cached( "BaseCaseUnsigned", "Overflow.c", context={'UINT': type, 'NAME': name})) elif self.rank <= 1: # sizeof(short) < sizeof(int) return "__Pyx_%s_%s_no_overflow" % (binop, name) else: _load_overflow_base(env) env.use_utility_code(TempitaUtilityCode.load_cached( "SizeCheck", "Overflow.c", context={'TYPE': type, 'NAME': name})) env.use_utility_code(TempitaUtilityCode.load_cached( "Binop", "Overflow.c", context={'TYPE': type, 'NAME': name, 'BINOP': binop})) return "__Pyx_%s_%s_checking_overflow" % (binop, name) def _load_overflow_base(env): env.use_utility_code(UtilityCode.load("Common", "Overflow.c")) for type in ('int', 'long', 'long long'): env.use_utility_code(TempitaUtilityCode.load_cached( "BaseCaseSigned", "Overflow.c", context={'INT': type, 'NAME': type.replace(' ', '_')})) for type in ('unsigned int', 'unsigned long', 'unsigned long long'): env.use_utility_code(TempitaUtilityCode.load_cached( "BaseCaseUnsigned", "Overflow.c", context={'UINT': type, 'NAME': type.replace(' ', '_')})) class CAnonEnumType(CIntType): is_enum = 1 def sign_and_name(self): return 'int' class CReturnCodeType(CIntType): to_py_function = "__Pyx_Owned_Py_None" is_returncode = True exception_check = False class CBIntType(CIntType): to_py_function = "__Pyx_PyBool_FromLong" from_py_function = "__Pyx_PyObject_IsTrue" exception_check = 1 # for C++ bool def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): if for_display: base_code = 'bool' elif pyrex: base_code = 'bint' else: base_code = public_decl('int', dll_linkage) return self.base_declaration_code(base_code, entity_code) def __repr__(self): return "" def __str__(self): return 'bint' def py_type_name(self): return "bool" class CPyUCS4IntType(CIntType): # Py_UCS4 is_unicode_char = True # Py_UCS4 coerces from and to single character unicode strings (or # at most two characters on 16bit Unicode builds), but we also # allow Python integers as input. The value range for Py_UCS4 # is 0..1114111, which is checked when converting from an integer # value. to_py_function = "PyUnicode_FromOrdinal" from_py_function = "__Pyx_PyObject_AsPy_UCS4" def create_from_py_utility_code(self, env): env.use_utility_code(UtilityCode.load_cached("ObjectAsUCS4", "TypeConversion.c")) return True def sign_and_name(self): return "Py_UCS4" class CPyUnicodeIntType(CIntType): # Py_UNICODE is_unicode_char = True # Py_UNICODE coerces from and to single character unicode strings, # but we also allow Python integers as input. The value range for # Py_UNICODE is 0..1114111, which is checked when converting from # an integer value. to_py_function = "PyUnicode_FromOrdinal" from_py_function = "__Pyx_PyObject_AsPy_UNICODE" def create_from_py_utility_code(self, env): env.use_utility_code(UtilityCode.load_cached("ObjectAsPyUnicode", "TypeConversion.c")) return True def sign_and_name(self): return "Py_UNICODE" class CPyHashTType(CIntType): to_py_function = "__Pyx_PyInt_FromHash_t" from_py_function = "__Pyx_PyInt_AsHash_t" def sign_and_name(self): return "Py_hash_t" class CPySSizeTType(CIntType): to_py_function = "PyInt_FromSsize_t" from_py_function = "__Pyx_PyIndex_AsSsize_t" def sign_and_name(self): return "Py_ssize_t" class CSSizeTType(CIntType): to_py_function = "PyInt_FromSsize_t" from_py_function = "PyInt_AsSsize_t" def sign_and_name(self): return "Py_ssize_t" class CSizeTType(CIntType): to_py_function = "__Pyx_PyInt_FromSize_t" def sign_and_name(self): return "size_t" class CPtrdiffTType(CIntType): def sign_and_name(self): return "ptrdiff_t" class CFloatType(CNumericType): is_float = 1 to_py_function = "PyFloat_FromDouble" from_py_function = "__pyx_PyFloat_AsDouble" exception_value = -1 def __init__(self, rank, math_h_modifier = ''): CNumericType.__init__(self, rank, 1) self.math_h_modifier = math_h_modifier if rank == RANK_FLOAT: self.from_py_function = "__pyx_PyFloat_AsFloat" def assignable_from_resolved_type(self, src_type): return (src_type.is_numeric and not src_type.is_complex) or src_type is error_type def invalid_value(self): return Naming.PYX_NAN class CComplexType(CNumericType): is_complex = 1 to_py_function = "__pyx_PyComplex_FromComplex" has_attributes = 1 scope = None def __init__(self, real_type): while real_type.is_typedef and not real_type.typedef_is_external: real_type = real_type.typedef_base_type if real_type.is_typedef and real_type.typedef_is_external: # The below is not actually used: Coercions are currently disabled # so that complex types of external types can not be created self.funcsuffix = "_%s" % real_type.specialization_name() elif hasattr(real_type, 'math_h_modifier'): self.funcsuffix = real_type.math_h_modifier else: self.funcsuffix = "_%s" % real_type.specialization_name() self.real_type = real_type CNumericType.__init__(self, real_type.rank + 0.5, real_type.signed) self.binops = {} self.from_parts = "%s_from_parts" % self.specialization_name() self.default_value = "%s(0, 0)" % self.from_parts def __eq__(self, other): if isinstance(self, CComplexType) and isinstance(other, CComplexType): return self.real_type == other.real_type else: return False def __ne__(self, other): if isinstance(self, CComplexType) and isinstance(other, CComplexType): return self.real_type != other.real_type else: return True def __lt__(self, other): if isinstance(self, CComplexType) and isinstance(other, CComplexType): return self.real_type < other.real_type else: # this is arbitrary, but it makes sure we always have # *some* kind of order return False def __hash__(self): return ~hash(self.real_type) def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): if pyrex or for_display: real_code = self.real_type.declaration_code("", for_display, dll_linkage, pyrex) base_code = "%s complex" % real_code else: base_code = public_decl(self.sign_and_name(), dll_linkage) return self.base_declaration_code(base_code, entity_code) def sign_and_name(self): real_type_name = self.real_type.specialization_name() real_type_name = real_type_name.replace('long__double','long_double') real_type_name = real_type_name.replace('PY_LONG_LONG','long_long') return Naming.type_prefix + real_type_name + "_complex" def assignable_from(self, src_type): # Temporary hack/feature disabling, see #441 if (not src_type.is_complex and src_type.is_numeric and src_type.is_typedef and src_type.typedef_is_external): return False else: return super(CComplexType, self).assignable_from(src_type) def assignable_from_resolved_type(self, src_type): return (src_type.is_complex and self.real_type.assignable_from_resolved_type(src_type.real_type) or src_type.is_numeric and self.real_type.assignable_from_resolved_type(src_type) or src_type is error_type) def attributes_known(self): if self.scope is None: from . import Symtab self.scope = scope = Symtab.CClassScope( '', None, visibility="extern") scope.parent_type = self scope.directives = {} scope.declare_var("real", self.real_type, None, cname="real", is_cdef=True) scope.declare_var("imag", self.real_type, None, cname="imag", is_cdef=True) scope.declare_cfunction( "conjugate", CFuncType(self, [CFuncTypeArg("self", self, None)], nogil=True), pos=None, defining=1, cname="__Pyx_c_conj%s" % self.funcsuffix) return True def create_declaration_utility_code(self, env): # This must always be run, because a single CComplexType instance can be shared # across multiple compilations (the one created in the module scope) env.use_utility_code(complex_header_utility_code) env.use_utility_code(complex_real_imag_utility_code) for utility_code in (complex_type_utility_code, complex_from_parts_utility_code, complex_arithmetic_utility_code): env.use_utility_code( utility_code.specialize( self, real_type = self.real_type.empty_declaration_code(), m = self.funcsuffix, is_float = self.real_type.is_float)) return True def can_coerce_to_pyobject(self, env): return True def create_to_py_utility_code(self, env): env.use_utility_code(complex_real_imag_utility_code) env.use_utility_code(complex_to_py_utility_code) return True def create_from_py_utility_code(self, env): self.real_type.create_from_py_utility_code(env) for utility_code in (complex_from_parts_utility_code, complex_from_py_utility_code): env.use_utility_code( utility_code.specialize( self, real_type = self.real_type.empty_declaration_code(), m = self.funcsuffix, is_float = self.real_type.is_float)) self.from_py_function = "__Pyx_PyComplex_As_" + self.specialization_name() return True def lookup_op(self, nargs, op): try: return self.binops[nargs, op] except KeyError: pass try: op_name = complex_ops[nargs, op] self.binops[nargs, op] = func_name = "__Pyx_c_%s%s" % (op_name, self.funcsuffix) return func_name except KeyError: return None def unary_op(self, op): return self.lookup_op(1, op) def binary_op(self, op): return self.lookup_op(2, op) def py_type_name(self): return "complex" def cast_code(self, expr_code): return expr_code complex_ops = { (1, '-'): 'neg', (1, 'zero'): 'is_zero', (2, '+'): 'sum', (2, '-'): 'diff', (2, '*'): 'prod', (2, '/'): 'quot', (2, '=='): 'eq', } complex_header_utility_code = UtilityCode( proto_block='h_code', proto=""" #if !defined(CYTHON_CCOMPLEX) #if defined(__cplusplus) #define CYTHON_CCOMPLEX 1 #elif defined(_Complex_I) #define CYTHON_CCOMPLEX 1 #else #define CYTHON_CCOMPLEX 0 #endif #endif #if CYTHON_CCOMPLEX #ifdef __cplusplus #include #else #include #endif #endif #if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__) #undef _Complex_I #define _Complex_I 1.0fj #endif """) complex_real_imag_utility_code = UtilityCode( proto=""" #if CYTHON_CCOMPLEX #ifdef __cplusplus #define __Pyx_CREAL(z) ((z).real()) #define __Pyx_CIMAG(z) ((z).imag()) #else #define __Pyx_CREAL(z) (__real__(z)) #define __Pyx_CIMAG(z) (__imag__(z)) #endif #else #define __Pyx_CREAL(z) ((z).real) #define __Pyx_CIMAG(z) ((z).imag) #endif #if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX #define __Pyx_SET_CREAL(z,x) ((z).real(x)) #define __Pyx_SET_CIMAG(z,y) ((z).imag(y)) #else #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x) #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y) #endif """) complex_type_utility_code = UtilityCode( proto_block='complex_type_declarations', proto=""" #if CYTHON_CCOMPLEX #ifdef __cplusplus typedef ::std::complex< %(real_type)s > %(type_name)s; #else typedef %(real_type)s _Complex %(type_name)s; #endif #else typedef struct { %(real_type)s real, imag; } %(type_name)s; #endif """) complex_from_parts_utility_code = UtilityCode( proto_block='utility_code_proto', proto=""" static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s); """, impl=""" #if CYTHON_CCOMPLEX #ifdef __cplusplus static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) { return ::std::complex< %(real_type)s >(x, y); } #else static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) { return x + y*(%(type)s)_Complex_I; } #endif #else static CYTHON_INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) { %(type)s z; z.real = x; z.imag = y; return z; } #endif """) complex_to_py_utility_code = UtilityCode( proto=""" #define __pyx_PyComplex_FromComplex(z) \\ PyComplex_FromDoubles((double)__Pyx_CREAL(z), \\ (double)__Pyx_CIMAG(z)) """) complex_from_py_utility_code = UtilityCode( proto=""" static %(type)s __Pyx_PyComplex_As_%(type_name)s(PyObject*); """, impl=""" static %(type)s __Pyx_PyComplex_As_%(type_name)s(PyObject* o) { Py_complex cval; #if CYTHON_COMPILING_IN_CPYTHON if (PyComplex_CheckExact(o)) cval = ((PyComplexObject *)o)->cval; else #endif cval = PyComplex_AsCComplex(o); return %(type_name)s_from_parts( (%(real_type)s)cval.real, (%(real_type)s)cval.imag); } """) complex_arithmetic_utility_code = UtilityCode( proto=""" #if CYTHON_CCOMPLEX #define __Pyx_c_eq%(m)s(a, b) ((a)==(b)) #define __Pyx_c_sum%(m)s(a, b) ((a)+(b)) #define __Pyx_c_diff%(m)s(a, b) ((a)-(b)) #define __Pyx_c_prod%(m)s(a, b) ((a)*(b)) #define __Pyx_c_quot%(m)s(a, b) ((a)/(b)) #define __Pyx_c_neg%(m)s(a) (-(a)) #ifdef __cplusplus #define __Pyx_c_is_zero%(m)s(z) ((z)==(%(real_type)s)0) #define __Pyx_c_conj%(m)s(z) (::std::conj(z)) #if %(is_float)s #define __Pyx_c_abs%(m)s(z) (::std::abs(z)) #define __Pyx_c_pow%(m)s(a, b) (::std::pow(a, b)) #endif #else #define __Pyx_c_is_zero%(m)s(z) ((z)==0) #define __Pyx_c_conj%(m)s(z) (conj%(m)s(z)) #if %(is_float)s #define __Pyx_c_abs%(m)s(z) (cabs%(m)s(z)) #define __Pyx_c_pow%(m)s(a, b) (cpow%(m)s(a, b)) #endif #endif #else static CYTHON_INLINE int __Pyx_c_eq%(m)s(%(type)s, %(type)s); static CYTHON_INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s, %(type)s); static CYTHON_INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s, %(type)s); static CYTHON_INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s, %(type)s); static CYTHON_INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s, %(type)s); static CYTHON_INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s); static CYTHON_INLINE int __Pyx_c_is_zero%(m)s(%(type)s); static CYTHON_INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s); #if %(is_float)s static CYTHON_INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s); static CYTHON_INLINE %(type)s __Pyx_c_pow%(m)s(%(type)s, %(type)s); #endif #endif """, impl=""" #if CYTHON_CCOMPLEX #else static CYTHON_INLINE int __Pyx_c_eq%(m)s(%(type)s a, %(type)s b) { return (a.real == b.real) && (a.imag == b.imag); } static CYTHON_INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s a, %(type)s b) { %(type)s z; z.real = a.real + b.real; z.imag = a.imag + b.imag; return z; } static CYTHON_INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s a, %(type)s b) { %(type)s z; z.real = a.real - b.real; z.imag = a.imag - b.imag; return z; } static CYTHON_INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s a, %(type)s b) { %(type)s z; z.real = a.real * b.real - a.imag * b.imag; z.imag = a.real * b.imag + a.imag * b.real; return z; } static CYTHON_INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s a, %(type)s b) { %(type)s z; %(real_type)s denom = b.real * b.real + b.imag * b.imag; z.real = (a.real * b.real + a.imag * b.imag) / denom; z.imag = (a.imag * b.real - a.real * b.imag) / denom; return z; } static CYTHON_INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s a) { %(type)s z; z.real = -a.real; z.imag = -a.imag; return z; } static CYTHON_INLINE int __Pyx_c_is_zero%(m)s(%(type)s a) { return (a.real == 0) && (a.imag == 0); } static CYTHON_INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s a) { %(type)s z; z.real = a.real; z.imag = -a.imag; return z; } #if %(is_float)s static CYTHON_INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s z) { #if !defined(HAVE_HYPOT) || defined(_MSC_VER) return sqrt%(m)s(z.real*z.real + z.imag*z.imag); #else return hypot%(m)s(z.real, z.imag); #endif } static CYTHON_INLINE %(type)s __Pyx_c_pow%(m)s(%(type)s a, %(type)s b) { %(type)s z; %(real_type)s r, lnr, theta, z_r, z_theta; if (b.imag == 0 && b.real == (int)b.real) { if (b.real < 0) { %(real_type)s denom = a.real * a.real + a.imag * a.imag; a.real = a.real / denom; a.imag = -a.imag / denom; b.real = -b.real; } switch ((int)b.real) { case 0: z.real = 1; z.imag = 0; return z; case 1: return a; case 2: z = __Pyx_c_prod%(m)s(a, a); return __Pyx_c_prod%(m)s(a, a); case 3: z = __Pyx_c_prod%(m)s(a, a); return __Pyx_c_prod%(m)s(z, a); case 4: z = __Pyx_c_prod%(m)s(a, a); return __Pyx_c_prod%(m)s(z, z); } } if (a.imag == 0) { if (a.real == 0) { return a; } r = a.real; theta = 0; } else { r = __Pyx_c_abs%(m)s(a); theta = atan2%(m)s(a.imag, a.real); } lnr = log%(m)s(r); z_r = exp%(m)s(lnr * b.real - theta * b.imag); z_theta = theta * b.real + lnr * b.imag; z.real = z_r * cos%(m)s(z_theta); z.imag = z_r * sin%(m)s(z_theta); return z; } #endif #endif """) class CPointerBaseType(CType): # common base type for pointer/array types # # base_type CType Reference type subtypes = ['base_type'] def __init__(self, base_type): self.base_type = base_type for char_type in (c_char_type, c_uchar_type, c_schar_type): if base_type.same_as(char_type): self.is_string = 1 break else: if base_type.same_as(c_py_unicode_type): self.is_pyunicode_ptr = 1 if self.is_string and not base_type.is_error: if base_type.signed == 2: self.to_py_function = "__Pyx_PyObject_FromCString" if self.is_ptr: self.from_py_function = "__Pyx_PyObject_AsSString" elif base_type.signed: self.to_py_function = "__Pyx_PyObject_FromString" if self.is_ptr: self.from_py_function = "__Pyx_PyObject_AsString" else: self.to_py_function = "__Pyx_PyObject_FromCString" if self.is_ptr: self.from_py_function = "__Pyx_PyObject_AsUString" self.exception_value = "NULL" elif self.is_pyunicode_ptr and not base_type.is_error: self.to_py_function = "__Pyx_PyUnicode_FromUnicode" if self.is_ptr: self.from_py_function = "__Pyx_PyUnicode_AsUnicode" self.exception_value = "NULL" def py_type_name(self): if self.is_string: return "bytes" elif self.is_pyunicode_ptr: return "unicode" else: return super(CPointerBaseType, self).py_type_name() def literal_code(self, value): if self.is_string: assert isinstance(value, str) return '"%s"' % StringEncoding.escape_byte_string(value) class CArrayType(CPointerBaseType): # base_type CType Element type # size integer or None Number of elements is_array = 1 to_tuple_function = None def __init__(self, base_type, size): super(CArrayType, self).__init__(base_type) self.size = size def __eq__(self, other): if isinstance(other, CType) and other.is_array and self.size == other.size: return self.base_type.same_as(other.base_type) return False def __hash__(self): return hash(self.base_type) + 28 # arbitrarily chosen offset def __repr__(self): return "" % (self.size, repr(self.base_type)) def same_as_resolved_type(self, other_type): return ((other_type.is_array and self.base_type.same_as(other_type.base_type)) or other_type is error_type) def assignable_from_resolved_type(self, src_type): # C arrays are assigned by value, either Python containers or C arrays/pointers if src_type.is_pyobject: return True if src_type.is_ptr or src_type.is_array: return self.base_type.assignable_from(src_type.base_type) return False def element_ptr_type(self): return c_ptr_type(self.base_type) def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): if self.size is not None: dimension_code = self.size else: dimension_code = "" if entity_code.startswith("*"): entity_code = "(%s)" % entity_code return self.base_type.declaration_code( "%s[%s]" % (entity_code, dimension_code), for_display, dll_linkage, pyrex) def as_argument_type(self): return c_ptr_type(self.base_type) def is_complete(self): return self.size is not None def specialize(self, values): base_type = self.base_type.specialize(values) if base_type == self.base_type: return self else: return CArrayType(base_type, self.size) def deduce_template_params(self, actual): if isinstance(actual, CArrayType): return self.base_type.deduce_template_params(actual.base_type) else: return None def can_coerce_to_pyobject(self, env): return self.base_type.can_coerce_to_pyobject(env) def create_to_py_utility_code(self, env): if self.to_py_function is not None: return self.to_py_function if not self.base_type.create_to_py_utility_code(env): return False base_type = self.base_type.declaration_code("", pyrex=1) safe_typename = re.sub('[^a-zA-Z0-9]', '__', base_type) to_py_function = "__Pyx_carray_to_py_%s" % safe_typename to_tuple_function = "__Pyx_carray_to_tuple_%s" % safe_typename from .UtilityCode import CythonUtilityCode context = { 'cname': to_py_function, 'to_tuple_cname': to_tuple_function, 'base_type': base_type, } env.use_utility_code(CythonUtilityCode.load( "carray.to_py", "CConvert.pyx", outer_module_scope=env.global_scope(), # need access to types declared in module context=context, compiler_directives=dict(env.global_scope().directives))) self.to_tuple_function = to_tuple_function self.to_py_function = to_py_function return True def to_py_call_code(self, source_code, result_code, result_type, to_py_function=None): func = self.to_py_function if to_py_function is None else to_py_function if self.is_string or self.is_pyunicode_ptr: return '%s = %s(%s)' % ( result_code, func, source_code) target_is_tuple = result_type.is_builtin_type and result_type.name == 'tuple' return '%s = %s(%s, %s)' % ( result_code, self.to_tuple_function if target_is_tuple else func, source_code, self.size) def create_from_py_utility_code(self, env): if self.from_py_function is not None: return self.from_py_function if not self.base_type.create_from_py_utility_code(env): return False base_type = self.base_type.declaration_code("", pyrex=1) safe_typename = re.sub('[^a-zA-Z0-9]', '__', base_type) from_py_function = "__Pyx_carray_from_py_%s" % safe_typename from .UtilityCode import CythonUtilityCode context = { 'cname': from_py_function, 'base_type': base_type, } env.use_utility_code(CythonUtilityCode.load( "carray.from_py", "CConvert.pyx", outer_module_scope=env.global_scope(), # need access to types declared in module context=context, compiler_directives=dict(env.global_scope().directives))) self.from_py_function = from_py_function return True def from_py_call_code(self, source_code, result_code, error_pos, code, from_py_function=None, error_condition=None): call_code = "%s(%s, %s, %s)" % ( from_py_function or self.from_py_function, source_code, result_code, self.size) return code.error_goto_if_neg(call_code, error_pos) class CPtrType(CPointerBaseType): # base_type CType Reference type is_ptr = 1 default_value = "0" def __hash__(self): return hash(self.base_type) + 27 # arbitrarily chosen offset def __eq__(self, other): if isinstance(other, CType) and other.is_ptr: return self.base_type.same_as(other.base_type) return False def __ne__(self, other): return not (self == other) def __repr__(self): return "" % repr(self.base_type) def same_as_resolved_type(self, other_type): return ((other_type.is_ptr and self.base_type.same_as(other_type.base_type)) or other_type is error_type) def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): #print "CPtrType.declaration_code: pointer to", self.base_type ### return self.base_type.declaration_code( "*%s" % entity_code, for_display, dll_linkage, pyrex) def assignable_from_resolved_type(self, other_type): if other_type is error_type: return 1 if other_type.is_null_ptr: return 1 if self.base_type.is_const: self = CPtrType(self.base_type.const_base_type) if self.base_type.is_cfunction: if other_type.is_ptr: other_type = other_type.base_type.resolve() if other_type.is_cfunction: return self.base_type.pointer_assignable_from_resolved_type(other_type) else: return 0 if (self.base_type.is_cpp_class and other_type.is_ptr and other_type.base_type.is_cpp_class and other_type.base_type.is_subclass(self.base_type)): return 1 if other_type.is_array or other_type.is_ptr: return self.base_type.is_void or self.base_type.same_as(other_type.base_type) return 0 def specialize(self, values): base_type = self.base_type.specialize(values) if base_type == self.base_type: return self else: return CPtrType(base_type) def deduce_template_params(self, actual): if isinstance(actual, CPtrType): return self.base_type.deduce_template_params(actual.base_type) else: return None def invalid_value(self): return "1" def find_cpp_operation_type(self, operator, operand_type=None): if self.base_type.is_cpp_class: return self.base_type.find_cpp_operation_type(operator, operand_type) return None class CNullPtrType(CPtrType): is_null_ptr = 1 class CReferenceType(BaseType): is_reference = 1 is_fake_reference = 0 def __init__(self, base_type): self.ref_base_type = base_type def __repr__(self): return "" % repr(self.ref_base_type) def __str__(self): return "%s &" % self.ref_base_type def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): #print "CReferenceType.declaration_code: pointer to", self.base_type ### return self.ref_base_type.declaration_code( "&%s" % entity_code, for_display, dll_linkage, pyrex) def specialize(self, values): base_type = self.ref_base_type.specialize(values) if base_type == self.ref_base_type: return self else: return type(self)(base_type) def deduce_template_params(self, actual): return self.ref_base_type.deduce_template_params(actual) def __getattr__(self, name): return getattr(self.ref_base_type, name) class CFakeReferenceType(CReferenceType): is_fake_reference = 1 def __repr__(self): return "" % repr(self.ref_base_type) def __str__(self): return "%s [&]" % self.ref_base_type def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): #print "CReferenceType.declaration_code: pointer to", self.base_type ### return "__Pyx_FakeReference<%s> %s" % (self.ref_base_type.empty_declaration_code(), entity_code) class CFuncType(CType): # return_type CType # args [CFuncTypeArg] # has_varargs boolean # exception_value string # exception_check boolean True if PyErr_Occurred check needed # calling_convention string Function calling convention # nogil boolean Can be called without gil # with_gil boolean Acquire gil around function body # templates [string] or None # cached_specialized_types [CFuncType] cached specialized versions of the CFuncType if defined in a pxd # from_fused boolean Indicates whether this is a specialized # C function # is_strict_signature boolean function refuses to accept coerced arguments # (used for optimisation overrides) # is_const_method boolean # is_static_method boolean is_cfunction = 1 original_sig = None cached_specialized_types = None from_fused = False is_const_method = False subtypes = ['return_type', 'args'] def __init__(self, return_type, args, has_varargs = 0, exception_value = None, exception_check = 0, calling_convention = "", nogil = 0, with_gil = 0, is_overridable = 0, optional_arg_count = 0, is_const_method = False, is_static_method=False, templates = None, is_strict_signature = False): self.return_type = return_type self.args = args self.has_varargs = has_varargs self.optional_arg_count = optional_arg_count self.exception_value = exception_value self.exception_check = exception_check self.calling_convention = calling_convention self.nogil = nogil self.with_gil = with_gil self.is_overridable = is_overridable self.is_const_method = is_const_method self.is_static_method = is_static_method self.templates = templates self.is_strict_signature = is_strict_signature def __repr__(self): arg_reprs = list(map(repr, self.args)) if self.has_varargs: arg_reprs.append("...") if self.exception_value: except_clause = " %r" % self.exception_value else: except_clause = "" if self.exception_check: except_clause += "?" return "" % ( repr(self.return_type), self.calling_convention_prefix(), ",".join(arg_reprs), except_clause) def calling_convention_prefix(self): cc = self.calling_convention if cc: return cc + " " else: return "" def as_argument_type(self): return c_ptr_type(self) def same_c_signature_as(self, other_type, as_cmethod = 0): return self.same_c_signature_as_resolved_type( other_type.resolve(), as_cmethod) def same_c_signature_as_resolved_type(self, other_type, as_cmethod = 0): #print "CFuncType.same_c_signature_as_resolved_type:", \ # self, other_type, "as_cmethod =", as_cmethod ### if other_type is error_type: return 1 if not other_type.is_cfunction: return 0 if self.is_overridable != other_type.is_overridable: return 0 nargs = len(self.args) if nargs != len(other_type.args): return 0 # When comparing C method signatures, the first argument # is exempt from compatibility checking (the proper check # is performed elsewhere). for i in range(as_cmethod, nargs): if not self.args[i].type.same_as(other_type.args[i].type): return 0 if self.has_varargs != other_type.has_varargs: return 0 if self.optional_arg_count != other_type.optional_arg_count: return 0 if not self.return_type.same_as(other_type.return_type): return 0 if not self.same_calling_convention_as(other_type): return 0 if self.exception_check != other_type.exception_check: return 0 if not self._same_exception_value(other_type.exception_value): return 0 return 1 def _same_exception_value(self, other_exc_value): if self.exception_value == other_exc_value: return 1 if self.exception_check != '+': return 0 if not self.exception_value or not other_exc_value: return 0 if self.exception_value.type != other_exc_value.type: return 0 if self.exception_value.entry and other_exc_value.entry: if self.exception_value.entry.cname != other_exc_value.entry.cname: return 0 if self.exception_value.name != other_exc_value.name: return 0 return 1 def compatible_signature_with(self, other_type, as_cmethod = 0): return self.compatible_signature_with_resolved_type(other_type.resolve(), as_cmethod) def compatible_signature_with_resolved_type(self, other_type, as_cmethod): #print "CFuncType.same_c_signature_as_resolved_type:", \ # self, other_type, "as_cmethod =", as_cmethod ### if other_type is error_type: return 1 if not other_type.is_cfunction: return 0 if not self.is_overridable and other_type.is_overridable: return 0 nargs = len(self.args) if nargs - self.optional_arg_count != len(other_type.args) - other_type.optional_arg_count: return 0 if self.optional_arg_count < other_type.optional_arg_count: return 0 # When comparing C method signatures, the first argument # is exempt from compatibility checking (the proper check # is performed elsewhere). for i in range(as_cmethod, len(other_type.args)): if not self.args[i].type.same_as( other_type.args[i].type): return 0 if self.has_varargs != other_type.has_varargs: return 0 if not self.return_type.subtype_of_resolved_type(other_type.return_type): return 0 if not self.same_calling_convention_as(other_type): return 0 if self.nogil != other_type.nogil: return 0 if not self.exception_check and other_type.exception_check: # a redundant exception check doesn't make functions incompatible, but a missing one does return 0 if not self._same_exception_value(other_type.exception_value): return 0 self.original_sig = other_type.original_sig or other_type return 1 def narrower_c_signature_than(self, other_type, as_cmethod = 0): return self.narrower_c_signature_than_resolved_type(other_type.resolve(), as_cmethod) def narrower_c_signature_than_resolved_type(self, other_type, as_cmethod): if other_type is error_type: return 1 if not other_type.is_cfunction: return 0 nargs = len(self.args) if nargs != len(other_type.args): return 0 for i in range(as_cmethod, nargs): if not self.args[i].type.subtype_of_resolved_type(other_type.args[i].type): return 0 else: self.args[i].needs_type_test = other_type.args[i].needs_type_test \ or not self.args[i].type.same_as(other_type.args[i].type) if self.has_varargs != other_type.has_varargs: return 0 if self.optional_arg_count != other_type.optional_arg_count: return 0 if not self.return_type.subtype_of_resolved_type(other_type.return_type): return 0 if not self.exception_check and other_type.exception_check: # a redundant exception check doesn't make functions incompatible, but a missing one does return 0 if not self._same_exception_value(other_type.exception_value): return 0 return 1 def same_calling_convention_as(self, other): ## XXX Under discussion ... ## callspec_words = ("__stdcall", "__cdecl", "__fastcall") ## cs1 = self.calling_convention ## cs2 = other.calling_convention ## if (cs1 in callspec_words or ## cs2 in callspec_words): ## return cs1 == cs2 ## else: ## return True sc1 = self.calling_convention == '__stdcall' sc2 = other.calling_convention == '__stdcall' return sc1 == sc2 def same_as_resolved_type(self, other_type, as_cmethod = 0): return self.same_c_signature_as_resolved_type(other_type, as_cmethod) \ and self.nogil == other_type.nogil def pointer_assignable_from_resolved_type(self, other_type): return self.same_c_signature_as_resolved_type(other_type) \ and not (self.nogil and not other_type.nogil) def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0, with_calling_convention = 1): arg_decl_list = [] for arg in self.args[:len(self.args)-self.optional_arg_count]: arg_decl_list.append( arg.type.declaration_code("", for_display, pyrex = pyrex)) if self.is_overridable: arg_decl_list.append("int %s" % Naming.skip_dispatch_cname) if self.optional_arg_count: arg_decl_list.append(self.op_arg_struct.declaration_code(Naming.optional_args_cname)) if self.has_varargs: arg_decl_list.append("...") arg_decl_code = ", ".join(arg_decl_list) if not arg_decl_code and not pyrex: arg_decl_code = "void" trailer = "" if (pyrex or for_display) and not self.return_type.is_pyobject: if self.exception_value and self.exception_check: trailer = " except? %s" % self.exception_value elif self.exception_value: trailer = " except %s" % self.exception_value elif self.exception_check == '+': trailer = " except +" elif self.exception_check and for_display: # not spelled out by default, unless for human eyes trailer = " except *" if self.nogil: trailer += " nogil" if not with_calling_convention: cc = '' else: cc = self.calling_convention_prefix() if (not entity_code and cc) or entity_code.startswith("*"): entity_code = "(%s%s)" % (cc, entity_code) cc = "" if self.is_const_method: trailer += " const" return self.return_type.declaration_code( "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer), for_display, dll_linkage, pyrex) def function_header_code(self, func_name, arg_code): if self.is_const_method: trailer = " const" else: trailer = "" return "%s%s(%s)%s" % (self.calling_convention_prefix(), func_name, arg_code, trailer) def signature_string(self): s = self.empty_declaration_code() return s def signature_cast_string(self): s = self.declaration_code("(*)", with_calling_convention=False) return '(%s)' % s def specialize(self, values): result = CFuncType(self.return_type.specialize(values), [arg.specialize(values) for arg in self.args], has_varargs = self.has_varargs, exception_value = self.exception_value, exception_check = self.exception_check, calling_convention = self.calling_convention, nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.is_overridable, optional_arg_count = self.optional_arg_count, is_const_method = self.is_const_method, is_static_method = self.is_static_method, templates = self.templates) result.from_fused = self.is_fused return result def opt_arg_cname(self, arg_name): return self.op_arg_struct.base_type.scope.lookup(arg_name).cname # Methods that deal with Fused Types # All but map_with_specific_entries should be called only on functions # with fused types (and not on their corresponding specific versions). def get_all_specialized_permutations(self, fused_types=None): """ Permute all the types. For every specific instance of a fused type, we want all other specific instances of all other fused types. It returns an iterable of two-tuples of the cname that should prefix the cname of the function, and a dict mapping any fused types to their respective specific types. """ assert self.is_fused if fused_types is None: fused_types = self.get_fused_types() return get_all_specialized_permutations(fused_types) def get_all_specialized_function_types(self): """ Get all the specific function types of this one. """ assert self.is_fused if self.entry.fused_cfunction: return [n.type for n in self.entry.fused_cfunction.nodes] elif self.cached_specialized_types is not None: return self.cached_specialized_types cfunc_entries = self.entry.scope.cfunc_entries cfunc_entries.remove(self.entry) result = [] permutations = self.get_all_specialized_permutations() for cname, fused_to_specific in permutations: new_func_type = self.entry.type.specialize(fused_to_specific) if self.optional_arg_count: # Remember, this method is set by CFuncDeclaratorNode self.declare_opt_arg_struct(new_func_type, cname) new_entry = copy.deepcopy(self.entry) new_func_type.specialize_entry(new_entry, cname) new_entry.type = new_func_type new_func_type.entry = new_entry result.append(new_func_type) cfunc_entries.append(new_entry) self.cached_specialized_types = result return result def get_fused_types(self, result=None, seen=None, subtypes=None): """Return fused types in the order they appear as parameter types""" return super(CFuncType, self).get_fused_types(result, seen, subtypes=['args']) def specialize_entry(self, entry, cname): assert not self.is_fused specialize_entry(entry, cname) def can_coerce_to_pyobject(self, env): # duplicating the decisions from create_to_py_utility_code() here avoids writing out unused code if self.has_varargs or self.optional_arg_count: return False if self.to_py_function is not None: return self.to_py_function for arg in self.args: if not arg.type.is_pyobject and not arg.type.can_coerce_to_pyobject(env): return False if not self.return_type.is_pyobject and not self.return_type.can_coerce_to_pyobject(env): return False return True def create_to_py_utility_code(self, env): # FIXME: it seems we're trying to coerce in more cases than we should if self.to_py_function is not None: return self.to_py_function if not self.can_coerce_to_pyobject(env): return False from .UtilityCode import CythonUtilityCode safe_typename = re.sub('[^a-zA-Z0-9]', '__', self.declaration_code("", pyrex=1)) to_py_function = "__Pyx_CFunc_%s_to_py" % safe_typename for arg in self.args: if not arg.type.is_pyobject and not arg.type.create_from_py_utility_code(env): return False if not self.return_type.is_pyobject and not self.return_type.create_to_py_utility_code(env): return False def declared_type(ctype): type_displayname = str(ctype.declaration_code("", for_display=True)) if ctype.is_pyobject: arg_ctype = type_name = type_displayname if ctype.is_builtin_type: arg_ctype = ctype.name elif not ctype.is_extension_type: type_name = 'object' type_displayname = None else: type_displayname = repr(type_displayname) elif ctype is c_bint_type: type_name = arg_ctype = 'bint' else: type_name = arg_ctype = type_displayname if ctype is c_double_type: type_displayname = 'float' else: type_displayname = repr(type_displayname) return type_name, arg_ctype, type_displayname class Arg(object): def __init__(self, arg_name, arg_type): self.name = arg_name self.type = arg_type self.type_cname, self.ctype, self.type_displayname = declared_type(arg_type) if self.return_type.is_void: except_clause = 'except *' elif self.return_type.is_pyobject: except_clause = '' elif self.exception_value: except_clause = ('except? %s' if self.exception_check else 'except %s') % self.exception_value else: except_clause = 'except *' context = { 'cname': to_py_function, 'args': [Arg(arg.name or 'arg%s' % ix, arg.type) for ix, arg in enumerate(self.args)], 'return_type': Arg('return', self.return_type), 'except_clause': except_clause, } # FIXME: directives come from first defining environment and do not adapt for reuse env.use_utility_code(CythonUtilityCode.load( "cfunc.to_py", "CConvert.pyx", outer_module_scope=env.global_scope(), # need access to types declared in module context=context, compiler_directives=dict(env.global_scope().directives))) self.to_py_function = to_py_function return True def specialize_entry(entry, cname): """ Specialize an entry of a copied fused function or method """ entry.is_fused_specialized = True entry.name = get_fused_cname(cname, entry.name) if entry.is_cmethod: entry.cname = entry.name if entry.is_inherited: entry.cname = StringEncoding.EncodedString( "%s.%s" % (Naming.obj_base_cname, entry.cname)) else: entry.cname = get_fused_cname(cname, entry.cname) if entry.func_cname: entry.func_cname = get_fused_cname(cname, entry.func_cname) def get_fused_cname(fused_cname, orig_cname): """ Given the fused cname id and an original cname, return a specialized cname """ assert fused_cname and orig_cname return StringEncoding.EncodedString('%s%s%s' % (Naming.fused_func_prefix, fused_cname, orig_cname)) def unique(somelist): seen = set() result = [] for obj in somelist: if obj not in seen: result.append(obj) seen.add(obj) return result def get_all_specialized_permutations(fused_types): return _get_all_specialized_permutations(unique(fused_types)) def _get_all_specialized_permutations(fused_types, id="", f2s=()): fused_type, = fused_types[0].get_fused_types() result = [] for newid, specific_type in enumerate(fused_type.types): # f2s = dict(f2s, **{ fused_type: specific_type }) f2s = dict(f2s) f2s.update({ fused_type: specific_type }) if id: cname = '%s_%s' % (id, newid) else: cname = str(newid) if len(fused_types) > 1: result.extend(_get_all_specialized_permutations( fused_types[1:], cname, f2s)) else: result.append((cname, f2s)) return result def specialization_signature_string(fused_compound_type, fused_to_specific): """ Return the signature for a specialization of a fused type. e.g. floating[:] -> 'float' or 'double' cdef fused ft: float[:] double[:] ft -> 'float[:]' or 'double[:]' integral func(floating) -> 'int (*func)(float)' or ... """ fused_types = fused_compound_type.get_fused_types() if len(fused_types) == 1: fused_type = fused_types[0] else: fused_type = fused_compound_type return fused_type.specialize(fused_to_specific).typeof_name() def get_specialized_types(type): """ Return a list of specialized types in their declared order. """ assert type.is_fused if isinstance(type, FusedType): result = list(type.types) for specialized_type in result: specialized_type.specialization_string = specialized_type.typeof_name() else: result = [] for cname, f2s in get_all_specialized_permutations(type.get_fused_types()): specialized_type = type.specialize(f2s) specialized_type.specialization_string = ( specialization_signature_string(type, f2s)) result.append(specialized_type) return result class CFuncTypeArg(BaseType): # name string # cname string # type PyrexType # pos source file position # FIXME: is this the right setup? should None be allowed here? not_none = False or_none = False accept_none = True accept_builtin_subtypes = False subtypes = ['type'] def __init__(self, name, type, pos, cname=None): self.name = name if cname is not None: self.cname = cname else: self.cname = Naming.var_prefix + name self.type = type self.pos = pos self.needs_type_test = False # TODO: should these defaults be set in analyse_types()? def __repr__(self): return "%s:%s" % (self.name, repr(self.type)) def declaration_code(self, for_display = 0): return self.type.declaration_code(self.cname, for_display) def specialize(self, values): return CFuncTypeArg(self.name, self.type.specialize(values), self.pos, self.cname) class ToPyStructUtilityCode(object): requires = None def __init__(self, type, forward_decl, env): self.type = type self.header = "static PyObject* %s(%s)" % (type.to_py_function, type.declaration_code('s')) self.forward_decl = forward_decl self.env = env def __eq__(self, other): return isinstance(other, ToPyStructUtilityCode) and self.header == other.header def __hash__(self): return hash(self.header) def get_tree(self): pass def put_code(self, output): code = output['utility_code_def'] proto = output['utility_code_proto'] code.putln("%s {" % self.header) code.putln("PyObject* res;") code.putln("PyObject* member;") code.putln("res = PyDict_New(); if (res == NULL) return NULL;") for member in self.type.scope.var_entries: nameconst_cname = code.get_py_string_const(member.name, identifier=True) code.putln("%s; if (member == NULL) goto bad;" % ( member.type.to_py_call_code('s.%s' % member.cname, 'member', member.type))) code.putln("if (PyDict_SetItem(res, %s, member) < 0) goto bad;" % nameconst_cname) code.putln("Py_DECREF(member);") code.putln("return res;") code.putln("bad:") code.putln("Py_XDECREF(member);") code.putln("Py_DECREF(res);") code.putln("return NULL;") code.putln("}") # This is a bit of a hack, we need a forward declaration # due to the way things are ordered in the module... if self.forward_decl: proto.putln(self.type.empty_declaration_code() + ';') proto.putln(self.header + ";") def inject_tree_and_scope_into(self, module_node): pass class CStructOrUnionType(CType): # name string # cname string # kind string "struct" or "union" # scope StructOrUnionScope, or None if incomplete # typedef_flag boolean # packed boolean # entry Entry is_struct_or_union = 1 has_attributes = 1 exception_check = True def __init__(self, name, kind, scope, typedef_flag, cname, packed=False): self.name = name self.cname = cname self.kind = kind self.scope = scope self.typedef_flag = typedef_flag self.is_struct = kind == 'struct' self.to_py_function = "%s_to_py_%s" % (Naming.convert_func_prefix, self.cname) self.from_py_function = "%s_from_py_%s" % (Naming.convert_func_prefix, self.cname) self.exception_check = True self._convert_to_py_code = None self._convert_from_py_code = None self.packed = packed def create_to_py_utility_code(self, env): if env.outer_scope is None: return False if self._convert_to_py_code is False: return None # tri-state-ish if self._convert_to_py_code is None: is_union = not self.is_struct unsafe_union_types = set() safe_union_types = set() for member in self.scope.var_entries: member_type = member.type if not member_type.create_to_py_utility_code(env): self.to_py_function = None self._convert_to_py_code = False return False if is_union: if member_type.is_ptr or member_type.is_cpp_class: unsafe_union_types.add(member_type) else: safe_union_types.add(member_type) if unsafe_union_types and (safe_union_types or len(unsafe_union_types) > 1): # unsafe mix of safe and unsafe to convert types self.from_py_function = None self._convert_from_py_code = False return False forward_decl = self.entry.visibility != 'extern' and not self.typedef_flag self._convert_to_py_code = ToPyStructUtilityCode(self, forward_decl, env) env.use_utility_code(self._convert_to_py_code) return True def create_from_py_utility_code(self, env): if env.outer_scope is None: return False if self._convert_from_py_code is False: return None # tri-state-ish if self._convert_from_py_code is None: for member in self.scope.var_entries: if not member.type.create_from_py_utility_code(env): self.from_py_function = None self._convert_from_py_code = False return False context = dict( struct_name=self.name, var_entries=self.scope.var_entries, funcname=self.from_py_function, ) from .UtilityCode import CythonUtilityCode self._convert_from_py_code = CythonUtilityCode.load( "FromPyStructUtility" if self.is_struct else "FromPyUnionUtility", "CConvert.pyx", outer_module_scope=env.global_scope(), # need access to types declared in module context=context) env.use_utility_code(self._convert_from_py_code) return True def __repr__(self): return "" % ( self.name, self.cname, ("", " typedef")[self.typedef_flag]) def declaration_code(self, entity_code, for_display=0, dll_linkage=None, pyrex=0): if pyrex or for_display: base_code = self.name else: if self.typedef_flag: base_code = self.cname else: base_code = "%s %s" % (self.kind, self.cname) base_code = public_decl(base_code, dll_linkage) return self.base_declaration_code(base_code, entity_code) def __eq__(self, other): try: return (isinstance(other, CStructOrUnionType) and self.name == other.name) except AttributeError: return False def __lt__(self, other): try: return self.name < other.name except AttributeError: # this is arbitrary, but it makes sure we always have # *some* kind of order return False def __hash__(self): return hash(self.cname) ^ hash(self.kind) def is_complete(self): return self.scope is not None def attributes_known(self): return self.is_complete() def can_be_complex(self): # Does the struct consist of exactly two identical floats? fields = self.scope.var_entries if len(fields) != 2: return False a, b = fields return (a.type.is_float and b.type.is_float and a.type.empty_declaration_code() == b.type.empty_declaration_code()) def struct_nesting_depth(self): child_depths = [x.type.struct_nesting_depth() for x in self.scope.var_entries] return max(child_depths) + 1 def cast_code(self, expr_code): if self.is_struct: return expr_code return super(CStructOrUnionType, self).cast_code(expr_code) cpp_string_conversions = ("std::string",) builtin_cpp_conversions = ("std::pair", "std::vector", "std::list", "std::set", "std::unordered_set", "std::map", "std::unordered_map") class CppClassType(CType): # name string # cname string # scope CppClassScope # templates [string] or None is_cpp_class = 1 has_attributes = 1 exception_check = True namespace = None # For struct-like declaration. kind = "struct" packed = False typedef_flag = False subtypes = ['templates'] def __init__(self, name, scope, cname, base_classes, templates=None, template_type=None): self.name = name self.cname = cname self.scope = scope self.base_classes = base_classes self.operators = [] self.templates = templates self.template_type = template_type self.specializations = {} self.is_cpp_string = cname in cpp_string_conversions def use_conversion_utility(self, from_or_to): pass def maybe_unordered(self): if 'unordered' in self.cname: return 'unordered_' else: return '' def create_from_py_utility_code(self, env): if self.from_py_function is not None: return True if self.cname in builtin_cpp_conversions or self.cname in cpp_string_conversions: X = "XYZABC" tags = [] declarations = ["cdef extern from *:"] for ix, T in enumerate(self.templates or []): if T.is_pyobject or not T.create_from_py_utility_code(env): return False tags.append(T.specialization_name()) if T.exception_value is not None: # This is a hack due to the except value clause # requiring a const (literal) value of the right # (visible) type. def guess_type(value): if not T.is_typedef and (T.is_numeric or T.is_ptr): return T try: int(value) return c_longlong_type except ValueError: pass try: float(value) return c_double_type except ValueError: pass return T except_type = guess_type(T.exception_value) except_clause = "%s " % T.exception_value if T.exception_check: except_clause = "? %s" % except_clause declarations.append( " ctypedef %s %s '%s'" % ( except_type.declaration_code("", for_display=True), X[ix], T.empty_declaration_code())) else: except_clause = "*" declarations.append( " ctypedef struct %s '%s':\n pass" % ( X[ix], T.empty_declaration_code())) declarations.append( " cdef %s %s_from_py '%s' (object) except %s" % ( X[ix], X[ix], T.from_py_function, except_clause)) if self.cname in cpp_string_conversions: cls = 'string' tags = type_identifier(self), else: cls = self.cname[5:] cname = '__pyx_convert_%s_from_py_%s' % (cls, '__and_'.join(tags)) context = { 'template_type_declarations': '\n'.join(declarations), 'cname': cname, 'maybe_unordered': self.maybe_unordered(), 'type': self.cname, } from .UtilityCode import CythonUtilityCode env.use_utility_code(CythonUtilityCode.load( cls.replace('unordered_', '') + ".from_py", "CppConvert.pyx", context=context)) self.from_py_function = cname return True def create_to_py_utility_code(self, env): if self.to_py_function is not None: return True if self.cname in builtin_cpp_conversions or self.cname in cpp_string_conversions: X = "XYZABC" tags = [] declarations = ["cdef extern from *:"] for ix, T in enumerate(self.templates or []): if not T.create_to_py_utility_code(env): return False tags.append(T.specialization_name()) declarations.append( " ctypedef struct %s '%s':\n pass" % ( X[ix], T.empty_declaration_code())) declarations.append( " cdef object %s_to_py '%s' (%s)" % ( X[ix], T.to_py_function, X[ix])) if self.cname in cpp_string_conversions: cls = 'string' prefix = 'PyObject_' # gets specialised by explicit type casts in CoerceToPyTypeNode tags = type_identifier(self), else: cls = self.cname[5:] prefix = '' cname = "__pyx_convert_%s%s_to_py_%s" % (prefix, cls, "____".join(tags)) context = { 'template_type_declarations': '\n'.join(declarations), 'cname': cname, 'maybe_unordered': self.maybe_unordered(), 'type': self.cname, } from .UtilityCode import CythonUtilityCode env.use_utility_code(CythonUtilityCode.load( cls.replace('unordered_', '') + ".to_py", "CppConvert.pyx", context=context)) self.to_py_function = cname return True def is_template_type(self): return self.templates is not None and self.template_type is None def get_fused_types(self, result=None, seen=None): if result is None: result = [] seen = set() if self.namespace: self.namespace.get_fused_types(result, seen) if self.templates: for T in self.templates: T.get_fused_types(result, seen) return result def specialize_here(self, pos, template_values=None): if not self.is_template_type(): error(pos, "'%s' type is not a template" % self) return error_type if len(self.templates) != len(template_values): error(pos, "%s templated type receives %d arguments, got %d" % (self.name, len(self.templates), len(template_values))) return error_type has_object_template_param = False for value in template_values: if value.is_pyobject: has_object_template_param = True error(pos, "Python object type '%s' cannot be used as a template argument" % value) if has_object_template_param: return error_type return self.specialize(dict(zip(self.templates, template_values))) def specialize(self, values): if not self.templates and not self.namespace: return self if self.templates is None: self.templates = [] key = tuple(values.items()) if key in self.specializations: return self.specializations[key] template_values = [t.specialize(values) for t in self.templates] specialized = self.specializations[key] = \ CppClassType(self.name, None, self.cname, [], template_values, template_type=self) # Need to do these *after* self.specializations[key] is set # to avoid infinite recursion on circular references. specialized.base_classes = [b.specialize(values) for b in self.base_classes] if self.namespace is not None: specialized.namespace = self.namespace.specialize(values) specialized.scope = self.scope.specialize(values, specialized) return specialized def deduce_template_params(self, actual): if self == actual: return {} # TODO(robertwb): Actual type equality. elif self.empty_declaration_code() == actual.template_type.empty_declaration_code(): return reduce( merge_template_deductions, [formal_param.deduce_template_params(actual_param) for (formal_param, actual_param) in zip(self.templates, actual.templates)], {}) else: return None def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): if self.templates: template_strings = [param.declaration_code('', for_display, None, pyrex) for param in self.templates] if for_display: brackets = "[%s]" else: brackets = "<%s> " templates = brackets % ",".join(template_strings) else: templates = "" if pyrex or for_display: base_code = "%s%s" % (self.name, templates) else: base_code = "%s%s" % (self.cname, templates) if self.namespace is not None: base_code = "%s::%s" % (self.namespace.empty_declaration_code(), base_code) base_code = public_decl(base_code, dll_linkage) return self.base_declaration_code(base_code, entity_code) def is_subclass(self, other_type): if self.same_as_resolved_type(other_type): return 1 for base_class in self.base_classes: if base_class.is_subclass(other_type): return 1 return 0 def same_as_resolved_type(self, other_type): if other_type.is_cpp_class: if self == other_type: return 1 elif (self.cname == other_type.cname and self.template_type and other_type.template_type): if self.templates == other_type.templates: return 1 for t1, t2 in zip(self.templates, other_type.templates): if not t1.same_as_resolved_type(t2): return 0 return 1 return 0 def assignable_from_resolved_type(self, other_type): # TODO: handle operator=(...) here? if other_type is error_type: return True return other_type.is_cpp_class and other_type.is_subclass(self) def attributes_known(self): return self.scope is not None def find_cpp_operation_type(self, operator, operand_type=None): operands = [self] if operand_type is not None: operands.append(operand_type) # pos == None => no errors operator_entry = self.scope.lookup_operator_for_types(None, operator, operands) if not operator_entry: return None func_type = operator_entry.type if func_type.is_ptr: func_type = func_type.base_type return func_type.return_type def check_nullary_constructor(self, pos, msg="stack allocated"): constructor = self.scope.lookup(u'') if constructor is not None and best_match([], constructor.all_alternatives()) is None: error(pos, "C++ class must have a nullary constructor to be %s" % msg) class TemplatePlaceholderType(CType): def __init__(self, name): self.name = name def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): if entity_code: return self.name + " " + entity_code else: return self.name def specialize(self, values): if self in values: return values[self] else: return self def deduce_template_params(self, actual): return {self: actual} def same_as_resolved_type(self, other_type): if isinstance(other_type, TemplatePlaceholderType): return self.name == other_type.name else: return 0 def __hash__(self): return hash(self.name) def __cmp__(self, other): if isinstance(other, TemplatePlaceholderType): return cmp(self.name, other.name) else: return cmp(type(self), type(other)) def __eq__(self, other): if isinstance(other, TemplatePlaceholderType): return self.name == other.name else: return False class CEnumType(CType): # name string # cname string or None # typedef_flag boolean is_enum = 1 signed = 1 rank = -1 # Ranks below any integer type def __init__(self, name, cname, typedef_flag): self.name = name self.cname = cname self.values = [] self.typedef_flag = typedef_flag self.default_value = "(%s) 0" % self.empty_declaration_code() def __str__(self): return self.name def __repr__(self): return "" % (self.name, self.cname, ("", " typedef")[self.typedef_flag]) def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): if pyrex or for_display: base_code = self.name else: if self.typedef_flag: base_code = self.cname else: base_code = "enum %s" % self.cname base_code = public_decl(base_code, dll_linkage) return self.base_declaration_code(base_code, entity_code) def create_to_py_utility_code(self, env): self.to_py_function = "__Pyx_PyInt_From_" + self.specialization_name() env.use_utility_code(TempitaUtilityCode.load_cached( "CIntToPy", "TypeConversion.c", context={"TYPE": self.empty_declaration_code(), "TO_PY_FUNCTION": self.to_py_function})) return True def create_from_py_utility_code(self, env): self.from_py_function = "__Pyx_PyInt_As_" + self.specialization_name() env.use_utility_code(TempitaUtilityCode.load_cached( "CIntFromPy", "TypeConversion.c", context={"TYPE": self.empty_declaration_code(), "FROM_PY_FUNCTION": self.from_py_function})) return True def from_py_call_code(self, source_code, result_code, error_pos, code, from_py_function=None, error_condition=None): rhs = "%s(%s)" % ( from_py_function or self.from_py_function, source_code) return '%s = %s;%s' % ( result_code, typecast(self, c_long_type, rhs), ' %s' % code.error_goto_if(error_condition or self.error_condition(result_code), error_pos)) class CTupleType(CType): # components [PyrexType] is_ctuple = True def __init__(self, cname, components): self.cname = cname self.components = components self.size = len(components) self.to_py_function = "%s_to_py_%s" % (Naming.convert_func_prefix, self.cname) self.from_py_function = "%s_from_py_%s" % (Naming.convert_func_prefix, self.cname) self.exception_check = True self._convert_to_py_code = None self._convert_from_py_code = None def __str__(self): return "(%s)" % ", ".join(str(c) for c in self.components) def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): if pyrex or for_display: return str(self) else: return self.base_declaration_code(self.cname, entity_code) def can_coerce_to_pyobject(self, env): for component in self.components: if not component.can_coerce_to_pyobject(env): return False return True def create_to_py_utility_code(self, env): if self._convert_to_py_code is False: return None # tri-state-ish if self._convert_to_py_code is None: for component in self.components: if not component.create_to_py_utility_code(env): self.to_py_function = None self._convert_to_py_code = False return False context = dict( struct_type_decl=self.empty_declaration_code(), components=self.components, funcname=self.to_py_function, size=len(self.components) ) self._convert_to_py_code = TempitaUtilityCode.load( "ToPyCTupleUtility", "TypeConversion.c", context=context) env.use_utility_code(self._convert_to_py_code) return True def create_from_py_utility_code(self, env): if self._convert_from_py_code is False: return None # tri-state-ish if self._convert_from_py_code is None: for component in self.components: if not component.create_from_py_utility_code(env): self.from_py_function = None self._convert_from_py_code = False return False context = dict( struct_type_decl=self.empty_declaration_code(), components=self.components, funcname=self.from_py_function, size=len(self.components) ) self._convert_from_py_code = TempitaUtilityCode.load( "FromPyCTupleUtility", "TypeConversion.c", context=context) env.use_utility_code(self._convert_from_py_code) return True def c_tuple_type(components): components = tuple(components) cname = Naming.ctuple_type_prefix + type_list_identifier(components) tuple_type = CTupleType(cname, components) return tuple_type class UnspecifiedType(PyrexType): # Used as a placeholder until the type can be determined. is_unspecified = 1 def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): return "" def same_as_resolved_type(self, other_type): return False class ErrorType(PyrexType): # Used to prevent propagation of error messages. is_error = 1 exception_value = "0" exception_check = 0 to_py_function = "dummy" from_py_function = "dummy" def create_to_py_utility_code(self, env): return True def create_from_py_utility_code(self, env): return True def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): return "" def same_as_resolved_type(self, other_type): return 1 def error_condition(self, result_code): return "dummy" rank_to_type_name = ( "char", # 0 "short", # 1 "int", # 2 "long", # 3 "PY_LONG_LONG", # 4 "float", # 5 "double", # 6 "long double", # 7 ) _rank_to_type_name = list(rank_to_type_name) RANK_INT = _rank_to_type_name.index('int') RANK_LONG = _rank_to_type_name.index('long') RANK_FLOAT = _rank_to_type_name.index('float') UNSIGNED = 0 SIGNED = 2 error_type = ErrorType() unspecified_type = UnspecifiedType() py_object_type = PyObjectType() c_void_type = CVoidType() c_uchar_type = CIntType(0, UNSIGNED) c_ushort_type = CIntType(1, UNSIGNED) c_uint_type = CIntType(2, UNSIGNED) c_ulong_type = CIntType(3, UNSIGNED) c_ulonglong_type = CIntType(4, UNSIGNED) c_char_type = CIntType(0) c_short_type = CIntType(1) c_int_type = CIntType(2) c_long_type = CIntType(3) c_longlong_type = CIntType(4) c_schar_type = CIntType(0, SIGNED) c_sshort_type = CIntType(1, SIGNED) c_sint_type = CIntType(2, SIGNED) c_slong_type = CIntType(3, SIGNED) c_slonglong_type = CIntType(4, SIGNED) c_float_type = CFloatType(5, math_h_modifier='f') c_double_type = CFloatType(6) c_longdouble_type = CFloatType(7, math_h_modifier='l') c_float_complex_type = CComplexType(c_float_type) c_double_complex_type = CComplexType(c_double_type) c_longdouble_complex_type = CComplexType(c_longdouble_type) c_anon_enum_type = CAnonEnumType(-1) c_returncode_type = CReturnCodeType(RANK_INT) c_bint_type = CBIntType(RANK_INT) c_py_unicode_type = CPyUnicodeIntType(RANK_INT-0.5, UNSIGNED) c_py_ucs4_type = CPyUCS4IntType(RANK_LONG-0.5, UNSIGNED) c_py_hash_t_type = CPyHashTType(RANK_LONG+0.5, SIGNED) c_py_ssize_t_type = CPySSizeTType(RANK_LONG+0.5, SIGNED) c_ssize_t_type = CSSizeTType(RANK_LONG+0.5, SIGNED) c_size_t_type = CSizeTType(RANK_LONG+0.5, UNSIGNED) c_ptrdiff_t_type = CPtrdiffTType(RANK_LONG+0.75, SIGNED) c_null_ptr_type = CNullPtrType(c_void_type) c_void_ptr_type = CPtrType(c_void_type) c_void_ptr_ptr_type = CPtrType(c_void_ptr_type) c_char_ptr_type = CPtrType(c_char_type) c_uchar_ptr_type = CPtrType(c_uchar_type) c_char_ptr_ptr_type = CPtrType(c_char_ptr_type) c_int_ptr_type = CPtrType(c_int_type) c_py_unicode_ptr_type = CPtrType(c_py_unicode_type) c_py_ssize_t_ptr_type = CPtrType(c_py_ssize_t_type) c_ssize_t_ptr_type = CPtrType(c_ssize_t_type) c_size_t_ptr_type = CPtrType(c_size_t_type) # GIL state c_gilstate_type = CEnumType("PyGILState_STATE", "PyGILState_STATE", True) c_threadstate_type = CStructOrUnionType("PyThreadState", "struct", None, 1, "PyThreadState") c_threadstate_ptr_type = CPtrType(c_threadstate_type) # the Py_buffer type is defined in Builtin.py c_py_buffer_type = CStructOrUnionType("Py_buffer", "struct", None, 1, "Py_buffer") c_py_buffer_ptr_type = CPtrType(c_py_buffer_type) # Not sure whether the unsigned versions and 'long long' should be in there # long long requires C99 and might be slow, and would always get preferred # when specialization happens through calling and not indexing cy_integral_type = FusedType([c_short_type, c_int_type, c_long_type], name="integral") # Omitting long double as it might be slow cy_floating_type = FusedType([c_float_type, c_double_type], name="floating") cy_numeric_type = FusedType([c_short_type, c_int_type, c_long_type, c_float_type, c_double_type, c_float_complex_type, c_double_complex_type], name="numeric") # buffer-related structs c_buf_diminfo_type = CStructOrUnionType("__Pyx_Buf_DimInfo", "struct", None, 1, "__Pyx_Buf_DimInfo") c_pyx_buffer_type = CStructOrUnionType("__Pyx_Buffer", "struct", None, 1, "__Pyx_Buffer") c_pyx_buffer_ptr_type = CPtrType(c_pyx_buffer_type) c_pyx_buffer_nd_type = CStructOrUnionType("__Pyx_LocalBuf_ND", "struct", None, 1, "__Pyx_LocalBuf_ND") cython_memoryview_type = CStructOrUnionType("__pyx_memoryview_obj", "struct", None, 0, "__pyx_memoryview_obj") memoryviewslice_type = CStructOrUnionType("memoryviewslice", "struct", None, 1, "__Pyx_memviewslice") modifiers_and_name_to_type = { #(signed, longness, name) : type (0, 0, "char"): c_uchar_type, (1, 0, "char"): c_char_type, (2, 0, "char"): c_schar_type, (0, -1, "int"): c_ushort_type, (0, 0, "int"): c_uint_type, (0, 1, "int"): c_ulong_type, (0, 2, "int"): c_ulonglong_type, (1, -1, "int"): c_short_type, (1, 0, "int"): c_int_type, (1, 1, "int"): c_long_type, (1, 2, "int"): c_longlong_type, (2, -1, "int"): c_sshort_type, (2, 0, "int"): c_sint_type, (2, 1, "int"): c_slong_type, (2, 2, "int"): c_slonglong_type, (1, 0, "float"): c_float_type, (1, 0, "double"): c_double_type, (1, 1, "double"): c_longdouble_type, (1, 0, "complex"): c_double_complex_type, # C: float, Python: double => Python wins (1, 0, "floatcomplex"): c_float_complex_type, (1, 0, "doublecomplex"): c_double_complex_type, (1, 1, "doublecomplex"): c_longdouble_complex_type, # (1, 0, "void"): c_void_type, (1, 0, "bint"): c_bint_type, (0, 0, "Py_UNICODE"): c_py_unicode_type, (0, 0, "Py_UCS4"): c_py_ucs4_type, (2, 0, "Py_hash_t"): c_py_hash_t_type, (2, 0, "Py_ssize_t"): c_py_ssize_t_type, (2, 0, "ssize_t") : c_ssize_t_type, (0, 0, "size_t") : c_size_t_type, (2, 0, "ptrdiff_t") : c_ptrdiff_t_type, (1, 0, "object"): py_object_type, } def is_promotion(src_type, dst_type): # It's hard to find a hard definition of promotion, but empirical # evidence suggests that the below is all that's allowed. if src_type.is_numeric: if dst_type.same_as(c_int_type): unsigned = (not src_type.signed) return (src_type.is_enum or (src_type.is_int and unsigned + src_type.rank < dst_type.rank)) elif dst_type.same_as(c_double_type): return src_type.is_float and src_type.rank <= dst_type.rank return False def best_match(args, functions, pos=None, env=None): """ Given a list args of arguments and a list of functions, choose one to call which seems to be the "best" fit for this list of arguments. This function is used, e.g., when deciding which overloaded method to dispatch for C++ classes. We first eliminate functions based on arity, and if only one function has the correct arity, we return it. Otherwise, we weight functions based on how much work must be done to convert the arguments, with the following priorities: * identical types or pointers to identical types * promotions * non-Python types That is, we prefer functions where no arguments need converted, and failing that, functions where only promotions are required, and so on. If no function is deemed a good fit, or if two or more functions have the same weight, we return None (as there is no best match). If pos is not None, we also generate an error. """ # TODO: args should be a list of types, not a list of Nodes. actual_nargs = len(args) candidates = [] errors = [] for func in functions: error_mesg = "" func_type = func.type if func_type.is_ptr: func_type = func_type.base_type # Check function type if not func_type.is_cfunction: if not func_type.is_error and pos is not None: error_mesg = "Calling non-function type '%s'" % func_type errors.append((func, error_mesg)) continue # Check no. of args max_nargs = len(func_type.args) min_nargs = max_nargs - func_type.optional_arg_count if actual_nargs < min_nargs or \ (not func_type.has_varargs and actual_nargs > max_nargs): if max_nargs == min_nargs and not func_type.has_varargs: expectation = max_nargs elif actual_nargs < min_nargs: expectation = "at least %s" % min_nargs else: expectation = "at most %s" % max_nargs error_mesg = "Call with wrong number of arguments (expected %s, got %s)" \ % (expectation, actual_nargs) errors.append((func, error_mesg)) continue if func_type.templates: arg_types = [arg.type for arg in args] deductions = reduce( merge_template_deductions, [pattern.type.deduce_template_params(actual) for (pattern, actual) in zip(func_type.args, arg_types)], {}) if deductions is None: errors.append((func, "Unable to deduce type parameters")) elif len(deductions) < len(func_type.templates): errors.append((func, "Unable to deduce type parameter %s" % ( ", ".join([param.name for param in set(func_type.templates) - set(deductions.keys())])))) else: type_list = [deductions[param] for param in func_type.templates] from .Symtab import Entry specialization = Entry( name = func.name + "[%s]" % ",".join([str(t) for t in type_list]), cname = func.cname + "<%s>" % ",".join([t.empty_declaration_code() for t in type_list]), type = func_type.specialize(deductions), pos = func.pos) candidates.append((specialization, specialization.type)) else: candidates.append((func, func_type)) # Optimize the most common case of no overloading... if len(candidates) == 1: return candidates[0][0] elif len(candidates) == 0: if pos is not None: func, errmsg = errors[0] if len(errors) == 1 or [1 for func, e in errors if e == errmsg]: error(pos, errmsg) else: error(pos, "no suitable method found") return None possibilities = [] bad_types = [] needed_coercions = {} for index, (func, func_type) in enumerate(candidates): score = [0,0,0,0] for i in range(min(len(args), len(func_type.args))): src_type = args[i].type dst_type = func_type.args[i].type assignable = dst_type.assignable_from(src_type) # Now take care of normal string literals. So when you call a cdef # function that takes a char *, the coercion will mean that the # type will simply become bytes. We need to do this coercion # manually for overloaded and fused functions if not assignable and src_type.is_pyobject: if (src_type.is_builtin_type and src_type.name == 'str' and dst_type.resolve() is c_char_ptr_type): c_src_type = c_char_ptr_type else: c_src_type = src_type.default_coerced_ctype() if c_src_type: assignable = dst_type.assignable_from(c_src_type) if assignable: src_type = c_src_type needed_coercions[func] = (i, dst_type) if assignable: if src_type == dst_type or dst_type.same_as(src_type): pass # score 0 elif func_type.is_strict_signature: break # exact match requested but not found elif is_promotion(src_type, dst_type): score[2] += 1 elif ((src_type.is_int and dst_type.is_int) or (src_type.is_float and dst_type.is_float)): score[2] += abs(dst_type.rank + (not dst_type.signed) - (src_type.rank + (not src_type.signed))) + 1 elif not src_type.is_pyobject: score[1] += 1 else: score[0] += 1 else: error_mesg = "Invalid conversion from '%s' to '%s'" % (src_type, dst_type) bad_types.append((func, error_mesg)) break else: possibilities.append((score, index, func)) # so we can sort it if possibilities: possibilities.sort() if len(possibilities) > 1: score1 = possibilities[0][0] score2 = possibilities[1][0] if score1 == score2: if pos is not None: error(pos, "ambiguous overloaded method") return None function = possibilities[0][-1] if function in needed_coercions and env: arg_i, coerce_to_type = needed_coercions[function] args[arg_i] = args[arg_i].coerce_to(coerce_to_type, env) return function if pos is not None: if len(bad_types) == 1: error(pos, bad_types[0][1]) else: error(pos, "no suitable method found") return None def merge_template_deductions(a, b): if a is None or b is None: return None all = a for param, value in b.items(): if param in all: if a[param] != b[param]: return None else: all[param] = value return all def widest_numeric_type(type1, type2): """Given two numeric types, return the narrowest type encompassing both of them. """ if type1 == type2: widest_type = type1 elif type1.is_complex or type2.is_complex: def real_type(ntype): if ntype.is_complex: return ntype.real_type return ntype widest_type = CComplexType( widest_numeric_type( real_type(type1), real_type(type2))) elif type1.is_enum and type2.is_enum: widest_type = c_int_type elif type1.rank < type2.rank: widest_type = type2 elif type1.rank > type2.rank: widest_type = type1 elif type1.signed < type2.signed: widest_type = type1 elif type1.signed > type2.signed: widest_type = type2 elif type1.is_typedef > type2.is_typedef: widest_type = type1 else: widest_type = type2 return widest_type def numeric_type_fits(small_type, large_type): return widest_numeric_type(small_type, large_type) == large_type def independent_spanning_type(type1, type2): # Return a type assignable independently from both type1 and # type2, but do not require any interoperability between the two. # For example, in "True * 2", it is safe to assume an integer # result type (so spanning_type() will do the right thing), # whereas "x = True or 2" must evaluate to a type that can hold # both a boolean value and an integer, so this function works # better. if type1.is_reference ^ type2.is_reference: if type1.is_reference: type1 = type1.ref_base_type else: type2 = type2.ref_base_type if type1 == type2: return type1 elif (type1 is c_bint_type or type2 is c_bint_type) and (type1.is_numeric and type2.is_numeric): # special case: if one of the results is a bint and the other # is another C integer, we must prevent returning a numeric # type so that we do not lose the ability to coerce to a # Python bool if we have to. return py_object_type span_type = _spanning_type(type1, type2) if span_type is None: return error_type return span_type def spanning_type(type1, type2): # Return a type assignable from both type1 and type2, or # py_object_type if no better type is found. Assumes that the # code that calls this will try a coercion afterwards, which will # fail if the types cannot actually coerce to a py_object_type. if type1 == type2: return type1 elif type1 is py_object_type or type2 is py_object_type: return py_object_type elif type1 is c_py_unicode_type or type2 is c_py_unicode_type: # Py_UNICODE behaves more like a string than an int return py_object_type span_type = _spanning_type(type1, type2) if span_type is None: return py_object_type return span_type def _spanning_type(type1, type2): if type1.is_numeric and type2.is_numeric: return widest_numeric_type(type1, type2) elif type1.is_builtin_type and type1.name == 'float' and type2.is_numeric: return widest_numeric_type(c_double_type, type2) elif type2.is_builtin_type and type2.name == 'float' and type1.is_numeric: return widest_numeric_type(type1, c_double_type) elif type1.is_extension_type and type2.is_extension_type: return widest_extension_type(type1, type2) elif type1.is_pyobject or type2.is_pyobject: return py_object_type elif type1.assignable_from(type2): if type1.is_extension_type and type1.typeobj_is_imported(): # external types are unsafe, so we use PyObject instead return py_object_type return type1 elif type2.assignable_from(type1): if type2.is_extension_type and type2.typeobj_is_imported(): # external types are unsafe, so we use PyObject instead return py_object_type return type2 elif type1.is_ptr and type2.is_ptr: # incompatible pointers, void* will do as a result return c_void_ptr_type else: return None def widest_extension_type(type1, type2): if type1.typeobj_is_imported() or type2.typeobj_is_imported(): return py_object_type while True: if type1.subtype_of(type2): return type2 elif type2.subtype_of(type1): return type1 type1, type2 = type1.base_type, type2.base_type if type1 is None or type2 is None: return py_object_type def simple_c_type(signed, longness, name): # Find type descriptor for simple type given name and modifiers. # Returns None if arguments don't make sense. return modifiers_and_name_to_type.get((signed, longness, name)) def parse_basic_type(name): base = None if name.startswith('p_'): base = parse_basic_type(name[2:]) elif name.startswith('p'): base = parse_basic_type(name[1:]) elif name.endswith('*'): base = parse_basic_type(name[:-1]) if base: return CPtrType(base) # basic_type = simple_c_type(1, 0, name) if basic_type: return basic_type # signed = 1 longness = 0 if name == 'Py_UNICODE': signed = 0 elif name == 'Py_UCS4': signed = 0 elif name == 'Py_hash_t': signed = 2 elif name == 'Py_ssize_t': signed = 2 elif name == 'ssize_t': signed = 2 elif name == 'size_t': signed = 0 else: if name.startswith('u'): name = name[1:] signed = 0 elif (name.startswith('s') and not name.startswith('short')): name = name[1:] signed = 2 longness = 0 while name.startswith('short'): name = name.replace('short', '', 1).strip() longness -= 1 while name.startswith('long'): name = name.replace('long', '', 1).strip() longness += 1 if longness != 0 and not name: name = 'int' return simple_c_type(signed, longness, name) def c_array_type(base_type, size): # Construct a C array type. if base_type is error_type: return error_type else: return CArrayType(base_type, size) def c_ptr_type(base_type): # Construct a C pointer type. if base_type is error_type: return error_type elif base_type.is_reference: return CPtrType(base_type.ref_base_type) else: return CPtrType(base_type) def c_ref_type(base_type): # Construct a C reference type if base_type is error_type: return error_type else: return CReferenceType(base_type) def c_const_type(base_type): # Construct a C const type. if base_type is error_type: return error_type else: return CConstType(base_type) def same_type(type1, type2): return type1.same_as(type2) def assignable_from(type1, type2): return type1.assignable_from(type2) def typecast(to_type, from_type, expr_code): # Return expr_code cast to a C type which can be # assigned to to_type, assuming its existing C type # is from_type. if (to_type is from_type or (not to_type.is_pyobject and assignable_from(to_type, from_type))): return expr_code elif (to_type is py_object_type and from_type and from_type.is_builtin_type and from_type.name != 'type'): # no cast needed, builtins are PyObject* already return expr_code else: #print "typecast: to", to_type, "from", from_type ### return to_type.cast_code(expr_code) def type_list_identifier(types): return cap_length('__and_'.join(type_identifier(type) for type in types)) _type_identifier_cache = {} def type_identifier(type): decl = type.empty_declaration_code() safe = _type_identifier_cache.get(decl) if safe is None: safe = decl safe = re.sub(' +', ' ', safe) safe = re.sub(' ([^a-zA-Z0-9_])', r'\1', safe) safe = re.sub('([^a-zA-Z0-9_]) ', r'\1', safe) safe = (safe.replace('__', '__dunder') .replace('const ', '__const_') .replace(' ', '__space_') .replace('*', '__ptr') .replace('&', '__ref') .replace('[', '__lArr') .replace(']', '__rArr') .replace('<', '__lAng') .replace('>', '__rAng') .replace('(', '__lParen') .replace(')', '__rParen') .replace(',', '__comma_') .replace('::', '__in_')) safe = cap_length(re.sub('[^a-zA-Z0-9_]', lambda x: '__%X' % ord(x.group(0)), safe)) _type_identifier_cache[decl] = safe return safe def cap_length(s, max_prefix=63, max_len=1024): if len(s) <= max_prefix: return s else: return '%x__%s__etc' % (abs(hash(s)) % (1<<20), s[:max_len-17]) Cython-0.23.4/Cython/Compiler/Pipeline.py0000644000175600017570000003151112606202452021342 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import import itertools from time import time from . import Errors from . import DebugFlags from . import Options from .Visitor import CythonTransform from .Errors import CompileError, InternalError, AbortError from . import Naming # # Really small pipeline stages # def dumptree(t): # For quick debugging in pipelines print(t.dump()) return t def abort_on_errors(node): # Stop the pipeline if there are any errors. if Errors.num_errors != 0: raise AbortError("pipeline break") return node def parse_stage_factory(context): def parse(compsrc): source_desc = compsrc.source_desc full_module_name = compsrc.full_module_name initial_pos = (source_desc, 1, 0) saved_cimport_from_pyx, Options.cimport_from_pyx = Options.cimport_from_pyx, False scope = context.find_module(full_module_name, pos = initial_pos, need_pxd = 0) Options.cimport_from_pyx = saved_cimport_from_pyx tree = context.parse(source_desc, scope, pxd = 0, full_module_name = full_module_name) tree.compilation_source = compsrc tree.scope = scope tree.is_pxd = False return tree return parse def parse_pxd_stage_factory(context, scope, module_name): def parse(source_desc): tree = context.parse(source_desc, scope, pxd=True, full_module_name=module_name) tree.scope = scope tree.is_pxd = True return tree return parse def generate_pyx_code_stage_factory(options, result): def generate_pyx_code_stage(module_node): module_node.process_implementation(options, result) result.compilation_source = module_node.compilation_source return result return generate_pyx_code_stage def inject_pxd_code_stage_factory(context): def inject_pxd_code_stage(module_node): for name, (statlistnode, scope) in context.pxds.items(): module_node.merge_in(statlistnode, scope) return module_node return inject_pxd_code_stage def use_utility_code_definitions(scope, target, seen=None): if seen is None: seen = set() for entry in scope.entries.values(): if entry in seen: continue seen.add(entry) if entry.used and entry.utility_code_definition: target.use_utility_code(entry.utility_code_definition) for required_utility in entry.utility_code_definition.requires: target.use_utility_code(required_utility) elif entry.as_module: use_utility_code_definitions(entry.as_module, target, seen) def inject_utility_code_stage_factory(context): def inject_utility_code_stage(module_node): module_node.prepare_utility_code() use_utility_code_definitions(context.cython_scope, module_node.scope) added = [] # Note: the list might be extended inside the loop (if some utility code # pulls in other utility code, explicitly or implicitly) for utilcode in module_node.scope.utility_code_list: if utilcode in added: continue added.append(utilcode) if utilcode.requires: for dep in utilcode.requires: if not dep in added and not dep in module_node.scope.utility_code_list: module_node.scope.utility_code_list.append(dep) tree = utilcode.get_tree() if tree: module_node.merge_in(tree.body, tree.scope, merge_scope=True) return module_node return inject_utility_code_stage class UseUtilityCodeDefinitions(CythonTransform): # Temporary hack to use any utility code in nodes' "utility_code_definitions". # This should be moved to the code generation phase of the relevant nodes once # it is safe to generate CythonUtilityCode at code generation time. def __call__(self, node): self.scope = node.scope return super(UseUtilityCodeDefinitions, self).__call__(node) def process_entry(self, entry): if entry: for utility_code in (entry.utility_code, entry.utility_code_definition): if utility_code: self.scope.use_utility_code(utility_code) def visit_AttributeNode(self, node): self.process_entry(node.entry) return node def visit_NameNode(self, node): self.process_entry(node.entry) self.process_entry(node.type_entry) return node # # Pipeline factories # def create_pipeline(context, mode, exclude_classes=()): assert mode in ('pyx', 'py', 'pxd') from .Visitor import PrintTree from .ParseTreeTransforms import WithTransform, NormalizeTree, PostParse, PxdPostParse from .ParseTreeTransforms import ForwardDeclareTypes, AnalyseDeclarationsTransform from .ParseTreeTransforms import AnalyseExpressionsTransform, FindInvalidUseOfFusedTypes from .ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform from .ParseTreeTransforms import InterpretCompilerDirectives, TransformBuiltinMethods from .ParseTreeTransforms import ExpandInplaceOperators, ParallelRangeTransform from .ParseTreeTransforms import CalculateQualifiedNamesTransform from .TypeInference import MarkParallelAssignments, MarkOverflowingArithmetic from .ParseTreeTransforms import AdjustDefByDirectives, AlignFunctionDefinitions from .ParseTreeTransforms import RemoveUnreachableCode, GilCheck from .FlowControl import ControlFlowAnalysis from .AnalysedTreeTransforms import AutoTestDictTransform from .AutoDocTransforms import EmbedSignature from .Optimize import FlattenInListTransform, SwitchTransform, IterationTransform from .Optimize import EarlyReplaceBuiltinCalls, OptimizeBuiltinCalls from .Optimize import InlineDefNodeCalls from .Optimize import ConstantFolding, FinalOptimizePhase from .Optimize import DropRefcountingTransform from .Optimize import ConsolidateOverflowCheck from .Buffer import IntroduceBufferAuxiliaryVars from .ModuleNode import check_c_declarations, check_c_declarations_pxd if mode == 'pxd': _check_c_declarations = check_c_declarations_pxd _specific_post_parse = PxdPostParse(context) else: _check_c_declarations = check_c_declarations _specific_post_parse = None if mode == 'py': _align_function_definitions = AlignFunctionDefinitions(context) else: _align_function_definitions = None # NOTE: This is the "common" parts of the pipeline, which is also # code in pxd files. So it will be run multiple times in a # compilation stage. stages = [ NormalizeTree(context), PostParse(context), _specific_post_parse, InterpretCompilerDirectives(context, context.compiler_directives), ParallelRangeTransform(context), AdjustDefByDirectives(context), WithTransform(context), MarkClosureVisitor(context), _align_function_definitions, RemoveUnreachableCode(context), ConstantFolding(), FlattenInListTransform(), DecoratorTransform(context), ForwardDeclareTypes(context), AnalyseDeclarationsTransform(context), AutoTestDictTransform(context), EmbedSignature(context), EarlyReplaceBuiltinCalls(context), ## Necessary? TransformBuiltinMethods(context), MarkParallelAssignments(context), ControlFlowAnalysis(context), RemoveUnreachableCode(context), # MarkParallelAssignments(context), MarkOverflowingArithmetic(context), IntroduceBufferAuxiliaryVars(context), _check_c_declarations, InlineDefNodeCalls(context), AnalyseExpressionsTransform(context), FindInvalidUseOfFusedTypes(context), ExpandInplaceOperators(context), IterationTransform(context), SwitchTransform(context), OptimizeBuiltinCalls(context), ## Necessary? CreateClosureClasses(context), ## After all lookups and type inference CalculateQualifiedNamesTransform(context), ConsolidateOverflowCheck(context), DropRefcountingTransform(), FinalOptimizePhase(context), GilCheck(), UseUtilityCodeDefinitions(context), ] filtered_stages = [] for s in stages: if s.__class__ not in exclude_classes: filtered_stages.append(s) return filtered_stages def create_pyx_pipeline(context, options, result, py=False, exclude_classes=()): if py: mode = 'py' else: mode = 'pyx' test_support = [] if options.evaluate_tree_assertions: from ..TestUtils import TreeAssertVisitor test_support.append(TreeAssertVisitor()) if options.gdb_debug: from ..Debugger import DebugWriter # requires Py2.5+ from .ParseTreeTransforms import DebugTransform context.gdb_debug_outputwriter = DebugWriter.CythonDebugWriter( options.output_dir) debug_transform = [DebugTransform(context, options, result)] else: debug_transform = [] return list(itertools.chain( [parse_stage_factory(context)], create_pipeline(context, mode, exclude_classes=exclude_classes), test_support, [inject_pxd_code_stage_factory(context), inject_utility_code_stage_factory(context), abort_on_errors], debug_transform, [generate_pyx_code_stage_factory(options, result)])) def create_pxd_pipeline(context, scope, module_name): from .CodeGeneration import ExtractPxdCode # The pxd pipeline ends up with a CCodeWriter containing the # code of the pxd, as well as a pxd scope. return [ parse_pxd_stage_factory(context, scope, module_name) ] + create_pipeline(context, 'pxd') + [ ExtractPxdCode() ] def create_py_pipeline(context, options, result): return create_pyx_pipeline(context, options, result, py=True) def create_pyx_as_pxd_pipeline(context, result): from .ParseTreeTransforms import AlignFunctionDefinitions, \ MarkClosureVisitor, WithTransform, AnalyseDeclarationsTransform from .Optimize import ConstantFolding, FlattenInListTransform from .Nodes import StatListNode pipeline = [] pyx_pipeline = create_pyx_pipeline(context, context.options, result, exclude_classes=[ AlignFunctionDefinitions, MarkClosureVisitor, ConstantFolding, FlattenInListTransform, WithTransform ]) for stage in pyx_pipeline: pipeline.append(stage) if isinstance(stage, AnalyseDeclarationsTransform): # This is the last stage we need. break def fake_pxd(root): for entry in root.scope.entries.values(): if not entry.in_cinclude: entry.defined_in_pxd = 1 if entry.name == entry.cname and entry.visibility != 'extern': # Always mangle non-extern cimported entries. entry.cname = entry.scope.mangle(Naming.func_prefix, entry.name) return StatListNode(root.pos, stats=[]), root.scope pipeline.append(fake_pxd) return pipeline def insert_into_pipeline(pipeline, transform, before=None, after=None): """ Insert a new transform into the pipeline after or before an instance of the given class. e.g. pipeline = insert_into_pipeline(pipeline, transform, after=AnalyseDeclarationsTransform) """ assert before or after cls = before or after for i, t in enumerate(pipeline): if isinstance(t, cls): break if after: i += 1 return pipeline[:i] + [transform] + pipeline[i:] # # Running a pipeline # def run_pipeline(pipeline, source, printtree=True): from .Visitor import PrintTree error = None data = source try: try: for phase in pipeline: if phase is not None: if DebugFlags.debug_verbose_pipeline: t = time() print("Entering pipeline phase %r" % phase) if not printtree and isinstance(phase, PrintTree): continue data = phase(data) if DebugFlags.debug_verbose_pipeline: print(" %.3f seconds" % (time() - t)) except CompileError as err: # err is set Errors.report_error(err) error = err except InternalError as err: # Only raise if there was not an earlier error if Errors.num_errors == 0: raise error = err except AbortError as err: error = err return (error, data) Cython-0.23.4/Cython/Compiler/Parsing.py0000644000175600017570000033760112606202452021211 0ustar jenkinsjenkins00000000000000# cython: auto_cpdef=True, infer_types=True, language_level=3, py2_import=True # # Parser # from __future__ import absolute_import # This should be done automatically import cython cython.declare(Nodes=object, ExprNodes=object, EncodedString=object, bytes_literal=object, StringEncoding=object, FileSourceDescriptor=object, lookup_unicodechar=object, Future=object, Options=object, error=object, warning=object, Builtin=object, ModuleNode=object, Utils=object, re=object, _unicode=object, _bytes=object, partial=object, reduce=object, _IS_PY3=cython.bint) import re import sys from unicodedata import lookup as lookup_unicodechar from functools import partial, reduce from .Scanning import PyrexScanner, FileSourceDescriptor from . import Nodes from . import ExprNodes from . import Builtin from . import StringEncoding from .StringEncoding import EncodedString, bytes_literal, _unicode, _bytes from .ModuleNode import ModuleNode from .Errors import error, warning from .. import Utils from . import Future from . import Options _IS_PY3 = sys.version_info[0] >= 3 class Ctx(object): # Parsing context level = 'other' visibility = 'private' cdef_flag = 0 typedef_flag = 0 api = 0 overridable = 0 nogil = 0 namespace = None templates = None allow_struct_enum_decorator = False def __init__(self, **kwds): self.__dict__.update(kwds) def __call__(self, **kwds): ctx = Ctx() d = ctx.__dict__ d.update(self.__dict__) d.update(kwds) return ctx def p_ident(s, message="Expected an identifier"): if s.sy == 'IDENT': name = s.systring s.next() return name else: s.error(message) def p_ident_list(s): names = [] while s.sy == 'IDENT': names.append(s.systring) s.next() if s.sy != ',': break s.next() return names #------------------------------------------ # # Expressions # #------------------------------------------ def p_binop_operator(s): pos = s.position() op = s.sy s.next() return op, pos def p_binop_expr(s, ops, p_sub_expr): n1 = p_sub_expr(s) while s.sy in ops: op, pos = p_binop_operator(s) n2 = p_sub_expr(s) n1 = ExprNodes.binop_node(pos, op, n1, n2) if op == '/': if Future.division in s.context.future_directives: n1.truedivision = True else: n1.truedivision = None # unknown return n1 #lambdef: 'lambda' [varargslist] ':' test def p_lambdef(s, allow_conditional=True): # s.sy == 'lambda' pos = s.position() s.next() if s.sy == ':': args = [] star_arg = starstar_arg = None else: args, star_arg, starstar_arg = p_varargslist( s, terminator=':', annotated=False) s.expect(':') if allow_conditional: expr = p_test(s) else: expr = p_test_nocond(s) return ExprNodes.LambdaNode( pos, args = args, star_arg = star_arg, starstar_arg = starstar_arg, result_expr = expr) #lambdef_nocond: 'lambda' [varargslist] ':' test_nocond def p_lambdef_nocond(s): return p_lambdef(s, allow_conditional=False) #test: or_test ['if' or_test 'else' test] | lambdef def p_test(s): if s.sy == 'lambda': return p_lambdef(s) pos = s.position() expr = p_or_test(s) if s.sy == 'if': s.next() test = p_or_test(s) s.expect('else') other = p_test(s) return ExprNodes.CondExprNode(pos, test=test, true_val=expr, false_val=other) else: return expr #test_nocond: or_test | lambdef_nocond def p_test_nocond(s): if s.sy == 'lambda': return p_lambdef_nocond(s) else: return p_or_test(s) #or_test: and_test ('or' and_test)* def p_or_test(s): return p_rassoc_binop_expr(s, ('or',), p_and_test) def p_rassoc_binop_expr(s, ops, p_subexpr): n1 = p_subexpr(s) if s.sy in ops: pos = s.position() op = s.sy s.next() n2 = p_rassoc_binop_expr(s, ops, p_subexpr) n1 = ExprNodes.binop_node(pos, op, n1, n2) return n1 #and_test: not_test ('and' not_test)* def p_and_test(s): #return p_binop_expr(s, ('and',), p_not_test) return p_rassoc_binop_expr(s, ('and',), p_not_test) #not_test: 'not' not_test | comparison def p_not_test(s): if s.sy == 'not': pos = s.position() s.next() return ExprNodes.NotNode(pos, operand = p_not_test(s)) else: return p_comparison(s) #comparison: expr (comp_op expr)* #comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' def p_comparison(s): n1 = p_starred_expr(s) if s.sy in comparison_ops: pos = s.position() op = p_cmp_op(s) n2 = p_starred_expr(s) n1 = ExprNodes.PrimaryCmpNode(pos, operator = op, operand1 = n1, operand2 = n2) if s.sy in comparison_ops: n1.cascade = p_cascaded_cmp(s) return n1 def p_test_or_starred_expr(s): if s.sy == '*': return p_starred_expr(s) else: return p_test(s) def p_starred_expr(s): pos = s.position() if s.sy == '*': starred = True s.next() else: starred = False expr = p_bit_expr(s) if starred: expr = ExprNodes.StarredUnpackingNode(pos, expr) return expr def p_cascaded_cmp(s): pos = s.position() op = p_cmp_op(s) n2 = p_starred_expr(s) result = ExprNodes.CascadedCmpNode(pos, operator = op, operand2 = n2) if s.sy in comparison_ops: result.cascade = p_cascaded_cmp(s) return result def p_cmp_op(s): if s.sy == 'not': s.next() s.expect('in') op = 'not_in' elif s.sy == 'is': s.next() if s.sy == 'not': s.next() op = 'is_not' else: op = 'is' else: op = s.sy s.next() if op == '<>': op = '!=' return op comparison_ops = cython.declare(set, set([ '<', '>', '==', '>=', '<=', '<>', '!=', 'in', 'is', 'not' ])) #expr: xor_expr ('|' xor_expr)* def p_bit_expr(s): return p_binop_expr(s, ('|',), p_xor_expr) #xor_expr: and_expr ('^' and_expr)* def p_xor_expr(s): return p_binop_expr(s, ('^',), p_and_expr) #and_expr: shift_expr ('&' shift_expr)* def p_and_expr(s): return p_binop_expr(s, ('&',), p_shift_expr) #shift_expr: arith_expr (('<<'|'>>') arith_expr)* def p_shift_expr(s): return p_binop_expr(s, ('<<', '>>'), p_arith_expr) #arith_expr: term (('+'|'-') term)* def p_arith_expr(s): return p_binop_expr(s, ('+', '-'), p_term) #term: factor (('*'|'@'|'/'|'%'|'//') factor)* def p_term(s): return p_binop_expr(s, ('*', '@', '/', '%', '//'), p_factor) #factor: ('+'|'-'|'~'|'&'|typecast|sizeof) factor | power def p_factor(s): # little indirection for C-ification purposes return _p_factor(s) def _p_factor(s): sy = s.sy if sy in ('+', '-', '~'): op = s.sy pos = s.position() s.next() return ExprNodes.unop_node(pos, op, p_factor(s)) elif not s.in_python_file: if sy == '&': pos = s.position() s.next() arg = p_factor(s) return ExprNodes.AmpersandNode(pos, operand = arg) elif sy == "<": return p_typecast(s) elif sy == 'IDENT' and s.systring == "sizeof": return p_sizeof(s) return p_power(s) def p_typecast(s): # s.sy == "<" pos = s.position() s.next() base_type = p_c_base_type(s) is_memslice = isinstance(base_type, Nodes.MemoryViewSliceTypeNode) is_template = isinstance(base_type, Nodes.TemplatedTypeNode) is_const = isinstance(base_type, Nodes.CConstTypeNode) if (not is_memslice and not is_template and not is_const and base_type.name is None): s.error("Unknown type") declarator = p_c_declarator(s, empty = 1) if s.sy == '?': s.next() typecheck = 1 else: typecheck = 0 s.expect(">") operand = p_factor(s) if is_memslice: return ExprNodes.CythonArrayNode(pos, base_type_node=base_type, operand=operand) return ExprNodes.TypecastNode(pos, base_type = base_type, declarator = declarator, operand = operand, typecheck = typecheck) def p_sizeof(s): # s.sy == ident "sizeof" pos = s.position() s.next() s.expect('(') # Here we decide if we are looking at an expression or type # If it is actually a type, but parsable as an expression, # we treat it as an expression here. if looking_at_expr(s): operand = p_test(s) node = ExprNodes.SizeofVarNode(pos, operand = operand) else: base_type = p_c_base_type(s) declarator = p_c_declarator(s, empty = 1) node = ExprNodes.SizeofTypeNode(pos, base_type = base_type, declarator = declarator) s.expect(')') return node def p_yield_expression(s): # s.sy == "yield" pos = s.position() s.next() is_yield_from = False if s.sy == 'from': is_yield_from = True s.next() if s.sy != ')' and s.sy not in statement_terminators: arg = p_testlist(s) else: if is_yield_from: s.error("'yield from' requires a source argument", pos=pos, fatal=False) arg = None if is_yield_from: return ExprNodes.YieldFromExprNode(pos, arg=arg) else: return ExprNodes.YieldExprNode(pos, arg=arg) def p_yield_statement(s): # s.sy == "yield" yield_expr = p_yield_expression(s) return Nodes.ExprStatNode(yield_expr.pos, expr=yield_expr) def p_async_statement(s, ctx, decorators): # s.sy >> 'async' ... if s.sy == 'def': # 'async def' statements aren't allowed in pxd files if 'pxd' in ctx.level: s.error('def statement not allowed here') s.level = ctx.level return p_def_statement(s, decorators, is_async_def=True) elif decorators: s.error("Decorators can only be followed by functions or classes") elif s.sy == 'for': return p_for_statement(s, is_async=True) elif s.sy == 'with': s.next() return p_with_items(s, is_async=True) else: s.error("expected one of 'def', 'for', 'with' after 'async'") #power: atom_expr ('**' factor)* #atom_expr: ['await'] atom trailer* def p_power(s): if s.systring == 'new' and s.peek()[0] == 'IDENT': return p_new_expr(s) await_pos = None if s.sy == 'await': await_pos = s.position() s.next() n1 = p_atom(s) while s.sy in ('(', '[', '.'): n1 = p_trailer(s, n1) if await_pos: n1 = ExprNodes.AwaitExprNode(await_pos, arg=n1) if s.sy == '**': pos = s.position() s.next() n2 = p_factor(s) n1 = ExprNodes.binop_node(pos, '**', n1, n2) return n1 def p_new_expr(s): # s.systring == 'new'. pos = s.position() s.next() cppclass = p_c_base_type(s) return p_call(s, ExprNodes.NewExprNode(pos, cppclass = cppclass)) #trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME def p_trailer(s, node1): pos = s.position() if s.sy == '(': return p_call(s, node1) elif s.sy == '[': return p_index(s, node1) else: # s.sy == '.' s.next() name = p_ident(s) return ExprNodes.AttributeNode(pos, obj=node1, attribute=name) # arglist: argument (',' argument)* [','] # argument: [test '='] test # Really [keyword '='] test # since PEP 448: # argument: ( test [comp_for] | # test '=' test | # '**' expr | # star_expr ) def p_call_parse_args(s, allow_genexp=True): # s.sy == '(' pos = s.position() s.next() positional_args = [] keyword_args = [] starstar_seen = False last_was_tuple_unpack = False while s.sy != ')': if s.sy == '*': if starstar_seen: s.error("Non-keyword arg following keyword arg", pos=s.position()) s.next() positional_args.append(p_test(s)) last_was_tuple_unpack = True elif s.sy == '**': s.next() keyword_args.append(p_test(s)) starstar_seen = True else: arg = p_test(s) if s.sy == '=': s.next() if not arg.is_name: s.error("Expected an identifier before '='", pos=arg.pos) encoded_name = s.context.intern_ustring(arg.name) keyword = ExprNodes.IdentifierStringNode( arg.pos, value=encoded_name) arg = p_test(s) keyword_args.append((keyword, arg)) else: if keyword_args: s.error("Non-keyword arg following keyword arg", pos=arg.pos) if positional_args and not last_was_tuple_unpack: positional_args[-1].append(arg) else: positional_args.append([arg]) last_was_tuple_unpack = False if s.sy != ',': break s.next() if s.sy == 'for': if not keyword_args and not last_was_tuple_unpack: if len(positional_args) == 1 and len(positional_args[0]) == 1: positional_args = [[p_genexp(s, positional_args[0][0])]] s.expect(')') return positional_args or [[]], keyword_args def p_call_build_packed_args(pos, positional_args, keyword_args): keyword_dict = None subtuples = [ ExprNodes.TupleNode(pos, args=arg) if isinstance(arg, list) else ExprNodes.AsTupleNode(pos, arg=arg) for arg in positional_args ] # TODO: implement a faster way to join tuples than creating each one and adding them arg_tuple = reduce(partial(ExprNodes.binop_node, pos, '+'), subtuples) if keyword_args: kwargs = [] dict_items = [] for item in keyword_args: if isinstance(item, tuple): key, value = item dict_items.append(ExprNodes.DictItemNode(pos=key.pos, key=key, value=value)) elif item.is_dict_literal: # unpack "**{a:b}" directly dict_items.extend(item.key_value_pairs) else: if dict_items: kwargs.append(ExprNodes.DictNode( dict_items[0].pos, key_value_pairs=dict_items, reject_duplicates=True)) dict_items = [] kwargs.append(item) if dict_items: kwargs.append(ExprNodes.DictNode( dict_items[0].pos, key_value_pairs=dict_items, reject_duplicates=True)) if kwargs: if len(kwargs) == 1 and kwargs[0].is_dict_literal: # only simple keyword arguments found -> one dict keyword_dict = kwargs[0] else: # at least one **kwargs keyword_dict = ExprNodes.MergedDictNode(pos, keyword_args=kwargs) return arg_tuple, keyword_dict def p_call(s, function): # s.sy == '(' pos = s.position() positional_args, keyword_args = p_call_parse_args(s) if not keyword_args and len(positional_args) == 1 and isinstance(positional_args[0], list): return ExprNodes.SimpleCallNode(pos, function=function, args=positional_args[0]) else: arg_tuple, keyword_dict = p_call_build_packed_args(pos, positional_args, keyword_args) return ExprNodes.GeneralCallNode( pos, function=function, positional_args=arg_tuple, keyword_args=keyword_dict) #lambdef: 'lambda' [varargslist] ':' test #subscriptlist: subscript (',' subscript)* [','] def p_index(s, base): # s.sy == '[' pos = s.position() s.next() subscripts, is_single_value = p_subscript_list(s) if is_single_value and len(subscripts[0]) == 2: start, stop = subscripts[0] result = ExprNodes.SliceIndexNode(pos, base = base, start = start, stop = stop) else: indexes = make_slice_nodes(pos, subscripts) if is_single_value: index = indexes[0] else: index = ExprNodes.TupleNode(pos, args = indexes) result = ExprNodes.IndexNode(pos, base = base, index = index) s.expect(']') return result def p_subscript_list(s): is_single_value = True items = [p_subscript(s)] while s.sy == ',': is_single_value = False s.next() if s.sy == ']': break items.append(p_subscript(s)) return items, is_single_value #subscript: '.' '.' '.' | test | [test] ':' [test] [':' [test]] def p_subscript(s): # Parse a subscript and return a list of # 1, 2 or 3 ExprNodes, depending on how # many slice elements were encountered. pos = s.position() start = p_slice_element(s, (':',)) if s.sy != ':': return [start] s.next() stop = p_slice_element(s, (':', ',', ']')) if s.sy != ':': return [start, stop] s.next() step = p_slice_element(s, (':', ',', ']')) return [start, stop, step] def p_slice_element(s, follow_set): # Simple expression which may be missing iff # it is followed by something in follow_set. if s.sy not in follow_set: return p_test(s) else: return None def expect_ellipsis(s): s.expect('.') s.expect('.') s.expect('.') def make_slice_nodes(pos, subscripts): # Convert a list of subscripts as returned # by p_subscript_list into a list of ExprNodes, # creating SliceNodes for elements with 2 or # more components. result = [] for subscript in subscripts: if len(subscript) == 1: result.append(subscript[0]) else: result.append(make_slice_node(pos, *subscript)) return result def make_slice_node(pos, start, stop = None, step = None): if not start: start = ExprNodes.NoneNode(pos) if not stop: stop = ExprNodes.NoneNode(pos) if not step: step = ExprNodes.NoneNode(pos) return ExprNodes.SliceNode(pos, start = start, stop = stop, step = step) #atom: '(' [yield_expr|testlist_comp] ')' | '[' [listmaker] ']' | '{' [dict_or_set_maker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+ def p_atom(s): pos = s.position() sy = s.sy if sy == '(': s.next() if s.sy == ')': result = ExprNodes.TupleNode(pos, args = []) elif s.sy == 'yield': result = p_yield_expression(s) else: result = p_testlist_comp(s) s.expect(')') return result elif sy == '[': return p_list_maker(s) elif sy == '{': return p_dict_or_set_maker(s) elif sy == '`': return p_backquote_expr(s) elif sy == '.': expect_ellipsis(s) return ExprNodes.EllipsisNode(pos) elif sy == 'INT': return p_int_literal(s) elif sy == 'FLOAT': value = s.systring s.next() return ExprNodes.FloatNode(pos, value = value) elif sy == 'IMAG': value = s.systring[:-1] s.next() return ExprNodes.ImagNode(pos, value = value) elif sy == 'BEGIN_STRING': kind, bytes_value, unicode_value = p_cat_string_literal(s) if kind == 'c': return ExprNodes.CharNode(pos, value = bytes_value) elif kind == 'u': return ExprNodes.UnicodeNode(pos, value = unicode_value, bytes_value = bytes_value) elif kind == 'b': return ExprNodes.BytesNode(pos, value = bytes_value) else: return ExprNodes.StringNode(pos, value = bytes_value, unicode_value = unicode_value) elif sy == 'IDENT': name = s.systring s.next() if name == "None": return ExprNodes.NoneNode(pos) elif name == "True": return ExprNodes.BoolNode(pos, value=True) elif name == "False": return ExprNodes.BoolNode(pos, value=False) elif name == "NULL" and not s.in_python_file: return ExprNodes.NullNode(pos) else: return p_name(s, name) else: s.error("Expected an identifier or literal") def p_int_literal(s): pos = s.position() value = s.systring s.next() unsigned = "" longness = "" while value[-1] in u"UuLl": if value[-1] in u"Ll": longness += "L" else: unsigned += "U" value = value[:-1] # '3L' is ambiguous in Py2 but not in Py3. '3U' and '3LL' are # illegal in Py2 Python files. All suffixes are illegal in Py3 # Python files. is_c_literal = None if unsigned: is_c_literal = True elif longness: if longness == 'LL' or s.context.language_level >= 3: is_c_literal = True if s.in_python_file: if is_c_literal: error(pos, "illegal integer literal syntax in Python source file") is_c_literal = False return ExprNodes.IntNode(pos, is_c_literal = is_c_literal, value = value, unsigned = unsigned, longness = longness) def p_name(s, name): pos = s.position() if not s.compile_time_expr and name in s.compile_time_env: value = s.compile_time_env.lookup_here(name) node = wrap_compile_time_constant(pos, value) if node is not None: return node return ExprNodes.NameNode(pos, name=name) def wrap_compile_time_constant(pos, value): rep = repr(value) if value is None: return ExprNodes.NoneNode(pos) elif value is Ellipsis: return ExprNodes.EllipsisNode(pos) elif isinstance(value, bool): return ExprNodes.BoolNode(pos, value=value) elif isinstance(value, int): return ExprNodes.IntNode(pos, value=rep, constant_result=value) elif isinstance(value, float): return ExprNodes.FloatNode(pos, value=rep, constant_result=value) elif isinstance(value, _unicode): return ExprNodes.UnicodeNode(pos, value=EncodedString(value)) elif isinstance(value, _bytes): bvalue = bytes_literal(value, 'ascii') # actually: unknown encoding, but BytesLiteral requires one return ExprNodes.BytesNode(pos, value=bvalue, constant_result=value) elif isinstance(value, tuple): args = [wrap_compile_time_constant(pos, arg) for arg in value] if None not in args: return ExprNodes.TupleNode(pos, args=args) else: # error already reported return None elif not _IS_PY3 and isinstance(value, long): return ExprNodes.IntNode(pos, value=rep.rstrip('L'), constant_result=value) error(pos, "Invalid type for compile-time constant: %r (type %s)" % (value, value.__class__.__name__)) return None def p_cat_string_literal(s): # A sequence of one or more adjacent string literals. # Returns (kind, bytes_value, unicode_value) # where kind in ('b', 'c', 'u', '') kind, bytes_value, unicode_value = p_string_literal(s) if kind == 'c' or s.sy != 'BEGIN_STRING': return kind, bytes_value, unicode_value bstrings, ustrings = [bytes_value], [unicode_value] bytes_value = unicode_value = None while s.sy == 'BEGIN_STRING': pos = s.position() next_kind, next_bytes_value, next_unicode_value = p_string_literal(s) if next_kind == 'c': error(pos, "Cannot concatenate char literal with another string or char literal") elif next_kind != kind: error(pos, "Cannot mix string literals of different types, expected %s'', got %s''" % (kind, next_kind)) else: bstrings.append(next_bytes_value) ustrings.append(next_unicode_value) # join and rewrap the partial literals if kind in ('b', 'c', '') or kind == 'u' and None not in bstrings: # Py3 enforced unicode literals are parsed as bytes/unicode combination bytes_value = bytes_literal(StringEncoding.join_bytes(bstrings), s.source_encoding) if kind in ('u', ''): unicode_value = EncodedString( u''.join([ u for u in ustrings if u is not None ]) ) return kind, bytes_value, unicode_value def p_opt_string_literal(s, required_type='u'): if s.sy == 'BEGIN_STRING': kind, bytes_value, unicode_value = p_string_literal(s, required_type) if required_type == 'u': return unicode_value elif required_type == 'b': return bytes_value else: s.error("internal parser configuration error") else: return None def check_for_non_ascii_characters(string): for c in string: if c >= u'\x80': return True return False def p_string_literal(s, kind_override=None): # A single string or char literal. Returns (kind, bvalue, uvalue) # where kind in ('b', 'c', 'u', ''). The 'bvalue' is the source # code byte sequence of the string literal, 'uvalue' is the # decoded Unicode string. Either of the two may be None depending # on the 'kind' of string, only unprefixed strings have both # representations. # s.sy == 'BEGIN_STRING' pos = s.position() is_raw = False is_python3_source = s.context.language_level >= 3 has_non_ascii_literal_characters = False kind = s.systring[:1].lower() if kind == 'r': # Py3 allows both 'br' and 'rb' as prefix if s.systring[1:2].lower() == 'b': kind = 'b' else: kind = '' is_raw = True elif kind in 'ub': is_raw = s.systring[1:2].lower() == 'r' elif kind != 'c': kind = '' if kind == '' and kind_override is None and Future.unicode_literals in s.context.future_directives: chars = StringEncoding.StrLiteralBuilder(s.source_encoding) kind = 'u' else: if kind_override is not None and kind_override in 'ub': kind = kind_override if kind == 'u': chars = StringEncoding.UnicodeLiteralBuilder() elif kind == '': chars = StringEncoding.StrLiteralBuilder(s.source_encoding) else: chars = StringEncoding.BytesLiteralBuilder(s.source_encoding) while 1: s.next() sy = s.sy systr = s.systring #print "p_string_literal: sy =", sy, repr(s.systring) ### if sy == 'CHARS': chars.append(systr) if is_python3_source and not has_non_ascii_literal_characters and check_for_non_ascii_characters(systr): has_non_ascii_literal_characters = True elif sy == 'ESCAPE': if is_raw: chars.append(systr) if is_python3_source and not has_non_ascii_literal_characters \ and check_for_non_ascii_characters(systr): has_non_ascii_literal_characters = True else: c = systr[1] if c in u"01234567": chars.append_charval( int(systr[1:], 8) ) elif c in u"'\"\\": chars.append(c) elif c in u"abfnrtv": chars.append( StringEncoding.char_from_escape_sequence(systr)) elif c == u'\n': pass elif c == u'x': # \xXX if len(systr) == 4: chars.append_charval( int(systr[2:], 16) ) else: s.error("Invalid hex escape '%s'" % systr, fatal=False) elif c in u'NUu' and kind in ('u', ''): # \uxxxx, \Uxxxxxxxx, \N{...} chrval = -1 if c == u'N': try: chrval = ord(lookup_unicodechar(systr[3:-1])) except KeyError: s.error("Unknown Unicode character name %s" % repr(systr[3:-1]).lstrip('u')) elif len(systr) in (6,10): chrval = int(systr[2:], 16) if chrval > 1114111: # sys.maxunicode: s.error("Invalid unicode escape '%s'" % systr) chrval = -1 else: s.error("Invalid unicode escape '%s'" % systr, fatal=False) if chrval >= 0: chars.append_uescape(chrval, systr) else: chars.append(u'\\' + systr[1:]) if is_python3_source and not has_non_ascii_literal_characters \ and check_for_non_ascii_characters(systr): has_non_ascii_literal_characters = True elif sy == 'NEWLINE': chars.append(u'\n') elif sy == 'END_STRING': break elif sy == 'EOF': s.error("Unclosed string literal", pos=pos) else: s.error("Unexpected token %r:%r in string literal" % (sy, s.systring)) if kind == 'c': unicode_value = None bytes_value = chars.getchar() if len(bytes_value) != 1: error(pos, u"invalid character literal: %r" % bytes_value) else: bytes_value, unicode_value = chars.getstrings() if is_python3_source and has_non_ascii_literal_characters: # Python 3 forbids literal non-ASCII characters in byte strings if kind != 'u': s.error("bytes can only contain ASCII literal characters.", pos=pos, fatal=False) bytes_value = None s.next() return (kind, bytes_value, unicode_value) # since PEP 448: # list_display ::= "[" [listmaker] "]" # listmaker ::= (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) # comp_iter ::= comp_for | comp_if # comp_for ::= "for" expression_list "in" testlist [comp_iter] # comp_if ::= "if" test [comp_iter] def p_list_maker(s): # s.sy == '[' pos = s.position() s.next() if s.sy == ']': s.expect(']') return ExprNodes.ListNode(pos, args=[]) expr = p_test_or_starred_expr(s) if s.sy == 'for': if expr.is_starred: s.error("iterable unpacking cannot be used in comprehension") append = ExprNodes.ComprehensionAppendNode(pos, expr=expr) loop = p_comp_for(s, append) s.expect(']') return ExprNodes.ComprehensionNode( pos, loop=loop, append=append, type=Builtin.list_type, # list comprehensions leak their loop variable in Py2 has_local_scope=s.context.language_level >= 3) # (merged) list literal if s.sy == ',': s.next() exprs = p_test_or_starred_expr_list(s, expr) else: exprs = [expr] s.expect(']') return ExprNodes.ListNode(pos, args=exprs) def p_comp_iter(s, body): if s.sy == 'for': return p_comp_for(s, body) elif s.sy == 'if': return p_comp_if(s, body) else: # insert the 'append' operation into the loop return body def p_comp_for(s, body): # s.sy == 'for' pos = s.position() s.next() kw = p_for_bounds(s, allow_testlist=False) kw.update(else_clause = None, body = p_comp_iter(s, body)) return Nodes.ForStatNode(pos, **kw) def p_comp_if(s, body): # s.sy == 'if' pos = s.position() s.next() test = p_test_nocond(s) return Nodes.IfStatNode(pos, if_clauses = [Nodes.IfClauseNode(pos, condition = test, body = p_comp_iter(s, body))], else_clause = None ) # since PEP 448: #dictorsetmaker: ( ((test ':' test | '**' expr) # (comp_for | (',' (test ':' test | '**' expr))* [','])) | # ((test | star_expr) # (comp_for | (',' (test | star_expr))* [','])) ) def p_dict_or_set_maker(s): # s.sy == '{' pos = s.position() s.next() if s.sy == '}': s.next() return ExprNodes.DictNode(pos, key_value_pairs=[]) parts = [] target_type = 0 last_was_simple_item = False while True: if s.sy in ('*', '**'): # merged set/dict literal if target_type == 0: target_type = 1 if s.sy == '*' else 2 # 'stars' elif target_type != len(s.sy): s.error("unexpected %sitem found in %s literal" % ( s.sy, 'set' if target_type == 1 else 'dict')) s.next() if s.sy == '*': s.error("expected expression, found '*'") item = p_starred_expr(s) parts.append(item) last_was_simple_item = False else: item = p_test(s) if target_type == 0: target_type = 2 if s.sy == ':' else 1 # dict vs. set if target_type == 2: # dict literal s.expect(':') key = item value = p_test(s) item = ExprNodes.DictItemNode(key.pos, key=key, value=value) if last_was_simple_item: parts[-1].append(item) else: parts.append([item]) last_was_simple_item = True if s.sy == ',': s.next() if s.sy == '}': break else: break if s.sy == 'for': # dict/set comprehension if len(parts) == 1 and isinstance(parts[0], list) and len(parts[0]) == 1: item = parts[0][0] if target_type == 2: assert isinstance(item, ExprNodes.DictItemNode), type(item) comprehension_type = Builtin.dict_type append = ExprNodes.DictComprehensionAppendNode( item.pos, key_expr=item.key, value_expr=item.value) else: comprehension_type = Builtin.set_type append = ExprNodes.ComprehensionAppendNode(item.pos, expr=item) loop = p_comp_for(s, append) s.expect('}') return ExprNodes.ComprehensionNode(pos, loop=loop, append=append, type=comprehension_type) else: # syntax error, try to find a good error message if len(parts) == 1 and not isinstance(parts[0], list): s.error("iterable unpacking cannot be used in comprehension") else: # e.g. "{1,2,3 for ..." s.expect('}') return ExprNodes.DictNode(pos, key_value_pairs=[]) s.expect('}') if target_type == 1: # (merged) set literal items = [] set_items = [] for part in parts: if isinstance(part, list): set_items.extend(part) else: if set_items: items.append(ExprNodes.SetNode(set_items[0].pos, args=set_items)) set_items = [] items.append(part) if set_items: items.append(ExprNodes.SetNode(set_items[0].pos, args=set_items)) if len(items) == 1 and items[0].is_set_literal: return items[0] return ExprNodes.MergedSequenceNode(pos, args=items, type=Builtin.set_type) else: # (merged) dict literal items = [] dict_items = [] for part in parts: if isinstance(part, list): dict_items.extend(part) else: if dict_items: items.append(ExprNodes.DictNode(dict_items[0].pos, key_value_pairs=dict_items)) dict_items = [] items.append(part) if dict_items: items.append(ExprNodes.DictNode(dict_items[0].pos, key_value_pairs=dict_items)) if len(items) == 1 and items[0].is_dict_literal: return items[0] return ExprNodes.MergedDictNode(pos, keyword_args=items, reject_duplicates=False) # NOTE: no longer in Py3 :) def p_backquote_expr(s): # s.sy == '`' pos = s.position() s.next() args = [p_test(s)] while s.sy == ',': s.next() args.append(p_test(s)) s.expect('`') if len(args) == 1: arg = args[0] else: arg = ExprNodes.TupleNode(pos, args = args) return ExprNodes.BackquoteNode(pos, arg = arg) def p_simple_expr_list(s, expr=None): exprs = expr is not None and [expr] or [] while s.sy not in expr_terminators: exprs.append( p_test(s) ) if s.sy != ',': break s.next() return exprs def p_test_or_starred_expr_list(s, expr=None): exprs = expr is not None and [expr] or [] while s.sy not in expr_terminators: exprs.append(p_test_or_starred_expr(s)) if s.sy != ',': break s.next() return exprs #testlist: test (',' test)* [','] def p_testlist(s): pos = s.position() expr = p_test(s) if s.sy == ',': s.next() exprs = p_simple_expr_list(s, expr) return ExprNodes.TupleNode(pos, args = exprs) else: return expr # testlist_star_expr: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) def p_testlist_star_expr(s): pos = s.position() expr = p_test_or_starred_expr(s) if s.sy == ',': s.next() exprs = p_test_or_starred_expr_list(s, expr) return ExprNodes.TupleNode(pos, args = exprs) else: return expr # testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) def p_testlist_comp(s): pos = s.position() expr = p_test_or_starred_expr(s) if s.sy == ',': s.next() exprs = p_test_or_starred_expr_list(s, expr) return ExprNodes.TupleNode(pos, args = exprs) elif s.sy == 'for': return p_genexp(s, expr) else: return expr def p_genexp(s, expr): # s.sy == 'for' loop = p_comp_for(s, Nodes.ExprStatNode( expr.pos, expr = ExprNodes.YieldExprNode(expr.pos, arg=expr))) return ExprNodes.GeneratorExpressionNode(expr.pos, loop=loop) expr_terminators = cython.declare(set, set([ ')', ']', '}', ':', '=', 'NEWLINE'])) #------------------------------------------------------- # # Statements # #------------------------------------------------------- def p_global_statement(s): # assume s.sy == 'global' pos = s.position() s.next() names = p_ident_list(s) return Nodes.GlobalNode(pos, names = names) def p_nonlocal_statement(s): pos = s.position() s.next() names = p_ident_list(s) return Nodes.NonlocalNode(pos, names = names) def p_expression_or_assignment(s): expr_list = [p_testlist_star_expr(s)] if s.sy == '=' and expr_list[0].is_starred: # This is a common enough error to make when learning Cython to let # it fail as early as possible and give a very clear error message. s.error("a starred assignment target must be in a list or tuple" " - maybe you meant to use an index assignment: var[0] = ...", pos=expr_list[0].pos) while s.sy == '=': s.next() if s.sy == 'yield': expr = p_yield_expression(s) else: expr = p_testlist_star_expr(s) expr_list.append(expr) if len(expr_list) == 1: if re.match(r"([-+*/%^&|]|<<|>>|\*\*|//|@)=", s.sy): lhs = expr_list[0] if isinstance(lhs, ExprNodes.SliceIndexNode): # implementation requires IndexNode lhs = ExprNodes.IndexNode( lhs.pos, base=lhs.base, index=make_slice_node(lhs.pos, lhs.start, lhs.stop)) elif not isinstance(lhs, (ExprNodes.AttributeNode, ExprNodes.IndexNode, ExprNodes.NameNode)): error(lhs.pos, "Illegal operand for inplace operation.") operator = s.sy[:-1] s.next() if s.sy == 'yield': rhs = p_yield_expression(s) else: rhs = p_testlist(s) return Nodes.InPlaceAssignmentNode(lhs.pos, operator=operator, lhs=lhs, rhs=rhs) expr = expr_list[0] return Nodes.ExprStatNode(expr.pos, expr=expr) rhs = expr_list[-1] if len(expr_list) == 2: return Nodes.SingleAssignmentNode(rhs.pos, lhs=expr_list[0], rhs=rhs) else: return Nodes.CascadedAssignmentNode(rhs.pos, lhs_list=expr_list[:-1], rhs=rhs) def p_print_statement(s): # s.sy == 'print' pos = s.position() ends_with_comma = 0 s.next() if s.sy == '>>': s.next() stream = p_test(s) if s.sy == ',': s.next() ends_with_comma = s.sy in ('NEWLINE', 'EOF') else: stream = None args = [] if s.sy not in ('NEWLINE', 'EOF'): args.append(p_test(s)) while s.sy == ',': s.next() if s.sy in ('NEWLINE', 'EOF'): ends_with_comma = 1 break args.append(p_test(s)) arg_tuple = ExprNodes.TupleNode(pos, args=args) return Nodes.PrintStatNode(pos, arg_tuple=arg_tuple, stream=stream, append_newline=not ends_with_comma) def p_exec_statement(s): # s.sy == 'exec' pos = s.position() s.next() code = p_bit_expr(s) if isinstance(code, ExprNodes.TupleNode): # Py3 compatibility syntax tuple_variant = True args = code.args if len(args) not in (2, 3): s.error("expected tuple of length 2 or 3, got length %d" % len(args), pos=pos, fatal=False) args = [code] else: tuple_variant = False args = [code] if s.sy == 'in': if tuple_variant: s.error("tuple variant of exec does not support additional 'in' arguments", fatal=False) s.next() args.append(p_test(s)) if s.sy == ',': s.next() args.append(p_test(s)) return Nodes.ExecStatNode(pos, args=args) def p_del_statement(s): # s.sy == 'del' pos = s.position() s.next() # FIXME: 'exprlist' in Python args = p_simple_expr_list(s) return Nodes.DelStatNode(pos, args = args) def p_pass_statement(s, with_newline = 0): pos = s.position() s.expect('pass') if with_newline: s.expect_newline("Expected a newline", ignore_semicolon=True) return Nodes.PassStatNode(pos) def p_break_statement(s): # s.sy == 'break' pos = s.position() s.next() return Nodes.BreakStatNode(pos) def p_continue_statement(s): # s.sy == 'continue' pos = s.position() s.next() return Nodes.ContinueStatNode(pos) def p_return_statement(s): # s.sy == 'return' pos = s.position() s.next() if s.sy not in statement_terminators: value = p_testlist(s) else: value = None return Nodes.ReturnStatNode(pos, value = value) def p_raise_statement(s): # s.sy == 'raise' pos = s.position() s.next() exc_type = None exc_value = None exc_tb = None cause = None if s.sy not in statement_terminators: exc_type = p_test(s) if s.sy == ',': s.next() exc_value = p_test(s) if s.sy == ',': s.next() exc_tb = p_test(s) elif s.sy == 'from': s.next() cause = p_test(s) if exc_type or exc_value or exc_tb: return Nodes.RaiseStatNode(pos, exc_type = exc_type, exc_value = exc_value, exc_tb = exc_tb, cause = cause) else: return Nodes.ReraiseStatNode(pos) def p_import_statement(s): # s.sy in ('import', 'cimport') pos = s.position() kind = s.sy s.next() items = [p_dotted_name(s, as_allowed=1)] while s.sy == ',': s.next() items.append(p_dotted_name(s, as_allowed=1)) stats = [] is_absolute = Future.absolute_import in s.context.future_directives for pos, target_name, dotted_name, as_name in items: if kind == 'cimport': stat = Nodes.CImportStatNode( pos, module_name=dotted_name, as_name=as_name, is_absolute=is_absolute) else: if as_name and "." in dotted_name: name_list = ExprNodes.ListNode(pos, args=[ ExprNodes.IdentifierStringNode(pos, value=s.context.intern_ustring("*"))]) else: name_list = None stat = Nodes.SingleAssignmentNode( pos, lhs=ExprNodes.NameNode(pos, name=as_name or target_name), rhs=ExprNodes.ImportNode( pos, module_name=ExprNodes.IdentifierStringNode(pos, value=dotted_name), level=0 if is_absolute else None, name_list=name_list)) stats.append(stat) return Nodes.StatListNode(pos, stats=stats) def p_from_import_statement(s, first_statement = 0): # s.sy == 'from' pos = s.position() s.next() if s.sy == '.': # count relative import level level = 0 while s.sy == '.': level += 1 s.next() else: level = None if level is not None and s.sy in ('import', 'cimport'): # we are dealing with "from .. import foo, bar" dotted_name_pos, dotted_name = s.position(), s.context.intern_ustring('') else: if level is None and Future.absolute_import in s.context.future_directives: level = 0 (dotted_name_pos, _, dotted_name, _) = p_dotted_name(s, as_allowed=False) if s.sy not in ('import', 'cimport'): s.error("Expected 'import' or 'cimport'") kind = s.sy s.next() is_cimport = kind == 'cimport' is_parenthesized = False if s.sy == '*': imported_names = [(s.position(), s.context.intern_ustring("*"), None, None)] s.next() else: if s.sy == '(': is_parenthesized = True s.next() imported_names = [p_imported_name(s, is_cimport)] while s.sy == ',': s.next() if is_parenthesized and s.sy == ')': break imported_names.append(p_imported_name(s, is_cimport)) if is_parenthesized: s.expect(')') if dotted_name == '__future__': if not first_statement: s.error("from __future__ imports must occur at the beginning of the file") elif level: s.error("invalid syntax") else: for (name_pos, name, as_name, kind) in imported_names: if name == "braces": s.error("not a chance", name_pos) break try: directive = getattr(Future, name) except AttributeError: s.error("future feature %s is not defined" % name, name_pos) break s.context.future_directives.add(directive) return Nodes.PassStatNode(pos) elif kind == 'cimport': return Nodes.FromCImportStatNode( pos, module_name=dotted_name, relative_level=level, imported_names=imported_names) else: imported_name_strings = [] items = [] for (name_pos, name, as_name, kind) in imported_names: imported_name_strings.append( ExprNodes.IdentifierStringNode(name_pos, value=name)) items.append( (name, ExprNodes.NameNode(name_pos, name=as_name or name))) import_list = ExprNodes.ListNode( imported_names[0][0], args=imported_name_strings) return Nodes.FromImportStatNode(pos, module = ExprNodes.ImportNode(dotted_name_pos, module_name = ExprNodes.IdentifierStringNode(pos, value = dotted_name), level = level, name_list = import_list), items = items) imported_name_kinds = cython.declare(set, set(['class', 'struct', 'union'])) def p_imported_name(s, is_cimport): pos = s.position() kind = None if is_cimport and s.systring in imported_name_kinds: kind = s.systring s.next() name = p_ident(s) as_name = p_as_name(s) return (pos, name, as_name, kind) def p_dotted_name(s, as_allowed): pos = s.position() target_name = p_ident(s) as_name = None names = [target_name] while s.sy == '.': s.next() names.append(p_ident(s)) if as_allowed: as_name = p_as_name(s) return (pos, target_name, s.context.intern_ustring(u'.'.join(names)), as_name) def p_as_name(s): if s.sy == 'IDENT' and s.systring == 'as': s.next() return p_ident(s) else: return None def p_assert_statement(s): # s.sy == 'assert' pos = s.position() s.next() cond = p_test(s) if s.sy == ',': s.next() value = p_test(s) else: value = None return Nodes.AssertStatNode(pos, cond = cond, value = value) statement_terminators = cython.declare(set, set([';', 'NEWLINE', 'EOF'])) def p_if_statement(s): # s.sy == 'if' pos = s.position() s.next() if_clauses = [p_if_clause(s)] while s.sy == 'elif': s.next() if_clauses.append(p_if_clause(s)) else_clause = p_else_clause(s) return Nodes.IfStatNode(pos, if_clauses = if_clauses, else_clause = else_clause) def p_if_clause(s): pos = s.position() test = p_test(s) body = p_suite(s) return Nodes.IfClauseNode(pos, condition = test, body = body) def p_else_clause(s): if s.sy == 'else': s.next() return p_suite(s) else: return None def p_while_statement(s): # s.sy == 'while' pos = s.position() s.next() test = p_test(s) body = p_suite(s) else_clause = p_else_clause(s) return Nodes.WhileStatNode(pos, condition = test, body = body, else_clause = else_clause) def p_for_statement(s, is_async=False): # s.sy == 'for' pos = s.position() s.next() kw = p_for_bounds(s, allow_testlist=True, is_async=is_async) body = p_suite(s) else_clause = p_else_clause(s) kw.update(body=body, else_clause=else_clause, is_async=is_async) return Nodes.ForStatNode(pos, **kw) def p_for_bounds(s, allow_testlist=True, is_async=False): target = p_for_target(s) if s.sy == 'in': s.next() iterator = p_for_iterator(s, allow_testlist, is_async=is_async) return dict(target=target, iterator=iterator) elif not s.in_python_file and not is_async: if s.sy == 'from': s.next() bound1 = p_bit_expr(s) else: # Support shorter "for a <= x < b" syntax bound1, target = target, None rel1 = p_for_from_relation(s) name2_pos = s.position() name2 = p_ident(s) rel2_pos = s.position() rel2 = p_for_from_relation(s) bound2 = p_bit_expr(s) step = p_for_from_step(s) if target is None: target = ExprNodes.NameNode(name2_pos, name = name2) else: if not target.is_name: error(target.pos, "Target of for-from statement must be a variable name") elif name2 != target.name: error(name2_pos, "Variable name in for-from range does not match target") if rel1[0] != rel2[0]: error(rel2_pos, "Relation directions in for-from do not match") return dict(target = target, bound1 = bound1, relation1 = rel1, relation2 = rel2, bound2 = bound2, step = step, ) else: s.expect('in') return {} def p_for_from_relation(s): if s.sy in inequality_relations: op = s.sy s.next() return op else: s.error("Expected one of '<', '<=', '>' '>='") def p_for_from_step(s): if s.sy == 'IDENT' and s.systring == 'by': s.next() step = p_bit_expr(s) return step else: return None inequality_relations = cython.declare(set, set(['<', '<=', '>', '>='])) def p_target(s, terminator): pos = s.position() expr = p_starred_expr(s) if s.sy == ',': s.next() exprs = [expr] while s.sy != terminator: exprs.append(p_starred_expr(s)) if s.sy != ',': break s.next() return ExprNodes.TupleNode(pos, args = exprs) else: return expr def p_for_target(s): return p_target(s, 'in') def p_for_iterator(s, allow_testlist=True, is_async=False): pos = s.position() if allow_testlist: expr = p_testlist(s) else: expr = p_or_test(s) return (ExprNodes.AsyncIteratorNode if is_async else ExprNodes.IteratorNode)(pos, sequence=expr) def p_try_statement(s): # s.sy == 'try' pos = s.position() s.next() body = p_suite(s) except_clauses = [] else_clause = None if s.sy in ('except', 'else'): while s.sy == 'except': except_clauses.append(p_except_clause(s)) if s.sy == 'else': s.next() else_clause = p_suite(s) body = Nodes.TryExceptStatNode(pos, body = body, except_clauses = except_clauses, else_clause = else_clause) if s.sy != 'finally': return body # try-except-finally is equivalent to nested try-except/try-finally if s.sy == 'finally': s.next() finally_clause = p_suite(s) return Nodes.TryFinallyStatNode(pos, body = body, finally_clause = finally_clause) else: s.error("Expected 'except' or 'finally'") def p_except_clause(s): # s.sy == 'except' pos = s.position() s.next() exc_type = None exc_value = None is_except_as = False if s.sy != ':': exc_type = p_test(s) # normalise into list of single exception tests if isinstance(exc_type, ExprNodes.TupleNode): exc_type = exc_type.args else: exc_type = [exc_type] if s.sy == ',' or (s.sy == 'IDENT' and s.systring == 'as' and s.context.language_level == 2): s.next() exc_value = p_test(s) elif s.sy == 'IDENT' and s.systring == 'as': # Py3 syntax requires a name here s.next() pos2 = s.position() name = p_ident(s) exc_value = ExprNodes.NameNode(pos2, name = name) is_except_as = True body = p_suite(s) return Nodes.ExceptClauseNode(pos, pattern = exc_type, target = exc_value, body = body, is_except_as=is_except_as) def p_include_statement(s, ctx): pos = s.position() s.next() # 'include' unicode_include_file_name = p_string_literal(s, 'u')[2] s.expect_newline("Syntax error in include statement") if s.compile_time_eval: include_file_name = unicode_include_file_name include_file_path = s.context.find_include_file(include_file_name, pos) if include_file_path: s.included_files.append(include_file_name) with Utils.open_source_file(include_file_path) as f: source_desc = FileSourceDescriptor(include_file_path) s2 = PyrexScanner(f, source_desc, s, source_encoding=f.encoding, parse_comments=s.parse_comments) tree = p_statement_list(s2, ctx) return tree else: return None else: return Nodes.PassStatNode(pos) def p_with_statement(s): s.next() # 'with' if s.systring == 'template' and not s.in_python_file: node = p_with_template(s) else: node = p_with_items(s) return node def p_with_items(s, is_async=False): pos = s.position() if not s.in_python_file and s.sy == 'IDENT' and s.systring in ('nogil', 'gil'): if is_async: s.error("with gil/nogil cannot be async") state = s.systring s.next() if s.sy == ',': s.next() body = p_with_items(s) else: body = p_suite(s) return Nodes.GILStatNode(pos, state=state, body=body) else: manager = p_test(s) target = None if s.sy == 'IDENT' and s.systring == 'as': s.next() target = p_starred_expr(s) if s.sy == ',': s.next() body = p_with_items(s, is_async=is_async) else: body = p_suite(s) return Nodes.WithStatNode(pos, manager=manager, target=target, body=body, is_async=is_async) def p_with_template(s): pos = s.position() templates = [] s.next() s.expect('[') templates.append(s.systring) s.next() while s.systring == ',': s.next() templates.append(s.systring) s.next() s.expect(']') if s.sy == ':': s.next() s.expect_newline("Syntax error in template function declaration") s.expect_indent() body_ctx = Ctx() body_ctx.templates = templates func_or_var = p_c_func_or_var_declaration(s, pos, body_ctx) s.expect_dedent() return func_or_var else: error(pos, "Syntax error in template function declaration") def p_simple_statement(s, first_statement = 0): #print "p_simple_statement:", s.sy, s.systring ### if s.sy == 'global': node = p_global_statement(s) elif s.sy == 'nonlocal': node = p_nonlocal_statement(s) elif s.sy == 'print': node = p_print_statement(s) elif s.sy == 'exec': node = p_exec_statement(s) elif s.sy == 'del': node = p_del_statement(s) elif s.sy == 'break': node = p_break_statement(s) elif s.sy == 'continue': node = p_continue_statement(s) elif s.sy == 'return': node = p_return_statement(s) elif s.sy == 'raise': node = p_raise_statement(s) elif s.sy in ('import', 'cimport'): node = p_import_statement(s) elif s.sy == 'from': node = p_from_import_statement(s, first_statement = first_statement) elif s.sy == 'yield': node = p_yield_statement(s) elif s.sy == 'assert': node = p_assert_statement(s) elif s.sy == 'pass': node = p_pass_statement(s) else: node = p_expression_or_assignment(s) return node def p_simple_statement_list(s, ctx, first_statement = 0): # Parse a series of simple statements on one line # separated by semicolons. stat = p_simple_statement(s, first_statement = first_statement) pos = stat.pos stats = [] if not isinstance(stat, Nodes.PassStatNode): stats.append(stat) while s.sy == ';': #print "p_simple_statement_list: maybe more to follow" ### s.next() if s.sy in ('NEWLINE', 'EOF'): break stat = p_simple_statement(s, first_statement = first_statement) if isinstance(stat, Nodes.PassStatNode): continue stats.append(stat) first_statement = False if not stats: stat = Nodes.PassStatNode(pos) elif len(stats) == 1: stat = stats[0] else: stat = Nodes.StatListNode(pos, stats = stats) s.expect_newline("Syntax error in simple statement list") return stat def p_compile_time_expr(s): old = s.compile_time_expr s.compile_time_expr = 1 expr = p_testlist(s) s.compile_time_expr = old return expr def p_DEF_statement(s): pos = s.position() denv = s.compile_time_env s.next() # 'DEF' name = p_ident(s) s.expect('=') expr = p_compile_time_expr(s) value = expr.compile_time_value(denv) #print "p_DEF_statement: %s = %r" % (name, value) ### denv.declare(name, value) s.expect_newline("Expected a newline", ignore_semicolon=True) return Nodes.PassStatNode(pos) def p_IF_statement(s, ctx): pos = s.position() saved_eval = s.compile_time_eval current_eval = saved_eval denv = s.compile_time_env result = None while 1: s.next() # 'IF' or 'ELIF' expr = p_compile_time_expr(s) s.compile_time_eval = current_eval and bool(expr.compile_time_value(denv)) body = p_suite(s, ctx) if s.compile_time_eval: result = body current_eval = 0 if s.sy != 'ELIF': break if s.sy == 'ELSE': s.next() s.compile_time_eval = current_eval body = p_suite(s, ctx) if current_eval: result = body if not result: result = Nodes.PassStatNode(pos) s.compile_time_eval = saved_eval return result def p_statement(s, ctx, first_statement = 0): cdef_flag = ctx.cdef_flag decorators = None if s.sy == 'ctypedef': if ctx.level not in ('module', 'module_pxd'): s.error("ctypedef statement not allowed here") #if ctx.api: # error(s.position(), "'api' not allowed with 'ctypedef'") return p_ctypedef_statement(s, ctx) elif s.sy == 'DEF': return p_DEF_statement(s) elif s.sy == 'IF': return p_IF_statement(s, ctx) elif s.sy == '@': if ctx.level not in ('module', 'class', 'c_class', 'function', 'property', 'module_pxd', 'c_class_pxd', 'other'): s.error('decorator not allowed here') s.level = ctx.level decorators = p_decorators(s) if not ctx.allow_struct_enum_decorator and s.sy not in ('def', 'cdef', 'cpdef', 'class'): if s.sy == 'IDENT' and s.systring == 'async': pass # handled below else: s.error("Decorators can only be followed by functions or classes") elif s.sy == 'pass' and cdef_flag: # empty cdef block return p_pass_statement(s, with_newline=1) overridable = 0 if s.sy == 'cdef': cdef_flag = 1 s.next() elif s.sy == 'cpdef': cdef_flag = 1 overridable = 1 s.next() if cdef_flag: if ctx.level not in ('module', 'module_pxd', 'function', 'c_class', 'c_class_pxd'): s.error('cdef statement not allowed here') s.level = ctx.level node = p_cdef_statement(s, ctx(overridable=overridable)) if decorators is not None: tup = (Nodes.CFuncDefNode, Nodes.CVarDefNode, Nodes.CClassDefNode) if ctx.allow_struct_enum_decorator: tup += (Nodes.CStructOrUnionDefNode, Nodes.CEnumDefNode) if not isinstance(node, tup): s.error("Decorators can only be followed by functions or classes") node.decorators = decorators return node else: if ctx.api: s.error("'api' not allowed with this statement", fatal=False) elif s.sy == 'def': # def statements aren't allowed in pxd files, except # as part of a cdef class if ('pxd' in ctx.level) and (ctx.level != 'c_class_pxd'): s.error('def statement not allowed here') s.level = ctx.level return p_def_statement(s, decorators) elif s.sy == 'class': if ctx.level not in ('module', 'function', 'class', 'other'): s.error("class definition not allowed here") return p_class_statement(s, decorators) elif s.sy == 'include': if ctx.level not in ('module', 'module_pxd'): s.error("include statement not allowed here") return p_include_statement(s, ctx) elif ctx.level == 'c_class' and s.sy == 'IDENT' and s.systring == 'property': return p_property_decl(s) elif s.sy == 'pass' and ctx.level != 'property': return p_pass_statement(s, with_newline=True) else: if ctx.level in ('c_class_pxd', 'property'): node = p_ignorable_statement(s) if node is not None: return node s.error("Executable statement not allowed here") if s.sy == 'if': return p_if_statement(s) elif s.sy == 'while': return p_while_statement(s) elif s.sy == 'for': return p_for_statement(s) elif s.sy == 'try': return p_try_statement(s) elif s.sy == 'with': return p_with_statement(s) elif s.sy == 'async': s.next() return p_async_statement(s, ctx, decorators) else: if s.sy == 'IDENT' and s.systring == 'async': ident_name = s.systring # PEP 492 enables the async/await keywords when it spots "async def ..." s.next() if s.sy == 'def': return p_async_statement(s, ctx, decorators) elif decorators: s.error("Decorators can only be followed by functions or classes") s.put_back('IDENT', ident_name) # re-insert original token return p_simple_statement_list(s, ctx, first_statement=first_statement) def p_statement_list(s, ctx, first_statement = 0): # Parse a series of statements separated by newlines. pos = s.position() stats = [] while s.sy not in ('DEDENT', 'EOF'): stat = p_statement(s, ctx, first_statement = first_statement) if isinstance(stat, Nodes.PassStatNode): continue stats.append(stat) first_statement = False if not stats: return Nodes.PassStatNode(pos) elif len(stats) == 1: return stats[0] else: return Nodes.StatListNode(pos, stats = stats) def p_suite(s, ctx=Ctx()): return p_suite_with_docstring(s, ctx, with_doc_only=False)[1] def p_suite_with_docstring(s, ctx, with_doc_only=False): s.expect(':') doc = None if s.sy == 'NEWLINE': s.next() s.expect_indent() if with_doc_only: doc = p_doc_string(s) body = p_statement_list(s, ctx) s.expect_dedent() else: if ctx.api: s.error("'api' not allowed with this statement", fatal=False) if ctx.level in ('module', 'class', 'function', 'other'): body = p_simple_statement_list(s, ctx) else: body = p_pass_statement(s) s.expect_newline("Syntax error in declarations", ignore_semicolon=True) if not with_doc_only: doc, body = _extract_docstring(body) return doc, body def p_positional_and_keyword_args(s, end_sy_set, templates = None): """ Parses positional and keyword arguments. end_sy_set should contain any s.sy that terminate the argument list. Argument expansion (* and **) are not allowed. Returns: (positional_args, keyword_args) """ positional_args = [] keyword_args = [] pos_idx = 0 while s.sy not in end_sy_set: if s.sy == '*' or s.sy == '**': s.error('Argument expansion not allowed here.', fatal=False) parsed_type = False if s.sy == 'IDENT' and s.peek()[0] == '=': ident = s.systring s.next() # s.sy is '=' s.next() if looking_at_expr(s): arg = p_test(s) else: base_type = p_c_base_type(s, templates = templates) declarator = p_c_declarator(s, empty = 1) arg = Nodes.CComplexBaseTypeNode(base_type.pos, base_type = base_type, declarator = declarator) parsed_type = True keyword_node = ExprNodes.IdentifierStringNode(arg.pos, value=ident) keyword_args.append((keyword_node, arg)) was_keyword = True else: if looking_at_expr(s): arg = p_test(s) else: base_type = p_c_base_type(s, templates = templates) declarator = p_c_declarator(s, empty = 1) arg = Nodes.CComplexBaseTypeNode(base_type.pos, base_type = base_type, declarator = declarator) parsed_type = True positional_args.append(arg) pos_idx += 1 if len(keyword_args) > 0: s.error("Non-keyword arg following keyword arg", pos=arg.pos) if s.sy != ',': if s.sy not in end_sy_set: if parsed_type: s.error("Unmatched %s" % " or ".join(end_sy_set)) break s.next() return positional_args, keyword_args def p_c_base_type(s, self_flag = 0, nonempty = 0, templates = None): # If self_flag is true, this is the base type for the # self argument of a C method of an extension type. if s.sy == '(': return p_c_complex_base_type(s, templates = templates) else: return p_c_simple_base_type(s, self_flag, nonempty = nonempty, templates = templates) def p_calling_convention(s): if s.sy == 'IDENT' and s.systring in calling_convention_words: result = s.systring s.next() return result else: return "" calling_convention_words = cython.declare( set, set(["__stdcall", "__cdecl", "__fastcall"])) def p_c_complex_base_type(s, templates = None): # s.sy == '(' pos = s.position() s.next() base_type = p_c_base_type(s, templates=templates) declarator = p_c_declarator(s, empty=True) type_node = Nodes.CComplexBaseTypeNode( pos, base_type=base_type, declarator=declarator) if s.sy == ',': components = [type_node] while s.sy == ',': s.next() if s.sy == ')': break base_type = p_c_base_type(s, templates=templates) declarator = p_c_declarator(s, empty=True) components.append(Nodes.CComplexBaseTypeNode( pos, base_type=base_type, declarator=declarator)) type_node = Nodes.CTupleBaseTypeNode(pos, components = components) s.expect(')') if s.sy == '[': if is_memoryviewslice_access(s): type_node = p_memoryviewslice_access(s, type_node) else: type_node = p_buffer_or_template(s, type_node, templates) return type_node def p_c_simple_base_type(s, self_flag, nonempty, templates = None): #print "p_c_simple_base_type: self_flag =", self_flag, nonempty is_basic = 0 signed = 1 longness = 0 complex = 0 module_path = [] pos = s.position() if not s.sy == 'IDENT': error(pos, "Expected an identifier, found '%s'" % s.sy) if s.systring == 'const': s.next() base_type = p_c_base_type(s, self_flag = self_flag, nonempty = nonempty, templates = templates) return Nodes.CConstTypeNode(pos, base_type = base_type) if looking_at_base_type(s): #print "p_c_simple_base_type: looking_at_base_type at", s.position() is_basic = 1 if s.sy == 'IDENT' and s.systring in special_basic_c_types: signed, longness = special_basic_c_types[s.systring] name = s.systring s.next() else: signed, longness = p_sign_and_longness(s) if s.sy == 'IDENT' and s.systring in basic_c_type_names: name = s.systring s.next() else: name = 'int' # long [int], short [int], long [int] complex, etc. if s.sy == 'IDENT' and s.systring == 'complex': complex = 1 s.next() elif looking_at_dotted_name(s): #print "p_c_simple_base_type: looking_at_type_name at", s.position() name = s.systring s.next() while s.sy == '.': module_path.append(name) s.next() name = p_ident(s) else: name = s.systring s.next() if nonempty and s.sy != 'IDENT': # Make sure this is not a declaration of a variable or function. if s.sy == '(': s.next() if (s.sy == '*' or s.sy == '**' or s.sy == '&' or (s.sy == 'IDENT' and s.systring in calling_convention_words)): s.put_back('(', '(') else: s.put_back('(', '(') s.put_back('IDENT', name) name = None elif s.sy not in ('*', '**', '[', '&'): s.put_back('IDENT', name) name = None type_node = Nodes.CSimpleBaseTypeNode(pos, name = name, module_path = module_path, is_basic_c_type = is_basic, signed = signed, complex = complex, longness = longness, is_self_arg = self_flag, templates = templates) # declarations here. if s.sy == '[': if is_memoryviewslice_access(s): type_node = p_memoryviewslice_access(s, type_node) else: type_node = p_buffer_or_template(s, type_node, templates) if s.sy == '.': s.next() name = p_ident(s) type_node = Nodes.CNestedBaseTypeNode(pos, base_type = type_node, name = name) return type_node def p_buffer_or_template(s, base_type_node, templates): # s.sy == '[' pos = s.position() s.next() # Note that buffer_positional_options_count=1, so the only positional argument is dtype. # For templated types, all parameters are types. positional_args, keyword_args = ( p_positional_and_keyword_args(s, (']',), templates) ) s.expect(']') if s.sy == '[': base_type_node = p_buffer_or_template(s, base_type_node, templates) keyword_dict = ExprNodes.DictNode(pos, key_value_pairs = [ ExprNodes.DictItemNode(pos=key.pos, key=key, value=value) for key, value in keyword_args ]) result = Nodes.TemplatedTypeNode(pos, positional_args = positional_args, keyword_args = keyword_dict, base_type_node = base_type_node) return result def p_bracketed_base_type(s, base_type_node, nonempty, empty): # s.sy == '[' if empty and not nonempty: # sizeof-like thing. Only anonymous C arrays allowed (int[SIZE]). return base_type_node elif not empty and nonempty: # declaration of either memoryview slice or buffer. if is_memoryviewslice_access(s): return p_memoryviewslice_access(s, base_type_node) else: return p_buffer_or_template(s, base_type_node, None) # return p_buffer_access(s, base_type_node) elif not empty and not nonempty: # only anonymous C arrays and memoryview slice arrays here. We # disallow buffer declarations for now, due to ambiguity with anonymous # C arrays. if is_memoryviewslice_access(s): return p_memoryviewslice_access(s, base_type_node) else: return base_type_node def is_memoryviewslice_access(s): # s.sy == '[' # a memoryview slice declaration is distinguishable from a buffer access # declaration by the first entry in the bracketed list. The buffer will # not have an unnested colon in the first entry; the memoryview slice will. saved = [(s.sy, s.systring)] s.next() retval = False if s.systring == ':': retval = True elif s.sy == 'INT': saved.append((s.sy, s.systring)) s.next() if s.sy == ':': retval = True for sv in saved[::-1]: s.put_back(*sv) return retval def p_memoryviewslice_access(s, base_type_node): # s.sy == '[' pos = s.position() s.next() subscripts, _ = p_subscript_list(s) # make sure each entry in subscripts is a slice for subscript in subscripts: if len(subscript) < 2: s.error("An axis specification in memoryview declaration does not have a ':'.") s.expect(']') indexes = make_slice_nodes(pos, subscripts) result = Nodes.MemoryViewSliceTypeNode(pos, base_type_node = base_type_node, axes = indexes) return result def looking_at_name(s): return s.sy == 'IDENT' and not s.systring in calling_convention_words def looking_at_expr(s): if s.systring in base_type_start_words: return False elif s.sy == 'IDENT': is_type = False name = s.systring dotted_path = [] s.next() while s.sy == '.': s.next() dotted_path.append(s.systring) s.expect('IDENT') saved = s.sy, s.systring if s.sy == 'IDENT': is_type = True elif s.sy == '*' or s.sy == '**': s.next() is_type = s.sy in (')', ']') s.put_back(*saved) elif s.sy == '(': s.next() is_type = s.sy == '*' s.put_back(*saved) elif s.sy == '[': s.next() is_type = s.sy == ']' s.put_back(*saved) dotted_path.reverse() for p in dotted_path: s.put_back('IDENT', p) s.put_back('.', '.') s.put_back('IDENT', name) return not is_type and saved[0] else: return True def looking_at_base_type(s): #print "looking_at_base_type?", s.sy, s.systring, s.position() return s.sy == 'IDENT' and s.systring in base_type_start_words def looking_at_dotted_name(s): if s.sy == 'IDENT': name = s.systring s.next() result = s.sy == '.' s.put_back('IDENT', name) return result else: return 0 def looking_at_call(s): "See if we're looking at a.b.c(" # Don't mess up the original position, so save and restore it. # Unfortunately there's no good way to handle this, as a subsequent call # to next() will not advance the position until it reads a new token. position = s.start_line, s.start_col result = looking_at_expr(s) == u'(' if not result: s.start_line, s.start_col = position return result basic_c_type_names = cython.declare( set, set(["void", "char", "int", "float", "double", "bint"])) special_basic_c_types = cython.declare(dict, { # name : (signed, longness) "Py_UNICODE" : (0, 0), "Py_UCS4" : (0, 0), "Py_hash_t" : (2, 0), "Py_ssize_t" : (2, 0), "ssize_t" : (2, 0), "size_t" : (0, 0), "ptrdiff_t" : (2, 0), }) sign_and_longness_words = cython.declare( set, set(["short", "long", "signed", "unsigned"])) base_type_start_words = cython.declare( set, basic_c_type_names | sign_and_longness_words | set(special_basic_c_types)) struct_enum_union = cython.declare( set, set(["struct", "union", "enum", "packed"])) def p_sign_and_longness(s): signed = 1 longness = 0 while s.sy == 'IDENT' and s.systring in sign_and_longness_words: if s.systring == 'unsigned': signed = 0 elif s.systring == 'signed': signed = 2 elif s.systring == 'short': longness = -1 elif s.systring == 'long': longness += 1 s.next() return signed, longness def p_opt_cname(s): literal = p_opt_string_literal(s, 'u') if literal is not None: cname = EncodedString(literal) cname.encoding = s.source_encoding else: cname = None return cname def p_c_declarator(s, ctx = Ctx(), empty = 0, is_type = 0, cmethod_flag = 0, assignable = 0, nonempty = 0, calling_convention_allowed = 0): # If empty is true, the declarator must be empty. If nonempty is true, # the declarator must be nonempty. Otherwise we don't care. # If cmethod_flag is true, then if this declarator declares # a function, it's a C method of an extension type. pos = s.position() if s.sy == '(': s.next() if s.sy == ')' or looking_at_name(s): base = Nodes.CNameDeclaratorNode(pos, name=s.context.intern_ustring(u""), cname=None) result = p_c_func_declarator(s, pos, ctx, base, cmethod_flag) else: result = p_c_declarator(s, ctx, empty = empty, is_type = is_type, cmethod_flag = cmethod_flag, nonempty = nonempty, calling_convention_allowed = 1) s.expect(')') else: result = p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, assignable, nonempty) if not calling_convention_allowed and result.calling_convention and s.sy != '(': error(s.position(), "%s on something that is not a function" % result.calling_convention) while s.sy in ('[', '('): pos = s.position() if s.sy == '[': result = p_c_array_declarator(s, result) else: # sy == '(' s.next() result = p_c_func_declarator(s, pos, ctx, result, cmethod_flag) cmethod_flag = 0 return result def p_c_array_declarator(s, base): pos = s.position() s.next() # '[' if s.sy != ']': dim = p_testlist(s) else: dim = None s.expect(']') return Nodes.CArrayDeclaratorNode(pos, base = base, dimension = dim) def p_c_func_declarator(s, pos, ctx, base, cmethod_flag): # Opening paren has already been skipped args = p_c_arg_list(s, ctx, cmethod_flag = cmethod_flag, nonempty_declarators = 0) ellipsis = p_optional_ellipsis(s) s.expect(')') nogil = p_nogil(s) exc_val, exc_check = p_exception_value_clause(s) with_gil = p_with_gil(s) return Nodes.CFuncDeclaratorNode(pos, base = base, args = args, has_varargs = ellipsis, exception_value = exc_val, exception_check = exc_check, nogil = nogil or ctx.nogil or with_gil, with_gil = with_gil) supported_overloaded_operators = cython.declare(set, set([ '+', '-', '*', '/', '%', '++', '--', '~', '|', '&', '^', '<<', '>>', ',', '==', '!=', '>=', '>', '<=', '<', '[]', '()', '!', '=', 'bool', ])) def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, assignable, nonempty): pos = s.position() calling_convention = p_calling_convention(s) if s.sy == '*': s.next() if s.systring == 'const': const_pos = s.position() s.next() const_base = p_c_declarator(s, ctx, empty = empty, is_type = is_type, cmethod_flag = cmethod_flag, assignable = assignable, nonempty = nonempty) base = Nodes.CConstDeclaratorNode(const_pos, base = const_base) else: base = p_c_declarator(s, ctx, empty = empty, is_type = is_type, cmethod_flag = cmethod_flag, assignable = assignable, nonempty = nonempty) result = Nodes.CPtrDeclaratorNode(pos, base = base) elif s.sy == '**': # scanner returns this as a single token s.next() base = p_c_declarator(s, ctx, empty = empty, is_type = is_type, cmethod_flag = cmethod_flag, assignable = assignable, nonempty = nonempty) result = Nodes.CPtrDeclaratorNode(pos, base = Nodes.CPtrDeclaratorNode(pos, base = base)) elif s.sy == '&': s.next() base = p_c_declarator(s, ctx, empty = empty, is_type = is_type, cmethod_flag = cmethod_flag, assignable = assignable, nonempty = nonempty) result = Nodes.CReferenceDeclaratorNode(pos, base = base) else: rhs = None if s.sy == 'IDENT': name = s.systring if empty: error(s.position(), "Declarator should be empty") s.next() cname = p_opt_cname(s) if name != 'operator' and s.sy == '=' and assignable: s.next() rhs = p_test(s) else: if nonempty: error(s.position(), "Empty declarator") name = "" cname = None if cname is None and ctx.namespace is not None and nonempty: cname = ctx.namespace + "::" + name if name == 'operator' and ctx.visibility == 'extern' and nonempty: op = s.sy if [1 for c in op if c in '+-*/<=>!%&|([^~,']: s.next() # Handle diphthong operators. if op == '(': s.expect(')') op = '()' elif op == '[': s.expect(']') op = '[]' elif op in ('-', '+', '|', '&') and s.sy == op: op *= 2 # ++, --, ... s.next() elif s.sy == '=': op += s.sy # +=, -=, ... s.next() if op not in supported_overloaded_operators: s.error("Overloading operator '%s' not yet supported." % op, fatal=False) name += op elif op == 'IDENT': op = s.systring; if op not in supported_overloaded_operators: s.error("Overloading operator '%s' not yet supported." % op, fatal=False) name = name + ' ' + op s.next() result = Nodes.CNameDeclaratorNode(pos, name = name, cname = cname, default = rhs) result.calling_convention = calling_convention return result def p_nogil(s): if s.sy == 'IDENT' and s.systring == 'nogil': s.next() return 1 else: return 0 def p_with_gil(s): if s.sy == 'with': s.next() s.expect_keyword('gil') return 1 else: return 0 def p_exception_value_clause(s): exc_val = None exc_check = 0 if s.sy == 'except': s.next() if s.sy == '*': exc_check = 1 s.next() elif s.sy == '+': exc_check = '+' s.next() if s.sy == 'IDENT': name = s.systring s.next() exc_val = p_name(s, name) else: if s.sy == '?': exc_check = 1 s.next() exc_val = p_test(s) return exc_val, exc_check c_arg_list_terminators = cython.declare(set, set(['*', '**', '.', ')'])) def p_c_arg_list(s, ctx = Ctx(), in_pyfunc = 0, cmethod_flag = 0, nonempty_declarators = 0, kw_only = 0, annotated = 1): # Comma-separated list of C argument declarations, possibly empty. # May have a trailing comma. args = [] is_self_arg = cmethod_flag while s.sy not in c_arg_list_terminators: args.append(p_c_arg_decl(s, ctx, in_pyfunc, is_self_arg, nonempty = nonempty_declarators, kw_only = kw_only, annotated = annotated)) if s.sy != ',': break s.next() is_self_arg = 0 return args def p_optional_ellipsis(s): if s.sy == '.': expect_ellipsis(s) return 1 else: return 0 def p_c_arg_decl(s, ctx, in_pyfunc, cmethod_flag = 0, nonempty = 0, kw_only = 0, annotated = 1): pos = s.position() not_none = or_none = 0 default = None annotation = None if s.in_python_file: # empty type declaration base_type = Nodes.CSimpleBaseTypeNode(pos, name = None, module_path = [], is_basic_c_type = 0, signed = 0, complex = 0, longness = 0, is_self_arg = cmethod_flag, templates = None) else: base_type = p_c_base_type(s, cmethod_flag, nonempty = nonempty) declarator = p_c_declarator(s, ctx, nonempty = nonempty) if s.sy in ('not', 'or') and not s.in_python_file: kind = s.sy s.next() if s.sy == 'IDENT' and s.systring == 'None': s.next() else: s.error("Expected 'None'") if not in_pyfunc: error(pos, "'%s None' only allowed in Python functions" % kind) or_none = kind == 'or' not_none = kind == 'not' if annotated and s.sy == ':': s.next() annotation = p_test(s) if s.sy == '=': s.next() if 'pxd' in ctx.level: if s.sy not in ['*', '?']: error(pos, "default values cannot be specified in pxd files, use ? or *") default = ExprNodes.BoolNode(1) s.next() else: default = p_test(s) return Nodes.CArgDeclNode(pos, base_type = base_type, declarator = declarator, not_none = not_none, or_none = or_none, default = default, annotation = annotation, kw_only = kw_only) def p_api(s): if s.sy == 'IDENT' and s.systring == 'api': s.next() return 1 else: return 0 def p_cdef_statement(s, ctx): pos = s.position() ctx.visibility = p_visibility(s, ctx.visibility) ctx.api = ctx.api or p_api(s) if ctx.api: if ctx.visibility not in ('private', 'public'): error(pos, "Cannot combine 'api' with '%s'" % ctx.visibility) if (ctx.visibility == 'extern') and s.sy == 'from': return p_cdef_extern_block(s, pos, ctx) elif s.sy == 'import': s.next() return p_cdef_extern_block(s, pos, ctx) elif p_nogil(s): ctx.nogil = 1 if ctx.overridable: error(pos, "cdef blocks cannot be declared cpdef") return p_cdef_block(s, ctx) elif s.sy == ':': if ctx.overridable: error(pos, "cdef blocks cannot be declared cpdef") return p_cdef_block(s, ctx) elif s.sy == 'class': if ctx.level not in ('module', 'module_pxd'): error(pos, "Extension type definition not allowed here") if ctx.overridable: error(pos, "Extension types cannot be declared cpdef") return p_c_class_definition(s, pos, ctx) elif s.sy == 'IDENT' and s.systring == 'cppclass': return p_cpp_class_definition(s, pos, ctx) elif s.sy == 'IDENT' and s.systring in struct_enum_union: if ctx.level not in ('module', 'module_pxd'): error(pos, "C struct/union/enum definition not allowed here") if ctx.overridable: if s.systring != 'enum': error(pos, "C struct/union cannot be declared cpdef") return p_struct_enum(s, pos, ctx) elif s.sy == 'IDENT' and s.systring == 'fused': return p_fused_definition(s, pos, ctx) else: return p_c_func_or_var_declaration(s, pos, ctx) def p_cdef_block(s, ctx): return p_suite(s, ctx(cdef_flag = 1)) def p_cdef_extern_block(s, pos, ctx): if ctx.overridable: error(pos, "cdef extern blocks cannot be declared cpdef") include_file = None s.expect('from') if s.sy == '*': s.next() else: include_file = p_string_literal(s, 'u')[2] ctx = ctx(cdef_flag = 1, visibility = 'extern') if s.systring == "namespace": s.next() ctx.namespace = p_string_literal(s, 'u')[2] if p_nogil(s): ctx.nogil = 1 body = p_suite(s, ctx) return Nodes.CDefExternNode(pos, include_file = include_file, body = body, namespace = ctx.namespace) def p_c_enum_definition(s, pos, ctx): # s.sy == ident 'enum' s.next() if s.sy == 'IDENT': name = s.systring s.next() cname = p_opt_cname(s) if cname is None and ctx.namespace is not None: cname = ctx.namespace + "::" + name else: name = None cname = None items = None s.expect(':') items = [] if s.sy != 'NEWLINE': p_c_enum_line(s, ctx, items) else: s.next() # 'NEWLINE' s.expect_indent() while s.sy not in ('DEDENT', 'EOF'): p_c_enum_line(s, ctx, items) s.expect_dedent() return Nodes.CEnumDefNode( pos, name = name, cname = cname, items = items, typedef_flag = ctx.typedef_flag, visibility = ctx.visibility, create_wrapper = ctx.overridable, api = ctx.api, in_pxd = ctx.level == 'module_pxd') def p_c_enum_line(s, ctx, items): if s.sy != 'pass': p_c_enum_item(s, ctx, items) while s.sy == ',': s.next() if s.sy in ('NEWLINE', 'EOF'): break p_c_enum_item(s, ctx, items) else: s.next() s.expect_newline("Syntax error in enum item list") def p_c_enum_item(s, ctx, items): pos = s.position() name = p_ident(s) cname = p_opt_cname(s) if cname is None and ctx.namespace is not None: cname = ctx.namespace + "::" + name value = None if s.sy == '=': s.next() value = p_test(s) items.append(Nodes.CEnumDefItemNode(pos, name = name, cname = cname, value = value)) def p_c_struct_or_union_definition(s, pos, ctx): packed = False if s.systring == 'packed': packed = True s.next() if s.sy != 'IDENT' or s.systring != 'struct': s.expected('struct') # s.sy == ident 'struct' or 'union' kind = s.systring s.next() name = p_ident(s) cname = p_opt_cname(s) if cname is None and ctx.namespace is not None: cname = ctx.namespace + "::" + name attributes = None if s.sy == ':': s.next() s.expect('NEWLINE') s.expect_indent() attributes = [] body_ctx = Ctx() while s.sy != 'DEDENT': if s.sy != 'pass': attributes.append( p_c_func_or_var_declaration(s, s.position(), body_ctx)) else: s.next() s.expect_newline("Expected a newline") s.expect_dedent() else: s.expect_newline("Syntax error in struct or union definition") return Nodes.CStructOrUnionDefNode(pos, name = name, cname = cname, kind = kind, attributes = attributes, typedef_flag = ctx.typedef_flag, visibility = ctx.visibility, api = ctx.api, in_pxd = ctx.level == 'module_pxd', packed = packed) def p_fused_definition(s, pos, ctx): """ c(type)def fused my_fused_type: ... """ # s.systring == 'fused' if ctx.level not in ('module', 'module_pxd'): error(pos, "Fused type definition not allowed here") s.next() name = p_ident(s) s.expect(":") s.expect_newline() s.expect_indent() types = [] while s.sy != 'DEDENT': if s.sy != 'pass': #types.append(p_c_declarator(s)) types.append(p_c_base_type(s)) #, nonempty=1)) else: s.next() s.expect_newline() s.expect_dedent() if not types: error(pos, "Need at least one type") return Nodes.FusedTypeNode(pos, name=name, types=types) def p_struct_enum(s, pos, ctx): if s.systring == 'enum': return p_c_enum_definition(s, pos, ctx) else: return p_c_struct_or_union_definition(s, pos, ctx) def p_visibility(s, prev_visibility): pos = s.position() visibility = prev_visibility if s.sy == 'IDENT' and s.systring in ('extern', 'public', 'readonly'): visibility = s.systring if prev_visibility != 'private' and visibility != prev_visibility: s.error("Conflicting visibility options '%s' and '%s'" % (prev_visibility, visibility), fatal=False) s.next() return visibility def p_c_modifiers(s): if s.sy == 'IDENT' and s.systring in ('inline',): modifier = s.systring s.next() return [modifier] + p_c_modifiers(s) return [] def p_c_func_or_var_declaration(s, pos, ctx): cmethod_flag = ctx.level in ('c_class', 'c_class_pxd') modifiers = p_c_modifiers(s) base_type = p_c_base_type(s, nonempty = 1, templates = ctx.templates) declarator = p_c_declarator(s, ctx, cmethod_flag = cmethod_flag, assignable = 1, nonempty = 1) declarator.overridable = ctx.overridable if s.sy == 'IDENT' and s.systring == 'const' and ctx.level == 'cpp_class': s.next() is_const_method = 1 else: is_const_method = 0 if s.sy == ':': if ctx.level not in ('module', 'c_class', 'module_pxd', 'c_class_pxd', 'cpp_class') and not ctx.templates: s.error("C function definition not allowed here") doc, suite = p_suite_with_docstring(s, Ctx(level='function')) result = Nodes.CFuncDefNode(pos, visibility = ctx.visibility, base_type = base_type, declarator = declarator, body = suite, doc = doc, modifiers = modifiers, api = ctx.api, overridable = ctx.overridable, is_const_method = is_const_method) else: #if api: # s.error("'api' not allowed with variable declaration") if is_const_method: declarator.is_const_method = is_const_method declarators = [declarator] while s.sy == ',': s.next() if s.sy == 'NEWLINE': break declarator = p_c_declarator(s, ctx, cmethod_flag = cmethod_flag, assignable = 1, nonempty = 1) declarators.append(declarator) doc_line = s.start_line + 1 s.expect_newline("Syntax error in C variable declaration", ignore_semicolon=True) if ctx.level in ('c_class', 'c_class_pxd') and s.start_line == doc_line: doc = p_doc_string(s) else: doc = None result = Nodes.CVarDefNode(pos, visibility = ctx.visibility, base_type = base_type, declarators = declarators, in_pxd = ctx.level in ('module_pxd', 'c_class_pxd'), doc = doc, api = ctx.api, modifiers = modifiers, overridable = ctx.overridable) return result def p_ctypedef_statement(s, ctx): # s.sy == 'ctypedef' pos = s.position() s.next() visibility = p_visibility(s, ctx.visibility) api = p_api(s) ctx = ctx(typedef_flag = 1, visibility = visibility) if api: ctx.api = 1 if s.sy == 'class': return p_c_class_definition(s, pos, ctx) elif s.sy == 'IDENT' and s.systring in struct_enum_union: return p_struct_enum(s, pos, ctx) elif s.sy == 'IDENT' and s.systring == 'fused': return p_fused_definition(s, pos, ctx) else: base_type = p_c_base_type(s, nonempty = 1) declarator = p_c_declarator(s, ctx, is_type = 1, nonempty = 1) s.expect_newline("Syntax error in ctypedef statement", ignore_semicolon=True) return Nodes.CTypeDefNode( pos, base_type = base_type, declarator = declarator, visibility = visibility, api = api, in_pxd = ctx.level == 'module_pxd') def p_decorators(s): decorators = [] while s.sy == '@': pos = s.position() s.next() decstring = p_dotted_name(s, as_allowed=0)[2] names = decstring.split('.') decorator = ExprNodes.NameNode(pos, name=s.context.intern_ustring(names[0])) for name in names[1:]: decorator = ExprNodes.AttributeNode( pos, attribute=s.context.intern_ustring(name), obj=decorator) if s.sy == '(': decorator = p_call(s, decorator) decorators.append(Nodes.DecoratorNode(pos, decorator=decorator)) s.expect_newline("Expected a newline after decorator") return decorators def p_def_statement(s, decorators=None, is_async_def=False): # s.sy == 'def' pos = s.position() # PEP 492 switches the async/await keywords on in "async def" functions if is_async_def: s.enter_async() s.next() name = p_ident(s) s.expect('(') args, star_arg, starstar_arg = p_varargslist(s, terminator=')') s.expect(')') if p_nogil(s): error(pos, "Python function cannot be declared nogil") return_type_annotation = None if s.sy == '->': s.next() return_type_annotation = p_test(s) doc, body = p_suite_with_docstring(s, Ctx(level='function')) if is_async_def: s.exit_async() return Nodes.DefNode( pos, name=name, args=args, star_arg=star_arg, starstar_arg=starstar_arg, doc=doc, body=body, decorators=decorators, is_async_def=is_async_def, return_type_annotation=return_type_annotation) def p_varargslist(s, terminator=')', annotated=1): args = p_c_arg_list(s, in_pyfunc = 1, nonempty_declarators = 1, annotated = annotated) star_arg = None starstar_arg = None if s.sy == '*': s.next() if s.sy == 'IDENT': star_arg = p_py_arg_decl(s, annotated=annotated) if s.sy == ',': s.next() args.extend(p_c_arg_list(s, in_pyfunc = 1, nonempty_declarators = 1, kw_only = 1, annotated = annotated)) elif s.sy != terminator: s.error("Syntax error in Python function argument list") if s.sy == '**': s.next() starstar_arg = p_py_arg_decl(s, annotated=annotated) return (args, star_arg, starstar_arg) def p_py_arg_decl(s, annotated = 1): pos = s.position() name = p_ident(s) annotation = None if annotated and s.sy == ':': s.next() annotation = p_test(s) return Nodes.PyArgDeclNode(pos, name = name, annotation = annotation) def p_class_statement(s, decorators): # s.sy == 'class' pos = s.position() s.next() class_name = EncodedString(p_ident(s)) class_name.encoding = s.source_encoding # FIXME: why is this needed? arg_tuple = None keyword_dict = None if s.sy == '(': positional_args, keyword_args = p_call_parse_args(s, allow_genexp=False) arg_tuple, keyword_dict = p_call_build_packed_args(pos, positional_args, keyword_args) if arg_tuple is None: # XXX: empty arg_tuple arg_tuple = ExprNodes.TupleNode(pos, args=[]) doc, body = p_suite_with_docstring(s, Ctx(level='class')) return Nodes.PyClassDefNode( pos, name=class_name, bases=arg_tuple, keyword_args=keyword_dict, doc=doc, body=body, decorators=decorators, force_py3_semantics=s.context.language_level >= 3) def p_c_class_definition(s, pos, ctx): # s.sy == 'class' s.next() module_path = [] class_name = p_ident(s) while s.sy == '.': s.next() module_path.append(class_name) class_name = p_ident(s) if module_path and ctx.visibility != 'extern': error(pos, "Qualified class name only allowed for 'extern' C class") if module_path and s.sy == 'IDENT' and s.systring == 'as': s.next() as_name = p_ident(s) else: as_name = class_name objstruct_name = None typeobj_name = None base_class_module = None base_class_name = None if s.sy == '(': s.next() base_class_path = [p_ident(s)] while s.sy == '.': s.next() base_class_path.append(p_ident(s)) if s.sy == ',': s.error("C class may only have one base class", fatal=False) s.expect(')') base_class_module = ".".join(base_class_path[:-1]) base_class_name = base_class_path[-1] if s.sy == '[': if ctx.visibility not in ('public', 'extern') and not ctx.api: error(s.position(), "Name options only allowed for 'public', 'api', or 'extern' C class") objstruct_name, typeobj_name = p_c_class_options(s) if s.sy == ':': if ctx.level == 'module_pxd': body_level = 'c_class_pxd' else: body_level = 'c_class' doc, body = p_suite_with_docstring(s, Ctx(level=body_level)) else: s.expect_newline("Syntax error in C class definition") doc = None body = None if ctx.visibility == 'extern': if not module_path: error(pos, "Module name required for 'extern' C class") if typeobj_name: error(pos, "Type object name specification not allowed for 'extern' C class") elif ctx.visibility == 'public': if not objstruct_name: error(pos, "Object struct name specification required for 'public' C class") if not typeobj_name: error(pos, "Type object name specification required for 'public' C class") elif ctx.visibility == 'private': if ctx.api: if not objstruct_name: error(pos, "Object struct name specification required for 'api' C class") if not typeobj_name: error(pos, "Type object name specification required for 'api' C class") else: error(pos, "Invalid class visibility '%s'" % ctx.visibility) return Nodes.CClassDefNode(pos, visibility = ctx.visibility, typedef_flag = ctx.typedef_flag, api = ctx.api, module_name = ".".join(module_path), class_name = class_name, as_name = as_name, base_class_module = base_class_module, base_class_name = base_class_name, objstruct_name = objstruct_name, typeobj_name = typeobj_name, in_pxd = ctx.level == 'module_pxd', doc = doc, body = body) def p_c_class_options(s): objstruct_name = None typeobj_name = None s.expect('[') while 1: if s.sy != 'IDENT': break if s.systring == 'object': s.next() objstruct_name = p_ident(s) elif s.systring == 'type': s.next() typeobj_name = p_ident(s) if s.sy != ',': break s.next() s.expect(']', "Expected 'object' or 'type'") return objstruct_name, typeobj_name def p_property_decl(s): pos = s.position() s.next() # 'property' name = p_ident(s) doc, body = p_suite_with_docstring( s, Ctx(level='property'), with_doc_only=True) return Nodes.PropertyNode(pos, name=name, doc=doc, body=body) def p_ignorable_statement(s): """ Parses any kind of ignorable statement that is allowed in .pxd files. """ if s.sy == 'BEGIN_STRING': pos = s.position() string_node = p_atom(s) s.expect_newline("Syntax error in string", ignore_semicolon=True) return Nodes.ExprStatNode(pos, expr=string_node) return None def p_doc_string(s): if s.sy == 'BEGIN_STRING': pos = s.position() kind, bytes_result, unicode_result = p_cat_string_literal(s) s.expect_newline("Syntax error in doc string", ignore_semicolon=True) if kind in ('u', ''): return unicode_result warning(pos, "Python 3 requires docstrings to be unicode strings") return bytes_result else: return None def _extract_docstring(node): """ Extract a docstring from a statement or from the first statement in a list. Remove the statement if found. Return a tuple (plain-docstring or None, node). """ doc_node = None if node is None: pass elif isinstance(node, Nodes.ExprStatNode): if node.expr.is_string_literal: doc_node = node.expr node = Nodes.StatListNode(node.pos, stats=[]) elif isinstance(node, Nodes.StatListNode) and node.stats: stats = node.stats if isinstance(stats[0], Nodes.ExprStatNode): if stats[0].expr.is_string_literal: doc_node = stats[0].expr del stats[0] if doc_node is None: doc = None elif isinstance(doc_node, ExprNodes.BytesNode): warning(node.pos, "Python 3 requires docstrings to be unicode strings") doc = doc_node.value elif isinstance(doc_node, ExprNodes.StringNode): doc = doc_node.unicode_value if doc is None: doc = doc_node.value else: doc = doc_node.value return doc, node def p_code(s, level=None, ctx=Ctx): body = p_statement_list(s, ctx(level = level), first_statement = 1) if s.sy != 'EOF': s.error("Syntax error in statement [%s,%s]" % ( repr(s.sy), repr(s.systring))) return body _match_compiler_directive_comment = cython.declare(object, re.compile( r"^#\s*cython\s*:\s*((\w|[.])+\s*=.*)$").match) def p_compiler_directive_comments(s): result = {} while s.sy == 'commentline': m = _match_compiler_directive_comment(s.systring) if m: directives = m.group(1).strip() try: result.update(Options.parse_directive_list( directives, ignore_unknown=True)) except ValueError as e: s.error(e.args[0], fatal=False) s.next() return result def p_module(s, pxd, full_module_name, ctx=Ctx): pos = s.position() directive_comments = p_compiler_directive_comments(s) s.parse_comments = False if 'language_level' in directive_comments: s.context.set_language_level(directive_comments['language_level']) doc = p_doc_string(s) if pxd: level = 'module_pxd' else: level = 'module' body = p_statement_list(s, ctx(level=level), first_statement = 1) if s.sy != 'EOF': s.error("Syntax error in statement [%s,%s]" % ( repr(s.sy), repr(s.systring))) return ModuleNode(pos, doc = doc, body = body, full_module_name = full_module_name, directive_comments = directive_comments) def p_cpp_class_definition(s, pos, ctx): # s.sy == 'cppclass' s.next() module_path = [] class_name = p_ident(s) cname = p_opt_cname(s) if cname is None and ctx.namespace is not None: cname = ctx.namespace + "::" + class_name if s.sy == '.': error(pos, "Qualified class name not allowed C++ class") if s.sy == '[': s.next() templates = [p_ident(s)] while s.sy == ',': s.next() templates.append(p_ident(s)) s.expect(']') else: templates = None if s.sy == '(': s.next() base_classes = [p_c_base_type(s, templates = templates)] while s.sy == ',': s.next() base_classes.append(p_c_base_type(s, templates = templates)) s.expect(')') else: base_classes = [] if s.sy == '[': error(s.position(), "Name options not allowed for C++ class") nogil = p_nogil(s) if s.sy == ':': s.next() s.expect('NEWLINE') s.expect_indent() attributes = [] body_ctx = Ctx(visibility = ctx.visibility, level='cpp_class', nogil=nogil or ctx.nogil) body_ctx.templates = templates while s.sy != 'DEDENT': if s.sy != 'pass': attributes.append(p_cpp_class_attribute(s, body_ctx)) else: s.next() s.expect_newline("Expected a newline") s.expect_dedent() else: attributes = None s.expect_newline("Syntax error in C++ class definition") return Nodes.CppClassNode(pos, name = class_name, cname = cname, base_classes = base_classes, visibility = ctx.visibility, in_pxd = ctx.level == 'module_pxd', attributes = attributes, templates = templates) def p_cpp_class_attribute(s, ctx): decorators = None if s.sy == '@': decorators = p_decorators(s) if s.systring == 'cppclass': return p_cpp_class_definition(s, s.position(), ctx) else: node = p_c_func_or_var_declaration(s, s.position(), ctx) if decorators is not None: tup = Nodes.CFuncDefNode, Nodes.CVarDefNode, Nodes.CClassDefNode if ctx.allow_struct_enum_decorator: tup += Nodes.CStructOrUnionDefNode, Nodes.CEnumDefNode if not isinstance(node, tup): s.error("Decorators can only be followed by functions or classes") node.decorators = decorators return node #---------------------------------------------- # # Debugging # #---------------------------------------------- def print_parse_tree(f, node, level, key = None): ind = " " * level if node: f.write(ind) if key: f.write("%s: " % key) t = type(node) if t is tuple: f.write("(%s @ %s\n" % (node[0], node[1])) for i in range(2, len(node)): print_parse_tree(f, node[i], level+1) f.write("%s)\n" % ind) return elif isinstance(node, Nodes.Node): try: tag = node.tag except AttributeError: tag = node.__class__.__name__ f.write("%s @ %s\n" % (tag, node.pos)) for name, value in node.__dict__.items(): if name != 'tag' and name != 'pos': print_parse_tree(f, value, level+1, name) return elif t is list: f.write("[\n") for i in range(len(node)): print_parse_tree(f, node[i], level+1) f.write("%s]\n" % ind) return f.write("%s%s\n" % (ind, node)) Cython-0.23.4/Cython/Compiler/Parsing.pxd0000644000175600017570000002030112606202452021336 0ustar jenkinsjenkins00000000000000# We declare all of these here to type the first argument. from __future__ import absolute_import cimport cython from .Scanning cimport PyrexScanner ctypedef object (*p_sub_expr_func)(PyrexScanner obj) # entry points cpdef p_module(PyrexScanner s, pxd, full_module_name, ctx=*) cpdef p_code(PyrexScanner s, level= *, ctx=*) # internal parser states cdef p_ident(PyrexScanner s, message =*) cdef p_ident_list(PyrexScanner s) cdef tuple p_binop_operator(PyrexScanner s) cdef p_binop_expr(PyrexScanner s, ops, p_sub_expr_func p_sub_expr) cdef p_lambdef(PyrexScanner s, bint allow_conditional=*) cdef p_lambdef_nocond(PyrexScanner s) cdef p_test(PyrexScanner s) cdef p_test_nocond(PyrexScanner s) cdef p_or_test(PyrexScanner s) cdef p_rassoc_binop_expr(PyrexScanner s, ops, p_sub_expr_func p_subexpr) cdef p_and_test(PyrexScanner s) cdef p_not_test(PyrexScanner s) cdef p_comparison(PyrexScanner s) cdef p_test_or_starred_expr(PyrexScanner s) cdef p_starred_expr(PyrexScanner s) cdef p_cascaded_cmp(PyrexScanner s) cdef p_cmp_op(PyrexScanner s) cdef p_bit_expr(PyrexScanner s) cdef p_xor_expr(PyrexScanner s) cdef p_and_expr(PyrexScanner s) cdef p_shift_expr(PyrexScanner s) cdef p_arith_expr(PyrexScanner s) cdef p_term(PyrexScanner s) cdef p_factor(PyrexScanner s) cdef _p_factor(PyrexScanner s) cdef p_typecast(PyrexScanner s) cdef p_sizeof(PyrexScanner s) cdef p_yield_expression(PyrexScanner s) cdef p_yield_statement(PyrexScanner s) cdef p_async_statement(PyrexScanner s, ctx, decorators) cdef p_power(PyrexScanner s) cdef p_new_expr(PyrexScanner s) cdef p_trailer(PyrexScanner s, node1) cdef p_call_parse_args(PyrexScanner s, bint allow_genexp = *) cdef p_call_build_packed_args(pos, positional_args, keyword_args) cdef p_call(PyrexScanner s, function) cdef p_index(PyrexScanner s, base) cdef tuple p_subscript_list(PyrexScanner s) cdef p_subscript(PyrexScanner s) cdef p_slice_element(PyrexScanner s, follow_set) cdef expect_ellipsis(PyrexScanner s) cdef make_slice_nodes(pos, subscripts) cpdef make_slice_node(pos, start, stop = *, step = *) cdef p_atom(PyrexScanner s) @cython.locals(value=unicode) cdef p_int_literal(PyrexScanner s) cdef p_name(PyrexScanner s, name) cdef wrap_compile_time_constant(pos, value) cdef p_cat_string_literal(PyrexScanner s) cdef p_opt_string_literal(PyrexScanner s, required_type=*) cdef bint check_for_non_ascii_characters(unicode string) @cython.locals(systr=unicode, is_python3_source=bint, is_raw=bint) cdef p_string_literal(PyrexScanner s, kind_override=*) cdef p_list_maker(PyrexScanner s) cdef p_comp_iter(PyrexScanner s, body) cdef p_comp_for(PyrexScanner s, body) cdef p_comp_if(PyrexScanner s, body) cdef p_dict_or_set_maker(PyrexScanner s) cdef p_backquote_expr(PyrexScanner s) cdef p_simple_expr_list(PyrexScanner s, expr=*) cdef p_test_or_starred_expr_list(PyrexScanner s, expr=*) cdef p_testlist(PyrexScanner s) cdef p_testlist_star_expr(PyrexScanner s) cdef p_testlist_comp(PyrexScanner s) cdef p_genexp(PyrexScanner s, expr) #------------------------------------------------------- # # Statements # #------------------------------------------------------- cdef p_global_statement(PyrexScanner s) cdef p_nonlocal_statement(PyrexScanner s) cdef p_expression_or_assignment(PyrexScanner s) cdef p_print_statement(PyrexScanner s) cdef p_exec_statement(PyrexScanner s) cdef p_del_statement(PyrexScanner s) cdef p_pass_statement(PyrexScanner s, bint with_newline = *) cdef p_break_statement(PyrexScanner s) cdef p_continue_statement(PyrexScanner s) cdef p_return_statement(PyrexScanner s) cdef p_raise_statement(PyrexScanner s) cdef p_import_statement(PyrexScanner s) cdef p_from_import_statement(PyrexScanner s, bint first_statement = *) cdef p_imported_name(PyrexScanner s, bint is_cimport) cdef p_dotted_name(PyrexScanner s, bint as_allowed) cdef p_as_name(PyrexScanner s) cdef p_assert_statement(PyrexScanner s) cdef p_if_statement(PyrexScanner s) cdef p_if_clause(PyrexScanner s) cdef p_else_clause(PyrexScanner s) cdef p_while_statement(PyrexScanner s) cdef p_for_statement(PyrexScanner s, bint is_async=*) cdef dict p_for_bounds(PyrexScanner s, bint allow_testlist=*, bint is_async=*) cdef p_for_from_relation(PyrexScanner s) cdef p_for_from_step(PyrexScanner s) cdef p_target(PyrexScanner s, terminator) cdef p_for_target(PyrexScanner s) cdef p_for_iterator(PyrexScanner s, bint allow_testlist=*, bint is_async=*) cdef p_try_statement(PyrexScanner s) cdef p_except_clause(PyrexScanner s) cdef p_include_statement(PyrexScanner s, ctx) cdef p_with_statement(PyrexScanner s) cdef p_with_items(PyrexScanner s, bint is_async=*) cdef p_with_template(PyrexScanner s) cdef p_simple_statement(PyrexScanner s, bint first_statement = *) cdef p_simple_statement_list(PyrexScanner s, ctx, bint first_statement = *) cdef p_compile_time_expr(PyrexScanner s) cdef p_DEF_statement(PyrexScanner s) cdef p_IF_statement(PyrexScanner s, ctx) cdef p_statement(PyrexScanner s, ctx, bint first_statement = *) cdef p_statement_list(PyrexScanner s, ctx, bint first_statement = *) cdef p_suite(PyrexScanner s, ctx = *) cdef tuple p_suite_with_docstring(PyrexScanner s, ctx, bint with_doc_only=*) cdef tuple _extract_docstring(node) cdef p_positional_and_keyword_args(PyrexScanner s, end_sy_set, templates = *) cpdef p_c_base_type(PyrexScanner s, bint self_flag = *, bint nonempty = *, templates = *) cdef p_calling_convention(PyrexScanner s) cdef p_c_complex_base_type(PyrexScanner s, templates = *) cdef p_c_simple_base_type(PyrexScanner s, bint self_flag, bint nonempty, templates = *) cdef p_buffer_or_template(PyrexScanner s, base_type_node, templates) cdef p_bracketed_base_type(PyrexScanner s, base_type_node, nonempty, empty) cdef is_memoryviewslice_access(PyrexScanner s) cdef p_memoryviewslice_access(PyrexScanner s, base_type_node) cdef bint looking_at_name(PyrexScanner s) except -2 cdef object looking_at_expr(PyrexScanner s)# except -2 cdef bint looking_at_base_type(PyrexScanner s) except -2 cdef bint looking_at_dotted_name(PyrexScanner s) except -2 cdef bint looking_at_call(PyrexScanner s) except -2 cdef p_sign_and_longness(PyrexScanner s) cdef p_opt_cname(PyrexScanner s) cpdef p_c_declarator(PyrexScanner s, ctx = *, bint empty = *, bint is_type = *, bint cmethod_flag = *, bint assignable = *, bint nonempty = *, bint calling_convention_allowed = *) cdef p_c_array_declarator(PyrexScanner s, base) cdef p_c_func_declarator(PyrexScanner s, pos, ctx, base, bint cmethod_flag) cdef p_c_simple_declarator(PyrexScanner s, ctx, bint empty, bint is_type, bint cmethod_flag, bint assignable, bint nonempty) cdef p_nogil(PyrexScanner s) cdef p_with_gil(PyrexScanner s) cdef p_exception_value_clause(PyrexScanner s) cpdef p_c_arg_list(PyrexScanner s, ctx = *, bint in_pyfunc = *, bint cmethod_flag = *, bint nonempty_declarators = *, bint kw_only = *, bint annotated = *) cdef p_optional_ellipsis(PyrexScanner s) cdef p_c_arg_decl(PyrexScanner s, ctx, in_pyfunc, bint cmethod_flag = *, bint nonempty = *, bint kw_only = *, bint annotated = *) cdef p_api(PyrexScanner s) cdef p_cdef_statement(PyrexScanner s, ctx) cdef p_cdef_block(PyrexScanner s, ctx) cdef p_cdef_extern_block(PyrexScanner s, pos, ctx) cdef p_c_enum_definition(PyrexScanner s, pos, ctx) cdef p_c_enum_line(PyrexScanner s, ctx, list items) cdef p_c_enum_item(PyrexScanner s, ctx, list items) cdef p_c_struct_or_union_definition(PyrexScanner s, pos, ctx) cdef p_fused_definition(PyrexScanner s, pos, ctx) cdef p_struct_enum(PyrexScanner s, pos, ctx) cdef p_visibility(PyrexScanner s, prev_visibility) cdef p_c_modifiers(PyrexScanner s) cdef p_c_func_or_var_declaration(PyrexScanner s, pos, ctx) cdef p_ctypedef_statement(PyrexScanner s, ctx) cdef p_decorators(PyrexScanner s) cdef p_def_statement(PyrexScanner s, list decorators=*, bint is_async_def=*) cdef p_varargslist(PyrexScanner s, terminator=*, bint annotated = *) cdef p_py_arg_decl(PyrexScanner s, bint annotated = *) cdef p_class_statement(PyrexScanner s, decorators) cdef p_c_class_definition(PyrexScanner s, pos, ctx) cdef p_c_class_options(PyrexScanner s) cdef p_property_decl(PyrexScanner s) cdef p_doc_string(PyrexScanner s) cdef p_ignorable_statement(PyrexScanner s) cdef p_compiler_directive_comments(PyrexScanner s) cdef p_cpp_class_definition(PyrexScanner s, pos, ctx) cdef p_cpp_class_attribute(PyrexScanner s, ctx) Cython-0.23.4/Cython/Compiler/ParseTreeTransforms.py0000644000175600017570000034611112606202452023553 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import import cython cython.declare(PyrexTypes=object, Naming=object, ExprNodes=object, Nodes=object, Options=object, UtilNodes=object, LetNode=object, LetRefNode=object, TreeFragment=object, EncodedString=object, error=object, warning=object, copy=object, _unicode=object) import copy from . import PyrexTypes from . import Naming from . import ExprNodes from . import Nodes from . import Options from . import Builtin from .Visitor import VisitorTransform, TreeVisitor from .Visitor import CythonTransform, EnvTransform, ScopeTrackingTransform from .UtilNodes import LetNode, LetRefNode, ResultRefNode from .TreeFragment import TreeFragment from .StringEncoding import EncodedString, _unicode from .Errors import error, warning, CompileError, InternalError from .Code import UtilityCode class NameNodeCollector(TreeVisitor): """Collect all NameNodes of a (sub-)tree in the ``name_nodes`` attribute. """ def __init__(self): super(NameNodeCollector, self).__init__() self.name_nodes = [] def visit_NameNode(self, node): self.name_nodes.append(node) def visit_Node(self, node): self._visitchildren(node, None) class SkipDeclarations(object): """ Variable and function declarations can often have a deep tree structure, and yet most transformations don't need to descend to this depth. Declaration nodes are removed after AnalyseDeclarationsTransform, so there is no need to use this for transformations after that point. """ def visit_CTypeDefNode(self, node): return node def visit_CVarDefNode(self, node): return node def visit_CDeclaratorNode(self, node): return node def visit_CBaseTypeNode(self, node): return node def visit_CEnumDefNode(self, node): return node def visit_CStructOrUnionDefNode(self, node): return node class NormalizeTree(CythonTransform): """ This transform fixes up a few things after parsing in order to make the parse tree more suitable for transforms. a) After parsing, blocks with only one statement will be represented by that statement, not by a StatListNode. When doing transforms this is annoying and inconsistent, as one cannot in general remove a statement in a consistent way and so on. This transform wraps any single statements in a StatListNode containing a single statement. b) The PassStatNode is a noop and serves no purpose beyond plugging such one-statement blocks; i.e., once parsed a ` "pass" can just as well be represented using an empty StatListNode. This means less special cases to worry about in subsequent transforms (one always checks to see if a StatListNode has no children to see if the block is empty). """ def __init__(self, context): super(NormalizeTree, self).__init__(context) self.is_in_statlist = False self.is_in_expr = False def visit_ExprNode(self, node): stacktmp = self.is_in_expr self.is_in_expr = True self.visitchildren(node) self.is_in_expr = stacktmp return node def visit_StatNode(self, node, is_listcontainer=False): stacktmp = self.is_in_statlist self.is_in_statlist = is_listcontainer self.visitchildren(node) self.is_in_statlist = stacktmp if not self.is_in_statlist and not self.is_in_expr: return Nodes.StatListNode(pos=node.pos, stats=[node]) else: return node def visit_StatListNode(self, node): self.is_in_statlist = True self.visitchildren(node) self.is_in_statlist = False return node def visit_ParallelAssignmentNode(self, node): return self.visit_StatNode(node, True) def visit_CEnumDefNode(self, node): return self.visit_StatNode(node, True) def visit_CStructOrUnionDefNode(self, node): return self.visit_StatNode(node, True) def visit_PassStatNode(self, node): """Eliminate PassStatNode""" if not self.is_in_statlist: return Nodes.StatListNode(pos=node.pos, stats=[]) else: return [] def visit_ExprStatNode(self, node): """Eliminate useless string literals""" if node.expr.is_string_literal: return self.visit_PassStatNode(node) else: return self.visit_StatNode(node) def visit_CDeclaratorNode(self, node): return node class PostParseError(CompileError): pass # error strings checked by unit tests, so define them ERR_CDEF_INCLASS = 'Cannot assign default value to fields in cdef classes, structs or unions' ERR_BUF_DEFAULTS = 'Invalid buffer defaults specification (see docs)' ERR_INVALID_SPECIALATTR_TYPE = 'Special attributes must not have a type declared' class PostParse(ScopeTrackingTransform): """ Basic interpretation of the parse tree, as well as validity checking that can be done on a very basic level on the parse tree (while still not being a problem with the basic syntax, as such). Specifically: - Default values to cdef assignments are turned into single assignments following the declaration (everywhere but in class bodies, where they raise a compile error) - Interpret some node structures into Python runtime values. Some nodes take compile-time arguments (currently: TemplatedTypeNode[args] and __cythonbufferdefaults__ = {args}), which should be interpreted. This happens in a general way and other steps should be taken to ensure validity. Type arguments cannot be interpreted in this way. - For __cythonbufferdefaults__ the arguments are checked for validity. TemplatedTypeNode has its directives interpreted: Any first positional argument goes into the "dtype" attribute, any "ndim" keyword argument goes into the "ndim" attribute and so on. Also it is checked that the directive combination is valid. - __cythonbufferdefaults__ attributes are parsed and put into the type information. Note: Currently Parsing.py does a lot of interpretation and reorganization that can be refactored into this transform if a more pure Abstract Syntax Tree is wanted. """ def __init__(self, context): super(PostParse, self).__init__(context) self.specialattribute_handlers = { '__cythonbufferdefaults__' : self.handle_bufferdefaults } def visit_LambdaNode(self, node): # unpack a lambda expression into the corresponding DefNode collector = YieldNodeCollector() collector.visitchildren(node.result_expr) if collector.yields or collector.awaits or isinstance(node.result_expr, ExprNodes.YieldExprNode): body = Nodes.ExprStatNode( node.result_expr.pos, expr=node.result_expr) else: body = Nodes.ReturnStatNode( node.result_expr.pos, value=node.result_expr) node.def_node = Nodes.DefNode( node.pos, name=node.name, args=node.args, star_arg=node.star_arg, starstar_arg=node.starstar_arg, body=body, doc=None) self.visitchildren(node) return node def visit_GeneratorExpressionNode(self, node): # unpack a generator expression into the corresponding DefNode node.def_node = Nodes.DefNode(node.pos, name=node.name, doc=None, args=[], star_arg=None, starstar_arg=None, body=node.loop) self.visitchildren(node) return node # cdef variables def handle_bufferdefaults(self, decl): if not isinstance(decl.default, ExprNodes.DictNode): raise PostParseError(decl.pos, ERR_BUF_DEFAULTS) self.scope_node.buffer_defaults_node = decl.default self.scope_node.buffer_defaults_pos = decl.pos def visit_CVarDefNode(self, node): # This assumes only plain names and pointers are assignable on # declaration. Also, it makes use of the fact that a cdef decl # must appear before the first use, so we don't have to deal with # "i = 3; cdef int i = i" and can simply move the nodes around. try: self.visitchildren(node) stats = [node] newdecls = [] for decl in node.declarators: declbase = decl while isinstance(declbase, Nodes.CPtrDeclaratorNode): declbase = declbase.base if isinstance(declbase, Nodes.CNameDeclaratorNode): if declbase.default is not None: if self.scope_type in ('cclass', 'pyclass', 'struct'): if isinstance(self.scope_node, Nodes.CClassDefNode): handler = self.specialattribute_handlers.get(decl.name) if handler: if decl is not declbase: raise PostParseError(decl.pos, ERR_INVALID_SPECIALATTR_TYPE) handler(decl) continue # Remove declaration raise PostParseError(decl.pos, ERR_CDEF_INCLASS) first_assignment = self.scope_type != 'module' stats.append(Nodes.SingleAssignmentNode(node.pos, lhs=ExprNodes.NameNode(node.pos, name=declbase.name), rhs=declbase.default, first=first_assignment)) declbase.default = None newdecls.append(decl) node.declarators = newdecls return stats except PostParseError as e: # An error in a cdef clause is ok, simply remove the declaration # and try to move on to report more errors self.context.nonfatal_error(e) return None # Split parallel assignments (a,b = b,a) into separate partial # assignments that are executed rhs-first using temps. This # restructuring must be applied before type analysis so that known # types on rhs and lhs can be matched directly. It is required in # the case that the types cannot be coerced to a Python type in # order to assign from a tuple. def visit_SingleAssignmentNode(self, node): self.visitchildren(node) return self._visit_assignment_node(node, [node.lhs, node.rhs]) def visit_CascadedAssignmentNode(self, node): self.visitchildren(node) return self._visit_assignment_node(node, node.lhs_list + [node.rhs]) def _visit_assignment_node(self, node, expr_list): """Flatten parallel assignments into separate single assignments or cascaded assignments. """ if sum([ 1 for expr in expr_list if expr.is_sequence_constructor or expr.is_string_literal ]) < 2: # no parallel assignments => nothing to do return node expr_list_list = [] flatten_parallel_assignments(expr_list, expr_list_list) temp_refs = [] eliminate_rhs_duplicates(expr_list_list, temp_refs) nodes = [] for expr_list in expr_list_list: lhs_list = expr_list[:-1] rhs = expr_list[-1] if len(lhs_list) == 1: node = Nodes.SingleAssignmentNode(rhs.pos, lhs = lhs_list[0], rhs = rhs) else: node = Nodes.CascadedAssignmentNode(rhs.pos, lhs_list = lhs_list, rhs = rhs) nodes.append(node) if len(nodes) == 1: assign_node = nodes[0] else: assign_node = Nodes.ParallelAssignmentNode(nodes[0].pos, stats = nodes) if temp_refs: duplicates_and_temps = [ (temp.expression, temp) for temp in temp_refs ] sort_common_subsequences(duplicates_and_temps) for _, temp_ref in duplicates_and_temps[::-1]: assign_node = LetNode(temp_ref, assign_node) return assign_node def _flatten_sequence(self, seq, result): for arg in seq.args: if arg.is_sequence_constructor: self._flatten_sequence(arg, result) else: result.append(arg) return result def visit_DelStatNode(self, node): self.visitchildren(node) node.args = self._flatten_sequence(node, []) return node def visit_ExceptClauseNode(self, node): if node.is_except_as: # except-as must delete NameNode target at the end del_target = Nodes.DelStatNode( node.pos, args=[ExprNodes.NameNode( node.target.pos, name=node.target.name)], ignore_nonexisting=True) node.body = Nodes.StatListNode( node.pos, stats=[Nodes.TryFinallyStatNode( node.pos, body=node.body, finally_clause=Nodes.StatListNode( node.pos, stats=[del_target]))]) self.visitchildren(node) return node def eliminate_rhs_duplicates(expr_list_list, ref_node_sequence): """Replace rhs items by LetRefNodes if they appear more than once. Creates a sequence of LetRefNodes that set up the required temps and appends them to ref_node_sequence. The input list is modified in-place. """ seen_nodes = set() ref_nodes = {} def find_duplicates(node): if node.is_literal or node.is_name: # no need to replace those; can't include attributes here # as their access is not necessarily side-effect free return if node in seen_nodes: if node not in ref_nodes: ref_node = LetRefNode(node) ref_nodes[node] = ref_node ref_node_sequence.append(ref_node) else: seen_nodes.add(node) if node.is_sequence_constructor: for item in node.args: find_duplicates(item) for expr_list in expr_list_list: rhs = expr_list[-1] find_duplicates(rhs) if not ref_nodes: return def substitute_nodes(node): if node in ref_nodes: return ref_nodes[node] elif node.is_sequence_constructor: node.args = list(map(substitute_nodes, node.args)) return node # replace nodes inside of the common subexpressions for node in ref_nodes: if node.is_sequence_constructor: node.args = list(map(substitute_nodes, node.args)) # replace common subexpressions on all rhs items for expr_list in expr_list_list: expr_list[-1] = substitute_nodes(expr_list[-1]) def sort_common_subsequences(items): """Sort items/subsequences so that all items and subsequences that an item contains appear before the item itself. This is needed because each rhs item must only be evaluated once, so its value must be evaluated first and then reused when packing sequences that contain it. This implies a partial order, and the sort must be stable to preserve the original order as much as possible, so we use a simple insertion sort (which is very fast for short sequences, the normal case in practice). """ def contains(seq, x): for item in seq: if item is x: return True elif item.is_sequence_constructor and contains(item.args, x): return True return False def lower_than(a,b): return b.is_sequence_constructor and contains(b.args, a) for pos, item in enumerate(items): key = item[1] # the ResultRefNode which has already been injected into the sequences new_pos = pos for i in range(pos-1, -1, -1): if lower_than(key, items[i][0]): new_pos = i if new_pos != pos: for i in range(pos, new_pos, -1): items[i] = items[i-1] items[new_pos] = item def unpack_string_to_character_literals(literal): chars = [] pos = literal.pos stype = literal.__class__ sval = literal.value sval_type = sval.__class__ for char in sval: cval = sval_type(char) chars.append(stype(pos, value=cval, constant_result=cval)) return chars def flatten_parallel_assignments(input, output): # The input is a list of expression nodes, representing the LHSs # and RHS of one (possibly cascaded) assignment statement. For # sequence constructors, rearranges the matching parts of both # sides into a list of equivalent assignments between the # individual elements. This transformation is applied # recursively, so that nested structures get matched as well. rhs = input[-1] if (not (rhs.is_sequence_constructor or isinstance(rhs, ExprNodes.UnicodeNode)) or not sum([lhs.is_sequence_constructor for lhs in input[:-1]])): output.append(input) return complete_assignments = [] if rhs.is_sequence_constructor: rhs_args = rhs.args elif rhs.is_string_literal: rhs_args = unpack_string_to_character_literals(rhs) rhs_size = len(rhs_args) lhs_targets = [[] for _ in range(rhs_size)] starred_assignments = [] for lhs in input[:-1]: if not lhs.is_sequence_constructor: if lhs.is_starred: error(lhs.pos, "starred assignment target must be in a list or tuple") complete_assignments.append(lhs) continue lhs_size = len(lhs.args) starred_targets = sum([1 for expr in lhs.args if expr.is_starred]) if starred_targets > 1: error(lhs.pos, "more than 1 starred expression in assignment") output.append([lhs,rhs]) continue elif lhs_size - starred_targets > rhs_size: error(lhs.pos, "need more than %d value%s to unpack" % (rhs_size, (rhs_size != 1) and 's' or '')) output.append([lhs,rhs]) continue elif starred_targets: map_starred_assignment(lhs_targets, starred_assignments, lhs.args, rhs_args) elif lhs_size < rhs_size: error(lhs.pos, "too many values to unpack (expected %d, got %d)" % (lhs_size, rhs_size)) output.append([lhs,rhs]) continue else: for targets, expr in zip(lhs_targets, lhs.args): targets.append(expr) if complete_assignments: complete_assignments.append(rhs) output.append(complete_assignments) # recursively flatten partial assignments for cascade, rhs in zip(lhs_targets, rhs_args): if cascade: cascade.append(rhs) flatten_parallel_assignments(cascade, output) # recursively flatten starred assignments for cascade in starred_assignments: if cascade[0].is_sequence_constructor: flatten_parallel_assignments(cascade, output) else: output.append(cascade) def map_starred_assignment(lhs_targets, starred_assignments, lhs_args, rhs_args): # Appends the fixed-position LHS targets to the target list that # appear left and right of the starred argument. # # The starred_assignments list receives a new tuple # (lhs_target, rhs_values_list) that maps the remaining arguments # (those that match the starred target) to a list. # left side of the starred target for i, (targets, expr) in enumerate(zip(lhs_targets, lhs_args)): if expr.is_starred: starred = i lhs_remaining = len(lhs_args) - i - 1 break targets.append(expr) else: raise InternalError("no starred arg found when splitting starred assignment") # right side of the starred target for i, (targets, expr) in enumerate(zip(lhs_targets[-lhs_remaining:], lhs_args[starred + 1:])): targets.append(expr) # the starred target itself, must be assigned a (potentially empty) list target = lhs_args[starred].target # unpack starred node starred_rhs = rhs_args[starred:] if lhs_remaining: starred_rhs = starred_rhs[:-lhs_remaining] if starred_rhs: pos = starred_rhs[0].pos else: pos = target.pos starred_assignments.append([ target, ExprNodes.ListNode(pos=pos, args=starred_rhs)]) class PxdPostParse(CythonTransform, SkipDeclarations): """ Basic interpretation/validity checking that should only be done on pxd trees. A lot of this checking currently happens in the parser; but what is listed below happens here. - "def" functions are let through only if they fill the getbuffer/releasebuffer slots - cdef functions are let through only if they are on the top level and are declared "inline" """ ERR_INLINE_ONLY = "function definition in pxd file must be declared 'cdef inline'" ERR_NOGO_WITH_INLINE = "inline function definition in pxd file cannot be '%s'" def __call__(self, node): self.scope_type = 'pxd' return super(PxdPostParse, self).__call__(node) def visit_CClassDefNode(self, node): old = self.scope_type self.scope_type = 'cclass' self.visitchildren(node) self.scope_type = old return node def visit_FuncDefNode(self, node): # FuncDefNode always come with an implementation (without # an imp they are CVarDefNodes..) err = self.ERR_INLINE_ONLY if (isinstance(node, Nodes.DefNode) and self.scope_type == 'cclass' and node.name in ('__getbuffer__', '__releasebuffer__')): err = None # allow these slots if isinstance(node, Nodes.CFuncDefNode): if (u'inline' in node.modifiers and self.scope_type in ('pxd', 'cclass')): node.inline_in_pxd = True if node.visibility != 'private': err = self.ERR_NOGO_WITH_INLINE % node.visibility elif node.api: err = self.ERR_NOGO_WITH_INLINE % 'api' else: err = None # allow inline function else: err = self.ERR_INLINE_ONLY if err: self.context.nonfatal_error(PostParseError(node.pos, err)) return None else: return node class InterpretCompilerDirectives(CythonTransform, SkipDeclarations): """ After parsing, directives can be stored in a number of places: - #cython-comments at the top of the file (stored in ModuleNode) - Command-line arguments overriding these - @cython.directivename decorators - with cython.directivename: statements This transform is responsible for interpreting these various sources and store the directive in two ways: - Set the directives attribute of the ModuleNode for global directives. - Use a CompilerDirectivesNode to override directives for a subtree. (The first one is primarily to not have to modify with the tree structure, so that ModuleNode stay on top.) The directives are stored in dictionaries from name to value in effect. Each such dictionary is always filled in for all possible directives, using default values where no value is given by the user. The available directives are controlled in Options.py. Note that we have to run this prior to analysis, and so some minor duplication of functionality has to occur: We manually track cimports and which names the "cython" module may have been imported to. """ unop_method_nodes = { 'typeof': ExprNodes.TypeofNode, 'operator.address': ExprNodes.AmpersandNode, 'operator.dereference': ExprNodes.DereferenceNode, 'operator.preincrement' : ExprNodes.inc_dec_constructor(True, '++'), 'operator.predecrement' : ExprNodes.inc_dec_constructor(True, '--'), 'operator.postincrement': ExprNodes.inc_dec_constructor(False, '++'), 'operator.postdecrement': ExprNodes.inc_dec_constructor(False, '--'), # For backwards compatability. 'address': ExprNodes.AmpersandNode, } binop_method_nodes = { 'operator.comma' : ExprNodes.c_binop_constructor(','), } special_methods = set(['declare', 'union', 'struct', 'typedef', 'sizeof', 'cast', 'pointer', 'compiled', 'NULL', 'fused_type', 'parallel']) special_methods.update(unop_method_nodes) valid_parallel_directives = set([ "parallel", "prange", "threadid", #"threadsavailable", ]) def __init__(self, context, compilation_directive_defaults): super(InterpretCompilerDirectives, self).__init__(context) self.cython_module_names = set() self.directive_names = {'staticmethod': 'staticmethod'} self.parallel_directives = {} directives = copy.deepcopy(Options.directive_defaults) for key, value in compilation_directive_defaults.items(): directives[_unicode(key)] = copy.deepcopy(value) self.directives = directives def check_directive_scope(self, pos, directive, scope): legal_scopes = Options.directive_scopes.get(directive, None) if legal_scopes and scope not in legal_scopes: self.context.nonfatal_error(PostParseError(pos, 'The %s compiler directive ' 'is not allowed in %s scope' % (directive, scope))) return False else: if (directive not in Options.directive_defaults and directive not in Options.directive_types): error(pos, "Invalid directive: '%s'." % (directive,)) return True # Set up processing and handle the cython: comments. def visit_ModuleNode(self, node): for key in sorted(node.directive_comments): if not self.check_directive_scope(node.pos, key, 'module'): self.wrong_scope_error(node.pos, key, 'module') del node.directive_comments[key] self.module_scope = node.scope self.directives.update(node.directive_comments) node.directives = self.directives node.parallel_directives = self.parallel_directives self.visitchildren(node) node.cython_module_names = self.cython_module_names return node # The following four functions track imports and cimports that # begin with "cython" def is_cython_directive(self, name): return (name in Options.directive_types or name in self.special_methods or PyrexTypes.parse_basic_type(name)) def is_parallel_directive(self, full_name, pos): """ Checks to see if fullname (e.g. cython.parallel.prange) is a valid parallel directive. If it is a star import it also updates the parallel_directives. """ result = (full_name + ".").startswith("cython.parallel.") if result: directive = full_name.split('.') if full_name == u"cython.parallel": self.parallel_directives[u"parallel"] = u"cython.parallel" elif full_name == u"cython.parallel.*": for name in self.valid_parallel_directives: self.parallel_directives[name] = u"cython.parallel.%s" % name elif (len(directive) != 3 or directive[-1] not in self.valid_parallel_directives): error(pos, "No such directive: %s" % full_name) self.module_scope.use_utility_code( UtilityCode.load_cached("InitThreads", "ModuleSetupCode.c")) return result def visit_CImportStatNode(self, node): if node.module_name == u"cython": self.cython_module_names.add(node.as_name or u"cython") elif node.module_name.startswith(u"cython."): if node.module_name.startswith(u"cython.parallel."): error(node.pos, node.module_name + " is not a module") if node.module_name == u"cython.parallel": if node.as_name and node.as_name != u"cython": self.parallel_directives[node.as_name] = node.module_name else: self.cython_module_names.add(u"cython") self.parallel_directives[ u"cython.parallel"] = node.module_name self.module_scope.use_utility_code( UtilityCode.load_cached("InitThreads", "ModuleSetupCode.c")) elif node.as_name: self.directive_names[node.as_name] = node.module_name[7:] else: self.cython_module_names.add(u"cython") # if this cimport was a compiler directive, we don't # want to leave the cimport node sitting in the tree return None return node def visit_FromCImportStatNode(self, node): if not node.relative_level and ( node.module_name == u"cython" or node.module_name.startswith(u"cython.")): submodule = (node.module_name + u".")[7:] newimp = [] for pos, name, as_name, kind in node.imported_names: full_name = submodule + name qualified_name = u"cython." + full_name if self.is_parallel_directive(qualified_name, node.pos): # from cython cimport parallel, or # from cython.parallel cimport parallel, prange, ... self.parallel_directives[as_name or name] = qualified_name elif self.is_cython_directive(full_name): self.directive_names[as_name or name] = full_name if kind is not None: self.context.nonfatal_error(PostParseError(pos, "Compiler directive imports must be plain imports")) else: newimp.append((pos, name, as_name, kind)) if not newimp: return None node.imported_names = newimp return node def visit_FromImportStatNode(self, node): if (node.module.module_name.value == u"cython") or \ node.module.module_name.value.startswith(u"cython."): submodule = (node.module.module_name.value + u".")[7:] newimp = [] for name, name_node in node.items: full_name = submodule + name qualified_name = u"cython." + full_name if self.is_parallel_directive(qualified_name, node.pos): self.parallel_directives[name_node.name] = qualified_name elif self.is_cython_directive(full_name): self.directive_names[name_node.name] = full_name else: newimp.append((name, name_node)) if not newimp: return None node.items = newimp return node def visit_SingleAssignmentNode(self, node): if isinstance(node.rhs, ExprNodes.ImportNode): module_name = node.rhs.module_name.value is_parallel = (module_name + u".").startswith(u"cython.parallel.") if module_name != u"cython" and not is_parallel: return node module_name = node.rhs.module_name.value as_name = node.lhs.name node = Nodes.CImportStatNode(node.pos, module_name = module_name, as_name = as_name) node = self.visit_CImportStatNode(node) else: self.visitchildren(node) return node def visit_NameNode(self, node): if node.name in self.cython_module_names: node.is_cython_module = True else: node.cython_attribute = self.directive_names.get(node.name) return node def try_to_parse_directives(self, node): # If node is the contents of an directive (in a with statement or # decorator), returns a list of (directivename, value) pairs. # Otherwise, returns None if isinstance(node, ExprNodes.CallNode): self.visit(node.function) optname = node.function.as_cython_attribute() if optname: directivetype = Options.directive_types.get(optname) if directivetype: args, kwds = node.explicit_args_kwds() directives = [] key_value_pairs = [] if kwds is not None and directivetype is not dict: for keyvalue in kwds.key_value_pairs: key, value = keyvalue sub_optname = "%s.%s" % (optname, key.value) if Options.directive_types.get(sub_optname): directives.append(self.try_to_parse_directive(sub_optname, [value], None, keyvalue.pos)) else: key_value_pairs.append(keyvalue) if not key_value_pairs: kwds = None else: kwds.key_value_pairs = key_value_pairs if directives and not kwds and not args: return directives directives.append(self.try_to_parse_directive(optname, args, kwds, node.function.pos)) return directives elif isinstance(node, (ExprNodes.AttributeNode, ExprNodes.NameNode)): self.visit(node) optname = node.as_cython_attribute() if optname: directivetype = Options.directive_types.get(optname) if directivetype is bool: return [(optname, True)] elif directivetype is None: return [(optname, None)] else: raise PostParseError( node.pos, "The '%s' directive should be used as a function call." % optname) return None def try_to_parse_directive(self, optname, args, kwds, pos): directivetype = Options.directive_types.get(optname) if len(args) == 1 and isinstance(args[0], ExprNodes.NoneNode): return optname, Options.directive_defaults[optname] elif directivetype is bool: if kwds is not None or len(args) != 1 or not isinstance(args[0], ExprNodes.BoolNode): raise PostParseError(pos, 'The %s directive takes one compile-time boolean argument' % optname) return (optname, args[0].value) elif directivetype is int: if kwds is not None or len(args) != 1 or not isinstance(args[0], ExprNodes.IntNode): raise PostParseError(pos, 'The %s directive takes one compile-time integer argument' % optname) return (optname, int(args[0].value)) elif directivetype is str: if kwds is not None or len(args) != 1 or not isinstance( args[0], (ExprNodes.StringNode, ExprNodes.UnicodeNode)): raise PostParseError(pos, 'The %s directive takes one compile-time string argument' % optname) return (optname, str(args[0].value)) elif directivetype is type: if kwds is not None or len(args) != 1: raise PostParseError(pos, 'The %s directive takes one type argument' % optname) return (optname, args[0]) elif directivetype is dict: if len(args) != 0: raise PostParseError(pos, 'The %s directive takes no prepositional arguments' % optname) return optname, dict([(key.value, value) for key, value in kwds.key_value_pairs]) elif directivetype is list: if kwds and len(kwds) != 0: raise PostParseError(pos, 'The %s directive takes no keyword arguments' % optname) return optname, [ str(arg.value) for arg in args ] elif callable(directivetype): if kwds is not None or len(args) != 1 or not isinstance( args[0], (ExprNodes.StringNode, ExprNodes.UnicodeNode)): raise PostParseError(pos, 'The %s directive takes one compile-time string argument' % optname) return (optname, directivetype(optname, str(args[0].value))) else: assert False def visit_with_directives(self, body, directives): olddirectives = self.directives newdirectives = copy.copy(olddirectives) newdirectives.update(directives) self.directives = newdirectives assert isinstance(body, Nodes.StatListNode), body retbody = self.visit_Node(body) directive = Nodes.CompilerDirectivesNode(pos=retbody.pos, body=retbody, directives=newdirectives) self.directives = olddirectives return directive # Handle decorators def visit_FuncDefNode(self, node): directives = self._extract_directives(node, 'function') if not directives: return self.visit_Node(node) body = Nodes.StatListNode(node.pos, stats=[node]) return self.visit_with_directives(body, directives) def visit_CVarDefNode(self, node): directives = self._extract_directives(node, 'function') if not directives: return node for name, value in directives.items(): if name == 'locals': node.directive_locals = value elif name not in ('final', 'staticmethod'): self.context.nonfatal_error(PostParseError( node.pos, "Cdef functions can only take cython.locals(), " "staticmethod, or final decorators, got %s." % name)) body = Nodes.StatListNode(node.pos, stats=[node]) return self.visit_with_directives(body, directives) def visit_CClassDefNode(self, node): directives = self._extract_directives(node, 'cclass') if not directives: return self.visit_Node(node) body = Nodes.StatListNode(node.pos, stats=[node]) return self.visit_with_directives(body, directives) def visit_CppClassNode(self, node): directives = self._extract_directives(node, 'cppclass') if not directives: return self.visit_Node(node) body = Nodes.StatListNode(node.pos, stats=[node]) return self.visit_with_directives(body, directives) def visit_PyClassDefNode(self, node): directives = self._extract_directives(node, 'class') if not directives: return self.visit_Node(node) body = Nodes.StatListNode(node.pos, stats=[node]) return self.visit_with_directives(body, directives) def _extract_directives(self, node, scope_name): if not node.decorators: return {} # Split the decorators into two lists -- real decorators and directives directives = [] realdecs = [] both = [] for dec in node.decorators: new_directives = self.try_to_parse_directives(dec.decorator) if new_directives is not None: for directive in new_directives: if self.check_directive_scope(node.pos, directive[0], scope_name): name, value = directive if self.directives.get(name, object()) != value: directives.append(directive) if directive[0] == 'staticmethod': both.append(dec) else: realdecs.append(dec) if realdecs and isinstance(node, (Nodes.CFuncDefNode, Nodes.CClassDefNode, Nodes.CVarDefNode)): raise PostParseError(realdecs[0].pos, "Cdef functions/classes cannot take arbitrary decorators.") else: node.decorators = realdecs + both # merge or override repeated directives optdict = {} directives.reverse() # Decorators coming first take precedence for directive in directives: name, value = directive if name in optdict: old_value = optdict[name] # keywords and arg lists can be merged, everything # else overrides completely if isinstance(old_value, dict): old_value.update(value) elif isinstance(old_value, list): old_value.extend(value) else: optdict[name] = value else: optdict[name] = value return optdict # Handle with statements def visit_WithStatNode(self, node): directive_dict = {} for directive in self.try_to_parse_directives(node.manager) or []: if directive is not None: if node.target is not None: self.context.nonfatal_error( PostParseError(node.pos, "Compiler directive with statements cannot contain 'as'")) else: name, value = directive if name in ('nogil', 'gil'): # special case: in pure mode, "with nogil" spells "with cython.nogil" node = Nodes.GILStatNode(node.pos, state = name, body = node.body) return self.visit_Node(node) if self.check_directive_scope(node.pos, name, 'with statement'): directive_dict[name] = value if directive_dict: return self.visit_with_directives(node.body, directive_dict) return self.visit_Node(node) class ParallelRangeTransform(CythonTransform, SkipDeclarations): """ Transform cython.parallel stuff. The parallel_directives come from the module node, set there by InterpretCompilerDirectives. x = cython.parallel.threadavailable() -> ParallelThreadAvailableNode with nogil, cython.parallel.parallel(): -> ParallelWithBlockNode print cython.parallel.threadid() -> ParallelThreadIdNode for i in cython.parallel.prange(...): -> ParallelRangeNode ... """ # a list of names, maps 'cython.parallel.prange' in the code to # ['cython', 'parallel', 'prange'] parallel_directive = None # Indicates whether a namenode in an expression is the cython module namenode_is_cython_module = False # Keep track of whether we are the context manager of a 'with' statement in_context_manager_section = False # One of 'prange' or 'with parallel'. This is used to disallow closely # nested 'with parallel:' blocks state = None directive_to_node = { u"cython.parallel.parallel": Nodes.ParallelWithBlockNode, # u"cython.parallel.threadsavailable": ExprNodes.ParallelThreadsAvailableNode, u"cython.parallel.threadid": ExprNodes.ParallelThreadIdNode, u"cython.parallel.prange": Nodes.ParallelRangeNode, } def node_is_parallel_directive(self, node): return node.name in self.parallel_directives or node.is_cython_module def get_directive_class_node(self, node): """ Figure out which parallel directive was used and return the associated Node class. E.g. for a cython.parallel.prange() call we return ParallelRangeNode """ if self.namenode_is_cython_module: directive = '.'.join(self.parallel_directive) else: directive = self.parallel_directives[self.parallel_directive[0]] directive = '%s.%s' % (directive, '.'.join(self.parallel_directive[1:])) directive = directive.rstrip('.') cls = self.directive_to_node.get(directive) if cls is None and not (self.namenode_is_cython_module and self.parallel_directive[0] != 'parallel'): error(node.pos, "Invalid directive: %s" % directive) self.namenode_is_cython_module = False self.parallel_directive = None return cls def visit_ModuleNode(self, node): """ If any parallel directives were imported, copy them over and visit the AST """ if node.parallel_directives: self.parallel_directives = node.parallel_directives return self.visit_Node(node) # No parallel directives were imported, so they can't be used :) return node def visit_NameNode(self, node): if self.node_is_parallel_directive(node): self.parallel_directive = [node.name] self.namenode_is_cython_module = node.is_cython_module return node def visit_AttributeNode(self, node): self.visitchildren(node) if self.parallel_directive: self.parallel_directive.append(node.attribute) return node def visit_CallNode(self, node): self.visit(node.function) if not self.parallel_directive: return node # We are a parallel directive, replace this node with the # corresponding ParallelSomethingSomething node if isinstance(node, ExprNodes.GeneralCallNode): args = node.positional_args.args kwargs = node.keyword_args else: args = node.args kwargs = {} parallel_directive_class = self.get_directive_class_node(node) if parallel_directive_class: # Note: in case of a parallel() the body is set by # visit_WithStatNode node = parallel_directive_class(node.pos, args=args, kwargs=kwargs) return node def visit_WithStatNode(self, node): "Rewrite with cython.parallel.parallel() blocks" newnode = self.visit(node.manager) if isinstance(newnode, Nodes.ParallelWithBlockNode): if self.state == 'parallel with': error(node.manager.pos, "Nested parallel with blocks are disallowed") self.state = 'parallel with' body = self.visit(node.body) self.state = None newnode.body = body return newnode elif self.parallel_directive: parallel_directive_class = self.get_directive_class_node(node) if not parallel_directive_class: # There was an error, stop here and now return None if parallel_directive_class is Nodes.ParallelWithBlockNode: error(node.pos, "The parallel directive must be called") return None node.body = self.visit(node.body) return node def visit_ForInStatNode(self, node): "Rewrite 'for i in cython.parallel.prange(...):'" self.visit(node.iterator) self.visit(node.target) in_prange = isinstance(node.iterator.sequence, Nodes.ParallelRangeNode) previous_state = self.state if in_prange: # This will replace the entire ForInStatNode, so copy the # attributes parallel_range_node = node.iterator.sequence parallel_range_node.target = node.target parallel_range_node.body = node.body parallel_range_node.else_clause = node.else_clause node = parallel_range_node if not isinstance(node.target, ExprNodes.NameNode): error(node.target.pos, "Can only iterate over an iteration variable") self.state = 'prange' self.visit(node.body) self.state = previous_state self.visit(node.else_clause) return node def visit(self, node): "Visit a node that may be None" if node is not None: return super(ParallelRangeTransform, self).visit(node) class WithTransform(CythonTransform, SkipDeclarations): def visit_WithStatNode(self, node): self.visitchildren(node, 'body') pos = node.pos is_async = node.is_async body, target, manager = node.body, node.target, node.manager node.enter_call = ExprNodes.SimpleCallNode( pos, function=ExprNodes.AttributeNode( pos, obj=ExprNodes.CloneNode(manager), attribute=EncodedString('__aenter__' if is_async else '__enter__'), is_special_lookup=True), args=[], is_temp=True) if is_async: node.enter_call = ExprNodes.AwaitExprNode(pos, arg=node.enter_call) if target is not None: body = Nodes.StatListNode( pos, stats=[ Nodes.WithTargetAssignmentStatNode( pos, lhs=target, with_node=node), body]) excinfo_target = ExprNodes.TupleNode(pos, slow=True, args=[ ExprNodes.ExcValueNode(pos) for _ in range(3)]) except_clause = Nodes.ExceptClauseNode( pos, body=Nodes.IfStatNode( pos, if_clauses=[ Nodes.IfClauseNode( pos, condition=ExprNodes.NotNode( pos, operand=ExprNodes.WithExitCallNode( pos, with_stat=node, test_if_run=False, args=excinfo_target, await=ExprNodes.AwaitExprNode(pos, arg=None) if is_async else None)), body=Nodes.ReraiseStatNode(pos), ), ], else_clause=None), pattern=None, target=None, excinfo_target=excinfo_target, ) node.body = Nodes.TryFinallyStatNode( pos, body=Nodes.TryExceptStatNode( pos, body=body, except_clauses=[except_clause], else_clause=None, ), finally_clause=Nodes.ExprStatNode( pos, expr=ExprNodes.WithExitCallNode( pos, with_stat=node, test_if_run=True, args=ExprNodes.TupleNode( pos, args=[ExprNodes.NoneNode(pos) for _ in range(3)]), await=ExprNodes.AwaitExprNode(pos, arg=None) if is_async else None)), handle_error_case=False, ) return node def visit_ExprNode(self, node): # With statements are never inside expressions. return node class DecoratorTransform(ScopeTrackingTransform, SkipDeclarations): """Originally, this was the only place where decorators were transformed into the corresponding calling code. Now, this is done directly in DefNode and PyClassDefNode to avoid reassignments to the function/class name - except for cdef class methods. For those, the reassignment is required as methods are originally defined in the PyMethodDef struct. The IndirectionNode allows DefNode to override the decorator """ def visit_DefNode(self, func_node): scope_type = self.scope_type func_node = self.visit_FuncDefNode(func_node) if scope_type != 'cclass' or not func_node.decorators: return func_node return self.handle_decorators(func_node, func_node.decorators, func_node.name) def handle_decorators(self, node, decorators, name): decorator_result = ExprNodes.NameNode(node.pos, name = name) for decorator in decorators[::-1]: decorator_result = ExprNodes.SimpleCallNode( decorator.pos, function = decorator.decorator, args = [decorator_result]) name_node = ExprNodes.NameNode(node.pos, name = name) reassignment = Nodes.SingleAssignmentNode( node.pos, lhs = name_node, rhs = decorator_result) reassignment = Nodes.IndirectionNode([reassignment]) node.decorator_indirection = reassignment return [node, reassignment] class CnameDirectivesTransform(CythonTransform, SkipDeclarations): """ Only part of the CythonUtilityCode pipeline. Must be run before DecoratorTransform in case this is a decorator for a cdef class. It filters out @cname('my_cname') decorators and rewrites them to CnameDecoratorNodes. """ def handle_function(self, node): if not getattr(node, 'decorators', None): return self.visit_Node(node) for i, decorator in enumerate(node.decorators): decorator = decorator.decorator if (isinstance(decorator, ExprNodes.CallNode) and decorator.function.is_name and decorator.function.name == 'cname'): args, kwargs = decorator.explicit_args_kwds() if kwargs: raise AssertionError( "cname decorator does not take keyword arguments") if len(args) != 1: raise AssertionError( "cname decorator takes exactly one argument") if not (args[0].is_literal and args[0].type == Builtin.str_type): raise AssertionError( "argument to cname decorator must be a string literal") cname = args[0].compile_time_value(None).decode('UTF-8') del node.decorators[i] node = Nodes.CnameDecoratorNode(pos=node.pos, node=node, cname=cname) break return self.visit_Node(node) visit_FuncDefNode = handle_function visit_CClassDefNode = handle_function visit_CEnumDefNode = handle_function visit_CStructOrUnionDefNode = handle_function class ForwardDeclareTypes(CythonTransform): def visit_CompilerDirectivesNode(self, node): env = self.module_scope old = env.directives env.directives = node.directives self.visitchildren(node) env.directives = old return node def visit_ModuleNode(self, node): self.module_scope = node.scope self.module_scope.directives = node.directives self.visitchildren(node) return node def visit_CDefExternNode(self, node): old_cinclude_flag = self.module_scope.in_cinclude self.module_scope.in_cinclude = 1 self.visitchildren(node) self.module_scope.in_cinclude = old_cinclude_flag return node def visit_CEnumDefNode(self, node): node.declare(self.module_scope) return node def visit_CStructOrUnionDefNode(self, node): if node.name not in self.module_scope.entries: node.declare(self.module_scope) return node def visit_CClassDefNode(self, node): if node.class_name not in self.module_scope.entries: node.declare(self.module_scope) return node class AnalyseDeclarationsTransform(EnvTransform): basic_property = TreeFragment(u""" property NAME: def __get__(self): return ATTR def __set__(self, value): ATTR = value """, level='c_class', pipeline=[NormalizeTree(None)]) basic_pyobject_property = TreeFragment(u""" property NAME: def __get__(self): return ATTR def __set__(self, value): ATTR = value def __del__(self): ATTR = None """, level='c_class', pipeline=[NormalizeTree(None)]) basic_property_ro = TreeFragment(u""" property NAME: def __get__(self): return ATTR """, level='c_class', pipeline=[NormalizeTree(None)]) struct_or_union_wrapper = TreeFragment(u""" cdef class NAME: cdef TYPE value def __init__(self, MEMBER=None): cdef int count count = 0 INIT_ASSIGNMENTS if IS_UNION and count > 1: raise ValueError, "At most one union member should be specified." def __str__(self): return STR_FORMAT % MEMBER_TUPLE def __repr__(self): return REPR_FORMAT % MEMBER_TUPLE """, pipeline=[NormalizeTree(None)]) init_assignment = TreeFragment(u""" if VALUE is not None: ATTR = VALUE count += 1 """, pipeline=[NormalizeTree(None)]) fused_function = None in_lambda = 0 def __call__(self, root): # needed to determine if a cdef var is declared after it's used. self.seen_vars_stack = [] self.fused_error_funcs = set() super_class = super(AnalyseDeclarationsTransform, self) self._super_visit_FuncDefNode = super_class.visit_FuncDefNode return super_class.__call__(root) def visit_NameNode(self, node): self.seen_vars_stack[-1].add(node.name) return node def visit_ModuleNode(self, node): self.seen_vars_stack.append(set()) node.analyse_declarations(self.current_env()) self.visitchildren(node) self.seen_vars_stack.pop() return node def visit_LambdaNode(self, node): self.in_lambda += 1 node.analyse_declarations(self.current_env()) self.visitchildren(node) self.in_lambda -= 1 return node def visit_CClassDefNode(self, node): node = self.visit_ClassDefNode(node) if node.scope and node.scope.implemented and node.body: stats = [] for entry in node.scope.var_entries: if entry.needs_property: property = self.create_Property(entry) property.analyse_declarations(node.scope) self.visit(property) stats.append(property) if stats: node.body.stats += stats return node def _handle_fused_def_decorators(self, old_decorators, env, node): """ Create function calls to the decorators and reassignments to the function. """ # Delete staticmethod and classmethod decorators, this is # handled directly by the fused function object. decorators = [] for decorator in old_decorators: func = decorator.decorator if (not func.is_name or func.name not in ('staticmethod', 'classmethod') or env.lookup_here(func.name)): # not a static or classmethod decorators.append(decorator) if decorators: transform = DecoratorTransform(self.context) def_node = node.node _, reassignments = transform.handle_decorators( def_node, decorators, def_node.name) reassignments.analyse_declarations(env) node = [node, reassignments] return node def _handle_def(self, decorators, env, node): "Handle def or cpdef fused functions" # Create PyCFunction nodes for each specialization node.stats.insert(0, node.py_func) node.py_func = self.visit(node.py_func) node.update_fused_defnode_entry(env) pycfunc = ExprNodes.PyCFunctionNode.from_defnode(node.py_func, True) pycfunc = ExprNodes.ProxyNode(pycfunc.coerce_to_temp(env)) node.resulting_fused_function = pycfunc # Create assignment node for our def function node.fused_func_assignment = self._create_assignment( node.py_func, ExprNodes.CloneNode(pycfunc), env) if decorators: node = self._handle_fused_def_decorators(decorators, env, node) return node def _create_fused_function(self, env, node): "Create a fused function for a DefNode with fused arguments" from . import FusedNode if self.fused_function or self.in_lambda: if self.fused_function not in self.fused_error_funcs: if self.in_lambda: error(node.pos, "Fused lambdas not allowed") else: error(node.pos, "Cannot nest fused functions") self.fused_error_funcs.add(self.fused_function) node.body = Nodes.PassStatNode(node.pos) for arg in node.args: if arg.type.is_fused: arg.type = arg.type.get_fused_types()[0] return node decorators = getattr(node, 'decorators', None) node = FusedNode.FusedCFuncDefNode(node, env) self.fused_function = node self.visitchildren(node) self.fused_function = None if node.py_func: node = self._handle_def(decorators, env, node) return node def _handle_nogil_cleanup(self, lenv, node): "Handle cleanup for 'with gil' blocks in nogil functions." if lenv.nogil and lenv.has_with_gil_block: # Acquire the GIL for cleanup in 'nogil' functions, by wrapping # the entire function body in try/finally. # The corresponding release will be taken care of by # Nodes.FuncDefNode.generate_function_definitions() node.body = Nodes.NogilTryFinallyStatNode( node.body.pos, body=node.body, finally_clause=Nodes.EnsureGILNode(node.body.pos), finally_except_clause=Nodes.EnsureGILNode(node.body.pos)) def _handle_fused(self, node): if node.is_generator and node.has_fused_arguments: node.has_fused_arguments = False error(node.pos, "Fused generators not supported") node.gbody = Nodes.StatListNode(node.pos, stats=[], body=Nodes.PassStatNode(node.pos)) return node.has_fused_arguments def visit_FuncDefNode(self, node): """ Analyse a function and its body, as that hasn't happend yet. Also analyse the directive_locals set by @cython.locals(). Then, if we are a function with fused arguments, replace the function (after it has declared itself in the symbol table!) with a FusedCFuncDefNode, and analyse its children (which are in turn normal functions). If we're a normal function, just analyse the body of the function. """ env = self.current_env() self.seen_vars_stack.append(set()) lenv = node.local_scope node.declare_arguments(lenv) # @cython.locals(...) for var, type_node in node.directive_locals.items(): if not lenv.lookup_here(var): # don't redeclare args type = type_node.analyse_as_type(lenv) if type: lenv.declare_var(var, type, type_node.pos) else: error(type_node.pos, "Not a type") if self._handle_fused(node): node = self._create_fused_function(env, node) else: node.body.analyse_declarations(lenv) self._handle_nogil_cleanup(lenv, node) self._super_visit_FuncDefNode(node) self.seen_vars_stack.pop() return node def visit_DefNode(self, node): node = self.visit_FuncDefNode(node) env = self.current_env() if (not isinstance(node, Nodes.DefNode) or node.fused_py_func or node.is_generator_body or not node.needs_assignment_synthesis(env)): return node return [node, self._synthesize_assignment(node, env)] def visit_GeneratorBodyDefNode(self, node): return self.visit_FuncDefNode(node) def _synthesize_assignment(self, node, env): # Synthesize assignment node and put it right after defnode genv = env while genv.is_py_class_scope or genv.is_c_class_scope: genv = genv.outer_scope if genv.is_closure_scope: rhs = node.py_cfunc_node = ExprNodes.InnerFunctionNode( node.pos, def_node=node, pymethdef_cname=node.entry.pymethdef_cname, code_object=ExprNodes.CodeObjectNode(node)) else: binding = self.current_directives.get('binding') rhs = ExprNodes.PyCFunctionNode.from_defnode(node, binding) node.code_object = rhs.code_object if env.is_py_class_scope: rhs.binding = True node.is_cyfunction = rhs.binding return self._create_assignment(node, rhs, env) def _create_assignment(self, def_node, rhs, env): if def_node.decorators: for decorator in def_node.decorators[::-1]: rhs = ExprNodes.SimpleCallNode( decorator.pos, function = decorator.decorator, args = [rhs]) def_node.decorators = None assmt = Nodes.SingleAssignmentNode( def_node.pos, lhs=ExprNodes.NameNode(def_node.pos, name=def_node.name), rhs=rhs) assmt.analyse_declarations(env) return assmt def visit_ScopedExprNode(self, node): env = self.current_env() node.analyse_declarations(env) # the node may or may not have a local scope if node.has_local_scope: self.seen_vars_stack.append(set(self.seen_vars_stack[-1])) self.enter_scope(node, node.expr_scope) node.analyse_scoped_declarations(node.expr_scope) self.visitchildren(node) self.exit_scope() self.seen_vars_stack.pop() else: node.analyse_scoped_declarations(env) self.visitchildren(node) return node def visit_TempResultFromStatNode(self, node): self.visitchildren(node) node.analyse_declarations(self.current_env()) return node def visit_CppClassNode(self, node): if node.visibility == 'extern': return None else: return self.visit_ClassDefNode(node) def visit_CStructOrUnionDefNode(self, node): # Create a wrapper node if needed. # We want to use the struct type information (so it can't happen # before this phase) but also create new objects to be declared # (so it can't happen later). # Note that we don't return the original node, as it is # never used after this phase. if True: # private (default) return None self_value = ExprNodes.AttributeNode( pos = node.pos, obj = ExprNodes.NameNode(pos=node.pos, name=u"self"), attribute = EncodedString(u"value")) var_entries = node.entry.type.scope.var_entries attributes = [] for entry in var_entries: attributes.append(ExprNodes.AttributeNode(pos = entry.pos, obj = self_value, attribute = entry.name)) # __init__ assignments init_assignments = [] for entry, attr in zip(var_entries, attributes): # TODO: branch on visibility init_assignments.append(self.init_assignment.substitute({ u"VALUE": ExprNodes.NameNode(entry.pos, name = entry.name), u"ATTR": attr, }, pos = entry.pos)) # create the class str_format = u"%s(%s)" % (node.entry.type.name, ("%s, " * len(attributes))[:-2]) wrapper_class = self.struct_or_union_wrapper.substitute({ u"INIT_ASSIGNMENTS": Nodes.StatListNode(node.pos, stats = init_assignments), u"IS_UNION": ExprNodes.BoolNode(node.pos, value = not node.entry.type.is_struct), u"MEMBER_TUPLE": ExprNodes.TupleNode(node.pos, args=attributes), u"STR_FORMAT": ExprNodes.StringNode(node.pos, value = EncodedString(str_format)), u"REPR_FORMAT": ExprNodes.StringNode(node.pos, value = EncodedString(str_format.replace("%s", "%r"))), }, pos = node.pos).stats[0] wrapper_class.class_name = node.name wrapper_class.shadow = True class_body = wrapper_class.body.stats # fix value type assert isinstance(class_body[0].base_type, Nodes.CSimpleBaseTypeNode) class_body[0].base_type.name = node.name # fix __init__ arguments init_method = class_body[1] assert isinstance(init_method, Nodes.DefNode) and init_method.name == '__init__' arg_template = init_method.args[1] if not node.entry.type.is_struct: arg_template.kw_only = True del init_method.args[1] for entry, attr in zip(var_entries, attributes): arg = copy.deepcopy(arg_template) arg.declarator.name = entry.name init_method.args.append(arg) # setters/getters for entry, attr in zip(var_entries, attributes): # TODO: branch on visibility if entry.type.is_pyobject: template = self.basic_pyobject_property else: template = self.basic_property property = template.substitute({ u"ATTR": attr, }, pos = entry.pos).stats[0] property.name = entry.name wrapper_class.body.stats.append(property) wrapper_class.analyse_declarations(self.current_env()) return self.visit_CClassDefNode(wrapper_class) # Some nodes are no longer needed after declaration # analysis and can be dropped. The analysis was performed # on these nodes in a seperate recursive process from the # enclosing function or module, so we can simply drop them. def visit_CDeclaratorNode(self, node): # necessary to ensure that all CNameDeclaratorNodes are visited. self.visitchildren(node) return node def visit_CTypeDefNode(self, node): return node def visit_CBaseTypeNode(self, node): return None def visit_CEnumDefNode(self, node): if node.visibility == 'public': return node else: return None def visit_CNameDeclaratorNode(self, node): if node.name in self.seen_vars_stack[-1]: entry = self.current_env().lookup(node.name) if (entry is None or entry.visibility != 'extern' and not entry.scope.is_c_class_scope): warning(node.pos, "cdef variable '%s' declared after it is used" % node.name, 2) self.visitchildren(node) return node def visit_CVarDefNode(self, node): # to ensure all CNameDeclaratorNodes are visited. self.visitchildren(node) return None def visit_CnameDecoratorNode(self, node): child_node = self.visit(node.node) if not child_node: return None if type(child_node) is list: # Assignment synthesized node.child_node = child_node[0] return [node] + child_node[1:] node.node = child_node return node def create_Property(self, entry): if entry.visibility == 'public': if entry.type.is_pyobject: template = self.basic_pyobject_property else: template = self.basic_property elif entry.visibility == 'readonly': template = self.basic_property_ro property = template.substitute({ u"ATTR": ExprNodes.AttributeNode(pos=entry.pos, obj=ExprNodes.NameNode(pos=entry.pos, name="self"), attribute=entry.name), }, pos=entry.pos).stats[0] property.name = entry.name property.doc = entry.doc return property class CalculateQualifiedNamesTransform(EnvTransform): """ Calculate and store the '__qualname__' and the global module name on some nodes. """ def visit_ModuleNode(self, node): self.module_name = self.global_scope().qualified_name self.qualified_name = [] _super = super(CalculateQualifiedNamesTransform, self) self._super_visit_FuncDefNode = _super.visit_FuncDefNode self._super_visit_ClassDefNode = _super.visit_ClassDefNode self.visitchildren(node) return node def _set_qualname(self, node, name=None): if name: qualname = self.qualified_name[:] qualname.append(name) else: qualname = self.qualified_name node.qualname = EncodedString('.'.join(qualname)) node.module_name = self.module_name def _append_entry(self, entry): if entry.is_pyglobal and not entry.is_pyclass_attr: self.qualified_name = [entry.name] else: self.qualified_name.append(entry.name) def visit_ClassNode(self, node): self._set_qualname(node, node.name) self.visitchildren(node) return node def visit_PyClassNamespaceNode(self, node): # class name was already added by parent node self._set_qualname(node) self.visitchildren(node) return node def visit_PyCFunctionNode(self, node): self._set_qualname(node, node.def_node.name) self.visitchildren(node) return node def visit_DefNode(self, node): self._set_qualname(node, node.name) return self.visit_FuncDefNode(node) def visit_FuncDefNode(self, node): orig_qualified_name = self.qualified_name[:] if getattr(node, 'name', None) == '': self.qualified_name.append('') else: self._append_entry(node.entry) self.qualified_name.append('') self._super_visit_FuncDefNode(node) self.qualified_name = orig_qualified_name return node def visit_ClassDefNode(self, node): orig_qualified_name = self.qualified_name[:] entry = (getattr(node, 'entry', None) or # PyClass self.current_env().lookup_here(node.name)) # CClass self._append_entry(entry) self._super_visit_ClassDefNode(node) self.qualified_name = orig_qualified_name return node class AnalyseExpressionsTransform(CythonTransform): def visit_ModuleNode(self, node): node.scope.infer_types() node.body = node.body.analyse_expressions(node.scope) self.visitchildren(node) return node def visit_FuncDefNode(self, node): node.local_scope.infer_types() node.body = node.body.analyse_expressions(node.local_scope) self.visitchildren(node) return node def visit_ScopedExprNode(self, node): if node.has_local_scope: node.expr_scope.infer_types() node = node.analyse_scoped_expressions(node.expr_scope) self.visitchildren(node) return node def visit_IndexNode(self, node): """ Replace index nodes used to specialize cdef functions with fused argument types with the Attribute- or NameNode referring to the function. We then need to copy over the specialization properties to the attribute or name node. Because the indexing might be a Python indexing operation on a fused function, or (usually) a Cython indexing operation, we need to re-analyse the types. """ self.visit_Node(node) if node.is_fused_index and not node.type.is_error: node = node.base elif node.memslice_ellipsis_noop: # memoryviewslice[...] expression, drop the IndexNode node = node.base return node class FindInvalidUseOfFusedTypes(CythonTransform): def visit_FuncDefNode(self, node): # Errors related to use in functions with fused args will already # have been detected if not node.has_fused_arguments: if not node.is_generator_body and node.return_type.is_fused: error(node.pos, "Return type is not specified as argument type") else: self.visitchildren(node) return node def visit_ExprNode(self, node): if node.type and node.type.is_fused: error(node.pos, "Invalid use of fused types, type cannot be specialized") else: self.visitchildren(node) return node class ExpandInplaceOperators(EnvTransform): def visit_InPlaceAssignmentNode(self, node): lhs = node.lhs rhs = node.rhs if lhs.type.is_cpp_class: # No getting around this exact operator here. return node if isinstance(lhs, ExprNodes.IndexNode) and lhs.is_buffer_access: # There is code to handle this case. return node env = self.current_env() def side_effect_free_reference(node, setting=False): if isinstance(node, ExprNodes.NameNode): return node, [] elif node.type.is_pyobject and not setting: node = LetRefNode(node) return node, [node] elif isinstance(node, ExprNodes.IndexNode): if node.is_buffer_access: raise ValueError("Buffer access") base, temps = side_effect_free_reference(node.base) index = LetRefNode(node.index) return ExprNodes.IndexNode(node.pos, base=base, index=index), temps + [index] elif isinstance(node, ExprNodes.AttributeNode): obj, temps = side_effect_free_reference(node.obj) return ExprNodes.AttributeNode(node.pos, obj=obj, attribute=node.attribute), temps else: node = LetRefNode(node) return node, [node] try: lhs, let_ref_nodes = side_effect_free_reference(lhs, setting=True) except ValueError: return node dup = lhs.__class__(**lhs.__dict__) binop = ExprNodes.binop_node(node.pos, operator = node.operator, operand1 = dup, operand2 = rhs, inplace=True) # Manually analyse types for new node. lhs.analyse_target_types(env) dup.analyse_types(env) binop.analyse_operation(env) node = Nodes.SingleAssignmentNode( node.pos, lhs = lhs, rhs=binop.coerce_to(lhs.type, env)) # Use LetRefNode to avoid side effects. let_ref_nodes.reverse() for t in let_ref_nodes: node = LetNode(t, node) return node def visit_ExprNode(self, node): # In-place assignments can't happen within an expression. return node class AdjustDefByDirectives(CythonTransform, SkipDeclarations): """ Adjust function and class definitions by the decorator directives: @cython.cfunc @cython.cclass @cython.ccall @cython.inline """ def visit_ModuleNode(self, node): self.directives = node.directives self.in_py_class = False self.visitchildren(node) return node def visit_CompilerDirectivesNode(self, node): old_directives = self.directives self.directives = node.directives self.visitchildren(node) self.directives = old_directives return node def visit_DefNode(self, node): modifiers = [] if 'inline' in self.directives: modifiers.append('inline') if 'ccall' in self.directives: node = node.as_cfunction( overridable=True, returns=self.directives.get('returns'), modifiers=modifiers) return self.visit(node) if 'cfunc' in self.directives: if self.in_py_class: error(node.pos, "cfunc directive is not allowed here") else: node = node.as_cfunction( overridable=False, returns=self.directives.get('returns'), modifiers=modifiers) return self.visit(node) if 'inline' in modifiers: error(node.pos, "Python functions cannot be declared 'inline'") self.visitchildren(node) return node def visit_PyClassDefNode(self, node): if 'cclass' in self.directives: node = node.as_cclass() return self.visit(node) else: old_in_pyclass = self.in_py_class self.in_py_class = True self.visitchildren(node) self.in_py_class = old_in_pyclass return node def visit_CClassDefNode(self, node): old_in_pyclass = self.in_py_class self.in_py_class = False self.visitchildren(node) self.in_py_class = old_in_pyclass return node class AlignFunctionDefinitions(CythonTransform): """ This class takes the signatures from a .pxd file and applies them to the def methods in a .py file. """ def visit_ModuleNode(self, node): self.scope = node.scope self.directives = node.directives self.imported_names = set() # hack, see visit_FromImportStatNode() self.visitchildren(node) return node def visit_PyClassDefNode(self, node): pxd_def = self.scope.lookup(node.name) if pxd_def: if pxd_def.is_cclass: return self.visit_CClassDefNode(node.as_cclass(), pxd_def) elif not pxd_def.scope or not pxd_def.scope.is_builtin_scope: error(node.pos, "'%s' redeclared" % node.name) if pxd_def.pos: error(pxd_def.pos, "previous declaration here") return None return node def visit_CClassDefNode(self, node, pxd_def=None): if pxd_def is None: pxd_def = self.scope.lookup(node.class_name) if pxd_def: outer_scope = self.scope self.scope = pxd_def.type.scope self.visitchildren(node) if pxd_def: self.scope = outer_scope return node def visit_DefNode(self, node): pxd_def = self.scope.lookup(node.name) if pxd_def and (not pxd_def.scope or not pxd_def.scope.is_builtin_scope): if not pxd_def.is_cfunction: error(node.pos, "'%s' redeclared" % node.name) if pxd_def.pos: error(pxd_def.pos, "previous declaration here") return None node = node.as_cfunction(pxd_def) elif (self.scope.is_module_scope and self.directives['auto_cpdef'] and not node.name in self.imported_names and node.is_cdef_func_compatible()): # FIXME: cpdef-ing should be done in analyse_declarations() node = node.as_cfunction(scope=self.scope) # Enable this when nested cdef functions are allowed. # self.visitchildren(node) return node def visit_FromImportStatNode(self, node): # hack to prevent conditional import fallback functions from # being cdpef-ed (global Python variables currently conflict # with imports) if self.scope.is_module_scope: for name, _ in node.items: self.imported_names.add(name) return node def visit_ExprNode(self, node): # ignore lambdas and everything else that appears in expressions return node class RemoveUnreachableCode(CythonTransform): def visit_StatListNode(self, node): if not self.current_directives['remove_unreachable']: return node self.visitchildren(node) for idx, stat in enumerate(node.stats): idx += 1 if stat.is_terminator: if idx < len(node.stats): if self.current_directives['warn.unreachable']: warning(node.stats[idx].pos, "Unreachable code", 2) node.stats = node.stats[:idx] node.is_terminator = True break return node def visit_IfClauseNode(self, node): self.visitchildren(node) if node.body.is_terminator: node.is_terminator = True return node def visit_IfStatNode(self, node): self.visitchildren(node) if node.else_clause and node.else_clause.is_terminator: for clause in node.if_clauses: if not clause.is_terminator: break else: node.is_terminator = True return node def visit_TryExceptStatNode(self, node): self.visitchildren(node) if node.body.is_terminator and node.else_clause: if self.current_directives['warn.unreachable']: warning(node.else_clause.pos, "Unreachable code", 2) node.else_clause = None return node class YieldNodeCollector(TreeVisitor): def __init__(self): super(YieldNodeCollector, self).__init__() self.yields = [] self.awaits = [] self.returns = [] self.has_return_value = False def visit_Node(self, node): self.visitchildren(node) def visit_YieldExprNode(self, node): self.yields.append(node) self.visitchildren(node) def visit_AwaitExprNode(self, node): self.awaits.append(node) self.visitchildren(node) def visit_ReturnStatNode(self, node): self.visitchildren(node) if node.value: self.has_return_value = True self.returns.append(node) def visit_ClassDefNode(self, node): pass def visit_FuncDefNode(self, node): pass def visit_LambdaNode(self, node): pass def visit_GeneratorExpressionNode(self, node): pass def visit_CArgDeclNode(self, node): # do not look into annotations # FIXME: support (yield) in default arguments (currently crashes) pass class MarkClosureVisitor(CythonTransform): def visit_ModuleNode(self, node): self.needs_closure = False self.visitchildren(node) return node def visit_FuncDefNode(self, node): self.needs_closure = False self.visitchildren(node) node.needs_closure = self.needs_closure self.needs_closure = True collector = YieldNodeCollector() collector.visitchildren(node) if node.is_async_def: if collector.yields: error(collector.yields[0].pos, "'yield' not allowed in async coroutines (use 'await')") yields = collector.awaits elif collector.yields: if collector.awaits: error(collector.yields[0].pos, "'await' not allowed in generators (use 'yield')") yields = collector.yields else: return node for i, yield_expr in enumerate(yields, 1): yield_expr.label_num = i for retnode in collector.returns: retnode.in_generator = True gbody = Nodes.GeneratorBodyDefNode( pos=node.pos, name=node.name, body=node.body) coroutine = (Nodes.AsyncDefNode if node.is_async_def else Nodes.GeneratorDefNode)( pos=node.pos, name=node.name, args=node.args, star_arg=node.star_arg, starstar_arg=node.starstar_arg, doc=node.doc, decorators=node.decorators, gbody=gbody, lambda_name=node.lambda_name) return coroutine def visit_CFuncDefNode(self, node): self.needs_closure = False self.visitchildren(node) node.needs_closure = self.needs_closure self.needs_closure = True if node.needs_closure and node.overridable: error(node.pos, "closures inside cpdef functions not yet supported") return node def visit_LambdaNode(self, node): self.needs_closure = False self.visitchildren(node) node.needs_closure = self.needs_closure self.needs_closure = True return node def visit_ClassDefNode(self, node): self.visitchildren(node) self.needs_closure = True return node class CreateClosureClasses(CythonTransform): # Output closure classes in module scope for all functions # that really need it. def __init__(self, context): super(CreateClosureClasses, self).__init__(context) self.path = [] self.in_lambda = False def visit_ModuleNode(self, node): self.module_scope = node.scope self.visitchildren(node) return node def find_entries_used_in_closures(self, node): from_closure = [] in_closure = [] for name, entry in node.local_scope.entries.items(): if entry.from_closure: from_closure.append((name, entry)) elif entry.in_closure: in_closure.append((name, entry)) return from_closure, in_closure def create_class_from_scope(self, node, target_module_scope, inner_node=None): # move local variables into closure if node.is_generator: for entry in node.local_scope.entries.values(): if not entry.from_closure: entry.in_closure = True from_closure, in_closure = self.find_entries_used_in_closures(node) in_closure.sort() # Now from the begining node.needs_closure = False node.needs_outer_scope = False func_scope = node.local_scope cscope = node.entry.scope while cscope.is_py_class_scope or cscope.is_c_class_scope: cscope = cscope.outer_scope if not from_closure and (self.path or inner_node): if not inner_node: if not node.py_cfunc_node: raise InternalError("DefNode does not have assignment node") inner_node = node.py_cfunc_node inner_node.needs_self_code = False node.needs_outer_scope = False if node.is_generator: pass elif not in_closure and not from_closure: return elif not in_closure: func_scope.is_passthrough = True func_scope.scope_class = cscope.scope_class node.needs_outer_scope = True return as_name = '%s_%s' % ( target_module_scope.next_id(Naming.closure_class_prefix), node.entry.cname) entry = target_module_scope.declare_c_class( name=as_name, pos=node.pos, defining=True, implementing=True) entry.type.is_final_type = True func_scope.scope_class = entry class_scope = entry.type.scope class_scope.is_internal = True if Options.closure_freelist_size: class_scope.directives['freelist'] = Options.closure_freelist_size if from_closure: assert cscope.is_closure_scope class_scope.declare_var(pos=node.pos, name=Naming.outer_scope_cname, cname=Naming.outer_scope_cname, type=cscope.scope_class.type, is_cdef=True) node.needs_outer_scope = True for name, entry in in_closure: closure_entry = class_scope.declare_var(pos=entry.pos, name=entry.name, cname=entry.cname, type=entry.type, is_cdef=True) if entry.is_declared_generic: closure_entry.is_declared_generic = 1 node.needs_closure = True # Do it here because other classes are already checked target_module_scope.check_c_class(func_scope.scope_class) def visit_LambdaNode(self, node): if not isinstance(node.def_node, Nodes.DefNode): # fused function, an error has been previously issued return node was_in_lambda = self.in_lambda self.in_lambda = True self.create_class_from_scope(node.def_node, self.module_scope, node) self.visitchildren(node) self.in_lambda = was_in_lambda return node def visit_FuncDefNode(self, node): if self.in_lambda: self.visitchildren(node) return node if node.needs_closure or self.path: self.create_class_from_scope(node, self.module_scope) self.path.append(node) self.visitchildren(node) self.path.pop() return node def visit_GeneratorBodyDefNode(self, node): self.visitchildren(node) return node def visit_CFuncDefNode(self, node): if not node.overridable: return self.visit_FuncDefNode(node) else: self.visitchildren(node) return node class GilCheck(VisitorTransform): """ Call `node.gil_check(env)` on each node to make sure we hold the GIL when we need it. Raise an error when on Python operations inside a `nogil` environment. Additionally, raise exceptions for closely nested with gil or with nogil statements. The latter would abort Python. """ def __call__(self, root): self.env_stack = [root.scope] self.nogil = False # True for 'cdef func() nogil:' functions, as the GIL may be held while # calling this function (thus contained 'nogil' blocks may be valid). self.nogil_declarator_only = False return super(GilCheck, self).__call__(root) def visit_FuncDefNode(self, node): self.env_stack.append(node.local_scope) was_nogil = self.nogil self.nogil = node.local_scope.nogil if self.nogil: self.nogil_declarator_only = True if self.nogil and node.nogil_check: node.nogil_check(node.local_scope) self.visitchildren(node) # This cannot be nested, so it doesn't need backup/restore self.nogil_declarator_only = False self.env_stack.pop() self.nogil = was_nogil return node def visit_GILStatNode(self, node): if self.nogil and node.nogil_check: node.nogil_check() was_nogil = self.nogil self.nogil = (node.state == 'nogil') if was_nogil == self.nogil and not self.nogil_declarator_only: if not was_nogil: error(node.pos, "Trying to acquire the GIL while it is " "already held.") else: error(node.pos, "Trying to release the GIL while it was " "previously released.") if isinstance(node.finally_clause, Nodes.StatListNode): # The finally clause of the GILStatNode is a GILExitNode, # which is wrapped in a StatListNode. Just unpack that. node.finally_clause, = node.finally_clause.stats self.visitchildren(node) self.nogil = was_nogil return node def visit_ParallelRangeNode(self, node): if node.nogil: node.nogil = False node = Nodes.GILStatNode(node.pos, state='nogil', body=node) return self.visit_GILStatNode(node) if not self.nogil: error(node.pos, "prange() can only be used without the GIL") # Forget about any GIL-related errors that may occur in the body return None node.nogil_check(self.env_stack[-1]) self.visitchildren(node) return node def visit_ParallelWithBlockNode(self, node): if not self.nogil: error(node.pos, "The parallel section may only be used without " "the GIL") return None if node.nogil_check: # It does not currently implement this, but test for it anyway to # avoid potential future surprises node.nogil_check(self.env_stack[-1]) self.visitchildren(node) return node def visit_TryFinallyStatNode(self, node): """ Take care of try/finally statements in nogil code sections. """ if not self.nogil or isinstance(node, Nodes.GILStatNode): return self.visit_Node(node) node.nogil_check = None node.is_try_finally_in_nogil = True self.visitchildren(node) return node def visit_Node(self, node): if self.env_stack and self.nogil and node.nogil_check: node.nogil_check(self.env_stack[-1]) self.visitchildren(node) node.in_nogil_context = self.nogil return node class TransformBuiltinMethods(EnvTransform): """ Replace Cython's own cython.* builtins by the corresponding tree nodes. """ def visit_SingleAssignmentNode(self, node): if node.declaration_only: return None else: self.visitchildren(node) return node def visit_AttributeNode(self, node): self.visitchildren(node) return self.visit_cython_attribute(node) def visit_NameNode(self, node): return self.visit_cython_attribute(node) def visit_cython_attribute(self, node): attribute = node.as_cython_attribute() if attribute: if attribute == u'compiled': node = ExprNodes.BoolNode(node.pos, value=True) elif attribute == u'__version__': from .. import __version__ as version node = ExprNodes.StringNode(node.pos, value=EncodedString(version)) elif attribute == u'NULL': node = ExprNodes.NullNode(node.pos) elif attribute in (u'set', u'frozenset', u'staticmethod'): node = ExprNodes.NameNode(node.pos, name=EncodedString(attribute), entry=self.current_env().builtin_scope().lookup_here(attribute)) elif PyrexTypes.parse_basic_type(attribute): pass elif self.context.cython_scope.lookup_qualified_name(attribute): pass else: error(node.pos, u"'%s' not a valid cython attribute or is being used incorrectly" % attribute) return node def visit_ExecStatNode(self, node): lenv = self.current_env() self.visitchildren(node) if len(node.args) == 1: node.args.append(ExprNodes.GlobalsExprNode(node.pos)) if not lenv.is_module_scope: node.args.append( ExprNodes.LocalsExprNode( node.pos, self.current_scope_node(), lenv)) return node def _inject_locals(self, node, func_name): # locals()/dir()/vars() builtins lenv = self.current_env() entry = lenv.lookup_here(func_name) if entry: # not the builtin return node pos = node.pos if func_name in ('locals', 'vars'): if func_name == 'locals' and len(node.args) > 0: error(self.pos, "Builtin 'locals()' called with wrong number of args, expected 0, got %d" % len(node.args)) return node elif func_name == 'vars': if len(node.args) > 1: error(self.pos, "Builtin 'vars()' called with wrong number of args, expected 0-1, got %d" % len(node.args)) if len(node.args) > 0: return node # nothing to do return ExprNodes.LocalsExprNode(pos, self.current_scope_node(), lenv) else: # dir() if len(node.args) > 1: error(self.pos, "Builtin 'dir()' called with wrong number of args, expected 0-1, got %d" % len(node.args)) if len(node.args) > 0: # optimised in Builtin.py return node if lenv.is_py_class_scope or lenv.is_module_scope: if lenv.is_py_class_scope: pyclass = self.current_scope_node() locals_dict = ExprNodes.CloneNode(pyclass.dict) else: locals_dict = ExprNodes.GlobalsExprNode(pos) return ExprNodes.SortedDictKeysNode(locals_dict) local_names = sorted(var.name for var in lenv.entries.values() if var.name) items = [ExprNodes.IdentifierStringNode(pos, value=var) for var in local_names] return ExprNodes.ListNode(pos, args=items) def visit_PrimaryCmpNode(self, node): # special case: for in/not-in test, we do not need to sort locals() self.visitchildren(node) if node.operator in 'not_in': # in/not_in if isinstance(node.operand2, ExprNodes.SortedDictKeysNode): arg = node.operand2.arg if isinstance(arg, ExprNodes.NoneCheckNode): arg = arg.arg node.operand2 = arg return node def visit_CascadedCmpNode(self, node): return self.visit_PrimaryCmpNode(node) def _inject_eval(self, node, func_name): lenv = self.current_env() entry = lenv.lookup_here(func_name) if entry or len(node.args) != 1: return node # Inject globals and locals node.args.append(ExprNodes.GlobalsExprNode(node.pos)) if not lenv.is_module_scope: node.args.append( ExprNodes.LocalsExprNode( node.pos, self.current_scope_node(), lenv)) return node def _inject_super(self, node, func_name): lenv = self.current_env() entry = lenv.lookup_here(func_name) if entry or node.args: return node # Inject no-args super def_node = self.current_scope_node() if (not isinstance(def_node, Nodes.DefNode) or not def_node.args or len(self.env_stack) < 2): return node class_node, class_scope = self.env_stack[-2] if class_scope.is_py_class_scope: def_node.requires_classobj = True class_node.class_cell.is_active = True node.args = [ ExprNodes.ClassCellNode( node.pos, is_generator=def_node.is_generator), ExprNodes.NameNode(node.pos, name=def_node.args[0].name) ] elif class_scope.is_c_class_scope: node.args = [ ExprNodes.NameNode( node.pos, name=class_node.scope.name, entry=class_node.entry), ExprNodes.NameNode(node.pos, name=def_node.args[0].name) ] return node def visit_SimpleCallNode(self, node): # cython.foo function = node.function.as_cython_attribute() if function: if function in InterpretCompilerDirectives.unop_method_nodes: if len(node.args) != 1: error(node.function.pos, u"%s() takes exactly one argument" % function) else: node = InterpretCompilerDirectives.unop_method_nodes[function]( node.function.pos, operand=node.args[0]) elif function in InterpretCompilerDirectives.binop_method_nodes: if len(node.args) != 2: error(node.function.pos, u"%s() takes exactly two arguments" % function) else: node = InterpretCompilerDirectives.binop_method_nodes[function]( node.function.pos, operand1=node.args[0], operand2=node.args[1]) elif function == u'cast': if len(node.args) != 2: error(node.function.pos, u"cast() takes exactly two arguments") else: type = node.args[0].analyse_as_type(self.current_env()) if type: node = ExprNodes.TypecastNode(node.function.pos, type=type, operand=node.args[1]) else: error(node.args[0].pos, "Not a type") elif function == u'sizeof': if len(node.args) != 1: error(node.function.pos, u"sizeof() takes exactly one argument") else: type = node.args[0].analyse_as_type(self.current_env()) if type: node = ExprNodes.SizeofTypeNode(node.function.pos, arg_type=type) else: node = ExprNodes.SizeofVarNode(node.function.pos, operand=node.args[0]) elif function == 'cmod': if len(node.args) != 2: error(node.function.pos, u"cmod() takes exactly two arguments") else: node = ExprNodes.binop_node(node.function.pos, '%', node.args[0], node.args[1]) node.cdivision = True elif function == 'cdiv': if len(node.args) != 2: error(node.function.pos, u"cdiv() takes exactly two arguments") else: node = ExprNodes.binop_node(node.function.pos, '/', node.args[0], node.args[1]) node.cdivision = True elif function == u'set': node.function = ExprNodes.NameNode(node.pos, name=EncodedString('set')) elif function == u'staticmethod': node.function = ExprNodes.NameNode(node.pos, name=EncodedString('staticmethod')) elif self.context.cython_scope.lookup_qualified_name(function): pass else: error(node.function.pos, u"'%s' not a valid cython language construct" % function) self.visitchildren(node) if isinstance(node, ExprNodes.SimpleCallNode) and node.function.is_name: func_name = node.function.name if func_name in ('dir', 'locals', 'vars'): return self._inject_locals(node, func_name) if func_name == 'eval': return self._inject_eval(node, func_name) if func_name == 'super': return self._inject_super(node, func_name) return node class ReplaceFusedTypeChecks(VisitorTransform): """ This is not a transform in the pipeline. It is invoked on the specific versions of a cdef function with fused argument types. It filters out any type branches that don't match. e.g. if fused_t is mytype: ... elif fused_t in other_fused_type: ... """ def __init__(self, local_scope): super(ReplaceFusedTypeChecks, self).__init__() self.local_scope = local_scope # defer the import until now to avoid circular import time dependencies from .Optimize import ConstantFolding self.transform = ConstantFolding(reevaluate=True) def visit_IfStatNode(self, node): """ Filters out any if clauses with false compile time type check expression. """ self.visitchildren(node) return self.transform(node) def visit_PrimaryCmpNode(self, node): type1 = node.operand1.analyse_as_type(self.local_scope) type2 = node.operand2.analyse_as_type(self.local_scope) if type1 and type2: false_node = ExprNodes.BoolNode(node.pos, value=False) true_node = ExprNodes.BoolNode(node.pos, value=True) type1 = self.specialize_type(type1, node.operand1.pos) op = node.operator if op in ('is', 'is_not', '==', '!='): type2 = self.specialize_type(type2, node.operand2.pos) is_same = type1.same_as(type2) eq = op in ('is', '==') if (is_same and eq) or (not is_same and not eq): return true_node elif op in ('in', 'not_in'): # We have to do an instance check directly, as operand2 # needs to be a fused type and not a type with a subtype # that is fused. First unpack the typedef if isinstance(type2, PyrexTypes.CTypedefType): type2 = type2.typedef_base_type if type1.is_fused: error(node.operand1.pos, "Type is fused") elif not type2.is_fused: error(node.operand2.pos, "Can only use 'in' or 'not in' on a fused type") else: types = PyrexTypes.get_specialized_types(type2) for specialized_type in types: if type1.same_as(specialized_type): if op == 'in': return true_node else: return false_node if op == 'not_in': return true_node return false_node return node def specialize_type(self, type, pos): try: return type.specialize(self.local_scope.fused_to_specific) except KeyError: error(pos, "Type is not specific") return type def visit_Node(self, node): self.visitchildren(node) return node class DebugTransform(CythonTransform): """ Write debug information for this Cython module. """ def __init__(self, context, options, result): super(DebugTransform, self).__init__(context) self.visited = set() # our treebuilder and debug output writer # (see Cython.Debugger.debug_output.CythonDebugWriter) self.tb = self.context.gdb_debug_outputwriter #self.c_output_file = options.output_file self.c_output_file = result.c_file # Closure support, basically treat nested functions as if the AST were # never nested self.nested_funcdefs = [] # tells visit_NameNode whether it should register step-into functions self.register_stepinto = False def visit_ModuleNode(self, node): self.tb.module_name = node.full_module_name attrs = dict( module_name=node.full_module_name, filename=node.pos[0].filename, c_filename=self.c_output_file) self.tb.start('Module', attrs) # serialize functions self.tb.start('Functions') # First, serialize functions normally... self.visitchildren(node) # ... then, serialize nested functions for nested_funcdef in self.nested_funcdefs: self.visit_FuncDefNode(nested_funcdef) self.register_stepinto = True self.serialize_modulenode_as_function(node) self.register_stepinto = False self.tb.end('Functions') # 2.3 compatibility. Serialize global variables self.tb.start('Globals') entries = {} for k, v in node.scope.entries.items(): if (v.qualified_name not in self.visited and not v.name.startswith('__pyx_') and not v.type.is_cfunction and not v.type.is_extension_type): entries[k]= v self.serialize_local_variables(entries) self.tb.end('Globals') # self.tb.end('Module') # end Module after the line number mapping in # Cython.Compiler.ModuleNode.ModuleNode._serialize_lineno_map return node def visit_FuncDefNode(self, node): self.visited.add(node.local_scope.qualified_name) if getattr(node, 'is_wrapper', False): return node if self.register_stepinto: self.nested_funcdefs.append(node) return node # node.entry.visibility = 'extern' if node.py_func is None: pf_cname = '' else: pf_cname = node.py_func.entry.func_cname attrs = dict( name=node.entry.name or getattr(node, 'name', ''), cname=node.entry.func_cname, pf_cname=pf_cname, qualified_name=node.local_scope.qualified_name, lineno=str(node.pos[1])) self.tb.start('Function', attrs=attrs) self.tb.start('Locals') self.serialize_local_variables(node.local_scope.entries) self.tb.end('Locals') self.tb.start('Arguments') for arg in node.local_scope.arg_entries: self.tb.start(arg.name) self.tb.end(arg.name) self.tb.end('Arguments') self.tb.start('StepIntoFunctions') self.register_stepinto = True self.visitchildren(node) self.register_stepinto = False self.tb.end('StepIntoFunctions') self.tb.end('Function') return node def visit_NameNode(self, node): if (self.register_stepinto and node.type is not None and node.type.is_cfunction and getattr(node, 'is_called', False) and node.entry.func_cname is not None): # don't check node.entry.in_cinclude, as 'cdef extern: ...' # declared functions are not 'in_cinclude'. # This means we will list called 'cdef' functions as # "step into functions", but this is not an issue as they will be # recognized as Cython functions anyway. attrs = dict(name=node.entry.func_cname) self.tb.start('StepIntoFunction', attrs=attrs) self.tb.end('StepIntoFunction') self.visitchildren(node) return node def serialize_modulenode_as_function(self, node): """ Serialize the module-level code as a function so the debugger will know it's a "relevant frame" and it will know where to set the breakpoint for 'break modulename'. """ name = node.full_module_name.rpartition('.')[-1] cname_py2 = 'init' + name cname_py3 = 'PyInit_' + name py2_attrs = dict( name=name, cname=cname_py2, pf_cname='', # Ignore the qualified_name, breakpoints should be set using # `cy break modulename:lineno` for module-level breakpoints. qualified_name='', lineno='1', is_initmodule_function="True", ) py3_attrs = dict(py2_attrs, cname=cname_py3) self._serialize_modulenode_as_function(node, py2_attrs) self._serialize_modulenode_as_function(node, py3_attrs) def _serialize_modulenode_as_function(self, node, attrs): self.tb.start('Function', attrs=attrs) self.tb.start('Locals') self.serialize_local_variables(node.scope.entries) self.tb.end('Locals') self.tb.start('Arguments') self.tb.end('Arguments') self.tb.start('StepIntoFunctions') self.register_stepinto = True self.visitchildren(node) self.register_stepinto = False self.tb.end('StepIntoFunctions') self.tb.end('Function') def serialize_local_variables(self, entries): for entry in entries.values(): if not entry.cname: # not a local variable continue if entry.type.is_pyobject: vartype = 'PythonObject' else: vartype = 'CObject' if entry.from_closure: # We're dealing with a closure where a variable from an outer # scope is accessed, get it from the scope object. cname = '%s->%s' % (Naming.cur_scope_cname, entry.outer_entry.cname) qname = '%s.%s.%s' % (entry.scope.outer_scope.qualified_name, entry.scope.name, entry.name) elif entry.in_closure: cname = '%s->%s' % (Naming.cur_scope_cname, entry.cname) qname = entry.qualified_name else: cname = entry.cname qname = entry.qualified_name if not entry.pos: # this happens for variables that are not in the user's code, # e.g. for the global __builtins__, __doc__, etc. We can just # set the lineno to 0 for those. lineno = '0' else: lineno = str(entry.pos[1]) attrs = dict( name=entry.name, cname=cname, qualified_name=qname, type=vartype, lineno=lineno) self.tb.start('LocalVar', attrs) self.tb.end('LocalVar') Cython-0.23.4/Cython/Compiler/ParseTreeTransforms.pxd0000644000175600017570000000410612606202452023711 0ustar jenkinsjenkins00000000000000 from __future__ import absolute_import cimport cython from .Visitor cimport ( CythonTransform, VisitorTransform, TreeVisitor, ScopeTrackingTransform, EnvTransform) cdef class NameNodeCollector(TreeVisitor): cdef list name_nodes cdef class SkipDeclarations: # (object): pass cdef class NormalizeTree(CythonTransform): cdef bint is_in_statlist cdef bint is_in_expr cpdef visit_StatNode(self, node, is_listcontainer=*) cdef class PostParse(ScopeTrackingTransform): cdef dict specialattribute_handlers cdef size_t lambda_counter cdef size_t genexpr_counter cdef _visit_assignment_node(self, node, list expr_list) #def eliminate_rhs_duplicates(list expr_list_list, list ref_node_sequence) #def sort_common_subsequences(list items) @cython.locals(starred_targets=Py_ssize_t, lhs_size=Py_ssize_t, rhs_size=Py_ssize_t) cdef flatten_parallel_assignments(list input, list output) cdef map_starred_assignment(list lhs_targets, list starred_assignments, list lhs_args, list rhs_args) #class PxdPostParse(CythonTransform, SkipDeclarations): #class InterpretCompilerDirectives(CythonTransform, SkipDeclarations): #class WithTransform(CythonTransform, SkipDeclarations): #class DecoratorTransform(CythonTransform, SkipDeclarations): #class AnalyseDeclarationsTransform(EnvTransform): cdef class AnalyseExpressionsTransform(CythonTransform): pass cdef class ExpandInplaceOperators(EnvTransform): pass cdef class AlignFunctionDefinitions(CythonTransform): cdef dict directives cdef scope cdef class YieldNodeCollector(TreeVisitor): cdef public list yields cdef public list returns cdef public bint has_return_value cdef class MarkClosureVisitor(CythonTransform): cdef bint needs_closure cdef class CreateClosureClasses(CythonTransform): cdef list path cdef bint in_lambda cdef module_scope cdef generator_class cdef class GilCheck(VisitorTransform): cdef list env_stack cdef bint nogil cdef bint nogil_declarator_only cdef class TransformBuiltinMethods(EnvTransform): cdef visit_cython_attribute(self, node) Cython-0.23.4/Cython/Compiler/Options.py0000644000175600017570000003103212606202452021226 0ustar jenkinsjenkins00000000000000# # Cython - Compilation-wide options and pragma declarations # from __future__ import absolute_import # Perform lookups on builtin names only once, at module initialisation # time. This will prevent the module from getting imported if a # builtin name that it uses cannot be found during initialisation. cache_builtins = True embed_pos_in_docstring = False gcc_branch_hints = True pre_import = None docstrings = True # Decref global variables in this module on exit for garbage collection. # 0: None, 1+: interned objects, 2+: cdef globals, 3+: types objects # Mostly for reducing noise for Valgrind, only executes at process exit # (when all memory will be reclaimed anyways). generate_cleanup_code = False # Generate an annotated HTML version of the input source files. annotate = False # When annotating source files in HTML, include coverage information from # this file. annotate_coverage_xml = None # This will abort the compilation on the first error occured rather than trying # to keep going and printing further error messages. fast_fail = False # Make all warnings into errors. warning_errors = False # Make unknown names an error. Python raises a NameError when # encountering unknown names at runtime, whereas this option makes # them a compile time error. If you want full Python compatibility, # you should disable this option and also 'cache_builtins'. error_on_unknown_names = True # Make uninitialized local variable reference a compile time error. # Python raises UnboundLocalError at runtime, whereas this option makes # them a compile time error. Note that this option affects only variables # of "python object" type. error_on_uninitialized = True # This will convert statements of the form "for i in range(...)" # to "for i from ..." when i is a cdef'd integer type, and the direction # (i.e. sign of step) can be determined. # WARNING: This may change the semantics if the range causes assignment to # i to overflow. Specifically, if this option is set, an error will be # raised before the loop is entered, wheras without this option the loop # will execute until an overflowing value is encountered. convert_range = True # Enable this to allow one to write your_module.foo = ... to overwrite the # definition if the cpdef function foo, at the cost of an extra dictionary # lookup on every call. # If this is 0 it simply creates a wrapper. lookup_module_cpdef = False # Whether or not to embed the Python interpreter, for use in making a # standalone executable or calling from external libraries. # This will provide a method which initalizes the interpreter and # executes the body of this module. embed = None # In previous iterations of Cython, globals() gave the first non-Cython module # globals in the call stack. Sage relies on this behavior for variable injection. old_style_globals = False # Allows cimporting from a pyx file without a pxd file. cimport_from_pyx = False # max # of dims for buffers -- set lower than number of dimensions in numpy, as # slices are passed by value and involve a lot of copying buffer_max_dims = 8 # Number of function closure instances to keep in a freelist (0: no freelists) closure_freelist_size = 8 # Should tp_clear() set object fields to None instead of clearing them to NULL? clear_to_none = True # Declare compiler directives directive_defaults = { 'boundscheck' : True, 'nonecheck' : False, 'initializedcheck' : True, 'embedsignature' : False, 'locals' : {}, 'auto_cpdef': False, 'cdivision': False, # was True before 0.12 'cdivision_warnings': False, 'overflowcheck': False, 'overflowcheck.fold': True, 'always_allow_keywords': False, 'allow_none_for_extension_args': True, 'wraparound' : True, 'ccomplex' : False, # use C99/C++ for complex types and arith 'callspec' : "", 'final' : False, 'internal' : False, 'profile': False, 'no_gc_clear': False, 'linetrace': False, 'annotation_typing': False, # read type declarations from Python function annotations 'infer_types': None, 'infer_types.verbose': False, 'autotestdict': True, 'autotestdict.cdef': False, 'autotestdict.all': False, 'language_level': 2, 'fast_getattr': False, # Undocumented until we come up with a better way to handle this everywhere. 'py2_import': False, # For backward compatibility of Cython's source code in Py3 source mode 'c_string_type': 'bytes', 'c_string_encoding': '', 'type_version_tag': True, # enables Py_TPFLAGS_HAVE_VERSION_TAG on extension types 'unraisable_tracebacks': False, # set __file__ and/or __path__ to known source/target path at import time (instead of not having them available) 'set_initial_path' : None, # SOURCEFILE or "/full/path/to/module" 'warn': None, 'warn.undeclared': False, 'warn.unreachable': True, 'warn.maybe_uninitialized': False, 'warn.unused': False, 'warn.unused_arg': False, 'warn.unused_result': False, 'warn.multiple_declarators': True, # optimizations 'optimize.inline_defnode_calls': True, 'optimize.unpack_method_calls': True, # increases code size when True 'optimize.use_switch': True, # remove unreachable code 'remove_unreachable': True, # control flow debug directives 'control_flow.dot_output': "", # Graphviz output filename 'control_flow.dot_annotate_defs': False, # Annotate definitions # test support 'test_assert_path_exists' : [], 'test_fail_if_path_exists' : [], # experimental, subject to change 'binding': None, 'freelist': 0, 'formal_grammar': False, } # Extra warning directives extra_warnings = { 'warn.maybe_uninitialized': True, 'warn.unreachable': True, 'warn.unused': True, } def one_of(*args): def validate(name, value): if value not in args: raise ValueError("%s directive must be one of %s, got '%s'" % ( name, args, value)) else: return value return validate def normalise_encoding_name(option_name, encoding): """ >>> normalise_encoding_name('c_string_encoding', 'ascii') 'ascii' >>> normalise_encoding_name('c_string_encoding', 'AsCIi') 'ascii' >>> normalise_encoding_name('c_string_encoding', 'us-ascii') 'ascii' >>> normalise_encoding_name('c_string_encoding', 'utF8') 'utf8' >>> normalise_encoding_name('c_string_encoding', 'utF-8') 'utf8' >>> normalise_encoding_name('c_string_encoding', 'deFAuLT') 'default' >>> normalise_encoding_name('c_string_encoding', 'default') 'default' >>> normalise_encoding_name('c_string_encoding', 'SeriousLyNoSuch--Encoding') 'SeriousLyNoSuch--Encoding' """ if not encoding: return '' if encoding.lower() in ('default', 'ascii', 'utf8'): return encoding.lower() import codecs try: decoder = codecs.getdecoder(encoding) except LookupError: return encoding # may exists at runtime ... for name in ('ascii', 'utf8'): if codecs.getdecoder(name) == decoder: return name return encoding # Override types possibilities above, if needed directive_types = { 'final' : bool, # final cdef classes and methods 'internal' : bool, # cdef class visibility in the module dict 'infer_types' : bool, # values can be True/None/False 'binding' : bool, 'cfunc' : None, # decorators do not take directive value 'ccall' : None, 'inline' : None, 'staticmethod' : None, 'cclass' : None, 'returns' : type, 'set_initial_path': str, 'freelist': int, 'c_string_type': one_of('bytes', 'bytearray', 'str', 'unicode'), 'c_string_encoding': normalise_encoding_name, } for key, val in directive_defaults.items(): if key not in directive_types: directive_types[key] = type(val) directive_scopes = { # defaults to available everywhere # 'module', 'function', 'class', 'with statement' 'final' : ('cclass', 'function'), 'inline' : ('function',), 'staticmethod' : ('function',), # FIXME: analysis currently lacks more specific function scope 'no_gc_clear' : ('cclass',), 'internal' : ('cclass',), 'autotestdict' : ('module',), 'autotestdict.all' : ('module',), 'autotestdict.cdef' : ('module',), 'set_initial_path' : ('module',), 'test_assert_path_exists' : ('function', 'class', 'cclass'), 'test_fail_if_path_exists' : ('function', 'class', 'cclass'), 'freelist': ('cclass',), 'annotation_typing': ('module',), # FIXME: analysis currently lacks more specific function scope # Avoid scope-specific to/from_py_functions for c_string. 'c_string_type': ('module',), 'c_string_encoding': ('module',), 'type_version_tag': ('module', 'cclass'), 'language_level': ('module',), } def parse_directive_value(name, value, relaxed_bool=False): """ Parses value as an option value for the given name and returns the interpreted value. None is returned if the option does not exist. >>> print(parse_directive_value('nonexisting', 'asdf asdfd')) None >>> parse_directive_value('boundscheck', 'True') True >>> parse_directive_value('boundscheck', 'true') Traceback (most recent call last): ... ValueError: boundscheck directive must be set to True or False, got 'true' >>> parse_directive_value('c_string_encoding', 'us-ascii') 'ascii' >>> parse_directive_value('c_string_type', 'str') 'str' >>> parse_directive_value('c_string_type', 'bytes') 'bytes' >>> parse_directive_value('c_string_type', 'bytearray') 'bytearray' >>> parse_directive_value('c_string_type', 'unicode') 'unicode' >>> parse_directive_value('c_string_type', 'unnicode') Traceback (most recent call last): ValueError: c_string_type directive must be one of ('bytes', 'bytearray', 'str', 'unicode'), got 'unnicode' """ type = directive_types.get(name) if not type: return None orig_value = value if type is bool: value = str(value) if value == 'True': return True if value == 'False': return False if relaxed_bool: value = value.lower() if value in ("true", "yes"): return True elif value in ("false", "no"): return False raise ValueError("%s directive must be set to True or False, got '%s'" % ( name, orig_value)) elif type is int: try: return int(value) except ValueError: raise ValueError("%s directive must be set to an integer, got '%s'" % ( name, orig_value)) elif type is str: return str(value) elif callable(type): return type(name, value) else: assert False def parse_directive_list(s, relaxed_bool=False, ignore_unknown=False, current_settings=None): """ Parses a comma-separated list of pragma options. Whitespace is not considered. >>> parse_directive_list(' ') {} >>> (parse_directive_list('boundscheck=True') == ... {'boundscheck': True}) True >>> parse_directive_list(' asdf') Traceback (most recent call last): ... ValueError: Expected "=" in option "asdf" >>> parse_directive_list('boundscheck=hey') Traceback (most recent call last): ... ValueError: boundscheck directive must be set to True or False, got 'hey' >>> parse_directive_list('unknown=True') Traceback (most recent call last): ... ValueError: Unknown option: "unknown" >>> warnings = parse_directive_list('warn.all=True') >>> len(warnings) > 1 True >>> sum(warnings.values()) == len(warnings) # all true. True """ if current_settings is None: result = {} else: result = current_settings for item in s.split(','): item = item.strip() if not item: continue if not '=' in item: raise ValueError('Expected "=" in option "%s"' % item) name, value = [ s.strip() for s in item.strip().split('=', 1) ] if name not in directive_defaults: found = False if name.endswith('.all'): prefix = name[:-3] for directive in directive_defaults: if directive.startswith(prefix): found = True parsed_value = parse_directive_value(directive, value, relaxed_bool=relaxed_bool) result[directive] = parsed_value if not found and not ignore_unknown: raise ValueError('Unknown option: "%s"' % name) else: parsed_value = parse_directive_value(name, value, relaxed_bool=relaxed_bool) result[name] = parsed_value return result Cython-0.23.4/Cython/Compiler/Optimize.py0000644000175600017570000054612512606202452021411 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import import sys import copy import codecs from . import TypeSlots from .ExprNodes import not_a_constant import cython cython.declare(UtilityCode=object, EncodedString=object, bytes_literal=object, Nodes=object, ExprNodes=object, PyrexTypes=object, Builtin=object, UtilNodes=object, _py_int_types=object) if sys.version_info[0] >= 3: _py_int_types = int else: _py_int_types = (int, long) from . import Nodes from . import ExprNodes from . import PyrexTypes from . import Visitor from . import Builtin from . import UtilNodes from . import Options from .Code import UtilityCode, TempitaUtilityCode from .StringEncoding import EncodedString, bytes_literal from .Errors import error from .ParseTreeTransforms import SkipDeclarations try: from __builtin__ import reduce except ImportError: from functools import reduce try: from __builtin__ import basestring except ImportError: basestring = str # Python 3 def load_c_utility(name): return UtilityCode.load_cached(name, "Optimize.c") def unwrap_coerced_node(node, coercion_nodes=(ExprNodes.CoerceToPyTypeNode, ExprNodes.CoerceFromPyTypeNode)): if isinstance(node, coercion_nodes): return node.arg return node def unwrap_node(node): while isinstance(node, UtilNodes.ResultRefNode): node = node.expression return node def is_common_value(a, b): a = unwrap_node(a) b = unwrap_node(b) if isinstance(a, ExprNodes.NameNode) and isinstance(b, ExprNodes.NameNode): return a.name == b.name if isinstance(a, ExprNodes.AttributeNode) and isinstance(b, ExprNodes.AttributeNode): return not a.is_py_attr and is_common_value(a.obj, b.obj) and a.attribute == b.attribute return False def filter_none_node(node): if node is not None and node.constant_result is None: return None return node class _YieldNodeCollector(Visitor.TreeVisitor): """ YieldExprNode finder for generator expressions. """ def __init__(self): Visitor.TreeVisitor.__init__(self) self.yield_stat_nodes = {} self.yield_nodes = [] visit_Node = Visitor.TreeVisitor.visitchildren def visit_YieldExprNode(self, node): self.yield_nodes.append(node) self.visitchildren(node) def visit_ExprStatNode(self, node): self.visitchildren(node) if node.expr in self.yield_nodes: self.yield_stat_nodes[node.expr] = node # everything below these nodes is out of scope: def visit_GeneratorExpressionNode(self, node): pass def visit_LambdaNode(self, node): pass def _find_single_yield_expression(node): collector = _YieldNodeCollector() collector.visitchildren(node) if len(collector.yield_nodes) != 1: return None, None yield_node = collector.yield_nodes[0] try: return yield_node.arg, collector.yield_stat_nodes[yield_node] except KeyError: return None, None class IterationTransform(Visitor.EnvTransform): """Transform some common for-in loop patterns into efficient C loops: - for-in-dict loop becomes a while loop calling PyDict_Next() - for-in-enumerate is replaced by an external counter variable - for-in-range loop becomes a plain C for loop """ def visit_PrimaryCmpNode(self, node): if node.is_ptr_contains(): # for t in operand2: # if operand1 == t: # res = True # break # else: # res = False pos = node.pos result_ref = UtilNodes.ResultRefNode(node) if isinstance(node.operand2, ExprNodes.IndexNode): base_type = node.operand2.base.type.base_type else: base_type = node.operand2.type.base_type target_handle = UtilNodes.TempHandle(base_type) target = target_handle.ref(pos) cmp_node = ExprNodes.PrimaryCmpNode( pos, operator=u'==', operand1=node.operand1, operand2=target) if_body = Nodes.StatListNode( pos, stats = [Nodes.SingleAssignmentNode(pos, lhs=result_ref, rhs=ExprNodes.BoolNode(pos, value=1)), Nodes.BreakStatNode(pos)]) if_node = Nodes.IfStatNode( pos, if_clauses=[Nodes.IfClauseNode(pos, condition=cmp_node, body=if_body)], else_clause=None) for_loop = UtilNodes.TempsBlockNode( pos, temps = [target_handle], body = Nodes.ForInStatNode( pos, target=target, iterator=ExprNodes.IteratorNode(node.operand2.pos, sequence=node.operand2), body=if_node, else_clause=Nodes.SingleAssignmentNode(pos, lhs=result_ref, rhs=ExprNodes.BoolNode(pos, value=0)))) for_loop = for_loop.analyse_expressions(self.current_env()) for_loop = self.visit(for_loop) new_node = UtilNodes.TempResultFromStatNode(result_ref, for_loop) if node.operator == 'not_in': new_node = ExprNodes.NotNode(pos, operand=new_node) return new_node else: self.visitchildren(node) return node def visit_ForInStatNode(self, node): self.visitchildren(node) return self._optimise_for_loop(node, node.iterator.sequence) def _optimise_for_loop(self, node, iterator, reversed=False): if iterator.type is Builtin.dict_type: # like iterating over dict.keys() if reversed: # CPython raises an error here: not a sequence return node return self._transform_dict_iteration( node, dict_obj=iterator, method=None, keys=True, values=False) # C array (slice) iteration? if iterator.type.is_ptr or iterator.type.is_array: return self._transform_carray_iteration(node, iterator, reversed=reversed) if iterator.type is Builtin.bytes_type: return self._transform_bytes_iteration(node, iterator, reversed=reversed) if iterator.type is Builtin.unicode_type: return self._transform_unicode_iteration(node, iterator, reversed=reversed) # the rest is based on function calls if not isinstance(iterator, ExprNodes.SimpleCallNode): return node if iterator.args is None: arg_count = iterator.arg_tuple and len(iterator.arg_tuple.args) or 0 else: arg_count = len(iterator.args) if arg_count and iterator.self is not None: arg_count -= 1 function = iterator.function # dict iteration? if function.is_attribute and not reversed and not arg_count: base_obj = iterator.self or function.obj method = function.attribute # in Py3, items() is equivalent to Py2's iteritems() is_safe_iter = self.global_scope().context.language_level >= 3 if not is_safe_iter and method in ('keys', 'values', 'items'): # try to reduce this to the corresponding .iter*() methods if isinstance(base_obj, ExprNodes.SimpleCallNode): inner_function = base_obj.function if (inner_function.is_name and inner_function.name == 'dict' and inner_function.entry and inner_function.entry.is_builtin): # e.g. dict(something).items() => safe to use .iter*() is_safe_iter = True keys = values = False if method == 'iterkeys' or (is_safe_iter and method == 'keys'): keys = True elif method == 'itervalues' or (is_safe_iter and method == 'values'): values = True elif method == 'iteritems' or (is_safe_iter and method == 'items'): keys = values = True if keys or values: return self._transform_dict_iteration( node, base_obj, method, keys, values) # enumerate/reversed ? if iterator.self is None and function.is_name and \ function.entry and function.entry.is_builtin: if function.name == 'enumerate': if reversed: # CPython raises an error here: not a sequence return node return self._transform_enumerate_iteration(node, iterator) elif function.name == 'reversed': if reversed: # CPython raises an error here: not a sequence return node return self._transform_reversed_iteration(node, iterator) # range() iteration? if Options.convert_range and node.target.type.is_int: if iterator.self is None and function.is_name and \ function.entry and function.entry.is_builtin and \ function.name in ('range', 'xrange'): return self._transform_range_iteration(node, iterator, reversed=reversed) return node def _transform_reversed_iteration(self, node, reversed_function): args = reversed_function.arg_tuple.args if len(args) == 0: error(reversed_function.pos, "reversed() requires an iterable argument") return node elif len(args) > 1: error(reversed_function.pos, "reversed() takes exactly 1 argument") return node arg = args[0] # reversed(list/tuple) ? if arg.type in (Builtin.tuple_type, Builtin.list_type): node.iterator.sequence = arg.as_none_safe_node("'NoneType' object is not iterable") node.iterator.reversed = True return node return self._optimise_for_loop(node, arg, reversed=True) PyBytes_AS_STRING_func_type = PyrexTypes.CFuncType( PyrexTypes.c_char_ptr_type, [ PyrexTypes.CFuncTypeArg("s", Builtin.bytes_type, None) ]) PyBytes_GET_SIZE_func_type = PyrexTypes.CFuncType( PyrexTypes.c_py_ssize_t_type, [ PyrexTypes.CFuncTypeArg("s", Builtin.bytes_type, None) ]) def _transform_bytes_iteration(self, node, slice_node, reversed=False): target_type = node.target.type if not target_type.is_int and target_type is not Builtin.bytes_type: # bytes iteration returns bytes objects in Py2, but # integers in Py3 return node unpack_temp_node = UtilNodes.LetRefNode( slice_node.as_none_safe_node("'NoneType' is not iterable")) slice_base_node = ExprNodes.PythonCapiCallNode( slice_node.pos, "PyBytes_AS_STRING", self.PyBytes_AS_STRING_func_type, args = [unpack_temp_node], is_temp = 0, ) len_node = ExprNodes.PythonCapiCallNode( slice_node.pos, "PyBytes_GET_SIZE", self.PyBytes_GET_SIZE_func_type, args = [unpack_temp_node], is_temp = 0, ) return UtilNodes.LetNode( unpack_temp_node, self._transform_carray_iteration( node, ExprNodes.SliceIndexNode( slice_node.pos, base = slice_base_node, start = None, step = None, stop = len_node, type = slice_base_node.type, is_temp = 1, ), reversed = reversed)) PyUnicode_READ_func_type = PyrexTypes.CFuncType( PyrexTypes.c_py_ucs4_type, [ PyrexTypes.CFuncTypeArg("kind", PyrexTypes.c_int_type, None), PyrexTypes.CFuncTypeArg("data", PyrexTypes.c_void_ptr_type, None), PyrexTypes.CFuncTypeArg("index", PyrexTypes.c_py_ssize_t_type, None) ]) init_unicode_iteration_func_type = PyrexTypes.CFuncType( PyrexTypes.c_int_type, [ PyrexTypes.CFuncTypeArg("s", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("length", PyrexTypes.c_py_ssize_t_ptr_type, None), PyrexTypes.CFuncTypeArg("data", PyrexTypes.c_void_ptr_ptr_type, None), PyrexTypes.CFuncTypeArg("kind", PyrexTypes.c_int_ptr_type, None) ], exception_value = '-1') def _transform_unicode_iteration(self, node, slice_node, reversed=False): if slice_node.is_literal: # try to reduce to byte iteration for plain Latin-1 strings try: bytes_value = bytes_literal(slice_node.value.encode('latin1'), 'iso8859-1') except UnicodeEncodeError: pass else: bytes_slice = ExprNodes.SliceIndexNode( slice_node.pos, base=ExprNodes.BytesNode( slice_node.pos, value=bytes_value, constant_result=bytes_value, type=PyrexTypes.c_char_ptr_type).coerce_to( PyrexTypes.c_uchar_ptr_type, self.current_env()), start=None, stop=ExprNodes.IntNode( slice_node.pos, value=str(len(bytes_value)), constant_result=len(bytes_value), type=PyrexTypes.c_py_ssize_t_type), type=Builtin.unicode_type, # hint for Python conversion ) return self._transform_carray_iteration(node, bytes_slice, reversed) unpack_temp_node = UtilNodes.LetRefNode( slice_node.as_none_safe_node("'NoneType' is not iterable")) start_node = ExprNodes.IntNode( node.pos, value='0', constant_result=0, type=PyrexTypes.c_py_ssize_t_type) length_temp = UtilNodes.TempHandle(PyrexTypes.c_py_ssize_t_type) end_node = length_temp.ref(node.pos) if reversed: relation1, relation2 = '>', '>=' start_node, end_node = end_node, start_node else: relation1, relation2 = '<=', '<' kind_temp = UtilNodes.TempHandle(PyrexTypes.c_int_type) data_temp = UtilNodes.TempHandle(PyrexTypes.c_void_ptr_type) counter_temp = UtilNodes.TempHandle(PyrexTypes.c_py_ssize_t_type) target_value = ExprNodes.PythonCapiCallNode( slice_node.pos, "__Pyx_PyUnicode_READ", self.PyUnicode_READ_func_type, args = [kind_temp.ref(slice_node.pos), data_temp.ref(slice_node.pos), counter_temp.ref(node.target.pos)], is_temp = False, ) if target_value.type != node.target.type: target_value = target_value.coerce_to(node.target.type, self.current_env()) target_assign = Nodes.SingleAssignmentNode( pos = node.target.pos, lhs = node.target, rhs = target_value) body = Nodes.StatListNode( node.pos, stats = [target_assign, node.body]) loop_node = Nodes.ForFromStatNode( node.pos, bound1=start_node, relation1=relation1, target=counter_temp.ref(node.target.pos), relation2=relation2, bound2=end_node, step=None, body=body, else_clause=node.else_clause, from_range=True) setup_node = Nodes.ExprStatNode( node.pos, expr = ExprNodes.PythonCapiCallNode( slice_node.pos, "__Pyx_init_unicode_iteration", self.init_unicode_iteration_func_type, args = [unpack_temp_node, ExprNodes.AmpersandNode(slice_node.pos, operand=length_temp.ref(slice_node.pos), type=PyrexTypes.c_py_ssize_t_ptr_type), ExprNodes.AmpersandNode(slice_node.pos, operand=data_temp.ref(slice_node.pos), type=PyrexTypes.c_void_ptr_ptr_type), ExprNodes.AmpersandNode(slice_node.pos, operand=kind_temp.ref(slice_node.pos), type=PyrexTypes.c_int_ptr_type), ], is_temp = True, result_is_used = False, utility_code=UtilityCode.load_cached("unicode_iter", "Optimize.c"), )) return UtilNodes.LetNode( unpack_temp_node, UtilNodes.TempsBlockNode( node.pos, temps=[counter_temp, length_temp, data_temp, kind_temp], body=Nodes.StatListNode(node.pos, stats=[setup_node, loop_node]))) def _transform_carray_iteration(self, node, slice_node, reversed=False): neg_step = False if isinstance(slice_node, ExprNodes.SliceIndexNode): slice_base = slice_node.base start = filter_none_node(slice_node.start) stop = filter_none_node(slice_node.stop) step = None if not stop: if not slice_base.type.is_pyobject: error(slice_node.pos, "C array iteration requires known end index") return node elif isinstance(slice_node, ExprNodes.IndexNode): assert isinstance(slice_node.index, ExprNodes.SliceNode) slice_base = slice_node.base index = slice_node.index start = filter_none_node(index.start) stop = filter_none_node(index.stop) step = filter_none_node(index.step) if step: if not isinstance(step.constant_result, _py_int_types) \ or step.constant_result == 0 \ or step.constant_result > 0 and not stop \ or step.constant_result < 0 and not start: if not slice_base.type.is_pyobject: error(step.pos, "C array iteration requires known step size and end index") return node else: # step sign is handled internally by ForFromStatNode step_value = step.constant_result if reversed: step_value = -step_value neg_step = step_value < 0 step = ExprNodes.IntNode(step.pos, type=PyrexTypes.c_py_ssize_t_type, value=str(abs(step_value)), constant_result=abs(step_value)) elif slice_node.type.is_array: if slice_node.type.size is None: error(slice_node.pos, "C array iteration requires known end index") return node slice_base = slice_node start = None stop = ExprNodes.IntNode( slice_node.pos, value=str(slice_node.type.size), type=PyrexTypes.c_py_ssize_t_type, constant_result=slice_node.type.size) step = None else: if not slice_node.type.is_pyobject: error(slice_node.pos, "C array iteration requires known end index") return node if start: start = start.coerce_to(PyrexTypes.c_py_ssize_t_type, self.current_env()) if stop: stop = stop.coerce_to(PyrexTypes.c_py_ssize_t_type, self.current_env()) if stop is None: if neg_step: stop = ExprNodes.IntNode( slice_node.pos, value='-1', type=PyrexTypes.c_py_ssize_t_type, constant_result=-1) else: error(slice_node.pos, "C array iteration requires known step size and end index") return node if reversed: if not start: start = ExprNodes.IntNode(slice_node.pos, value="0", constant_result=0, type=PyrexTypes.c_py_ssize_t_type) # if step was provided, it was already negated above start, stop = stop, start ptr_type = slice_base.type if ptr_type.is_array: ptr_type = ptr_type.element_ptr_type() carray_ptr = slice_base.coerce_to_simple(self.current_env()) if start and start.constant_result != 0: start_ptr_node = ExprNodes.AddNode( start.pos, operand1=carray_ptr, operator='+', operand2=start, type=ptr_type) else: start_ptr_node = carray_ptr if stop and stop.constant_result != 0: stop_ptr_node = ExprNodes.AddNode( stop.pos, operand1=ExprNodes.CloneNode(carray_ptr), operator='+', operand2=stop, type=ptr_type ).coerce_to_simple(self.current_env()) else: stop_ptr_node = ExprNodes.CloneNode(carray_ptr) counter = UtilNodes.TempHandle(ptr_type) counter_temp = counter.ref(node.target.pos) if slice_base.type.is_string and node.target.type.is_pyobject: # special case: char* -> bytes/unicode if slice_node.type is Builtin.unicode_type: target_value = ExprNodes.CastNode( ExprNodes.DereferenceNode( node.target.pos, operand=counter_temp, type=ptr_type.base_type), PyrexTypes.c_py_ucs4_type).coerce_to( node.target.type, self.current_env()) else: # char* -> bytes coercion requires slicing, not indexing target_value = ExprNodes.SliceIndexNode( node.target.pos, start=ExprNodes.IntNode(node.target.pos, value='0', constant_result=0, type=PyrexTypes.c_int_type), stop=ExprNodes.IntNode(node.target.pos, value='1', constant_result=1, type=PyrexTypes.c_int_type), base=counter_temp, type=Builtin.bytes_type, is_temp=1) elif node.target.type.is_ptr and not node.target.type.assignable_from(ptr_type.base_type): # Allow iteration with pointer target to avoid copy. target_value = counter_temp else: # TODO: can this safely be replaced with DereferenceNode() as above? target_value = ExprNodes.IndexNode( node.target.pos, index=ExprNodes.IntNode(node.target.pos, value='0', constant_result=0, type=PyrexTypes.c_int_type), base=counter_temp, is_buffer_access=False, type=ptr_type.base_type) if target_value.type != node.target.type: target_value = target_value.coerce_to(node.target.type, self.current_env()) target_assign = Nodes.SingleAssignmentNode( pos = node.target.pos, lhs = node.target, rhs = target_value) body = Nodes.StatListNode( node.pos, stats = [target_assign, node.body]) relation1, relation2 = self._find_for_from_node_relations(neg_step, reversed) for_node = Nodes.ForFromStatNode( node.pos, bound1=start_ptr_node, relation1=relation1, target=counter_temp, relation2=relation2, bound2=stop_ptr_node, step=step, body=body, else_clause=node.else_clause, from_range=True) return UtilNodes.TempsBlockNode( node.pos, temps=[counter], body=for_node) def _transform_enumerate_iteration(self, node, enumerate_function): args = enumerate_function.arg_tuple.args if len(args) == 0: error(enumerate_function.pos, "enumerate() requires an iterable argument") return node elif len(args) > 2: error(enumerate_function.pos, "enumerate() takes at most 2 arguments") return node if not node.target.is_sequence_constructor: # leave this untouched for now return node targets = node.target.args if len(targets) != 2: # leave this untouched for now return node enumerate_target, iterable_target = targets counter_type = enumerate_target.type if not counter_type.is_pyobject and not counter_type.is_int: # nothing we can do here, I guess return node if len(args) == 2: start = unwrap_coerced_node(args[1]).coerce_to(counter_type, self.current_env()) else: start = ExprNodes.IntNode(enumerate_function.pos, value='0', type=counter_type, constant_result=0) temp = UtilNodes.LetRefNode(start) inc_expression = ExprNodes.AddNode( enumerate_function.pos, operand1 = temp, operand2 = ExprNodes.IntNode(node.pos, value='1', type=counter_type, constant_result=1), operator = '+', type = counter_type, #inplace = True, # not worth using in-place operation for Py ints is_temp = counter_type.is_pyobject ) loop_body = [ Nodes.SingleAssignmentNode( pos = enumerate_target.pos, lhs = enumerate_target, rhs = temp), Nodes.SingleAssignmentNode( pos = enumerate_target.pos, lhs = temp, rhs = inc_expression) ] if isinstance(node.body, Nodes.StatListNode): node.body.stats = loop_body + node.body.stats else: loop_body.append(node.body) node.body = Nodes.StatListNode( node.body.pos, stats = loop_body) node.target = iterable_target node.item = node.item.coerce_to(iterable_target.type, self.current_env()) node.iterator.sequence = args[0] # recurse into loop to check for further optimisations return UtilNodes.LetNode(temp, self._optimise_for_loop(node, node.iterator.sequence)) def _find_for_from_node_relations(self, neg_step_value, reversed): if reversed: if neg_step_value: return '<', '<=' else: return '>', '>=' else: if neg_step_value: return '>=', '>' else: return '<=', '<' def _transform_range_iteration(self, node, range_function, reversed=False): args = range_function.arg_tuple.args if len(args) < 3: step_pos = range_function.pos step_value = 1 step = ExprNodes.IntNode(step_pos, value='1', constant_result=1) else: step = args[2] step_pos = step.pos if not isinstance(step.constant_result, _py_int_types): # cannot determine step direction return node step_value = step.constant_result if step_value == 0: # will lead to an error elsewhere return node step = ExprNodes.IntNode(step_pos, value=str(step_value), constant_result=step_value) if len(args) == 1: bound1 = ExprNodes.IntNode(range_function.pos, value='0', constant_result=0) bound2 = args[0].coerce_to_integer(self.current_env()) else: bound1 = args[0].coerce_to_integer(self.current_env()) bound2 = args[1].coerce_to_integer(self.current_env()) relation1, relation2 = self._find_for_from_node_relations(step_value < 0, reversed) bound2_ref_node = None if reversed: bound1, bound2 = bound2, bound1 abs_step = abs(step_value) if abs_step != 1: if (isinstance(bound1.constant_result, _py_int_types) and isinstance(bound2.constant_result, _py_int_types)): # calculate final bounds now if step_value < 0: begin_value = bound2.constant_result end_value = bound1.constant_result bound1_value = begin_value - abs_step * ((begin_value - end_value - 1) // abs_step) - 1 else: begin_value = bound1.constant_result end_value = bound2.constant_result bound1_value = end_value + abs_step * ((begin_value - end_value - 1) // abs_step) + 1 bound1 = ExprNodes.IntNode( bound1.pos, value=str(bound1_value), constant_result=bound1_value, type=PyrexTypes.spanning_type(bound1.type, bound2.type)) else: # evaluate the same expression as above at runtime bound2_ref_node = UtilNodes.LetRefNode(bound2) spanning_type = PyrexTypes.spanning_type(bound1.type, bound2.type) if step.type.is_int and abs(step_value) < 0x7FFF: # Avoid loss of integer precision warnings. spanning_step_type = PyrexTypes.spanning_type(spanning_type, PyrexTypes.c_int_type) else: spanning_step_type = PyrexTypes.spanning_type(spanning_type, step.type) if step_value < 0: begin_value = bound2_ref_node end_value = bound1 final_op = '-' else: begin_value = bound1 end_value = bound2_ref_node final_op = '+' bound1 = ExprNodes.binop_node( bound1.pos, operand1=ExprNodes.binop_node( bound1.pos, operand1=bound2_ref_node, operator=final_op, # +/- operand2=ExprNodes.MulNode( bound1.pos, operand1=ExprNodes.IntNode( bound1.pos, value=str(abs_step), constant_value=abs_step, type=spanning_step_type), operator='*', operand2=ExprNodes.DivNode( bound1.pos, operand1=ExprNodes.SubNode( bound1.pos, operand1=ExprNodes.SubNode( bound1.pos, operand1=begin_value, operator='-', operand2=end_value, type=spanning_type), operator='-', operand2=ExprNodes.IntNode( bound1.pos, value='1', constant_result=1), type=spanning_step_type), operator='//', operand2=ExprNodes.IntNode( bound1.pos, value=str(abs_step), constant_value=abs_step, type=spanning_step_type), type=spanning_step_type), type=spanning_step_type), type=spanning_step_type), operator=final_op, # +/- operand2=ExprNodes.IntNode( bound1.pos, value='1', constant_result=1), type=spanning_type) if step_value < 0: step_value = -step_value step.value = str(step_value) step.constant_result = step_value step = step.coerce_to_integer(self.current_env()) if not bound2.is_literal: # stop bound must be immutable => keep it in a temp var bound2_is_temp = True bound2 = bound2_ref_node or UtilNodes.LetRefNode(bound2) else: bound2_is_temp = False for_node = Nodes.ForFromStatNode( node.pos, target=node.target, bound1=bound1, relation1=relation1, relation2=relation2, bound2=bound2, step=step, body=node.body, else_clause=node.else_clause, from_range=True) if bound2_is_temp: for_node = UtilNodes.LetNode(bound2, for_node) return for_node def _transform_dict_iteration(self, node, dict_obj, method, keys, values): temps = [] temp = UtilNodes.TempHandle(PyrexTypes.py_object_type) temps.append(temp) dict_temp = temp.ref(dict_obj.pos) temp = UtilNodes.TempHandle(PyrexTypes.c_py_ssize_t_type) temps.append(temp) pos_temp = temp.ref(node.pos) key_target = value_target = tuple_target = None if keys and values: if node.target.is_sequence_constructor: if len(node.target.args) == 2: key_target, value_target = node.target.args else: # unusual case that may or may not lead to an error return node else: tuple_target = node.target elif keys: key_target = node.target else: value_target = node.target if isinstance(node.body, Nodes.StatListNode): body = node.body else: body = Nodes.StatListNode(pos = node.body.pos, stats = [node.body]) # keep original length to guard against dict modification dict_len_temp = UtilNodes.TempHandle(PyrexTypes.c_py_ssize_t_type) temps.append(dict_len_temp) dict_len_temp_addr = ExprNodes.AmpersandNode( node.pos, operand=dict_len_temp.ref(dict_obj.pos), type=PyrexTypes.c_ptr_type(dict_len_temp.type)) temp = UtilNodes.TempHandle(PyrexTypes.c_int_type) temps.append(temp) is_dict_temp = temp.ref(node.pos) is_dict_temp_addr = ExprNodes.AmpersandNode( node.pos, operand=is_dict_temp, type=PyrexTypes.c_ptr_type(temp.type)) iter_next_node = Nodes.DictIterationNextNode( dict_temp, dict_len_temp.ref(dict_obj.pos), pos_temp, key_target, value_target, tuple_target, is_dict_temp) iter_next_node = iter_next_node.analyse_expressions(self.current_env()) body.stats[0:0] = [iter_next_node] if method: method_node = ExprNodes.StringNode( dict_obj.pos, is_identifier=True, value=method) dict_obj = dict_obj.as_none_safe_node( "'NoneType' object has no attribute '%s'", error = "PyExc_AttributeError", format_args = [method]) else: method_node = ExprNodes.NullNode(dict_obj.pos) dict_obj = dict_obj.as_none_safe_node("'NoneType' object is not iterable") def flag_node(value): value = value and 1 or 0 return ExprNodes.IntNode(node.pos, value=str(value), constant_result=value) result_code = [ Nodes.SingleAssignmentNode( node.pos, lhs = pos_temp, rhs = ExprNodes.IntNode(node.pos, value='0', constant_result=0)), Nodes.SingleAssignmentNode( dict_obj.pos, lhs = dict_temp, rhs = ExprNodes.PythonCapiCallNode( dict_obj.pos, "__Pyx_dict_iterator", self.PyDict_Iterator_func_type, utility_code = UtilityCode.load_cached("dict_iter", "Optimize.c"), args = [dict_obj, flag_node(dict_obj.type is Builtin.dict_type), method_node, dict_len_temp_addr, is_dict_temp_addr, ], is_temp=True, )), Nodes.WhileStatNode( node.pos, condition = None, body = body, else_clause = node.else_clause ) ] return UtilNodes.TempsBlockNode( node.pos, temps=temps, body=Nodes.StatListNode( node.pos, stats = result_code )) PyDict_Iterator_func_type = PyrexTypes.CFuncType( PyrexTypes.py_object_type, [ PyrexTypes.CFuncTypeArg("dict", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("is_dict", PyrexTypes.c_int_type, None), PyrexTypes.CFuncTypeArg("method_name", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("p_orig_length", PyrexTypes.c_py_ssize_t_ptr_type, None), PyrexTypes.CFuncTypeArg("p_is_dict", PyrexTypes.c_int_ptr_type, None), ]) class SwitchTransform(Visitor.EnvTransform): """ This transformation tries to turn long if statements into C switch statements. The requirement is that every clause be an (or of) var == value, where the var is common among all clauses and both var and value are ints. """ NO_MATCH = (None, None, None) def extract_conditions(self, cond, allow_not_in): while True: if isinstance(cond, (ExprNodes.CoerceToTempNode, ExprNodes.CoerceToBooleanNode)): cond = cond.arg elif isinstance(cond, ExprNodes.BoolBinopResultNode): cond = cond.arg.arg elif isinstance(cond, UtilNodes.EvalWithTempExprNode): # this is what we get from the FlattenInListTransform cond = cond.subexpression elif isinstance(cond, ExprNodes.TypecastNode): cond = cond.operand else: break if isinstance(cond, ExprNodes.PrimaryCmpNode): if cond.cascade is not None: return self.NO_MATCH elif cond.is_c_string_contains() and \ isinstance(cond.operand2, (ExprNodes.UnicodeNode, ExprNodes.BytesNode)): not_in = cond.operator == 'not_in' if not_in and not allow_not_in: return self.NO_MATCH if isinstance(cond.operand2, ExprNodes.UnicodeNode) and \ cond.operand2.contains_surrogates(): # dealing with surrogates leads to different # behaviour on wide and narrow Unicode # platforms => refuse to optimise this case return self.NO_MATCH return not_in, cond.operand1, self.extract_in_string_conditions(cond.operand2) elif not cond.is_python_comparison(): if cond.operator == '==': not_in = False elif allow_not_in and cond.operator == '!=': not_in = True else: return self.NO_MATCH # this looks somewhat silly, but it does the right # checks for NameNode and AttributeNode if is_common_value(cond.operand1, cond.operand1): if cond.operand2.is_literal: return not_in, cond.operand1, [cond.operand2] elif getattr(cond.operand2, 'entry', None) \ and cond.operand2.entry.is_const: return not_in, cond.operand1, [cond.operand2] if is_common_value(cond.operand2, cond.operand2): if cond.operand1.is_literal: return not_in, cond.operand2, [cond.operand1] elif getattr(cond.operand1, 'entry', None) \ and cond.operand1.entry.is_const: return not_in, cond.operand2, [cond.operand1] elif isinstance(cond, ExprNodes.BoolBinopNode): if cond.operator == 'or' or (allow_not_in and cond.operator == 'and'): allow_not_in = (cond.operator == 'and') not_in_1, t1, c1 = self.extract_conditions(cond.operand1, allow_not_in) not_in_2, t2, c2 = self.extract_conditions(cond.operand2, allow_not_in) if t1 is not None and not_in_1 == not_in_2 and is_common_value(t1, t2): if (not not_in_1) or allow_not_in: return not_in_1, t1, c1+c2 return self.NO_MATCH def extract_in_string_conditions(self, string_literal): if isinstance(string_literal, ExprNodes.UnicodeNode): charvals = list(map(ord, set(string_literal.value))) charvals.sort() return [ ExprNodes.IntNode(string_literal.pos, value=str(charval), constant_result=charval) for charval in charvals ] else: # this is a bit tricky as Py3's bytes type returns # integers on iteration, whereas Py2 returns 1-char byte # strings characters = string_literal.value characters = list(set([ characters[i:i+1] for i in range(len(characters)) ])) characters.sort() return [ ExprNodes.CharNode(string_literal.pos, value=charval, constant_result=charval) for charval in characters ] def extract_common_conditions(self, common_var, condition, allow_not_in): not_in, var, conditions = self.extract_conditions(condition, allow_not_in) if var is None: return self.NO_MATCH elif common_var is not None and not is_common_value(var, common_var): return self.NO_MATCH elif not (var.type.is_int or var.type.is_enum) or sum([not (cond.type.is_int or cond.type.is_enum) for cond in conditions]): return self.NO_MATCH return not_in, var, conditions def has_duplicate_values(self, condition_values): # duplicated values don't work in a switch statement seen = set() for value in condition_values: if value.has_constant_result(): if value.constant_result in seen: return True seen.add(value.constant_result) else: # this isn't completely safe as we don't know the # final C value, but this is about the best we can do try: if value.entry.cname in seen: return True except AttributeError: return True # play safe seen.add(value.entry.cname) return False def visit_IfStatNode(self, node): if not self.current_directives.get('optimize.use_switch'): self.visitchildren(node) return node common_var = None cases = [] for if_clause in node.if_clauses: _, common_var, conditions = self.extract_common_conditions( common_var, if_clause.condition, False) if common_var is None: self.visitchildren(node) return node cases.append(Nodes.SwitchCaseNode(pos = if_clause.pos, conditions = conditions, body = if_clause.body)) condition_values = [ cond for case in cases for cond in case.conditions] if len(condition_values) < 2: self.visitchildren(node) return node if self.has_duplicate_values(condition_values): self.visitchildren(node) return node common_var = unwrap_node(common_var) switch_node = Nodes.SwitchStatNode(pos = node.pos, test = common_var, cases = cases, else_clause = node.else_clause) return switch_node def visit_CondExprNode(self, node): if not self.current_directives.get('optimize.use_switch'): self.visitchildren(node) return node not_in, common_var, conditions = self.extract_common_conditions( None, node.test, True) if common_var is None \ or len(conditions) < 2 \ or self.has_duplicate_values(conditions): self.visitchildren(node) return node return self.build_simple_switch_statement( node, common_var, conditions, not_in, node.true_val, node.false_val) def visit_BoolBinopNode(self, node): if not self.current_directives.get('optimize.use_switch'): self.visitchildren(node) return node not_in, common_var, conditions = self.extract_common_conditions( None, node, True) if common_var is None \ or len(conditions) < 2 \ or self.has_duplicate_values(conditions): self.visitchildren(node) node.wrap_operands(self.current_env()) # in case we changed the operands return node return self.build_simple_switch_statement( node, common_var, conditions, not_in, ExprNodes.BoolNode(node.pos, value=True, constant_result=True), ExprNodes.BoolNode(node.pos, value=False, constant_result=False)) def visit_PrimaryCmpNode(self, node): if not self.current_directives.get('optimize.use_switch'): self.visitchildren(node) return node not_in, common_var, conditions = self.extract_common_conditions( None, node, True) if common_var is None \ or len(conditions) < 2 \ or self.has_duplicate_values(conditions): self.visitchildren(node) return node return self.build_simple_switch_statement( node, common_var, conditions, not_in, ExprNodes.BoolNode(node.pos, value=True, constant_result=True), ExprNodes.BoolNode(node.pos, value=False, constant_result=False)) def build_simple_switch_statement(self, node, common_var, conditions, not_in, true_val, false_val): result_ref = UtilNodes.ResultRefNode(node) true_body = Nodes.SingleAssignmentNode( node.pos, lhs=result_ref, rhs=true_val.coerce_to(node.type, self.current_env()), first=True) false_body = Nodes.SingleAssignmentNode( node.pos, lhs=result_ref, rhs=false_val.coerce_to(node.type, self.current_env()), first=True) if not_in: true_body, false_body = false_body, true_body cases = [Nodes.SwitchCaseNode(pos = node.pos, conditions = conditions, body = true_body)] common_var = unwrap_node(common_var) switch_node = Nodes.SwitchStatNode(pos = node.pos, test = common_var, cases = cases, else_clause = false_body) replacement = UtilNodes.TempResultFromStatNode(result_ref, switch_node) return replacement def visit_EvalWithTempExprNode(self, node): if not self.current_directives.get('optimize.use_switch'): self.visitchildren(node) return node # drop unused expression temp from FlattenInListTransform orig_expr = node.subexpression temp_ref = node.lazy_temp self.visitchildren(node) if node.subexpression is not orig_expr: # node was restructured => check if temp is still used if not Visitor.tree_contains(node.subexpression, temp_ref): return node.subexpression return node visit_Node = Visitor.VisitorTransform.recurse_to_children class FlattenInListTransform(Visitor.VisitorTransform, SkipDeclarations): """ This transformation flattens "x in [val1, ..., valn]" into a sequential list of comparisons. """ def visit_PrimaryCmpNode(self, node): self.visitchildren(node) if node.cascade is not None: return node elif node.operator == 'in': conjunction = 'or' eq_or_neq = '==' elif node.operator == 'not_in': conjunction = 'and' eq_or_neq = '!=' else: return node if not isinstance(node.operand2, (ExprNodes.TupleNode, ExprNodes.ListNode, ExprNodes.SetNode)): return node args = node.operand2.args if len(args) == 0: # note: lhs may have side effects return node lhs = UtilNodes.ResultRefNode(node.operand1) conds = [] temps = [] for arg in args: try: # Trial optimisation to avoid redundant temp # assignments. However, since is_simple() is meant to # be called after type analysis, we ignore any errors # and just play safe in that case. is_simple_arg = arg.is_simple() except Exception: is_simple_arg = False if not is_simple_arg: # must evaluate all non-simple RHS before doing the comparisons arg = UtilNodes.LetRefNode(arg) temps.append(arg) cond = ExprNodes.PrimaryCmpNode( pos = node.pos, operand1 = lhs, operator = eq_or_neq, operand2 = arg, cascade = None) conds.append(ExprNodes.TypecastNode( pos = node.pos, operand = cond, type = PyrexTypes.c_bint_type)) def concat(left, right): return ExprNodes.BoolBinopNode( pos = node.pos, operator = conjunction, operand1 = left, operand2 = right) condition = reduce(concat, conds) new_node = UtilNodes.EvalWithTempExprNode(lhs, condition) for temp in temps[::-1]: new_node = UtilNodes.EvalWithTempExprNode(temp, new_node) return new_node visit_Node = Visitor.VisitorTransform.recurse_to_children class DropRefcountingTransform(Visitor.VisitorTransform): """Drop ref-counting in safe places. """ visit_Node = Visitor.VisitorTransform.recurse_to_children def visit_ParallelAssignmentNode(self, node): """ Parallel swap assignments like 'a,b = b,a' are safe. """ left_names, right_names = [], [] left_indices, right_indices = [], [] temps = [] for stat in node.stats: if isinstance(stat, Nodes.SingleAssignmentNode): if not self._extract_operand(stat.lhs, left_names, left_indices, temps): return node if not self._extract_operand(stat.rhs, right_names, right_indices, temps): return node elif isinstance(stat, Nodes.CascadedAssignmentNode): # FIXME return node else: return node if left_names or right_names: # lhs/rhs names must be a non-redundant permutation lnames = [ path for path, n in left_names ] rnames = [ path for path, n in right_names ] if set(lnames) != set(rnames): return node if len(set(lnames)) != len(right_names): return node if left_indices or right_indices: # base name and index of index nodes must be a # non-redundant permutation lindices = [] for lhs_node in left_indices: index_id = self._extract_index_id(lhs_node) if not index_id: return node lindices.append(index_id) rindices = [] for rhs_node in right_indices: index_id = self._extract_index_id(rhs_node) if not index_id: return node rindices.append(index_id) if set(lindices) != set(rindices): return node if len(set(lindices)) != len(right_indices): return node # really supporting IndexNode requires support in # __Pyx_GetItemInt(), so let's stop short for now return node temp_args = [t.arg for t in temps] for temp in temps: temp.use_managed_ref = False for _, name_node in left_names + right_names: if name_node not in temp_args: name_node.use_managed_ref = False for index_node in left_indices + right_indices: index_node.use_managed_ref = False return node def _extract_operand(self, node, names, indices, temps): node = unwrap_node(node) if not node.type.is_pyobject: return False if isinstance(node, ExprNodes.CoerceToTempNode): temps.append(node) node = node.arg name_path = [] obj_node = node while isinstance(obj_node, ExprNodes.AttributeNode): if obj_node.is_py_attr: return False name_path.append(obj_node.member) obj_node = obj_node.obj if isinstance(obj_node, ExprNodes.NameNode): name_path.append(obj_node.name) names.append( ('.'.join(name_path[::-1]), node) ) elif isinstance(node, ExprNodes.IndexNode): if node.base.type != Builtin.list_type: return False if not node.index.type.is_int: return False if not isinstance(node.base, ExprNodes.NameNode): return False indices.append(node) else: return False return True def _extract_index_id(self, index_node): base = index_node.base index = index_node.index if isinstance(index, ExprNodes.NameNode): index_val = index.name elif isinstance(index, ExprNodes.ConstNode): # FIXME: return None else: return None return (base.name, index_val) class EarlyReplaceBuiltinCalls(Visitor.EnvTransform): """Optimize some common calls to builtin types *before* the type analysis phase and *after* the declarations analysis phase. This transform cannot make use of any argument types, but it can restructure the tree in a way that the type analysis phase can respond to. Introducing C function calls here may not be a good idea. Move them to the OptimizeBuiltinCalls transform instead, which runs after type analysis. """ # only intercept on call nodes visit_Node = Visitor.VisitorTransform.recurse_to_children def visit_SimpleCallNode(self, node): self.visitchildren(node) function = node.function if not self._function_is_builtin_name(function): return node return self._dispatch_to_handler(node, function, node.args) def visit_GeneralCallNode(self, node): self.visitchildren(node) function = node.function if not self._function_is_builtin_name(function): return node arg_tuple = node.positional_args if not isinstance(arg_tuple, ExprNodes.TupleNode): return node args = arg_tuple.args return self._dispatch_to_handler( node, function, args, node.keyword_args) def _function_is_builtin_name(self, function): if not function.is_name: return False env = self.current_env() entry = env.lookup(function.name) if entry is not env.builtin_scope().lookup_here(function.name): return False # if entry is None, it's at least an undeclared name, so likely builtin return True def _dispatch_to_handler(self, node, function, args, kwargs=None): if kwargs is None: handler_name = '_handle_simple_function_%s' % function.name else: handler_name = '_handle_general_function_%s' % function.name handle_call = getattr(self, handler_name, None) if handle_call is not None: if kwargs is None: return handle_call(node, args) else: return handle_call(node, args, kwargs) return node def _inject_capi_function(self, node, cname, func_type, utility_code=None): node.function = ExprNodes.PythonCapiFunctionNode( node.function.pos, node.function.name, cname, func_type, utility_code = utility_code) def _error_wrong_arg_count(self, function_name, node, args, expected=None): if not expected: # None or 0 arg_str = '' elif isinstance(expected, basestring) or expected > 1: arg_str = '...' elif expected == 1: arg_str = 'x' else: arg_str = '' if expected is not None: expected_str = 'expected %s, ' % expected else: expected_str = '' error(node.pos, "%s(%s) called with wrong number of args, %sfound %d" % ( function_name, arg_str, expected_str, len(args))) # specific handlers for simple call nodes def _handle_simple_function_float(self, node, pos_args): if not pos_args: return ExprNodes.FloatNode(node.pos, value='0.0') if len(pos_args) > 1: self._error_wrong_arg_count('float', node, pos_args, 1) arg_type = getattr(pos_args[0], 'type', None) if arg_type in (PyrexTypes.c_double_type, Builtin.float_type): return pos_args[0] return node def _handle_simple_function_slice(self, node, pos_args): arg_count = len(pos_args) start = step = None if arg_count == 1: stop, = pos_args elif arg_count == 2: start, stop = pos_args elif arg_count == 3: start, stop, step = pos_args else: self._error_wrong_arg_count('slice', node, pos_args) return node return ExprNodes.SliceNode( node.pos, start=start or ExprNodes.NoneNode(node.pos), stop=stop, step=step or ExprNodes.NoneNode(node.pos)) def _handle_simple_function_ord(self, node, pos_args): """Unpack ord('X'). """ if len(pos_args) != 1: return node arg = pos_args[0] if isinstance(arg, (ExprNodes.UnicodeNode, ExprNodes.BytesNode)): if len(arg.value) == 1: return ExprNodes.IntNode( arg.pos, type=PyrexTypes.c_long_type, value=str(ord(arg.value)), constant_result=ord(arg.value) ) elif isinstance(arg, ExprNodes.StringNode): if arg.unicode_value and len(arg.unicode_value) == 1 \ and ord(arg.unicode_value) <= 255: # Py2/3 portability return ExprNodes.IntNode( arg.pos, type=PyrexTypes.c_int_type, value=str(ord(arg.unicode_value)), constant_result=ord(arg.unicode_value) ) return node # sequence processing def _handle_simple_function_all(self, node, pos_args): """Transform _result = all(x for L in LL for x in L) into for L in LL: for x in L: if not x: _result = False break else: continue break else: _result = True """ return self._transform_any_all(node, pos_args, False) def _handle_simple_function_any(self, node, pos_args): """Transform _result = any(x for L in LL for x in L) into for L in LL: for x in L: if x: _result = True break else: continue break else: _result = False """ return self._transform_any_all(node, pos_args, True) def _transform_any_all(self, node, pos_args, is_any): if len(pos_args) != 1: return node if not isinstance(pos_args[0], ExprNodes.GeneratorExpressionNode): return node gen_expr_node = pos_args[0] generator_body = gen_expr_node.def_node.gbody loop_node = generator_body.body yield_expression, yield_stat_node = _find_single_yield_expression(loop_node) if yield_expression is None: return node if is_any: condition = yield_expression else: condition = ExprNodes.NotNode(yield_expression.pos, operand=yield_expression) test_node = Nodes.IfStatNode( yield_expression.pos, else_clause=None, if_clauses=[ Nodes.IfClauseNode( yield_expression.pos, condition=condition, body=Nodes.ReturnStatNode( node.pos, value=ExprNodes.BoolNode(yield_expression.pos, value=is_any, constant_result=is_any)) )] ) loop = loop_node while isinstance(loop.body, Nodes.LoopNode): next_loop = loop.body loop.body = Nodes.StatListNode(loop.body.pos, stats=[ loop.body, Nodes.BreakStatNode(yield_expression.pos) ]) next_loop.else_clause = Nodes.ContinueStatNode(yield_expression.pos) loop = next_loop loop_node.else_clause = Nodes.ReturnStatNode( node.pos, value=ExprNodes.BoolNode(yield_expression.pos, value=not is_any, constant_result=not is_any)) Visitor.recursively_replace_node(gen_expr_node, yield_stat_node, test_node) return ExprNodes.InlinedGeneratorExpressionNode( gen_expr_node.pos, gen=gen_expr_node, orig_func='any' if is_any else 'all') PySequence_List_func_type = PyrexTypes.CFuncType( Builtin.list_type, [PyrexTypes.CFuncTypeArg("it", PyrexTypes.py_object_type, None)]) def _handle_simple_function_sorted(self, node, pos_args): """Transform sorted(genexpr) and sorted([listcomp]) into [listcomp].sort(). CPython just reads the iterable into a list and calls .sort() on it. Expanding the iterable in a listcomp is still faster and the result can be sorted in place. """ if len(pos_args) != 1: return node arg = pos_args[0] if isinstance(arg, ExprNodes.ComprehensionNode) and arg.type is Builtin.list_type: list_node = pos_args[0] loop_node = list_node.loop elif isinstance(arg, ExprNodes.GeneratorExpressionNode): gen_expr_node = arg loop_node = gen_expr_node.loop yield_expression, yield_stat_node = _find_single_yield_expression(loop_node) if yield_expression is None: return node list_node = ExprNodes.InlinedGeneratorExpressionNode( node.pos, gen_expr_node, orig_func='sorted', comprehension_type=Builtin.list_type) append_node = ExprNodes.ComprehensionAppendNode( yield_expression.pos, expr=yield_expression, target=list_node.target) Visitor.recursively_replace_node(gen_expr_node, yield_stat_node, append_node) elif arg.is_sequence_constructor: # sorted([a, b, c]) or sorted((a, b, c)). The result is always a list, # so starting off with a fresh one is more efficient. list_node = loop_node = arg.as_list() else: # Interestingly, PySequence_List works on a lot of non-sequence # things as well. list_node = loop_node = ExprNodes.PythonCapiCallNode( node.pos, "PySequence_List", self.PySequence_List_func_type, args=pos_args, is_temp=True) result_node = UtilNodes.ResultRefNode( pos=loop_node.pos, type=Builtin.list_type, may_hold_none=False) list_assign_node = Nodes.SingleAssignmentNode( node.pos, lhs=result_node, rhs=list_node, first=True) sort_method = ExprNodes.AttributeNode( node.pos, obj=result_node, attribute=EncodedString('sort'), # entry ? type ? needs_none_check=False) sort_node = Nodes.ExprStatNode( node.pos, expr=ExprNodes.SimpleCallNode( node.pos, function=sort_method, args=[])) sort_node.analyse_declarations(self.current_env()) return UtilNodes.TempResultFromStatNode( result_node, Nodes.StatListNode(node.pos, stats=[list_assign_node, sort_node])) def __handle_simple_function_sum(self, node, pos_args): """Transform sum(genexpr) into an equivalent inlined aggregation loop. """ if len(pos_args) not in (1,2): return node if not isinstance(pos_args[0], (ExprNodes.GeneratorExpressionNode, ExprNodes.ComprehensionNode)): return node gen_expr_node = pos_args[0] loop_node = gen_expr_node.loop if isinstance(gen_expr_node, ExprNodes.GeneratorExpressionNode): yield_expression, yield_stat_node = _find_single_yield_expression(loop_node) # FIXME: currently nonfunctional yield_expression = None if yield_expression is None: return node else: # ComprehensionNode yield_stat_node = gen_expr_node.append yield_expression = yield_stat_node.expr try: if not yield_expression.is_literal or not yield_expression.type.is_int: return node except AttributeError: return node # in case we don't have a type yet # special case: old Py2 backwards compatible "sum([int_const for ...])" # can safely be unpacked into a genexpr if len(pos_args) == 1: start = ExprNodes.IntNode(node.pos, value='0', constant_result=0) else: start = pos_args[1] result_ref = UtilNodes.ResultRefNode(pos=node.pos, type=PyrexTypes.py_object_type) add_node = Nodes.SingleAssignmentNode( yield_expression.pos, lhs = result_ref, rhs = ExprNodes.binop_node(node.pos, '+', result_ref, yield_expression) ) Visitor.recursively_replace_node(gen_expr_node, yield_stat_node, add_node) exec_code = Nodes.StatListNode( node.pos, stats = [ Nodes.SingleAssignmentNode( start.pos, lhs = UtilNodes.ResultRefNode(pos=node.pos, expression=result_ref), rhs = start, first = True), loop_node ]) return ExprNodes.InlinedGeneratorExpressionNode( gen_expr_node.pos, loop = exec_code, result_node = result_ref, expr_scope = gen_expr_node.expr_scope, orig_func = 'sum', has_local_scope = gen_expr_node.has_local_scope) def _handle_simple_function_min(self, node, pos_args): return self._optimise_min_max(node, pos_args, '<') def _handle_simple_function_max(self, node, pos_args): return self._optimise_min_max(node, pos_args, '>') def _optimise_min_max(self, node, args, operator): """Replace min(a,b,...) and max(a,b,...) by explicit comparison code. """ if len(args) <= 1: if len(args) == 1 and args[0].is_sequence_constructor: args = args[0].args if len(args) <= 1: # leave this to Python return node cascaded_nodes = list(map(UtilNodes.ResultRefNode, args[1:])) last_result = args[0] for arg_node in cascaded_nodes: result_ref = UtilNodes.ResultRefNode(last_result) last_result = ExprNodes.CondExprNode( arg_node.pos, true_val = arg_node, false_val = result_ref, test = ExprNodes.PrimaryCmpNode( arg_node.pos, operand1 = arg_node, operator = operator, operand2 = result_ref, ) ) last_result = UtilNodes.EvalWithTempExprNode(result_ref, last_result) for ref_node in cascaded_nodes[::-1]: last_result = UtilNodes.EvalWithTempExprNode(ref_node, last_result) return last_result # builtin type creation def _DISABLED_handle_simple_function_tuple(self, node, pos_args): if not pos_args: return ExprNodes.TupleNode(node.pos, args=[], constant_result=()) # This is a bit special - for iterables (including genexps), # Python actually overallocates and resizes a newly created # tuple incrementally while reading items, which we can't # easily do without explicit node support. Instead, we read # the items into a list and then copy them into a tuple of the # final size. This takes up to twice as much memory, but will # have to do until we have real support for genexps. result = self._transform_list_set_genexpr(node, pos_args, Builtin.list_type) if result is not node: return ExprNodes.AsTupleNode(node.pos, arg=result) return node def _handle_simple_function_frozenset(self, node, pos_args): """Replace frozenset([...]) by frozenset((...)) as tuples are more efficient. """ if len(pos_args) != 1: return node if pos_args[0].is_sequence_constructor and not pos_args[0].args: del pos_args[0] elif isinstance(pos_args[0], ExprNodes.ListNode): pos_args[0] = pos_args[0].as_tuple() return node def _handle_simple_function_list(self, node, pos_args): if not pos_args: return ExprNodes.ListNode(node.pos, args=[], constant_result=[]) return self._transform_list_set_genexpr(node, pos_args, Builtin.list_type) def _handle_simple_function_set(self, node, pos_args): if not pos_args: return ExprNodes.SetNode(node.pos, args=[], constant_result=set()) return self._transform_list_set_genexpr(node, pos_args, Builtin.set_type) def _transform_list_set_genexpr(self, node, pos_args, target_type): """Replace set(genexpr) and list(genexpr) by an inlined comprehension. """ if len(pos_args) > 1: return node if not isinstance(pos_args[0], ExprNodes.GeneratorExpressionNode): return node gen_expr_node = pos_args[0] loop_node = gen_expr_node.loop yield_expression, yield_stat_node = _find_single_yield_expression(loop_node) if yield_expression is None: return node result_node = ExprNodes.InlinedGeneratorExpressionNode( node.pos, gen_expr_node, orig_func='set' if target_type is Builtin.set_type else 'list', comprehension_type=target_type) append_node = ExprNodes.ComprehensionAppendNode( yield_expression.pos, expr=yield_expression, target=result_node.target) Visitor.recursively_replace_node(gen_expr_node, yield_stat_node, append_node) return result_node def _handle_simple_function_dict(self, node, pos_args): """Replace dict( (a,b) for ... ) by an inlined { a:b for ... } """ if len(pos_args) == 0: return ExprNodes.DictNode(node.pos, key_value_pairs=[], constant_result={}) if len(pos_args) > 1: return node if not isinstance(pos_args[0], ExprNodes.GeneratorExpressionNode): return node gen_expr_node = pos_args[0] loop_node = gen_expr_node.loop yield_expression, yield_stat_node = _find_single_yield_expression(loop_node) if yield_expression is None: return node if not isinstance(yield_expression, ExprNodes.TupleNode): return node if len(yield_expression.args) != 2: return node result_node = ExprNodes.InlinedGeneratorExpressionNode( node.pos, gen_expr_node, orig_func='dict', comprehension_type=Builtin.dict_type) append_node = ExprNodes.DictComprehensionAppendNode( yield_expression.pos, key_expr = yield_expression.args[0], value_expr = yield_expression.args[1], target=result_node.target) Visitor.recursively_replace_node(gen_expr_node, yield_stat_node, append_node) return result_node # specific handlers for general call nodes def _handle_general_function_dict(self, node, pos_args, kwargs): """Replace dict(a=b,c=d,...) by the underlying keyword dict construction which is done anyway. """ if len(pos_args) > 0: return node if not isinstance(kwargs, ExprNodes.DictNode): return node return kwargs class InlineDefNodeCalls(Visitor.NodeRefCleanupMixin, Visitor.EnvTransform): visit_Node = Visitor.VisitorTransform.recurse_to_children def get_constant_value_node(self, name_node): if name_node.cf_state is None: return None if name_node.cf_state.cf_is_null: return None entry = self.current_env().lookup(name_node.name) if not entry or (not entry.cf_assignments or len(entry.cf_assignments) != 1): # not just a single assignment in all closures return None return entry.cf_assignments[0].rhs def visit_SimpleCallNode(self, node): self.visitchildren(node) if not self.current_directives.get('optimize.inline_defnode_calls'): return node function_name = node.function if not function_name.is_name: return node function = self.get_constant_value_node(function_name) if not isinstance(function, ExprNodes.PyCFunctionNode): return node inlined = ExprNodes.InlinedDefNodeCallNode( node.pos, function_name=function_name, function=function, args=node.args) if inlined.can_be_inlined(): return self.replace(node, inlined) return node class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin, Visitor.MethodDispatcherTransform): """Optimize some common methods calls and instantiation patterns for builtin types *after* the type analysis phase. Running after type analysis, this transform can only perform function replacements that do not alter the function return type in a way that was not anticipated by the type analysis. """ ### cleanup to avoid redundant coercions to/from Python types def _visit_PyTypeTestNode(self, node): # disabled - appears to break assignments in some cases, and # also drops a None check, which might still be required """Flatten redundant type checks after tree changes. """ old_arg = node.arg self.visitchildren(node) if old_arg is node.arg or node.arg.type != node.type: return node return node.arg def _visit_TypecastNode(self, node): # disabled - the user may have had a reason to put a type # cast, even if it looks redundant to Cython """ Drop redundant type casts. """ self.visitchildren(node) if node.type == node.operand.type: return node.operand return node def visit_ExprStatNode(self, node): """ Drop useless coercions. """ self.visitchildren(node) if isinstance(node.expr, ExprNodes.CoerceToPyTypeNode): node.expr = node.expr.arg return node def visit_CoerceToBooleanNode(self, node): """Drop redundant conversion nodes after tree changes. """ self.visitchildren(node) arg = node.arg if isinstance(arg, ExprNodes.PyTypeTestNode): arg = arg.arg if isinstance(arg, ExprNodes.CoerceToPyTypeNode): if arg.type in (PyrexTypes.py_object_type, Builtin.bool_type): return arg.arg.coerce_to_boolean(self.current_env()) return node def visit_CoerceFromPyTypeNode(self, node): """Drop redundant conversion nodes after tree changes. Also, optimise away calls to Python's builtin int() and float() if the result is going to be coerced back into a C type anyway. """ self.visitchildren(node) arg = node.arg if not arg.type.is_pyobject: # no Python conversion left at all, just do a C coercion instead if node.type == arg.type: return arg else: return arg.coerce_to(node.type, self.current_env()) if isinstance(arg, ExprNodes.PyTypeTestNode): arg = arg.arg if arg.is_literal: if (node.type.is_int and isinstance(arg, ExprNodes.IntNode) or node.type.is_float and isinstance(arg, ExprNodes.FloatNode) or node.type.is_int and isinstance(arg, ExprNodes.BoolNode)): return arg.coerce_to(node.type, self.current_env()) elif isinstance(arg, ExprNodes.CoerceToPyTypeNode): if arg.type is PyrexTypes.py_object_type: if node.type.assignable_from(arg.arg.type): # completely redundant C->Py->C coercion return arg.arg.coerce_to(node.type, self.current_env()) elif isinstance(arg, ExprNodes.SimpleCallNode): if node.type.is_int or node.type.is_float: return self._optimise_numeric_cast_call(node, arg) elif isinstance(arg, ExprNodes.IndexNode) and not arg.is_buffer_access: index_node = arg.index if isinstance(index_node, ExprNodes.CoerceToPyTypeNode): index_node = index_node.arg if index_node.type.is_int: return self._optimise_int_indexing(node, arg, index_node) return node PyBytes_GetItemInt_func_type = PyrexTypes.CFuncType( PyrexTypes.c_char_type, [ PyrexTypes.CFuncTypeArg("bytes", Builtin.bytes_type, None), PyrexTypes.CFuncTypeArg("index", PyrexTypes.c_py_ssize_t_type, None), PyrexTypes.CFuncTypeArg("check_bounds", PyrexTypes.c_int_type, None), ], exception_value = "((char)-1)", exception_check = True) def _optimise_int_indexing(self, coerce_node, arg, index_node): env = self.current_env() bound_check_bool = env.directives['boundscheck'] and 1 or 0 if arg.base.type is Builtin.bytes_type: if coerce_node.type in (PyrexTypes.c_char_type, PyrexTypes.c_uchar_type): # bytes[index] -> char bound_check_node = ExprNodes.IntNode( coerce_node.pos, value=str(bound_check_bool), constant_result=bound_check_bool) node = ExprNodes.PythonCapiCallNode( coerce_node.pos, "__Pyx_PyBytes_GetItemInt", self.PyBytes_GetItemInt_func_type, args=[ arg.base.as_none_safe_node("'NoneType' object is not subscriptable"), index_node.coerce_to(PyrexTypes.c_py_ssize_t_type, env), bound_check_node, ], is_temp=True, utility_code=UtilityCode.load_cached( 'bytes_index', 'StringTools.c')) if coerce_node.type is not PyrexTypes.c_char_type: node = node.coerce_to(coerce_node.type, env) return node return coerce_node def _optimise_numeric_cast_call(self, node, arg): function = arg.function if not isinstance(function, ExprNodes.NameNode) \ or not function.type.is_builtin_type \ or not isinstance(arg.arg_tuple, ExprNodes.TupleNode): return node args = arg.arg_tuple.args if len(args) != 1: return node func_arg = args[0] if isinstance(func_arg, ExprNodes.CoerceToPyTypeNode): func_arg = func_arg.arg elif func_arg.type.is_pyobject: # play safe: Python conversion might work on all sorts of things return node if function.name == 'int': if func_arg.type.is_int or node.type.is_int: if func_arg.type == node.type: return func_arg elif node.type.assignable_from(func_arg.type) or func_arg.type.is_float: return ExprNodes.TypecastNode( node.pos, operand=func_arg, type=node.type) elif function.name == 'float': if func_arg.type.is_float or node.type.is_float: if func_arg.type == node.type: return func_arg elif node.type.assignable_from(func_arg.type) or func_arg.type.is_float: return ExprNodes.TypecastNode( node.pos, operand=func_arg, type=node.type) return node def _error_wrong_arg_count(self, function_name, node, args, expected=None): if not expected: # None or 0 arg_str = '' elif isinstance(expected, basestring) or expected > 1: arg_str = '...' elif expected == 1: arg_str = 'x' else: arg_str = '' if expected is not None: expected_str = 'expected %s, ' % expected else: expected_str = '' error(node.pos, "%s(%s) called with wrong number of args, %sfound %d" % ( function_name, arg_str, expected_str, len(args))) ### generic fallbacks def _handle_function(self, node, function_name, function, arg_list, kwargs): return node def _handle_method(self, node, type_name, attr_name, function, arg_list, is_unbound_method, kwargs): """ Try to inject C-API calls for unbound method calls to builtin types. While the method declarations in Builtin.py already handle this, we can additionally resolve bound and unbound methods here that were assigned to variables ahead of time. """ if kwargs: return node if not function or not function.is_attribute or not function.obj.is_name: # cannot track unbound method calls over more than one indirection as # the names might have been reassigned in the meantime return node type_entry = self.current_env().lookup(type_name) if not type_entry: return node method = ExprNodes.AttributeNode( node.function.pos, obj=ExprNodes.NameNode( function.pos, name=type_name, entry=type_entry, type=type_entry.type), attribute=attr_name, is_called=True).analyse_as_unbound_cmethod_node(self.current_env()) if method is None: return node args = node.args if args is None and node.arg_tuple: args = node.arg_tuple.args call_node = ExprNodes.SimpleCallNode( node.pos, function=method, args=args) if not is_unbound_method: call_node.self = function.obj call_node.analyse_c_function_call(self.current_env()) call_node.analysed = True return call_node.coerce_to(node.type, self.current_env()) ### builtin types PyDict_Copy_func_type = PyrexTypes.CFuncType( Builtin.dict_type, [ PyrexTypes.CFuncTypeArg("dict", Builtin.dict_type, None) ]) def _handle_simple_function_dict(self, node, function, pos_args): """Replace dict(some_dict) by PyDict_Copy(some_dict). """ if len(pos_args) != 1: return node arg = pos_args[0] if arg.type is Builtin.dict_type: arg = arg.as_none_safe_node("'NoneType' is not iterable") return ExprNodes.PythonCapiCallNode( node.pos, "PyDict_Copy", self.PyDict_Copy_func_type, args = [arg], is_temp = node.is_temp ) return node PySequence_List_func_type = PyrexTypes.CFuncType( Builtin.list_type, [PyrexTypes.CFuncTypeArg("it", PyrexTypes.py_object_type, None)]) def _handle_simple_function_list(self, node, function, pos_args): """Turn list(ob) into PySequence_List(ob). """ if len(pos_args) != 1: return node arg = pos_args[0] return ExprNodes.PythonCapiCallNode( node.pos, "PySequence_List", self.PySequence_List_func_type, args=pos_args, is_temp=node.is_temp) PyList_AsTuple_func_type = PyrexTypes.CFuncType( Builtin.tuple_type, [ PyrexTypes.CFuncTypeArg("list", Builtin.list_type, None) ]) PySequence_Tuple_func_type = PyrexTypes.CFuncType( Builtin.tuple_type, [PyrexTypes.CFuncTypeArg("it", PyrexTypes.py_object_type, None)]) def _handle_simple_function_tuple(self, node, function, pos_args): """Replace tuple([...]) by PyList_AsTuple or PySequence_Tuple. """ if len(pos_args) != 1: return node arg = pos_args[0] if arg.type is Builtin.tuple_type and not arg.may_be_none(): return arg if arg.type is Builtin.list_type: pos_args[0] = arg.as_none_safe_node( "'NoneType' object is not iterable") return ExprNodes.PythonCapiCallNode( node.pos, "PyList_AsTuple", self.PyList_AsTuple_func_type, args=pos_args, is_temp=node.is_temp) else: return ExprNodes.PythonCapiCallNode( node.pos, "PySequence_Tuple", self.PySequence_Tuple_func_type, args=pos_args, is_temp=node.is_temp) PySet_New_func_type = PyrexTypes.CFuncType( Builtin.set_type, [ PyrexTypes.CFuncTypeArg("it", PyrexTypes.py_object_type, None) ]) def _handle_simple_function_set(self, node, function, pos_args): if len(pos_args) != 1: return node if pos_args[0].is_sequence_constructor: # We can optimise set([x,y,z]) safely into a set literal, # but only if we create all items before adding them - # adding an item may raise an exception if it is not # hashable, but creating the later items may have # side-effects. args = [] temps = [] for arg in pos_args[0].args: if not arg.is_simple(): arg = UtilNodes.LetRefNode(arg) temps.append(arg) args.append(arg) result = ExprNodes.SetNode(node.pos, is_temp=1, args=args) self.replace(node, result) for temp in temps[::-1]: result = UtilNodes.EvalWithTempExprNode(temp, result) return result else: # PySet_New(it) is better than a generic Python call to set(it) return self.replace(node, ExprNodes.PythonCapiCallNode( node.pos, "PySet_New", self.PySet_New_func_type, args=pos_args, is_temp=node.is_temp, py_name="set")) PyFrozenSet_New_func_type = PyrexTypes.CFuncType( Builtin.frozenset_type, [ PyrexTypes.CFuncTypeArg("it", PyrexTypes.py_object_type, None) ]) def _handle_simple_function_frozenset(self, node, function, pos_args): if not pos_args: pos_args = [ExprNodes.NullNode(node.pos)] elif len(pos_args) > 1: return node elif pos_args[0].type is Builtin.frozenset_type and not pos_args[0].may_be_none(): return pos_args[0] # PyFrozenSet_New(it) is better than a generic Python call to frozenset(it) return ExprNodes.PythonCapiCallNode( node.pos, "__Pyx_PyFrozenSet_New", self.PyFrozenSet_New_func_type, args=pos_args, is_temp=node.is_temp, utility_code=UtilityCode.load_cached('pyfrozenset_new', 'Builtins.c'), py_name="frozenset") PyObject_AsDouble_func_type = PyrexTypes.CFuncType( PyrexTypes.c_double_type, [ PyrexTypes.CFuncTypeArg("obj", PyrexTypes.py_object_type, None), ], exception_value = "((double)-1)", exception_check = True) def _handle_simple_function_float(self, node, function, pos_args): """Transform float() into either a C type cast or a faster C function call. """ # Note: this requires the float() function to be typed as # returning a C 'double' if len(pos_args) == 0: return ExprNodes.FloatNode( node, value="0.0", constant_result=0.0 ).coerce_to(Builtin.float_type, self.current_env()) elif len(pos_args) != 1: self._error_wrong_arg_count('float', node, pos_args, '0 or 1') return node func_arg = pos_args[0] if isinstance(func_arg, ExprNodes.CoerceToPyTypeNode): func_arg = func_arg.arg if func_arg.type is PyrexTypes.c_double_type: return func_arg elif node.type.assignable_from(func_arg.type) or func_arg.type.is_numeric: return ExprNodes.TypecastNode( node.pos, operand=func_arg, type=node.type) return ExprNodes.PythonCapiCallNode( node.pos, "__Pyx_PyObject_AsDouble", self.PyObject_AsDouble_func_type, args = pos_args, is_temp = node.is_temp, utility_code = load_c_utility('pyobject_as_double'), py_name = "float") PyNumber_Int_func_type = PyrexTypes.CFuncType( PyrexTypes.py_object_type, [ PyrexTypes.CFuncTypeArg("o", PyrexTypes.py_object_type, None) ]) def _handle_simple_function_int(self, node, function, pos_args): """Transform int() into a faster C function call. """ if len(pos_args) == 0: return ExprNodes.IntNode(node.pos, value="0", constant_result=0, type=PyrexTypes.py_object_type) elif len(pos_args) != 1: return node # int(x, base) func_arg = pos_args[0] if isinstance(func_arg, ExprNodes.CoerceToPyTypeNode): return node # handled in visit_CoerceFromPyTypeNode() if func_arg.type.is_pyobject and node.type.is_pyobject: return ExprNodes.PythonCapiCallNode( node.pos, "PyNumber_Int", self.PyNumber_Int_func_type, args=pos_args, is_temp=True) return node def _handle_simple_function_bool(self, node, function, pos_args): """Transform bool(x) into a type coercion to a boolean. """ if len(pos_args) == 0: return ExprNodes.BoolNode( node.pos, value=False, constant_result=False ).coerce_to(Builtin.bool_type, self.current_env()) elif len(pos_args) != 1: self._error_wrong_arg_count('bool', node, pos_args, '0 or 1') return node else: # => !!(x) to make sure it's exactly 0 or 1 operand = pos_args[0].coerce_to_boolean(self.current_env()) operand = ExprNodes.NotNode(node.pos, operand = operand) operand = ExprNodes.NotNode(node.pos, operand = operand) # coerce back to Python object as that's the result we are expecting return operand.coerce_to_pyobject(self.current_env()) ### builtin functions Pyx_strlen_func_type = PyrexTypes.CFuncType( PyrexTypes.c_size_t_type, [ PyrexTypes.CFuncTypeArg("bytes", PyrexTypes.c_char_ptr_type, None) ]) Pyx_Py_UNICODE_strlen_func_type = PyrexTypes.CFuncType( PyrexTypes.c_size_t_type, [ PyrexTypes.CFuncTypeArg("unicode", PyrexTypes.c_py_unicode_ptr_type, None) ]) PyObject_Size_func_type = PyrexTypes.CFuncType( PyrexTypes.c_py_ssize_t_type, [ PyrexTypes.CFuncTypeArg("obj", PyrexTypes.py_object_type, None) ], exception_value="-1") _map_to_capi_len_function = { Builtin.unicode_type: "__Pyx_PyUnicode_GET_LENGTH", Builtin.bytes_type: "PyBytes_GET_SIZE", Builtin.list_type: "PyList_GET_SIZE", Builtin.tuple_type: "PyTuple_GET_SIZE", Builtin.set_type: "PySet_GET_SIZE", Builtin.frozenset_type: "PySet_GET_SIZE", Builtin.dict_type: "PyDict_Size", }.get _ext_types_with_pysize = set(["cpython.array.array"]) def _handle_simple_function_len(self, node, function, pos_args): """Replace len(char*) by the equivalent call to strlen(), len(Py_UNICODE) by the equivalent Py_UNICODE_strlen() and len(known_builtin_type) by an equivalent C-API call. """ if len(pos_args) != 1: self._error_wrong_arg_count('len', node, pos_args, 1) return node arg = pos_args[0] if isinstance(arg, ExprNodes.CoerceToPyTypeNode): arg = arg.arg if arg.type.is_string: new_node = ExprNodes.PythonCapiCallNode( node.pos, "strlen", self.Pyx_strlen_func_type, args = [arg], is_temp = node.is_temp, utility_code = UtilityCode.load_cached("IncludeStringH", "StringTools.c")) elif arg.type.is_pyunicode_ptr: new_node = ExprNodes.PythonCapiCallNode( node.pos, "__Pyx_Py_UNICODE_strlen", self.Pyx_Py_UNICODE_strlen_func_type, args = [arg], is_temp = node.is_temp) elif arg.type.is_pyobject: cfunc_name = self._map_to_capi_len_function(arg.type) if cfunc_name is None: arg_type = arg.type if ((arg_type.is_extension_type or arg_type.is_builtin_type) and arg_type.entry.qualified_name in self._ext_types_with_pysize): cfunc_name = 'Py_SIZE' else: return node arg = arg.as_none_safe_node( "object of type 'NoneType' has no len()") new_node = ExprNodes.PythonCapiCallNode( node.pos, cfunc_name, self.PyObject_Size_func_type, args = [arg], is_temp = node.is_temp) elif arg.type.is_unicode_char: return ExprNodes.IntNode(node.pos, value='1', constant_result=1, type=node.type) else: return node if node.type not in (PyrexTypes.c_size_t_type, PyrexTypes.c_py_ssize_t_type): new_node = new_node.coerce_to(node.type, self.current_env()) return new_node Pyx_Type_func_type = PyrexTypes.CFuncType( Builtin.type_type, [ PyrexTypes.CFuncTypeArg("object", PyrexTypes.py_object_type, None) ]) def _handle_simple_function_type(self, node, function, pos_args): """Replace type(o) by a macro call to Py_TYPE(o). """ if len(pos_args) != 1: return node node = ExprNodes.PythonCapiCallNode( node.pos, "Py_TYPE", self.Pyx_Type_func_type, args = pos_args, is_temp = False) return ExprNodes.CastNode(node, PyrexTypes.py_object_type) Py_type_check_func_type = PyrexTypes.CFuncType( PyrexTypes.c_bint_type, [ PyrexTypes.CFuncTypeArg("arg", PyrexTypes.py_object_type, None) ]) def _handle_simple_function_isinstance(self, node, function, pos_args): """Replace isinstance() checks against builtin types by the corresponding C-API call. """ if len(pos_args) != 2: return node arg, types = pos_args temps = [] if isinstance(types, ExprNodes.TupleNode): types = types.args if len(types) == 1 and not types[0].type is Builtin.type_type: return node # nothing to improve here if arg.is_attribute or not arg.is_simple(): arg = UtilNodes.ResultRefNode(arg) temps.append(arg) elif types.type is Builtin.type_type: types = [types] else: return node tests = [] test_nodes = [] env = self.current_env() for test_type_node in types: builtin_type = None if test_type_node.is_name: if test_type_node.entry: entry = env.lookup(test_type_node.entry.name) if entry and entry.type and entry.type.is_builtin_type: builtin_type = entry.type if builtin_type is Builtin.type_type: # all types have type "type", but there's only one 'type' if entry.name != 'type' or not ( entry.scope and entry.scope.is_builtin_scope): builtin_type = None if builtin_type is not None: type_check_function = entry.type.type_check_function(exact=False) if type_check_function in tests: continue tests.append(type_check_function) type_check_args = [arg] elif test_type_node.type is Builtin.type_type: type_check_function = '__Pyx_TypeCheck' type_check_args = [arg, test_type_node] else: if not test_type_node.is_literal: test_type_node = UtilNodes.ResultRefNode(test_type_node) temps.append(test_type_node) type_check_function = 'PyObject_IsInstance' type_check_args = [arg, test_type_node] test_nodes.append( ExprNodes.PythonCapiCallNode( test_type_node.pos, type_check_function, self.Py_type_check_func_type, args=type_check_args, is_temp=True, )) def join_with_or(a, b, make_binop_node=ExprNodes.binop_node): or_node = make_binop_node(node.pos, 'or', a, b) or_node.type = PyrexTypes.c_bint_type or_node.wrap_operands(env) return or_node test_node = reduce(join_with_or, test_nodes).coerce_to(node.type, env) for temp in temps[::-1]: test_node = UtilNodes.EvalWithTempExprNode(temp, test_node) return test_node def _handle_simple_function_ord(self, node, function, pos_args): """Unpack ord(Py_UNICODE) and ord('X'). """ if len(pos_args) != 1: return node arg = pos_args[0] if isinstance(arg, ExprNodes.CoerceToPyTypeNode): if arg.arg.type.is_unicode_char: return ExprNodes.TypecastNode( arg.pos, operand=arg.arg, type=PyrexTypes.c_long_type ).coerce_to(node.type, self.current_env()) elif isinstance(arg, ExprNodes.UnicodeNode): if len(arg.value) == 1: return ExprNodes.IntNode( arg.pos, type=PyrexTypes.c_int_type, value=str(ord(arg.value)), constant_result=ord(arg.value) ).coerce_to(node.type, self.current_env()) elif isinstance(arg, ExprNodes.StringNode): if arg.unicode_value and len(arg.unicode_value) == 1 \ and ord(arg.unicode_value) <= 255: # Py2/3 portability return ExprNodes.IntNode( arg.pos, type=PyrexTypes.c_int_type, value=str(ord(arg.unicode_value)), constant_result=ord(arg.unicode_value) ).coerce_to(node.type, self.current_env()) return node ### special methods Pyx_tp_new_func_type = PyrexTypes.CFuncType( PyrexTypes.py_object_type, [ PyrexTypes.CFuncTypeArg("type", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("args", Builtin.tuple_type, None), ]) Pyx_tp_new_kwargs_func_type = PyrexTypes.CFuncType( PyrexTypes.py_object_type, [ PyrexTypes.CFuncTypeArg("type", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("args", Builtin.tuple_type, None), PyrexTypes.CFuncTypeArg("kwargs", Builtin.dict_type, None), ]) def _handle_any_slot__new__(self, node, function, args, is_unbound_method, kwargs=None): """Replace 'exttype.__new__(exttype, ...)' by a call to exttype->tp_new() """ obj = function.obj if not is_unbound_method or len(args) < 1: return node type_arg = args[0] if not obj.is_name or not type_arg.is_name: # play safe return node if obj.type != Builtin.type_type or type_arg.type != Builtin.type_type: # not a known type, play safe return node if not type_arg.type_entry or not obj.type_entry: if obj.name != type_arg.name: return node # otherwise, we know it's a type and we know it's the same # type for both - that should do elif type_arg.type_entry != obj.type_entry: # different types - may or may not lead to an error at runtime return node args_tuple = ExprNodes.TupleNode(node.pos, args=args[1:]) args_tuple = args_tuple.analyse_types( self.current_env(), skip_children=True) if type_arg.type_entry: ext_type = type_arg.type_entry.type if (ext_type.is_extension_type and ext_type.typeobj_cname and ext_type.scope.global_scope() == self.current_env().global_scope()): # known type in current module tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__') slot_func_cname = TypeSlots.get_slot_function(ext_type.scope, tp_slot) if slot_func_cname: cython_scope = self.context.cython_scope PyTypeObjectPtr = PyrexTypes.CPtrType( cython_scope.lookup('PyTypeObject').type) pyx_tp_new_kwargs_func_type = PyrexTypes.CFuncType( PyrexTypes.py_object_type, [ PyrexTypes.CFuncTypeArg("type", PyTypeObjectPtr, None), PyrexTypes.CFuncTypeArg("args", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("kwargs", PyrexTypes.py_object_type, None), ]) type_arg = ExprNodes.CastNode(type_arg, PyTypeObjectPtr) if not kwargs: kwargs = ExprNodes.NullNode(node.pos, type=PyrexTypes.py_object_type) # hack? return ExprNodes.PythonCapiCallNode( node.pos, slot_func_cname, pyx_tp_new_kwargs_func_type, args=[type_arg, args_tuple, kwargs], is_temp=True) else: # arbitrary variable, needs a None check for safety type_arg = type_arg.as_none_safe_node( "object.__new__(X): X is not a type object (NoneType)") utility_code = UtilityCode.load_cached('tp_new', 'ObjectHandling.c') if kwargs: return ExprNodes.PythonCapiCallNode( node.pos, "__Pyx_tp_new_kwargs", self.Pyx_tp_new_kwargs_func_type, args=[type_arg, args_tuple, kwargs], utility_code=utility_code, is_temp=node.is_temp ) else: return ExprNodes.PythonCapiCallNode( node.pos, "__Pyx_tp_new", self.Pyx_tp_new_func_type, args=[type_arg, args_tuple], utility_code=utility_code, is_temp=node.is_temp ) ### methods of builtin types PyObject_Append_func_type = PyrexTypes.CFuncType( PyrexTypes.c_returncode_type, [ PyrexTypes.CFuncTypeArg("list", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("item", PyrexTypes.py_object_type, None), ], exception_value="-1") def _handle_simple_method_object_append(self, node, function, args, is_unbound_method): """Optimistic optimisation as X.append() is almost always referring to a list. """ if len(args) != 2 or node.result_is_used: return node return ExprNodes.PythonCapiCallNode( node.pos, "__Pyx_PyObject_Append", self.PyObject_Append_func_type, args=args, may_return_none=False, is_temp=node.is_temp, result_is_used=False, utility_code=load_c_utility('append') ) PyByteArray_Append_func_type = PyrexTypes.CFuncType( PyrexTypes.c_returncode_type, [ PyrexTypes.CFuncTypeArg("bytearray", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("value", PyrexTypes.c_int_type, None), ], exception_value="-1") PyByteArray_AppendObject_func_type = PyrexTypes.CFuncType( PyrexTypes.c_returncode_type, [ PyrexTypes.CFuncTypeArg("bytearray", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("value", PyrexTypes.py_object_type, None), ], exception_value="-1") def _handle_simple_method_bytearray_append(self, node, function, args, is_unbound_method): if len(args) != 2: return node func_name = "__Pyx_PyByteArray_Append" func_type = self.PyByteArray_Append_func_type value = unwrap_coerced_node(args[1]) if value.type.is_int or isinstance(value, ExprNodes.IntNode): value = value.coerce_to(PyrexTypes.c_int_type, self.current_env()) utility_code = UtilityCode.load_cached("ByteArrayAppend", "StringTools.c") elif value.is_string_literal: if not value.can_coerce_to_char_literal(): return node value = value.coerce_to(PyrexTypes.c_char_type, self.current_env()) utility_code = UtilityCode.load_cached("ByteArrayAppend", "StringTools.c") elif value.type.is_pyobject: func_name = "__Pyx_PyByteArray_AppendObject" func_type = self.PyByteArray_AppendObject_func_type utility_code = UtilityCode.load_cached("ByteArrayAppendObject", "StringTools.c") else: return node new_node = ExprNodes.PythonCapiCallNode( node.pos, func_name, func_type, args=[args[0], value], may_return_none=False, is_temp=node.is_temp, utility_code=utility_code, ) if node.result_is_used: new_node = new_node.coerce_to(node.type, self.current_env()) return new_node PyObject_Pop_func_type = PyrexTypes.CFuncType( PyrexTypes.py_object_type, [ PyrexTypes.CFuncTypeArg("list", PyrexTypes.py_object_type, None), ]) PyObject_PopIndex_func_type = PyrexTypes.CFuncType( PyrexTypes.py_object_type, [ PyrexTypes.CFuncTypeArg("list", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("py_index", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("c_index", PyrexTypes.c_py_ssize_t_type, None), PyrexTypes.CFuncTypeArg("is_signed", PyrexTypes.c_int_type, None), ], has_varargs=True) # to fake the additional macro args that lack a proper C type def _handle_simple_method_list_pop(self, node, function, args, is_unbound_method): return self._handle_simple_method_object_pop( node, function, args, is_unbound_method, is_list=True) def _handle_simple_method_object_pop(self, node, function, args, is_unbound_method, is_list=False): """Optimistic optimisation as X.pop([n]) is almost always referring to a list. """ if not args: return node obj = args[0] if is_list: type_name = 'List' obj = obj.as_none_safe_node( "'NoneType' object has no attribute '%s'", error="PyExc_AttributeError", format_args=['pop']) else: type_name = 'Object' if len(args) == 1: return ExprNodes.PythonCapiCallNode( node.pos, "__Pyx_Py%s_Pop" % type_name, self.PyObject_Pop_func_type, args=[obj], may_return_none=True, is_temp=node.is_temp, utility_code=load_c_utility('pop'), ) elif len(args) == 2: index = unwrap_coerced_node(args[1]) py_index = ExprNodes.NoneNode(index.pos) orig_index_type = index.type if not index.type.is_int: if isinstance(index, ExprNodes.IntNode): py_index = index.coerce_to_pyobject(self.current_env()) index = index.coerce_to(PyrexTypes.c_py_ssize_t_type, self.current_env()) elif is_list: if index.type.is_pyobject: py_index = index.coerce_to_simple(self.current_env()) index = ExprNodes.CloneNode(py_index) index = index.coerce_to(PyrexTypes.c_py_ssize_t_type, self.current_env()) else: return node elif not PyrexTypes.numeric_type_fits(index.type, PyrexTypes.c_py_ssize_t_type): return node elif isinstance(index, ExprNodes.IntNode): py_index = index.coerce_to_pyobject(self.current_env()) # real type might still be larger at runtime if not orig_index_type.is_int: orig_index_type = index.type if not orig_index_type.create_to_py_utility_code(self.current_env()): return node convert_func = orig_index_type.to_py_function conversion_type = PyrexTypes.CFuncType( PyrexTypes.py_object_type, [PyrexTypes.CFuncTypeArg("intval", orig_index_type, None)]) return ExprNodes.PythonCapiCallNode( node.pos, "__Pyx_Py%s_PopIndex" % type_name, self.PyObject_PopIndex_func_type, args=[obj, py_index, index, ExprNodes.IntNode(index.pos, value=str(orig_index_type.signed and 1 or 0), constant_result=orig_index_type.signed and 1 or 0, type=PyrexTypes.c_int_type), ExprNodes.RawCNameExprNode(index.pos, PyrexTypes.c_void_type, orig_index_type.empty_declaration_code()), ExprNodes.RawCNameExprNode(index.pos, conversion_type, convert_func)], may_return_none=True, is_temp=node.is_temp, utility_code=load_c_utility("pop_index"), ) return node single_param_func_type = PyrexTypes.CFuncType( PyrexTypes.c_returncode_type, [ PyrexTypes.CFuncTypeArg("obj", PyrexTypes.py_object_type, None), ], exception_value = "-1") def _handle_simple_method_list_sort(self, node, function, args, is_unbound_method): """Call PyList_Sort() instead of the 0-argument l.sort(). """ if len(args) != 1: return node return self._substitute_method_call( node, function, "PyList_Sort", self.single_param_func_type, 'sort', is_unbound_method, args).coerce_to(node.type, self.current_env) Pyx_PyDict_GetItem_func_type = PyrexTypes.CFuncType( PyrexTypes.py_object_type, [ PyrexTypes.CFuncTypeArg("dict", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("key", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("default", PyrexTypes.py_object_type, None), ]) def _handle_simple_method_dict_get(self, node, function, args, is_unbound_method): """Replace dict.get() by a call to PyDict_GetItem(). """ if len(args) == 2: args.append(ExprNodes.NoneNode(node.pos)) elif len(args) != 3: self._error_wrong_arg_count('dict.get', node, args, "2 or 3") return node return self._substitute_method_call( node, function, "__Pyx_PyDict_GetItemDefault", self.Pyx_PyDict_GetItem_func_type, 'get', is_unbound_method, args, may_return_none = True, utility_code = load_c_utility("dict_getitem_default")) Pyx_PyDict_SetDefault_func_type = PyrexTypes.CFuncType( PyrexTypes.py_object_type, [ PyrexTypes.CFuncTypeArg("dict", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("key", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("default", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("is_safe_type", PyrexTypes.c_int_type, None), ]) def _handle_simple_method_dict_setdefault(self, node, function, args, is_unbound_method): """Replace dict.setdefault() by calls to PyDict_GetItem() and PyDict_SetItem(). """ if len(args) == 2: args.append(ExprNodes.NoneNode(node.pos)) elif len(args) != 3: self._error_wrong_arg_count('dict.setdefault', node, args, "2 or 3") return node key_type = args[1].type if key_type.is_builtin_type: is_safe_type = int(key_type.name in 'str bytes unicode float int long bool') elif key_type is PyrexTypes.py_object_type: is_safe_type = -1 # don't know else: is_safe_type = 0 # definitely not args.append(ExprNodes.IntNode( node.pos, value=str(is_safe_type), constant_result=is_safe_type)) return self._substitute_method_call( node, function, "__Pyx_PyDict_SetDefault", self.Pyx_PyDict_SetDefault_func_type, 'setdefault', is_unbound_method, args, may_return_none=True, utility_code=load_c_utility('dict_setdefault')) Pyx_PyInt_BinopInt_func_type = PyrexTypes.CFuncType( PyrexTypes.py_object_type, [ PyrexTypes.CFuncTypeArg("op1", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("op2", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("intval", PyrexTypes.c_long_type, None), PyrexTypes.CFuncTypeArg("inplace", PyrexTypes.c_bint_type, None), ]) Pyx_PyFloat_BinopInt_func_type = PyrexTypes.CFuncType( PyrexTypes.py_object_type, [ PyrexTypes.CFuncTypeArg("op1", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("op2", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("fval", PyrexTypes.c_double_type, None), PyrexTypes.CFuncTypeArg("inplace", PyrexTypes.c_bint_type, None), ]) def _handle_simple_method_object___add__(self, node, function, args, is_unbound_method): return self._optimise_num_binop('Add', node, function, args, is_unbound_method) def _handle_simple_method_object___sub__(self, node, function, args, is_unbound_method): return self._optimise_num_binop('Subtract', node, function, args, is_unbound_method) def _handle_simple_method_object___eq__(self, node, function, args, is_unbound_method): return self._optimise_num_binop('Eq', node, function, args, is_unbound_method) def _handle_simple_method_object___neq__(self, node, function, args, is_unbound_method): return self._optimise_num_binop('Ne', node, function, args, is_unbound_method) def _handle_simple_method_object___and__(self, node, function, args, is_unbound_method): return self._optimise_num_binop('And', node, function, args, is_unbound_method) def _handle_simple_method_object___or__(self, node, function, args, is_unbound_method): return self._optimise_num_binop('Or', node, function, args, is_unbound_method) def _handle_simple_method_object___xor__(self, node, function, args, is_unbound_method): return self._optimise_num_binop('Xor', node, function, args, is_unbound_method) def _handle_simple_method_object___rshift__(self, node, function, args, is_unbound_method): if len(args) != 2 or not isinstance(args[1], ExprNodes.IntNode): return node if not args[1].has_constant_result() or not (1 <= args[1].constant_result <= 63): return node return self._optimise_num_binop('Rshift', node, function, args, is_unbound_method) def _handle_simple_method_object___mod__(self, node, function, args, is_unbound_method): return self._optimise_num_div('Remainder', node, function, args, is_unbound_method) def _handle_simple_method_object___floordiv__(self, node, function, args, is_unbound_method): return self._optimise_num_div('FloorDivide', node, function, args, is_unbound_method) def _handle_simple_method_object___truediv__(self, node, function, args, is_unbound_method): return self._optimise_num_div('TrueDivide', node, function, args, is_unbound_method) def _handle_simple_method_object___div__(self, node, function, args, is_unbound_method): return self._optimise_num_div('Divide', node, function, args, is_unbound_method) def _optimise_num_div(self, operator, node, function, args, is_unbound_method): if len(args) != 2 or not args[1].has_constant_result() or args[1].constant_result == 0: return node if isinstance(args[1], ExprNodes.IntNode): if not (-2**30 <= args[1].constant_result <= 2**30): return node elif isinstance(args[1], ExprNodes.FloatNode): if not (-2**53 <= args[1].constant_result <= 2**53): return node else: return node return self._optimise_num_binop(operator, node, function, args, is_unbound_method) def _handle_simple_method_float___add__(self, node, function, args, is_unbound_method): return self._optimise_num_binop('Add', node, function, args, is_unbound_method) def _handle_simple_method_float___sub__(self, node, function, args, is_unbound_method): return self._optimise_num_binop('Subtract', node, function, args, is_unbound_method) def _handle_simple_method_float___truediv__(self, node, function, args, is_unbound_method): return self._optimise_num_binop('TrueDivide', node, function, args, is_unbound_method) def _handle_simple_method_float___div__(self, node, function, args, is_unbound_method): return self._optimise_num_binop('Divide', node, function, args, is_unbound_method) def _handle_simple_method_float___mod__(self, node, function, args, is_unbound_method): return self._optimise_num_binop('Remainder', node, function, args, is_unbound_method) def _handle_simple_method_float___eq__(self, node, function, args, is_unbound_method): return self._optimise_num_binop('Eq', node, function, args, is_unbound_method) def _handle_simple_method_float___neq__(self, node, function, args, is_unbound_method): return self._optimise_num_binop('Ne', node, function, args, is_unbound_method) def _optimise_num_binop(self, operator, node, function, args, is_unbound_method): """ Optimise math operators for (likely) float or small integer operations. """ if len(args) != 2: return node if not node.type.is_pyobject: return node # When adding IntNode/FloatNode to something else, assume other operand is also numeric. # Prefer constants on RHS as they allows better size control for some operators. num_nodes = (ExprNodes.IntNode, ExprNodes.FloatNode) if isinstance(args[1], num_nodes): if args[0].type is not PyrexTypes.py_object_type: return node numval = args[1] arg_order = 'ObjC' elif isinstance(args[0], num_nodes): if args[1].type is not PyrexTypes.py_object_type: return node numval = args[0] arg_order = 'CObj' else: return node if not numval.has_constant_result(): return node is_float = isinstance(numval, ExprNodes.FloatNode) if is_float: if operator not in ('Add', 'Subtract', 'Remainder', 'TrueDivide', 'Divide', 'Eq', 'Ne'): return node elif operator == 'Divide': # mixed old-/new-style division is not currently optimised for integers return node elif abs(numval.constant_result) > 2**30: return node args = list(args) args.append((ExprNodes.FloatNode if is_float else ExprNodes.IntNode)( numval.pos, value=numval.value, constant_result=numval.constant_result, type=PyrexTypes.c_double_type if is_float else PyrexTypes.c_long_type)) inplace = node.inplace if isinstance(node, ExprNodes.NumBinopNode) else False args.append(ExprNodes.BoolNode(node.pos, value=inplace, constant_result=inplace)) utility_code = TempitaUtilityCode.load_cached( "PyFloatBinop" if is_float else "PyIntBinop", "Optimize.c", context=dict(op=operator, order=arg_order)) return self._substitute_method_call( node, function, "__Pyx_Py%s_%s%s" % ('Float' if is_float else 'Int', operator, arg_order), self.Pyx_PyFloat_BinopInt_func_type if is_float else self.Pyx_PyInt_BinopInt_func_type, '__%s__' % operator[:3].lower(), is_unbound_method, args, may_return_none=True, with_none_check=False, utility_code=utility_code) ### unicode type methods PyUnicode_uchar_predicate_func_type = PyrexTypes.CFuncType( PyrexTypes.c_bint_type, [ PyrexTypes.CFuncTypeArg("uchar", PyrexTypes.c_py_ucs4_type, None), ]) def _inject_unicode_predicate(self, node, function, args, is_unbound_method): if is_unbound_method or len(args) != 1: return node ustring = args[0] if not isinstance(ustring, ExprNodes.CoerceToPyTypeNode) or \ not ustring.arg.type.is_unicode_char: return node uchar = ustring.arg method_name = function.attribute if method_name == 'istitle': # istitle() doesn't directly map to Py_UNICODE_ISTITLE() utility_code = UtilityCode.load_cached( "py_unicode_istitle", "StringTools.c") function_name = '__Pyx_Py_UNICODE_ISTITLE' else: utility_code = None function_name = 'Py_UNICODE_%s' % method_name.upper() func_call = self._substitute_method_call( node, function, function_name, self.PyUnicode_uchar_predicate_func_type, method_name, is_unbound_method, [uchar], utility_code = utility_code) if node.type.is_pyobject: func_call = func_call.coerce_to_pyobject(self.current_env) return func_call _handle_simple_method_unicode_isalnum = _inject_unicode_predicate _handle_simple_method_unicode_isalpha = _inject_unicode_predicate _handle_simple_method_unicode_isdecimal = _inject_unicode_predicate _handle_simple_method_unicode_isdigit = _inject_unicode_predicate _handle_simple_method_unicode_islower = _inject_unicode_predicate _handle_simple_method_unicode_isnumeric = _inject_unicode_predicate _handle_simple_method_unicode_isspace = _inject_unicode_predicate _handle_simple_method_unicode_istitle = _inject_unicode_predicate _handle_simple_method_unicode_isupper = _inject_unicode_predicate PyUnicode_uchar_conversion_func_type = PyrexTypes.CFuncType( PyrexTypes.c_py_ucs4_type, [ PyrexTypes.CFuncTypeArg("uchar", PyrexTypes.c_py_ucs4_type, None), ]) def _inject_unicode_character_conversion(self, node, function, args, is_unbound_method): if is_unbound_method or len(args) != 1: return node ustring = args[0] if not isinstance(ustring, ExprNodes.CoerceToPyTypeNode) or \ not ustring.arg.type.is_unicode_char: return node uchar = ustring.arg method_name = function.attribute function_name = 'Py_UNICODE_TO%s' % method_name.upper() func_call = self._substitute_method_call( node, function, function_name, self.PyUnicode_uchar_conversion_func_type, method_name, is_unbound_method, [uchar]) if node.type.is_pyobject: func_call = func_call.coerce_to_pyobject(self.current_env) return func_call _handle_simple_method_unicode_lower = _inject_unicode_character_conversion _handle_simple_method_unicode_upper = _inject_unicode_character_conversion _handle_simple_method_unicode_title = _inject_unicode_character_conversion PyUnicode_Splitlines_func_type = PyrexTypes.CFuncType( Builtin.list_type, [ PyrexTypes.CFuncTypeArg("str", Builtin.unicode_type, None), PyrexTypes.CFuncTypeArg("keepends", PyrexTypes.c_bint_type, None), ]) def _handle_simple_method_unicode_splitlines(self, node, function, args, is_unbound_method): """Replace unicode.splitlines(...) by a direct call to the corresponding C-API function. """ if len(args) not in (1,2): self._error_wrong_arg_count('unicode.splitlines', node, args, "1 or 2") return node self._inject_bint_default_argument(node, args, 1, False) return self._substitute_method_call( node, function, "PyUnicode_Splitlines", self.PyUnicode_Splitlines_func_type, 'splitlines', is_unbound_method, args) PyUnicode_Split_func_type = PyrexTypes.CFuncType( Builtin.list_type, [ PyrexTypes.CFuncTypeArg("str", Builtin.unicode_type, None), PyrexTypes.CFuncTypeArg("sep", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("maxsplit", PyrexTypes.c_py_ssize_t_type, None), ] ) def _handle_simple_method_unicode_split(self, node, function, args, is_unbound_method): """Replace unicode.split(...) by a direct call to the corresponding C-API function. """ if len(args) not in (1,2,3): self._error_wrong_arg_count('unicode.split', node, args, "1-3") return node if len(args) < 2: args.append(ExprNodes.NullNode(node.pos)) self._inject_int_default_argument( node, args, 2, PyrexTypes.c_py_ssize_t_type, "-1") return self._substitute_method_call( node, function, "PyUnicode_Split", self.PyUnicode_Split_func_type, 'split', is_unbound_method, args) PyUnicode_Join_func_type = PyrexTypes.CFuncType( Builtin.unicode_type, [ PyrexTypes.CFuncTypeArg("str", Builtin.unicode_type, None), PyrexTypes.CFuncTypeArg("seq", PyrexTypes.py_object_type, None), ]) def _handle_simple_method_unicode_join(self, node, function, args, is_unbound_method): """ unicode.join() builds a list first => see if we can do this more efficiently """ if len(args) != 2: self._error_wrong_arg_count('unicode.join', node, args, "2") return node if isinstance(args[1], ExprNodes.GeneratorExpressionNode): gen_expr_node = args[1] loop_node = gen_expr_node.loop yield_expression, yield_stat_node = _find_single_yield_expression(loop_node) if yield_expression is not None: inlined_genexpr = ExprNodes.InlinedGeneratorExpressionNode( node.pos, gen_expr_node, orig_func='list', comprehension_type=Builtin.list_type) append_node = ExprNodes.ComprehensionAppendNode( yield_expression.pos, expr=yield_expression, target=inlined_genexpr.target) Visitor.recursively_replace_node(gen_expr_node, yield_stat_node, append_node) args[1] = inlined_genexpr return self._substitute_method_call( node, function, "PyUnicode_Join", self.PyUnicode_Join_func_type, 'join', is_unbound_method, args) PyString_Tailmatch_func_type = PyrexTypes.CFuncType( PyrexTypes.c_bint_type, [ PyrexTypes.CFuncTypeArg("str", PyrexTypes.py_object_type, None), # bytes/str/unicode PyrexTypes.CFuncTypeArg("substring", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("start", PyrexTypes.c_py_ssize_t_type, None), PyrexTypes.CFuncTypeArg("end", PyrexTypes.c_py_ssize_t_type, None), PyrexTypes.CFuncTypeArg("direction", PyrexTypes.c_int_type, None), ], exception_value = '-1') def _handle_simple_method_unicode_endswith(self, node, function, args, is_unbound_method): return self._inject_tailmatch( node, function, args, is_unbound_method, 'unicode', 'endswith', unicode_tailmatch_utility_code, +1) def _handle_simple_method_unicode_startswith(self, node, function, args, is_unbound_method): return self._inject_tailmatch( node, function, args, is_unbound_method, 'unicode', 'startswith', unicode_tailmatch_utility_code, -1) def _inject_tailmatch(self, node, function, args, is_unbound_method, type_name, method_name, utility_code, direction): """Replace unicode.startswith(...) and unicode.endswith(...) by a direct call to the corresponding C-API function. """ if len(args) not in (2,3,4): self._error_wrong_arg_count('%s.%s' % (type_name, method_name), node, args, "2-4") return node self._inject_int_default_argument( node, args, 2, PyrexTypes.c_py_ssize_t_type, "0") self._inject_int_default_argument( node, args, 3, PyrexTypes.c_py_ssize_t_type, "PY_SSIZE_T_MAX") args.append(ExprNodes.IntNode( node.pos, value=str(direction), type=PyrexTypes.c_int_type)) method_call = self._substitute_method_call( node, function, "__Pyx_Py%s_Tailmatch" % type_name.capitalize(), self.PyString_Tailmatch_func_type, method_name, is_unbound_method, args, utility_code = utility_code) return method_call.coerce_to(Builtin.bool_type, self.current_env()) PyUnicode_Find_func_type = PyrexTypes.CFuncType( PyrexTypes.c_py_ssize_t_type, [ PyrexTypes.CFuncTypeArg("str", Builtin.unicode_type, None), PyrexTypes.CFuncTypeArg("substring", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("start", PyrexTypes.c_py_ssize_t_type, None), PyrexTypes.CFuncTypeArg("end", PyrexTypes.c_py_ssize_t_type, None), PyrexTypes.CFuncTypeArg("direction", PyrexTypes.c_int_type, None), ], exception_value = '-2') def _handle_simple_method_unicode_find(self, node, function, args, is_unbound_method): return self._inject_unicode_find( node, function, args, is_unbound_method, 'find', +1) def _handle_simple_method_unicode_rfind(self, node, function, args, is_unbound_method): return self._inject_unicode_find( node, function, args, is_unbound_method, 'rfind', -1) def _inject_unicode_find(self, node, function, args, is_unbound_method, method_name, direction): """Replace unicode.find(...) and unicode.rfind(...) by a direct call to the corresponding C-API function. """ if len(args) not in (2,3,4): self._error_wrong_arg_count('unicode.%s' % method_name, node, args, "2-4") return node self._inject_int_default_argument( node, args, 2, PyrexTypes.c_py_ssize_t_type, "0") self._inject_int_default_argument( node, args, 3, PyrexTypes.c_py_ssize_t_type, "PY_SSIZE_T_MAX") args.append(ExprNodes.IntNode( node.pos, value=str(direction), type=PyrexTypes.c_int_type)) method_call = self._substitute_method_call( node, function, "PyUnicode_Find", self.PyUnicode_Find_func_type, method_name, is_unbound_method, args) return method_call.coerce_to_pyobject(self.current_env()) PyUnicode_Count_func_type = PyrexTypes.CFuncType( PyrexTypes.c_py_ssize_t_type, [ PyrexTypes.CFuncTypeArg("str", Builtin.unicode_type, None), PyrexTypes.CFuncTypeArg("substring", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("start", PyrexTypes.c_py_ssize_t_type, None), PyrexTypes.CFuncTypeArg("end", PyrexTypes.c_py_ssize_t_type, None), ], exception_value = '-1') def _handle_simple_method_unicode_count(self, node, function, args, is_unbound_method): """Replace unicode.count(...) by a direct call to the corresponding C-API function. """ if len(args) not in (2,3,4): self._error_wrong_arg_count('unicode.count', node, args, "2-4") return node self._inject_int_default_argument( node, args, 2, PyrexTypes.c_py_ssize_t_type, "0") self._inject_int_default_argument( node, args, 3, PyrexTypes.c_py_ssize_t_type, "PY_SSIZE_T_MAX") method_call = self._substitute_method_call( node, function, "PyUnicode_Count", self.PyUnicode_Count_func_type, 'count', is_unbound_method, args) return method_call.coerce_to_pyobject(self.current_env()) PyUnicode_Replace_func_type = PyrexTypes.CFuncType( Builtin.unicode_type, [ PyrexTypes.CFuncTypeArg("str", Builtin.unicode_type, None), PyrexTypes.CFuncTypeArg("substring", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("replstr", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("maxcount", PyrexTypes.c_py_ssize_t_type, None), ]) def _handle_simple_method_unicode_replace(self, node, function, args, is_unbound_method): """Replace unicode.replace(...) by a direct call to the corresponding C-API function. """ if len(args) not in (3,4): self._error_wrong_arg_count('unicode.replace', node, args, "3-4") return node self._inject_int_default_argument( node, args, 3, PyrexTypes.c_py_ssize_t_type, "-1") return self._substitute_method_call( node, function, "PyUnicode_Replace", self.PyUnicode_Replace_func_type, 'replace', is_unbound_method, args) PyUnicode_AsEncodedString_func_type = PyrexTypes.CFuncType( Builtin.bytes_type, [ PyrexTypes.CFuncTypeArg("obj", Builtin.unicode_type, None), PyrexTypes.CFuncTypeArg("encoding", PyrexTypes.c_char_ptr_type, None), PyrexTypes.CFuncTypeArg("errors", PyrexTypes.c_char_ptr_type, None), ]) PyUnicode_AsXyzString_func_type = PyrexTypes.CFuncType( Builtin.bytes_type, [ PyrexTypes.CFuncTypeArg("obj", Builtin.unicode_type, None), ]) _special_encodings = ['UTF8', 'UTF16', 'Latin1', 'ASCII', 'unicode_escape', 'raw_unicode_escape'] _special_codecs = [ (name, codecs.getencoder(name)) for name in _special_encodings ] def _handle_simple_method_unicode_encode(self, node, function, args, is_unbound_method): """Replace unicode.encode(...) by a direct C-API call to the corresponding codec. """ if len(args) < 1 or len(args) > 3: self._error_wrong_arg_count('unicode.encode', node, args, '1-3') return node string_node = args[0] if len(args) == 1: null_node = ExprNodes.NullNode(node.pos) return self._substitute_method_call( node, function, "PyUnicode_AsEncodedString", self.PyUnicode_AsEncodedString_func_type, 'encode', is_unbound_method, [string_node, null_node, null_node]) parameters = self._unpack_encoding_and_error_mode(node.pos, args) if parameters is None: return node encoding, encoding_node, error_handling, error_handling_node = parameters if encoding and isinstance(string_node, ExprNodes.UnicodeNode): # constant, so try to do the encoding at compile time try: value = string_node.value.encode(encoding, error_handling) except: # well, looks like we can't pass else: value = bytes_literal(value, encoding) return ExprNodes.BytesNode(string_node.pos, value=value, type=Builtin.bytes_type) if encoding and error_handling == 'strict': # try to find a specific encoder function codec_name = self._find_special_codec_name(encoding) if codec_name is not None: encode_function = "PyUnicode_As%sString" % codec_name return self._substitute_method_call( node, function, encode_function, self.PyUnicode_AsXyzString_func_type, 'encode', is_unbound_method, [string_node]) return self._substitute_method_call( node, function, "PyUnicode_AsEncodedString", self.PyUnicode_AsEncodedString_func_type, 'encode', is_unbound_method, [string_node, encoding_node, error_handling_node]) PyUnicode_DecodeXyz_func_ptr_type = PyrexTypes.CPtrType(PyrexTypes.CFuncType( Builtin.unicode_type, [ PyrexTypes.CFuncTypeArg("string", PyrexTypes.c_char_ptr_type, None), PyrexTypes.CFuncTypeArg("size", PyrexTypes.c_py_ssize_t_type, None), PyrexTypes.CFuncTypeArg("errors", PyrexTypes.c_char_ptr_type, None), ])) _decode_c_string_func_type = PyrexTypes.CFuncType( Builtin.unicode_type, [ PyrexTypes.CFuncTypeArg("string", PyrexTypes.c_char_ptr_type, None), PyrexTypes.CFuncTypeArg("start", PyrexTypes.c_py_ssize_t_type, None), PyrexTypes.CFuncTypeArg("stop", PyrexTypes.c_py_ssize_t_type, None), PyrexTypes.CFuncTypeArg("encoding", PyrexTypes.c_char_ptr_type, None), PyrexTypes.CFuncTypeArg("errors", PyrexTypes.c_char_ptr_type, None), PyrexTypes.CFuncTypeArg("decode_func", PyUnicode_DecodeXyz_func_ptr_type, None), ]) _decode_bytes_func_type = PyrexTypes.CFuncType( Builtin.unicode_type, [ PyrexTypes.CFuncTypeArg("string", PyrexTypes.py_object_type, None), PyrexTypes.CFuncTypeArg("start", PyrexTypes.c_py_ssize_t_type, None), PyrexTypes.CFuncTypeArg("stop", PyrexTypes.c_py_ssize_t_type, None), PyrexTypes.CFuncTypeArg("encoding", PyrexTypes.c_char_ptr_type, None), PyrexTypes.CFuncTypeArg("errors", PyrexTypes.c_char_ptr_type, None), PyrexTypes.CFuncTypeArg("decode_func", PyUnicode_DecodeXyz_func_ptr_type, None), ]) _decode_cpp_string_func_type = None # lazy init def _handle_simple_method_bytes_decode(self, node, function, args, is_unbound_method): """Replace char*.decode() by a direct C-API call to the corresponding codec, possibly resolving a slice on the char*. """ if not (1 <= len(args) <= 3): self._error_wrong_arg_count('bytes.decode', node, args, '1-3') return node # normalise input nodes string_node = args[0] start = stop = None if isinstance(string_node, ExprNodes.SliceIndexNode): index_node = string_node string_node = index_node.base start, stop = index_node.start, index_node.stop if not start or start.constant_result == 0: start = None if isinstance(string_node, ExprNodes.CoerceToPyTypeNode): string_node = string_node.arg string_type = string_node.type if string_type in (Builtin.bytes_type, Builtin.bytearray_type): if is_unbound_method: string_node = string_node.as_none_safe_node( "descriptor '%s' requires a '%s' object but received a 'NoneType'", format_args=['decode', string_type.name]) else: string_node = string_node.as_none_safe_node( "'NoneType' object has no attribute '%s'", error="PyExc_AttributeError", format_args=['decode']) elif not string_type.is_string and not string_type.is_cpp_string: # nothing to optimise here return node parameters = self._unpack_encoding_and_error_mode(node.pos, args) if parameters is None: return node encoding, encoding_node, error_handling, error_handling_node = parameters if not start: start = ExprNodes.IntNode(node.pos, value='0', constant_result=0) elif not start.type.is_int: start = start.coerce_to(PyrexTypes.c_py_ssize_t_type, self.current_env()) if stop and not stop.type.is_int: stop = stop.coerce_to(PyrexTypes.c_py_ssize_t_type, self.current_env()) # try to find a specific encoder function codec_name = None if encoding is not None: codec_name = self._find_special_codec_name(encoding) if codec_name is not None: decode_function = ExprNodes.RawCNameExprNode( node.pos, type=self.PyUnicode_DecodeXyz_func_ptr_type, cname="PyUnicode_Decode%s" % codec_name) encoding_node = ExprNodes.NullNode(node.pos) else: decode_function = ExprNodes.NullNode(node.pos) # build the helper function call temps = [] if string_type.is_string: # C string if not stop: # use strlen() to find the string length, just as CPython would if not string_node.is_name: string_node = UtilNodes.LetRefNode(string_node) # used twice temps.append(string_node) stop = ExprNodes.PythonCapiCallNode( string_node.pos, "strlen", self.Pyx_strlen_func_type, args=[string_node], is_temp=False, utility_code=UtilityCode.load_cached("IncludeStringH", "StringTools.c"), ).coerce_to(PyrexTypes.c_py_ssize_t_type, self.current_env()) helper_func_type = self._decode_c_string_func_type utility_code_name = 'decode_c_string' elif string_type.is_cpp_string: # C++ std::string if not stop: stop = ExprNodes.IntNode(node.pos, value='PY_SSIZE_T_MAX', constant_result=ExprNodes.not_a_constant) if self._decode_cpp_string_func_type is None: # lazy init to reuse the C++ string type self._decode_cpp_string_func_type = PyrexTypes.CFuncType( Builtin.unicode_type, [ PyrexTypes.CFuncTypeArg("string", string_type, None), PyrexTypes.CFuncTypeArg("start", PyrexTypes.c_py_ssize_t_type, None), PyrexTypes.CFuncTypeArg("stop", PyrexTypes.c_py_ssize_t_type, None), PyrexTypes.CFuncTypeArg("encoding", PyrexTypes.c_char_ptr_type, None), PyrexTypes.CFuncTypeArg("errors", PyrexTypes.c_char_ptr_type, None), PyrexTypes.CFuncTypeArg("decode_func", self.PyUnicode_DecodeXyz_func_ptr_type, None), ]) helper_func_type = self._decode_cpp_string_func_type utility_code_name = 'decode_cpp_string' else: # Python bytes/bytearray object if not stop: stop = ExprNodes.IntNode(node.pos, value='PY_SSIZE_T_MAX', constant_result=ExprNodes.not_a_constant) helper_func_type = self._decode_bytes_func_type if string_type is Builtin.bytes_type: utility_code_name = 'decode_bytes' else: utility_code_name = 'decode_bytearray' node = ExprNodes.PythonCapiCallNode( node.pos, '__Pyx_%s' % utility_code_name, helper_func_type, args=[string_node, start, stop, encoding_node, error_handling_node, decode_function], is_temp=node.is_temp, utility_code=UtilityCode.load_cached(utility_code_name, 'StringTools.c'), ) for temp in temps[::-1]: node = UtilNodes.EvalWithTempExprNode(temp, node) return node _handle_simple_method_bytearray_decode = _handle_simple_method_bytes_decode def _find_special_codec_name(self, encoding): try: requested_codec = codecs.getencoder(encoding) except LookupError: return None for name, codec in self._special_codecs: if codec == requested_codec: if '_' in name: name = ''.join([s.capitalize() for s in name.split('_')]) return name return None def _unpack_encoding_and_error_mode(self, pos, args): null_node = ExprNodes.NullNode(pos) if len(args) >= 2: encoding, encoding_node = self._unpack_string_and_cstring_node(args[1]) if encoding_node is None: return None else: encoding = None encoding_node = null_node if len(args) == 3: error_handling, error_handling_node = self._unpack_string_and_cstring_node(args[2]) if error_handling_node is None: return None if error_handling == 'strict': error_handling_node = null_node else: error_handling = 'strict' error_handling_node = null_node return (encoding, encoding_node, error_handling, error_handling_node) def _unpack_string_and_cstring_node(self, node): if isinstance(node, ExprNodes.CoerceToPyTypeNode): node = node.arg if isinstance(node, ExprNodes.UnicodeNode): encoding = node.value node = ExprNodes.BytesNode( node.pos, value=encoding.as_utf8_string(), type=PyrexTypes.c_char_ptr_type) elif isinstance(node, (ExprNodes.StringNode, ExprNodes.BytesNode)): encoding = node.value.decode('ISO-8859-1') node = ExprNodes.BytesNode( node.pos, value=node.value, type=PyrexTypes.c_char_ptr_type) elif node.type is Builtin.bytes_type: encoding = None node = node.coerce_to(PyrexTypes.c_char_ptr_type, self.current_env()) elif node.type.is_string: encoding = None else: encoding = node = None return encoding, node def _handle_simple_method_str_endswith(self, node, function, args, is_unbound_method): return self._inject_tailmatch( node, function, args, is_unbound_method, 'str', 'endswith', str_tailmatch_utility_code, +1) def _handle_simple_method_str_startswith(self, node, function, args, is_unbound_method): return self._inject_tailmatch( node, function, args, is_unbound_method, 'str', 'startswith', str_tailmatch_utility_code, -1) def _handle_simple_method_bytes_endswith(self, node, function, args, is_unbound_method): return self._inject_tailmatch( node, function, args, is_unbound_method, 'bytes', 'endswith', bytes_tailmatch_utility_code, +1) def _handle_simple_method_bytes_startswith(self, node, function, args, is_unbound_method): return self._inject_tailmatch( node, function, args, is_unbound_method, 'bytes', 'startswith', bytes_tailmatch_utility_code, -1) ''' # disabled for now, enable when we consider it worth it (see StringTools.c) def _handle_simple_method_bytearray_endswith(self, node, function, args, is_unbound_method): return self._inject_tailmatch( node, function, args, is_unbound_method, 'bytearray', 'endswith', bytes_tailmatch_utility_code, +1) def _handle_simple_method_bytearray_startswith(self, node, function, args, is_unbound_method): return self._inject_tailmatch( node, function, args, is_unbound_method, 'bytearray', 'startswith', bytes_tailmatch_utility_code, -1) ''' ### helpers def _substitute_method_call(self, node, function, name, func_type, attr_name, is_unbound_method, args=(), utility_code=None, is_temp=None, may_return_none=ExprNodes.PythonCapiCallNode.may_return_none, with_none_check=True): args = list(args) if with_none_check and args and not args[0].is_literal: self_arg = args[0] if is_unbound_method: self_arg = self_arg.as_none_safe_node( "descriptor '%s' requires a '%s' object but received a 'NoneType'", format_args=[attr_name, function.obj.name]) else: self_arg = self_arg.as_none_safe_node( "'NoneType' object has no attribute '%s'", error = "PyExc_AttributeError", format_args = [attr_name]) args[0] = self_arg if is_temp is None: is_temp = node.is_temp return ExprNodes.PythonCapiCallNode( node.pos, name, func_type, args = args, is_temp = is_temp, utility_code = utility_code, may_return_none = may_return_none, result_is_used = node.result_is_used, ) def _inject_int_default_argument(self, node, args, arg_index, type, default_value): assert len(args) >= arg_index if len(args) == arg_index: args.append(ExprNodes.IntNode(node.pos, value=str(default_value), type=type, constant_result=default_value)) else: args[arg_index] = args[arg_index].coerce_to(type, self.current_env()) def _inject_bint_default_argument(self, node, args, arg_index, default_value): assert len(args) >= arg_index if len(args) == arg_index: default_value = bool(default_value) args.append(ExprNodes.BoolNode(node.pos, value=default_value, constant_result=default_value)) else: args[arg_index] = args[arg_index].coerce_to_boolean(self.current_env()) unicode_tailmatch_utility_code = UtilityCode.load_cached('unicode_tailmatch', 'StringTools.c') bytes_tailmatch_utility_code = UtilityCode.load_cached('bytes_tailmatch', 'StringTools.c') str_tailmatch_utility_code = UtilityCode.load_cached('str_tailmatch', 'StringTools.c') class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations): """Calculate the result of constant expressions to store it in ``expr_node.constant_result``, and replace trivial cases by their constant result. General rules: - We calculate float constants to make them available to the compiler, but we do not aggregate them into a single literal node to prevent any loss of precision. - We recursively calculate constants from non-literal nodes to make them available to the compiler, but we only aggregate literal nodes at each step. Non-literal nodes are never merged into a single node. """ def __init__(self, reevaluate=False): """ The reevaluate argument specifies whether constant values that were previously computed should be recomputed. """ super(ConstantFolding, self).__init__() self.reevaluate = reevaluate def _calculate_const(self, node): if (not self.reevaluate and node.constant_result is not ExprNodes.constant_value_not_set): return # make sure we always set the value not_a_constant = ExprNodes.not_a_constant node.constant_result = not_a_constant # check if all children are constant children = self.visitchildren(node) for child_result in children.values(): if type(child_result) is list: for child in child_result: if getattr(child, 'constant_result', not_a_constant) is not_a_constant: return elif getattr(child_result, 'constant_result', not_a_constant) is not_a_constant: return # now try to calculate the real constant value try: node.calculate_constant_result() # if node.constant_result is not ExprNodes.not_a_constant: # print node.__class__.__name__, node.constant_result except (ValueError, TypeError, KeyError, IndexError, AttributeError, ArithmeticError): # ignore all 'normal' errors here => no constant result pass except Exception: # this looks like a real error import traceback, sys traceback.print_exc(file=sys.stdout) NODE_TYPE_ORDER = [ExprNodes.BoolNode, ExprNodes.CharNode, ExprNodes.IntNode, ExprNodes.FloatNode] def _widest_node_class(self, *nodes): try: return self.NODE_TYPE_ORDER[ max(map(self.NODE_TYPE_ORDER.index, map(type, nodes)))] except ValueError: return None def _bool_node(self, node, value): value = bool(value) return ExprNodes.BoolNode(node.pos, value=value, constant_result=value) def visit_ExprNode(self, node): self._calculate_const(node) return node def visit_UnopNode(self, node): self._calculate_const(node) if not node.has_constant_result(): if node.operator == '!': return self._handle_NotNode(node) return node if not node.operand.is_literal: return node if node.operator == '!': return self._bool_node(node, node.constant_result) elif isinstance(node.operand, ExprNodes.BoolNode): return ExprNodes.IntNode(node.pos, value=str(int(node.constant_result)), type=PyrexTypes.c_int_type, constant_result=int(node.constant_result)) elif node.operator == '+': return self._handle_UnaryPlusNode(node) elif node.operator == '-': return self._handle_UnaryMinusNode(node) return node _negate_operator = { 'in': 'not_in', 'not_in': 'in', 'is': 'is_not', 'is_not': 'is' }.get def _handle_NotNode(self, node): operand = node.operand if isinstance(operand, ExprNodes.PrimaryCmpNode): operator = self._negate_operator(operand.operator) if operator: node = copy.copy(operand) node.operator = operator node = self.visit_PrimaryCmpNode(node) return node def _handle_UnaryMinusNode(self, node): def _negate(value): if value.startswith('-'): value = value[1:] else: value = '-' + value return value node_type = node.operand.type if isinstance(node.operand, ExprNodes.FloatNode): # this is a safe operation return ExprNodes.FloatNode(node.pos, value=_negate(node.operand.value), type=node_type, constant_result=node.constant_result) if node_type.is_int and node_type.signed or \ isinstance(node.operand, ExprNodes.IntNode) and node_type.is_pyobject: return ExprNodes.IntNode(node.pos, value=_negate(node.operand.value), type=node_type, longness=node.operand.longness, constant_result=node.constant_result) return node def _handle_UnaryPlusNode(self, node): if (node.operand.has_constant_result() and node.constant_result == node.operand.constant_result): return node.operand return node def visit_BoolBinopNode(self, node): self._calculate_const(node) if not node.operand1.has_constant_result(): return node if node.operand1.constant_result: if node.operator == 'and': return node.operand2 else: return node.operand1 else: if node.operator == 'and': return node.operand1 else: return node.operand2 def visit_BinopNode(self, node): self._calculate_const(node) if node.constant_result is ExprNodes.not_a_constant: return node if isinstance(node.constant_result, float): return node operand1, operand2 = node.operand1, node.operand2 if not operand1.is_literal or not operand2.is_literal: return node # now inject a new constant node with the calculated value try: type1, type2 = operand1.type, operand2.type if type1 is None or type2 is None: return node except AttributeError: return node if type1.is_numeric and type2.is_numeric: widest_type = PyrexTypes.widest_numeric_type(type1, type2) else: widest_type = PyrexTypes.py_object_type target_class = self._widest_node_class(operand1, operand2) if target_class is None: return node elif target_class is ExprNodes.BoolNode and node.operator in '+-//<<%**>>': # C arithmetic results in at least an int type target_class = ExprNodes.IntNode elif target_class is ExprNodes.CharNode and node.operator in '+-//<<%**>>&|^': # C arithmetic results in at least an int type target_class = ExprNodes.IntNode if target_class is ExprNodes.IntNode: unsigned = getattr(operand1, 'unsigned', '') and \ getattr(operand2, 'unsigned', '') longness = "LL"[:max(len(getattr(operand1, 'longness', '')), len(getattr(operand2, 'longness', '')))] new_node = ExprNodes.IntNode(pos=node.pos, unsigned=unsigned, longness=longness, value=str(int(node.constant_result)), constant_result=int(node.constant_result)) # IntNode is smart about the type it chooses, so we just # make sure we were not smarter this time if widest_type.is_pyobject or new_node.type.is_pyobject: new_node.type = PyrexTypes.py_object_type else: new_node.type = PyrexTypes.widest_numeric_type(widest_type, new_node.type) else: if target_class is ExprNodes.BoolNode: node_value = node.constant_result else: node_value = str(node.constant_result) new_node = target_class(pos=node.pos, type = widest_type, value = node_value, constant_result = node.constant_result) return new_node def visit_AddNode(self, node): self._calculate_const(node) if node.constant_result is ExprNodes.not_a_constant: return node if node.operand1.is_string_literal and node.operand2.is_string_literal: # some people combine string literals with a '+' str1, str2 = node.operand1, node.operand2 if isinstance(str1, ExprNodes.UnicodeNode) and isinstance(str2, ExprNodes.UnicodeNode): bytes_value = None if str1.bytes_value is not None and str2.bytes_value is not None: if str1.bytes_value.encoding == str2.bytes_value.encoding: bytes_value = bytes_literal( str1.bytes_value + str2.bytes_value, str1.bytes_value.encoding) string_value = EncodedString(node.constant_result) return ExprNodes.UnicodeNode( str1.pos, value=string_value, constant_result=node.constant_result, bytes_value=bytes_value) elif isinstance(str1, ExprNodes.BytesNode) and isinstance(str2, ExprNodes.BytesNode): if str1.value.encoding == str2.value.encoding: bytes_value = bytes_literal(node.constant_result, str1.value.encoding) return ExprNodes.BytesNode(str1.pos, value=bytes_value, constant_result=node.constant_result) # all other combinations are rather complicated # to get right in Py2/3: encodings, unicode escapes, ... return self.visit_BinopNode(node) def visit_MulNode(self, node): self._calculate_const(node) if node.operand1.is_sequence_constructor: return self._calculate_constant_seq(node, node.operand1, node.operand2) if isinstance(node.operand1, ExprNodes.IntNode) and \ node.operand2.is_sequence_constructor: return self._calculate_constant_seq(node, node.operand2, node.operand1) return self.visit_BinopNode(node) def _calculate_constant_seq(self, node, sequence_node, factor): if factor.constant_result != 1 and sequence_node.args: if isinstance(factor.constant_result, _py_int_types) and factor.constant_result <= 0: del sequence_node.args[:] sequence_node.mult_factor = None elif sequence_node.mult_factor is not None: if (isinstance(factor.constant_result, _py_int_types) and isinstance(sequence_node.mult_factor.constant_result, _py_int_types)): value = sequence_node.mult_factor.constant_result * factor.constant_result sequence_node.mult_factor = ExprNodes.IntNode( sequence_node.mult_factor.pos, value=str(value), constant_result=value) else: # don't know if we can combine the factors, so don't return self.visit_BinopNode(node) else: sequence_node.mult_factor = factor return sequence_node def visit_MergedDictNode(self, node): """Unpack **args in place if we can.""" self.visitchildren(node) args = [] items = [] def add(arg): if arg.is_dict_literal: if items: items[0].key_value_pairs.extend(arg.key_value_pairs) else: items.append(arg) elif isinstance(arg, ExprNodes.MergedDictNode): for child_arg in arg.keyword_args: add(child_arg) else: if items: args.append(items[0]) del items[:] args.append(arg) for arg in node.keyword_args: add(arg) if items: args.append(items[0]) if len(args) == 1: arg = args[0] if arg.is_dict_literal or isinstance(arg, ExprNodes.MergedDictNode): return arg node.keyword_args[:] = args self._calculate_const(node) return node def visit_MergedSequenceNode(self, node): """Unpack *args in place if we can.""" self.visitchildren(node) is_set = node.type is Builtin.set_type args = [] values = [] def add(arg): if (is_set and arg.is_set_literal) or (arg.is_sequence_constructor and not arg.mult_factor): if values: values[0].args.extend(arg.args) else: values.append(arg) elif isinstance(arg, ExprNodes.MergedSequenceNode): for child_arg in arg.args: add(child_arg) else: if values: args.append(values[0]) del values[:] args.append(arg) for arg in node.args: add(arg) if values: args.append(values[0]) if len(args) == 1: arg = args[0] if ((is_set and arg.is_set_literal) or (arg.is_sequence_constructor and arg.type is node.type) or isinstance(arg, ExprNodes.MergedSequenceNode)): return arg node.args[:] = args self._calculate_const(node) return node def visit_SequenceNode(self, node): """Unpack *args in place if we can.""" self.visitchildren(node) args = [] for arg in node.args: if not arg.is_starred: args.append(arg) elif arg.target.is_sequence_constructor and not arg.target.mult_factor: args.extend(arg.target.args) else: args.append(arg) node.args[:] = args self._calculate_const(node) return node def visit_PrimaryCmpNode(self, node): # calculate constant partial results in the comparison cascade self.visitchildren(node, ['operand1']) left_node = node.operand1 cmp_node = node while cmp_node is not None: self.visitchildren(cmp_node, ['operand2']) right_node = cmp_node.operand2 cmp_node.constant_result = not_a_constant if left_node.has_constant_result() and right_node.has_constant_result(): try: cmp_node.calculate_cascaded_constant_result(left_node.constant_result) except (ValueError, TypeError, KeyError, IndexError, AttributeError, ArithmeticError): pass # ignore all 'normal' errors here => no constant result left_node = right_node cmp_node = cmp_node.cascade if not node.cascade: if node.has_constant_result(): return self._bool_node(node, node.constant_result) return node # collect partial cascades: [[value, CmpNode...], [value, CmpNode, ...], ...] cascades = [[node.operand1]] final_false_result = [] def split_cascades(cmp_node): if cmp_node.has_constant_result(): if not cmp_node.constant_result: # False => short-circuit final_false_result.append(self._bool_node(cmp_node, False)) return else: # True => discard and start new cascade cascades.append([cmp_node.operand2]) else: # not constant => append to current cascade cascades[-1].append(cmp_node) if cmp_node.cascade: split_cascades(cmp_node.cascade) split_cascades(node) cmp_nodes = [] for cascade in cascades: if len(cascade) < 2: continue cmp_node = cascade[1] pcmp_node = ExprNodes.PrimaryCmpNode( cmp_node.pos, operand1=cascade[0], operator=cmp_node.operator, operand2=cmp_node.operand2, constant_result=not_a_constant) cmp_nodes.append(pcmp_node) last_cmp_node = pcmp_node for cmp_node in cascade[2:]: last_cmp_node.cascade = cmp_node last_cmp_node = cmp_node last_cmp_node.cascade = None if final_false_result: # last cascade was constant False cmp_nodes.append(final_false_result[0]) elif not cmp_nodes: # only constants, but no False result return self._bool_node(node, True) node = cmp_nodes[0] if len(cmp_nodes) == 1: if node.has_constant_result(): return self._bool_node(node, node.constant_result) else: for cmp_node in cmp_nodes[1:]: node = ExprNodes.BoolBinopNode( node.pos, operand1=node, operator='and', operand2=cmp_node, constant_result=not_a_constant) return node def visit_CondExprNode(self, node): self._calculate_const(node) if not node.test.has_constant_result(): return node if node.test.constant_result: return node.true_val else: return node.false_val def visit_IfStatNode(self, node): self.visitchildren(node) # eliminate dead code based on constant condition results if_clauses = [] for if_clause in node.if_clauses: condition = if_clause.condition if condition.has_constant_result(): if condition.constant_result: # always true => subsequent clauses can safely be dropped node.else_clause = if_clause.body break # else: false => drop clause else: # unknown result => normal runtime evaluation if_clauses.append(if_clause) if if_clauses: node.if_clauses = if_clauses return node elif node.else_clause: return node.else_clause else: return Nodes.StatListNode(node.pos, stats=[]) def visit_SliceIndexNode(self, node): self._calculate_const(node) # normalise start/stop values if node.start is None or node.start.constant_result is None: start = node.start = None else: start = node.start.constant_result if node.stop is None or node.stop.constant_result is None: stop = node.stop = None else: stop = node.stop.constant_result # cut down sliced constant sequences if node.constant_result is not not_a_constant: base = node.base if base.is_sequence_constructor and base.mult_factor is None: base.args = base.args[start:stop] return base elif base.is_string_literal: base = base.as_sliced_node(start, stop) if base is not None: return base return node def visit_ComprehensionNode(self, node): self.visitchildren(node) if isinstance(node.loop, Nodes.StatListNode) and not node.loop.stats: # loop was pruned already => transform into literal if node.type is Builtin.list_type: return ExprNodes.ListNode( node.pos, args=[], constant_result=[]) elif node.type is Builtin.set_type: return ExprNodes.SetNode( node.pos, args=[], constant_result=set()) elif node.type is Builtin.dict_type: return ExprNodes.DictNode( node.pos, key_value_pairs=[], constant_result={}) return node def visit_ForInStatNode(self, node): self.visitchildren(node) sequence = node.iterator.sequence if isinstance(sequence, ExprNodes.SequenceNode): if not sequence.args: if node.else_clause: return node.else_clause else: # don't break list comprehensions return Nodes.StatListNode(node.pos, stats=[]) # iterating over a list literal? => tuples are more efficient if isinstance(sequence, ExprNodes.ListNode): node.iterator.sequence = sequence.as_tuple() return node def visit_WhileStatNode(self, node): self.visitchildren(node) if node.condition and node.condition.has_constant_result(): if node.condition.constant_result: node.condition = None node.else_clause = None else: return node.else_clause return node def visit_ExprStatNode(self, node): self.visitchildren(node) if not isinstance(node.expr, ExprNodes.ExprNode): # ParallelRangeTransform does this ... return node # drop unused constant expressions if node.expr.has_constant_result(): return None return node # in the future, other nodes can have their own handler method here # that can replace them with a constant result node visit_Node = Visitor.VisitorTransform.recurse_to_children class FinalOptimizePhase(Visitor.CythonTransform, Visitor.NodeRefCleanupMixin): """ This visitor handles several commuting optimizations, and is run just before the C code generation phase. The optimizations currently implemented in this class are: - eliminate None assignment and refcounting for first assignment. - isinstance -> typecheck for cdef types - eliminate checks for None and/or types that became redundant after tree changes - replace Python function calls that look like method calls by a faster PyMethodCallNode """ def visit_SingleAssignmentNode(self, node): """Avoid redundant initialisation of local variables before their first assignment. """ self.visitchildren(node) if node.first: lhs = node.lhs lhs.lhs_of_first_assignment = True return node def visit_SimpleCallNode(self, node): """ Replace generic calls to isinstance(x, type) by a more efficient type check. Replace likely Python method calls by a specialised PyMethodCallNode. """ self.visitchildren(node) function = node.function if function.type.is_cfunction and function.is_name: if function.name == 'isinstance' and len(node.args) == 2: type_arg = node.args[1] if type_arg.type.is_builtin_type and type_arg.type.name == 'type': cython_scope = self.context.cython_scope function.entry = cython_scope.lookup('PyObject_TypeCheck') function.type = function.entry.type PyTypeObjectPtr = PyrexTypes.CPtrType(cython_scope.lookup('PyTypeObject').type) node.args[1] = ExprNodes.CastNode(node.args[1], PyTypeObjectPtr) elif (self.current_directives.get("optimize.unpack_method_calls") and node.is_temp and function.type.is_pyobject): # optimise simple Python methods calls if isinstance(node.arg_tuple, ExprNodes.TupleNode) and not ( node.arg_tuple.mult_factor or (node.arg_tuple.is_literal and node.arg_tuple.args)): # simple call, now exclude calls to objects that are definitely not methods may_be_a_method = True if function.type is Builtin.type_type: may_be_a_method = False elif function.is_attribute: if function.entry and function.entry.type.is_cfunction: # optimised builtin method may_be_a_method = False elif function.is_name: entry = function.entry if entry.is_builtin or entry.type.is_cfunction: may_be_a_method = False elif entry.cf_assignments: # local functions/classes are definitely not methods non_method_nodes = (ExprNodes.PyCFunctionNode, ExprNodes.ClassNode, ExprNodes.Py3ClassNode) may_be_a_method = any( assignment.rhs and not isinstance(assignment.rhs, non_method_nodes) for assignment in entry.cf_assignments) if may_be_a_method: if (node.self and function.is_attribute and isinstance(function.obj, ExprNodes.CloneNode) and function.obj.arg is node.self): # function self object was moved into a CloneNode => undo function.obj = function.obj.arg node = self.replace(node, ExprNodes.PyMethodCallNode.from_node( node, function=function, arg_tuple=node.arg_tuple, type=node.type)) return node def visit_PyTypeTestNode(self, node): """Remove tests for alternatively allowed None values from type tests when we know that the argument cannot be None anyway. """ self.visitchildren(node) if not node.notnone: if not node.arg.may_be_none(): node.notnone = True return node def visit_NoneCheckNode(self, node): """Remove None checks from expressions that definitely do not carry a None value. """ self.visitchildren(node) if not node.arg.may_be_none(): return node.arg return node class ConsolidateOverflowCheck(Visitor.CythonTransform): """ This class facilitates the sharing of overflow checking among all nodes of a nested arithmetic expression. For example, given the expression a*b + c, where a, b, and x are all possibly overflowing ints, the entire sequence will be evaluated and the overflow bit checked only at the end. """ overflow_bit_node = None def visit_Node(self, node): if self.overflow_bit_node is not None: saved = self.overflow_bit_node self.overflow_bit_node = None self.visitchildren(node) self.overflow_bit_node = saved else: self.visitchildren(node) return node def visit_NumBinopNode(self, node): if node.overflow_check and node.overflow_fold: top_level_overflow = self.overflow_bit_node is None if top_level_overflow: self.overflow_bit_node = node else: node.overflow_bit_node = self.overflow_bit_node node.overflow_check = False self.visitchildren(node) if top_level_overflow: self.overflow_bit_node = None else: self.visitchildren(node) return node Cython-0.23.4/Cython/Compiler/Nodes.py0000644000175600017570000127302012606202452020651 0ustar jenkinsjenkins00000000000000# # Parse tree nodes # from __future__ import absolute_import import cython cython.declare(sys=object, os=object, copy=object, Builtin=object, error=object, warning=object, Naming=object, PyrexTypes=object, py_object_type=object, ModuleScope=object, LocalScope=object, ClosureScope=object, StructOrUnionScope=object, PyClassScope=object, CppClassScope=object, UtilityCode=object, EncodedString=object, absolute_path_length=cython.Py_ssize_t, error_type=object, _py_int_types=object) import sys, os, copy from itertools import chain if sys.version_info[0] >= 3: _py_int_types = int else: _py_int_types = (int, long) from . import Builtin from .Errors import error, warning, InternalError, CompileError from . import Naming from . import PyrexTypes from . import TypeSlots from .PyrexTypes import py_object_type, error_type from .Symtab import (ModuleScope, LocalScope, ClosureScope, StructOrUnionScope, PyClassScope, CppClassScope, TemplateScope) from .Code import UtilityCode from .StringEncoding import EncodedString, escape_byte_string, split_string_literal from . import Future from . import Options from . import DebugFlags from ..Utils import add_metaclass absolute_path_length = 0 def relative_position(pos): """ We embed the relative filename in the generated C file, since we don't want to have to regenerate and compile all the source code whenever the Python install directory moves (which could happen, e.g,. when distributing binaries.) INPUT: a position tuple -- (absolute filename, line number column position) OUTPUT: relative filename line number AUTHOR: William Stein """ global absolute_path_length if absolute_path_length==0: absolute_path_length = len(os.path.abspath(os.getcwd())) return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1]) def embed_position(pos, docstring): if not Options.embed_pos_in_docstring: return docstring pos_line = u'File: %s (starting at line %s)' % relative_position(pos) if docstring is None: # unicode string return EncodedString(pos_line) # make sure we can encode the filename in the docstring encoding # otherwise make the docstring a unicode string encoding = docstring.encoding if encoding is not None: try: pos_line.encode(encoding) except UnicodeEncodeError: encoding = None if not docstring: # reuse the string encoding of the original docstring doc = EncodedString(pos_line) else: doc = EncodedString(pos_line + u'\n' + docstring) doc.encoding = encoding return doc def _analyse_signature_annotation(annotation, env): base_type = None explicit_pytype = explicit_ctype = False if annotation.is_dict_literal: for name, value in annotation.key_value_pairs: if not name.is_string_literal: continue if name.value in ('type', b'type'): explicit_pytype = True if not explicit_ctype: annotation = value elif name.value in ('ctype', b'ctype'): explicit_ctype = True annotation = value if explicit_pytype and explicit_ctype: warning(annotation.pos, "Duplicate type declarations found in signature annotation") arg_type = annotation.analyse_as_type(env) if arg_type is not None: if explicit_pytype and not explicit_ctype and not arg_type.is_pyobject: warning(annotation.pos, "Python type declaration in signature annotation does not refer to a Python type") base_type = CAnalysedBaseTypeNode( annotation.pos, type=arg_type, is_arg=True) else: warning(annotation.pos, "Unknown type declaration found in signature annotation") return base_type, arg_type def write_func_call(func, codewriter_class): def f(*args, **kwds): if len(args) > 1 and isinstance(args[1], codewriter_class): # here we annotate the code with this function call # but only if new code is generated node, code = args[:2] marker = ' /* %s -> %s.%s %s */' % ( ' ' * code.call_level, node.__class__.__name__, func.__name__, node.pos[1:]) pristine = code.buffer.stream.tell() code.putln(marker) start = code.buffer.stream.tell() code.call_level += 4 res = func(*args, **kwds) code.call_level -= 4 if start == code.buffer.stream.tell(): # no code written => undo writing marker code.buffer.stream.truncate(pristine) else: marker = marker.replace('->', '<-', 1) code.putln(marker) return res else: return func(*args, **kwds) return f class VerboseCodeWriter(type): # Set this as a metaclass to trace function calls in code. # This slows down code generation and makes much larger files. def __new__(cls, name, bases, attrs): from types import FunctionType from .Code import CCodeWriter attrs = dict(attrs) for mname, m in attrs.items(): if isinstance(m, FunctionType): attrs[mname] = write_func_call(m, CCodeWriter) return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs) class CheckAnalysers(type): """Metaclass to check that type analysis functions return a node. """ methods = set(['analyse_types', 'analyse_expressions', 'analyse_target_types']) def __new__(cls, name, bases, attrs): from types import FunctionType def check(name, func): def call(*args, **kwargs): retval = func(*args, **kwargs) if retval is None: print('%s %s %s' % (name, args, kwargs)) return retval return call attrs = dict(attrs) for mname, m in attrs.items(): if isinstance(m, FunctionType) and mname in cls.methods: attrs[mname] = check(mname, m) return super(CheckAnalysers, cls).__new__(cls, name, bases, attrs) def _with_metaclass(cls): if DebugFlags.debug_trace_code_generation: return add_metaclass(VerboseCodeWriter)(cls) #return add_metaclass(CheckAnalysers)(cls) return cls @_with_metaclass class Node(object): # pos (string, int, int) Source file position # is_name boolean Is a NameNode # is_literal boolean Is a ConstNode is_name = 0 is_none = 0 is_nonecheck = 0 is_literal = 0 is_terminator = 0 temps = None # All descendants should set child_attrs to a list of the attributes # containing nodes considered "children" in the tree. Each such attribute # can either contain a single node or a list of nodes. See Visitor.py. child_attrs = None cf_state = None # This may be an additional (or 'actual') type that will be checked when # this node is coerced to another type. This could be useful to set when # the actual type to which it can coerce is known, but you want to leave # the type a py_object_type coercion_type = None def __init__(self, pos, **kw): self.pos = pos self.__dict__.update(kw) gil_message = "Operation" nogil_check = None def gil_error(self, env=None): error(self.pos, "%s not allowed without gil" % self.gil_message) cpp_message = "Operation" def cpp_check(self, env): if not env.is_cpp(): self.cpp_error() def cpp_error(self): error(self.pos, "%s only allowed in c++" % self.cpp_message) def clone_node(self): """Clone the node. This is defined as a shallow copy, except for member lists amongst the child attributes (from get_child_accessors) which are also copied. Lists containing child nodes are thus seen as a way for the node to hold multiple children directly; the list is not treated as a separate level in the tree.""" result = copy.copy(self) for attrname in result.child_attrs: value = getattr(result, attrname) if isinstance(value, list): setattr(result, attrname, [x for x in value]) return result # # There are 3 phases of parse tree processing, applied in order to # all the statements in a given scope-block: # # (0) analyse_declarations # Make symbol table entries for all declarations at the current # level, both explicit (def, cdef, etc.) and implicit (assignment # to an otherwise undeclared name). # # (1) analyse_expressions # Determine the result types of expressions and fill in the # 'type' attribute of each ExprNode. Insert coercion nodes into the # tree where needed to convert to and from Python objects. # Allocate temporary locals for intermediate results. Fill # in the 'result_code' attribute of each ExprNode with a C code # fragment. # # (2) generate_code # Emit C code for all declarations, statements and expressions. # Recursively applies the 3 processing phases to the bodies of # functions. # def analyse_declarations(self, env): pass def analyse_expressions(self, env): raise InternalError("analyse_expressions not implemented for %s" % \ self.__class__.__name__) def generate_code(self, code): raise InternalError("generate_code not implemented for %s" % \ self.__class__.__name__) def annotate(self, code): # mro does the wrong thing if isinstance(self, BlockNode): self.body.annotate(code) def end_pos(self): try: return self._end_pos except AttributeError: pos = self.pos if not self.child_attrs: self._end_pos = pos return pos for attr in self.child_attrs: child = getattr(self, attr) # Sometimes lists, sometimes nodes if child is None: pass elif isinstance(child, list): for c in child: pos = max(pos, c.end_pos()) else: pos = max(pos, child.end_pos()) self._end_pos = pos return pos def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None): """Debug helper method that returns a recursive string representation of this node. """ if cutoff == 0: return "<...nesting level cutoff...>" if encountered is None: encountered = set() if id(self) in encountered: return "<%s (0x%x) -- already output>" % (self.__class__.__name__, id(self)) encountered.add(id(self)) def dump_child(x, level): if isinstance(x, Node): return x.dump(level, filter_out, cutoff-1, encountered) elif isinstance(x, list): return "[%s]" % ", ".join([dump_child(item, level) for item in x]) else: return repr(x) attrs = [(key, value) for key, value in self.__dict__.items() if key not in filter_out] if len(attrs) == 0: return "<%s (0x%x)>" % (self.__class__.__name__, id(self)) else: indent = " " * level res = "<%s (0x%x)\n" % (self.__class__.__name__, id(self)) for key, value in attrs: res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1)) res += "%s>" % indent return res def dump_pos(self, mark_column=False, marker='(#)'): """Debug helper method that returns the source code context of this node as a string. """ if not self.pos: return u'' source_desc, line, col = self.pos contents = source_desc.get_lines(encoding='ASCII', error_handling='ignore') # line numbers start at 1 lines = contents[max(0,line-3):line] current = lines[-1] if mark_column: current = current[:col] + marker + current[col:] lines[-1] = current.rstrip() + u' # <<<<<<<<<<<<<<\n' lines += contents[line:line+2] return u'"%s":%d:%d\n%s\n' % ( source_desc.get_escaped_description(), line, col, u''.join(lines)) class CompilerDirectivesNode(Node): """ Sets compiler directives for the children nodes """ # directives {string:value} A dictionary holding the right value for # *all* possible directives. # body Node child_attrs = ["body"] def analyse_declarations(self, env): old = env.directives env.directives = self.directives self.body.analyse_declarations(env) env.directives = old def analyse_expressions(self, env): old = env.directives env.directives = self.directives self.body = self.body.analyse_expressions(env) env.directives = old return self def generate_function_definitions(self, env, code): env_old = env.directives code_old = code.globalstate.directives code.globalstate.directives = self.directives self.body.generate_function_definitions(env, code) env.directives = env_old code.globalstate.directives = code_old def generate_execution_code(self, code): old = code.globalstate.directives code.globalstate.directives = self.directives self.body.generate_execution_code(code) code.globalstate.directives = old def annotate(self, code): old = code.globalstate.directives code.globalstate.directives = self.directives self.body.annotate(code) code.globalstate.directives = old class BlockNode(object): # Mixin class for nodes representing a declaration block. def generate_cached_builtins_decls(self, env, code): entries = env.global_scope().undeclared_cached_builtins for entry in entries: code.globalstate.add_cached_builtin_decl(entry) del entries[:] def generate_lambda_definitions(self, env, code): for node in env.lambda_defs: node.generate_function_definitions(env, code) class StatListNode(Node): # stats a list of StatNode child_attrs = ["stats"] @staticmethod def create_analysed(pos, env, *args, **kw): node = StatListNode(pos, *args, **kw) return node # No node-specific analysis needed def analyse_declarations(self, env): #print "StatListNode.analyse_declarations" ### for stat in self.stats: stat.analyse_declarations(env) def analyse_expressions(self, env): #print "StatListNode.analyse_expressions" ### self.stats = [ stat.analyse_expressions(env) for stat in self.stats ] return self def generate_function_definitions(self, env, code): #print "StatListNode.generate_function_definitions" ### for stat in self.stats: stat.generate_function_definitions(env, code) def generate_execution_code(self, code): #print "StatListNode.generate_execution_code" ### for stat in self.stats: code.mark_pos(stat.pos) stat.generate_execution_code(code) def annotate(self, code): for stat in self.stats: stat.annotate(code) class StatNode(Node): # # Code generation for statements is split into the following subphases: # # (1) generate_function_definitions # Emit C code for the definitions of any structs, # unions, enums and functions defined in the current # scope-block. # # (2) generate_execution_code # Emit C code for executable statements. # def generate_function_definitions(self, env, code): pass def generate_execution_code(self, code): raise InternalError("generate_execution_code not implemented for %s" % \ self.__class__.__name__) class CDefExternNode(StatNode): # include_file string or None # body StatNode child_attrs = ["body"] def analyse_declarations(self, env): if self.include_file: env.add_include_file(self.include_file) old_cinclude_flag = env.in_cinclude env.in_cinclude = 1 self.body.analyse_declarations(env) env.in_cinclude = old_cinclude_flag def analyse_expressions(self, env): return self def generate_execution_code(self, code): pass def annotate(self, code): self.body.annotate(code) class CDeclaratorNode(Node): # Part of a C declaration. # # Processing during analyse_declarations phase: # # analyse # Returns (name, type) pair where name is the # CNameDeclaratorNode of the name being declared # and type is the type it is being declared as. # # calling_convention string Calling convention of CFuncDeclaratorNode # for which this is a base child_attrs = [] calling_convention = "" def analyse_templates(self): # Only C++ functions have templates. return None class CNameDeclaratorNode(CDeclaratorNode): # name string The Cython name being declared # cname string or None C name, if specified # default ExprNode or None the value assigned on declaration child_attrs = ['default'] default = None def analyse(self, base_type, env, nonempty = 0): if nonempty and self.name == '': # May have mistaken the name for the type. if base_type.is_ptr or base_type.is_array or base_type.is_buffer: error(self.pos, "Missing argument name") elif base_type.is_void: error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.") else: self.name = base_type.declaration_code("", for_display=1, pyrex=1) base_type = py_object_type if base_type.is_fused and env.fused_to_specific: base_type = base_type.specialize(env.fused_to_specific) self.type = base_type return self, base_type class CPtrDeclaratorNode(CDeclaratorNode): # base CDeclaratorNode child_attrs = ["base"] def analyse(self, base_type, env, nonempty = 0): if base_type.is_pyobject: error(self.pos, "Pointer base type cannot be a Python object") ptr_type = PyrexTypes.c_ptr_type(base_type) return self.base.analyse(ptr_type, env, nonempty = nonempty) class CReferenceDeclaratorNode(CDeclaratorNode): # base CDeclaratorNode child_attrs = ["base"] def analyse(self, base_type, env, nonempty = 0): if base_type.is_pyobject: error(self.pos, "Reference base type cannot be a Python object") ref_type = PyrexTypes.c_ref_type(base_type) return self.base.analyse(ref_type, env, nonempty = nonempty) class CArrayDeclaratorNode(CDeclaratorNode): # base CDeclaratorNode # dimension ExprNode child_attrs = ["base", "dimension"] def analyse(self, base_type, env, nonempty = 0): if (base_type.is_cpp_class and base_type.is_template_type()) or base_type.is_cfunction: from .ExprNodes import TupleNode if isinstance(self.dimension, TupleNode): args = self.dimension.args else: args = self.dimension, values = [v.analyse_as_type(env) for v in args] if None in values: ix = values.index(None) error(args[ix].pos, "Template parameter not a type") base_type = error_type else: base_type = base_type.specialize_here(self.pos, values) return self.base.analyse(base_type, env, nonempty = nonempty) if self.dimension: self.dimension = self.dimension.analyse_const_expression(env) if not self.dimension.type.is_int: error(self.dimension.pos, "Array dimension not integer") size = self.dimension.get_constant_c_result_code() if size is not None: try: size = int(size) except ValueError: # runtime constant? pass else: size = None if not base_type.is_complete(): error(self.pos, "Array element type '%s' is incomplete" % base_type) if base_type.is_pyobject: error(self.pos, "Array element cannot be a Python object") if base_type.is_cfunction: error(self.pos, "Array element cannot be a function") array_type = PyrexTypes.c_array_type(base_type, size) return self.base.analyse(array_type, env, nonempty = nonempty) class CFuncDeclaratorNode(CDeclaratorNode): # base CDeclaratorNode # args [CArgDeclNode] # templates [TemplatePlaceholderType] # has_varargs boolean # exception_value ConstNode # exception_check boolean True if PyErr_Occurred check needed # nogil boolean Can be called without gil # with_gil boolean Acquire gil around function body # is_const_method boolean Whether this is a const method child_attrs = ["base", "args", "exception_value"] overridable = 0 optional_arg_count = 0 is_const_method = 0 templates = None def analyse_templates(self): if isinstance(self.base, CArrayDeclaratorNode): from .ExprNodes import TupleNode, NameNode template_node = self.base.dimension if isinstance(template_node, TupleNode): template_nodes = template_node.args elif isinstance(template_node, NameNode): template_nodes = [template_node] else: error(template_node.pos, "Template arguments must be a list of names") return None self.templates = [] for template in template_nodes: if isinstance(template, NameNode): self.templates.append(PyrexTypes.TemplatePlaceholderType(template.name)) else: error(template.pos, "Template arguments must be a list of names") self.base = self.base.base return self.templates else: return None def analyse(self, return_type, env, nonempty = 0, directive_locals = {}): if nonempty: nonempty -= 1 func_type_args = [] for i, arg_node in enumerate(self.args): name_declarator, type = arg_node.analyse( env, nonempty=nonempty, is_self_arg=(i == 0 and env.is_c_class_scope and 'staticmethod' not in env.directives)) name = name_declarator.name if name in directive_locals: type_node = directive_locals[name] other_type = type_node.analyse_as_type(env) if other_type is None: error(type_node.pos, "Not a type") elif (type is not PyrexTypes.py_object_type and not type.same_as(other_type)): error(self.base.pos, "Signature does not agree with previous declaration") error(type_node.pos, "Previous declaration here") else: type = other_type if name_declarator.cname: error(self.pos, "Function argument cannot have C name specification") if i==0 and env.is_c_class_scope and type.is_unspecified: # fix the type of self type = env.parent_type # Turn *[] argument into ** if type.is_array: type = PyrexTypes.c_ptr_type(type.base_type) # Catch attempted C-style func(void) decl if type.is_void: error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.") func_type_args.append( PyrexTypes.CFuncTypeArg(name, type, arg_node.pos)) if arg_node.default: self.optional_arg_count += 1 elif self.optional_arg_count: error(self.pos, "Non-default argument follows default argument") exc_val = None exc_check = 0 if self.exception_check == '+': env.add_include_file('ios') # for std::ios_base::failure env.add_include_file('new') # for std::bad_alloc env.add_include_file('stdexcept') env.add_include_file('typeinfo') # for std::bad_cast if (return_type.is_pyobject and (self.exception_value or self.exception_check) and self.exception_check != '+'): error(self.pos, "Exception clause not allowed for function returning Python object") else: if self.exception_value: self.exception_value = self.exception_value.analyse_const_expression(env) if self.exception_check == '+': exc_val_type = self.exception_value.type if (not exc_val_type.is_error and not exc_val_type.is_pyobject and not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and not exc_val_type.args)): error(self.exception_value.pos, "Exception value must be a Python exception or cdef function with no arguments.") exc_val = self.exception_value else: self.exception_value = self.exception_value.coerce_to( return_type, env).analyse_const_expression(env) exc_val = self.exception_value.get_constant_c_result_code() if exc_val is None: raise InternalError( "get_constant_c_result_code not implemented for %s" % self.exception_value.__class__.__name__) if not return_type.assignable_from(self.exception_value.type): error(self.exception_value.pos, "Exception value incompatible with function return type") exc_check = self.exception_check if return_type.is_cfunction: error(self.pos, "Function cannot return a function") func_type = PyrexTypes.CFuncType( return_type, func_type_args, self.has_varargs, optional_arg_count = self.optional_arg_count, exception_value = exc_val, exception_check = exc_check, calling_convention = self.base.calling_convention, nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable, is_const_method = self.is_const_method, templates = self.templates) if self.optional_arg_count: if func_type.is_fused: # This is a bit of a hack... When we need to create specialized CFuncTypes # on the fly because the cdef is defined in a pxd, we need to declare the specialized optional arg # struct def declare_opt_arg_struct(func_type, fused_cname): self.declare_optional_arg_struct(func_type, env, fused_cname) func_type.declare_opt_arg_struct = declare_opt_arg_struct else: self.declare_optional_arg_struct(func_type, env) callspec = env.directives['callspec'] if callspec: current = func_type.calling_convention if current and current != callspec: error(self.pos, "cannot have both '%s' and '%s' " "calling conventions" % (current, callspec)) func_type.calling_convention = callspec return self.base.analyse(func_type, env) def declare_optional_arg_struct(self, func_type, env, fused_cname=None): """ Declares the optional argument struct (the struct used to hold the values for optional arguments). For fused cdef functions, this is deferred as analyse_declarations is called only once (on the fused cdef function). """ scope = StructOrUnionScope() arg_count_member = '%sn' % Naming.pyrex_prefix scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos) for arg in func_type.args[len(func_type.args)-self.optional_arg_count:]: scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1) struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name) if fused_cname is not None: struct_cname = PyrexTypes.get_fused_cname(fused_cname, struct_cname) op_args_struct = env.global_scope().declare_struct_or_union( name = struct_cname, kind = 'struct', scope = scope, typedef_flag = 0, pos = self.pos, cname = struct_cname) op_args_struct.defined_in_pxd = 1 op_args_struct.used = 1 func_type.op_arg_struct = PyrexTypes.c_ptr_type(op_args_struct.type) class CConstDeclaratorNode(CDeclaratorNode): # base CDeclaratorNode child_attrs = ["base"] def analyse(self, base_type, env, nonempty = 0): if base_type.is_pyobject: error(self.pos, "Const base type cannot be a Python object") const = PyrexTypes.c_const_type(base_type) return self.base.analyse(const, env, nonempty = nonempty) class CArgDeclNode(Node): # Item in a function declaration argument list. # # base_type CBaseTypeNode # declarator CDeclaratorNode # not_none boolean Tagged with 'not None' # or_none boolean Tagged with 'or None' # accept_none boolean Resolved boolean for not_none/or_none # default ExprNode or None # default_value PyObjectConst constant for default value # annotation ExprNode or None Py3 function arg annotation # is_self_arg boolean Is the "self" arg of an extension type method # is_type_arg boolean Is the "class" arg of an extension type classmethod # is_kw_only boolean Is a keyword-only argument # is_dynamic boolean Non-literal arg stored inside CyFunction child_attrs = ["base_type", "declarator", "default", "annotation"] is_self_arg = 0 is_type_arg = 0 is_generic = 1 kw_only = 0 not_none = 0 or_none = 0 type = None name_declarator = None default_value = None annotation = None is_dynamic = 0 def analyse(self, env, nonempty = 0, is_self_arg = False): if is_self_arg: self.base_type.is_self_arg = self.is_self_arg = True if self.type is None: # The parser may misinterpret names as types. We fix that here. if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '': if nonempty: if self.base_type.is_basic_c_type: # char, short, long called "int" type = self.base_type.analyse(env, could_be_name=True) arg_name = type.empty_declaration_code() else: arg_name = self.base_type.name self.declarator.name = EncodedString(arg_name) self.base_type.name = None self.base_type.is_basic_c_type = False could_be_name = True else: could_be_name = False self.base_type.is_arg = True base_type = self.base_type.analyse(env, could_be_name=could_be_name) if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name: self.declarator.name = self.base_type.arg_name # The parser is unable to resolve the ambiguity of [] as part of the # type (e.g. in buffers) or empty declarator (as with arrays). # This is only arises for empty multi-dimensional arrays. if (base_type.is_array and isinstance(self.base_type, TemplatedTypeNode) and isinstance(self.declarator, CArrayDeclaratorNode)): declarator = self.declarator while isinstance(declarator.base, CArrayDeclaratorNode): declarator = declarator.base declarator.base = self.base_type.array_declarator base_type = base_type.base_type # inject type declaration from annotations if self.annotation and env.directives['annotation_typing'] and self.base_type.name is None: arg_type = self.inject_type_from_annotations(env) if arg_type is not None: base_type = arg_type return self.declarator.analyse(base_type, env, nonempty=nonempty) else: return self.name_declarator, self.type def inject_type_from_annotations(self, env): annotation = self.annotation if not annotation: return None base_type, arg_type = _analyse_signature_annotation(annotation, env) if base_type is not None: self.base_type = base_type return arg_type def calculate_default_value_code(self, code): if self.default_value is None: if self.default: if self.default.is_literal: # will not output any code, just assign the result_code self.default.generate_evaluation_code(code) return self.type.cast_code(self.default.result()) self.default_value = code.get_argument_default_const(self.type) return self.default_value def annotate(self, code): if self.default: self.default.annotate(code) def generate_assignment_code(self, code, target=None, overloaded_assignment=False): default = self.default if default is None or default.is_literal: return if target is None: target = self.calculate_default_value_code(code) default.generate_evaluation_code(code) default.make_owned_reference(code) result = default.result() if overloaded_assignment else default.result_as(self.type) code.putln("%s = %s;" % (target, result)) if self.type.is_pyobject: code.put_giveref(default.result()) default.generate_post_assignment_code(code) default.free_temps(code) class CBaseTypeNode(Node): # Abstract base class for C base type nodes. # # Processing during analyse_declarations phase: # # analyse # Returns the type. def analyse_as_type(self, env): return self.analyse(env) class CAnalysedBaseTypeNode(Node): # type type child_attrs = [] def analyse(self, env, could_be_name = False): return self.type class CSimpleBaseTypeNode(CBaseTypeNode): # name string # module_path [string] Qualifying name components # is_basic_c_type boolean # signed boolean # longness integer # complex boolean # is_self_arg boolean Is self argument of C method # ##is_type_arg boolean Is type argument of class method child_attrs = [] arg_name = None # in case the argument name was interpreted as a type module_path = [] is_basic_c_type = False complex = False def analyse(self, env, could_be_name = False): # Return type descriptor. #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ### type = None if self.is_basic_c_type: type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name) if not type: error(self.pos, "Unrecognised type modifier combination") elif self.name == "object" and not self.module_path: type = py_object_type elif self.name is None: if self.is_self_arg and env.is_c_class_scope: #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ### type = env.parent_type ## elif self.is_type_arg and env.is_c_class_scope: ## type = Builtin.type_type else: type = py_object_type else: if self.module_path: # Maybe it's a nested C++ class. scope = env for item in self.module_path: entry = scope.lookup(item) if entry is not None and entry.is_cpp_class: scope = entry.type.scope else: scope = None break if scope is None: # Maybe it's a cimport. scope = env.find_imported_module(self.module_path, self.pos) if scope: scope.fused_to_specific = env.fused_to_specific else: scope = env if scope: if scope.is_c_class_scope: scope = scope.global_scope() type = scope.lookup_type(self.name) if type is not None: pass elif could_be_name: if self.is_self_arg and env.is_c_class_scope: type = env.parent_type ## elif self.is_type_arg and env.is_c_class_scope: ## type = Builtin.type_type else: type = py_object_type self.arg_name = EncodedString(self.name) else: if self.templates: if not self.name in self.templates: error(self.pos, "'%s' is not a type identifier" % self.name) type = PyrexTypes.TemplatePlaceholderType(self.name) else: error(self.pos, "'%s' is not a type identifier" % self.name) if self.complex: if not type.is_numeric or type.is_complex: error(self.pos, "can only complexify c numeric types") type = PyrexTypes.CComplexType(type) type.create_declaration_utility_code(env) elif type is Builtin.complex_type: # Special case: optimise builtin complex type into C's # double complex. The parser cannot do this (as for the # normal scalar types) as the user may have redeclared the # 'complex' type. Testing for the exact type here works. type = PyrexTypes.c_double_complex_type type.create_declaration_utility_code(env) self.complex = True if type: return type else: return PyrexTypes.error_type class MemoryViewSliceTypeNode(CBaseTypeNode): name = 'memoryview' child_attrs = ['base_type_node', 'axes'] def analyse(self, env, could_be_name = False): base_type = self.base_type_node.analyse(env) if base_type.is_error: return base_type from . import MemoryView try: axes_specs = MemoryView.get_axes_specs(env, self.axes) except CompileError as e: error(e.position, e.message_only) self.type = PyrexTypes.ErrorType() return self.type if not MemoryView.validate_axes(self.pos, axes_specs): self.type = error_type else: MemoryView.validate_memslice_dtype(self.pos, base_type) self.type = PyrexTypes.MemoryViewSliceType(base_type, axes_specs) self.use_memview_utilities(env) return self.type def use_memview_utilities(self, env): from . import MemoryView env.use_utility_code(MemoryView.view_utility_code) class CNestedBaseTypeNode(CBaseTypeNode): # For C++ classes that live inside other C++ classes. # name string # base_type CBaseTypeNode child_attrs = ['base_type'] def analyse(self, env, could_be_name = None): base_type = self.base_type.analyse(env) if base_type is PyrexTypes.error_type: return PyrexTypes.error_type if not base_type.is_cpp_class: error(self.pos, "'%s' is not a valid type scope" % base_type) return PyrexTypes.error_type type_entry = base_type.scope.lookup_here(self.name) if not type_entry or not type_entry.is_type: error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name)) return PyrexTypes.error_type return type_entry.type class TemplatedTypeNode(CBaseTypeNode): # After parsing: # positional_args [ExprNode] List of positional arguments # keyword_args DictNode Keyword arguments # base_type_node CBaseTypeNode # After analysis: # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options child_attrs = ["base_type_node", "positional_args", "keyword_args", "dtype_node"] dtype_node = None name = None def analyse(self, env, could_be_name = False, base_type = None): if base_type is None: base_type = self.base_type_node.analyse(env) if base_type.is_error: return base_type if base_type.is_cpp_class and base_type.is_template_type(): # Templated class if self.keyword_args and self.keyword_args.key_value_pairs: error(self.pos, "c++ templates cannot take keyword arguments") self.type = PyrexTypes.error_type else: template_types = [] for template_node in self.positional_args: type = template_node.analyse_as_type(env) if type is None: error(template_node.pos, "unknown type in template argument") return error_type template_types.append(type) self.type = base_type.specialize_here(self.pos, template_types) elif base_type.is_pyobject: # Buffer from . import Buffer options = Buffer.analyse_buffer_options( self.pos, env, self.positional_args, self.keyword_args, base_type.buffer_defaults) if sys.version_info[0] < 3: # Py 2.x enforces byte strings as keyword arguments ... options = dict([ (name.encode('ASCII'), value) for name, value in options.items() ]) self.type = PyrexTypes.BufferType(base_type, **options) else: # Array empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None) if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs: error(self.pos, "invalid array declaration") self.type = PyrexTypes.error_type else: # It would be nice to merge this class with CArrayDeclaratorNode, # but arrays are part of the declaration, not the type... if not self.positional_args: dimension = None else: dimension = self.positional_args[0] self.array_declarator = CArrayDeclaratorNode(self.pos, base = empty_declarator, dimension = dimension) self.type = self.array_declarator.analyse(base_type, env)[1] if self.type.is_fused and env.fused_to_specific: self.type = self.type.specialize(env.fused_to_specific) return self.type class CComplexBaseTypeNode(CBaseTypeNode): # base_type CBaseTypeNode # declarator CDeclaratorNode child_attrs = ["base_type", "declarator"] def analyse(self, env, could_be_name = False): base = self.base_type.analyse(env, could_be_name) _, type = self.declarator.analyse(base, env) return type class CTupleBaseTypeNode(CBaseTypeNode): # components [CBaseTypeNode] child_attrs = ["components"] def analyse(self, env, could_be_name=False): component_types = [] for c in self.components: type = c.analyse(env) if type.is_pyobject: error(c.pos, "Tuple types can't (yet) contain Python objects.") return error_type component_types.append(type) entry = env.declare_tuple_type(self.pos, component_types) entry.used = True return entry.type class FusedTypeNode(CBaseTypeNode): """ Represents a fused type in a ctypedef statement: ctypedef cython.fused_type(int, long, long long) integral name str name of this fused type types [CSimpleBaseTypeNode] is the list of types to be fused """ child_attrs = [] def analyse_declarations(self, env): type = self.analyse(env) entry = env.declare_typedef(self.name, type, self.pos) # Omit the typedef declaration that self.declarator would produce entry.in_cinclude = True def analyse(self, env, could_be_name = False): types = [] for type_node in self.types: type = type_node.analyse_as_type(env) if not type: error(type_node.pos, "Not a type") continue if type in types: error(type_node.pos, "Type specified multiple times") else: types.append(type) # if len(self.types) == 1: # return types[0] return PyrexTypes.FusedType(types, name=self.name) class CConstTypeNode(CBaseTypeNode): # base_type CBaseTypeNode child_attrs = ["base_type"] def analyse(self, env, could_be_name = False): base = self.base_type.analyse(env, could_be_name) if base.is_pyobject: error(self.pos, "Const base type cannot be a Python object") return PyrexTypes.c_const_type(base) class CVarDefNode(StatNode): # C variable definition or forward/extern function declaration. # # visibility 'private' or 'public' or 'extern' # base_type CBaseTypeNode # declarators [CDeclaratorNode] # in_pxd boolean # api boolean # overridable boolean whether it is a cpdef # modifiers ['inline'] # decorators [cython.locals(...)] or None # directive_locals { string : NameNode } locals defined by cython.locals(...) child_attrs = ["base_type", "declarators"] decorators = None directive_locals = None def analyse_declarations(self, env, dest_scope = None): if self.directive_locals is None: self.directive_locals = {} if not dest_scope: dest_scope = env self.dest_scope = dest_scope if self.declarators: templates = self.declarators[0].analyse_templates() else: templates = None if templates is not None: if self.visibility != 'extern': error(self.pos, "Only extern functions allowed") if len(self.declarators) > 1: error(self.declarators[1].pos, "Can't multiply declare template types") env = TemplateScope('func_template', env) env.directives = env.outer_scope.directives for template_param in templates: env.declare_type(template_param.name, template_param, self.pos) base_type = self.base_type.analyse(env) if base_type.is_fused and not self.in_pxd and (env.is_c_class_scope or env.is_module_scope): error(self.pos, "Fused types not allowed here") return error_type self.entry = None visibility = self.visibility for declarator in self.declarators: if (len(self.declarators) > 1 and not isinstance(declarator, CNameDeclaratorNode) and env.directives['warn.multiple_declarators']): warning(declarator.pos, "Non-trivial type declarators in shared declaration (e.g. mix of pointers and values). " + "Each pointer declaration should be on its own line.", 1) create_extern_wrapper = (self.overridable and self.visibility == 'extern' and env.is_module_scope) if create_extern_wrapper: declarator.overridable = False if isinstance(declarator, CFuncDeclaratorNode): name_declarator, type = declarator.analyse(base_type, env, directive_locals=self.directive_locals) else: name_declarator, type = declarator.analyse(base_type, env) if not type.is_complete(): if not (self.visibility == 'extern' and type.is_array or type.is_memoryviewslice): error(declarator.pos, "Variable type '%s' is incomplete" % type) if self.visibility == 'extern' and type.is_pyobject: error(declarator.pos, "Python object cannot be declared extern") name = name_declarator.name cname = name_declarator.cname if name == '': error(declarator.pos, "Missing name in declaration.") return if type.is_cfunction: if 'staticmethod' in env.directives: type.is_static_method = True self.entry = dest_scope.declare_cfunction(name, type, declarator.pos, cname=cname, visibility=self.visibility, in_pxd=self.in_pxd, api=self.api, modifiers=self.modifiers, overridable=self.overridable) if self.entry is not None: self.entry.directive_locals = copy.copy(self.directive_locals) if create_extern_wrapper: self.entry.type.create_to_py_utility_code(env) self.entry.create_wrapper = True else: if self.directive_locals: error(self.pos, "Decorators can only be followed by functions") self.entry = dest_scope.declare_var(name, type, declarator.pos, cname=cname, visibility=visibility, in_pxd=self.in_pxd, api=self.api, is_cdef=1) if Options.docstrings: self.entry.doc = embed_position(self.pos, self.doc) class CStructOrUnionDefNode(StatNode): # name string # cname string or None # kind "struct" or "union" # typedef_flag boolean # visibility "public" or "private" # api boolean # in_pxd boolean # attributes [CVarDefNode] or None # entry Entry # packed boolean child_attrs = ["attributes"] def declare(self, env, scope=None): self.entry = env.declare_struct_or_union( self.name, self.kind, scope, self.typedef_flag, self.pos, self.cname, visibility = self.visibility, api = self.api, packed = self.packed) def analyse_declarations(self, env): scope = None if self.attributes is not None: scope = StructOrUnionScope(self.name) self.declare(env, scope) if self.attributes is not None: if self.in_pxd and not env.in_cinclude: self.entry.defined_in_pxd = 1 for attr in self.attributes: attr.analyse_declarations(env, scope) if self.visibility != 'extern': for attr in scope.var_entries: type = attr.type while type.is_array: type = type.base_type if type == self.entry.type: error(attr.pos, "Struct cannot contain itself as a member.") def analyse_expressions(self, env): return self def generate_execution_code(self, code): pass class CppClassNode(CStructOrUnionDefNode, BlockNode): # name string # cname string or None # visibility "extern" # in_pxd boolean # attributes [CVarDefNode] or None # entry Entry # base_classes [CBaseTypeNode] # templates [string] or None # decorators [DecoratorNode] or None decorators = None def declare(self, env): if self.templates is None: template_types = None else: template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates] self.entry = env.declare_cpp_class( self.name, None, self.pos, self.cname, base_classes = [], visibility = self.visibility, templates = template_types) def analyse_declarations(self, env): scope = None if self.attributes is not None: scope = CppClassScope(self.name, env, templates = self.templates) def base_ok(base_class): if base_class.is_cpp_class or base_class.is_struct: return True else: error(self.pos, "Base class '%s' not a struct or class." % base_class) base_class_types = filter(base_ok, [b.analyse(scope or env) for b in self.base_classes]) if self.templates is None: template_types = None else: template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates] self.entry = env.declare_cpp_class( self.name, scope, self.pos, self.cname, base_class_types, visibility = self.visibility, templates = template_types) if self.entry is None: return self.entry.is_cpp_class = 1 if scope is not None: scope.type = self.entry.type defined_funcs = [] def func_attributes(attributes): for attr in attributes: if isinstance(attr, CFuncDefNode): yield attr elif isinstance(attr, CompilerDirectivesNode): for sub_attr in func_attributes(attr.body.stats): yield sub_attr if self.attributes is not None: if self.in_pxd and not env.in_cinclude: self.entry.defined_in_pxd = 1 for attr in self.attributes: attr.analyse_declarations(scope) for func in func_attributes(self.attributes): defined_funcs.append(func) if self.templates is not None: func.template_declaration = "template " % ", typename ".join(self.templates) self.body = StatListNode(self.pos, stats=defined_funcs) self.scope = scope def analyse_expressions(self, env): self.body = self.body.analyse_expressions(self.entry.type.scope) return self def generate_function_definitions(self, env, code): self.body.generate_function_definitions(self.entry.type.scope, code) def generate_execution_code(self, code): self.body.generate_execution_code(code) def annotate(self, code): self.body.annotate(code) class CEnumDefNode(StatNode): # name string or None # cname string or None # items [CEnumDefItemNode] # typedef_flag boolean # visibility "public" or "private" or "extern" # api boolean # in_pxd boolean # create_wrapper boolean # entry Entry child_attrs = ["items"] def declare(self, env): self.entry = env.declare_enum(self.name, self.pos, cname = self.cname, typedef_flag = self.typedef_flag, visibility = self.visibility, api = self.api, create_wrapper = self.create_wrapper) def analyse_declarations(self, env): if self.items is not None: if self.in_pxd and not env.in_cinclude: self.entry.defined_in_pxd = 1 for item in self.items: item.analyse_declarations(env, self.entry) def analyse_expressions(self, env): return self def generate_execution_code(self, code): if self.visibility == 'public' or self.api: code.mark_pos(self.pos) temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True) for item in self.entry.enum_values: code.putln("%s = PyInt_FromLong(%s); %s" % ( temp, item.cname, code.error_goto_if_null(temp, item.pos))) code.put_gotref(temp) code.putln('if (PyDict_SetItemString(%s, "%s", %s) < 0) %s' % ( Naming.moddict_cname, item.name, temp, code.error_goto(item.pos))) code.put_decref_clear(temp, PyrexTypes.py_object_type) code.funcstate.release_temp(temp) class CEnumDefItemNode(StatNode): # name string # cname string or None # value ExprNode or None child_attrs = ["value"] def analyse_declarations(self, env, enum_entry): if self.value: self.value = self.value.analyse_const_expression(env) if not self.value.type.is_int: self.value = self.value.coerce_to(PyrexTypes.c_int_type, env) self.value = self.value.analyse_const_expression(env) entry = env.declare_const(self.name, enum_entry.type, self.value, self.pos, cname = self.cname, visibility = enum_entry.visibility, api = enum_entry.api, create_wrapper = enum_entry.create_wrapper) enum_entry.enum_values.append(entry) if enum_entry.name: enum_entry.type.values.append(entry.cname) class CTypeDefNode(StatNode): # base_type CBaseTypeNode # declarator CDeclaratorNode # visibility "public" or "private" # api boolean # in_pxd boolean child_attrs = ["base_type", "declarator"] def analyse_declarations(self, env): base = self.base_type.analyse(env) name_declarator, type = self.declarator.analyse(base, env) name = name_declarator.name cname = name_declarator.cname entry = env.declare_typedef(name, type, self.pos, cname = cname, visibility = self.visibility, api = self.api) if type.is_fused: entry.in_cinclude = True if self.in_pxd and not env.in_cinclude: entry.defined_in_pxd = 1 def analyse_expressions(self, env): return self def generate_execution_code(self, code): pass class FuncDefNode(StatNode, BlockNode): # Base class for function definition nodes. # # return_type PyrexType # #filename string C name of filename string const # entry Symtab.Entry # needs_closure boolean Whether or not this function has inner functions/classes/yield # needs_outer_scope boolean Whether or not this function requires outer scope # pymethdef_required boolean Force Python method struct generation # directive_locals { string : ExprNode } locals defined by cython.locals(...) # directive_returns [ExprNode] type defined by cython.returns(...) # star_arg PyArgDeclNode or None * argument # starstar_arg PyArgDeclNode or None ** argument # # is_async_def boolean is a Coroutine function # # has_fused_arguments boolean # Whether this cdef function has fused parameters. This is needed # by AnalyseDeclarationsTransform, so it can replace CFuncDefNodes # with fused argument types with a FusedCFuncDefNode py_func = None needs_closure = False needs_outer_scope = False pymethdef_required = False is_generator = False is_generator_body = False is_async_def = False modifiers = [] has_fused_arguments = False star_arg = None starstar_arg = None is_cyfunction = False code_object = None def analyse_default_values(self, env): default_seen = 0 for arg in self.args: if arg.default: default_seen = 1 if arg.is_generic: arg.default = arg.default.analyse_types(env) arg.default = arg.default.coerce_to(arg.type, env) else: error(arg.pos, "This argument cannot have a default value") arg.default = None elif arg.kw_only: default_seen = 1 elif default_seen: error(arg.pos, "Non-default argument following default argument") def analyse_annotations(self, env): for arg in self.args: if arg.annotation: arg.annotation = arg.annotation.analyse_types(env) def align_argument_type(self, env, arg): # @cython.locals() directive_locals = self.directive_locals orig_type = arg.type if arg.name in directive_locals: type_node = directive_locals[arg.name] other_type = type_node.analyse_as_type(env) elif isinstance(arg, CArgDeclNode) and arg.annotation and env.directives['annotation_typing']: type_node = arg.annotation other_type = arg.inject_type_from_annotations(env) if other_type is None: return arg else: return arg if other_type is None: error(type_node.pos, "Not a type") elif (orig_type is not PyrexTypes.py_object_type and not orig_type.same_as(other_type)): error(arg.base_type.pos, "Signature does not agree with previous declaration") error(type_node.pos, "Previous declaration here") else: arg.type = other_type return arg def need_gil_acquisition(self, lenv): return 0 def create_local_scope(self, env): genv = env while genv.is_py_class_scope or genv.is_c_class_scope: genv = genv.outer_scope if self.needs_closure: lenv = ClosureScope(name=self.entry.name, outer_scope = genv, parent_scope = env, scope_name=self.entry.cname) else: lenv = LocalScope(name=self.entry.name, outer_scope=genv, parent_scope=env) lenv.return_type = self.return_type type = self.entry.type if type.is_cfunction: lenv.nogil = type.nogil and not type.with_gil self.local_scope = lenv lenv.directives = env.directives return lenv def generate_function_body(self, env, code): self.body.generate_execution_code(code) def generate_function_definitions(self, env, code): from . import Buffer if self.return_type.is_memoryviewslice: from . import MemoryView lenv = self.local_scope if lenv.is_closure_scope and not lenv.is_passthrough: outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname, Naming.outer_scope_cname) else: outer_scope_cname = Naming.outer_scope_cname lenv.mangle_closure_cnames(outer_scope_cname) # Generate closure function definitions self.body.generate_function_definitions(lenv, code) # generate lambda function definitions self.generate_lambda_definitions(lenv, code) is_getbuffer_slot = (self.entry.name == "__getbuffer__" and self.entry.scope.is_c_class_scope) is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and self.entry.scope.is_c_class_scope) is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot if is_buffer_slot: if 'cython_unused' not in self.modifiers: self.modifiers = self.modifiers + ['cython_unused'] preprocessor_guard = self.get_preprocessor_guard() profile = code.globalstate.directives['profile'] linetrace = code.globalstate.directives['linetrace'] if profile or linetrace: code.globalstate.use_utility_code( UtilityCode.load_cached("Profile", "Profile.c")) # Generate C code for header and body of function code.enter_cfunc_scope() code.return_from_error_cleanup_label = code.new_label() code.funcstate.gil_owned = not lenv.nogil # ----- Top-level constants used by this function code.mark_pos(self.pos) self.generate_cached_builtins_decls(lenv, code) # ----- Function header code.putln("") if preprocessor_guard: code.putln(preprocessor_guard) with_pymethdef = (self.needs_assignment_synthesis(env, code) or self.pymethdef_required) if self.py_func: self.py_func.generate_function_header(code, with_pymethdef = with_pymethdef, proto_only=True) self.generate_function_header(code, with_pymethdef = with_pymethdef) # ----- Local variable declarations # Find function scope cenv = env while cenv.is_py_class_scope or cenv.is_c_class_scope: cenv = cenv.outer_scope if self.needs_closure: code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname)) code.putln(";") elif self.needs_outer_scope: if lenv.is_passthrough: code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname)) code.putln(";") code.put(cenv.scope_class.type.declaration_code(Naming.outer_scope_cname)) code.putln(";") self.generate_argument_declarations(lenv, code) for entry in lenv.var_entries: if not (entry.in_closure or entry.is_arg): code.put_var_declaration(entry) # Initialize the return variable __pyx_r init = "" if not self.return_type.is_void: if self.return_type.is_pyobject: init = " = NULL" elif self.return_type.is_memoryviewslice: init = ' = ' + MemoryView.memslice_entry_init code.putln( "%s%s;" % (self.return_type.declaration_code(Naming.retval_cname), init)) tempvardecl_code = code.insertion_point() self.generate_keyword_list(code) # ----- Extern library function declarations lenv.generate_library_function_declarations(code) # ----- GIL acquisition acquire_gil = self.acquire_gil # See if we need to acquire the GIL for variable declarations, or for # refnanny only # Closures are not currently possible for cdef nogil functions, # but check them anyway have_object_args = self.needs_closure or self.needs_outer_scope for arg in lenv.arg_entries: if arg.type.is_pyobject: have_object_args = True break acquire_gil_for_var_decls_only = ( lenv.nogil and lenv.has_with_gil_block and (have_object_args or lenv.buffer_entries)) acquire_gil_for_refnanny_only = ( lenv.nogil and lenv.has_with_gil_block and not acquire_gil_for_var_decls_only) use_refnanny = not lenv.nogil or lenv.has_with_gil_block if acquire_gil or acquire_gil_for_var_decls_only: code.put_ensure_gil() code.funcstate.gil_owned = True elif lenv.nogil and lenv.has_with_gil_block: code.declare_gilstate() if profile or linetrace: tempvardecl_code.put_trace_declarations() code_object = self.code_object.calculate_result_code(code) if self.code_object else None code.put_trace_frame_init(code_object) # ----- set up refnanny if use_refnanny: tempvardecl_code.put_declare_refcount_context() code.put_setup_refcount_context( self.entry.name, acquire_gil=acquire_gil_for_refnanny_only) # ----- Automatic lead-ins for certain special functions if is_getbuffer_slot: self.getbuffer_init(code) # ----- Create closure scope object if self.needs_closure: tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__') slot_func_cname = TypeSlots.get_slot_function(lenv.scope_class.type.scope, tp_slot) if not slot_func_cname: slot_func_cname = '%s->tp_new' % lenv.scope_class.type.typeptr_cname code.putln("%s = (%s)%s(%s, %s, NULL);" % ( Naming.cur_scope_cname, lenv.scope_class.type.empty_declaration_code(), slot_func_cname, lenv.scope_class.type.typeptr_cname, Naming.empty_tuple)) code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname) if is_getbuffer_slot: self.getbuffer_error_cleanup(code) if use_refnanny: code.put_finish_refcount_context() if acquire_gil or acquire_gil_for_var_decls_only: code.put_release_ensured_gil() # FIXME: what if the error return value is a Python value? err_val = self.error_value() if err_val is None: if not self.caller_will_check_exceptions(): warning(self.entry.pos, "Unraisable exception in function '%s'." % self.entry.qualified_name, 0) code.put_unraisable(self.entry.qualified_name, lenv.nogil) #if self.return_type.is_void: code.putln("return;") else: code.putln("return %s;" % err_val) code.putln("}") code.put_gotref(Naming.cur_scope_cname) # Note that it is unsafe to decref the scope at this point. if self.needs_outer_scope: if self.is_cyfunction: code.putln("%s = (%s) __Pyx_CyFunction_GetClosure(%s);" % ( outer_scope_cname, cenv.scope_class.type.empty_declaration_code(), Naming.self_cname)) else: code.putln("%s = (%s) %s;" % ( outer_scope_cname, cenv.scope_class.type.empty_declaration_code(), Naming.self_cname)) if lenv.is_passthrough: code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname)) elif self.needs_closure: # inner closures own a reference to their outer parent code.put_incref(outer_scope_cname, cenv.scope_class.type) code.put_giveref(outer_scope_cname) # ----- Trace function call if profile or linetrace: # this looks a bit late, but if we don't get here due to a # fatal error before hand, it's not really worth tracing code.put_trace_call(self.entry.name, self.pos, nogil=not code.funcstate.gil_owned) code.funcstate.can_trace = True # ----- Fetch arguments self.generate_argument_parsing_code(env, code) # If an argument is assigned to in the body, we must # incref it to properly keep track of refcounts. is_cdef = isinstance(self, CFuncDefNode) for entry in lenv.arg_entries: if entry.type.is_pyobject: if (acquire_gil or len(entry.cf_assignments) > 1) and not entry.in_closure: code.put_var_incref(entry) # Note: defaults are always incref-ed. For def functions, we # we aquire arguments from object converstion, so we have # new references. If we are a cdef function, we need to # incref our arguments elif is_cdef and entry.type.is_memoryviewslice and len(entry.cf_assignments) > 1: code.put_incref_memoryviewslice(entry.cname, have_gil=code.funcstate.gil_owned) for entry in lenv.var_entries: if entry.is_arg and len(entry.cf_assignments) > 1: if entry.xdecref_cleanup: code.put_var_xincref(entry) else: code.put_var_incref(entry) # ----- Initialise local buffer auxiliary variables for entry in lenv.var_entries + lenv.arg_entries: if entry.type.is_buffer and entry.buffer_aux.buflocal_nd_var.used: Buffer.put_init_vars(entry, code) # ----- Check and convert arguments self.generate_argument_type_tests(code) # ----- Acquire buffer arguments for entry in lenv.arg_entries: if entry.type.is_buffer: Buffer.put_acquire_arg_buffer(entry, code, self.pos) if acquire_gil_for_var_decls_only: code.put_release_ensured_gil() code.funcstate.gil_owned = False # ------------------------- # ----- Function body ----- # ------------------------- self.generate_function_body(env, code) code.mark_pos(self.pos, trace=False) code.putln("") code.putln("/* function exit code */") # ----- Default return value if not self.body.is_terminator: if self.return_type.is_pyobject: #if self.return_type.is_extension_type: # lhs = "(PyObject *)%s" % Naming.retval_cname #else: lhs = Naming.retval_cname code.put_init_to_py_none(lhs, self.return_type) else: val = self.return_type.default_value if val: code.putln("%s = %s;" % (Naming.retval_cname, val)) # ----- Error cleanup if code.error_label in code.labels_used: if not self.body.is_terminator: code.put_goto(code.return_label) code.put_label(code.error_label) for cname, type in code.funcstate.all_managed_temps(): code.put_xdecref(cname, type, have_gil=not lenv.nogil) # Clean up buffers -- this calls a Python function # so need to save and restore error state buffers_present = len(lenv.buffer_entries) > 0 #memslice_entries = [e for e in lenv.entries.values() if e.type.is_memoryviewslice] if buffers_present: code.globalstate.use_utility_code(restore_exception_utility_code) code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;") code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);") for entry in lenv.buffer_entries: if entry.used: Buffer.put_release_buffer_code(code, entry) #code.putln("%s = 0;" % entry.cname) code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}") if self.return_type.is_memoryviewslice: MemoryView.put_init_entry(Naming.retval_cname, code) err_val = Naming.retval_cname else: err_val = self.error_value() exc_check = self.caller_will_check_exceptions() if err_val is not None or exc_check: # TODO: Fix exception tracing (though currently unused by cProfile). # code.globalstate.use_utility_code(get_exception_tuple_utility_code) # code.put_trace_exception() if lenv.nogil and not lenv.has_with_gil_block: code.putln("{") code.put_ensure_gil() code.put_add_traceback(self.entry.qualified_name) if lenv.nogil and not lenv.has_with_gil_block: code.put_release_ensured_gil() code.putln("}") else: warning(self.entry.pos, "Unraisable exception in function '%s'." % self.entry.qualified_name, 0) code.put_unraisable(self.entry.qualified_name, lenv.nogil) default_retval = self.return_type.default_value if err_val is None and default_retval: err_val = default_retval if err_val is not None: code.putln("%s = %s;" % (Naming.retval_cname, err_val)) if is_getbuffer_slot: self.getbuffer_error_cleanup(code) # If we are using the non-error cleanup section we should # jump past it if we have an error. The if-test below determine # whether this section is used. if buffers_present or is_getbuffer_slot or self.return_type.is_memoryviewslice: code.put_goto(code.return_from_error_cleanup_label) # ----- Non-error return cleanup code.put_label(code.return_label) for entry in lenv.buffer_entries: if entry.used: Buffer.put_release_buffer_code(code, entry) if is_getbuffer_slot: self.getbuffer_normal_cleanup(code) if self.return_type.is_memoryviewslice: # See if our return value is uninitialized on non-error return # from . import MemoryView # MemoryView.err_if_nogil_initialized_check(self.pos, env) cond = code.unlikely(self.return_type.error_condition( Naming.retval_cname)) code.putln( 'if (%s) {' % cond) if env.nogil: code.put_ensure_gil() code.putln( 'PyErr_SetString(' 'PyExc_TypeError,' '"Memoryview return value is not initialized");') if env.nogil: code.put_release_ensured_gil() code.putln( '}') # ----- Return cleanup for both error and no-error return code.put_label(code.return_from_error_cleanup_label) for entry in lenv.var_entries: if not entry.used or entry.in_closure: continue if entry.type.is_memoryviewslice: code.put_xdecref_memoryviewslice(entry.cname, have_gil=not lenv.nogil) elif entry.type.is_pyobject: if not entry.is_arg or len(entry.cf_assignments) > 1: if entry.xdecref_cleanup: code.put_var_xdecref(entry) else: code.put_var_decref(entry) # Decref any increfed args for entry in lenv.arg_entries: if entry.type.is_pyobject: if ((acquire_gil or len(entry.cf_assignments) > 1) and not entry.in_closure): code.put_var_decref(entry) elif (entry.type.is_memoryviewslice and (not is_cdef or len(entry.cf_assignments) > 1)): # decref slices of def functions and acquired slices from cdef # functions, but not borrowed slices from cdef functions. code.put_xdecref_memoryviewslice(entry.cname, have_gil=not lenv.nogil) if self.needs_closure: code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type) # ----- Return # This code is duplicated in ModuleNode.generate_module_init_func if not lenv.nogil: default_retval = self.return_type.default_value err_val = self.error_value() if err_val is None and default_retval: err_val = default_retval # FIXME: why is err_val not used? if self.return_type.is_pyobject: code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname)) if self.entry.is_special and self.entry.name == "__hash__": # Returning -1 for __hash__ is supposed to signal an error # We do as Python instances and coerce -1 into -2. code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % ( Naming.retval_cname, Naming.retval_cname)) if profile or linetrace: code.funcstate.can_trace = False if self.return_type.is_pyobject: code.put_trace_return(Naming.retval_cname, nogil=not code.funcstate.gil_owned) else: code.put_trace_return("Py_None", nogil=not code.funcstate.gil_owned) if not lenv.nogil: # GIL holding function code.put_finish_refcount_context() if acquire_gil or (lenv.nogil and lenv.has_with_gil_block): # release the GIL (note that with-gil blocks acquire it on exit in their EnsureGILNode) code.put_release_ensured_gil() code.funcstate.gil_owned = False if not self.return_type.is_void: code.putln("return %s;" % Naming.retval_cname) code.putln("}") if preprocessor_guard: code.putln("#endif /*!(%s)*/" % preprocessor_guard) # ----- Go back and insert temp variable declarations tempvardecl_code.put_temp_declarations(code.funcstate) # ----- Python version code.exit_cfunc_scope() if self.py_func: self.py_func.generate_function_definitions(env, code) self.generate_wrapper_functions(code) def declare_argument(self, env, arg): if arg.type.is_void: error(arg.pos, "Invalid use of 'void'") elif not arg.type.is_complete() and not (arg.type.is_array or arg.type.is_memoryviewslice): error(arg.pos, "Argument type '%s' is incomplete" % arg.type) return env.declare_arg(arg.name, arg.type, arg.pos) def generate_arg_type_test(self, arg, code): # Generate type test for one argument. if arg.type.typeobj_is_available(): code.globalstate.use_utility_code( UtilityCode.load_cached("ArgTypeTest", "FunctionArguments.c")) typeptr_cname = arg.type.typeptr_cname arg_code = "((PyObject *)%s)" % arg.entry.cname code.putln( 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % ( arg_code, typeptr_cname, arg.accept_none, arg.name, arg.type.is_builtin_type, code.error_goto(arg.pos))) else: error(arg.pos, "Cannot test type of extern C class " "without type object name specification") def generate_arg_none_check(self, arg, code): # Generate None check for one argument. if arg.type.is_memoryviewslice: cname = "%s.memview" % arg.entry.cname else: cname = arg.entry.cname code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % cname) code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%%.%ds' must not be None", "%s"); %s''' % ( max(200, len(arg.name)), arg.name, code.error_goto(arg.pos))) code.putln('}') def generate_wrapper_functions(self, code): pass def generate_execution_code(self, code): code.mark_pos(self.pos) # Evaluate and store argument default values for arg in self.args: if not arg.is_dynamic: arg.generate_assignment_code(code) # # Special code for the __getbuffer__ function # def getbuffer_init(self, code): info = self.local_scope.arg_entries[1].cname # Python 3.0 betas have a bug in memoryview which makes it call # getbuffer with a NULL parameter. For now we work around this; # the following block should be removed when this bug is fixed. code.putln("if (%s != NULL) {" % info) code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info) code.put_giveref("%s->obj" % info) # Do not refnanny object within structs code.putln("}") def getbuffer_error_cleanup(self, code): info = self.local_scope.arg_entries[1].cname code.putln("if (%s != NULL && %s->obj != NULL) {" % (info, info)) code.put_gotref("%s->obj" % info) code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" % (info, info)) code.putln("}") def getbuffer_normal_cleanup(self, code): info = self.local_scope.arg_entries[1].cname code.putln("if (%s != NULL && %s->obj == Py_None) {" % (info, info)) code.put_gotref("Py_None") code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info) code.putln("}") def get_preprocessor_guard(self): if not self.entry.is_special: return None name = self.entry.name slot = TypeSlots.method_name_to_slot.get(name) if not slot: return None if name == '__long__' and not self.entry.scope.lookup_here('__int__'): return None if name in ("__getbuffer__", "__releasebuffer__") and self.entry.scope.is_c_class_scope: return None return slot.preprocessor_guard_code() class CFuncDefNode(FuncDefNode): # C function definition. # # modifiers ['inline'] # visibility 'private' or 'public' or 'extern' # base_type CBaseTypeNode # declarator CDeclaratorNode # cfunc_declarator the CFuncDeclarator of this function # (this is also available through declarator or a # base thereof) # body StatListNode # api boolean # decorators [DecoratorNode] list of decorators # # with_gil boolean Acquire GIL around body # type CFuncType # py_func wrapper for calling from Python # overridable whether or not this is a cpdef function # inline_in_pxd whether this is an inline function in a pxd file # template_declaration String or None Used for c++ class methods # is_const_method whether this is a const method # is_static_method whether this is a static method # is_c_class_method whether this is a cclass method child_attrs = ["base_type", "declarator", "body", "py_func_stat"] inline_in_pxd = False decorators = None directive_locals = None directive_returns = None override = None template_declaration = None is_const_method = False py_func_stat = None def unqualified_name(self): return self.entry.name def analyse_declarations(self, env): self.is_c_class_method = env.is_c_class_scope if self.directive_locals is None: self.directive_locals = {} self.directive_locals.update(env.directives['locals']) if self.directive_returns is not None: base_type = self.directive_returns.analyse_as_type(env) if base_type is None: error(self.directive_returns.pos, "Not a type") base_type = PyrexTypes.error_type else: base_type = self.base_type.analyse(env) self.is_static_method = 'staticmethod' in env.directives and not env.lookup_here('staticmethod') # The 2 here is because we need both function and argument names. if isinstance(self.declarator, CFuncDeclaratorNode): name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None), directive_locals = self.directive_locals) else: name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None)) if not type.is_cfunction: error(self.pos, "Suite attached to non-function declaration") # Remember the actual type according to the function header # written here, because the type in the symbol table entry # may be different if we're overriding a C method inherited # from the base type of an extension type. self.type = type type.is_overridable = self.overridable declarator = self.declarator while not hasattr(declarator, 'args'): declarator = declarator.base self.cfunc_declarator = declarator self.args = declarator.args opt_arg_count = self.cfunc_declarator.optional_arg_count if (self.visibility == 'public' or self.api) and opt_arg_count: error(self.cfunc_declarator.pos, "Function with optional arguments may not be declared " "public or api") if (type.exception_check == '+' and self.visibility != 'extern'): warning(self.cfunc_declarator.pos, "Only extern functions can throw C++ exceptions.") for formal_arg, type_arg in zip(self.args, type.args): self.align_argument_type(env, type_arg) formal_arg.type = type_arg.type formal_arg.name = type_arg.name formal_arg.cname = type_arg.cname self._validate_type_visibility(type_arg.type, type_arg.pos, env) if type_arg.type.is_fused: self.has_fused_arguments = True if type_arg.type.is_buffer and 'inline' in self.modifiers: warning(formal_arg.pos, "Buffer unpacking not optimized away.", 1) if type_arg.type.is_buffer: if self.type.nogil: error(formal_arg.pos, "Buffer may not be acquired without the GIL. " "Consider using memoryview slices instead.") elif 'inline' in self.modifiers: warning(formal_arg.pos, "Buffer unpacking not optimized away.", 1) self._validate_type_visibility(type.return_type, self.pos, env) name = name_declarator.name cname = name_declarator.cname type.is_const_method = self.is_const_method type.is_static_method = self.is_static_method self.entry = env.declare_cfunction( name, type, self.pos, cname=cname, visibility=self.visibility, api=self.api, defining=self.body is not None, modifiers=self.modifiers, overridable=self.overridable) self.entry.inline_func_in_pxd = self.inline_in_pxd self.return_type = type.return_type if self.return_type.is_array and self.visibility != 'extern': error(self.pos, "Function cannot return an array") if self.return_type.is_cpp_class: self.return_type.check_nullary_constructor(self.pos, "used as a return value") if self.overridable and not env.is_module_scope and not self.is_static_method: if len(self.args) < 1 or not self.args[0].type.is_pyobject: # An error will be produced in the cdef function self.overridable = False self.declare_cpdef_wrapper(env) self.create_local_scope(env) def declare_cpdef_wrapper(self, env): if self.overridable: if self.is_static_method: # TODO(robertwb): Finish this up, perhaps via more function refactoring. error(self.pos, "static cpdef methods not yet supported") name = self.entry.name py_func_body = self.call_self_node(is_module_scope = env.is_module_scope) if self.is_static_method: from .ExprNodes import NameNode decorators = [DecoratorNode(self.pos, decorator=NameNode(self.pos, name='staticmethod'))] decorators[0].decorator.analyse_types(env) else: decorators = [] self.py_func = DefNode(pos = self.pos, name = self.entry.name, args = self.args, star_arg = None, starstar_arg = None, doc = self.doc, body = py_func_body, decorators = decorators, is_wrapper = 1) self.py_func.is_module_scope = env.is_module_scope self.py_func.analyse_declarations(env) self.py_func_stat = StatListNode(pos = self.pos, stats = [self.py_func]) self.py_func.type = PyrexTypes.py_object_type self.entry.as_variable = self.py_func.entry self.entry.used = self.entry.as_variable.used = True # Reset scope entry the above cfunction env.entries[name] = self.entry if (not self.entry.is_final_cmethod and (not env.is_module_scope or Options.lookup_module_cpdef)): self.override = OverrideCheckNode(self.pos, py_func = self.py_func) self.body = StatListNode(self.pos, stats=[self.override, self.body]) def _validate_type_visibility(self, type, pos, env): """ Ensure that types used in cdef functions are public or api, or defined in a C header. """ public_or_api = (self.visibility == 'public' or self.api) entry = getattr(type, 'entry', None) if public_or_api and entry and env.is_module_scope: if not (entry.visibility in ('public', 'extern') or entry.api or entry.in_cinclude): error(pos, "Function declared public or api may not have " "private types") def call_self_node(self, omit_optional_args=0, is_module_scope=0): from . import ExprNodes args = self.type.args if omit_optional_args: args = args[:len(args) - self.type.optional_arg_count] arg_names = [arg.name for arg in args] if is_module_scope: cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name) call_arg_names = arg_names skip_dispatch = Options.lookup_module_cpdef elif self.type.is_static_method: class_entry = self.entry.scope.parent_type.entry class_node = ExprNodes.NameNode(self.pos, name=class_entry.name) class_node.entry = class_entry cfunc = ExprNodes.AttributeNode(self.pos, obj=class_node, attribute=self.entry.name) # Calling static c(p)def methods on an instance disallowed. # TODO(robertwb): Support by passing self to check for override? skip_dispatch = True else: type_entry = self.type.args[0].type.entry type_arg = ExprNodes.NameNode(self.pos, name=type_entry.name) type_arg.entry = type_entry cfunc = ExprNodes.AttributeNode(self.pos, obj=type_arg, attribute=self.entry.name) skip_dispatch = not is_module_scope or Options.lookup_module_cpdef c_call = ExprNodes.SimpleCallNode( self.pos, function=cfunc, args=[ExprNodes.NameNode(self.pos, name=n) for n in arg_names], wrapper_call=skip_dispatch) return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call) def declare_arguments(self, env): for arg in self.type.args: if not arg.name: error(arg.pos, "Missing argument name") self.declare_argument(env, arg) def need_gil_acquisition(self, lenv): return self.type.with_gil def nogil_check(self, env): type = self.type with_gil = type.with_gil if type.nogil and not with_gil: if type.return_type.is_pyobject: error(self.pos, "Function with Python return type cannot be declared nogil") for entry in self.local_scope.var_entries: if entry.type.is_pyobject and not entry.in_with_gil_block: error(self.pos, "Function declared nogil has Python locals or temporaries") def analyse_expressions(self, env): self.local_scope.directives = env.directives if self.py_func is not None: # this will also analyse the default values self.py_func = self.py_func.analyse_expressions(env) else: self.analyse_default_values(env) self.analyse_annotations(env) self.acquire_gil = self.need_gil_acquisition(self.local_scope) return self def needs_assignment_synthesis(self, env, code=None): return False def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None): scope = self.local_scope arg_decls = [] type = self.type for arg in type.args[:len(type.args)-type.optional_arg_count]: arg_decl = arg.declaration_code() entry = scope.lookup(arg.name) if not entry.cf_used: arg_decl = 'CYTHON_UNUSED %s' % arg_decl arg_decls.append(arg_decl) if with_dispatch and self.overridable: dispatch_arg = PyrexTypes.c_int_type.declaration_code( Naming.skip_dispatch_cname) if self.override: arg_decls.append(dispatch_arg) else: arg_decls.append('CYTHON_UNUSED %s' % dispatch_arg) if type.optional_arg_count and with_opt_args: arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname)) if type.has_varargs: arg_decls.append("...") if not arg_decls: arg_decls = ["void"] if cname is None: cname = self.entry.func_cname entity = type.function_header_code(cname, ', '.join(arg_decls)) if self.entry.visibility == 'private' and '::' not in cname: storage_class = "static " else: storage_class = "" dll_linkage = None modifiers = code.build_function_modifiers(self.entry.func_modifiers) header = self.return_type.declaration_code(entity, dll_linkage=dll_linkage) #print (storage_class, modifiers, header) needs_proto = self.is_c_class_method if self.template_declaration: if needs_proto: code.globalstate.parts['module_declarations'].putln(self.template_declaration) code.putln(self.template_declaration) if needs_proto: code.globalstate.parts['module_declarations'].putln("%s%s%s; /* proto*/" % (storage_class, modifiers, header)) code.putln("%s%s%s {" % (storage_class, modifiers, header)) def generate_argument_declarations(self, env, code): scope = self.local_scope for arg in self.args: if arg.default: entry = scope.lookup(arg.name) if self.override or entry.cf_used: result = arg.calculate_default_value_code(code) code.putln('%s = %s;' % ( arg.type.declaration_code(arg.cname), result)) def generate_keyword_list(self, code): pass def generate_argument_parsing_code(self, env, code): i = 0 used = 0 scope = self.local_scope if self.type.optional_arg_count: code.putln('if (%s) {' % Naming.optional_args_cname) for arg in self.args: if arg.default: entry = scope.lookup(arg.name) if self.override or entry.cf_used: code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i)) declarator = arg.declarator while not hasattr(declarator, 'name'): declarator = declarator.base code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name))) used += 1 i += 1 for _ in range(used): code.putln('}') code.putln('}') # Move arguments into closure if required def put_into_closure(entry): if entry.in_closure and not arg.default: code.putln('%s = %s;' % (entry.cname, entry.original_cname)) code.put_var_incref(entry) code.put_var_giveref(entry) for arg in self.args: put_into_closure(scope.lookup_here(arg.name)) def generate_argument_conversion_code(self, code): pass def generate_argument_type_tests(self, code): # Generate type tests for args whose type in a parent # class is a supertype of the declared type. for arg in self.type.args: if arg.needs_type_test: self.generate_arg_type_test(arg, code) elif arg.type.is_pyobject and not arg.accept_none: self.generate_arg_none_check(arg, code) def generate_execution_code(self, code): super(CFuncDefNode, self).generate_execution_code(code) if self.py_func_stat: self.py_func_stat.generate_execution_code(code) def error_value(self): if self.return_type.is_pyobject: return "0" else: #return None return self.entry.type.exception_value def caller_will_check_exceptions(self): return self.entry.type.exception_check def generate_wrapper_functions(self, code): # If the C signature of a function has changed, we need to generate # wrappers to put in the slots here. k = 0 entry = self.entry func_type = entry.type while entry.prev_entry is not None: k += 1 entry = entry.prev_entry entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k) code.putln() self.generate_function_header(code, 0, with_dispatch = entry.type.is_overridable, with_opt_args = entry.type.optional_arg_count, cname = entry.func_cname) if not self.return_type.is_void: code.put('return ') args = self.type.args arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]] if entry.type.is_overridable: arglist.append(Naming.skip_dispatch_cname) elif func_type.is_overridable: arglist.append('0') if entry.type.optional_arg_count: arglist.append(Naming.optional_args_cname) elif func_type.optional_arg_count: arglist.append('NULL') code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist))) code.putln('}') class PyArgDeclNode(Node): # Argument which must be a Python object (used # for * and ** arguments). # # name string # entry Symtab.Entry # annotation ExprNode or None Py3 argument annotation child_attrs = [] is_self_arg = False is_type_arg = False def generate_function_definitions(self, env, code): self.entry.generate_function_definitions(env, code) class DecoratorNode(Node): # A decorator # # decorator NameNode or CallNode or AttributeNode child_attrs = ['decorator'] class DefNode(FuncDefNode): # A Python function definition. # # name string the Python name of the function # lambda_name string the internal name of a lambda 'function' # decorators [DecoratorNode] list of decorators # args [CArgDeclNode] formal arguments # doc EncodedString or None # body StatListNode # return_type_annotation # ExprNode or None the Py3 return type annotation # # The following subnode is constructed internally # when the def statement is inside a Python class definition. # # fused_py_func DefNode The original fused cpdef DefNode # (in case this is a specialization) # specialized_cpdefs [DefNode] list of specialized cpdef DefNodes # py_cfunc_node PyCFunctionNode/InnerFunctionNode The PyCFunction to create and assign # # decorator_indirection IndirectionNode Used to remove __Pyx_Method_ClassMethod for fused functions child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators", "return_type_annotation"] lambda_name = None reqd_kw_flags_cname = "0" is_wrapper = 0 no_assignment_synthesis = 0 decorators = None return_type_annotation = None entry = None acquire_gil = 0 self_in_stararg = 0 py_cfunc_node = None requires_classobj = False defaults_struct = None # Dynamic kwrds structure name doc = None fused_py_func = False specialized_cpdefs = None py_wrapper = None py_wrapper_required = True func_cname = None defaults_getter = None def __init__(self, pos, **kwds): FuncDefNode.__init__(self, pos, **kwds) k = rk = r = 0 for arg in self.args: if arg.kw_only: k += 1 if not arg.default: rk += 1 if not arg.default: r += 1 self.num_kwonly_args = k self.num_required_kw_args = rk self.num_required_args = r def as_cfunction(self, cfunc=None, scope=None, overridable=True, returns=None, modifiers=None): if self.star_arg: error(self.star_arg.pos, "cdef function cannot have star argument") if self.starstar_arg: error(self.starstar_arg.pos, "cdef function cannot have starstar argument") if cfunc is None: cfunc_args = [] for formal_arg in self.args: name_declarator, type = formal_arg.analyse(scope, nonempty=1) cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name, cname = None, type = py_object_type, pos = formal_arg.pos)) cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type, args = cfunc_args, has_varargs = False, exception_value = None, exception_check = False, nogil = False, with_gil = False, is_overridable = overridable) cfunc = CVarDefNode(self.pos, type=cfunc_type) else: if scope is None: scope = cfunc.scope cfunc_type = cfunc.type if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs: error(self.pos, "wrong number of arguments") error(cfunc.pos, "previous declaration here") for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)): name_declarator, type = formal_arg.analyse(scope, nonempty=1, is_self_arg = (i == 0 and scope.is_c_class_scope)) if type is None or type is PyrexTypes.py_object_type: formal_arg.type = type_arg.type formal_arg.name_declarator = name_declarator from . import ExprNodes if cfunc_type.exception_value is None: exception_value = None else: exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type) declarator = CFuncDeclaratorNode(self.pos, base = CNameDeclaratorNode(self.pos, name=self.name, cname=None), args = self.args, has_varargs = False, exception_check = cfunc_type.exception_check, exception_value = exception_value, with_gil = cfunc_type.with_gil, nogil = cfunc_type.nogil) return CFuncDefNode(self.pos, modifiers = modifiers or [], base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type), declarator = declarator, body = self.body, doc = self.doc, overridable = cfunc_type.is_overridable, type = cfunc_type, with_gil = cfunc_type.with_gil, nogil = cfunc_type.nogil, visibility = 'private', api = False, directive_locals = getattr(cfunc, 'directive_locals', {}), directive_returns = returns) def is_cdef_func_compatible(self): """Determines if the function's signature is compatible with a cdef function. This can be used before calling .as_cfunction() to see if that will be successful. """ if self.needs_closure: return False if self.star_arg or self.starstar_arg: return False return True def analyse_declarations(self, env): self.is_classmethod = self.is_staticmethod = False if self.decorators: for decorator in self.decorators: func = decorator.decorator if func.is_name: self.is_classmethod |= func.name == 'classmethod' self.is_staticmethod |= func.name == 'staticmethod' if self.is_classmethod and env.lookup_here('classmethod'): # classmethod() was overridden - not much we can do here ... self.is_classmethod = False if self.is_staticmethod and env.lookup_here('staticmethod'): # staticmethod() was overridden - not much we can do here ... self.is_staticmethod = False if self.name == '__new__' and env.is_py_class_scope: self.is_staticmethod = 1 self.analyse_argument_types(env) if self.name == '': self.declare_lambda_function(env) else: self.declare_pyfunction(env) self.analyse_signature(env) self.return_type = self.entry.signature.return_type() # if a signature annotation provides a more specific return object type, use it if self.return_type is py_object_type and self.return_type_annotation: if env.directives['annotation_typing'] and not self.entry.is_special: _, return_type = _analyse_signature_annotation(self.return_type_annotation, env) if return_type and return_type.is_pyobject: self.return_type = return_type self.create_local_scope(env) self.py_wrapper = DefNodeWrapper( self.pos, target=self, name=self.entry.name, args=self.args, star_arg=self.star_arg, starstar_arg=self.starstar_arg, return_type=self.return_type) self.py_wrapper.analyse_declarations(env) def analyse_argument_types(self, env): self.directive_locals = env.directives['locals'] allow_none_for_extension_args = env.directives['allow_none_for_extension_args'] f2s = env.fused_to_specific env.fused_to_specific = None for arg in self.args: if hasattr(arg, 'name'): name_declarator = None else: base_type = arg.base_type.analyse(env) name_declarator, type = \ arg.declarator.analyse(base_type, env) arg.name = name_declarator.name arg.type = type if type.is_fused: self.has_fused_arguments = True self.align_argument_type(env, arg) if name_declarator and name_declarator.cname: error(self.pos, "Python function argument cannot have C name specification") arg.type = arg.type.as_argument_type() arg.hdr_type = None arg.needs_conversion = 0 arg.needs_type_test = 0 arg.is_generic = 1 if arg.type.is_pyobject or arg.type.is_buffer or arg.type.is_memoryviewslice: if arg.or_none: arg.accept_none = True elif arg.not_none: arg.accept_none = False elif (arg.type.is_extension_type or arg.type.is_builtin_type or arg.type.is_buffer or arg.type.is_memoryviewslice): if arg.default and arg.default.constant_result is None: # special case: def func(MyType obj = None) arg.accept_none = True else: # default depends on compiler directive arg.accept_none = allow_none_for_extension_args else: # probably just a plain 'object' arg.accept_none = True else: arg.accept_none = True # won't be used, but must be there if arg.not_none: error(arg.pos, "Only Python type arguments can have 'not None'") if arg.or_none: error(arg.pos, "Only Python type arguments can have 'or None'") env.fused_to_specific = f2s def analyse_signature(self, env): if self.entry.is_special: if self.decorators: error(self.pos, "special functions of cdef classes cannot have decorators") self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg) elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg): # Use the simpler calling signature for zero- and one-argument functions. if self.entry.signature is TypeSlots.pyfunction_signature: if len(self.args) == 0: self.entry.signature = TypeSlots.pyfunction_noargs 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: 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() if sig is TypeSlots.pymethod_signature and nfixed == 1 \ and len(self.args) == 0 and self.star_arg: # this is the only case where a diverging number of # arguments is not an error - when we have no explicit # 'self' parameter as in method(*args) sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used self.self_in_stararg = 1 nfixed = 0 if self.is_staticmethod and env.is_c_class_scope: nfixed = 0 self.self_in_stararg = True # FIXME: why for staticmethods? self.entry.signature = sig = copy.copy(sig) sig.fixed_arg_format = "*" sig.is_staticmethod = True sig.has_generic_args = True if ((self.is_classmethod or self.is_staticmethod) and self.has_fused_arguments and env.is_c_class_scope): del self.decorator_indirection.stats[:] for i in range(min(nfixed, len(self.args))): arg = self.args[i] arg.is_generic = 0 if sig.is_self_arg(i) and not self.is_staticmethod: if self.is_classmethod: arg.is_type_arg = 1 arg.hdr_type = arg.type = Builtin.type_type else: arg.is_self_arg = 1 arg.hdr_type = arg.type = env.parent_type arg.needs_conversion = 0 else: arg.hdr_type = sig.fixed_arg_type(i) if not arg.type.same_as(arg.hdr_type): if arg.hdr_type.is_pyobject and arg.type.is_pyobject: arg.needs_type_test = 1 else: arg.needs_conversion = 1 if arg.needs_conversion: arg.hdr_cname = Naming.arg_prefix + arg.name else: arg.hdr_cname = Naming.var_prefix + arg.name if nfixed > len(self.args): self.bad_signature() return elif nfixed < len(self.args): if not sig.has_generic_args: self.bad_signature() for arg in self.args: if arg.is_generic and \ (arg.type.is_extension_type or arg.type.is_builtin_type): arg.needs_type_test = 1 def bad_signature(self): sig = self.entry.signature expected_str = "%d" % sig.num_fixed_args() if sig.has_generic_args: expected_str += " or more" name = self.name if name.startswith("__") and name.endswith("__"): desc = "Special method" else: desc = "Method" error(self.pos, "%s %s has wrong number of arguments " "(%d declared, %s expected)" % ( desc, self.name, len(self.args), expected_str)) def declare_pyfunction(self, env): #print "DefNode.declare_pyfunction:", self.name, "in", env ### name = self.name entry = env.lookup_here(name) if entry: if entry.is_final_cmethod and not env.parent_type.is_final_type: error(self.pos, "Only final types can have final Python (def/cpdef) methods") if (entry.type.is_cfunction and not entry.is_builtin_cmethod and not self.is_wrapper): warning(self.pos, "Overriding cdef method with def method.", 5) entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper) self.entry = entry prefix = env.next_id(env.scope_prefix) self.entry.pyfunc_cname = Naming.pyfunc_prefix + prefix + name if Options.docstrings: entry.doc = embed_position(self.pos, self.doc) entry.doc_cname = Naming.funcdoc_prefix + prefix + name if entry.is_special: if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']): entry.wrapperbase_cname = None else: entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name else: entry.doc = None def declare_lambda_function(self, env): entry = env.declare_lambda_function(self.lambda_name, self.pos) entry.doc = None self.entry = entry self.entry.pyfunc_cname = entry.cname def declare_arguments(self, env): for arg in self.args: if not arg.name: error(arg.pos, "Missing argument name") if arg.needs_conversion: arg.entry = env.declare_var(arg.name, arg.type, arg.pos) if arg.type.is_pyobject: arg.entry.init = "0" else: arg.entry = self.declare_argument(env, arg) arg.entry.is_arg = 1 arg.entry.used = 1 arg.entry.is_self_arg = arg.is_self_arg self.declare_python_arg(env, self.star_arg) self.declare_python_arg(env, self.starstar_arg) def declare_python_arg(self, env, arg): if arg: if env.directives['infer_types'] != False: type = PyrexTypes.unspecified_type else: type = py_object_type entry = env.declare_var(arg.name, type, arg.pos) entry.is_arg = 1 entry.used = 1 entry.init = "0" entry.xdecref_cleanup = 1 arg.entry = entry def analyse_expressions(self, env): self.local_scope.directives = env.directives self.analyse_default_values(env) self.analyse_annotations(env) if self.return_type_annotation: self.return_type_annotation = self.return_type_annotation.analyse_types(env) if not self.needs_assignment_synthesis(env) and self.decorators: for decorator in self.decorators[::-1]: decorator.decorator = decorator.decorator.analyse_expressions(env) self.py_wrapper.prepare_argument_coercion(env) return self def needs_assignment_synthesis(self, env, code=None): if self.is_staticmethod: return True if self.is_wrapper or self.specialized_cpdefs or self.entry.is_fused_specialized: return False if self.no_assignment_synthesis: return False # Should enable for module level as well, that will require more testing... if self.entry.is_anonymous: return True if env.is_module_scope: if code is None: return env.directives['binding'] else: return code.globalstate.directives['binding'] return env.is_py_class_scope or env.is_closure_scope def error_value(self): return self.entry.signature.error_value def caller_will_check_exceptions(self): return self.entry.signature.exception_check def generate_function_definitions(self, env, code): if self.defaults_getter: self.defaults_getter.generate_function_definitions(env, code) # Before closure cnames are mangled if self.py_wrapper_required: # func_cname might be modified by @cname self.py_wrapper.func_cname = self.entry.func_cname self.py_wrapper.generate_function_definitions(env, code) FuncDefNode.generate_function_definitions(self, env, code) def generate_function_header(self, code, with_pymethdef, proto_only=0): if proto_only: if self.py_wrapper_required: self.py_wrapper.generate_function_header( code, with_pymethdef, True) return arg_code_list = [] if self.entry.signature.has_dummy_arg: self_arg = 'PyObject *%s' % Naming.self_cname if not self.needs_outer_scope: self_arg = 'CYTHON_UNUSED ' + self_arg arg_code_list.append(self_arg) def arg_decl_code(arg): entry = arg.entry if entry.in_closure: cname = entry.original_cname else: cname = entry.cname decl = entry.type.declaration_code(cname) if not entry.cf_used: decl = 'CYTHON_UNUSED ' + decl return decl for arg in self.args: arg_code_list.append(arg_decl_code(arg)) if self.star_arg: arg_code_list.append(arg_decl_code(self.star_arg)) if self.starstar_arg: arg_code_list.append(arg_decl_code(self.starstar_arg)) arg_code = ', '.join(arg_code_list) dc = self.return_type.declaration_code(self.entry.pyfunc_cname) decls_code = code.globalstate['decls'] preprocessor_guard = self.get_preprocessor_guard() if preprocessor_guard: decls_code.putln(preprocessor_guard) decls_code.putln( "static %s(%s); /* proto */" % (dc, arg_code)) if preprocessor_guard: decls_code.putln("#endif") code.putln("static %s(%s) {" % (dc, arg_code)) def generate_argument_declarations(self, env, code): pass def generate_keyword_list(self, code): pass def generate_argument_parsing_code(self, env, code): # Move arguments into closure if required def put_into_closure(entry): if entry.in_closure: code.putln('%s = %s;' % (entry.cname, entry.original_cname)) code.put_var_incref(entry) code.put_var_giveref(entry) for arg in self.args: put_into_closure(arg.entry) for arg in self.star_arg, self.starstar_arg: if arg: put_into_closure(arg.entry) def generate_argument_type_tests(self, code): pass class DefNodeWrapper(FuncDefNode): # DefNode python wrapper code generator defnode = None target = None # Target DefNode def __init__(self, *args, **kwargs): FuncDefNode.__init__(self, *args, **kwargs) self.num_kwonly_args = self.target.num_kwonly_args self.num_required_kw_args = self.target.num_required_kw_args self.num_required_args = self.target.num_required_args self.self_in_stararg = self.target.self_in_stararg self.signature = None def analyse_declarations(self, env): target_entry = self.target.entry name = self.name prefix = env.next_id(env.scope_prefix) target_entry.func_cname = Naming.pywrap_prefix + prefix + name target_entry.pymethdef_cname = Naming.pymethdef_prefix + prefix + name self.signature = target_entry.signature def prepare_argument_coercion(self, env): # This is only really required for Cython utility code at this time, # everything else can be done during code generation. But we expand # all utility code here, simply because we cannot easily distinguish # different code types. for arg in self.args: if not arg.type.is_pyobject: if not arg.type.create_from_py_utility_code(env): pass # will fail later elif arg.hdr_type and not arg.hdr_type.is_pyobject: if not arg.hdr_type.create_to_py_utility_code(env): pass # will fail later if self.starstar_arg and not self.starstar_arg.entry.cf_used: # we will set the kwargs argument to NULL instead of a new dict # and must therefore correct the control flow state entry = self.starstar_arg.entry entry.xdecref_cleanup = 1 for ass in entry.cf_assignments: if not ass.is_arg and ass.lhs.is_name: ass.lhs.cf_maybe_null = True def signature_has_nongeneric_args(self): argcount = len(self.args) if argcount == 0 or ( argcount == 1 and (self.args[0].is_self_arg or self.args[0].is_type_arg)): return 0 return 1 def signature_has_generic_args(self): return self.signature.has_generic_args def generate_function_body(self, code): args = [] if self.signature.has_dummy_arg: args.append(Naming.self_cname) for arg in self.args: if arg.hdr_type and not (arg.type.is_memoryviewslice or arg.type.is_struct or arg.type.is_complex): args.append(arg.type.cast_code(arg.entry.cname)) else: args.append(arg.entry.cname) if self.star_arg: args.append(self.star_arg.entry.cname) if self.starstar_arg: args.append(self.starstar_arg.entry.cname) args = ', '.join(args) if not self.return_type.is_void: code.put('%s = ' % Naming.retval_cname) code.putln('%s(%s);' % ( self.target.entry.pyfunc_cname, args)) def generate_function_definitions(self, env, code): lenv = self.target.local_scope # Generate C code for header and body of function code.mark_pos(self.pos) code.putln("") code.putln("/* Python wrapper */") preprocessor_guard = self.target.get_preprocessor_guard() if preprocessor_guard: code.putln(preprocessor_guard) code.enter_cfunc_scope() code.return_from_error_cleanup_label = code.new_label() with_pymethdef = (self.target.needs_assignment_synthesis(env, code) or self.target.pymethdef_required) self.generate_function_header(code, with_pymethdef) self.generate_argument_declarations(lenv, code) tempvardecl_code = code.insertion_point() if self.return_type.is_pyobject: retval_init = ' = 0' else: retval_init = '' if not self.return_type.is_void: code.putln('%s%s;' % ( self.return_type.declaration_code(Naming.retval_cname), retval_init)) code.put_declare_refcount_context() code.put_setup_refcount_context('%s (wrapper)' % self.name) self.generate_argument_parsing_code(lenv, code) self.generate_argument_type_tests(code) self.generate_function_body(code) # ----- Go back and insert temp variable declarations tempvardecl_code.put_temp_declarations(code.funcstate) code.mark_pos(self.pos) code.putln("") code.putln("/* function exit code */") # ----- Error cleanup if code.error_label in code.labels_used: code.put_goto(code.return_label) code.put_label(code.error_label) for cname, type in code.funcstate.all_managed_temps(): code.put_xdecref(cname, type) err_val = self.error_value() if err_val is not None: code.putln("%s = %s;" % (Naming.retval_cname, err_val)) # ----- Non-error return cleanup code.put_label(code.return_label) for entry in lenv.var_entries: if entry.is_arg and entry.type.is_pyobject: code.put_var_decref(entry) code.put_finish_refcount_context() if not self.return_type.is_void: code.putln("return %s;" % Naming.retval_cname) code.putln('}') code.exit_cfunc_scope() if preprocessor_guard: code.putln("#endif /*!(%s)*/" % preprocessor_guard) def generate_function_header(self, code, with_pymethdef, proto_only=0): arg_code_list = [] sig = self.signature if sig.has_dummy_arg or self.self_in_stararg: arg_code = "PyObject *%s" % Naming.self_cname if not sig.has_dummy_arg: arg_code = 'CYTHON_UNUSED ' + arg_code arg_code_list.append(arg_code) for arg in self.args: if not arg.is_generic: if arg.is_self_arg or arg.is_type_arg: arg_code_list.append("PyObject *%s" % arg.hdr_cname) else: arg_code_list.append( arg.hdr_type.declaration_code(arg.hdr_cname)) entry = self.target.entry if not entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]: arg_code_list.append("CYTHON_UNUSED PyObject *unused") if entry.scope.is_c_class_scope and entry.name == "__ipow__": arg_code_list.append("CYTHON_UNUSED PyObject *unused") if sig.has_generic_args: arg_code_list.append( "PyObject *%s, PyObject *%s" % (Naming.args_cname, Naming.kwds_cname)) arg_code = ", ".join(arg_code_list) # Prevent warning: unused function '__pyx_pw_5numpy_7ndarray_1__getbuffer__' mf = "" if (entry.name in ("__getbuffer__", "__releasebuffer__") and entry.scope.is_c_class_scope): mf = "CYTHON_UNUSED " with_pymethdef = False dc = self.return_type.declaration_code(entry.func_cname) header = "static %s%s(%s)" % (mf, dc, arg_code) code.putln("%s; /*proto*/" % header) if proto_only: if self.target.fused_py_func: # If we are the specialized version of the cpdef, we still # want the prototype for the "fused cpdef", in case we're # checking to see if our method was overridden in Python self.target.fused_py_func.generate_function_header( code, with_pymethdef, proto_only=True) return if (Options.docstrings and entry.doc and not self.target.fused_py_func and not entry.scope.is_property_scope and (not entry.is_special or entry.wrapperbase_cname)): # h_code = code.globalstate['h_code'] docstr = entry.doc if docstr.is_unicode: docstr = docstr.utf8encode() code.putln( 'static char %s[] = "%s";' % ( entry.doc_cname, split_string_literal(escape_byte_string(docstr)))) if entry.is_special: code.putln('#if CYTHON_COMPILING_IN_CPYTHON') code.putln( "struct wrapperbase %s;" % entry.wrapperbase_cname) code.putln('#endif') if with_pymethdef or self.target.fused_py_func: code.put( "static PyMethodDef %s = " % entry.pymethdef_cname) code.put_pymethoddef(self.target.entry, ";", allow_skip=False) code.putln("%s {" % header) def generate_argument_declarations(self, env, code): for arg in self.args: if arg.is_generic: if arg.needs_conversion: code.putln("PyObject *%s = 0;" % arg.hdr_cname) else: code.put_var_declaration(arg.entry) for entry in env.var_entries: if entry.is_arg: code.put_var_declaration(entry) def generate_argument_parsing_code(self, env, code): # Generate fast equivalent of PyArg_ParseTuple call for # generic arguments, if any, including args/kwargs old_error_label = code.new_error_label() our_error_label = code.error_label end_label = code.new_label("argument_unpacking_done") has_kwonly_args = self.num_kwonly_args > 0 has_star_or_kw_args = self.star_arg is not None \ or self.starstar_arg is not None or has_kwonly_args for arg in self.args: if not arg.type.is_pyobject: if not arg.type.create_from_py_utility_code(env): pass # will fail later if not self.signature_has_generic_args(): if has_star_or_kw_args: error(self.pos, "This method cannot have * or keyword arguments") self.generate_argument_conversion_code(code) elif not self.signature_has_nongeneric_args(): # func(*args) or func(**kw) or func(*args, **kw) self.generate_stararg_copy_code(code) else: self.generate_tuple_and_keyword_parsing_code(self.args, end_label, code) code.error_label = old_error_label if code.label_used(our_error_label): if not code.label_used(end_label): code.put_goto(end_label) code.put_label(our_error_label) if has_star_or_kw_args: self.generate_arg_decref(self.star_arg, code) if self.starstar_arg: if self.starstar_arg.entry.xdecref_cleanup: code.put_var_xdecref_clear(self.starstar_arg.entry) else: code.put_var_decref_clear(self.starstar_arg.entry) code.put_add_traceback(self.target.entry.qualified_name) code.put_finish_refcount_context() code.putln("return %s;" % self.error_value()) if code.label_used(end_label): code.put_label(end_label) def generate_arg_xdecref(self, arg, code): if arg: code.put_var_xdecref_clear(arg.entry) def generate_arg_decref(self, arg, code): if arg: code.put_var_decref_clear(arg.entry) def generate_stararg_copy_code(self, code): if not self.star_arg: code.globalstate.use_utility_code( UtilityCode.load_cached("RaiseArgTupleInvalid", "FunctionArguments.c")) code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" % Naming.args_cname) code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % ( self.name, Naming.args_cname, self.error_value())) code.putln("}") if self.starstar_arg: if self.star_arg or not self.starstar_arg.entry.cf_used: kwarg_check = "unlikely(%s)" % Naming.kwds_cname else: kwarg_check = "%s" % Naming.kwds_cname else: kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % ( Naming.kwds_cname, Naming.kwds_cname) code.globalstate.use_utility_code( UtilityCode.load_cached("KeywordStringCheck", "FunctionArguments.c")) code.putln( "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % ( kwarg_check, Naming.kwds_cname, self.name, bool(self.starstar_arg), self.error_value())) if self.starstar_arg and self.starstar_arg.entry.cf_used: if all(ref.node.allow_null for ref in self.starstar_arg.entry.cf_references): code.putln("if (%s) {" % kwarg_check) code.putln("%s = PyDict_Copy(%s); if (unlikely(!%s)) return %s;" % ( self.starstar_arg.entry.cname, Naming.kwds_cname, self.starstar_arg.entry.cname, self.error_value())) code.put_gotref(self.starstar_arg.entry.cname) code.putln("} else {") code.putln("%s = NULL;" % (self.starstar_arg.entry.cname,)) code.putln("}") self.starstar_arg.entry.xdecref_cleanup = 1 else: code.put("%s = (%s) ? PyDict_Copy(%s) : PyDict_New(); " % ( self.starstar_arg.entry.cname, Naming.kwds_cname, Naming.kwds_cname)) code.putln("if (unlikely(!%s)) return %s;" % ( self.starstar_arg.entry.cname, self.error_value())) self.starstar_arg.entry.xdecref_cleanup = 0 code.put_gotref(self.starstar_arg.entry.cname) if self.self_in_stararg and not self.target.is_staticmethod: # need to create a new tuple with 'self' inserted as first item code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % ( self.star_arg.entry.cname, Naming.args_cname, self.star_arg.entry.cname)) if self.starstar_arg and self.starstar_arg.entry.cf_used: code.putln("{") code.put_xdecref_clear(self.starstar_arg.entry.cname, py_object_type) code.putln("return %s;" % self.error_value()) code.putln("}") else: code.putln("return %s;" % self.error_value()) code.put_gotref(self.star_arg.entry.cname) code.put_incref(Naming.self_cname, py_object_type) code.put_giveref(Naming.self_cname) code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % ( self.star_arg.entry.cname, Naming.self_cname)) temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False) code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % ( temp, temp, Naming.args_cname, temp)) code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % ( Naming.args_cname, temp)) code.put_incref("item", py_object_type) code.put_giveref("item") code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % ( self.star_arg.entry.cname, temp)) code.putln("}") code.funcstate.release_temp(temp) self.star_arg.entry.xdecref_cleanup = 0 elif self.star_arg: code.put_incref(Naming.args_cname, py_object_type) code.putln("%s = %s;" % ( self.star_arg.entry.cname, Naming.args_cname)) self.star_arg.entry.xdecref_cleanup = 0 def generate_tuple_and_keyword_parsing_code(self, args, success_label, code): argtuple_error_label = code.new_label("argtuple_error") positional_args = [] required_kw_only_args = [] optional_kw_only_args = [] for arg in args: if arg.is_generic: if arg.default: if not arg.is_self_arg and not arg.is_type_arg: if arg.kw_only: optional_kw_only_args.append(arg) else: positional_args.append(arg) elif arg.kw_only: required_kw_only_args.append(arg) elif not arg.is_self_arg and not arg.is_type_arg: positional_args.append(arg) # sort required kw-only args before optional ones to avoid special # cases in the unpacking code kw_only_args = required_kw_only_args + optional_kw_only_args min_positional_args = self.num_required_args - self.num_required_kw_args if len(args) > 0 and (args[0].is_self_arg or args[0].is_type_arg): min_positional_args -= 1 max_positional_args = len(positional_args) has_fixed_positional_count = not self.star_arg and \ min_positional_args == max_positional_args has_kw_only_args = bool(kw_only_args) if self.num_required_kw_args: code.globalstate.use_utility_code( UtilityCode.load_cached("RaiseKeywordRequired", "FunctionArguments.c")) if self.starstar_arg or self.star_arg: self.generate_stararg_init_code(max_positional_args, code) code.putln('{') all_args = tuple(positional_args) + tuple(kw_only_args) code.putln("static PyObject **%s[] = {%s,0};" % ( Naming.pykwdlist_cname, ','.join([ '&%s' % code.intern_identifier(arg.name) for arg in all_args ]))) # Before being converted and assigned to the target variables, # borrowed references to all unpacked argument values are # collected into a local PyObject* array called "values", # regardless if they were taken from default arguments, # positional arguments or keyword arguments. Note that # C-typed default arguments are handled at conversion time, # so their array value is NULL in the end if no argument # was passed for them. self.generate_argument_values_setup_code(all_args, code) # --- optimised code when we receive keyword arguments code.putln("if (%s(%s)) {" % ( (self.num_required_kw_args > 0) and "likely" or "unlikely", Naming.kwds_cname)) self.generate_keyword_unpacking_code( min_positional_args, max_positional_args, has_fixed_positional_count, has_kw_only_args, all_args, argtuple_error_label, code) # --- optimised code when we do not receive any keyword arguments if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args: # Python raises arg tuple related errors first, so we must # check the length here if min_positional_args == max_positional_args and not self.star_arg: compare = '!=' else: compare = '<' code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % ( Naming.args_cname, compare, min_positional_args)) code.put_goto(argtuple_error_label) if self.num_required_kw_args: # pure error case: keywords required but not passed if max_positional_args > min_positional_args and not self.star_arg: code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % ( Naming.args_cname, max_positional_args)) code.put_goto(argtuple_error_label) code.putln('} else {') for i, arg in enumerate(kw_only_args): if not arg.default: pystring_cname = code.intern_identifier(arg.name) # required keyword-only argument missing code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % ( self.name, pystring_cname)) code.putln(code.error_goto(self.pos)) break else: # optimised tuple unpacking code code.putln('} else {') if min_positional_args == max_positional_args: # parse the exact number of positional arguments from # the args tuple for i, arg in enumerate(positional_args): code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (i, Naming.args_cname, i)) else: # parse the positional arguments from the variable length # args tuple and reject illegal argument tuple sizes code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname) if self.star_arg: code.putln('default:') reversed_args = list(enumerate(positional_args))[::-1] for i, arg in reversed_args: if i >= min_positional_args-1: code.put('case %2d: ' % (i+1)) code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (i, Naming.args_cname, i)) if min_positional_args == 0: code.put('case 0: ') code.putln('break;') if self.star_arg: if min_positional_args: for i in range(min_positional_args-1, -1, -1): code.putln('case %2d:' % i) code.put_goto(argtuple_error_label) else: code.put('default: ') code.put_goto(argtuple_error_label) code.putln('}') code.putln('}') # end of the conditional unpacking blocks # Convert arg values to their final type and assign them. # Also inject non-Python default arguments, which do cannot # live in the values[] array. for i, arg in enumerate(all_args): self.generate_arg_assignment(arg, "values[%d]" % i, code) code.putln('}') # end of the whole argument unpacking block if code.label_used(argtuple_error_label): code.put_goto(success_label) code.put_label(argtuple_error_label) code.globalstate.use_utility_code( UtilityCode.load_cached("RaiseArgTupleInvalid", "FunctionArguments.c")) code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % ( self.name, has_fixed_positional_count, min_positional_args, max_positional_args, Naming.args_cname)) code.putln(code.error_goto(self.pos)) def generate_arg_assignment(self, arg, item, code): if arg.type.is_pyobject: # Python default arguments were already stored in 'item' at the very beginning if arg.is_generic: item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item) entry = arg.entry code.putln("%s = %s;" % (entry.cname, item)) else: func = arg.type.from_py_function if func: if arg.default: # C-typed default arguments must be handled here code.putln('if (%s) {' % item) rhs = "%s(%s)" % (func, item) if arg.type.is_enum: rhs = arg.type.cast_code(rhs) code.putln("%s = %s; %s" % ( arg.entry.cname, rhs, code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos))) if arg.default: code.putln('} else {') code.putln( "%s = %s;" % ( arg.entry.cname, arg.calculate_default_value_code(code))) if arg.type.is_memoryviewslice: code.put_incref_memoryviewslice(arg.entry.cname, have_gil=True) code.putln('}') else: error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type) def generate_stararg_init_code(self, max_positional_args, code): if self.starstar_arg: self.starstar_arg.entry.xdecref_cleanup = 0 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % ( self.starstar_arg.entry.cname, self.starstar_arg.entry.cname, self.error_value())) code.put_gotref(self.starstar_arg.entry.cname) if self.star_arg: self.star_arg.entry.xdecref_cleanup = 0 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % ( Naming.args_cname, max_positional_args)) code.putln('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s));' % ( self.star_arg.entry.cname, Naming.args_cname, max_positional_args, Naming.args_cname)) code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname) if self.starstar_arg: code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type) code.put_finish_refcount_context() code.putln('return %s;' % self.error_value()) code.putln('}') code.put_gotref(self.star_arg.entry.cname) code.putln('} else {') code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple)) code.put_incref(Naming.empty_tuple, py_object_type) code.putln('}') def generate_argument_values_setup_code(self, args, code): max_args = len(args) # the 'values' array collects borrowed references to arguments # before doing any type coercion etc. code.putln("PyObject* values[%d] = {%s};" % ( max_args, ','.join('0'*max_args))) if self.target.defaults_struct: code.putln('%s *%s = __Pyx_CyFunction_Defaults(%s, %s);' % ( self.target.defaults_struct, Naming.dynamic_args_cname, self.target.defaults_struct, Naming.self_cname)) # assign borrowed Python default values to the values array, # so that they can be overwritten by received arguments below for i, arg in enumerate(args): if arg.default and arg.type.is_pyobject: default_value = arg.calculate_default_value_code(code) code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value))) def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args, has_fixed_positional_count, has_kw_only_args, all_args, argtuple_error_label, code): code.putln('Py_ssize_t kw_args;') code.putln('const Py_ssize_t pos_args = PyTuple_GET_SIZE(%s);' % Naming.args_cname) # copy the values from the args tuple and check that it's not too long code.putln('switch (pos_args) {') if self.star_arg: code.putln('default:') for i in range(max_positional_args-1, -1, -1): code.put('case %2d: ' % (i+1)) code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % ( i, Naming.args_cname, i)) code.putln('case 0: break;') if not self.star_arg: code.put('default: ') # more arguments than allowed code.put_goto(argtuple_error_label) code.putln('}') # The code above is very often (but not always) the same as # the optimised non-kwargs tuple unpacking code, so we keep # the code block above at the very top, before the following # 'external' PyDict_Size() call, to make it easy for the C # compiler to merge the two separate tuple unpacking # implementations into one when they turn out to be identical. # If we received kwargs, fill up the positional/required # arguments with values from the kw dict code.putln('kw_args = PyDict_Size(%s);' % Naming.kwds_cname) if self.num_required_args or max_positional_args > 0: last_required_arg = -1 for i, arg in enumerate(all_args): if not arg.default: last_required_arg = i if last_required_arg < max_positional_args: last_required_arg = max_positional_args-1 if max_positional_args > 0: code.putln('switch (pos_args) {') for i, arg in enumerate(all_args[:last_required_arg+1]): if max_positional_args > 0 and i <= max_positional_args: if self.star_arg and i == max_positional_args: code.putln('default:') else: code.putln('case %2d:' % i) pystring_cname = code.intern_identifier(arg.name) if arg.default: if arg.kw_only: # optional kw-only args are handled separately below continue code.putln('if (kw_args > 0) {') # don't overwrite default argument code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % ( Naming.kwds_cname, pystring_cname)) code.putln('if (value) { values[%d] = value; kw_args--; }' % i) code.putln('}') else: code.putln('if (likely((values[%d] = PyDict_GetItem(%s, %s)) != 0)) kw_args--;' % ( i, Naming.kwds_cname, pystring_cname)) if i < min_positional_args: if i == 0: # special case: we know arg 0 is missing code.put('else ') code.put_goto(argtuple_error_label) else: # print the correct number of values (args or # kwargs) that were passed into positional # arguments up to this point code.putln('else {') code.globalstate.use_utility_code( UtilityCode.load_cached("RaiseArgTupleInvalid", "FunctionArguments.c")) code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % ( self.name, has_fixed_positional_count, min_positional_args, max_positional_args, i)) code.putln(code.error_goto(self.pos)) code.putln('}') elif arg.kw_only: code.putln('else {') code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %( self.name, pystring_cname)) code.putln(code.error_goto(self.pos)) code.putln('}') if max_positional_args > 0: code.putln('}') if has_kw_only_args: # unpack optional keyword-only arguments separately because # checking for interned strings in a dict is faster than iterating self.generate_optional_kwonly_args_unpacking_code(all_args, code) code.putln('if (unlikely(kw_args > 0)) {') # non-positional/-required kw args left in dict: default args, # kw-only args, **kwargs or error # # This is sort of a catch-all: except for checking required # arguments, this will always do the right thing for unpacking # keyword arguments, so that we can concentrate on optimising # common cases above. if max_positional_args == 0: pos_arg_count = "0" elif self.star_arg: code.putln("const Py_ssize_t used_pos_args = (pos_args < %d) ? pos_args : %d;" % ( max_positional_args, max_positional_args)) pos_arg_count = "used_pos_args" else: pos_arg_count = "pos_args" code.globalstate.use_utility_code( UtilityCode.load_cached("ParseKeywords", "FunctionArguments.c")) code.putln( 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) %s' % ( Naming.kwds_cname, Naming.pykwdlist_cname, self.starstar_arg and self.starstar_arg.entry.cname or '0', pos_arg_count, self.name, code.error_goto(self.pos))) code.putln('}') def generate_optional_kwonly_args_unpacking_code(self, all_args, code): optional_args = [] first_optional_arg = -1 for i, arg in enumerate(all_args): if not arg.kw_only or not arg.default: continue if not optional_args: first_optional_arg = i optional_args.append(arg.name) if optional_args: if len(optional_args) > 1: # if we receive more than the named kwargs, we either have **kwargs # (in which case we must iterate anyway) or it's an error (which we # also handle during iteration) => skip this part if there are more code.putln('if (kw_args > 0 && %s(kw_args <= %d)) {' % ( not self.starstar_arg and 'likely' or '', len(optional_args))) code.putln('Py_ssize_t index;') # not unrolling the loop here reduces the C code overhead code.putln('for (index = %d; index < %d && kw_args > 0; index++) {' % ( first_optional_arg, first_optional_arg + len(optional_args))) else: code.putln('if (kw_args == 1) {') code.putln('const Py_ssize_t index = %d;' % first_optional_arg) code.putln('PyObject* value = PyDict_GetItem(%s, *%s[index]);' % ( Naming.kwds_cname, Naming.pykwdlist_cname)) code.putln('if (value) { values[index] = value; kw_args--; }') if len(optional_args) > 1: code.putln('}') code.putln('}') def generate_argument_conversion_code(self, code): # Generate code to convert arguments from signature type to # declared type, if needed. Also copies signature arguments # into closure fields. for arg in self.args: if arg.needs_conversion: self.generate_arg_conversion(arg, code) def generate_arg_conversion(self, arg, code): # Generate conversion code for one argument. old_type = arg.hdr_type new_type = arg.type if old_type.is_pyobject: if arg.default: code.putln("if (%s) {" % arg.hdr_cname) else: code.putln("assert(%s); {" % arg.hdr_cname) self.generate_arg_conversion_from_pyobject(arg, code) code.putln("}") elif new_type.is_pyobject: self.generate_arg_conversion_to_pyobject(arg, code) else: if new_type.assignable_from(old_type): code.putln( "%s = %s;" % (arg.entry.cname, arg.hdr_cname)) else: error(arg.pos, "Cannot convert 1 argument from '%s' to '%s'" % (old_type, new_type)) def generate_arg_conversion_from_pyobject(self, arg, code): new_type = arg.type func = new_type.from_py_function # copied from CoerceFromPyTypeNode if func: lhs = arg.entry.cname rhs = "%s(%s)" % (func, arg.hdr_cname) if new_type.is_enum: rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs) code.putln("%s = %s; %s" % ( lhs, rhs, code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos))) else: error(arg.pos, "Cannot convert Python object argument to type '%s'" % new_type) def generate_arg_conversion_to_pyobject(self, arg, code): old_type = arg.hdr_type func = old_type.to_py_function if func: code.putln("%s = %s(%s); %s" % ( arg.entry.cname, func, arg.hdr_cname, code.error_goto_if_null(arg.entry.cname, arg.pos))) code.put_var_gotref(arg.entry) else: error(arg.pos, "Cannot convert argument of type '%s' to Python object" % old_type) def generate_argument_type_tests(self, code): # Generate type tests for args whose signature # type is PyObject * and whose declared type is # a subtype thereof. for arg in self.args: if arg.needs_type_test: self.generate_arg_type_test(arg, code) elif not arg.accept_none and (arg.type.is_pyobject or arg.type.is_buffer or arg.type.is_memoryviewslice): self.generate_arg_none_check(arg, code) def error_value(self): return self.signature.error_value class GeneratorDefNode(DefNode): # Generator function node that creates a new generator instance when called. # # gbody GeneratorBodyDefNode the function implementing the generator # is_generator = True is_coroutine = False needs_closure = True child_attrs = DefNode.child_attrs + ["gbody"] def __init__(self, pos, **kwargs): # XXX: don't actually needs a body kwargs['body'] = StatListNode(pos, stats=[], is_terminator=True) super(GeneratorDefNode, self).__init__(pos, **kwargs) def analyse_declarations(self, env): super(GeneratorDefNode, self).analyse_declarations(env) self.gbody.local_scope = self.local_scope self.gbody.analyse_declarations(env) def generate_function_body(self, env, code): body_cname = self.gbody.entry.func_cname name = code.intern_identifier(self.name) qualname = code.intern_identifier(self.qualname) code.putln('{') code.putln('__pyx_CoroutineObject *gen = __Pyx_%s_New(' '(__pyx_coroutine_body_t) %s, (PyObject *) %s, %s, %s); %s' % ( 'Coroutine' if self.is_coroutine else 'Generator', body_cname, Naming.cur_scope_cname, name, qualname, code.error_goto_if_null('gen', self.pos))) code.put_decref(Naming.cur_scope_cname, py_object_type) if self.requires_classobj: classobj_cname = 'gen->classobj' code.putln('%s = __Pyx_CyFunction_GetClassObj(%s);' % ( classobj_cname, Naming.self_cname)) code.put_incref(classobj_cname, py_object_type) code.put_giveref(classobj_cname) code.put_finish_refcount_context() code.putln('return (PyObject *) gen;') code.putln('}') def generate_function_definitions(self, env, code): env.use_utility_code(UtilityCode.load_cached( 'Coroutine' if self.is_coroutine else 'Generator', "Coroutine.c")) self.gbody.generate_function_header(code, proto=True) super(GeneratorDefNode, self).generate_function_definitions(env, code) self.gbody.generate_function_definitions(env, code) class AsyncDefNode(GeneratorDefNode): is_coroutine = True class GeneratorBodyDefNode(DefNode): # Main code body of a generator implemented as a DefNode. # is_generator_body = True is_inlined = False inlined_comprehension_type = None # container type for inlined comprehensions def __init__(self, pos=None, name=None, body=None): super(GeneratorBodyDefNode, self).__init__( pos=pos, body=body, name=name, doc=None, args=[], star_arg=None, starstar_arg=None) def declare_generator_body(self, env): prefix = env.next_id(env.scope_prefix) name = env.next_id('generator') cname = Naming.genbody_prefix + prefix + name entry = env.declare_var(None, py_object_type, self.pos, cname=cname, visibility='private') entry.func_cname = cname entry.qualified_name = EncodedString(self.name) self.entry = entry def analyse_declarations(self, env): self.analyse_argument_types(env) self.declare_generator_body(env) def generate_function_header(self, code, proto=False): header = "static PyObject *%s(__pyx_CoroutineObject *%s, PyObject *%s)" % ( self.entry.func_cname, Naming.generator_cname, Naming.sent_value_cname) if proto: code.putln('%s; /* proto */' % header) else: code.putln('%s /* generator body */\n{' % header) def generate_function_definitions(self, env, code): lenv = self.local_scope # Generate closure function definitions self.body.generate_function_definitions(lenv, code) # Generate C code for header and body of function code.enter_cfunc_scope() code.return_from_error_cleanup_label = code.new_label() # ----- Top-level constants used by this function code.mark_pos(self.pos) self.generate_cached_builtins_decls(lenv, code) # ----- Function header code.putln("") self.generate_function_header(code) closure_init_code = code.insertion_point() # ----- Local variables code.putln("PyObject *%s = NULL;" % Naming.retval_cname) tempvardecl_code = code.insertion_point() code.put_declare_refcount_context() code.put_setup_refcount_context(self.entry.name) # ----- Resume switch point. code.funcstate.init_closure_temps(lenv.scope_class.type.scope) resume_code = code.insertion_point() first_run_label = code.new_label('first_run') code.use_label(first_run_label) code.put_label(first_run_label) code.putln('%s' % (code.error_goto_if_null(Naming.sent_value_cname, self.pos))) # ----- prepare target container for inlined comprehension if self.is_inlined and self.inlined_comprehension_type is not None: target_type = self.inlined_comprehension_type if target_type is Builtin.list_type: comp_init = 'PyList_New(0)' elif target_type is Builtin.set_type: comp_init = 'PySet_New(NULL)' elif target_type is Builtin.dict_type: comp_init = 'PyDict_New()' else: raise InternalError( "invalid type of inlined comprehension: %s" % target_type) code.putln("%s = %s; %s" % ( Naming.retval_cname, comp_init, code.error_goto_if_null(Naming.retval_cname, self.pos))) code.put_gotref(Naming.retval_cname) # ----- Function body self.generate_function_body(env, code) # ----- Closure initialization if lenv.scope_class.type.scope.entries: closure_init_code.putln('%s = %s;' % ( lenv.scope_class.type.declaration_code(Naming.cur_scope_cname), lenv.scope_class.type.cast_code('%s->closure' % Naming.generator_cname))) code.mark_pos(self.pos) code.putln("") code.putln("/* function exit code */") # on normal generator termination, we do not take the exception propagation # path: no traceback info is required and not creating it is much faster if not self.is_inlined and not self.body.is_terminator: code.putln('PyErr_SetNone(PyExc_StopIteration);') # ----- Error cleanup if code.error_label in code.labels_used: if not self.body.is_terminator: code.put_goto(code.return_label) code.put_label(code.error_label) if self.is_inlined and self.inlined_comprehension_type is not None: code.put_xdecref_clear(Naming.retval_cname, py_object_type) if Future.generator_stop in env.global_scope().context.future_directives: # PEP 479: turn accidental StopIteration exceptions into a RuntimeError code.globalstate.use_utility_code(UtilityCode.load_cached("pep479", "Coroutine.c")) code.putln("if (unlikely(PyErr_ExceptionMatches(PyExc_StopIteration))) " "__Pyx_Generator_Replace_StopIteration();") for cname, type in code.funcstate.all_managed_temps(): code.put_xdecref(cname, type) code.put_add_traceback(self.entry.qualified_name) # ----- Non-error return cleanup code.put_label(code.return_label) if self.is_inlined: code.put_xgiveref(Naming.retval_cname) else: code.put_xdecref_clear(Naming.retval_cname, py_object_type) code.putln('%s->resume_label = -1;' % Naming.generator_cname) # clean up as early as possible to help breaking any reference cycles code.putln('__Pyx_Coroutine_clear((PyObject*)%s);' % Naming.generator_cname) code.put_finish_refcount_context() code.putln("return %s;" % Naming.retval_cname) code.putln("}") # ----- Go back and insert temp variable declarations tempvardecl_code.put_temp_declarations(code.funcstate) # ----- Generator resume code resume_code.putln("switch (%s->resume_label) {" % ( Naming.generator_cname)) resume_code.putln("case 0: goto %s;" % first_run_label) for i, label in code.yield_labels: resume_code.putln("case %d: goto %s;" % (i, label)) resume_code.putln("default: /* CPython raises the right error here */") resume_code.put_finish_refcount_context() resume_code.putln("return NULL;") resume_code.putln("}") code.exit_cfunc_scope() class OverrideCheckNode(StatNode): # A Node for dispatching to the def method if it # is overriden. # # py_func # # args # func_temp # body child_attrs = ['body'] body = None def analyse_expressions(self, env): self.args = env.arg_entries if self.py_func.is_module_scope: first_arg = 0 else: first_arg = 1 from . import ExprNodes self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type) call_node = ExprNodes.SimpleCallNode( self.pos, function=self.func_node, args=[ ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:] ]) if env.return_type.is_void or env.return_type.is_returncode: self.body = StatListNode(self.pos, stats=[ ExprStatNode(self.pos, expr=call_node), ReturnStatNode(self.pos, value=None)]) else: self.body = ReturnStatNode(self.pos, value=call_node) self.body = self.body.analyse_expressions(env) return self def generate_execution_code(self, code): interned_attr_cname = code.intern_identifier(self.py_func.entry.name) # Check to see if we are an extension type if self.py_func.is_module_scope: self_arg = "((PyObject *)%s)" % Naming.module_cname else: self_arg = "((PyObject *)%s)" % self.args[0].cname code.putln("/* Check if called by wrapper */") code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname) code.putln("/* Check if overridden in Python */") if self.py_func.is_module_scope: code.putln("else {") else: code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg) func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True) self.func_node.set_cname(func_node_temp) # need to get attribute manually--scope would return cdef method code.globalstate.use_utility_code( UtilityCode.load_cached("PyObjectGetAttrStr", "ObjectHandling.c")) err = code.error_goto_if_null(func_node_temp, self.pos) code.putln("%s = __Pyx_PyObject_GetAttrStr(%s, %s); %s" % ( func_node_temp, self_arg, interned_attr_cname, err)) code.put_gotref(func_node_temp) is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (PyCFunction)%s)" % ( func_node_temp, self.py_func.entry.func_cname) code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden)) self.body.generate_execution_code(code) code.putln("}") code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type) code.funcstate.release_temp(func_node_temp) code.putln("}") class ClassDefNode(StatNode, BlockNode): pass class PyClassDefNode(ClassDefNode): # A Python class definition. # # name EncodedString Name of the class # doc string or None # body StatNode Attribute definition code # entry Symtab.Entry # scope PyClassScope # decorators [DecoratorNode] list of decorators or None # # The following subnodes are constructed internally: # # dict DictNode Class dictionary or Py3 namespace # classobj ClassNode Class object # target NameNode Variable to assign class object to child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "class_result", "target", "class_cell", "decorators"] decorators = None class_result = None is_py3_style_class = False # Python3 style class (kwargs) metaclass = None mkw = None def __init__(self, pos, name, bases, doc, body, decorators=None, keyword_args=None, force_py3_semantics=False): StatNode.__init__(self, pos) self.name = name self.doc = doc self.body = body self.decorators = decorators self.bases = bases from . import ExprNodes if self.doc and Options.docstrings: doc = embed_position(self.pos, self.doc) doc_node = ExprNodes.StringNode(pos, value=doc) else: doc_node = None allow_py2_metaclass = not force_py3_semantics if keyword_args: allow_py2_metaclass = False self.is_py3_style_class = True if keyword_args.is_dict_literal: if keyword_args.key_value_pairs: for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]: if item.key.value == 'metaclass': if self.metaclass is not None: error(item.pos, "keyword argument 'metaclass' passed multiple times") # special case: we already know the metaclass, # so we don't need to do the "build kwargs, # find metaclass" dance at runtime self.metaclass = item.value del keyword_args.key_value_pairs[i] self.mkw = keyword_args else: assert self.metaclass is not None else: # MergedDictNode self.mkw = ExprNodes.ProxyNode(keyword_args) if force_py3_semantics or self.bases or self.mkw or self.metaclass: if self.metaclass is None: if keyword_args and not keyword_args.is_dict_literal: # **kwargs may contain 'metaclass' arg mkdict = self.mkw else: mkdict = None if (not mkdict and self.bases.is_sequence_constructor and not self.bases.args): pass # no base classes => no inherited metaclass else: self.metaclass = ExprNodes.PyClassMetaclassNode( pos, mkw=mkdict, bases=self.bases) needs_metaclass_calculation = False else: needs_metaclass_calculation = True self.dict = ExprNodes.PyClassNamespaceNode( pos, name=name, doc=doc_node, metaclass=self.metaclass, bases=self.bases, mkw=self.mkw) self.classobj = ExprNodes.Py3ClassNode( pos, name=name, bases=self.bases, dict=self.dict, doc=doc_node, metaclass=self.metaclass, mkw=self.mkw, calculate_metaclass=needs_metaclass_calculation, allow_py2_metaclass=allow_py2_metaclass) else: # no bases, no metaclass => old style class creation self.dict = ExprNodes.DictNode(pos, key_value_pairs=[]) self.classobj = ExprNodes.ClassNode( pos, name=name, bases=bases, dict=self.dict, doc=doc_node) self.target = ExprNodes.NameNode(pos, name=name) self.class_cell = ExprNodes.ClassCellInjectorNode(self.pos) def as_cclass(self): """ Return this node as if it were declared as an extension class """ if self.is_py3_style_class: error(self.classobj.pos, "Python3 style class could not be represented as C class") return bases = self.classobj.bases.args if len(bases) == 0: base_class_name = None base_class_module = None elif len(bases) == 1: base = bases[0] path = [] from .ExprNodes import AttributeNode, NameNode while isinstance(base, AttributeNode): path.insert(0, base.attribute) base = base.obj if isinstance(base, NameNode): path.insert(0, base.name) base_class_name = path[-1] if len(path) > 1: base_class_module = u'.'.join(path[:-1]) else: base_class_module = None else: error(self.classobj.bases.args.pos, "Invalid base class") else: error(self.classobj.bases.args.pos, "C class may only have one base class") return None return CClassDefNode(self.pos, visibility = 'private', module_name = None, class_name = self.name, base_class_module = base_class_module, base_class_name = base_class_name, decorators = self.decorators, body = self.body, in_pxd = False, doc = self.doc) def create_scope(self, env): genv = env while genv.is_py_class_scope or genv.is_c_class_scope: genv = genv.outer_scope cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv) return cenv def analyse_declarations(self, env): class_result = self.classobj if self.decorators: from .ExprNodes import SimpleCallNode for decorator in self.decorators[::-1]: class_result = SimpleCallNode( decorator.pos, function = decorator.decorator, args = [class_result]) self.decorators = None self.class_result = class_result self.class_result.analyse_declarations(env) self.target.analyse_target_declaration(env) cenv = self.create_scope(env) cenv.directives = env.directives cenv.class_obj_cname = self.target.entry.cname self.body.analyse_declarations(cenv) def analyse_expressions(self, env): if self.bases: self.bases = self.bases.analyse_expressions(env) if self.metaclass: self.metaclass = self.metaclass.analyse_expressions(env) if self.mkw: self.mkw = self.mkw.analyse_expressions(env) self.dict = self.dict.analyse_expressions(env) self.class_result = self.class_result.analyse_expressions(env) genv = env.global_scope() cenv = self.scope self.body = self.body.analyse_expressions(cenv) self.target.analyse_target_expression(env, self.classobj) self.class_cell = self.class_cell.analyse_expressions(cenv) return self def generate_function_definitions(self, env, code): self.generate_lambda_definitions(self.scope, code) self.body.generate_function_definitions(self.scope, code) def generate_execution_code(self, code): code.mark_pos(self.pos) code.pyclass_stack.append(self) cenv = self.scope if self.bases: self.bases.generate_evaluation_code(code) if self.mkw: self.mkw.generate_evaluation_code(code) if self.metaclass: self.metaclass.generate_evaluation_code(code) self.dict.generate_evaluation_code(code) cenv.namespace_cname = cenv.class_obj_cname = self.dict.result() self.class_cell.generate_evaluation_code(code) self.body.generate_execution_code(code) self.class_result.generate_evaluation_code(code) self.class_cell.generate_injection_code( code, self.class_result.result()) self.class_cell.generate_disposal_code(code) cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result() self.target.generate_assignment_code(self.class_result, code) self.dict.generate_disposal_code(code) self.dict.free_temps(code) if self.metaclass: self.metaclass.generate_disposal_code(code) self.metaclass.free_temps(code) if self.mkw: self.mkw.generate_disposal_code(code) self.mkw.free_temps(code) if self.bases: self.bases.generate_disposal_code(code) self.bases.free_temps(code) code.pyclass_stack.pop() class CClassDefNode(ClassDefNode): # An extension type definition. # # visibility 'private' or 'public' or 'extern' # typedef_flag boolean # api boolean # module_name string or None For import of extern type objects # class_name string Unqualified name of class # as_name string or None Name to declare as in this scope # base_class_module string or None Module containing the base class # base_class_name string or None Name of the base class # objstruct_name string or None Specified C name of object struct # typeobj_name string or None Specified C name of type object # in_pxd boolean Is in a .pxd file # decorators [DecoratorNode] list of decorators or None # doc string or None # body StatNode or None # entry Symtab.Entry # base_type PyExtensionType or None # buffer_defaults_node DictNode or None Declares defaults for a buffer # buffer_defaults_pos child_attrs = ["body"] buffer_defaults_node = None buffer_defaults_pos = None typedef_flag = False api = False objstruct_name = None typeobj_name = None decorators = None shadow = False def buffer_defaults(self, env): if not hasattr(self, '_buffer_defaults'): from . import Buffer if self.buffer_defaults_node: self._buffer_defaults = Buffer.analyse_buffer_options( self.buffer_defaults_pos, env, [], self.buffer_defaults_node, need_complete=False) else: self._buffer_defaults = None return self._buffer_defaults def declare(self, env): if self.module_name and self.visibility != 'extern': module_path = self.module_name.split(".") home_scope = env.find_imported_module(module_path, self.pos) if not home_scope: return None else: home_scope = env self.entry = home_scope.declare_c_class( name = self.class_name, pos = self.pos, defining = 0, implementing = 0, module_name = self.module_name, base_type = None, objstruct_cname = self.objstruct_name, typeobj_cname = self.typeobj_name, visibility = self.visibility, typedef_flag = self.typedef_flag, api = self.api, buffer_defaults = self.buffer_defaults(env), shadow = self.shadow) def analyse_declarations(self, env): #print "CClassDefNode.analyse_declarations:", self.class_name #print "...visibility =", self.visibility #print "...module_name =", self.module_name if env.in_cinclude and not self.objstruct_name: error(self.pos, "Object struct name specification required for " "C class defined in 'extern from' block") if self.decorators: error(self.pos, "Decorators not allowed on cdef classes (used on type '%s')" % self.class_name) self.base_type = None # Now that module imports are cached, we need to # import the modules for extern classes. if self.module_name: self.module = None for module in env.cimported_modules: if module.name == self.module_name: self.module = module if self.module is None: self.module = ModuleScope(self.module_name, None, env.context) self.module.has_extern_class = 1 env.add_imported_module(self.module) if self.base_class_name: if self.base_class_module: base_class_scope = env.find_module(self.base_class_module, self.pos) else: base_class_scope = env if self.base_class_name == 'object': # extension classes are special and don't need to inherit from object if base_class_scope is None or base_class_scope.lookup('object') is None: self.base_class_name = None self.base_class_module = None base_class_scope = None if base_class_scope: base_class_entry = base_class_scope.find(self.base_class_name, self.pos) if base_class_entry: if not base_class_entry.is_type: error(self.pos, "'%s' is not a type name" % self.base_class_name) elif not base_class_entry.type.is_extension_type and \ not (base_class_entry.type.is_builtin_type and base_class_entry.type.objstruct_cname): error(self.pos, "'%s' is not an extension type" % self.base_class_name) elif not base_class_entry.type.is_complete(): error(self.pos, "Base class '%s' of type '%s' is incomplete" % ( self.base_class_name, self.class_name)) elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \ base_class_entry.type.is_final_type: error(self.pos, "Base class '%s' of type '%s' is final" % ( self.base_class_name, self.class_name)) elif base_class_entry.type.is_builtin_type and \ base_class_entry.type.name in ('tuple', 'str', 'bytes'): error(self.pos, "inheritance from PyVarObject types like '%s' is not currently supported" % base_class_entry.type.name) else: self.base_type = base_class_entry.type if env.directives.get('freelist', 0) > 0: warning(self.pos, "freelists cannot be used on subtypes, only the base class can manage them", 1) has_body = self.body is not None if has_body and self.base_type and not self.base_type.scope: # To properly initialize inherited attributes, the base type must # be analysed before this type. self.base_type.defered_declarations.append(lambda : self.analyse_declarations(env)) return if self.module_name and self.visibility != 'extern': module_path = self.module_name.split(".") home_scope = env.find_imported_module(module_path, self.pos) if not home_scope: return else: home_scope = env if self.visibility == 'extern': if (self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types and env.qualified_name[:8] != 'cpython.'): # allow overloaded names for cimporting from cpython warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1) self.entry = home_scope.declare_c_class( name = self.class_name, pos = self.pos, defining = has_body and self.in_pxd, implementing = has_body and not self.in_pxd, module_name = self.module_name, base_type = self.base_type, objstruct_cname = self.objstruct_name, typeobj_cname = self.typeobj_name, visibility = self.visibility, typedef_flag = self.typedef_flag, api = self.api, buffer_defaults = self.buffer_defaults(env), shadow = self.shadow) if self.shadow: home_scope.lookup(self.class_name).as_variable = self.entry if home_scope is not env and self.visibility == 'extern': env.add_imported_entry(self.class_name, self.entry, self.pos) self.scope = scope = self.entry.type.scope if scope is not None: scope.directives = env.directives if self.doc and Options.docstrings: scope.doc = embed_position(self.pos, self.doc) if has_body: self.body.analyse_declarations(scope) if self.in_pxd: scope.defined = 1 else: scope.implemented = 1 env.allocate_vtable_names(self.entry) for thunk in self.entry.type.defered_declarations: thunk() def analyse_expressions(self, env): if self.body: scope = self.entry.type.scope self.body = self.body.analyse_expressions(scope) return self def generate_function_definitions(self, env, code): if self.body: self.generate_lambda_definitions(self.scope, code) self.body.generate_function_definitions(self.scope, code) def generate_execution_code(self, code): # This is needed to generate evaluation code for # default values of method arguments. code.mark_pos(self.pos) if self.body: self.body.generate_execution_code(code) def annotate(self, code): if self.body: self.body.annotate(code) class PropertyNode(StatNode): # Definition of a property in an extension type. # # name string # doc EncodedString or None Doc string # entry Symtab.Entry # body StatListNode child_attrs = ["body"] def analyse_declarations(self, env): self.entry = env.declare_property(self.name, self.doc, self.pos) self.entry.scope.directives = env.directives self.body.analyse_declarations(self.entry.scope) def analyse_expressions(self, env): self.body = self.body.analyse_expressions(env) return self def generate_function_definitions(self, env, code): self.body.generate_function_definitions(env, code) def generate_execution_code(self, code): pass def annotate(self, code): self.body.annotate(code) class GlobalNode(StatNode): # Global variable declaration. # # names [string] child_attrs = [] def analyse_declarations(self, env): for name in self.names: env.declare_global(name, self.pos) def analyse_expressions(self, env): return self def generate_execution_code(self, code): pass class NonlocalNode(StatNode): # Nonlocal variable declaration via the 'nonlocal' keyword. # # names [string] child_attrs = [] def analyse_declarations(self, env): for name in self.names: env.declare_nonlocal(name, self.pos) def analyse_expressions(self, env): return self def generate_execution_code(self, code): pass class ExprStatNode(StatNode): # Expression used as a statement. # # expr ExprNode child_attrs = ["expr"] def analyse_declarations(self, env): from . import ExprNodes if isinstance(self.expr, ExprNodes.GeneralCallNode): func = self.expr.function.as_cython_attribute() if func == u'declare': args, kwds = self.expr.explicit_args_kwds() if len(args): error(self.expr.pos, "Variable names must be specified.") for var, type_node in kwds.key_value_pairs: type = type_node.analyse_as_type(env) if type is None: error(type_node.pos, "Unknown type") else: env.declare_var(var.value, type, var.pos, is_cdef = True) self.__class__ = PassStatNode def analyse_expressions(self, env): self.expr.result_is_used = False # hint that .result() may safely be left empty self.expr = self.expr.analyse_expressions(env) return self def nogil_check(self, env): if self.expr.type.is_pyobject and self.expr.is_temp: self.gil_error() gil_message = "Discarding owned Python object" def generate_execution_code(self, code): code.mark_pos(self.pos) self.expr.generate_evaluation_code(code) if not self.expr.is_temp and self.expr.result(): code.putln("%s;" % self.expr.result()) self.expr.generate_disposal_code(code) self.expr.free_temps(code) def generate_function_definitions(self, env, code): self.expr.generate_function_definitions(env, code) def annotate(self, code): self.expr.annotate(code) class AssignmentNode(StatNode): # Abstract base class for assignment nodes. # # The analyse_expressions and generate_execution_code # phases of assignments are split into two sub-phases # each, to enable all the right hand sides of a # parallel assignment to be evaluated before assigning # to any of the left hand sides. def analyse_expressions(self, env): node = self.analyse_types(env) if isinstance(node, AssignmentNode) and not isinstance(node, ParallelAssignmentNode): if node.rhs.type.is_ptr and node.rhs.is_ephemeral(): error(self.pos, "Storing unsafe C derivative of temporary Python reference") return node # def analyse_expressions(self, env): # self.analyse_expressions_1(env) # self.analyse_expressions_2(env) def generate_execution_code(self, code): code.mark_pos(self.pos) self.generate_rhs_evaluation_code(code) self.generate_assignment_code(code) class SingleAssignmentNode(AssignmentNode): # The simplest case: # # a = b # # lhs ExprNode Left hand side # rhs ExprNode Right hand side # first bool Is this guaranteed the first assignment to lhs? # is_overloaded_assignment bool Is this assignment done via an overloaded operator= child_attrs = ["lhs", "rhs"] first = False is_overloaded_assignment = False declaration_only = False def analyse_declarations(self, env): from . import ExprNodes # handle declarations of the form x = cython.foo() if isinstance(self.rhs, ExprNodes.CallNode): func_name = self.rhs.function.as_cython_attribute() if func_name: args, kwds = self.rhs.explicit_args_kwds() if func_name in ['declare', 'typedef']: if len(args) > 2 or kwds is not None: error(self.rhs.pos, "Can only declare one type at a time.") return type = args[0].analyse_as_type(env) if type is None: error(args[0].pos, "Unknown type") return lhs = self.lhs if func_name == 'declare': if isinstance(lhs, ExprNodes.NameNode): vars = [(lhs.name, lhs.pos)] elif isinstance(lhs, ExprNodes.TupleNode): vars = [(var.name, var.pos) for var in lhs.args] else: error(lhs.pos, "Invalid declaration") return for var, pos in vars: env.declare_var(var, type, pos, is_cdef = True) if len(args) == 2: # we have a value self.rhs = args[1] else: self.declaration_only = True else: self.declaration_only = True if not isinstance(lhs, ExprNodes.NameNode): error(lhs.pos, "Invalid declaration.") env.declare_typedef(lhs.name, type, self.pos, visibility='private') elif func_name in ['struct', 'union']: self.declaration_only = True if len(args) > 0 or kwds is None: error(self.rhs.pos, "Struct or union members must be given by name.") return members = [] for member, type_node in kwds.key_value_pairs: type = type_node.analyse_as_type(env) if type is None: error(type_node.pos, "Unknown type") else: members.append((member.value, type, member.pos)) if len(members) < len(kwds.key_value_pairs): return if not isinstance(self.lhs, ExprNodes.NameNode): error(self.lhs.pos, "Invalid declaration.") name = self.lhs.name scope = StructOrUnionScope(name) env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos) for member, type, pos in members: scope.declare_var(member, type, pos) elif func_name == 'fused_type': # dtype = cython.fused_type(...) self.declaration_only = True if kwds: error(self.rhs.function.pos, "fused_type does not take keyword arguments") fusednode = FusedTypeNode(self.rhs.pos, name=self.lhs.name, types=args) fusednode.analyse_declarations(env) if self.declaration_only: return else: self.lhs.analyse_target_declaration(env) def analyse_types(self, env, use_temp=0): from . import ExprNodes self.rhs = self.rhs.analyse_types(env) unrolled_assignment = self.unroll_rhs(env) if unrolled_assignment: return unrolled_assignment self.lhs = self.lhs.analyse_target_types(env) self.lhs.gil_assignment_check(env) unrolled_assignment = self.unroll_lhs(env) if unrolled_assignment: return unrolled_assignment if self.lhs.memslice_broadcast or self.rhs.memslice_broadcast: self.lhs.memslice_broadcast = True self.rhs.memslice_broadcast = True if (self.lhs.is_subscript and not self.rhs.type.is_memoryviewslice and (self.lhs.memslice_slice or self.lhs.is_memslice_copy) and (self.lhs.type.dtype.assignable_from(self.rhs.type) or self.rhs.type.is_pyobject)): # scalar slice assignment self.lhs.is_memslice_scalar_assignment = True dtype = self.lhs.type.dtype elif self.lhs.type.is_array: if not isinstance(self.lhs, ExprNodes.SliceIndexNode): # cannot assign to C array, only to its full slice self.lhs = ExprNodes.SliceIndexNode( self.lhs.pos, base=self.lhs, start=None, stop=None) self.lhs = self.lhs.analyse_target_types(env) dtype = self.lhs.type else: dtype = self.lhs.type if self.lhs.type.is_cpp_class: op = env.lookup_operator_for_types(self.pos, '=', [self.lhs.type, self.rhs.type]) if op: rhs = self.rhs self.is_overloaded_assignment = True else: rhs = self.rhs.coerce_to(dtype, env) else: rhs = self.rhs.coerce_to(dtype, env) if use_temp or rhs.is_attribute or ( not rhs.is_name and not rhs.is_literal and rhs.type.is_pyobject): # things like (cdef) attribute access are not safe (traverses pointers) rhs = rhs.coerce_to_temp(env) elif rhs.type.is_pyobject: rhs = rhs.coerce_to_simple(env) self.rhs = rhs return self def unroll(self, node, target_size, env): from . import ExprNodes, UtilNodes base = node start_node = stop_node = step_node = check_node = None if node.type.is_ctuple: slice_size = node.type.size elif node.type.is_ptr or node.type.is_array: while isinstance(node, ExprNodes.SliceIndexNode) and not (node.start or node.stop): base = node = node.base if isinstance(node, ExprNodes.SliceIndexNode): base = node.base start_node = node.start if start_node: start_node = start_node.coerce_to(PyrexTypes.c_py_ssize_t_type, env) stop_node = node.stop if stop_node: stop_node = stop_node.coerce_to(PyrexTypes.c_py_ssize_t_type, env) else: if node.type.is_array and node.type.size: stop_node = ExprNodes.IntNode( self.pos, value=str(node.type.size), constant_result=(node.type.size if isinstance(node.type.size, _py_int_types) else ExprNodes.constant_value_not_set)) else: error(self.pos, "C array iteration requires known end index") return step_node = None #node.step if step_node: step_node = step_node.coerce_to(PyrexTypes.c_py_ssize_t_type, env) # TODO: Factor out SliceIndexNode.generate_slice_guard_code() for use here. def get_const(node, none_value): if node is None: return none_value elif node.has_constant_result(): return node.constant_result else: raise ValueError("Not a constant.") try: slice_size = (get_const(stop_node, None) - get_const(start_node, 0)) / get_const(step_node, 1) except ValueError: error(self.pos, "C array assignment currently requires known endpoints") return elif node.type.is_array: slice_size = node.type.size if not isinstance(slice_size, _py_int_types): return # might still work when coercing to Python else: return else: return if slice_size != target_size: error(self.pos, "Assignment to/from slice of wrong length, expected %s, got %s" % ( slice_size, target_size)) return items = [] base = UtilNodes.LetRefNode(base) refs = [base] if start_node and not start_node.is_literal: start_node = UtilNodes.LetRefNode(start_node) refs.append(start_node) if stop_node and not stop_node.is_literal: stop_node = UtilNodes.LetRefNode(stop_node) refs.append(stop_node) if step_node and not step_node.is_literal: step_node = UtilNodes.LetRefNode(step_node) refs.append(step_node) for ix in range(target_size): ix_node = ExprNodes.IntNode(self.pos, value=str(ix), constant_result=ix, type=PyrexTypes.c_py_ssize_t_type) if step_node is not None: if step_node.has_constant_result(): step_value = ix_node.constant_result * step_node.constant_result ix_node = ExprNodes.IntNode(self.pos, value=str(step_value), constant_result=step_value) else: ix_node = ExprNodes.MulNode(self.pos, operator='*', operand1=step_node, operand2=ix_node) if start_node is not None: if start_node.has_constant_result() and ix_node.has_constant_result(): index_value = ix_node.constant_result + start_node.constant_result ix_node = ExprNodes.IntNode(self.pos, value=str(index_value), constant_result=index_value) else: ix_node = ExprNodes.AddNode( self.pos, operator='+', operand1=start_node, operand2=ix_node) items.append(ExprNodes.IndexNode(self.pos, base=base, index=ix_node.analyse_types(env))) return check_node, refs, items def unroll_assignments(self, refs, check_node, lhs_list, rhs_list, env): from . import UtilNodes assignments = [] for lhs, rhs in zip(lhs_list, rhs_list): assignments.append(SingleAssignmentNode(self.pos, lhs=lhs, rhs=rhs, first=self.first)) all = ParallelAssignmentNode(pos=self.pos, stats=assignments).analyse_expressions(env) if check_node: all = StatListNode(pos=self.pos, stats=[check_node, all]) for ref in refs[::-1]: all = UtilNodes.LetNode(ref, all) return all def unroll_rhs(self, env): from . import ExprNodes if not isinstance(self.lhs, ExprNodes.TupleNode): return if any(arg.is_starred for arg in self.lhs.args): return unrolled = self.unroll(self.rhs, len(self.lhs.args), env) if not unrolled: return check_node, refs, rhs = unrolled return self.unroll_assignments(refs, check_node, self.lhs.args, rhs, env) def unroll_lhs(self, env): if self.lhs.type.is_ctuple: # Handled directly. return from . import ExprNodes, UtilNodes if not isinstance(self.rhs, ExprNodes.TupleNode): return unrolled = self.unroll(self.lhs, len(self.rhs.args), env) if not unrolled: return check_node, refs, lhs = unrolled return self.unroll_assignments(refs, check_node, lhs, self.rhs.args, env) def generate_rhs_evaluation_code(self, code): self.rhs.generate_evaluation_code(code) def generate_assignment_code(self, code, overloaded_assignment=False): self.lhs.generate_assignment_code( self.rhs, code, overloaded_assignment=self.is_overloaded_assignment) def generate_function_definitions(self, env, code): self.rhs.generate_function_definitions(env, code) def annotate(self, code): self.lhs.annotate(code) self.rhs.annotate(code) class CascadedAssignmentNode(AssignmentNode): # An assignment with multiple left hand sides: # # a = b = c # # lhs_list [ExprNode] Left hand sides # rhs ExprNode Right hand sides # # Used internally: # # coerced_values [ExprNode] RHS coerced to all distinct LHS types # cloned_values [ExprNode] cloned RHS value for each LHS # assignment_overloads [Bool] If each assignment uses a C++ operator= child_attrs = ["lhs_list", "rhs", "coerced_values", "cloned_values"] cloned_values = None coerced_values = None assignment_overloads = None def analyse_declarations(self, env): for lhs in self.lhs_list: lhs.analyse_target_declaration(env) def analyse_types(self, env, use_temp=0): from .ExprNodes import CloneNode, ProxyNode # collect distinct types used on the LHS lhs_types = set() for lhs in self.lhs_list: lhs.analyse_target_types(env) lhs.gil_assignment_check(env) lhs_types.add(lhs.type) rhs = self.rhs.analyse_types(env) # common special case: only one type needed on the LHS => coerce only once if len(lhs_types) == 1: # Avoid coercion for overloaded assignment operators. if next(iter(lhs_types)).is_cpp_class: op = env.lookup_operator('=', [lhs, self.rhs]) if not op: rhs = rhs.coerce_to(lhs_types.pop(), env) else: rhs = rhs.coerce_to(lhs_types.pop(), env) if not rhs.is_name and not rhs.is_literal and ( use_temp or rhs.is_attribute or rhs.type.is_pyobject): rhs = rhs.coerce_to_temp(env) else: rhs = rhs.coerce_to_simple(env) self.rhs = ProxyNode(rhs) if rhs.is_temp else rhs # clone RHS and coerce it to all distinct LHS types self.coerced_values = [] coerced_values = {} self.assignment_overloads = [] for lhs in self.lhs_list: overloaded = lhs.type.is_cpp_class and env.lookup_operator('=', [lhs, self.rhs]) self.assignment_overloads.append(overloaded) if lhs.type not in coerced_values and lhs.type != rhs.type: rhs = CloneNode(self.rhs) if not overloaded: rhs = rhs.coerce_to(lhs.type, env) self.coerced_values.append(rhs) coerced_values[lhs.type] = rhs # clone coerced values for all LHS assignments self.cloned_values = [] for lhs in self.lhs_list: rhs = coerced_values.get(lhs.type, self.rhs) self.cloned_values.append(CloneNode(rhs)) return self def generate_rhs_evaluation_code(self, code): self.rhs.generate_evaluation_code(code) def generate_assignment_code(self, code, overloaded_assignment=False): # prepare all coercions for rhs in self.coerced_values: rhs.generate_evaluation_code(code) # assign clones to LHS for lhs, rhs, overload in zip(self.lhs_list, self.cloned_values, self.assignment_overloads): rhs.generate_evaluation_code(code) lhs.generate_assignment_code(rhs, code, overloaded_assignment=overload) # dispose of coerced values and original RHS for rhs_value in self.coerced_values: rhs_value.generate_disposal_code(code) rhs_value.free_temps(code) self.rhs.generate_disposal_code(code) self.rhs.free_temps(code) def generate_function_definitions(self, env, code): self.rhs.generate_function_definitions(env, code) def annotate(self, code): for rhs in self.coerced_values: rhs.annotate(code) for lhs, rhs in zip(self.lhs_list, self.cloned_values): lhs.annotate(code) rhs.annotate(code) self.rhs.annotate(code) class ParallelAssignmentNode(AssignmentNode): # A combined packing/unpacking assignment: # # a, b, c = d, e, f # # This has been rearranged by the parser into # # a = d ; b = e ; c = f # # but we must evaluate all the right hand sides # before assigning to any of the left hand sides. # # stats [AssignmentNode] The constituent assignments child_attrs = ["stats"] def analyse_declarations(self, env): for stat in self.stats: stat.analyse_declarations(env) def analyse_expressions(self, env): self.stats = [ stat.analyse_types(env, use_temp = 1) for stat in self.stats ] return self # def analyse_expressions(self, env): # for stat in self.stats: # stat.analyse_expressions_1(env, use_temp = 1) # for stat in self.stats: # stat.analyse_expressions_2(env) def generate_execution_code(self, code): code.mark_pos(self.pos) for stat in self.stats: stat.generate_rhs_evaluation_code(code) for stat in self.stats: stat.generate_assignment_code(code) def generate_function_definitions(self, env, code): for stat in self.stats: stat.generate_function_definitions(env, code) def annotate(self, code): for stat in self.stats: stat.annotate(code) class InPlaceAssignmentNode(AssignmentNode): # An in place arithmetic operand: # # a += b # a -= b # ... # # lhs ExprNode Left hand side # rhs ExprNode Right hand side # operator char one of "+-*/%^&|" # # This code is a bit tricky because in order to obey Python # semantics the sub-expressions (e.g. indices) of the lhs must # not be evaluated twice. So we must re-use the values calculated # in evaluation phase for the assignment phase as well. # Fortunately, the type of the lhs node is fairly constrained # (it must be a NameNode, AttributeNode, or IndexNode). child_attrs = ["lhs", "rhs"] def analyse_declarations(self, env): self.lhs.analyse_target_declaration(env) def analyse_types(self, env): self.rhs = self.rhs.analyse_types(env) self.lhs = self.lhs.analyse_target_types(env) # When assigning to a fully indexed buffer or memoryview, coerce the rhs if (self.lhs.is_subscript and (self.lhs.memslice_index or self.lhs.is_buffer_access)): self.rhs = self.rhs.coerce_to(self.lhs.type, env) elif self.lhs.type.is_string and self.operator in '+-': # use pointer arithmetic for char* LHS instead of string concat self.rhs = self.rhs.coerce_to(PyrexTypes.c_py_ssize_t_type, env) return self def generate_execution_code(self, code): code.mark_pos(self.pos) self.rhs.generate_evaluation_code(code) self.lhs.generate_subexpr_evaluation_code(code) c_op = self.operator if c_op == "//": c_op = "/" elif c_op == "**": error(self.pos, "No C inplace power operator") if self.lhs.is_subscript and self.lhs.is_buffer_access: if self.lhs.type.is_pyobject: error(self.pos, "In-place operators not allowed on object buffers in this release.") if (c_op in ('/', '%') and self.lhs.type.is_int and not code.globalstate.directives['cdivision']): error(self.pos, "In-place non-c divide operators not allowed on int buffers.") self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op) else: # C++ # TODO: make sure overload is declared code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result())) self.lhs.generate_subexpr_disposal_code(code) self.lhs.free_subexpr_temps(code) self.rhs.generate_disposal_code(code) self.rhs.free_temps(code) def annotate(self, code): self.lhs.annotate(code) self.rhs.annotate(code) def create_binop_node(self): from . import ExprNodes return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs) class PrintStatNode(StatNode): # print statement # # arg_tuple TupleNode # stream ExprNode or None (stdout) # append_newline boolean child_attrs = ["arg_tuple", "stream"] def analyse_expressions(self, env): if self.stream: stream = self.stream.analyse_expressions(env) self.stream = stream.coerce_to_pyobject(env) arg_tuple = self.arg_tuple.analyse_expressions(env) self.arg_tuple = arg_tuple.coerce_to_pyobject(env) env.use_utility_code(printing_utility_code) if len(self.arg_tuple.args) == 1 and self.append_newline: env.use_utility_code(printing_one_utility_code) return self nogil_check = Node.gil_error gil_message = "Python print statement" def generate_execution_code(self, code): code.mark_pos(self.pos) if self.stream: self.stream.generate_evaluation_code(code) stream_result = self.stream.py_result() else: stream_result = '0' if len(self.arg_tuple.args) == 1 and self.append_newline: arg = self.arg_tuple.args[0] arg.generate_evaluation_code(code) code.putln( "if (__Pyx_PrintOne(%s, %s) < 0) %s" % ( stream_result, arg.py_result(), code.error_goto(self.pos))) arg.generate_disposal_code(code) arg.free_temps(code) else: self.arg_tuple.generate_evaluation_code(code) code.putln( "if (__Pyx_Print(%s, %s, %d) < 0) %s" % ( stream_result, self.arg_tuple.py_result(), self.append_newline, code.error_goto(self.pos))) self.arg_tuple.generate_disposal_code(code) self.arg_tuple.free_temps(code) if self.stream: self.stream.generate_disposal_code(code) self.stream.free_temps(code) def generate_function_definitions(self, env, code): if self.stream: self.stream.generate_function_definitions(env, code) self.arg_tuple.generate_function_definitions(env, code) def annotate(self, code): if self.stream: self.stream.annotate(code) self.arg_tuple.annotate(code) class ExecStatNode(StatNode): # exec statement # # args [ExprNode] child_attrs = ["args"] def analyse_expressions(self, env): for i, arg in enumerate(self.args): arg = arg.analyse_expressions(env) arg = arg.coerce_to_pyobject(env) self.args[i] = arg env.use_utility_code(Builtin.pyexec_utility_code) return self nogil_check = Node.gil_error gil_message = "Python exec statement" def generate_execution_code(self, code): code.mark_pos(self.pos) args = [] for arg in self.args: arg.generate_evaluation_code(code) args.append( arg.py_result() ) args = tuple(args + ['0', '0'][:3-len(args)]) temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True) code.putln("%s = __Pyx_PyExec3(%s, %s, %s);" % ( (temp_result,) + args)) for arg in self.args: arg.generate_disposal_code(code) arg.free_temps(code) code.putln( code.error_goto_if_null(temp_result, self.pos)) code.put_gotref(temp_result) code.put_decref_clear(temp_result, py_object_type) code.funcstate.release_temp(temp_result) def annotate(self, code): for arg in self.args: arg.annotate(code) class DelStatNode(StatNode): # del statement # # args [ExprNode] child_attrs = ["args"] ignore_nonexisting = False def analyse_declarations(self, env): for arg in self.args: arg.analyse_target_declaration(env) def analyse_expressions(self, env): for i, arg in enumerate(self.args): arg = self.args[i] = arg.analyse_target_expression(env, None) if arg.type.is_pyobject or (arg.is_name and arg.type.is_memoryviewslice): if arg.is_name and arg.entry.is_cglobal: error(arg.pos, "Deletion of global C variable") elif arg.type.is_ptr and arg.type.base_type.is_cpp_class: self.cpp_check(env) elif arg.type.is_cpp_class: error(arg.pos, "Deletion of non-heap C++ object") elif arg.is_subscript and arg.base.type is Builtin.bytearray_type: pass # del ba[i] else: error(arg.pos, "Deletion of non-Python, non-C++ object") #arg.release_target_temp(env) return self def nogil_check(self, env): for arg in self.args: if arg.type.is_pyobject: self.gil_error() gil_message = "Deleting Python object" def generate_execution_code(self, code): code.mark_pos(self.pos) for arg in self.args: if (arg.type.is_pyobject or arg.type.is_memoryviewslice or arg.is_subscript and arg.base.type is Builtin.bytearray_type): arg.generate_deletion_code( code, ignore_nonexisting=self.ignore_nonexisting) elif arg.type.is_ptr and arg.type.base_type.is_cpp_class: arg.generate_result_code(code) code.putln("delete %s;" % arg.result()) # else error reported earlier def annotate(self, code): for arg in self.args: arg.annotate(code) class PassStatNode(StatNode): # pass statement child_attrs = [] def analyse_expressions(self, env): return self def generate_execution_code(self, code): pass class IndirectionNode(StatListNode): """ This adds an indirection so that the node can be shared and a subtree can be removed at any time by clearing self.stats. """ def __init__(self, stats): super(IndirectionNode, self).__init__(stats[0].pos, stats=stats) class BreakStatNode(StatNode): child_attrs = [] is_terminator = True def analyse_expressions(self, env): return self def generate_execution_code(self, code): code.mark_pos(self.pos) if not code.break_label: error(self.pos, "break statement not inside loop") else: code.put_goto(code.break_label) class ContinueStatNode(StatNode): child_attrs = [] is_terminator = True def analyse_expressions(self, env): return self def generate_execution_code(self, code): code.mark_pos(self.pos) if code.funcstate.in_try_finally: error(self.pos, "continue statement inside try of try...finally") elif not code.continue_label: error(self.pos, "continue statement not inside loop") else: code.put_goto(code.continue_label) class ReturnStatNode(StatNode): # return statement # # value ExprNode or None # return_type PyrexType # in_generator return inside of generator => raise StopIteration child_attrs = ["value"] is_terminator = True in_generator = False # Whether we are in a parallel section in_parallel = False def analyse_expressions(self, env): return_type = env.return_type self.return_type = return_type if not return_type: error(self.pos, "Return not inside a function body") return self if self.value: self.value = self.value.analyse_types(env) if return_type.is_void or return_type.is_returncode: error(self.value.pos, "Return with value in void function") else: self.value = self.value.coerce_to(env.return_type, env) else: if (not return_type.is_void and not return_type.is_pyobject and not return_type.is_returncode): error(self.pos, "Return value required") return self def nogil_check(self, env): if self.return_type.is_pyobject: self.gil_error() gil_message = "Returning Python object" def generate_execution_code(self, code): code.mark_pos(self.pos) if not self.return_type: # error reported earlier return if self.return_type.is_pyobject: code.put_xdecref(Naming.retval_cname, self.return_type) if self.value: self.value.generate_evaluation_code(code) if self.return_type.is_memoryviewslice: from . import MemoryView MemoryView.put_acquire_memoryviewslice( lhs_cname=Naming.retval_cname, lhs_type=self.return_type, lhs_pos=self.value.pos, rhs=self.value, code=code, have_gil=self.in_nogil_context) elif self.in_generator: # return value == raise StopIteration(value), but uncatchable code.globalstate.use_utility_code( UtilityCode.load_cached("ReturnWithStopIteration", "Coroutine.c")) code.putln("%s = NULL; __Pyx_ReturnWithStopIteration(%s);" % ( Naming.retval_cname, self.value.py_result())) self.value.generate_disposal_code(code) else: self.value.make_owned_reference(code) code.putln( "%s = %s;" % ( Naming.retval_cname, self.value.result_as(self.return_type))) self.value.generate_post_assignment_code(code) self.value.free_temps(code) else: if self.return_type.is_pyobject: if self.in_generator: code.putln("%s = NULL;" % Naming.retval_cname) else: code.put_init_to_py_none(Naming.retval_cname, self.return_type) elif self.return_type.is_returncode: self.put_return(code, self.return_type.default_value) for cname, type in code.funcstate.temps_holding_reference(): code.put_decref_clear(cname, type) code.put_goto(code.return_label) def put_return(self, code, value): if self.in_parallel: code.putln_openmp("#pragma omp critical(__pyx_returning)") code.putln("%s = %s;" % (Naming.retval_cname, value)) def generate_function_definitions(self, env, code): if self.value is not None: self.value.generate_function_definitions(env, code) def annotate(self, code): if self.value: self.value.annotate(code) class RaiseStatNode(StatNode): # raise statement # # exc_type ExprNode or None # exc_value ExprNode or None # exc_tb ExprNode or None # cause ExprNode or None child_attrs = ["exc_type", "exc_value", "exc_tb", "cause"] is_terminator = True def analyse_expressions(self, env): if self.exc_type: exc_type = self.exc_type.analyse_types(env) self.exc_type = exc_type.coerce_to_pyobject(env) if self.exc_value: exc_value = self.exc_value.analyse_types(env) self.exc_value = exc_value.coerce_to_pyobject(env) if self.exc_tb: exc_tb = self.exc_tb.analyse_types(env) self.exc_tb = exc_tb.coerce_to_pyobject(env) if self.cause: cause = self.cause.analyse_types(env) self.cause = cause.coerce_to_pyobject(env) # special cases for builtin exceptions self.builtin_exc_name = None if self.exc_type and not self.exc_value and not self.exc_tb: exc = self.exc_type from . import ExprNodes if (isinstance(exc, ExprNodes.SimpleCallNode) and not (exc.args or (exc.arg_tuple is not None and exc.arg_tuple.args))): exc = exc.function # extract the exception type if exc.is_name and exc.entry.is_builtin: self.builtin_exc_name = exc.name if self.builtin_exc_name == 'MemoryError': self.exc_type = None # has a separate implementation return self nogil_check = Node.gil_error gil_message = "Raising exception" def generate_execution_code(self, code): code.mark_pos(self.pos) if self.builtin_exc_name == 'MemoryError': code.putln('PyErr_NoMemory(); %s' % code.error_goto(self.pos)) return if self.exc_type: self.exc_type.generate_evaluation_code(code) type_code = self.exc_type.py_result() else: type_code = "0" if self.exc_value: self.exc_value.generate_evaluation_code(code) value_code = self.exc_value.py_result() else: value_code = "0" if self.exc_tb: self.exc_tb.generate_evaluation_code(code) tb_code = self.exc_tb.py_result() else: tb_code = "0" if self.cause: self.cause.generate_evaluation_code(code) cause_code = self.cause.py_result() else: cause_code = "0" code.globalstate.use_utility_code(raise_utility_code) code.putln( "__Pyx_Raise(%s, %s, %s, %s);" % ( type_code, value_code, tb_code, cause_code)) for obj in (self.exc_type, self.exc_value, self.exc_tb, self.cause): if obj: obj.generate_disposal_code(code) obj.free_temps(code) code.putln( code.error_goto(self.pos)) def generate_function_definitions(self, env, code): if self.exc_type is not None: self.exc_type.generate_function_definitions(env, code) if self.exc_value is not None: self.exc_value.generate_function_definitions(env, code) if self.exc_tb is not None: self.exc_tb.generate_function_definitions(env, code) if self.cause is not None: self.cause.generate_function_definitions(env, code) def annotate(self, code): if self.exc_type: self.exc_type.annotate(code) if self.exc_value: self.exc_value.annotate(code) if self.exc_tb: self.exc_tb.annotate(code) if self.cause: self.cause.annotate(code) class ReraiseStatNode(StatNode): child_attrs = [] is_terminator = True def analyse_expressions(self, env): return self nogil_check = Node.gil_error gil_message = "Raising exception" def generate_execution_code(self, code): code.mark_pos(self.pos) vars = code.funcstate.exc_vars if vars: code.globalstate.use_utility_code(restore_exception_utility_code) code.put_giveref(vars[0]) code.put_giveref(vars[1]) # fresh exceptions may not have a traceback yet (-> finally!) code.put_xgiveref(vars[2]) code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars)) for varname in vars: code.put("%s = 0; " % varname) code.putln() code.putln(code.error_goto(self.pos)) else: code.globalstate.use_utility_code( UtilityCode.load_cached("ReRaiseException", "Exceptions.c")) code.putln("__Pyx_ReraiseException(); %s" % code.error_goto(self.pos)) class AssertStatNode(StatNode): # assert statement # # cond ExprNode # value ExprNode or None child_attrs = ["cond", "value"] def analyse_expressions(self, env): self.cond = self.cond.analyse_boolean_expression(env) if self.value: value = self.value.analyse_types(env) if value.type is Builtin.tuple_type or not value.type.is_builtin_type: # prevent tuple values from being interpreted as argument value tuples from .ExprNodes import TupleNode value = TupleNode(value.pos, args=[value], slow=True) self.value = value.analyse_types(env, skip_children=True).coerce_to_pyobject(env) else: self.value = value.coerce_to_pyobject(env) return self nogil_check = Node.gil_error gil_message = "Raising exception" def generate_execution_code(self, code): code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS") code.putln("if (unlikely(!Py_OptimizeFlag)) {") code.mark_pos(self.pos) self.cond.generate_evaluation_code(code) code.putln( "if (unlikely(!%s)) {" % self.cond.result()) if self.value: self.value.generate_evaluation_code(code) code.putln( "PyErr_SetObject(PyExc_AssertionError, %s);" % self.value.py_result()) self.value.generate_disposal_code(code) self.value.free_temps(code) else: code.putln( "PyErr_SetNone(PyExc_AssertionError);") code.putln( code.error_goto(self.pos)) code.putln( "}") self.cond.generate_disposal_code(code) self.cond.free_temps(code) code.putln( "}") code.putln("#endif") def generate_function_definitions(self, env, code): self.cond.generate_function_definitions(env, code) if self.value is not None: self.value.generate_function_definitions(env, code) def annotate(self, code): self.cond.annotate(code) if self.value: self.value.annotate(code) class IfStatNode(StatNode): # if statement # # if_clauses [IfClauseNode] # else_clause StatNode or None child_attrs = ["if_clauses", "else_clause"] def analyse_declarations(self, env): for if_clause in self.if_clauses: if_clause.analyse_declarations(env) if self.else_clause: self.else_clause.analyse_declarations(env) def analyse_expressions(self, env): self.if_clauses = [if_clause.analyse_expressions(env) for if_clause in self.if_clauses] if self.else_clause: self.else_clause = self.else_clause.analyse_expressions(env) return self def generate_execution_code(self, code): code.mark_pos(self.pos) end_label = code.new_label() last = len(self.if_clauses) if not self.else_clause: last -= 1 # avoid redundant goto at end of last if-clause for i, if_clause in enumerate(self.if_clauses): if_clause.generate_execution_code(code, end_label, is_last=i == last) if self.else_clause: code.mark_pos(self.else_clause.pos) code.putln("/*else*/ {") self.else_clause.generate_execution_code(code) code.putln("}") code.put_label(end_label) def generate_function_definitions(self, env, code): for clause in self.if_clauses: clause.generate_function_definitions(env, code) if self.else_clause is not None: self.else_clause.generate_function_definitions(env, code) def annotate(self, code): for if_clause in self.if_clauses: if_clause.annotate(code) if self.else_clause: self.else_clause.annotate(code) class IfClauseNode(Node): # if or elif clause in an if statement # # condition ExprNode # body StatNode child_attrs = ["condition", "body"] def analyse_declarations(self, env): self.body.analyse_declarations(env) def analyse_expressions(self, env): self.condition = self.condition.analyse_temp_boolean_expression(env) self.body = self.body.analyse_expressions(env) return self def generate_execution_code(self, code, end_label, is_last): self.condition.generate_evaluation_code(code) code.mark_pos(self.pos) code.putln("if (%s) {" % self.condition.result()) self.condition.generate_disposal_code(code) self.condition.free_temps(code) self.body.generate_execution_code(code) code.mark_pos(self.pos, trace=False) if not (is_last or self.body.is_terminator): code.put_goto(end_label) code.putln("}") def generate_function_definitions(self, env, code): self.condition.generate_function_definitions(env, code) self.body.generate_function_definitions(env, code) def annotate(self, code): self.condition.annotate(code) self.body.annotate(code) class SwitchCaseNode(StatNode): # Generated in the optimization of an if-elif-else node # # conditions [ExprNode] # body StatNode child_attrs = ['conditions', 'body'] def generate_execution_code(self, code): for cond in self.conditions: code.mark_pos(cond.pos) cond.generate_evaluation_code(code) code.putln("case %s:" % cond.result()) self.body.generate_execution_code(code) code.mark_pos(self.pos, trace=False) code.putln("break;") def generate_function_definitions(self, env, code): for cond in self.conditions: cond.generate_function_definitions(env, code) self.body.generate_function_definitions(env, code) def annotate(self, code): for cond in self.conditions: cond.annotate(code) self.body.annotate(code) class SwitchStatNode(StatNode): # Generated in the optimization of an if-elif-else node # # test ExprNode # cases [SwitchCaseNode] # else_clause StatNode or None child_attrs = ['test', 'cases', 'else_clause'] def generate_execution_code(self, code): self.test.generate_evaluation_code(code) code.mark_pos(self.pos) code.putln("switch (%s) {" % self.test.result()) for case in self.cases: case.generate_execution_code(code) if self.else_clause is not None: code.putln("default:") self.else_clause.generate_execution_code(code) code.putln("break;") else: # Always generate a default clause to prevent C compiler warnings # about unmatched enum values (it was not the user who decided to # generate the switch statement, so shouldn't be bothered). code.putln("default: break;") code.putln("}") def generate_function_definitions(self, env, code): self.test.generate_function_definitions(env, code) for case in self.cases: case.generate_function_definitions(env, code) if self.else_clause is not None: self.else_clause.generate_function_definitions(env, code) def annotate(self, code): self.test.annotate(code) for case in self.cases: case.annotate(code) if self.else_clause is not None: self.else_clause.annotate(code) class LoopNode(object): pass class WhileStatNode(LoopNode, StatNode): # while statement # # condition ExprNode # body StatNode # else_clause StatNode child_attrs = ["condition", "body", "else_clause"] def analyse_declarations(self, env): self.body.analyse_declarations(env) if self.else_clause: self.else_clause.analyse_declarations(env) def analyse_expressions(self, env): if self.condition: self.condition = self.condition.analyse_temp_boolean_expression(env) self.body = self.body.analyse_expressions(env) if self.else_clause: self.else_clause = self.else_clause.analyse_expressions(env) return self def generate_execution_code(self, code): code.mark_pos(self.pos) old_loop_labels = code.new_loop_labels() code.putln( "while (1) {") if self.condition: self.condition.generate_evaluation_code(code) self.condition.generate_disposal_code(code) code.putln( "if (!%s) break;" % self.condition.result()) self.condition.free_temps(code) self.body.generate_execution_code(code) code.put_label(code.continue_label) code.putln("}") break_label = code.break_label code.set_loop_labels(old_loop_labels) if self.else_clause: code.mark_pos(self.else_clause.pos) code.putln("/*else*/ {") self.else_clause.generate_execution_code(code) code.putln("}") code.put_label(break_label) def generate_function_definitions(self, env, code): if self.condition: self.condition.generate_function_definitions(env, code) self.body.generate_function_definitions(env, code) if self.else_clause is not None: self.else_clause.generate_function_definitions(env, code) def annotate(self, code): if self.condition: self.condition.annotate(code) self.body.annotate(code) if self.else_clause: self.else_clause.annotate(code) class DictIterationNextNode(Node): # Helper node for calling PyDict_Next() inside of a WhileStatNode # and checking the dictionary size for changes. Created in # Optimize.py. child_attrs = ['dict_obj', 'expected_size', 'pos_index_var', 'coerced_key_var', 'coerced_value_var', 'coerced_tuple_var', 'key_target', 'value_target', 'tuple_target', 'is_dict_flag'] coerced_key_var = key_ref = None coerced_value_var = value_ref = None coerced_tuple_var = tuple_ref = None def __init__(self, dict_obj, expected_size, pos_index_var, key_target, value_target, tuple_target, is_dict_flag): Node.__init__( self, dict_obj.pos, dict_obj = dict_obj, expected_size = expected_size, pos_index_var = pos_index_var, key_target = key_target, value_target = value_target, tuple_target = tuple_target, is_dict_flag = is_dict_flag, is_temp = True, type = PyrexTypes.c_bint_type) def analyse_expressions(self, env): from . import ExprNodes self.dict_obj = self.dict_obj.analyse_types(env) self.expected_size = self.expected_size.analyse_types(env) if self.pos_index_var: self.pos_index_var = self.pos_index_var.analyse_types(env) if self.key_target: self.key_target = self.key_target.analyse_target_types(env) self.key_ref = ExprNodes.TempNode(self.key_target.pos, PyrexTypes.py_object_type) self.coerced_key_var = self.key_ref.coerce_to(self.key_target.type, env) if self.value_target: self.value_target = self.value_target.analyse_target_types(env) self.value_ref = ExprNodes.TempNode(self.value_target.pos, type=PyrexTypes.py_object_type) self.coerced_value_var = self.value_ref.coerce_to(self.value_target.type, env) if self.tuple_target: self.tuple_target = self.tuple_target.analyse_target_types(env) self.tuple_ref = ExprNodes.TempNode(self.tuple_target.pos, PyrexTypes.py_object_type) self.coerced_tuple_var = self.tuple_ref.coerce_to(self.tuple_target.type, env) self.is_dict_flag = self.is_dict_flag.analyse_types(env) return self def generate_function_definitions(self, env, code): self.dict_obj.generate_function_definitions(env, code) def generate_execution_code(self, code): code.globalstate.use_utility_code(UtilityCode.load_cached("dict_iter", "Optimize.c")) self.dict_obj.generate_evaluation_code(code) assignments = [] temp_addresses = [] for var, result, target in [(self.key_ref, self.coerced_key_var, self.key_target), (self.value_ref, self.coerced_value_var, self.value_target), (self.tuple_ref, self.coerced_tuple_var, self.tuple_target)]: if target is None: addr = 'NULL' else: assignments.append((var, result, target)) var.allocate(code) addr = '&%s' % var.result() temp_addresses.append(addr) result_temp = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False) code.putln("%s = __Pyx_dict_iter_next(%s, %s, &%s, %s, %s, %s, %s);" % ( result_temp, self.dict_obj.py_result(), self.expected_size.result(), self.pos_index_var.result(), temp_addresses[0], temp_addresses[1], temp_addresses[2], self.is_dict_flag.result() )) code.putln("if (unlikely(%s == 0)) break;" % result_temp) code.putln(code.error_goto_if("%s == -1" % result_temp, self.pos)) code.funcstate.release_temp(result_temp) # evaluate all coercions before the assignments for var, result, target in assignments: code.put_gotref(var.result()) for var, result, target in assignments: result.generate_evaluation_code(code) for var, result, target in assignments: target.generate_assignment_code(result, code) var.release(code) def ForStatNode(pos, **kw): if 'iterator' in kw: if kw['iterator'].is_async: return AsyncForStatNode(pos, **kw) else: return ForInStatNode(pos, **kw) else: return ForFromStatNode(pos, **kw) class _ForInStatNode(LoopNode, StatNode): # Base class of 'for-in' statements. # # target ExprNode # iterator IteratorNode | AwaitExprNode(AsyncIteratorNode) # body StatNode # else_clause StatNode # item NextNode | AwaitExprNode(AsyncNextNode) # is_async boolean true for 'async for' statements child_attrs = ["target", "item", "iterator", "body", "else_clause"] item = None is_async = False def _create_item_node(self): raise NotImplementedError("must be implemented by subclasses") def analyse_declarations(self, env): self.target.analyse_target_declaration(env) self.body.analyse_declarations(env) if self.else_clause: self.else_clause.analyse_declarations(env) self._create_item_node() def analyse_expressions(self, env): self.target = self.target.analyse_target_types(env) self.iterator = self.iterator.analyse_expressions(env) self._create_item_node() # must rewrap self.item after analysis self.item = self.item.analyse_expressions(env) if (not self.is_async and (self.iterator.type.is_ptr or self.iterator.type.is_array) and self.target.type.assignable_from(self.iterator.type)): # C array slice optimization. pass else: self.item = self.item.coerce_to(self.target.type, env) self.body = self.body.analyse_expressions(env) if self.else_clause: self.else_clause = self.else_clause.analyse_expressions(env) return self def generate_execution_code(self, code): code.mark_pos(self.pos) old_loop_labels = code.new_loop_labels() self.iterator.generate_evaluation_code(code) code.putln("for (;;) {") self.item.generate_evaluation_code(code) self.target.generate_assignment_code(self.item, code) self.body.generate_execution_code(code) code.mark_pos(self.pos) code.put_label(code.continue_label) code.putln("}") break_label = code.break_label code.set_loop_labels(old_loop_labels) if self.else_clause: # in nested loops, the 'else' block can contain a # 'continue' statement for the outer loop, but we may need # to generate cleanup code before taking that path, so we # intercept it here orig_continue_label = code.continue_label code.continue_label = code.new_label('outer_continue') code.putln("/*else*/ {") self.else_clause.generate_execution_code(code) code.putln("}") if code.label_used(code.continue_label): code.put_goto(break_label) code.mark_pos(self.pos) code.put_label(code.continue_label) self.iterator.generate_disposal_code(code) code.put_goto(orig_continue_label) code.set_loop_labels(old_loop_labels) code.mark_pos(self.pos) if code.label_used(break_label): code.put_label(break_label) self.iterator.generate_disposal_code(code) self.iterator.free_temps(code) def generate_function_definitions(self, env, code): self.target.generate_function_definitions(env, code) self.iterator.generate_function_definitions(env, code) self.body.generate_function_definitions(env, code) if self.else_clause is not None: self.else_clause.generate_function_definitions(env, code) def annotate(self, code): self.target.annotate(code) self.iterator.annotate(code) self.body.annotate(code) if self.else_clause: self.else_clause.annotate(code) self.item.annotate(code) class ForInStatNode(_ForInStatNode): # 'for' statement is_async = False def _create_item_node(self): from .ExprNodes import NextNode self.item = NextNode(self.iterator) class AsyncForStatNode(_ForInStatNode): # 'async for' statement # # iterator AwaitExprNode(AsyncIteratorNode) # item AwaitIterNextExprNode(AsyncIteratorNode) is_async = True def __init__(self, pos, iterator, **kw): assert 'item' not in kw from . import ExprNodes # AwaitExprNodes must appear before running MarkClosureVisitor kw['iterator'] = ExprNodes.AwaitExprNode(iterator.pos, arg=iterator) kw['item'] = ExprNodes.AwaitIterNextExprNode(iterator.pos, arg=None) _ForInStatNode.__init__(self, pos, **kw) def _create_item_node(self): from . import ExprNodes self.item.arg = ExprNodes.AsyncNextNode(self.iterator) class ForFromStatNode(LoopNode, StatNode): # for name from expr rel name rel expr # # target NameNode # bound1 ExprNode # relation1 string # relation2 string # bound2 ExprNode # step ExprNode or None # body StatNode # else_clause StatNode or None # # Used internally: # # from_range bool # is_py_target bool # loopvar_node ExprNode (usually a NameNode or temp node) # py_loopvar_node PyTempNode or None child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"] is_py_target = False loopvar_node = None py_loopvar_node = None from_range = False gil_message = "For-loop using object bounds or target" def nogil_check(self, env): for x in (self.target, self.bound1, self.bound2): if x.type.is_pyobject: self.gil_error() def analyse_declarations(self, env): self.target.analyse_target_declaration(env) self.body.analyse_declarations(env) if self.else_clause: self.else_clause.analyse_declarations(env) def analyse_expressions(self, env): from . import ExprNodes self.target = self.target.analyse_target_types(env) self.bound1 = self.bound1.analyse_types(env) self.bound2 = self.bound2.analyse_types(env) if self.step is not None: if isinstance(self.step, ExprNodes.UnaryMinusNode): warning(self.step.pos, "Probable infinite loop in for-from-by statement. Consider switching the directions of the relations.", 2) self.step = self.step.analyse_types(env) if self.target.type.is_numeric: loop_type = self.target.type else: loop_type = PyrexTypes.c_int_type if not self.bound1.type.is_pyobject: loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type) if not self.bound2.type.is_pyobject: loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type) if self.step is not None and not self.step.type.is_pyobject: loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type) self.bound1 = self.bound1.coerce_to(loop_type, env) self.bound2 = self.bound2.coerce_to(loop_type, env) if not self.bound2.is_literal: self.bound2 = self.bound2.coerce_to_temp(env) if self.step is not None: self.step = self.step.coerce_to(loop_type, env) if not self.step.is_literal: self.step = self.step.coerce_to_temp(env) target_type = self.target.type if not (target_type.is_pyobject or target_type.is_numeric): error(self.target.pos, "for-from loop variable must be c numeric type or Python object") if target_type.is_numeric: self.is_py_target = False if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access: raise error(self.pos, "Buffer indexing not allowed as for loop target.") self.loopvar_node = self.target self.py_loopvar_node = None else: self.is_py_target = True c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env) self.loopvar_node = c_loopvar_node self.py_loopvar_node = \ ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env) self.body = self.body.analyse_expressions(env) if self.else_clause: self.else_clause = self.else_clause.analyse_expressions(env) return self def generate_execution_code(self, code): code.mark_pos(self.pos) old_loop_labels = code.new_loop_labels() from_range = self.from_range self.bound1.generate_evaluation_code(code) self.bound2.generate_evaluation_code(code) offset, incop = self.relation_table[self.relation1] if self.step is not None: self.step.generate_evaluation_code(code) step = self.step.result() incop = "%s=%s" % (incop[0], step) from . import ExprNodes if isinstance(self.loopvar_node, ExprNodes.TempNode): self.loopvar_node.allocate(code) if isinstance(self.py_loopvar_node, ExprNodes.TempNode): self.py_loopvar_node.allocate(code) if from_range: loopvar_name = code.funcstate.allocate_temp(self.target.type, False) else: loopvar_name = self.loopvar_node.result() if self.target.type.is_int and not self.target.type.signed and self.relation2[0] == '>': # Handle the case where the endpoint of an unsigned int iteration # is within step of 0. if not self.step: step = 1 code.putln( "for (%s = %s%s + %s; %s %s %s + %s; ) { %s%s;" % ( loopvar_name, self.bound1.result(), offset, step, loopvar_name, self.relation2, self.bound2.result(), step, loopvar_name, incop)) else: code.putln( "for (%s = %s%s; %s %s %s; %s%s) {" % ( loopvar_name, self.bound1.result(), offset, loopvar_name, self.relation2, self.bound2.result(), loopvar_name, incop)) if self.py_loopvar_node: self.py_loopvar_node.generate_evaluation_code(code) self.target.generate_assignment_code(self.py_loopvar_node, code) elif from_range: code.putln("%s = %s;" % ( self.target.result(), loopvar_name)) self.body.generate_execution_code(code) code.put_label(code.continue_label) if self.py_loopvar_node: # This mess is to make for..from loops with python targets behave # exactly like those with C targets with regards to re-assignment # of the loop variable. if self.target.entry.is_pyglobal: # We know target is a NameNode, this is the only ugly case. target_node = ExprNodes.PyTempNode(self.target.pos, None) target_node.allocate(code) interned_cname = code.intern_identifier(self.target.entry.name) if self.target.entry.scope.is_module_scope: code.globalstate.use_utility_code( UtilityCode.load_cached("GetModuleGlobalName", "ObjectHandling.c")) lookup_func = '__Pyx_GetModuleGlobalName(%s)' else: code.globalstate.use_utility_code( UtilityCode.load_cached("GetNameInClass", "ObjectHandling.c")) lookup_func = '__Pyx_GetNameInClass(%s, %%s)' % ( self.target.entry.scope.namespace_cname) code.putln("%s = %s; %s" % ( target_node.result(), lookup_func % interned_cname, code.error_goto_if_null(target_node.result(), self.target.pos))) code.put_gotref(target_node.result()) else: target_node = self.target from_py_node = ExprNodes.CoerceFromPyTypeNode( self.loopvar_node.type, target_node, self.target.entry.scope) from_py_node.temp_code = loopvar_name from_py_node.generate_result_code(code) if self.target.entry.is_pyglobal: code.put_decref(target_node.result(), target_node.type) target_node.release(code) code.putln("}") if self.py_loopvar_node: # This is potentially wasteful, but we don't want the semantics to # depend on whether or not the loop is a python type. self.py_loopvar_node.generate_evaluation_code(code) self.target.generate_assignment_code(self.py_loopvar_node, code) if from_range: code.funcstate.release_temp(loopvar_name) break_label = code.break_label code.set_loop_labels(old_loop_labels) if self.else_clause: code.putln("/*else*/ {") self.else_clause.generate_execution_code(code) code.putln("}") code.put_label(break_label) self.bound1.generate_disposal_code(code) self.bound1.free_temps(code) self.bound2.generate_disposal_code(code) self.bound2.free_temps(code) if isinstance(self.loopvar_node, ExprNodes.TempNode): self.loopvar_node.release(code) if isinstance(self.py_loopvar_node, ExprNodes.TempNode): self.py_loopvar_node.release(code) if self.step is not None: self.step.generate_disposal_code(code) self.step.free_temps(code) relation_table = { # {relop : (initial offset, increment op)} '<=': ("", "++"), '<' : ("+1", "++"), '>=': ("", "--"), '>' : ("-1", "--") } def generate_function_definitions(self, env, code): self.target.generate_function_definitions(env, code) self.bound1.generate_function_definitions(env, code) self.bound2.generate_function_definitions(env, code) if self.step is not None: self.step.generate_function_definitions(env, code) self.body.generate_function_definitions(env, code) if self.else_clause is not None: self.else_clause.generate_function_definitions(env, code) def annotate(self, code): self.target.annotate(code) self.bound1.annotate(code) self.bound2.annotate(code) if self.step: self.step.annotate(code) self.body.annotate(code) if self.else_clause: self.else_clause.annotate(code) class WithStatNode(StatNode): """ Represents a Python with statement. Implemented by the WithTransform as follows: MGR = EXPR EXIT = MGR.__exit__ VALUE = MGR.__enter__() EXC = True try: try: TARGET = VALUE # optional BODY except: EXC = False if not EXIT(*EXCINFO): raise finally: if EXC: EXIT(None, None, None) MGR = EXIT = VALUE = None """ # manager The with statement manager object # target ExprNode the target lhs of the __enter__() call # body StatNode # enter_call ExprNode the call to the __enter__() method # exit_var String the cname of the __exit__() method reference child_attrs = ["manager", "enter_call", "target", "body"] enter_call = None target_temp = None def analyse_declarations(self, env): self.manager.analyse_declarations(env) self.enter_call.analyse_declarations(env) self.body.analyse_declarations(env) def analyse_expressions(self, env): self.manager = self.manager.analyse_types(env) self.enter_call = self.enter_call.analyse_types(env) if self.target: # set up target_temp before descending into body (which uses it) from .ExprNodes import TempNode self.target_temp = TempNode(self.enter_call.pos, self.enter_call.type) self.body = self.body.analyse_expressions(env) return self def generate_function_definitions(self, env, code): self.manager.generate_function_definitions(env, code) self.enter_call.generate_function_definitions(env, code) self.body.generate_function_definitions(env, code) def generate_execution_code(self, code): code.mark_pos(self.pos) code.putln("/*with:*/ {") self.manager.generate_evaluation_code(code) self.exit_var = code.funcstate.allocate_temp(py_object_type, manage_ref=False) code.globalstate.use_utility_code( UtilityCode.load_cached("PyObjectLookupSpecial", "ObjectHandling.c")) code.putln("%s = __Pyx_PyObject_LookupSpecial(%s, %s); %s" % ( self.exit_var, self.manager.py_result(), code.intern_identifier(EncodedString('__aexit__' if self.is_async else '__exit__')), code.error_goto_if_null(self.exit_var, self.pos), )) code.put_gotref(self.exit_var) # need to free exit_var in the face of exceptions during setup old_error_label = code.new_error_label() intermediate_error_label = code.error_label self.enter_call.generate_evaluation_code(code) if self.target: # The temp result will be cleaned up by the WithTargetAssignmentStatNode # after assigning its result to the target of the 'with' statement. self.target_temp.allocate(code) self.enter_call.make_owned_reference(code) code.putln("%s = %s;" % (self.target_temp.result(), self.enter_call.result())) self.enter_call.generate_post_assignment_code(code) else: self.enter_call.generate_disposal_code(code) self.enter_call.free_temps(code) self.manager.generate_disposal_code(code) self.manager.free_temps(code) code.error_label = old_error_label self.body.generate_execution_code(code) if code.label_used(intermediate_error_label): step_over_label = code.new_label() code.put_goto(step_over_label) code.put_label(intermediate_error_label) code.put_decref_clear(self.exit_var, py_object_type) code.put_goto(old_error_label) code.put_label(step_over_label) code.funcstate.release_temp(self.exit_var) code.putln('}') class WithTargetAssignmentStatNode(AssignmentNode): # The target assignment of the 'with' statement value (return # value of the __enter__() call). # # This is a special cased assignment that properly cleans up the RHS. # # lhs ExprNode the assignment target # rhs ExprNode a (coerced) TempNode for the rhs (from WithStatNode) # with_node WithStatNode the surrounding with-statement child_attrs = ["rhs", "lhs"] with_node = None rhs = None def analyse_declarations(self, env): self.lhs.analyse_target_declaration(env) def analyse_expressions(self, env): self.lhs = self.lhs.analyse_target_types(env) self.lhs.gil_assignment_check(env) self.rhs = self.with_node.target_temp.coerce_to(self.lhs.type, env) return self def generate_execution_code(self, code): self.rhs.generate_evaluation_code(code) self.lhs.generate_assignment_code(self.rhs, code) self.with_node.target_temp.release(code) def annotate(self, code): self.lhs.annotate(code) self.rhs.annotate(code) class TryExceptStatNode(StatNode): # try .. except statement # # body StatNode # except_clauses [ExceptClauseNode] # else_clause StatNode or None child_attrs = ["body", "except_clauses", "else_clause"] def analyse_declarations(self, env): self.body.analyse_declarations(env) for except_clause in self.except_clauses: except_clause.analyse_declarations(env) if self.else_clause: self.else_clause.analyse_declarations(env) def analyse_expressions(self, env): self.body = self.body.analyse_expressions(env) default_clause_seen = 0 for i, except_clause in enumerate(self.except_clauses): except_clause = self.except_clauses[i] = except_clause.analyse_expressions(env) if default_clause_seen: error(except_clause.pos, "default 'except:' must be last") if not except_clause.pattern: default_clause_seen = 1 self.has_default_clause = default_clause_seen if self.else_clause: self.else_clause = self.else_clause.analyse_expressions(env) return self nogil_check = Node.gil_error gil_message = "Try-except statement" def generate_execution_code(self, code): old_return_label = code.return_label old_break_label = code.break_label old_continue_label = code.continue_label old_error_label = code.new_error_label() our_error_label = code.error_label except_end_label = code.new_label('exception_handled') except_error_label = code.new_label('except_error') except_return_label = code.new_label('except_return') try_return_label = code.new_label('try_return') try_break_label = code.new_label('try_break') try_continue_label = code.new_label('try_continue') try_end_label = code.new_label('try_end') exc_save_vars = [code.funcstate.allocate_temp(py_object_type, False) for _ in range(3)] code.mark_pos(self.pos) code.putln("{") save_exc = code.insertion_point() code.putln( "/*try:*/ {") code.return_label = try_return_label code.break_label = try_break_label code.continue_label = try_continue_label self.body.generate_execution_code(code) code.mark_pos(self.pos, trace=False) code.putln( "}") temps_to_clean_up = code.funcstate.all_free_managed_temps() can_raise = code.label_used(our_error_label) if can_raise: # inject code before the try block to save away the exception state code.globalstate.use_utility_code(reset_exception_utility_code) save_exc.putln("__Pyx_ExceptionSave(%s);" % ', '.join(['&%s' % var for var in exc_save_vars])) for var in exc_save_vars: save_exc.put_xgotref(var) def restore_saved_exception(): for name in exc_save_vars: code.put_xgiveref(name) code.putln("__Pyx_ExceptionReset(%s);" % ', '.join(exc_save_vars)) else: # try block cannot raise exceptions, but we had to allocate the temps above, # so just keep the C compiler from complaining about them being unused save_exc.putln("if (%s); else {/*mark used*/}" % '||'.join(exc_save_vars)) def restore_saved_exception(): pass code.error_label = except_error_label code.return_label = except_return_label normal_case_terminates = self.body.is_terminator if self.else_clause: code.mark_pos(self.else_clause.pos) code.putln( "/*else:*/ {") self.else_clause.generate_execution_code(code) code.putln( "}") if not normal_case_terminates: normal_case_terminates = self.else_clause.is_terminator if can_raise: if not normal_case_terminates: for var in exc_save_vars: code.put_xdecref_clear(var, py_object_type) code.put_goto(try_end_label) code.put_label(our_error_label) for temp_name, temp_type in temps_to_clean_up: code.put_xdecref_clear(temp_name, temp_type) for except_clause in self.except_clauses: except_clause.generate_handling_code(code, except_end_label) if not self.has_default_clause: code.put_goto(except_error_label) for exit_label, old_label in [(except_error_label, old_error_label), (try_break_label, old_break_label), (try_continue_label, old_continue_label), (try_return_label, old_return_label), (except_return_label, old_return_label)]: if code.label_used(exit_label): if not normal_case_terminates and not code.label_used(try_end_label): code.put_goto(try_end_label) code.put_label(exit_label) code.mark_pos(self.pos, trace=False) restore_saved_exception() code.put_goto(old_label) if code.label_used(except_end_label): if not normal_case_terminates and not code.label_used(try_end_label): code.put_goto(try_end_label) code.put_label(except_end_label) restore_saved_exception() if code.label_used(try_end_label): code.put_label(try_end_label) code.putln("}") for cname in exc_save_vars: code.funcstate.release_temp(cname) code.return_label = old_return_label code.break_label = old_break_label code.continue_label = old_continue_label code.error_label = old_error_label def generate_function_definitions(self, env, code): self.body.generate_function_definitions(env, code) for except_clause in self.except_clauses: except_clause.generate_function_definitions(env, code) if self.else_clause is not None: self.else_clause.generate_function_definitions(env, code) def annotate(self, code): self.body.annotate(code) for except_node in self.except_clauses: except_node.annotate(code) if self.else_clause: self.else_clause.annotate(code) class ExceptClauseNode(Node): # Part of try ... except statement. # # pattern [ExprNode] # target ExprNode or None # body StatNode # excinfo_target TupleNode(3*ResultRefNode) or None optional target for exception info (not owned here!) # match_flag string result of exception match # exc_value ExcValueNode used internally # function_name string qualified name of enclosing function # exc_vars (string * 3) local exception variables # is_except_as bool Py3-style "except ... as xyz" # excinfo_target is never set by the parser, but can be set by a transform # in order to extract more extensive information about the exception as a # sys.exc_info()-style tuple into a target variable child_attrs = ["pattern", "target", "body", "exc_value"] exc_value = None excinfo_target = None is_except_as = False def analyse_declarations(self, env): if self.target: self.target.analyse_target_declaration(env) self.body.analyse_declarations(env) def analyse_expressions(self, env): self.function_name = env.qualified_name if self.pattern: # normalise/unpack self.pattern into a list for i, pattern in enumerate(self.pattern): pattern = pattern.analyse_expressions(env) self.pattern[i] = pattern.coerce_to_pyobject(env) if self.target: from . import ExprNodes self.exc_value = ExprNodes.ExcValueNode(self.pos) self.target = self.target.analyse_target_expression(env, self.exc_value) self.body = self.body.analyse_expressions(env) return self def generate_handling_code(self, code, end_label): code.mark_pos(self.pos) if self.pattern: exc_tests = [] for pattern in self.pattern: pattern.generate_evaluation_code(code) exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result()) match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False) code.putln( "%s = %s;" % (match_flag, ' || '.join(exc_tests))) for pattern in self.pattern: pattern.generate_disposal_code(code) pattern.free_temps(code) code.putln( "if (%s) {" % match_flag) code.funcstate.release_temp(match_flag) else: code.putln("/*except:*/ {") if (not getattr(self.body, 'stats', True) and self.excinfo_target is None and self.target is None): # most simple case: no exception variable, empty body (pass) # => reset the exception state, done code.putln("PyErr_Restore(0,0,0);") code.put_goto(end_label) code.putln("}") return exc_vars = [code.funcstate.allocate_temp(py_object_type, manage_ref=True) for _ in range(3)] code.put_add_traceback(self.function_name) # We always have to fetch the exception value even if # there is no target, because this also normalises the # exception and stores it in the thread state. code.globalstate.use_utility_code(get_exception_utility_code) exc_args = "&%s, &%s, &%s" % tuple(exc_vars) code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args, code.error_goto(self.pos))) for x in exc_vars: code.put_gotref(x) if self.target: self.exc_value.set_var(exc_vars[1]) self.exc_value.generate_evaluation_code(code) self.target.generate_assignment_code(self.exc_value, code) if self.excinfo_target is not None: for tempvar, node in zip(exc_vars, self.excinfo_target.args): node.set_var(tempvar) old_break_label, old_continue_label = code.break_label, code.continue_label code.break_label = code.new_label('except_break') code.continue_label = code.new_label('except_continue') old_exc_vars = code.funcstate.exc_vars code.funcstate.exc_vars = exc_vars self.body.generate_execution_code(code) code.funcstate.exc_vars = old_exc_vars if not self.body.is_terminator: for var in exc_vars: code.put_decref_clear(var, py_object_type) code.put_goto(end_label) for new_label, old_label in [(code.break_label, old_break_label), (code.continue_label, old_continue_label)]: if code.label_used(new_label): code.put_label(new_label) for var in exc_vars: code.put_decref_clear(var, py_object_type) code.put_goto(old_label) code.break_label = old_break_label code.continue_label = old_continue_label for temp in exc_vars: code.funcstate.release_temp(temp) code.putln( "}") def generate_function_definitions(self, env, code): if self.target is not None: self.target.generate_function_definitions(env, code) self.body.generate_function_definitions(env, code) def annotate(self, code): if self.pattern: for pattern in self.pattern: pattern.annotate(code) if self.target: self.target.annotate(code) self.body.annotate(code) class TryFinallyStatNode(StatNode): # try ... finally statement # # body StatNode # finally_clause StatNode # finally_except_clause deep-copy of finally_clause for exception case # # The plan is that we funnel all continue, break # return and error gotos into the beginning of the # finally block, setting a variable to remember which # one we're doing. At the end of the finally block, we # switch on the variable to figure out where to go. # In addition, if we're doing an error, we save the # exception on entry to the finally block and restore # it on exit. child_attrs = ["body", "finally_clause", "finally_except_clause"] preserve_exception = 1 # handle exception case, in addition to return/break/continue handle_error_case = True func_return_type = None finally_except_clause = None disallow_continue_in_try_finally = 0 # There doesn't seem to be any point in disallowing # continue in the try block, since we have no problem # handling it. is_try_finally_in_nogil = False @staticmethod def create_analysed(pos, env, body, finally_clause): node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause) return node def analyse_declarations(self, env): self.body.analyse_declarations(env) self.finally_except_clause = copy.deepcopy(self.finally_clause) self.finally_except_clause.analyse_declarations(env) self.finally_clause.analyse_declarations(env) def analyse_expressions(self, env): self.body = self.body.analyse_expressions(env) self.finally_clause = self.finally_clause.analyse_expressions(env) self.finally_except_clause = self.finally_except_clause.analyse_expressions(env) if env.return_type and not env.return_type.is_void: self.func_return_type = env.return_type return self nogil_check = Node.gil_error gil_message = "Try-finally statement" def generate_execution_code(self, code): code.mark_pos(self.pos) old_error_label = code.error_label old_labels = code.all_new_labels() new_labels = code.get_all_labels() new_error_label = code.error_label if not self.handle_error_case: code.error_label = old_error_label catch_label = code.new_label() code.putln("/*try:*/ {") if self.disallow_continue_in_try_finally: was_in_try_finally = code.funcstate.in_try_finally code.funcstate.in_try_finally = 1 self.body.generate_execution_code(code) if self.disallow_continue_in_try_finally: code.funcstate.in_try_finally = was_in_try_finally code.putln("}") code.set_all_labels(old_labels) temps_to_clean_up = code.funcstate.all_free_managed_temps() code.mark_pos(self.finally_clause.pos) code.putln("/*finally:*/ {") def fresh_finally_clause(_next=[self.finally_clause]): # generate the original subtree once and always keep a fresh copy node = _next[0] node_copy = copy.deepcopy(node) if node is self.finally_clause: _next[0] = node_copy else: node = node_copy return node preserve_error = self.preserve_exception and code.label_used(new_error_label) needs_success_cleanup = not self.finally_clause.is_terminator if not self.body.is_terminator: code.putln('/*normal exit:*/{') fresh_finally_clause().generate_execution_code(code) if not self.finally_clause.is_terminator: code.put_goto(catch_label) code.putln('}') if preserve_error: code.putln('/*exception exit:*/{') if self.is_try_finally_in_nogil: code.declare_gilstate() if needs_success_cleanup: exc_lineno_cnames = tuple([ code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False) for _ in range(2)]) exc_filename_cname = code.funcstate.allocate_temp( PyrexTypes.CPtrType(PyrexTypes.c_const_type(PyrexTypes.c_char_type)), manage_ref=False) else: exc_lineno_cnames = exc_filename_cname = None exc_vars = tuple([ code.funcstate.allocate_temp(py_object_type, manage_ref=False) for _ in range(6)]) code.put_label(new_error_label) self.put_error_catcher( code, temps_to_clean_up, exc_vars, exc_lineno_cnames, exc_filename_cname) finally_old_labels = code.all_new_labels() code.putln('{') old_exc_vars = code.funcstate.exc_vars code.funcstate.exc_vars = exc_vars[:3] self.finally_except_clause.generate_execution_code(code) code.funcstate.exc_vars = old_exc_vars code.putln('}') if needs_success_cleanup: self.put_error_uncatcher(code, exc_vars, exc_lineno_cnames, exc_filename_cname) if exc_lineno_cnames: for cname in exc_lineno_cnames: code.funcstate.release_temp(cname) if exc_filename_cname: code.funcstate.release_temp(exc_filename_cname) code.put_goto(old_error_label) for new_label, old_label in zip(code.get_all_labels(), finally_old_labels): if not code.label_used(new_label): continue code.put_label(new_label) self.put_error_cleaner(code, exc_vars) code.put_goto(old_label) for cname in exc_vars: code.funcstate.release_temp(cname) code.putln('}') code.set_all_labels(old_labels) return_label = code.return_label for i, (new_label, old_label) in enumerate(zip(new_labels, old_labels)): if not code.label_used(new_label): continue if new_label == new_error_label and preserve_error: continue # handled above code.put('%s: ' % new_label) code.putln('{') ret_temp = None if old_label == return_label and not self.finally_clause.is_terminator: # store away return value for later reuse if (self.func_return_type and not self.is_try_finally_in_nogil and not isinstance(self.finally_clause, GILExitNode)): ret_temp = code.funcstate.allocate_temp( self.func_return_type, manage_ref=False) code.putln("%s = %s;" % (ret_temp, Naming.retval_cname)) if self.func_return_type.is_pyobject: code.putln("%s = 0;" % Naming.retval_cname) fresh_finally_clause().generate_execution_code(code) if ret_temp: code.putln("%s = %s;" % (Naming.retval_cname, ret_temp)) if self.func_return_type.is_pyobject: code.putln("%s = 0;" % ret_temp) code.funcstate.release_temp(ret_temp) ret_temp = None if not self.finally_clause.is_terminator: code.put_goto(old_label) code.putln('}') # End finally code.put_label(catch_label) code.putln( "}") def generate_function_definitions(self, env, code): self.body.generate_function_definitions(env, code) self.finally_clause.generate_function_definitions(env, code) def put_error_catcher(self, code, temps_to_clean_up, exc_vars, exc_lineno_cnames, exc_filename_cname): code.globalstate.use_utility_code(restore_exception_utility_code) code.globalstate.use_utility_code(get_exception_utility_code) code.globalstate.use_utility_code(swap_exception_utility_code) code.putln(' '.join(["%s = 0;"]*len(exc_vars)) % exc_vars) if self.is_try_finally_in_nogil: code.put_ensure_gil(declare_gilstate=False) for temp_name, type in temps_to_clean_up: code.put_xdecref_clear(temp_name, type) # not using preprocessor here to avoid warnings about # unused utility functions and/or temps code.putln("if (PY_MAJOR_VERSION >= 3)" " __Pyx_ExceptionSwap(&%s, &%s, &%s);" % exc_vars[3:]) code.putln("if ((PY_MAJOR_VERSION < 3) ||" # if __Pyx_GetException() fails in Py3, # store the newly raised exception instead " unlikely(__Pyx_GetException(&%s, &%s, &%s) < 0)) " "__Pyx_ErrFetch(&%s, &%s, &%s);" % (exc_vars[:3] * 2)) for var in exc_vars: code.put_xgotref(var) if exc_lineno_cnames: code.putln("%s = %s; %s = %s; %s = %s;" % ( exc_lineno_cnames[0], Naming.lineno_cname, exc_lineno_cnames[1], Naming.clineno_cname, exc_filename_cname, Naming.filename_cname)) if self.is_try_finally_in_nogil: code.put_release_ensured_gil() def put_error_uncatcher(self, code, exc_vars, exc_lineno_cnames, exc_filename_cname): code.globalstate.use_utility_code(restore_exception_utility_code) code.globalstate.use_utility_code(reset_exception_utility_code) if self.is_try_finally_in_nogil: code.put_ensure_gil(declare_gilstate=False) # not using preprocessor here to avoid warnings about # unused utility functions and/or temps code.putln("if (PY_MAJOR_VERSION >= 3) {") for var in exc_vars[3:]: code.put_xgiveref(var) code.putln("__Pyx_ExceptionReset(%s, %s, %s);" % exc_vars[3:]) code.putln("}") for var in exc_vars[:3]: code.put_xgiveref(var) code.putln("__Pyx_ErrRestore(%s, %s, %s);" % exc_vars[:3]) if self.is_try_finally_in_nogil: code.put_release_ensured_gil() code.putln(' '.join(["%s = 0;"]*len(exc_vars)) % exc_vars) if exc_lineno_cnames: code.putln("%s = %s; %s = %s; %s = %s;" % ( Naming.lineno_cname, exc_lineno_cnames[0], Naming.clineno_cname, exc_lineno_cnames[1], Naming.filename_cname, exc_filename_cname)) def put_error_cleaner(self, code, exc_vars): code.globalstate.use_utility_code(reset_exception_utility_code) if self.is_try_finally_in_nogil: code.put_ensure_gil(declare_gilstate=False) # not using preprocessor here to avoid warnings about # unused utility functions and/or temps code.putln("if (PY_MAJOR_VERSION >= 3) {") for var in exc_vars[3:]: code.put_xgiveref(var) code.putln("__Pyx_ExceptionReset(%s, %s, %s);" % exc_vars[3:]) code.putln("}") for var in exc_vars[:3]: code.put_xdecref_clear(var, py_object_type) if self.is_try_finally_in_nogil: code.put_release_ensured_gil() code.putln(' '.join(["%s = 0;"]*3) % exc_vars[3:]) def annotate(self, code): self.body.annotate(code) self.finally_clause.annotate(code) class NogilTryFinallyStatNode(TryFinallyStatNode): """ A try/finally statement that may be used in nogil code sections. """ preserve_exception = False nogil_check = None class GILStatNode(NogilTryFinallyStatNode): # 'with gil' or 'with nogil' statement # # state string 'gil' or 'nogil' state_temp = None def __init__(self, pos, state, body): self.state = state self.create_state_temp_if_needed(pos, state, body) TryFinallyStatNode.__init__(self, pos, body=body, finally_clause=GILExitNode( pos, state=state, state_temp=self.state_temp)) def create_state_temp_if_needed(self, pos, state, body): from .ParseTreeTransforms import YieldNodeCollector collector = YieldNodeCollector() collector.visitchildren(body) if not collector.yields and not collector.awaits: return if state == 'gil': temp_type = PyrexTypes.c_gilstate_type else: temp_type = PyrexTypes.c_threadstate_ptr_type from . import ExprNodes self.state_temp = ExprNodes.TempNode(pos, temp_type) def analyse_declarations(self, env): env._in_with_gil_block = (self.state == 'gil') if self.state == 'gil': env.has_with_gil_block = True return super(GILStatNode, self).analyse_declarations(env) def analyse_expressions(self, env): env.use_utility_code( UtilityCode.load_cached("ForceInitThreads", "ModuleSetupCode.c")) was_nogil = env.nogil env.nogil = self.state == 'nogil' node = TryFinallyStatNode.analyse_expressions(self, env) env.nogil = was_nogil return node def generate_execution_code(self, code): code.mark_pos(self.pos) code.begin_block() if self.state_temp: self.state_temp.allocate(code) variable = self.state_temp.result() else: variable = None old_gil_config = code.funcstate.gil_owned if self.state == 'gil': code.put_ensure_gil(variable=variable) code.funcstate.gil_owned = True else: code.put_release_gil(variable=variable) code.funcstate.gil_owned = False TryFinallyStatNode.generate_execution_code(self, code) if self.state_temp: self.state_temp.release(code) code.funcstate.gil_owned = old_gil_config code.end_block() class GILExitNode(StatNode): """ Used as the 'finally' block in a GILStatNode state string 'gil' or 'nogil' """ child_attrs = [] state_temp = None def analyse_expressions(self, env): return self def generate_execution_code(self, code): if self.state_temp: variable = self.state_temp.result() else: variable = None if self.state == 'gil': code.put_release_ensured_gil(variable) else: code.put_acquire_gil(variable) class EnsureGILNode(GILExitNode): """ Ensure the GIL in nogil functions for cleanup before returning. """ def generate_execution_code(self, code): code.put_ensure_gil(declare_gilstate=False) utility_code_for_cimports = { # utility code (or inlining c) in a pxd (or pyx) file. # TODO: Consider a generic user-level mechanism for importing 'cpython.array' : ("ArrayAPI", "arrayarray.h"), 'cpython.array.array' : ("ArrayAPI", "arrayarray.h"), } utility_code_for_imports = { # utility code used when special modules are imported. # TODO: Consider a generic user-level mechanism for importing 'asyncio': ("__Pyx_patch_asyncio", "PatchAsyncIO", "Coroutine.c"), 'inspect': ("__Pyx_patch_inspect", "PatchInspect", "Coroutine.c"), } class CImportStatNode(StatNode): # cimport statement # # module_name string Qualified name of module being imported # as_name string or None Name specified in "as" clause, if any # is_absolute bool True for absolute imports, False otherwise child_attrs = [] is_absolute = False def analyse_declarations(self, env): if not env.is_module_scope: error(self.pos, "cimport only allowed at module level") return module_scope = env.find_module( self.module_name, self.pos, relative_level=0 if self.is_absolute else -1) if "." in self.module_name: names = [EncodedString(name) for name in self.module_name.split(".")] top_name = names[0] top_module_scope = env.context.find_submodule(top_name) module_scope = top_module_scope for name in names[1:]: submodule_scope = module_scope.find_submodule(name) module_scope.declare_module(name, submodule_scope, self.pos) module_scope = submodule_scope if self.as_name: env.declare_module(self.as_name, module_scope, self.pos) else: env.add_imported_module(module_scope) env.declare_module(top_name, top_module_scope, self.pos) else: name = self.as_name or self.module_name env.declare_module(name, module_scope, self.pos) if self.module_name in utility_code_for_cimports: env.use_utility_code(UtilityCode.load_cached( *utility_code_for_cimports[self.module_name])) def analyse_expressions(self, env): return self def generate_execution_code(self, code): pass class FromCImportStatNode(StatNode): # from ... cimport statement # # module_name string Qualified name of module # relative_level int or None Relative import: number of dots before module_name # imported_names [(pos, name, as_name, kind)] Names to be imported child_attrs = [] module_name = None relative_level = None imported_names = None def analyse_declarations(self, env): if not env.is_module_scope: error(self.pos, "cimport only allowed at module level") return if self.relative_level and self.relative_level > env.qualified_name.count('.'): error(self.pos, "relative cimport beyond main package is not allowed") return module_scope = env.find_module(self.module_name, self.pos, relative_level=self.relative_level) module_name = module_scope.qualified_name env.add_imported_module(module_scope) for pos, name, as_name, kind in self.imported_names: if name == "*": for local_name, entry in list(module_scope.entries.items()): env.add_imported_entry(local_name, entry, pos) else: entry = module_scope.lookup(name) if entry: if kind and not self.declaration_matches(entry, kind): entry.redeclared(pos) entry.used = 1 else: if kind == 'struct' or kind == 'union': entry = module_scope.declare_struct_or_union( name, kind=kind, scope=None, typedef_flag=0, pos=pos) elif kind == 'class': entry = module_scope.declare_c_class(name, pos=pos, module_name=module_name) else: submodule_scope = env.context.find_module( name, relative_to=module_scope, pos=self.pos, absolute_fallback=False) if submodule_scope.parent_module is module_scope: env.declare_module(as_name or name, submodule_scope, self.pos) else: error(pos, "Name '%s' not declared in module '%s'" % (name, module_name)) if entry: local_name = as_name or name env.add_imported_entry(local_name, entry, pos) if module_name.startswith('cpython'): # enough for now if module_name in utility_code_for_cimports: env.use_utility_code(UtilityCode.load_cached( *utility_code_for_cimports[module_name])) for _, name, _, _ in self.imported_names: fqname = '%s.%s' % (module_name, name) if fqname in utility_code_for_cimports: env.use_utility_code(UtilityCode.load_cached( *utility_code_for_cimports[fqname])) def declaration_matches(self, entry, kind): if not entry.is_type: return 0 type = entry.type if kind == 'class': if not type.is_extension_type: return 0 else: if not type.is_struct_or_union: return 0 if kind != type.kind: return 0 return 1 def analyse_expressions(self, env): return self def generate_execution_code(self, code): pass class FromImportStatNode(StatNode): # from ... import statement # # module ImportNode # items [(string, NameNode)] # interned_items [(string, NameNode, ExprNode)] # item PyTempNode used internally # import_star boolean used internally child_attrs = ["module"] import_star = 0 def analyse_declarations(self, env): for name, target in self.items: if name == "*": if not env.is_module_scope: error(self.pos, "import * only allowed at module level") return env.has_import_star = 1 self.import_star = 1 else: target.analyse_target_declaration(env) def analyse_expressions(self, env): from . import ExprNodes self.module = self.module.analyse_expressions(env) self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type) self.interned_items = [] for name, target in self.items: if name == '*': for _, entry in env.entries.items(): if not entry.is_type and entry.type.is_extension_type: env.use_utility_code(UtilityCode.load_cached("ExtTypeTest", "ObjectHandling.c")) break else: entry = env.lookup(target.name) # check whether or not entry is already cimported if (entry.is_type and entry.type.name == name and hasattr(entry.type, 'module_name')): if entry.type.module_name == self.module.module_name.value: # cimported with absolute name continue try: # cimported with relative name module = env.find_module(self.module.module_name.value, pos=self.pos, relative_level=self.module.level) if entry.type.module_name == module.qualified_name: continue except AttributeError: pass target = target.analyse_target_expression(env, None) # FIXME? if target.type is py_object_type: coerced_item = None else: coerced_item = self.item.coerce_to(target.type, env) self.interned_items.append((name, target, coerced_item)) return self def generate_execution_code(self, code): code.mark_pos(self.pos) self.module.generate_evaluation_code(code) if self.import_star: code.putln( 'if (%s(%s) < 0) %s;' % ( Naming.import_star, self.module.py_result(), code.error_goto(self.pos))) item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True) self.item.set_cname(item_temp) if self.interned_items: code.globalstate.use_utility_code( UtilityCode.load_cached("ImportFrom", "ImportExport.c")) for name, target, coerced_item in self.interned_items: code.putln( '%s = __Pyx_ImportFrom(%s, %s); %s' % ( item_temp, self.module.py_result(), code.intern_identifier(name), code.error_goto_if_null(item_temp, self.pos))) code.put_gotref(item_temp) if coerced_item is None: target.generate_assignment_code(self.item, code) else: coerced_item.allocate_temp_result(code) coerced_item.generate_result_code(code) target.generate_assignment_code(coerced_item, code) code.put_decref_clear(item_temp, py_object_type) code.funcstate.release_temp(item_temp) self.module.generate_disposal_code(code) self.module.free_temps(code) class ParallelNode(Node): """ Base class for cython.parallel constructs. """ nogil_check = None class ParallelStatNode(StatNode, ParallelNode): """ Base class for 'with cython.parallel.parallel():' and 'for i in prange():'. assignments { Entry(var) : (var.pos, inplace_operator_or_None) } assignments to variables in this parallel section parent parent ParallelStatNode or None is_parallel indicates whether this node is OpenMP parallel (true for #pragma omp parallel for and #pragma omp parallel) is_parallel is true for: #pragma omp parallel #pragma omp parallel for sections, but NOT for #pragma omp for We need this to determine the sharing attributes. privatization_insertion_point a code insertion point used to make temps private (esp. the "nsteps" temp) args tuple the arguments passed to the parallel construct kwargs DictNode the keyword arguments passed to the parallel construct (replaced by its compile time value) """ child_attrs = ['body', 'num_threads'] body = None is_prange = False is_nested_prange = False error_label_used = False num_threads = None chunksize = None parallel_exc = ( Naming.parallel_exc_type, Naming.parallel_exc_value, Naming.parallel_exc_tb, ) parallel_pos_info = ( Naming.parallel_filename, Naming.parallel_lineno, Naming.parallel_clineno, ) pos_info = ( Naming.filename_cname, Naming.lineno_cname, Naming.clineno_cname, ) critical_section_counter = 0 def __init__(self, pos, **kwargs): super(ParallelStatNode, self).__init__(pos, **kwargs) # All assignments in this scope self.assignments = kwargs.get('assignments') or {} # All seen closure cnames and their temporary cnames self.seen_closure_vars = set() # Dict of variables that should be declared (first|last|)private or # reduction { Entry: (op, lastprivate) }. # If op is not None, it's a reduction. self.privates = {} # [NameNode] self.assigned_nodes = [] def analyse_declarations(self, env): self.body.analyse_declarations(env) self.num_threads = None if self.kwargs: # Try to find num_threads and chunksize keyword arguments pairs = [] for dictitem in self.kwargs.key_value_pairs: if dictitem.key.value == 'num_threads': self.num_threads = dictitem.value elif self.is_prange and dictitem.key.value == 'chunksize': self.chunksize = dictitem.value else: pairs.append(dictitem) self.kwargs.key_value_pairs = pairs try: self.kwargs = self.kwargs.compile_time_value(env) except Exception as e: error(self.kwargs.pos, "Only compile-time values may be " "supplied as keyword arguments") else: self.kwargs = {} for kw, val in self.kwargs.items(): if kw not in self.valid_keyword_arguments: error(self.pos, "Invalid keyword argument: %s" % kw) else: setattr(self, kw, val) def analyse_expressions(self, env): if self.num_threads: self.num_threads = self.num_threads.analyse_expressions(env) if self.chunksize: self.chunksize = self.chunksize.analyse_expressions(env) self.body = self.body.analyse_expressions(env) self.analyse_sharing_attributes(env) if self.num_threads is not None: if (self.parent and self.parent.num_threads is not None and not self.parent.is_prange): error(self.pos, "num_threads already declared in outer section") elif self.parent and not self.parent.is_prange: error(self.pos, "num_threads must be declared in the parent parallel section") elif (self.num_threads.type.is_int and self.num_threads.is_literal and self.num_threads.compile_time_value(env) <= 0): error(self.pos, "argument to num_threads must be greater than 0") if not self.num_threads.is_simple(): self.num_threads = self.num_threads.coerce_to( PyrexTypes.c_int_type, env).coerce_to_temp(env) return self def analyse_sharing_attributes(self, env): """ Analyse the privates for this block and set them in self.privates. This should be called in a post-order fashion during the analyse_expressions phase """ for entry, (pos, op) in self.assignments.items(): if self.is_prange and not self.is_parallel: # closely nested prange in a with parallel block, disallow # assigning to privates in the with parallel block (we # consider it too implicit and magicky for users) if entry in self.parent.assignments: error(pos, "Cannot assign to private of outer parallel block") continue if not self.is_prange and op: # Again possible, but considered to magicky error(pos, "Reductions not allowed for parallel blocks") continue # By default all variables should have the same values as if # executed sequentially lastprivate = True self.propagate_var_privatization(entry, pos, op, lastprivate) def propagate_var_privatization(self, entry, pos, op, lastprivate): """ Propagate the sharing attributes of a variable. If the privatization is determined by a parent scope, done propagate further. If we are a prange, we propagate our sharing attributes outwards to other pranges. If we are a prange in parallel block and the parallel block does not determine the variable private, we propagate to the parent of the parent. Recursion stops at parallel blocks, as they have no concept of lastprivate or reduction. So the following cases propagate: sum is a reduction for all loops: for i in prange(n): for j in prange(n): for k in prange(n): sum += i * j * k sum is a reduction for both loops, local_var is private to the parallel with block: for i in prange(n): with parallel: local_var = ... # private to the parallel for j in prange(n): sum += i * j Nested with parallel blocks are disallowed, because they wouldn't allow you to propagate lastprivates or reductions: #pragma omp parallel for lastprivate(i) for i in prange(n): sum = 0 #pragma omp parallel private(j, sum) with parallel: #pragma omp parallel with parallel: #pragma omp for lastprivate(j) reduction(+:sum) for j in prange(n): sum += i # sum and j are well-defined here # sum and j are undefined here # sum and j are undefined here """ self.privates[entry] = (op, lastprivate) if entry.type.is_memoryviewslice: error(pos, "Memoryview slices can only be shared in parallel sections") return if self.is_prange: if not self.is_parallel and entry not in self.parent.assignments: # Parent is a parallel with block parent = self.parent.parent else: parent = self.parent # We don't need to propagate privates, only reductions and # lastprivates if parent and (op or lastprivate): parent.propagate_var_privatization(entry, pos, op, lastprivate) def _allocate_closure_temp(self, code, entry): """ Helper function that allocate a temporary for a closure variable that is assigned to. """ if self.parent: return self.parent._allocate_closure_temp(code, entry) if entry.cname in self.seen_closure_vars: return entry.cname cname = code.funcstate.allocate_temp(entry.type, True) # Add both the actual cname and the temp cname, as the actual cname # will be replaced with the temp cname on the entry self.seen_closure_vars.add(entry.cname) self.seen_closure_vars.add(cname) self.modified_entries.append((entry, entry.cname)) code.putln("%s = %s;" % (cname, entry.cname)) entry.cname = cname def initialize_privates_to_nan(self, code, exclude=None): first = True for entry, (op, lastprivate) in self.privates.items(): if not op and (not exclude or entry != exclude): invalid_value = entry.type.invalid_value() if invalid_value: if first: code.putln("/* Initialize private variables to " "invalid values */") first = False code.putln("%s = %s;" % (entry.cname, entry.type.cast_code(invalid_value))) def evaluate_before_block(self, code, expr): c = self.begin_of_parallel_control_block_point_after_decls # we need to set the owner to ourselves temporarily, as # allocate_temp may generate a comment in the middle of our pragma # otherwise when DebugFlags.debug_temp_code_comments is in effect owner = c.funcstate.owner c.funcstate.owner = c expr.generate_evaluation_code(c) c.funcstate.owner = owner return expr.result() def put_num_threads(self, code): """ Write self.num_threads if set as the num_threads OpenMP directive """ if self.num_threads is not None: code.put(" num_threads(%s)" % self.evaluate_before_block(code, self.num_threads)) def declare_closure_privates(self, code): """ If a variable is in a scope object, we need to allocate a temp and assign the value from the temp to the variable in the scope object after the parallel section. This kind of copying should be done only in the outermost parallel section. """ self.modified_entries = [] for entry in self.assignments: if entry.from_closure or entry.in_closure: self._allocate_closure_temp(code, entry) def release_closure_privates(self, code): """ Release any temps used for variables in scope objects. As this is the outermost parallel block, we don't need to delete the cnames from self.seen_closure_vars. """ for entry, original_cname in self.modified_entries: code.putln("%s = %s;" % (original_cname, entry.cname)) code.funcstate.release_temp(entry.cname) entry.cname = original_cname def privatize_temps(self, code, exclude_temps=()): """ Make any used temporaries private. Before the relevant code block code.start_collecting_temps() should have been called. """ if self.is_parallel: c = self.privatization_insertion_point self.temps = temps = code.funcstate.stop_collecting_temps() privates, firstprivates = [], [] for temp, type in temps: if type.is_pyobject or type.is_memoryviewslice: firstprivates.append(temp) else: privates.append(temp) if privates: c.put(" private(%s)" % ", ".join(privates)) if firstprivates: c.put(" firstprivate(%s)" % ", ".join(firstprivates)) if self.breaking_label_used: shared_vars = [Naming.parallel_why] if self.error_label_used: shared_vars.extend(self.parallel_exc) c.put(" private(%s, %s, %s)" % self.pos_info) c.put(" shared(%s)" % ', '.join(shared_vars)) def cleanup_temps(self, code): # Now clean up any memoryview slice and object temporaries if self.is_parallel and not self.is_nested_prange: code.putln("/* Clean up any temporaries */") for temp, type in self.temps: if type.is_memoryviewslice: code.put_xdecref_memoryviewslice(temp, have_gil=False) elif type.is_pyobject: code.put_xdecref(temp, type) code.putln("%s = NULL;" % temp) def setup_parallel_control_flow_block(self, code): """ Sets up a block that surrounds the parallel block to determine how the parallel section was exited. Any kind of return is trapped (break, continue, return, exceptions). This is the idea: { int why = 0; #pragma omp parallel { return # -> goto new_return_label; goto end_parallel; new_return_label: why = 3; goto end_parallel; end_parallel:; #pragma omp flush(why) # we need to flush for every iteration } if (why == 3) goto old_return_label; } """ self.old_loop_labels = code.new_loop_labels() self.old_error_label = code.new_error_label() self.old_return_label = code.return_label code.return_label = code.new_label(name="return") code.begin_block() # parallel control flow block self.begin_of_parallel_control_block_point = code.insertion_point() self.begin_of_parallel_control_block_point_after_decls = code.insertion_point() self.undef_builtin_expect_apple_gcc_bug(code) def begin_parallel_block(self, code): """ Each OpenMP thread in a parallel section that contains a with gil block must have the thread-state initialized. The call to PyGILState_Release() then deallocates our threadstate. If we wouldn't do this, each with gil block would allocate and deallocate one, thereby losing exception information before it can be saved before leaving the parallel section. """ self.begin_of_parallel_block = code.insertion_point() def end_parallel_block(self, code): """ To ensure all OpenMP threads have thread states, we ensure the GIL in each thread (which creates a thread state if it doesn't exist), after which we release the GIL. On exit, reacquire the GIL and release the thread state. If compiled without OpenMP support (at the C level), then we still have to acquire the GIL to decref any object temporaries. """ if self.error_label_used: begin_code = self.begin_of_parallel_block end_code = code begin_code.putln("#ifdef _OPENMP") begin_code.put_ensure_gil(declare_gilstate=True) begin_code.putln("Py_BEGIN_ALLOW_THREADS") begin_code.putln("#endif /* _OPENMP */") end_code.putln("#ifdef _OPENMP") end_code.putln("Py_END_ALLOW_THREADS") end_code.putln("#else") end_code.put_safe("{\n") end_code.put_ensure_gil() end_code.putln("#endif /* _OPENMP */") self.cleanup_temps(end_code) end_code.put_release_ensured_gil() end_code.putln("#ifndef _OPENMP") end_code.put_safe("}\n") end_code.putln("#endif /* _OPENMP */") def trap_parallel_exit(self, code, should_flush=False): """ Trap any kind of return inside a parallel construct. 'should_flush' indicates whether the variable should be flushed, which is needed by prange to skip the loop. It also indicates whether we need to register a continue (we need this for parallel blocks, but not for prange loops, as it is a direct jump there). It uses the same mechanism as try/finally: 1 continue 2 break 3 return 4 error """ save_lastprivates_label = code.new_label() dont_return_label = code.new_label() self.any_label_used = False self.breaking_label_used = False self.error_label_used = False self.parallel_private_temps = [] all_labels = code.get_all_labels() # Figure this out before starting to generate any code for label in all_labels: if code.label_used(label): self.breaking_label_used = (self.breaking_label_used or label != code.continue_label) self.any_label_used = True if self.any_label_used: code.put_goto(dont_return_label) for i, label in enumerate(all_labels): if not code.label_used(label): continue is_continue_label = label == code.continue_label code.put_label(label) if not (should_flush and is_continue_label): if label == code.error_label: self.error_label_used = True self.fetch_parallel_exception(code) code.putln("%s = %d;" % (Naming.parallel_why, i + 1)) if (self.breaking_label_used and self.is_prange and not is_continue_label): code.put_goto(save_lastprivates_label) else: code.put_goto(dont_return_label) if self.any_label_used: if self.is_prange and self.breaking_label_used: # Don't rely on lastprivate, save our lastprivates code.put_label(save_lastprivates_label) self.save_parallel_vars(code) code.put_label(dont_return_label) if should_flush and self.breaking_label_used: code.putln_openmp("#pragma omp flush(%s)" % Naming.parallel_why) def save_parallel_vars(self, code): """ The following shenanigans are instated when we break, return or propagate errors from a prange. In this case we cannot rely on lastprivate() to do its job, as no iterations may have executed yet in the last thread, leaving the values undefined. It is most likely that the breaking thread has well-defined values of the lastprivate variables, so we keep those values. """ section_name = ("__pyx_parallel_lastprivates%d" % self.critical_section_counter) code.putln_openmp("#pragma omp critical(%s)" % section_name) ParallelStatNode.critical_section_counter += 1 code.begin_block() # begin critical section c = self.begin_of_parallel_control_block_point temp_count = 0 for entry, (op, lastprivate) in self.privates.items(): if not lastprivate or entry.type.is_pyobject: continue type_decl = entry.type.empty_declaration_code() temp_cname = "__pyx_parallel_temp%d" % temp_count private_cname = entry.cname temp_count += 1 invalid_value = entry.type.invalid_value() if invalid_value: init = ' = ' + invalid_value else: init = '' # Declare the parallel private in the outer block c.putln("%s %s%s;" % (type_decl, temp_cname, init)) # Initialize before escaping code.putln("%s = %s;" % (temp_cname, private_cname)) self.parallel_private_temps.append((temp_cname, private_cname)) code.end_block() # end critical section def fetch_parallel_exception(self, code): """ As each OpenMP thread may raise an exception, we need to fetch that exception from the threadstate and save it for after the parallel section where it can be re-raised in the master thread. Although it would seem that __pyx_filename, __pyx_lineno and __pyx_clineno are only assigned to under exception conditions (i.e., when we have the GIL), and thus should be allowed to be shared without any race condition, they are in fact subject to the same race conditions that they were previously when they were global variables and functions were allowed to release the GIL: thread A thread B acquire set lineno release acquire set lineno release acquire fetch exception release skip the fetch deallocate threadstate deallocate threadstate """ code.begin_block() code.put_ensure_gil(declare_gilstate=True) code.putln_openmp("#pragma omp flush(%s)" % Naming.parallel_exc_type) code.putln( "if (!%s) {" % Naming.parallel_exc_type) code.putln("__Pyx_ErrFetch(&%s, &%s, &%s);" % self.parallel_exc) pos_info = chain(*zip(self.parallel_pos_info, self.pos_info)) code.funcstate.uses_error_indicator = True code.putln("%s = %s; %s = %s; %s = %s;" % tuple(pos_info)) code.put_gotref(Naming.parallel_exc_type) code.putln( "}") code.put_release_ensured_gil() code.end_block() def restore_parallel_exception(self, code): "Re-raise a parallel exception" code.begin_block() code.put_ensure_gil(declare_gilstate=True) code.put_giveref(Naming.parallel_exc_type) code.putln("__Pyx_ErrRestore(%s, %s, %s);" % self.parallel_exc) pos_info = chain(*zip(self.pos_info, self.parallel_pos_info)) code.putln("%s = %s; %s = %s; %s = %s;" % tuple(pos_info)) code.put_release_ensured_gil() code.end_block() def restore_labels(self, code): """ Restore all old labels. Call this before the 'else' clause to for loops and always before ending the parallel control flow block. """ code.set_all_labels(self.old_loop_labels + (self.old_return_label, self.old_error_label)) def end_parallel_control_flow_block(self, code, break_=False, continue_=False): """ This ends the parallel control flow block and based on how the parallel section was exited, takes the corresponding action. The break_ and continue_ parameters indicate whether these should be propagated outwards: for i in prange(...): with cython.parallel.parallel(): continue Here break should be trapped in the parallel block, and propagated to the for loop. """ c = self.begin_of_parallel_control_block_point # Firstly, always prefer errors over returning, continue or break if self.error_label_used: c.putln("const char *%s = NULL; int %s = 0, %s = 0;" % self.parallel_pos_info) c.putln("PyObject *%s = NULL, *%s = NULL, *%s = NULL;" % self.parallel_exc) code.putln( "if (%s) {" % Naming.parallel_exc_type) code.putln("/* This may have been overridden by a continue, " "break or return in another thread. Prefer the error. */") code.putln("%s = 4;" % Naming.parallel_why) code.putln( "}") if continue_: any_label_used = self.any_label_used else: any_label_used = self.breaking_label_used if any_label_used: # __pyx_parallel_why is used, declare and initialize c.putln("int %s;" % Naming.parallel_why) c.putln("%s = 0;" % Naming.parallel_why) code.putln( "if (%s) {" % Naming.parallel_why) for temp_cname, private_cname in self.parallel_private_temps: code.putln("%s = %s;" % (private_cname, temp_cname)) code.putln("switch (%s) {" % Naming.parallel_why) if continue_: code.put(" case 1: ") code.put_goto(code.continue_label) if break_: code.put(" case 2: ") code.put_goto(code.break_label) code.put(" case 3: ") code.put_goto(code.return_label) if self.error_label_used: code.globalstate.use_utility_code(restore_exception_utility_code) code.putln(" case 4:") self.restore_parallel_exception(code) code.put_goto(code.error_label) code.putln("}") # end switch code.putln( "}") # end if code.end_block() # end parallel control flow block self.redef_builtin_expect_apple_gcc_bug(code) # FIXME: improve with version number for OS X Lion buggy_platform_macro_condition = "(defined(__APPLE__) || defined(__OSX__))" have_expect_condition = "(defined(__GNUC__) && " \ "(__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))))" redef_condition = "(%s && %s)" % (buggy_platform_macro_condition, have_expect_condition) def undef_builtin_expect_apple_gcc_bug(self, code): """ A bug on OS X Lion disallows __builtin_expect macros. This code avoids them """ if not self.parent: code.undef_builtin_expect(self.redef_condition) def redef_builtin_expect_apple_gcc_bug(self, code): if not self.parent: code.redef_builtin_expect(self.redef_condition) class ParallelWithBlockNode(ParallelStatNode): """ This node represents a 'with cython.parallel.parallel():' block """ valid_keyword_arguments = ['num_threads'] num_threads = None def analyse_declarations(self, env): super(ParallelWithBlockNode, self).analyse_declarations(env) if self.args: error(self.pos, "cython.parallel.parallel() does not take " "positional arguments") def generate_execution_code(self, code): self.declare_closure_privates(code) self.setup_parallel_control_flow_block(code) code.putln("#ifdef _OPENMP") code.put("#pragma omp parallel ") if self.privates: privates = [e.cname for e in self.privates if not e.type.is_pyobject] code.put('private(%s)' % ', '.join(privates)) self.privatization_insertion_point = code.insertion_point() self.put_num_threads(code) code.putln("") code.putln("#endif /* _OPENMP */") code.begin_block() # parallel block self.begin_parallel_block(code) self.initialize_privates_to_nan(code) code.funcstate.start_collecting_temps() self.body.generate_execution_code(code) self.trap_parallel_exit(code) self.privatize_temps(code) self.end_parallel_block(code) code.end_block() # end parallel block continue_ = code.label_used(code.continue_label) break_ = code.label_used(code.break_label) self.restore_labels(code) self.end_parallel_control_flow_block(code, break_=break_, continue_=continue_) self.release_closure_privates(code) class ParallelRangeNode(ParallelStatNode): """ This node represents a 'for i in cython.parallel.prange():' construct. target NameNode the target iteration variable else_clause Node or None the else clause of this loop """ child_attrs = ['body', 'target', 'else_clause', 'args', 'num_threads', 'chunksize'] body = target = else_clause = args = None start = stop = step = None is_prange = True nogil = None schedule = None valid_keyword_arguments = ['schedule', 'nogil', 'num_threads', 'chunksize'] def __init__(self, pos, **kwds): super(ParallelRangeNode, self).__init__(pos, **kwds) # Pretend to be a ForInStatNode for control flow analysis self.iterator = PassStatNode(pos) def analyse_declarations(self, env): super(ParallelRangeNode, self).analyse_declarations(env) self.target.analyse_target_declaration(env) if self.else_clause is not None: self.else_clause.analyse_declarations(env) if not self.args or len(self.args) > 3: error(self.pos, "Invalid number of positional arguments to prange") return if len(self.args) == 1: self.stop, = self.args elif len(self.args) == 2: self.start, self.stop = self.args else: self.start, self.stop, self.step = self.args if hasattr(self.schedule, 'decode'): self.schedule = self.schedule.decode('ascii') if self.schedule not in (None, 'static', 'dynamic', 'guided', 'runtime'): error(self.pos, "Invalid schedule argument to prange: %s" % (self.schedule,)) def analyse_expressions(self, env): was_nogil = env.nogil if self.nogil: env.nogil = True if self.target is None: error(self.pos, "prange() can only be used as part of a for loop") return self self.target = self.target.analyse_target_types(env) if not self.target.type.is_numeric: # Not a valid type, assume one for now anyway if not self.target.type.is_pyobject: # nogil_check will catch the is_pyobject case error(self.target.pos, "Must be of numeric type, not %s" % self.target.type) self.index_type = PyrexTypes.c_py_ssize_t_type else: self.index_type = self.target.type if not self.index_type.signed: warning(self.target.pos, "Unsigned index type not allowed before OpenMP 3.0", level=2) # Setup start, stop and step, allocating temps if needed self.names = 'start', 'stop', 'step' start_stop_step = self.start, self.stop, self.step for node, name in zip(start_stop_step, self.names): if node is not None: node.analyse_types(env) if not node.type.is_numeric: error(node.pos, "%s argument must be numeric" % name) continue if not node.is_literal: node = node.coerce_to_temp(env) setattr(self, name, node) # As we range from 0 to nsteps, computing the index along the # way, we need a fitting type for 'i' and 'nsteps' self.index_type = PyrexTypes.widest_numeric_type( self.index_type, node.type) if self.else_clause is not None: self.else_clause = self.else_clause.analyse_expressions(env) # Although not actually an assignment in this scope, it should be # treated as such to ensure it is unpacked if a closure temp, and to # ensure lastprivate behaviour and propagation. If the target index is # not a NameNode, it won't have an entry, and an error was issued by # ParallelRangeTransform if hasattr(self.target, 'entry'): self.assignments[self.target.entry] = self.target.pos, None node = super(ParallelRangeNode, self).analyse_expressions(env) if node.chunksize: if not node.schedule: error(node.chunksize.pos, "Must provide schedule with chunksize") elif node.schedule == 'runtime': error(node.chunksize.pos, "Chunksize not valid for the schedule runtime") elif (node.chunksize.type.is_int and node.chunksize.is_literal and node.chunksize.compile_time_value(env) <= 0): error(node.chunksize.pos, "Chunksize must not be negative") node.chunksize = node.chunksize.coerce_to( PyrexTypes.c_int_type, env).coerce_to_temp(env) if node.nogil: env.nogil = was_nogil node.is_nested_prange = node.parent and node.parent.is_prange if node.is_nested_prange: parent = node while parent.parent and parent.parent.is_prange: parent = parent.parent parent.assignments.update(node.assignments) parent.privates.update(node.privates) parent.assigned_nodes.extend(node.assigned_nodes) return node def nogil_check(self, env): names = 'start', 'stop', 'step', 'target' nodes = self.start, self.stop, self.step, self.target for name, node in zip(names, nodes): if node is not None and node.type.is_pyobject: error(node.pos, "%s may not be a Python object " "as we don't have the GIL" % name) def generate_execution_code(self, code): """ Generate code in the following steps 1) copy any closure variables determined thread-private into temporaries 2) allocate temps for start, stop and step 3) generate a loop that calculates the total number of steps, which then computes the target iteration variable for every step: for i in prange(start, stop, step): ... becomes nsteps = (stop - start) / step; i = start; #pragma omp parallel for lastprivate(i) for (temp = 0; temp < nsteps; temp++) { i = start + step * temp; ... } Note that accumulation of 'i' would have a data dependency between iterations. Also, you can't do this for (i = start; i < stop; i += step) ... as the '<' operator should become '>' for descending loops. 'for i from x < i < y:' does not suffer from this problem as the relational operator is known at compile time! 4) release our temps and write back any private closure variables """ self.declare_closure_privates(code) # This can only be a NameNode target_index_cname = self.target.entry.cname # This will be used as the dict to format our code strings, holding # the start, stop , step, temps and target cnames fmt_dict = { 'target': target_index_cname, } # Setup start, stop and step, allocating temps if needed start_stop_step = self.start, self.stop, self.step defaults = '0', '0', '1' for node, name, default in zip(start_stop_step, self.names, defaults): if node is None: result = default elif node.is_literal: result = node.get_constant_c_result_code() else: node.generate_evaluation_code(code) result = node.result() fmt_dict[name] = result fmt_dict['i'] = code.funcstate.allocate_temp(self.index_type, False) fmt_dict['nsteps'] = code.funcstate.allocate_temp(self.index_type, False) # TODO: check if the step is 0 and if so, raise an exception in a # 'with gil' block. For now, just abort code.putln("if (%(step)s == 0) abort();" % fmt_dict) self.setup_parallel_control_flow_block(code) # parallel control flow block self.control_flow_var_code_point = code.insertion_point() # Note: nsteps is private in an outer scope if present code.putln("%(nsteps)s = (%(stop)s - %(start)s) / %(step)s;" % fmt_dict) # The target iteration variable might not be initialized, do it only if # we are executing at least 1 iteration, otherwise we should leave the # target unaffected. The target iteration variable is firstprivate to # shut up compiler warnings caused by lastprivate, as the compiler # erroneously believes that nsteps may be <= 0, leaving the private # target index uninitialized code.putln("if (%(nsteps)s > 0)" % fmt_dict) code.begin_block() # if block self.generate_loop(code, fmt_dict) code.end_block() # end if block self.restore_labels(code) if self.else_clause: if self.breaking_label_used: code.put("if (%s < 2)" % Naming.parallel_why) code.begin_block() # else block code.putln("/* else */") self.else_clause.generate_execution_code(code) code.end_block() # end else block # ------ cleanup ------ self.end_parallel_control_flow_block(code) # end parallel control flow block # And finally, release our privates and write back any closure # variables for temp in start_stop_step + (self.chunksize, self.num_threads): if temp is not None: temp.generate_disposal_code(code) temp.free_temps(code) code.funcstate.release_temp(fmt_dict['i']) code.funcstate.release_temp(fmt_dict['nsteps']) self.release_closure_privates(code) def generate_loop(self, code, fmt_dict): if self.is_nested_prange: code.putln("#if 0") else: code.putln("#ifdef _OPENMP") if not self.is_parallel: code.put("#pragma omp for") self.privatization_insertion_point = code.insertion_point() reduction_codepoint = self.parent.privatization_insertion_point else: code.put("#pragma omp parallel") self.privatization_insertion_point = code.insertion_point() reduction_codepoint = self.privatization_insertion_point code.putln("") code.putln("#endif /* _OPENMP */") code.begin_block() # pragma omp parallel begin block # Initialize the GIL if needed for this thread self.begin_parallel_block(code) if self.is_nested_prange: code.putln("#if 0") else: code.putln("#ifdef _OPENMP") code.put("#pragma omp for") for entry, (op, lastprivate) in self.privates.items(): # Don't declare the index variable as a reduction if op and op in "+*-&^|" and entry != self.target.entry: if entry.type.is_pyobject: error(self.pos, "Python objects cannot be reductions") else: #code.put(" reduction(%s:%s)" % (op, entry.cname)) # This is the only way reductions + nesting works in gcc4.5 reduction_codepoint.put( " reduction(%s:%s)" % (op, entry.cname)) else: if entry == self.target.entry: code.put(" firstprivate(%s)" % entry.cname) code.put(" lastprivate(%s)" % entry.cname) continue if not entry.type.is_pyobject: if lastprivate: private = 'lastprivate' else: private = 'private' code.put(" %s(%s)" % (private, entry.cname)) if self.schedule: if self.chunksize: chunksize = ", %s" % self.evaluate_before_block(code, self.chunksize) else: chunksize = "" code.put(" schedule(%s%s)" % (self.schedule, chunksize)) self.put_num_threads(reduction_codepoint) code.putln("") code.putln("#endif /* _OPENMP */") code.put("for (%(i)s = 0; %(i)s < %(nsteps)s; %(i)s++)" % fmt_dict) code.begin_block() # for loop block guard_around_body_codepoint = code.insertion_point() # Start if guard block around the body. This may be unnecessary, but # at least it doesn't spoil indentation code.begin_block() code.putln("%(target)s = %(start)s + %(step)s * %(i)s;" % fmt_dict) self.initialize_privates_to_nan(code, exclude=self.target.entry) if self.is_parallel: code.funcstate.start_collecting_temps() self.body.generate_execution_code(code) self.trap_parallel_exit(code, should_flush=True) self.privatize_temps(code) if self.breaking_label_used: # Put a guard around the loop body in case return, break or # exceptions might be used guard_around_body_codepoint.putln("if (%s < 2)" % Naming.parallel_why) code.end_block() # end guard around loop body code.end_block() # end for loop block if self.is_parallel: # Release the GIL and deallocate the thread state self.end_parallel_block(code) code.end_block() # pragma omp parallel end block class CnameDecoratorNode(StatNode): """ This node is for the cname decorator in CythonUtilityCode: @cname('the_cname') cdef func(...): ... In case of a cdef class the cname specifies the objstruct_cname. node the node to which the cname decorator is applied cname the cname the node should get """ child_attrs = ['node'] def analyse_declarations(self, env): self.node.analyse_declarations(env) node = self.node if isinstance(node, CompilerDirectivesNode): node = node.body.stats[0] self.is_function = isinstance(node, FuncDefNode) is_struct_or_enum = isinstance(node, (CStructOrUnionDefNode, CEnumDefNode)) e = node.entry if self.is_function: e.cname = self.cname e.func_cname = self.cname e.used = True if e.pyfunc_cname and '.' in e.pyfunc_cname: e.pyfunc_cname = self.mangle(e.pyfunc_cname) elif is_struct_or_enum: e.cname = e.type.cname = self.cname else: scope = node.scope e.cname = self.cname e.type.objstruct_cname = self.cname + '_obj' e.type.typeobj_cname = Naming.typeobj_prefix + self.cname e.type.typeptr_cname = self.cname + '_type' e.type.scope.namespace_cname = e.type.typeptr_cname e.as_variable.cname = e.type.typeptr_cname scope.scope_prefix = self.cname + "_" for name, entry in scope.entries.items(): if entry.func_cname: entry.func_cname = self.mangle(entry.cname) if entry.pyfunc_cname: entry.pyfunc_cname = self.mangle(entry.pyfunc_cname) def mangle(self, cname): if '.' in cname: # remove __pyx_base from func_cname cname = cname.split('.')[-1] return '%s_%s' % (self.cname, cname) def analyse_expressions(self, env): self.node = self.node.analyse_expressions(env) return self def generate_function_definitions(self, env, code): "Ensure a prototype for every @cname method in the right place" if self.is_function and env.is_c_class_scope: # method in cdef class, generate a prototype in the header h_code = code.globalstate['utility_code_proto'] if isinstance(self.node, DefNode): self.node.generate_function_header( h_code, with_pymethdef=False, proto_only=True) else: from . import ModuleNode entry = self.node.entry cname = entry.cname entry.cname = entry.func_cname ModuleNode.generate_cfunction_declaration( entry, env.global_scope(), h_code, definition=True) entry.cname = cname self.node.generate_function_definitions(env, code) def generate_execution_code(self, code): self.node.generate_execution_code(code) #------------------------------------------------------------------------------------ # # Runtime support code # #------------------------------------------------------------------------------------ if Options.gcc_branch_hints: branch_prediction_macros = """ /* Test for GCC > 2.95 */ #if defined(__GNUC__) \ && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #else /* !__GNUC__ or GCC < 2.95 */ #define likely(x) (x) #define unlikely(x) (x) #endif /* __GNUC__ */ """ else: branch_prediction_macros = """ #define likely(x) (x) #define unlikely(x) (x) """ #------------------------------------------------------------------------------------ printing_utility_code = UtilityCode.load_cached("Print", "Printing.c") printing_one_utility_code = UtilityCode.load_cached("PrintOne", "Printing.c") #------------------------------------------------------------------------------------ # Exception raising code # # Exceptions are raised by __Pyx_Raise() and stored as plain # type/value/tb in PyThreadState->curexc_*. When being caught by an # 'except' statement, curexc_* is moved over to exc_* by # __Pyx_GetException() restore_exception_utility_code = UtilityCode.load_cached("PyErrFetchRestore", "Exceptions.c") raise_utility_code = UtilityCode.load_cached("RaiseException", "Exceptions.c") get_exception_utility_code = UtilityCode.load_cached("GetException", "Exceptions.c") swap_exception_utility_code = UtilityCode.load_cached("SwapException", "Exceptions.c") reset_exception_utility_code = UtilityCode.load_cached("SaveResetException", "Exceptions.c") traceback_utility_code = UtilityCode.load_cached("AddTraceback", "Exceptions.c") #------------------------------------------------------------------------------------ get_exception_tuple_utility_code = UtilityCode(proto=""" static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/ """, # I doubt that calling __Pyx_GetException() here is correct as it moves # the exception from tstate->curexc_* to tstate->exc_*, which prevents # exception handlers later on from receiving it. impl = """ static PyObject *__Pyx_GetExceptionTuple(void) { PyObject *type = NULL, *value = NULL, *tb = NULL; if (__Pyx_GetException(&type, &value, &tb) == 0) { PyObject* exc_info = PyTuple_New(3); if (exc_info) { Py_INCREF(type); Py_INCREF(value); Py_INCREF(tb); PyTuple_SET_ITEM(exc_info, 0, type); PyTuple_SET_ITEM(exc_info, 1, value); PyTuple_SET_ITEM(exc_info, 2, tb); return exc_info; } } return NULL; } """, requires=[get_exception_utility_code]) Cython-0.23.4/Cython/Compiler/Naming.py0000644000175600017570000001314212606202452021006 0ustar jenkinsjenkins00000000000000# # C naming conventions # # # Prefixes for generating C names. # Collected here to facilitate ensuring uniqueness. # pyrex_prefix = "__pyx_" codewriter_temp_prefix = pyrex_prefix + "t_" temp_prefix = u"__cyt_" builtin_prefix = pyrex_prefix + "builtin_" arg_prefix = pyrex_prefix + "arg_" funcdoc_prefix = pyrex_prefix + "doc_" enum_prefix = pyrex_prefix + "e_" func_prefix = pyrex_prefix + "f_" func_prefix_api = pyrex_prefix + "api_f_" pyfunc_prefix = pyrex_prefix + "pf_" pywrap_prefix = pyrex_prefix + "pw_" genbody_prefix = pyrex_prefix + "gb_" gstab_prefix = pyrex_prefix + "getsets_" prop_get_prefix = pyrex_prefix + "getprop_" const_prefix = pyrex_prefix + "k_" py_const_prefix = pyrex_prefix + "kp_" label_prefix = pyrex_prefix + "L" pymethdef_prefix = pyrex_prefix + "mdef_" methtab_prefix = pyrex_prefix + "methods_" memtab_prefix = pyrex_prefix + "members_" objstruct_prefix = pyrex_prefix + "obj_" typeptr_prefix = pyrex_prefix + "ptype_" prop_set_prefix = pyrex_prefix + "setprop_" type_prefix = pyrex_prefix + "t_" typeobj_prefix = pyrex_prefix + "type_" var_prefix = pyrex_prefix + "v_" varptr_prefix = pyrex_prefix + "vp_" varptr_prefix_api = pyrex_prefix + "api_vp_" wrapperbase_prefix= pyrex_prefix + "wrapperbase_" pybuffernd_prefix = pyrex_prefix + "pybuffernd_" pybufferstruct_prefix = pyrex_prefix + "pybuffer_" vtable_prefix = pyrex_prefix + "vtable_" vtabptr_prefix = pyrex_prefix + "vtabptr_" vtabstruct_prefix = pyrex_prefix + "vtabstruct_" opt_arg_prefix = pyrex_prefix + "opt_args_" convert_func_prefix = pyrex_prefix + "convert_" closure_scope_prefix = pyrex_prefix + "scope_" closure_class_prefix = pyrex_prefix + "scope_struct_" lambda_func_prefix = pyrex_prefix + "lambda_" module_is_main = pyrex_prefix + "module_is_main_" defaults_struct_prefix = pyrex_prefix + "defaults" dynamic_args_cname = pyrex_prefix + "dynamic_args" interned_prefixes = { 'str': pyrex_prefix + "n_", 'int': pyrex_prefix + "int_", 'float': pyrex_prefix + "float_", 'tuple': pyrex_prefix + "tuple_", 'codeobj': pyrex_prefix + "codeobj_", 'slice': pyrex_prefix + "slice_", 'ustring': pyrex_prefix + "ustring_", 'umethod': pyrex_prefix + "umethod_", } ctuple_type_prefix = pyrex_prefix + "ctuple_" args_cname = pyrex_prefix + "args" generator_cname = pyrex_prefix + "generator" sent_value_cname = pyrex_prefix + "sent_value" pykwdlist_cname = pyrex_prefix + "pyargnames" obj_base_cname = pyrex_prefix + "base" builtins_cname = pyrex_prefix + "b" preimport_cname = pyrex_prefix + "i" moddict_cname = pyrex_prefix + "d" dummy_cname = pyrex_prefix + "dummy" filename_cname = pyrex_prefix + "filename" modulename_cname = pyrex_prefix + "modulename" filetable_cname = pyrex_prefix + "f" intern_tab_cname = pyrex_prefix + "intern_tab" kwds_cname = pyrex_prefix + "kwds" lineno_cname = pyrex_prefix + "lineno" clineno_cname = pyrex_prefix + "clineno" cfilenm_cname = pyrex_prefix + "cfilenm" module_cname = pyrex_prefix + "m" moddoc_cname = pyrex_prefix + "mdoc" methtable_cname = pyrex_prefix + "methods" retval_cname = pyrex_prefix + "r" reqd_kwds_cname = pyrex_prefix + "reqd_kwds" self_cname = pyrex_prefix + "self" stringtab_cname = pyrex_prefix + "string_tab" vtabslot_cname = pyrex_prefix + "vtab" c_api_tab_cname = pyrex_prefix + "c_api_tab" gilstate_cname = pyrex_prefix + "state" skip_dispatch_cname = pyrex_prefix + "skip_dispatch" empty_tuple = pyrex_prefix + "empty_tuple" empty_bytes = pyrex_prefix + "empty_bytes" print_function = pyrex_prefix + "print" print_function_kwargs = pyrex_prefix + "print_kwargs" cleanup_cname = pyrex_prefix + "module_cleanup" pymoduledef_cname = pyrex_prefix + "moduledef" optional_args_cname = pyrex_prefix + "optional_args" import_star = pyrex_prefix + "import_star" import_star_set = pyrex_prefix + "import_star_set" outer_scope_cname= pyrex_prefix + "outer_scope" cur_scope_cname = pyrex_prefix + "cur_scope" enc_scope_cname = pyrex_prefix + "enc_scope" frame_cname = pyrex_prefix + "frame" frame_code_cname = pyrex_prefix + "frame_code" binding_cfunc = pyrex_prefix + "binding_PyCFunctionType" fused_func_prefix = pyrex_prefix + 'fuse_' quick_temp_cname = pyrex_prefix + "temp" # temp variable for quick'n'dirty temping global_code_object_cache_find = pyrex_prefix + 'find_code_object' global_code_object_cache_insert = pyrex_prefix + 'insert_code_object' genexpr_id_ref = 'genexpr' freelist_name = 'freelist' freecount_name = 'freecount' line_c_macro = "__LINE__" file_c_macro = "__FILE__" extern_c_macro = pyrex_prefix.upper() + "EXTERN_C" exc_type_name = pyrex_prefix + "exc_type" exc_value_name = pyrex_prefix + "exc_value" exc_tb_name = pyrex_prefix + "exc_tb" exc_lineno_name = pyrex_prefix + "exc_lineno" parallel_exc_type = pyrex_prefix + "parallel_exc_type" parallel_exc_value = pyrex_prefix + "parallel_exc_value" parallel_exc_tb = pyrex_prefix + "parallel_exc_tb" parallel_filename = pyrex_prefix + "parallel_filename" parallel_lineno = pyrex_prefix + "parallel_lineno" parallel_clineno = pyrex_prefix + "parallel_clineno" parallel_why = pyrex_prefix + "parallel_why" exc_vars = (exc_type_name, exc_value_name, exc_tb_name) api_name = pyrex_prefix + "capi__" h_guard_prefix = "__PYX_HAVE__" api_guard_prefix = "__PYX_HAVE_API__" api_func_guard = "__PYX_HAVE_API_FUNC_" PYX_NAN = "__PYX_NAN()" def py_version_hex(major, minor=0, micro=0, release_level=0, release_serial=0): return (major << 24) | (minor << 16) | (micro << 8) | (release_level << 4) | (release_serial) Cython-0.23.4/Cython/Compiler/ModuleNode.py0000644000175600017570000036172112606202452021641 0ustar jenkinsjenkins00000000000000# # Module parse tree node # from __future__ import absolute_import import cython cython.declare(Naming=object, Options=object, PyrexTypes=object, TypeSlots=object, error=object, warning=object, py_object_type=object, UtilityCode=object, EncodedString=object) import json import os import operator from .PyrexTypes import CPtrType from . import Future from . import Annotate from . import Code from . import Naming from . import Nodes from . import Options from . import TypeSlots from . import PyrexTypes from .Errors import error, warning from .PyrexTypes import py_object_type from ..Utils import open_new_file, replace_suffix, decode_filename from .Code import UtilityCode from .StringEncoding import EncodedString def check_c_declarations_pxd(module_node): module_node.scope.check_c_classes_pxd() return module_node def check_c_declarations(module_node): module_node.scope.check_c_classes() module_node.scope.check_c_functions() return module_node class ModuleNode(Nodes.Node, Nodes.BlockNode): # doc string or None # body StatListNode # # referenced_modules [ModuleScope] # full_module_name string # # scope The module scope. # compilation_source A CompilationSource (see Main) # directives Top-level compiler directives child_attrs = ["body"] directives = None def merge_in(self, tree, scope, merge_scope=False): # Merges in the contents of another tree, and possibly scope. With the # current implementation below, this must be done right prior # to code generation. # # Note: This way of doing it seems strange -- I believe the # right concept is to split ModuleNode into a ModuleNode and a # CodeGenerator, and tell that CodeGenerator to generate code # from multiple sources. assert isinstance(self.body, Nodes.StatListNode) if isinstance(tree, Nodes.StatListNode): self.body.stats.extend(tree.stats) else: self.body.stats.append(tree) self.scope.utility_code_list.extend(scope.utility_code_list) def extend_if_not_in(L1, L2): for x in L2: if x not in L1: L1.append(x) extend_if_not_in(self.scope.include_files, scope.include_files) extend_if_not_in(self.scope.included_files, scope.included_files) extend_if_not_in(self.scope.python_include_files, scope.python_include_files) if merge_scope: # Ensure that we don't generate import code for these entries! for entry in scope.c_class_entries: entry.type.module_name = self.full_module_name entry.type.scope.directives["internal"] = True self.scope.merge_in(scope) def analyse_declarations(self, env): if not Options.docstrings: env.doc = self.doc = None elif Options.embed_pos_in_docstring: env.doc = EncodedString(u'File: %s (starting at line %s)' % Nodes.relative_position(self.pos)) if not self.doc is None: env.doc = EncodedString(env.doc + u'\n' + self.doc) env.doc.encoding = self.doc.encoding else: env.doc = self.doc env.directives = self.directives self.body.analyse_declarations(env) def prepare_utility_code(self): # prepare any utility code that must be created before code generation # specifically: CythonUtilityCode env = self.scope if env.has_import_star: self.create_import_star_conversion_utility_code(env) def process_implementation(self, options, result): env = self.scope env.return_type = PyrexTypes.c_void_type self.referenced_modules = [] self.find_referenced_modules(env, self.referenced_modules, {}) self.sort_cdef_classes(env) self.generate_c_code(env, options, result) self.generate_h_code(env, options, result) self.generate_api_code(env, result) def has_imported_c_functions(self): for module in self.referenced_modules: for entry in module.cfunc_entries: if entry.defined_in_pxd: return 1 return 0 def generate_h_code(self, env, options, result): def h_entries(entries, api=0, pxd=0): return [entry for entry in entries if ((entry.visibility == 'public') or (api and entry.api) or (pxd and entry.defined_in_pxd))] h_types = h_entries(env.type_entries, api=1) h_vars = h_entries(env.var_entries) h_funcs = h_entries(env.cfunc_entries) h_extension_types = h_entries(env.c_class_entries) if (h_types or h_vars or h_funcs or h_extension_types): result.h_file = replace_suffix(result.c_file, ".h") h_code = Code.CCodeWriter() Code.GlobalState(h_code, self) if options.generate_pxi: result.i_file = replace_suffix(result.c_file, ".pxi") i_code = Code.PyrexCodeWriter(result.i_file) else: i_code = None h_code.put_generated_by() h_guard = Naming.h_guard_prefix + self.api_name(env) h_code.put_h_guard(h_guard) h_code.putln("") self.generate_type_header_code(h_types, h_code) if options.capi_reexport_cincludes: self.generate_includes(env, [], h_code) h_code.putln("") api_guard = Naming.api_guard_prefix + self.api_name(env) h_code.putln("#ifndef %s" % api_guard) h_code.putln("") self.generate_extern_c_macro_definition(h_code) h_code.putln("") self.generate_dl_import_macro(h_code) if h_extension_types: h_code.putln("") for entry in h_extension_types: self.generate_cclass_header_code(entry.type, h_code) if i_code: self.generate_cclass_include_code(entry.type, i_code) if h_funcs: h_code.putln("") for entry in h_funcs: self.generate_public_declaration(entry, h_code, i_code) if h_vars: h_code.putln("") for entry in h_vars: self.generate_public_declaration(entry, h_code, i_code) h_code.putln("") h_code.putln("#endif /* !%s */" % api_guard) h_code.putln("") h_code.putln("#if PY_MAJOR_VERSION < 3") h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name) h_code.putln("#else") h_code.putln("PyMODINIT_FUNC PyInit_%s(void);" % env.module_name) h_code.putln("#endif") h_code.putln("") h_code.putln("#endif /* !%s */" % h_guard) f = open_new_file(result.h_file) try: h_code.copyto(f) finally: f.close() def generate_public_declaration(self, entry, h_code, i_code): h_code.putln("%s %s;" % ( Naming.extern_c_macro, entry.type.declaration_code( entry.cname, dll_linkage = "DL_IMPORT"))) if i_code: i_code.putln("cdef extern %s" % entry.type.declaration_code(entry.cname, pyrex = 1)) def api_name(self, env): return env.qualified_name.replace(".", "__") def generate_api_code(self, env, result): def api_entries(entries, pxd=0): return [entry for entry in entries if entry.api or (pxd and entry.defined_in_pxd)] api_vars = api_entries(env.var_entries) api_funcs = api_entries(env.cfunc_entries) api_extension_types = api_entries(env.c_class_entries) if api_vars or api_funcs or api_extension_types: result.api_file = replace_suffix(result.c_file, "_api.h") h_code = Code.CCodeWriter() Code.GlobalState(h_code, self) h_code.put_generated_by() api_guard = Naming.api_guard_prefix + self.api_name(env) h_code.put_h_guard(api_guard) h_code.putln('#include "Python.h"') if result.h_file: h_code.putln('#include "%s"' % os.path.basename(result.h_file)) if api_extension_types: h_code.putln("") for entry in api_extension_types: type = entry.type h_code.putln("static PyTypeObject *%s = 0;" % type.typeptr_cname) h_code.putln("#define %s (*%s)" % ( type.typeobj_cname, type.typeptr_cname)) if api_funcs: h_code.putln("") for entry in api_funcs: type = CPtrType(entry.type) cname = env.mangle(Naming.func_prefix_api, entry.name) h_code.putln("static %s = 0;" % type.declaration_code(cname)) h_code.putln("#define %s %s" % (entry.name, cname)) if api_vars: h_code.putln("") for entry in api_vars: type = CPtrType(entry.type) cname = env.mangle(Naming.varptr_prefix_api, entry.name) h_code.putln("static %s = 0;" % type.declaration_code(cname)) h_code.putln("#define %s (*%s)" % (entry.name, cname)) h_code.put(UtilityCode.load_as_string("PyIdentifierFromString", "ImportExport.c")[0]) h_code.put(UtilityCode.load_as_string("ModuleImport", "ImportExport.c")[1]) if api_vars: h_code.put(UtilityCode.load_as_string("VoidPtrImport", "ImportExport.c")[1]) if api_funcs: h_code.put(UtilityCode.load_as_string("FunctionImport", "ImportExport.c")[1]) if api_extension_types: h_code.put(UtilityCode.load_as_string("TypeImport", "ImportExport.c")[1]) h_code.putln("") h_code.putln("static int import_%s(void) {" % self.api_name(env)) h_code.putln("PyObject *module = 0;") h_code.putln('module = __Pyx_ImportModule("%s");' % env.qualified_name) h_code.putln("if (!module) goto bad;") for entry in api_funcs: cname = env.mangle(Naming.func_prefix_api, entry.name) sig = entry.type.signature_string() h_code.putln( 'if (__Pyx_ImportFunction(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;' % (entry.name, cname, sig)) for entry in api_vars: cname = env.mangle(Naming.varptr_prefix_api, entry.name) sig = entry.type.empty_declaration_code() h_code.putln( 'if (__Pyx_ImportVoidPtr(module, "%s", (void **)&%s, "%s") < 0) goto bad;' % (entry.name, cname, sig)) h_code.putln("Py_DECREF(module); module = 0;") for entry in api_extension_types: self.generate_type_import_call( entry.type, h_code, "if (!%s) goto bad;" % entry.type.typeptr_cname) h_code.putln("return 0;") h_code.putln("bad:") h_code.putln("Py_XDECREF(module);") h_code.putln("return -1;") h_code.putln("}") h_code.putln("") h_code.putln("#endif /* !%s */" % api_guard) f = open_new_file(result.api_file) try: h_code.copyto(f) finally: f.close() def generate_cclass_header_code(self, type, h_code): h_code.putln("%s %s %s;" % ( Naming.extern_c_macro, PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"), type.typeobj_cname)) def generate_cclass_include_code(self, type, i_code): i_code.putln("cdef extern class %s.%s:" % ( type.module_name, type.name)) i_code.indent() var_entries = type.scope.var_entries if var_entries: for entry in var_entries: i_code.putln("cdef %s" % entry.type.declaration_code(entry.cname, pyrex = 1)) else: i_code.putln("pass") i_code.dedent() def generate_c_code(self, env, options, result): modules = self.referenced_modules if Options.annotate or options.annotate: emit_linenums = False rootwriter = Annotate.AnnotationCCodeWriter() else: emit_linenums = options.emit_linenums rootwriter = Code.CCodeWriter(emit_linenums=emit_linenums, c_line_in_traceback=options.c_line_in_traceback) globalstate = Code.GlobalState(rootwriter, self, emit_linenums, options.common_utility_include_dir) globalstate.initialize_main_c_code() h_code = globalstate['h_code'] self.generate_module_preamble(env, modules, result.embedded_metadata, h_code) globalstate.module_pos = self.pos globalstate.directives = self.directives globalstate.use_utility_code(refnanny_utility_code) code = globalstate['before_global_var'] 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("") code.putln("/* Implementation of '%s' */" % env.qualified_name) code = globalstate['all_the_rest'] self.generate_cached_builtins_decls(env, code) self.generate_lambda_definitions(env, code) # generate normal variable and function definitions self.generate_variable_definitions(env, code) self.body.generate_function_definitions(env, code) code.mark_pos(None) self.generate_typeobj_definitions(env, code) self.generate_method_table(env, code) if env.has_import_star: self.generate_import_star(env, code) self.generate_pymoduledef_struct(env, code) # init_globals is inserted before this self.generate_module_init_func(modules[:-1], env, globalstate['init_module']) self.generate_module_cleanup_func(env, globalstate['cleanup_module']) if Options.embed: self.generate_main_method(env, globalstate['main_method']) self.generate_filename_table(globalstate['filename_table']) self.generate_declarations_for_modules(env, modules, globalstate) h_code.write('\n') for utilcode in env.utility_code_list[:]: globalstate.use_utility_code(utilcode) globalstate.finalize_main_c_code() f = open_new_file(result.c_file) try: rootwriter.copyto(f) finally: f.close() result.c_file_generated = 1 if options.gdb_debug: self._serialize_lineno_map(env, rootwriter) if Options.annotate or options.annotate: self._generate_annotations(rootwriter, result, options) def _generate_annotations(self, rootwriter, result, options): self.annotate(rootwriter) coverage_xml_filename = Options.annotate_coverage_xml or options.annotate_coverage_xml if coverage_xml_filename and os.path.exists(coverage_xml_filename): try: import xml.etree.cElementTree as ET except ImportError: import xml.etree.ElementTree as ET coverage_xml = ET.parse(coverage_xml_filename).getroot() for el in coverage_xml.getiterator(): el.tail = None # save some memory else: coverage_xml = None rootwriter.save_annotation(result.main_source_file, result.c_file, coverage_xml=coverage_xml) # if we included files, additionally generate one annotation file for each if not self.scope.included_files: return search_include_file = self.scope.context.search_include_directories target_dir = os.path.abspath(os.path.dirname(result.c_file)) for included_file in self.scope.included_files: target_file = os.path.abspath(os.path.join(target_dir, included_file)) target_file_dir = os.path.dirname(target_file) if not target_file_dir.startswith(target_dir): # any other directories may not be writable => avoid trying continue source_file = search_include_file(included_file, "", self.pos, include=True) if not source_file: continue if target_file_dir != target_dir and not os.path.exists(target_file_dir): try: os.makedirs(target_file_dir) except OSError as e: import errno if e.errno != errno.EEXIST: raise rootwriter.save_annotation(source_file, target_file, coverage_xml=coverage_xml) def _serialize_lineno_map(self, env, ccodewriter): tb = env.context.gdb_debug_outputwriter markers = ccodewriter.buffer.allmarkers() d = {} for c_lineno, cython_lineno in enumerate(markers): if cython_lineno > 0: d.setdefault(cython_lineno, []).append(c_lineno + 1) tb.start('LineNumberMapping') for cython_lineno, c_linenos in sorted(d.items()): attrs = { 'c_linenos': ' '.join(map(str, c_linenos)), 'cython_lineno': str(cython_lineno), } tb.start('LineNumber', attrs) tb.end('LineNumber') tb.end('LineNumberMapping') tb.serialize() def find_referenced_modules(self, env, module_list, modules_seen): if env not in modules_seen: modules_seen[env] = 1 for imported_module in env.cimported_modules: self.find_referenced_modules(imported_module, module_list, modules_seen) module_list.append(env) def sort_types_by_inheritance(self, type_dict, type_order, getkey): # copy the types into a list moving each parent type before # its first child type_list = [] for i, key in enumerate(type_order): new_entry = type_dict[key] # collect all base classes to check for children hierarchy = set() base = new_entry while base: base_type = base.type.base_type if not base_type: break base_key = getkey(base_type) hierarchy.add(base_key) base = type_dict.get(base_key) new_entry.base_keys = hierarchy # find the first (sub-)subclass and insert before that for j in range(i): entry = type_list[j] if key in entry.base_keys: type_list.insert(j, new_entry) break else: type_list.append(new_entry) return type_list def sort_type_hierarchy(self, module_list, env): # poor developer's OrderedDict vtab_dict, vtab_dict_order = {}, [] vtabslot_dict, vtabslot_dict_order = {}, [] for module in module_list: for entry in module.c_class_entries: if entry.used and not entry.in_cinclude: type = entry.type key = type.vtabstruct_cname if not key: continue if key in vtab_dict: # FIXME: this should *never* happen, but apparently it does # for Cython generated utility code from .UtilityCode import NonManglingModuleScope assert isinstance(entry.scope, NonManglingModuleScope), str(entry.scope) assert isinstance(vtab_dict[key].scope, NonManglingModuleScope), str(vtab_dict[key].scope) else: vtab_dict[key] = entry vtab_dict_order.append(key) all_defined_here = module is env for entry in module.type_entries: if entry.used and (all_defined_here or entry.defined_in_pxd): type = entry.type if type.is_extension_type and not entry.in_cinclude: type = entry.type key = type.objstruct_cname assert key not in vtabslot_dict, key vtabslot_dict[key] = entry vtabslot_dict_order.append(key) def vtabstruct_cname(entry_type): return entry_type.vtabstruct_cname vtab_list = self.sort_types_by_inheritance( vtab_dict, vtab_dict_order, vtabstruct_cname) def objstruct_cname(entry_type): return entry_type.objstruct_cname vtabslot_list = self.sort_types_by_inheritance( vtabslot_dict, vtabslot_dict_order, objstruct_cname) return (vtab_list, vtabslot_list) def sort_cdef_classes(self, env): key_func = operator.attrgetter('objstruct_cname') entry_dict, entry_order = {}, [] for entry in env.c_class_entries: key = key_func(entry.type) assert key not in entry_dict, key entry_dict[key] = entry entry_order.append(key) env.c_class_entries[:] = self.sort_types_by_inheritance( entry_dict, entry_order, key_func) def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code): # TODO: Why are these separated out? for entry in vtabslot_list: self.generate_objstruct_predeclaration(entry.type, code) vtabslot_entries = set(vtabslot_list) for module in modules: definition = module is env if definition: type_entries = module.type_entries else: type_entries = [] for entry in module.type_entries: if entry.defined_in_pxd: type_entries.append(entry) type_entries = [t for t in type_entries if t not in vtabslot_entries] self.generate_type_header_code(type_entries, code) for entry in vtabslot_list: self.generate_objstruct_definition(entry.type, code) self.generate_typeobj_predeclaration(entry, code) for entry in vtab_list: self.generate_typeobj_predeclaration(entry, code) self.generate_exttype_vtable_struct(entry, code) self.generate_exttype_vtabptr_declaration(entry, code) self.generate_exttype_final_methods_declaration(entry, code) def generate_declarations_for_modules(self, env, modules, globalstate): typecode = globalstate['type_declarations'] typecode.putln("") typecode.putln("/*--- Type declarations ---*/") # This is to work around the fact that array.h isn't part of the C-API, # but we need to declare it earlier than utility code. if 'cpython.array' in [m.qualified_name for m in modules]: typecode.putln('#ifndef _ARRAYARRAY_H') typecode.putln('struct arrayobject;') typecode.putln('typedef struct arrayobject arrayobject;') typecode.putln('#endif') vtab_list, vtabslot_list = self.sort_type_hierarchy(modules, env) self.generate_type_definitions( env, modules, vtab_list, vtabslot_list, typecode) modulecode = globalstate['module_declarations'] for module in modules: defined_here = module is env modulecode.putln("") modulecode.putln("/* Module declarations from '%s' */" % module.qualified_name) self.generate_c_class_declarations(module, modulecode, defined_here) self.generate_cvariable_declarations(module, modulecode, defined_here) self.generate_cfunction_declarations(module, modulecode, defined_here) def _put_setup_code(self, code, name): code.put(UtilityCode.load_as_string(name, "ModuleSetupCode.c")[1]) def generate_module_preamble(self, env, cimported_modules, metadata, code): code.put_generated_by() if metadata: code.putln("/* BEGIN: Cython Metadata") code.putln(json.dumps(metadata, indent=4, sort_keys=True)) code.putln("END: Cython Metadata */") code.putln("") code.putln("#define PY_SSIZE_T_CLEAN") for filename in env.python_include_files: code.putln('#include "%s"' % filename) code.putln("#ifndef Py_PYTHON_H") code.putln(" #error Python headers needed to compile C extensions, please install development version of Python.") code.putln("#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)") code.putln(" #error Cython requires Python 2.6+ or Python 3.2+.") code.putln("#else") code.globalstate["end"].putln("#endif /* Py_PYTHON_H */") from .. import __version__ code.putln('#define CYTHON_ABI "%s"' % __version__.replace('.', '_')) self._put_setup_code(code, "CModulePreamble") if env.context.options.cplus: self._put_setup_code(code, "CppInitCode") else: self._put_setup_code(code, "CInitCode") self._put_setup_code(code, "MathInitCode") code.put(""" #if PY_MAJOR_VERSION >= 3 #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) #else """) if Future.division in env.context.future_directives: code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)") code.putln(" #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)") else: code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)") code.putln(" #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)") code.putln("#endif") code.putln("") self.generate_extern_c_macro_definition(code) code.putln("") code.putln("#define %s" % Naming.h_guard_prefix + self.api_name(env)) code.putln("#define %s" % Naming.api_guard_prefix + self.api_name(env)) self.generate_includes(env, cimported_modules, code) code.putln("") code.putln("#ifdef PYREX_WITHOUT_ASSERTIONS") code.putln("#define CYTHON_WITHOUT_ASSERTIONS") code.putln("#endif") code.putln("") if env.directives['ccomplex']: code.putln("") code.putln("#if !defined(CYTHON_CCOMPLEX)") code.putln("#define CYTHON_CCOMPLEX 1") code.putln("#endif") code.putln("") code.put(UtilityCode.load_as_string("UtilityFunctionPredeclarations", "ModuleSetupCode.c")[0]) c_string_type = env.directives['c_string_type'] c_string_encoding = env.directives['c_string_encoding'] if c_string_type not in ('bytes', 'bytearray') and not c_string_encoding: error(self.pos, "a default encoding must be provided if c_string_type is not a byte type") code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII %s' % int(c_string_encoding == 'ascii')) if c_string_encoding == 'default': code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 1') else: code.putln('#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0') code.putln('#define __PYX_DEFAULT_STRING_ENCODING "%s"' % c_string_encoding) if c_string_type == 'bytearray': c_string_func_name = 'ByteArray' else: c_string_func_name = c_string_type.title() code.putln('#define __Pyx_PyObject_FromString __Pyx_Py%s_FromString' % c_string_func_name) code.putln('#define __Pyx_PyObject_FromStringAndSize __Pyx_Py%s_FromStringAndSize' % c_string_func_name) code.put(UtilityCode.load_as_string("TypeConversions", "TypeConversion.c")[0]) # These utility functions are assumed to exist and used elsewhere. PyrexTypes.c_long_type.create_to_py_utility_code(env) PyrexTypes.c_long_type.create_from_py_utility_code(env) PyrexTypes.c_int_type.create_from_py_utility_code(env) code.put(Nodes.branch_prediction_macros) code.putln('') code.putln('static PyObject *%s;' % env.module_cname) code.putln('static PyObject *%s;' % env.module_dict_cname) code.putln('static PyObject *%s;' % Naming.builtins_cname) code.putln('static PyObject *%s;' % Naming.empty_tuple) code.putln('static PyObject *%s;' % Naming.empty_bytes) if Options.pre_import is not None: code.putln('static PyObject *%s;' % Naming.preimport_cname) code.putln('static int %s;' % Naming.lineno_cname) code.putln('static int %s = 0;' % Naming.clineno_cname) code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro)) code.putln('static const char *%s;' % Naming.filename_cname) def generate_extern_c_macro_definition(self, code): name = Naming.extern_c_macro code.putln("#ifndef %s" % name) code.putln(" #ifdef __cplusplus") code.putln(' #define %s extern "C"' % name) code.putln(" #else") code.putln(" #define %s extern" % name) code.putln(" #endif") code.putln("#endif") def generate_dl_import_macro(self, code): code.putln("#ifndef DL_IMPORT") code.putln(" #define DL_IMPORT(_T) _T") code.putln("#endif") def generate_includes(self, env, cimported_modules, code): includes = [] for filename in env.include_files: byte_decoded_filenname = str(filename) if byte_decoded_filenname[0] == '<' and byte_decoded_filenname[-1] == '>': code.putln('#include %s' % byte_decoded_filenname) else: code.putln('#include "%s"' % byte_decoded_filenname) code.putln_openmp("#include ") def generate_filename_table(self, code): import os.path as path full_module_path = path.join(*self.full_module_name.split('.')) module_abspath = path.splitext(path.abspath( self.compilation_source.source_desc.get_filenametable_entry() ))[0] root_path = module_abspath[:-len(full_module_path)] workdir = path.abspath(os.getcwd()) + os.sep if root_path.startswith(workdir): # prefer relative paths to current directory (which is most likely the project root) root_path = workdir code.putln("") code.putln("static const char *%s[] = {" % Naming.filetable_cname) if code.globalstate.filename_list: for source_desc in code.globalstate.filename_list: file_abspath = path.abspath(source_desc.get_filenametable_entry()) if file_abspath.startswith(root_path): filename = file_abspath[len(root_path):] else: filename = path.basename(file_abspath) escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"') code.putln('"%s",' % escaped_filename) else: # Some C compilers don't like an empty array code.putln("0") code.putln("};") def generate_type_predeclarations(self, env, code): pass def generate_type_header_code(self, type_entries, code): # Generate definitions of structs/unions/enums/typedefs/objstructs. #self.generate_gcc33_hack(env, code) # Is this still needed? # Forward declarations for entry in type_entries: if not entry.in_cinclude: #print "generate_type_header_code:", entry.name, repr(entry.type) ### type = entry.type if type.is_typedef: # Must test this first! pass elif type.is_struct_or_union or type.is_cpp_class: self.generate_struct_union_predeclaration(entry, code) elif type.is_ctuple and entry.used: self.generate_struct_union_predeclaration(entry.type.struct_entry, code) elif type.is_extension_type: self.generate_objstruct_predeclaration(type, code) # Actual declarations for entry in type_entries: if not entry.in_cinclude: #print "generate_type_header_code:", entry.name, repr(entry.type) ### type = entry.type if type.is_typedef: # Must test this first! self.generate_typedef(entry, code) elif type.is_enum: self.generate_enum_definition(entry, code) elif type.is_struct_or_union: self.generate_struct_union_definition(entry, code) elif type.is_ctuple and entry.used: self.generate_struct_union_definition(entry.type.struct_entry, code) elif type.is_cpp_class: self.generate_cpp_class_definition(entry, code) elif type.is_extension_type: self.generate_objstruct_definition(type, code) def generate_gcc33_hack(self, env, code): # Workaround for spurious warning generation in gcc 3.3 code.putln("") for entry in env.c_class_entries: type = entry.type if not type.typedef_flag: name = type.objstruct_cname if name.startswith("__pyx_"): tail = name[6:] else: tail = name code.putln("typedef struct %s __pyx_gcc33_%s;" % ( name, tail)) def generate_typedef(self, entry, code): base_type = entry.type.typedef_base_type if base_type.is_numeric: try: writer = code.globalstate['numeric_typedefs'] except KeyError: writer = code else: writer = code writer.mark_pos(entry.pos) writer.putln("typedef %s;" % base_type.declaration_code(entry.cname)) def sue_predeclaration(self, type, kind, name): if type.typedef_flag: return "%s %s;\ntypedef %s %s %s;" % ( kind, name, kind, name, name) else: return "%s %s;" % (kind, name) def generate_struct_union_predeclaration(self, entry, code): type = entry.type if type.is_cpp_class and type.templates: code.putln("template " % ", typename ".join([T.empty_declaration_code() for T in type.templates])) code.putln(self.sue_predeclaration(type, type.kind, type.cname)) def sue_header_footer(self, type, kind, name): header = "%s %s {" % (kind, name) footer = "};" return header, footer def generate_struct_union_definition(self, entry, code): code.mark_pos(entry.pos) type = entry.type scope = type.scope if scope: kind = type.kind packed = type.is_struct and type.packed if packed: kind = "%s %s" % (type.kind, "__Pyx_PACKED") code.globalstate.use_utility_code(packed_struct_utility_code) header, footer = \ self.sue_header_footer(type, kind, type.cname) if packed: code.putln("#if defined(__SUNPRO_C)") code.putln(" #pragma pack(1)") code.putln("#elif !defined(__GNUC__)") code.putln(" #pragma pack(push, 1)") code.putln("#endif") code.putln(header) var_entries = scope.var_entries if not var_entries: error(entry.pos, "Empty struct or union definition not allowed outside a" " 'cdef extern from' block") for attr in var_entries: code.putln( "%s;" % attr.type.declaration_code(attr.cname)) code.putln(footer) if packed: code.putln("#if defined(__SUNPRO_C)") code.putln(" #pragma pack()") code.putln("#elif !defined(__GNUC__)") code.putln(" #pragma pack(pop)") code.putln("#endif") def generate_cpp_class_definition(self, entry, code): code.mark_pos(entry.pos) type = entry.type scope = type.scope if scope: if type.templates: code.putln("template " % ", class ".join([T.empty_declaration_code() for T in type.templates])) # Just let everything be public. code.put("struct %s" % type.cname) if type.base_classes: base_class_decl = ", public ".join( [base_class.empty_declaration_code() for base_class in type.base_classes]) code.put(" : public %s" % base_class_decl) code.putln(" {") has_virtual_methods = False has_destructor = False for attr in scope.var_entries: if attr.type.is_cfunction and attr.type.is_static_method: code.put("static ") elif attr.type.is_cfunction and attr.name != "": code.put("virtual ") has_virtual_methods = True if attr.cname[0] == '~': has_destructor = True code.putln( "%s;" % attr.type.declaration_code(attr.cname)) if has_virtual_methods and not has_destructor: code.put("virtual ~%s() { }" % type.cname) code.putln("};") def generate_enum_definition(self, entry, code): code.mark_pos(entry.pos) type = entry.type name = entry.cname or entry.name or "" header, footer = \ self.sue_header_footer(type, "enum", name) code.putln(header) enum_values = entry.enum_values if not enum_values: error(entry.pos, "Empty enum definition not allowed outside a" " 'cdef extern from' block") else: last_entry = enum_values[-1] # this does not really generate code, just builds the result value for value_entry in enum_values: if value_entry.value_node is not None: value_entry.value_node.generate_evaluation_code(code) for value_entry in enum_values: if value_entry.value_node is None: value_code = value_entry.cname else: value_code = ("%s = %s" % ( value_entry.cname, value_entry.value_node.result())) if value_entry is not last_entry: value_code += "," code.putln(value_code) code.putln(footer) if entry.type.typedef_flag: # Not pre-declared. code.putln("typedef enum %s %s;" % (name, name)) def generate_typeobj_predeclaration(self, entry, code): code.putln("") name = entry.type.typeobj_cname if name: if entry.visibility == 'extern' and not entry.in_cinclude: code.putln("%s %s %s;" % ( Naming.extern_c_macro, PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"), name)) elif entry.visibility == 'public': code.putln("%s %s %s;" % ( Naming.extern_c_macro, PyrexTypes.public_decl("PyTypeObject", "DL_EXPORT"), name)) # ??? Do we really need the rest of this? ??? #else: # code.putln("static PyTypeObject %s;" % name) def generate_exttype_vtable_struct(self, entry, code): if not entry.used: return code.mark_pos(entry.pos) # Generate struct declaration for an extension type's vtable. type = entry.type scope = type.scope self.specialize_fused_types(scope) if type.vtabstruct_cname: code.putln("") code.putln( "struct %s {" % type.vtabstruct_cname) if type.base_type and type.base_type.vtabstruct_cname: code.putln("struct %s %s;" % ( type.base_type.vtabstruct_cname, Naming.obj_base_cname)) for method_entry in scope.cfunc_entries: if not method_entry.is_inherited: code.putln( "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.cname)) code.putln( "};") def generate_exttype_vtabptr_declaration(self, entry, code): if not entry.used: return code.mark_pos(entry.pos) # Generate declaration of pointer to an extension type's vtable. type = entry.type if type.vtabptr_cname: code.putln("static struct %s *%s;" % ( type.vtabstruct_cname, type.vtabptr_cname)) def generate_exttype_final_methods_declaration(self, entry, code): if not entry.used: return code.mark_pos(entry.pos) # Generate final methods prototypes type = entry.type for method_entry in entry.type.scope.cfunc_entries: if not method_entry.is_inherited and method_entry.final_func_cname: declaration = method_entry.type.declaration_code( method_entry.final_func_cname) modifiers = code.build_function_modifiers(method_entry.func_modifiers) code.putln("static %s%s;" % (modifiers, declaration)) def generate_objstruct_predeclaration(self, type, code): if not type.scope: return code.putln(self.sue_predeclaration(type, "struct", type.objstruct_cname)) def generate_objstruct_definition(self, type, code): code.mark_pos(type.pos) # Generate object struct definition for an # extension type. if not type.scope: return # Forward declared but never defined header, footer = \ self.sue_header_footer(type, "struct", type.objstruct_cname) code.putln(header) base_type = type.base_type if base_type: basestruct_cname = base_type.objstruct_cname if basestruct_cname == "PyTypeObject": # User-defined subclasses of type are heap allocated. basestruct_cname = "PyHeapTypeObject" code.putln( "%s%s %s;" % ( ("struct ", "")[base_type.typedef_flag], basestruct_cname, Naming.obj_base_cname)) else: code.putln( "PyObject_HEAD") if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname): code.putln( "struct %s *%s;" % ( type.vtabstruct_cname, type.vtabslot_cname)) for attr in type.scope.var_entries: if attr.is_declared_generic: attr_type = py_object_type else: attr_type = attr.type code.putln( "%s;" % attr_type.declaration_code(attr.cname)) code.putln(footer) if type.objtypedef_cname is not None: # Only for exposing public typedef name. code.putln("typedef struct %s %s;" % (type.objstruct_cname, type.objtypedef_cname)) def generate_c_class_declarations(self, env, code, definition): for entry in env.c_class_entries: if definition or entry.defined_in_pxd: code.putln("static PyTypeObject *%s = 0;" % entry.type.typeptr_cname) def generate_cvariable_declarations(self, env, code, definition): if env.is_cython_builtin: return for entry in env.var_entries: if (entry.in_cinclude or entry.in_closure or (entry.visibility == 'private' and not (entry.defined_in_pxd or entry.used))): continue storage_class = None dll_linkage = None cname = None init = None if entry.visibility == 'extern': storage_class = Naming.extern_c_macro dll_linkage = "DL_IMPORT" elif entry.visibility == 'public': storage_class = Naming.extern_c_macro if definition: dll_linkage = "DL_EXPORT" else: dll_linkage = "DL_IMPORT" elif entry.visibility == 'private': storage_class = "static" dll_linkage = None if entry.init is not None: init = entry.type.literal_code(entry.init) type = entry.type cname = entry.cname if entry.defined_in_pxd and not definition: storage_class = "static" dll_linkage = None type = CPtrType(type) cname = env.mangle(Naming.varptr_prefix, entry.name) init = 0 if storage_class: code.put("%s " % storage_class) code.put(type.declaration_code( cname, dll_linkage = dll_linkage)) if init is not None: code.put_safe(" = %s" % init) code.putln(";") if entry.cname != cname: code.putln("#define %s (*%s)" % (entry.cname, cname)) def generate_cfunction_declarations(self, env, code, definition): for entry in env.cfunc_entries: if entry.used or (entry.visibility == 'public' or entry.api): generate_cfunction_declaration(entry, env, code, definition) def generate_variable_definitions(self, env, code): for entry in env.var_entries: if (not entry.in_cinclude and entry.visibility == "public"): code.put(entry.type.declaration_code(entry.cname)) if entry.init is not None: init = entry.type.literal_code(entry.init) code.put_safe(" = %s" % init) code.putln(";") def generate_typeobj_definitions(self, env, code): full_module_name = env.qualified_name for entry in env.c_class_entries: #print "generate_typeobj_definitions:", entry.name #print "...visibility =", entry.visibility if entry.visibility != 'extern': type = entry.type scope = type.scope if scope: # could be None if there was an error self.generate_exttype_vtable(scope, code) self.generate_new_function(scope, code, entry) self.generate_dealloc_function(scope, code) if scope.needs_gc(): self.generate_traverse_function(scope, code, entry) if scope.needs_tp_clear(): self.generate_clear_function(scope, code, entry) if scope.defines_any(["__getitem__"]): self.generate_getitem_int_function(scope, code) if scope.defines_any(["__setitem__", "__delitem__"]): self.generate_ass_subscript_function(scope, code) if scope.defines_any(["__getslice__", "__setslice__", "__delslice__"]): warning(self.pos, "__getslice__, __setslice__, and __delslice__ are not supported by Python 3, use __getitem__, __setitem__, and __delitem__ instead", 1) code.putln("#if PY_MAJOR_VERSION >= 3") code.putln("#error __getslice__, __setslice__, and __delslice__ not supported in Python 3.") code.putln("#endif") if scope.defines_any(["__setslice__", "__delslice__"]): self.generate_ass_slice_function(scope, code) if scope.defines_any(["__getattr__","__getattribute__"]): self.generate_getattro_function(scope, code) if scope.defines_any(["__setattr__", "__delattr__"]): self.generate_setattro_function(scope, code) if scope.defines_any(["__get__"]): self.generate_descr_get_function(scope, code) if scope.defines_any(["__set__", "__delete__"]): self.generate_descr_set_function(scope, code) self.generate_property_accessors(scope, code) self.generate_method_table(scope, code) self.generate_getset_table(scope, code) self.generate_typeobj_definition(full_module_name, entry, code) def generate_exttype_vtable(self, scope, code): # Generate the definition of an extension type's vtable. type = scope.parent_type if type.vtable_cname: code.putln("static struct %s %s;" % ( type.vtabstruct_cname, type.vtable_cname)) def generate_self_cast(self, scope, code): type = scope.parent_type code.putln( "%s = (%s)o;" % ( type.declaration_code("p"), type.empty_declaration_code())) def generate_new_function(self, scope, code, cclass_entry): tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__') slot_func = scope.mangle_internal("tp_new") type = scope.parent_type base_type = type.base_type have_entries, (py_attrs, py_buffers, memoryview_slices) = \ scope.get_refcounted_entries() is_final_type = scope.parent_type.is_final_type if scope.is_internal: # internal classes (should) never need None inits, normal zeroing will do py_attrs = [] cpp_class_attrs = [entry for entry in scope.var_entries if entry.type.is_cpp_class] new_func_entry = scope.lookup_here("__new__") if base_type or (new_func_entry and new_func_entry.is_special and not new_func_entry.trivial_signature): unused_marker = '' else: unused_marker = 'CYTHON_UNUSED ' if base_type: freelist_size = 0 # not currently supported else: freelist_size = scope.directives.get('freelist', 0) freelist_name = scope.mangle_internal(Naming.freelist_name) freecount_name = scope.mangle_internal(Naming.freecount_name) decls = code.globalstate['decls'] decls.putln("static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/" % slot_func) code.putln("") if freelist_size: code.putln("static %s[%d];" % ( scope.parent_type.declaration_code(freelist_name), freelist_size)) code.putln("static int %s = 0;" % freecount_name) code.putln("") code.putln( "static PyObject *%s(PyTypeObject *t, %sPyObject *a, %sPyObject *k) {" % (slot_func, unused_marker, unused_marker)) need_self_cast = (type.vtabslot_cname or (py_buffers or memoryview_slices or py_attrs) or cpp_class_attrs) if need_self_cast: code.putln("%s;" % scope.parent_type.declaration_code("p")) if base_type: tp_new = TypeSlots.get_base_slot_function(scope, tp_slot) if tp_new is None: tp_new = "%s->tp_new" % base_type.typeptr_cname code.putln("PyObject *o = %s(t, a, k);" % tp_new) else: code.putln("PyObject *o;") if freelist_size: code.globalstate.use_utility_code( UtilityCode.load_cached("IncludeStringH", "StringTools.c")) if is_final_type: type_safety_check = '' else: type_safety_check = ' & ((t->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0)' obj_struct = type.declaration_code("", deref=True) code.putln("if (CYTHON_COMPILING_IN_CPYTHON && likely((%s > 0) & (t->tp_basicsize == sizeof(%s))%s)) {" % ( freecount_name, obj_struct, type_safety_check)) code.putln("o = (PyObject*)%s[--%s];" % ( freelist_name, freecount_name)) code.putln("memset(o, 0, sizeof(%s));" % obj_struct) code.putln("(void) PyObject_INIT(o, t);") if scope.needs_gc(): code.putln("PyObject_GC_Track(o);") code.putln("} else {") if not is_final_type: code.putln("if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {") code.putln("o = (*t->tp_alloc)(t, 0);") if not is_final_type: code.putln("} else {") code.putln("o = (PyObject *) PyBaseObject_Type.tp_new(t, %s, 0);" % Naming.empty_tuple) code.putln("}") code.putln("if (unlikely(!o)) return 0;") if freelist_size and not base_type: code.putln('}') if need_self_cast: code.putln("p = %s;" % type.cast_code("o")) #if need_self_cast: # self.generate_self_cast(scope, code) if type.vtabslot_cname: vtab_base_type = type while vtab_base_type.base_type and vtab_base_type.base_type.vtabstruct_cname: vtab_base_type = vtab_base_type.base_type if vtab_base_type is not type: struct_type_cast = "(struct %s*)" % vtab_base_type.vtabstruct_cname else: struct_type_cast = "" code.putln("p->%s = %s%s;" % ( type.vtabslot_cname, struct_type_cast, type.vtabptr_cname)) for entry in cpp_class_attrs: code.putln("new((void*)&(p->%s)) %s();" % (entry.cname, entry.type.empty_declaration_code())) for entry in py_attrs: code.put_init_var_to_py_none(entry, "p->%s", nanny=False) for entry in memoryview_slices: code.putln("p->%s.data = NULL;" % entry.cname) code.putln("p->%s.memview = NULL;" % entry.cname) for entry in py_buffers: code.putln("p->%s.obj = NULL;" % entry.cname) if cclass_entry.cname == '__pyx_memoryviewslice': code.putln("p->from_slice.memview = NULL;") if new_func_entry and new_func_entry.is_special: if new_func_entry.trivial_signature: cinit_args = "o, %s, NULL" % Naming.empty_tuple else: cinit_args = "o, a, k" code.putln( "if (unlikely(%s(%s) < 0)) {" % (new_func_entry.func_cname, cinit_args)) code.put_decref_clear("o", py_object_type, nanny=False) code.putln( "}") code.putln( "return o;") code.putln( "}") def generate_dealloc_function(self, scope, code): tp_slot = TypeSlots.ConstructorSlot("tp_dealloc", '__dealloc__') slot_func = scope.mangle_internal("tp_dealloc") base_type = scope.parent_type.base_type if tp_slot.slot_code(scope) != slot_func: return # never used slot_func_cname = scope.mangle_internal("tp_dealloc") code.putln("") code.putln( "static void %s(PyObject *o) {" % slot_func_cname) is_final_type = scope.parent_type.is_final_type needs_gc = scope.needs_gc() weakref_slot = scope.lookup_here("__weakref__") if weakref_slot not in scope.var_entries: weakref_slot = None _, (py_attrs, _, memoryview_slices) = scope.get_refcounted_entries() cpp_class_attrs = [entry for entry in scope.var_entries if entry.type.is_cpp_class] if py_attrs or cpp_class_attrs or memoryview_slices or weakref_slot: self.generate_self_cast(scope, code) if not is_final_type: # in Py3.4+, call tp_finalize() as early as possible code.putln("#if PY_VERSION_HEX >= 0x030400a1") if needs_gc: finalised_check = '!_PyGC_FINALIZED(o)' else: finalised_check = ( '(!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))') code.putln("if (unlikely(Py_TYPE(o)->tp_finalize) && %s) {" % finalised_check) # if instance was resurrected by finaliser, return code.putln("if (PyObject_CallFinalizerFromDealloc(o)) return;") code.putln("}") code.putln("#endif") if needs_gc: # We must mark this object as (gc) untracked while tearing # it down, lest the garbage collection is invoked while # running this destructor. code.putln("PyObject_GC_UnTrack(o);") # call the user's __dealloc__ self.generate_usr_dealloc_call(scope, code) if weakref_slot: code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);") for entry in cpp_class_attrs: code.putln("__Pyx_call_destructor(p->%s);" % entry.cname) for entry in py_attrs: code.put_xdecref_clear("p->%s" % entry.cname, entry.type, nanny=False, clear_before_decref=True) for entry in memoryview_slices: code.put_xdecref_memoryviewslice("p->%s" % entry.cname, have_gil=True) if base_type: if needs_gc: # The base class deallocator probably expects this to be tracked, # so undo the untracking above. if base_type.scope and base_type.scope.needs_gc(): code.putln("PyObject_GC_Track(o);") else: code.putln("#if CYTHON_COMPILING_IN_CPYTHON") code.putln("if (PyType_IS_GC(Py_TYPE(o)->tp_base))") code.putln("#endif") code.putln("PyObject_GC_Track(o);") tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot) if tp_dealloc is not None: code.putln("%s(o);" % tp_dealloc) elif base_type.is_builtin_type: code.putln("%s->tp_dealloc(o);" % base_type.typeptr_cname) else: # This is an externally defined type. Calling through the # cimported base type pointer directly interacts badly with # the module cleanup, which may already have cleared it. # In that case, fall back to traversing the type hierarchy. base_cname = base_type.typeptr_cname code.putln("if (likely(%s)) %s->tp_dealloc(o); " "else __Pyx_call_next_tp_dealloc(o, %s);" % ( base_cname, base_cname, slot_func_cname)) code.globalstate.use_utility_code( UtilityCode.load_cached("CallNextTpDealloc", "ExtensionTypes.c")) else: freelist_size = scope.directives.get('freelist', 0) if freelist_size: freelist_name = scope.mangle_internal(Naming.freelist_name) freecount_name = scope.mangle_internal(Naming.freecount_name) if is_final_type: type_safety_check = '' else: type_safety_check = ( ' & ((Py_TYPE(o)->tp_flags & (Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_HEAPTYPE)) == 0)') type = scope.parent_type code.putln("if (CYTHON_COMPILING_IN_CPYTHON && ((%s < %d) & (Py_TYPE(o)->tp_basicsize == sizeof(%s))%s)) {" % ( freecount_name, freelist_size, type.declaration_code("", deref=True), type_safety_check)) code.putln("%s[%s++] = %s;" % ( freelist_name, freecount_name, type.cast_code("o"))) code.putln("} else {") code.putln("(*Py_TYPE(o)->tp_free)(o);") if freelist_size: code.putln("}") code.putln( "}") def generate_usr_dealloc_call(self, scope, code): entry = scope.lookup_here("__dealloc__") if not entry: return code.putln("{") code.putln("PyObject *etype, *eval, *etb;") code.putln("PyErr_Fetch(&etype, &eval, &etb);") code.putln("++Py_REFCNT(o);") code.putln("%s(o);" % entry.func_cname) code.putln("--Py_REFCNT(o);") code.putln("PyErr_Restore(etype, eval, etb);") code.putln("}") def generate_traverse_function(self, scope, code, cclass_entry): tp_slot = TypeSlots.GCDependentSlot("tp_traverse") slot_func = scope.mangle_internal("tp_traverse") base_type = scope.parent_type.base_type if tp_slot.slot_code(scope) != slot_func: return # never used code.putln("") code.putln( "static int %s(PyObject *o, visitproc v, void *a) {" % slot_func) have_entries, (py_attrs, py_buffers, memoryview_slices) = ( scope.get_refcounted_entries(include_gc_simple=False)) if base_type or py_attrs: code.putln("int e;") if py_attrs or py_buffers: self.generate_self_cast(scope, code) if base_type: # want to call it explicitly if possible so inlining can be performed static_call = TypeSlots.get_base_slot_function(scope, tp_slot) if static_call: code.putln("e = %s(o, v, a); if (e) return e;" % static_call) elif base_type.is_builtin_type: base_cname = base_type.typeptr_cname code.putln("if (!%s->tp_traverse); else { e = %s->tp_traverse(o,v,a); if (e) return e; }" % ( base_cname, base_cname)) else: # This is an externally defined type. Calling through the # cimported base type pointer directly interacts badly with # the module cleanup, which may already have cleared it. # In that case, fall back to traversing the type hierarchy. base_cname = base_type.typeptr_cname code.putln("e = ((likely(%s)) ? ((%s->tp_traverse) ? %s->tp_traverse(o, v, a) : 0) : __Pyx_call_next_tp_traverse(o, v, a, %s)); if (e) return e;" % ( base_cname, base_cname, base_cname, slot_func)) code.globalstate.use_utility_code( UtilityCode.load_cached("CallNextTpTraverse", "ExtensionTypes.c")) for entry in py_attrs: var_code = "p->%s" % entry.cname code.putln( "if (%s) {" % var_code) if entry.type.is_extension_type: var_code = "((PyObject*)%s)" % var_code code.putln( "e = (*v)(%s, a); if (e) return e;" % var_code) code.putln( "}") # Traverse buffer exporting objects. # Note: not traversing memoryview attributes of memoryview slices! # When triggered by the GC, it would cause multiple visits (gc_refs # subtractions which is not matched by its reference count!) for entry in py_buffers: cname = entry.cname + ".obj" code.putln("if (p->%s) {" % cname) code.putln( "e = (*v)(p->%s, a); if (e) return e;" % cname) code.putln("}") code.putln( "return 0;") code.putln( "}") def generate_clear_function(self, scope, code, cclass_entry): tp_slot = TypeSlots.GCDependentSlot("tp_clear") slot_func = scope.mangle_internal("tp_clear") base_type = scope.parent_type.base_type if tp_slot.slot_code(scope) != slot_func: return # never used have_entries, (py_attrs, py_buffers, memoryview_slices) = ( scope.get_refcounted_entries(include_gc_simple=False)) if py_attrs or py_buffers or base_type: unused = '' else: unused = 'CYTHON_UNUSED ' code.putln("") code.putln("static int %s(%sPyObject *o) {" % (slot_func, unused)) if py_attrs and Options.clear_to_none: code.putln("PyObject* tmp;") if py_attrs or py_buffers: self.generate_self_cast(scope, code) if base_type: # want to call it explicitly if possible so inlining can be performed static_call = TypeSlots.get_base_slot_function(scope, tp_slot) if static_call: code.putln("%s(o);" % static_call) elif base_type.is_builtin_type: base_cname = base_type.typeptr_cname code.putln("if (!%s->tp_clear); else %s->tp_clear(o);" % ( base_cname, base_cname)) else: # This is an externally defined type. Calling through the # cimported base type pointer directly interacts badly with # the module cleanup, which may already have cleared it. # In that case, fall back to traversing the type hierarchy. base_cname = base_type.typeptr_cname code.putln("if (likely(%s)) { if (%s->tp_clear) %s->tp_clear(o); } else __Pyx_call_next_tp_clear(o, %s);" % ( base_cname, base_cname, base_cname, slot_func)) code.globalstate.use_utility_code( UtilityCode.load_cached("CallNextTpClear", "ExtensionTypes.c")) if Options.clear_to_none: for entry in py_attrs: name = "p->%s" % entry.cname code.putln("tmp = ((PyObject*)%s);" % name) if entry.is_declared_generic: code.put_init_to_py_none(name, py_object_type, nanny=False) else: code.put_init_to_py_none(name, entry.type, nanny=False) code.putln("Py_XDECREF(tmp);") else: for entry in py_attrs: code.putln("Py_CLEAR(p->%s);" % entry.cname) for entry in py_buffers: # Note: shouldn't this call __Pyx_ReleaseBuffer ?? code.putln("Py_CLEAR(p->%s.obj);" % entry.cname) if cclass_entry.cname == '__pyx_memoryviewslice': code.putln("__PYX_XDEC_MEMVIEW(&p->from_slice, 1);") code.putln( "return 0;") code.putln( "}") def generate_getitem_int_function(self, scope, code): # This function is put into the sq_item slot when # a __getitem__ method is present. It converts its # argument to a Python integer and calls mp_subscript. code.putln( "static PyObject *%s(PyObject *o, Py_ssize_t i) {" % scope.mangle_internal("sq_item")) code.putln( "PyObject *r;") code.putln( "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;") code.putln( "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);") code.putln( "Py_DECREF(x);") code.putln( "return r;") code.putln( "}") def generate_ass_subscript_function(self, scope, code): # Setting and deleting an item are both done through # the ass_subscript method, so we dispatch to user's __setitem__ # or __delitem__, or raise an exception. base_type = scope.parent_type.base_type set_entry = scope.lookup_here("__setitem__") del_entry = scope.lookup_here("__delitem__") code.putln("") code.putln( "static int %s(PyObject *o, PyObject *i, PyObject *v) {" % scope.mangle_internal("mp_ass_subscript")) code.putln( "if (v) {") if set_entry: code.putln( "return %s(o, i, v);" % set_entry.func_cname) else: self.generate_guarded_basetype_call( base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code) code.putln( "PyErr_Format(PyExc_NotImplementedError,") code.putln( ' "Subscript assignment not supported by %.200s", Py_TYPE(o)->tp_name);') code.putln( "return -1;") code.putln( "}") code.putln( "else {") if del_entry: code.putln( "return %s(o, i);" % del_entry.func_cname) else: self.generate_guarded_basetype_call( base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code) code.putln( "PyErr_Format(PyExc_NotImplementedError,") code.putln( ' "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);') code.putln( "return -1;") code.putln( "}") code.putln( "}") def generate_guarded_basetype_call( self, base_type, substructure, slot, args, code): if base_type: base_tpname = base_type.typeptr_cname if substructure: code.putln( "if (%s->%s && %s->%s->%s)" % ( base_tpname, substructure, base_tpname, substructure, slot)) code.putln( " return %s->%s->%s(%s);" % ( base_tpname, substructure, slot, args)) else: code.putln( "if (%s->%s)" % ( base_tpname, slot)) code.putln( " return %s->%s(%s);" % ( base_tpname, slot, args)) def generate_ass_slice_function(self, scope, code): # Setting and deleting a slice are both done through # the ass_slice method, so we dispatch to user's __setslice__ # or __delslice__, or raise an exception. base_type = scope.parent_type.base_type set_entry = scope.lookup_here("__setslice__") del_entry = scope.lookup_here("__delslice__") code.putln("") code.putln( "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" % scope.mangle_internal("sq_ass_slice")) code.putln( "if (v) {") if set_entry: code.putln( "return %s(o, i, j, v);" % set_entry.func_cname) else: self.generate_guarded_basetype_call( base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code) code.putln( "PyErr_Format(PyExc_NotImplementedError,") code.putln( ' "2-element slice assignment not supported by %.200s", Py_TYPE(o)->tp_name);') code.putln( "return -1;") code.putln( "}") code.putln( "else {") if del_entry: code.putln( "return %s(o, i, j);" % del_entry.func_cname) else: self.generate_guarded_basetype_call( base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code) code.putln( "PyErr_Format(PyExc_NotImplementedError,") code.putln( ' "2-element slice deletion not supported by %.200s", Py_TYPE(o)->tp_name);') code.putln( "return -1;") code.putln( "}") code.putln( "}") def generate_getattro_function(self, scope, code): # First try to get the attribute using __getattribute__, if defined, or # PyObject_GenericGetAttr. # # If that raises an AttributeError, call the __getattr__ if defined. # # In both cases, defined can be in this class, or any base class. def lookup_here_or_base(n,type=None): # Recursive lookup if type is None: type = scope.parent_type r = type.scope.lookup_here(n) if r is None and \ type.base_type is not None: return lookup_here_or_base(n,type.base_type) else: return r getattr_entry = lookup_here_or_base("__getattr__") getattribute_entry = lookup_here_or_base("__getattribute__") code.putln("") code.putln( "static PyObject *%s(PyObject *o, PyObject *n) {" % scope.mangle_internal("tp_getattro")) if getattribute_entry is not None: code.putln( "PyObject *v = %s(o, n);" % getattribute_entry.func_cname) else: code.putln( "PyObject *v = PyObject_GenericGetAttr(o, n);") if getattr_entry is not None: code.putln( "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {") code.putln( "PyErr_Clear();") code.putln( "v = %s(o, n);" % getattr_entry.func_cname) code.putln( "}") code.putln( "return v;") code.putln( "}") def generate_setattro_function(self, scope, code): # Setting and deleting an attribute are both done through # the setattro method, so we dispatch to user's __setattr__ # or __delattr__ or fall back on PyObject_GenericSetAttr. base_type = scope.parent_type.base_type set_entry = scope.lookup_here("__setattr__") del_entry = scope.lookup_here("__delattr__") code.putln("") code.putln( "static int %s(PyObject *o, PyObject *n, PyObject *v) {" % scope.mangle_internal("tp_setattro")) code.putln( "if (v) {") if set_entry: code.putln( "return %s(o, n, v);" % set_entry.func_cname) else: self.generate_guarded_basetype_call( base_type, None, "tp_setattro", "o, n, v", code) code.putln( "return PyObject_GenericSetAttr(o, n, v);") code.putln( "}") code.putln( "else {") if del_entry: code.putln( "return %s(o, n);" % del_entry.func_cname) else: self.generate_guarded_basetype_call( base_type, None, "tp_setattro", "o, n, v", code) code.putln( "return PyObject_GenericSetAttr(o, n, 0);") code.putln( "}") code.putln( "}") def generate_descr_get_function(self, scope, code): # The __get__ function of a descriptor object can be # called with NULL for the second or third arguments # under some circumstances, so we replace them with # None in that case. user_get_entry = scope.lookup_here("__get__") code.putln("") code.putln( "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" % scope.mangle_internal("tp_descr_get")) code.putln( "PyObject *r = 0;") code.putln( "if (!i) i = Py_None;") code.putln( "if (!c) c = Py_None;") #code.put_incref("i", py_object_type) #code.put_incref("c", py_object_type) code.putln( "r = %s(o, i, c);" % user_get_entry.func_cname) #code.put_decref("i", py_object_type) #code.put_decref("c", py_object_type) code.putln( "return r;") code.putln( "}") def generate_descr_set_function(self, scope, code): # Setting and deleting are both done through the __set__ # method of a descriptor, so we dispatch to user's __set__ # or __delete__ or raise an exception. base_type = scope.parent_type.base_type user_set_entry = scope.lookup_here("__set__") user_del_entry = scope.lookup_here("__delete__") code.putln("") code.putln( "static int %s(PyObject *o, PyObject *i, PyObject *v) {" % scope.mangle_internal("tp_descr_set")) code.putln( "if (v) {") if user_set_entry: code.putln( "return %s(o, i, v);" % user_set_entry.func_cname) else: self.generate_guarded_basetype_call( base_type, None, "tp_descr_set", "o, i, v", code) code.putln( 'PyErr_SetString(PyExc_NotImplementedError, "__set__");') code.putln( "return -1;") code.putln( "}") code.putln( "else {") if user_del_entry: code.putln( "return %s(o, i);" % user_del_entry.func_cname) else: self.generate_guarded_basetype_call( base_type, None, "tp_descr_set", "o, i, v", code) code.putln( 'PyErr_SetString(PyExc_NotImplementedError, "__delete__");') code.putln( "return -1;") code.putln( "}") code.putln( "}") def generate_property_accessors(self, cclass_scope, code): for entry in cclass_scope.property_entries: property_scope = entry.scope if property_scope.defines_any(["__get__"]): self.generate_property_get_function(entry, code) if property_scope.defines_any(["__set__", "__del__"]): self.generate_property_set_function(entry, code) def generate_property_get_function(self, property_entry, code): property_scope = property_entry.scope property_entry.getter_cname = property_scope.parent_scope.mangle( Naming.prop_get_prefix, property_entry.name) get_entry = property_scope.lookup_here("__get__") code.putln("") code.putln( "static PyObject *%s(PyObject *o, CYTHON_UNUSED void *x) {" % property_entry.getter_cname) code.putln( "return %s(o);" % get_entry.func_cname) code.putln( "}") def generate_property_set_function(self, property_entry, code): property_scope = property_entry.scope property_entry.setter_cname = property_scope.parent_scope.mangle( Naming.prop_set_prefix, property_entry.name) set_entry = property_scope.lookup_here("__set__") del_entry = property_scope.lookup_here("__del__") code.putln("") code.putln( "static int %s(PyObject *o, PyObject *v, CYTHON_UNUSED void *x) {" % property_entry.setter_cname) code.putln( "if (v) {") if set_entry: code.putln( "return %s(o, v);" % set_entry.func_cname) else: code.putln( 'PyErr_SetString(PyExc_NotImplementedError, "__set__");') code.putln( "return -1;") code.putln( "}") code.putln( "else {") if del_entry: code.putln( "return %s(o);" % del_entry.func_cname) else: code.putln( 'PyErr_SetString(PyExc_NotImplementedError, "__del__");') code.putln( "return -1;") code.putln( "}") code.putln( "}") def generate_typeobj_definition(self, modname, entry, code): type = entry.type scope = type.scope for suite in TypeSlots.substructures: suite.generate_substructure(scope, code) code.putln("") if entry.visibility == 'public': header = "DL_EXPORT(PyTypeObject) %s = {" else: header = "static PyTypeObject %s = {" #code.putln(header % scope.parent_type.typeobj_cname) code.putln(header % type.typeobj_cname) code.putln( "PyVarObject_HEAD_INIT(0, 0)") code.putln( '"%s.%s", /*tp_name*/' % ( self.full_module_name, scope.class_name)) if type.typedef_flag: objstruct = type.objstruct_cname else: objstruct = "struct %s" % type.objstruct_cname code.putln( "sizeof(%s), /*tp_basicsize*/" % objstruct) code.putln( "0, /*tp_itemsize*/") for slot in TypeSlots.slot_table: slot.generate(scope, code) code.putln( "};") def generate_method_table(self, env, code): if env.is_c_class_scope and not env.pyfunc_entries: return code.putln("") code.putln( "static PyMethodDef %s[] = {" % env.method_table_cname) for entry in env.pyfunc_entries: if not entry.fused_cfunction: code.put_pymethoddef(entry, ",") code.putln( "{0, 0, 0, 0}") code.putln( "};") def generate_getset_table(self, env, code): if env.property_entries: code.putln("") code.putln( "static struct PyGetSetDef %s[] = {" % env.getset_table_cname) for entry in env.property_entries: if entry.doc: doc_code = "%s" % code.get_string_const(entry.doc) else: doc_code = "0" code.putln( '{(char *)"%s", %s, %s, %s, 0},' % ( entry.name, entry.getter_cname or "0", entry.setter_cname or "0", doc_code)) code.putln( "{0, 0, 0, 0, 0}") code.putln( "};") def create_import_star_conversion_utility_code(self, env): # Create all conversion helpers that are needed for "import *" assignments. # Must be done before code generation to support CythonUtilityCode. for name, entry in env.entries.items(): if entry.is_cglobal and entry.used: if not entry.type.is_pyobject: entry.type.create_from_py_utility_code(env) def generate_import_star(self, env, code): env.use_utility_code(UtilityCode.load_cached("CStringEquals", "StringTools.c")) code.putln() code.enter_cfunc_scope() # as we need labels code.putln("static int %s(PyObject *o, PyObject* py_name, char *name) {" % Naming.import_star_set) code.putln("static const char* internal_type_names[] = {") for name, entry in sorted(env.entries.items()): if entry.is_type: code.putln('"%s",' % name) code.putln("0") code.putln("};") code.putln("const char** type_name = internal_type_names;") code.putln("while (*type_name) {") code.putln("if (__Pyx_StrEq(name, *type_name)) {") code.putln('PyErr_Format(PyExc_TypeError, "Cannot overwrite C type %s", name);') code.putln('goto bad;') code.putln("}") code.putln("type_name++;") code.putln("}") old_error_label = code.new_error_label() code.putln("if (0);") # so the first one can be "else if" for name, entry in env.entries.items(): if entry.is_cglobal and entry.used: code.putln('else if (__Pyx_StrEq(name, "%s")) {' % name) if entry.type.is_pyobject: if entry.type.is_extension_type or entry.type.is_builtin_type: code.putln("if (!(%s)) %s;" % ( entry.type.type_test_code("o"), code.error_goto(entry.pos))) code.putln("Py_INCREF(o);") code.put_decref(entry.cname, entry.type, nanny=False) code.putln("%s = %s;" % ( entry.cname, PyrexTypes.typecast(entry.type, py_object_type, "o"))) elif entry.type.create_from_py_utility_code(env): # if available, utility code was already created in self.prepare_utility_code() rhs = "%s(o)" % entry.type.from_py_function if entry.type.is_enum: rhs = PyrexTypes.typecast(entry.type, PyrexTypes.c_long_type, rhs) code.putln("%s = %s; if (%s) %s;" % ( entry.cname, rhs, entry.type.error_condition(entry.cname), code.error_goto(entry.pos))) else: code.putln('PyErr_Format(PyExc_TypeError, "Cannot convert Python object %s to %s");' % ( name, entry.type)) code.putln(code.error_goto(entry.pos)) code.putln("}") code.putln("else {") code.putln("if (PyObject_SetAttr(%s, py_name, o) < 0) goto bad;" % Naming.module_cname) code.putln("}") code.putln("return 0;") if code.label_used(code.error_label): code.put_label(code.error_label) # This helps locate the offending name. code.put_add_traceback(self.full_module_name) code.error_label = old_error_label code.putln("bad:") code.putln("return -1;") code.putln("}") code.putln("") code.putln(UtilityCode.load_cached("ImportStar", "ImportExport.c").impl) code.exit_cfunc_scope() # done with labels def generate_module_init_func(self, imported_modules, env, code): code.enter_cfunc_scope() code.putln("") header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name header3 = "PyMODINIT_FUNC PyInit_%s(void)" % env.module_name code.putln("#if PY_MAJOR_VERSION < 3") code.putln("%s; /*proto*/" % header2) code.putln(header2) code.putln("#else") code.putln("%s; /*proto*/" % header3) code.putln(header3) code.putln("#endif") code.putln("{") tempdecl_code = code.insertion_point() profile = code.globalstate.directives['profile'] linetrace = code.globalstate.directives['linetrace'] if profile or linetrace: code.globalstate.use_utility_code(UtilityCode.load_cached("Profile", "Profile.c")) code.put_declare_refcount_context() if profile or linetrace: tempdecl_code.put_trace_declarations() code.put_trace_frame_init() code.putln("#if CYTHON_REFNANNY") code.putln("__Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"refnanny\");") code.putln("if (!__Pyx_RefNanny) {") code.putln(" PyErr_Clear();") code.putln(" __Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"Cython.Runtime.refnanny\");") code.putln(" if (!__Pyx_RefNanny)") code.putln(" Py_FatalError(\"failed to import 'refnanny' module\");") code.putln("}") code.putln("#endif") code.put_setup_refcount_context(header3) env.use_utility_code(UtilityCode.load("CheckBinaryVersion", "ModuleSetupCode.c")) code.put_error_if_neg(self.pos, "__Pyx_check_binary_version()") code.putln("%s = PyTuple_New(0); %s" % ( Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos))) code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % ( Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos))) for ext_type in ('CyFunction', 'FusedFunction', 'Coroutine', 'Generator', 'StopAsyncIteration'): code.putln("#ifdef __Pyx_%s_USED" % ext_type) code.put_error_if_neg(self.pos, "__pyx_%s_init()" % ext_type) code.putln("#endif") code.putln("/*--- Library function declarations ---*/") env.generate_library_function_declarations(code) code.putln("/*--- Threads initialization code ---*/") code.putln("#if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS") code.putln("#ifdef WITH_THREAD /* Python build with threading support? */") code.putln("PyEval_InitThreads();") code.putln("#endif") code.putln("#endif") code.putln("/*--- Module creation code ---*/") self.generate_module_creation_code(env, code) code.putln("/*--- Initialize various global constants etc. ---*/") code.put_error_if_neg(self.pos, "__Pyx_InitGlobals()") code.putln("#if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)") code.put_error_if_neg(self.pos, "__Pyx_init_sys_getdefaultencoding_params()") code.putln("#endif") __main__name = code.globalstate.get_py_string_const( EncodedString("__main__"), identifier=True) code.putln("if (%s%s) {" % (Naming.module_is_main, self.full_module_name.replace('.', '__'))) code.put_error_if_neg(self.pos, 'PyObject_SetAttrString(%s, "__name__", %s)' % ( env.module_cname, __main__name.cname)) code.putln("}") # set up __file__ and __path__, then add the module to sys.modules self.generate_module_import_setup(env, code) if Options.cache_builtins: code.putln("/*--- Builtin init code ---*/") code.put_error_if_neg(self.pos, "__Pyx_InitCachedBuiltins()") code.putln("/*--- Constants init code ---*/") code.put_error_if_neg(self.pos, "__Pyx_InitCachedConstants()") code.putln("/*--- Global init code ---*/") self.generate_global_init_code(env, code) code.putln("/*--- Variable export code ---*/") self.generate_c_variable_export_code(env, code) code.putln("/*--- Function export code ---*/") self.generate_c_function_export_code(env, code) code.putln("/*--- Type init code ---*/") self.generate_type_init_code(env, code) code.putln("/*--- Type import code ---*/") for module in imported_modules: self.generate_type_import_code_for_module(module, env, code) code.putln("/*--- Variable import code ---*/") for module in imported_modules: self.generate_c_variable_import_code_for_module(module, env, code) code.putln("/*--- Function import code ---*/") for module in imported_modules: self.specialize_fused_types(module) self.generate_c_function_import_code_for_module(module, env, code) code.putln("/*--- Execution code ---*/") code.mark_pos(None) code.putln("#if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)") code.put_error_if_neg(self.pos, "__Pyx_patch_abc()") code.putln("#endif") if profile or linetrace: code.put_trace_call(header3, self.pos, nogil=not code.funcstate.gil_owned) code.funcstate.can_trace = True self.body.generate_execution_code(code) if profile or linetrace: code.funcstate.can_trace = False code.put_trace_return("Py_None", nogil=not code.funcstate.gil_owned) code.putln() code.putln("/*--- Wrapped vars code ---*/") self.generate_wrapped_entries_code(env, code) code.putln() if Options.generate_cleanup_code: code.globalstate.use_utility_code( UtilityCode.load_cached("RegisterModuleCleanup", "ModuleSetupCode.c")) code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos)) code.put_goto(code.return_label) code.put_label(code.error_label) for cname, type in code.funcstate.all_managed_temps(): code.put_xdecref(cname, type) code.putln('if (%s) {' % env.module_cname) code.putln('if (%s) {' % env.module_dict_cname) code.put_add_traceback("init %s" % env.qualified_name) code.globalstate.use_utility_code(Nodes.traceback_utility_code) # Module reference and module dict are in global variables which might still be needed # for cleanup, atexit code, etc., so leaking is better than crashing. # At least clearing the module dict here might be a good idea, but could still break # user code in atexit or other global registries. ##code.put_decref_clear(env.module_dict_cname, py_object_type, nanny=False) code.putln('}') code.put_decref_clear(env.module_cname, py_object_type, nanny=False) code.putln('} else if (!PyErr_Occurred()) {') code.putln('PyErr_SetString(PyExc_ImportError, "init %s");' % env.qualified_name) code.putln('}') code.put_label(code.return_label) code.put_finish_refcount_context() code.putln("#if PY_MAJOR_VERSION < 3") code.putln("return;") code.putln("#else") code.putln("return %s;" % env.module_cname) code.putln("#endif") code.putln('}') tempdecl_code.put_temp_declarations(code.funcstate) code.exit_cfunc_scope() def generate_module_import_setup(self, env, code): module_path = env.directives['set_initial_path'] if module_path == 'SOURCEFILE': module_path = self.pos[0].filename if module_path: code.putln('if (PyObject_SetAttrString(%s, "__file__", %s) < 0) %s;' % ( env.module_cname, code.globalstate.get_py_string_const( EncodedString(decode_filename(module_path))).cname, code.error_goto(self.pos))) if env.is_package: # set __path__ to mark the module as package temp = code.funcstate.allocate_temp(py_object_type, True) code.putln('%s = Py_BuildValue("[O]", %s); %s' % ( temp, code.globalstate.get_py_string_const( EncodedString(decode_filename( os.path.dirname(module_path)))).cname, code.error_goto_if_null(temp, self.pos))) code.put_gotref(temp) code.putln( 'if (PyObject_SetAttrString(%s, "__path__", %s) < 0) %s;' % ( env.module_cname, temp, code.error_goto(self.pos))) code.put_decref_clear(temp, py_object_type) code.funcstate.release_temp(temp) elif env.is_package: # packages require __path__, so all we can do is try to figure # out the module path at runtime by rerunning the import lookup package_name, _ = self.full_module_name.rsplit('.', 1) if '.' in package_name: parent_name = '"%s"' % (package_name.rsplit('.', 1)[0],) else: parent_name = 'NULL' code.globalstate.use_utility_code(UtilityCode.load( "SetPackagePathFromImportLib", "ImportExport.c")) code.putln(code.error_goto_if_neg( '__Pyx_SetPackagePathFromImportLib(%s, %s)' % ( parent_name, code.globalstate.get_py_string_const( EncodedString(env.module_name)).cname), self.pos)) # CPython may not have put us into sys.modules yet, but relative imports and reimports require it fq_module_name = self.full_module_name if fq_module_name.endswith('.__init__'): fq_module_name = fq_module_name[:-len('.__init__')] code.putln("#if PY_MAJOR_VERSION >= 3") code.putln("{") code.putln("PyObject *modules = PyImport_GetModuleDict(); %s" % code.error_goto_if_null("modules", self.pos)) code.putln('if (!PyDict_GetItemString(modules, "%s")) {' % fq_module_name) code.putln(code.error_goto_if_neg('PyDict_SetItemString(modules, "%s", %s)' % ( fq_module_name, env.module_cname), self.pos)) code.putln("}") code.putln("}") code.putln("#endif") def generate_module_cleanup_func(self, env, code): if not Options.generate_cleanup_code: return code.putln('static void %s(CYTHON_UNUSED PyObject *self) {' % Naming.cleanup_cname) if Options.generate_cleanup_code >= 2: code.putln("/*--- Global cleanup code ---*/") rev_entries = list(env.var_entries) rev_entries.reverse() for entry in rev_entries: if entry.visibility != 'extern': if entry.type.is_pyobject and entry.used: code.put_xdecref_clear( entry.cname, entry.type, clear_before_decref=True, nanny=False) code.putln("__Pyx_CleanupGlobals();") if Options.generate_cleanup_code >= 3: code.putln("/*--- Type import cleanup code ---*/") for ext_type in sorted(env.types_imported, key=operator.attrgetter('typeptr_cname')): code.put_xdecref_clear( ext_type.typeptr_cname, ext_type, clear_before_decref=True, nanny=False) if Options.cache_builtins: code.putln("/*--- Builtin cleanup code ---*/") for entry in env.cached_builtins: code.put_xdecref_clear( entry.cname, PyrexTypes.py_object_type, clear_before_decref=True, nanny=False) code.putln("/*--- Intern cleanup code ---*/") code.put_decref_clear(Naming.empty_tuple, PyrexTypes.py_object_type, clear_before_decref=True, nanny=False) for entry in env.c_class_entries: cclass_type = entry.type if cclass_type.is_external or cclass_type.base_type: continue if cclass_type.scope.directives.get('freelist', 0): scope = cclass_type.scope freelist_name = scope.mangle_internal(Naming.freelist_name) freecount_name = scope.mangle_internal(Naming.freecount_name) code.putln("while (%s > 0) {" % freecount_name) code.putln("PyObject* o = (PyObject*)%s[--%s];" % ( freelist_name, freecount_name)) code.putln("(*Py_TYPE(o)->tp_free)(o);") code.putln("}") # for entry in env.pynum_entries: # code.put_decref_clear(entry.cname, # PyrexTypes.py_object_type, # nanny=False) # for entry in env.all_pystring_entries: # if entry.is_interned: # code.put_decref_clear(entry.pystring_cname, # PyrexTypes.py_object_type, # nanny=False) # for entry in env.default_entries: # if entry.type.is_pyobject and entry.used: # code.putln("Py_DECREF(%s); %s = 0;" % ( # code.entry_as_pyobject(entry), entry.cname)) code.putln('#if CYTHON_COMPILING_IN_PYPY') code.putln('Py_CLEAR(%s);' % Naming.builtins_cname) code.putln('#endif') code.put_decref_clear(env.module_dict_cname, py_object_type, nanny=False, clear_before_decref=True) def generate_main_method(self, env, code): module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__')) if Options.embed == "main": wmain = "wmain" else: wmain = Options.embed main_method = UtilityCode.load_cached("MainFunction", "Embed.c") code.globalstate.use_utility_code( main_method.specialize( module_name=env.module_name, module_is_main=module_is_main, main_method=Options.embed, wmain_method=wmain)) def generate_pymoduledef_struct(self, env, code): if env.doc: doc = "%s" % code.get_string_const(env.doc) else: doc = "0" if Options.generate_cleanup_code: cleanup_func = "(freefunc)%s" % Naming.cleanup_cname else: cleanup_func = 'NULL' code.putln("") code.putln("#if PY_MAJOR_VERSION >= 3") code.putln("static struct PyModuleDef %s = {" % Naming.pymoduledef_cname) code.putln("#if PY_VERSION_HEX < 0x03020000") # fix C compiler warnings due to missing initialisers code.putln(" { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },") code.putln("#else") code.putln(" PyModuleDef_HEAD_INIT,") code.putln("#endif") code.putln(' "%s",' % env.module_name) code.putln(" %s, /* m_doc */" % doc) code.putln(" -1, /* m_size */") code.putln(" %s /* m_methods */," % env.method_table_cname) code.putln(" NULL, /* m_reload */") code.putln(" NULL, /* m_traverse */") code.putln(" NULL, /* m_clear */") code.putln(" %s /* m_free */" % cleanup_func) code.putln("};") code.putln("#endif") def generate_module_creation_code(self, env, code): # Generate code to create the module object and # install the builtins. if env.doc: doc = "%s" % code.get_string_const(env.doc) else: doc = "0" code.putln("#if PY_MAJOR_VERSION < 3") code.putln( '%s = Py_InitModule4("%s", %s, %s, 0, PYTHON_API_VERSION); Py_XINCREF(%s);' % ( env.module_cname, env.module_name, env.method_table_cname, doc, env.module_cname)) code.putln("#else") code.putln( "%s = PyModule_Create(&%s);" % ( env.module_cname, Naming.pymoduledef_cname)) code.putln("#endif") code.putln(code.error_goto_if_null(env.module_cname, self.pos)) code.putln( "%s = PyModule_GetDict(%s); %s" % ( env.module_dict_cname, env.module_cname, code.error_goto_if_null(env.module_dict_cname, self.pos))) code.put_incref(env.module_dict_cname, py_object_type, nanny=False) code.putln( '%s = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); %s' % ( Naming.builtins_cname, code.error_goto_if_null(Naming.builtins_cname, self.pos))) code.putln('#if CYTHON_COMPILING_IN_PYPY') code.putln('Py_INCREF(%s);' % Naming.builtins_cname) code.putln('#endif') code.putln( 'if (PyObject_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % ( env.module_cname, Naming.builtins_cname, code.error_goto(self.pos))) if Options.pre_import is not None: code.putln( '%s = PyImport_AddModule("%s"); %s' % ( Naming.preimport_cname, Options.pre_import, code.error_goto_if_null(Naming.preimport_cname, self.pos))) def generate_global_init_code(self, env, code): # Generate code to initialise global PyObject * # variables to None. for entry in env.var_entries: if entry.visibility != 'extern': if entry.used: entry.type.global_init_code(entry, code) def generate_wrapped_entries_code(self, env, code): for name, entry in env.entries.items(): if (entry.create_wrapper and not entry.is_type and entry.scope is env): if not entry.type.create_to_py_utility_code(env): error(entry.pos, "Cannot convert '%s' to Python object" % entry.type) code.putln("{") code.putln("PyObject* wrapped = %s(%s);" % ( entry.type.to_py_function, entry.cname)) code.putln(code.error_goto_if_null("wrapped", entry.pos)) code.putln( 'if (PyObject_SetAttrString(%s, "%s", wrapped) < 0) %s;' % ( env.module_cname, name, code.error_goto(entry.pos))) code.putln("}") def generate_c_variable_export_code(self, env, code): # Generate code to create PyCFunction wrappers for exported C functions. entries = [] for entry in env.var_entries: if (entry.api or entry.defined_in_pxd or (Options.cimport_from_pyx and not entry.visibility == 'extern')): entries.append(entry) if entries: env.use_utility_code(UtilityCode.load_cached("VoidPtrExport", "ImportExport.c")) for entry in entries: signature = entry.type.empty_declaration_code() name = code.intern_identifier(entry.name) code.putln('if (__Pyx_ExportVoidPtr(%s, (void *)&%s, "%s") < 0) %s' % ( name, entry.cname, signature, code.error_goto(self.pos))) def generate_c_function_export_code(self, env, code): # Generate code to create PyCFunction wrappers for exported C functions. entries = [] for entry in env.cfunc_entries: if (entry.api or entry.defined_in_pxd or (Options.cimport_from_pyx and not entry.visibility == 'extern')): entries.append(entry) if entries: env.use_utility_code( UtilityCode.load_cached("FunctionExport", "ImportExport.c")) for entry in entries: signature = entry.type.signature_string() code.putln('if (__Pyx_ExportFunction("%s", (void (*)(void))%s, "%s") < 0) %s' % ( entry.name, entry.cname, signature, code.error_goto(self.pos))) def generate_type_import_code_for_module(self, module, env, code): # Generate type import code for all exported extension types in # an imported module. #if module.c_class_entries: for entry in module.c_class_entries: if entry.defined_in_pxd: self.generate_type_import_code(env, entry.type, entry.pos, code) def specialize_fused_types(self, pxd_env): """ If fused c(p)def functions are defined in an imported pxd, but not used in this implementation file, we still have fused entries and not specialized ones. This method replaces any fused entries with their specialized ones. """ for entry in pxd_env.cfunc_entries[:]: if entry.type.is_fused: # This call modifies the cfunc_entries in-place entry.type.get_all_specialized_function_types() def generate_c_variable_import_code_for_module(self, module, env, code): # Generate import code for all exported C functions in a cimported module. entries = [] for entry in module.var_entries: if entry.defined_in_pxd: entries.append(entry) if entries: env.use_utility_code( UtilityCode.load_cached("ModuleImport", "ImportExport.c")) env.use_utility_code( UtilityCode.load_cached("VoidPtrImport", "ImportExport.c")) temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True) code.putln( '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % ( temp, module.qualified_name, temp, code.error_goto(self.pos))) for entry in entries: if env is module: cname = entry.cname else: cname = module.mangle(Naming.varptr_prefix, entry.name) signature = entry.type.empty_declaration_code() code.putln( 'if (__Pyx_ImportVoidPtr(%s, "%s", (void **)&%s, "%s") < 0) %s' % ( temp, entry.name, cname, signature, code.error_goto(self.pos))) code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp)) def generate_c_function_import_code_for_module(self, module, env, code): # Generate import code for all exported C functions in a cimported module. entries = [] for entry in module.cfunc_entries: if entry.defined_in_pxd and entry.used: entries.append(entry) if entries: env.use_utility_code( UtilityCode.load_cached("ModuleImport", "ImportExport.c")) env.use_utility_code( UtilityCode.load_cached("FunctionImport", "ImportExport.c")) temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True) code.putln( '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % ( temp, module.qualified_name, temp, code.error_goto(self.pos))) for entry in entries: code.putln( 'if (__Pyx_ImportFunction(%s, "%s", (void (**)(void))&%s, "%s") < 0) %s' % ( temp, entry.name, entry.cname, entry.type.signature_string(), code.error_goto(self.pos))) code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp)) def generate_type_init_code(self, env, code): # Generate type import code for extern extension types # and type ready code for non-extern ones. for entry in env.c_class_entries: if entry.visibility == 'extern' and not entry.utility_code_definition: self.generate_type_import_code(env, entry.type, entry.pos, code) else: self.generate_base_type_import_code(env, entry, code) self.generate_exttype_vtable_init_code(entry, code) self.generate_type_ready_code(env, entry, code) self.generate_typeptr_assignment_code(entry, code) def generate_base_type_import_code(self, env, entry, code): base_type = entry.type.base_type if (base_type and base_type.module_name != env.qualified_name and not base_type.is_builtin_type and not entry.utility_code_definition): self.generate_type_import_code(env, base_type, self.pos, code) def generate_type_import_code(self, env, type, pos, code): # If not already done, generate code to import the typeobject of an # extension type defined in another module, and extract its C method # table pointer if any. if type in env.types_imported: return env.use_utility_code(UtilityCode.load_cached("TypeImport", "ImportExport.c")) self.generate_type_import_call(type, code, code.error_goto_if_null(type.typeptr_cname, pos)) if type.vtabptr_cname: code.globalstate.use_utility_code( UtilityCode.load_cached('GetVTable', 'ImportExport.c')) code.putln("%s = (struct %s*)__Pyx_GetVtable(%s->tp_dict); %s" % ( type.vtabptr_cname, type.vtabstruct_cname, type.typeptr_cname, code.error_goto_if_null(type.vtabptr_cname, pos))) env.types_imported.add(type) py3_type_name_map = {'str' : 'bytes', 'unicode' : 'str'} def generate_type_import_call(self, type, code, error_code): if type.typedef_flag: objstruct = type.objstruct_cname else: objstruct = "struct %s" % type.objstruct_cname sizeof_objstruct = objstruct module_name = type.module_name condition = replacement = None if module_name not in ('__builtin__', 'builtins'): module_name = '"%s"' % module_name else: module_name = '__Pyx_BUILTIN_MODULE_NAME' if type.name in Code.non_portable_builtins_map: condition, replacement = Code.non_portable_builtins_map[type.name] if objstruct in Code.basicsize_builtins_map: # Some builtin types have a tp_basicsize which differs from sizeof(...): sizeof_objstruct = Code.basicsize_builtins_map[objstruct] code.put('%s = __Pyx_ImportType(%s,' % ( type.typeptr_cname, module_name)) if condition and replacement: code.putln("") # start in new line code.putln("#if %s" % condition) code.putln('"%s",' % replacement) code.putln("#else") code.putln('"%s",' % type.name) code.putln("#endif") else: code.put(' "%s", ' % type.name) if sizeof_objstruct != objstruct: if not condition: code.putln("") # start in new line code.putln("#if CYTHON_COMPILING_IN_PYPY") code.putln('sizeof(%s),' % objstruct) code.putln("#else") code.putln('sizeof(%s),' % sizeof_objstruct) code.putln("#endif") else: code.put('sizeof(%s), ' % objstruct) code.putln('%i); %s' % ( not type.is_external or type.is_subclassed, error_code)) def generate_type_ready_code(self, env, entry, code): # Generate a call to PyType_Ready for an extension # type defined in this module. type = entry.type typeobj_cname = type.typeobj_cname scope = type.scope if scope: # could be None if there was an error if entry.visibility != 'extern': for slot in TypeSlots.slot_table: slot.generate_dynamic_init_code(scope, code) code.putln( "if (PyType_Ready(&%s) < 0) %s" % ( typeobj_cname, code.error_goto(entry.pos))) # Don't inherit tp_print from builtin types, restoring the # behavior of using tp_repr or tp_str instead. code.putln("%s.tp_print = 0;" % typeobj_cname) # Fix special method docstrings. This is a bit of a hack, but # unless we let PyType_Ready create the slot wrappers we have # a significant performance hit. (See trac #561.) for func in entry.type.scope.pyfunc_entries: is_buffer = func.name in ('__getbuffer__', '__releasebuffer__') if (func.is_special and Options.docstrings and func.wrapperbase_cname and not is_buffer): slot = TypeSlots.method_name_to_slot[func.name] preprocessor_guard = slot.preprocessor_guard_code() if preprocessor_guard: code.putln(preprocessor_guard) code.putln('#if CYTHON_COMPILING_IN_CPYTHON') code.putln("{") code.putln( 'PyObject *wrapper = PyObject_GetAttrString((PyObject *)&%s, "%s"); %s' % ( typeobj_cname, func.name, code.error_goto_if_null('wrapper', entry.pos))) code.putln( "if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {") code.putln( "%s = *((PyWrapperDescrObject *)wrapper)->d_base;" % ( func.wrapperbase_cname)) code.putln( "%s.doc = %s;" % (func.wrapperbase_cname, func.doc_cname)) code.putln( "((PyWrapperDescrObject *)wrapper)->d_base = &%s;" % ( func.wrapperbase_cname)) code.putln("}") code.putln("}") code.putln('#endif') if preprocessor_guard: code.putln('#endif') if type.vtable_cname: code.putln( "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % ( typeobj_cname, type.vtabptr_cname, code.error_goto(entry.pos))) code.globalstate.use_utility_code( UtilityCode.load_cached('SetVTable', 'ImportExport.c')) if not type.scope.is_internal and not type.scope.directives['internal']: # scope.is_internal is set for types defined by # Cython (such as closures), the 'internal' # directive is set by users code.putln( 'if (PyObject_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % ( Naming.module_cname, scope.class_name, typeobj_cname, code.error_goto(entry.pos))) weakref_entry = scope.lookup_here("__weakref__") if weakref_entry: if weakref_entry.type is py_object_type: tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname if type.typedef_flag: objstruct = type.objstruct_cname else: objstruct = "struct %s" % type.objstruct_cname code.putln("if (%s == 0) %s = offsetof(%s, %s);" % ( tp_weaklistoffset, tp_weaklistoffset, objstruct, weakref_entry.cname)) else: error(weakref_entry.pos, "__weakref__ slot must be of type 'object'") def generate_exttype_vtable_init_code(self, entry, code): # Generate code to initialise the C method table of an # extension type. type = entry.type if type.vtable_cname: code.putln( "%s = &%s;" % ( type.vtabptr_cname, type.vtable_cname)) if type.base_type and type.base_type.vtabptr_cname: code.putln( "%s.%s = *%s;" % ( type.vtable_cname, Naming.obj_base_cname, type.base_type.vtabptr_cname)) c_method_entries = [ entry for entry in type.scope.cfunc_entries if entry.func_cname ] if c_method_entries: for meth_entry in c_method_entries: cast = meth_entry.type.signature_cast_string() code.putln( "%s.%s = %s%s;" % ( type.vtable_cname, meth_entry.cname, cast, meth_entry.func_cname)) def generate_typeptr_assignment_code(self, entry, code): # Generate code to initialise the typeptr of an extension # type defined in this module to point to its type object. type = entry.type if type.typeobj_cname: code.putln( "%s = &%s;" % ( type.typeptr_cname, type.typeobj_cname)) def generate_cfunction_declaration(entry, env, code, definition): from_cy_utility = entry.used and entry.utility_code_definition if entry.used and entry.inline_func_in_pxd or (not entry.in_cinclude and (definition or entry.defined_in_pxd or entry.visibility == 'extern' or from_cy_utility)): if entry.visibility == 'extern': storage_class = Naming.extern_c_macro dll_linkage = "DL_IMPORT" elif entry.visibility == 'public': storage_class = Naming.extern_c_macro dll_linkage = "DL_EXPORT" elif entry.visibility == 'private': storage_class = "static" dll_linkage = None else: storage_class = "static" dll_linkage = None type = entry.type if entry.defined_in_pxd and not definition: storage_class = "static" dll_linkage = None type = CPtrType(type) header = type.declaration_code( entry.cname, dll_linkage = dll_linkage) modifiers = code.build_function_modifiers(entry.func_modifiers) code.putln("%s %s%s; /*proto*/" % ( storage_class, modifiers, header)) #------------------------------------------------------------------------------------ # # Runtime support code # #------------------------------------------------------------------------------------ refnanny_utility_code = UtilityCode.load("Refnanny", "ModuleSetupCode.c") packed_struct_utility_code = UtilityCode(proto=""" #if defined(__GNUC__) #define __Pyx_PACKED __attribute__((__packed__)) #else #define __Pyx_PACKED #endif """, impl="", proto_block='utility_code_proto_before_types') capsule_utility_code = UtilityCode.load("Capsule") Cython-0.23.4/Cython/Compiler/MemoryView.py0000644000175600017570000010135612606202452021705 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import from .Errors import CompileError, error from . import ExprNodes from .ExprNodes import IntNode, NameNode, AttributeNode from . import Options from .Code import UtilityCode, TempitaUtilityCode from .UtilityCode import CythonUtilityCode from . import Buffer from . import PyrexTypes from . import ModuleNode START_ERR = "Start must not be given." STOP_ERR = "Axis specification only allowed in the 'step' slot." STEP_ERR = "Step must be omitted, 1, or a valid specifier." BOTH_CF_ERR = "Cannot specify an array that is both C and Fortran contiguous." INVALID_ERR = "Invalid axis specification." NOT_CIMPORTED_ERR = "Variable was not cimported from cython.view" EXPR_ERR = "no expressions allowed in axis spec, only names and literals." CF_ERR = "Invalid axis specification for a C/Fortran contiguous array." ERR_UNINITIALIZED = ("Cannot check if memoryview %s is initialized without the " "GIL, consider using initializedcheck(False)") def err_if_nogil_initialized_check(pos, env, name='variable'): "This raises an exception at runtime now" pass #if env.nogil and env.directives['initializedcheck']: #error(pos, ERR_UNINITIALIZED % name) def concat_flags(*flags): return "(%s)" % "|".join(flags) format_flag = "PyBUF_FORMAT" memview_c_contiguous = "(PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE)" memview_f_contiguous = "(PyBUF_F_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE)" memview_any_contiguous = "(PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE)" memview_full_access = "PyBUF_FULL" #memview_strided_access = "PyBUF_STRIDED" memview_strided_access = "PyBUF_RECORDS" MEMVIEW_DIRECT = '__Pyx_MEMVIEW_DIRECT' MEMVIEW_PTR = '__Pyx_MEMVIEW_PTR' MEMVIEW_FULL = '__Pyx_MEMVIEW_FULL' MEMVIEW_CONTIG = '__Pyx_MEMVIEW_CONTIG' MEMVIEW_STRIDED= '__Pyx_MEMVIEW_STRIDED' MEMVIEW_FOLLOW = '__Pyx_MEMVIEW_FOLLOW' _spec_to_const = { 'direct' : MEMVIEW_DIRECT, 'ptr' : MEMVIEW_PTR, 'full' : MEMVIEW_FULL, 'contig' : MEMVIEW_CONTIG, 'strided': MEMVIEW_STRIDED, 'follow' : MEMVIEW_FOLLOW, } _spec_to_abbrev = { 'direct' : 'd', 'ptr' : 'p', 'full' : 'f', 'contig' : 'c', 'strided' : 's', 'follow' : '_', } memslice_entry_init = "{ 0, 0, { 0 }, { 0 }, { 0 } }" memview_name = u'memoryview' memview_typeptr_cname = '__pyx_memoryview_type' memview_objstruct_cname = '__pyx_memoryview_obj' memviewslice_cname = u'__Pyx_memviewslice' def put_init_entry(mv_cname, code): code.putln("%s.data = NULL;" % mv_cname) code.putln("%s.memview = NULL;" % mv_cname) def mangle_dtype_name(dtype): # a dumb wrapper for now; move Buffer.mangle_dtype_name in here later? from . import Buffer return Buffer.mangle_dtype_name(dtype) #def axes_to_str(axes): # return "".join([access[0].upper()+packing[0] for (access, packing) in axes]) def put_acquire_memoryviewslice(lhs_cname, lhs_type, lhs_pos, rhs, code, have_gil=False, first_assignment=True): "We can avoid decreffing the lhs if we know it is the first assignment" assert rhs.type.is_memoryviewslice pretty_rhs = rhs.result_in_temp() or rhs.is_simple() if pretty_rhs: rhstmp = rhs.result() else: rhstmp = code.funcstate.allocate_temp(lhs_type, manage_ref=False) code.putln("%s = %s;" % (rhstmp, rhs.result_as(lhs_type))) # Allow uninitialized assignment #code.putln(code.put_error_if_unbound(lhs_pos, rhs.entry)) put_assign_to_memviewslice(lhs_cname, rhs, rhstmp, lhs_type, code, have_gil=have_gil, first_assignment=first_assignment) if not pretty_rhs: code.funcstate.release_temp(rhstmp) def put_assign_to_memviewslice(lhs_cname, rhs, rhs_cname, memviewslicetype, code, have_gil=False, first_assignment=False): if not first_assignment: code.put_xdecref_memoryviewslice(lhs_cname, have_gil=have_gil) if not rhs.result_in_temp(): rhs.make_owned_memoryviewslice(code) code.putln("%s = %s;" % (lhs_cname, rhs_cname)) def get_buf_flags(specs): is_c_contig, is_f_contig = is_cf_contig(specs) if is_c_contig: return memview_c_contiguous elif is_f_contig: return memview_f_contiguous access, packing = zip(*specs) if 'full' in access or 'ptr' in access: return memview_full_access else: return memview_strided_access def insert_newaxes(memoryviewtype, n): axes = [('direct', 'strided')] * n axes.extend(memoryviewtype.axes) return PyrexTypes.MemoryViewSliceType(memoryviewtype.dtype, axes) def broadcast_types(src, dst): n = abs(src.ndim - dst.ndim) if src.ndim < dst.ndim: return insert_newaxes(src, n), dst else: return src, insert_newaxes(dst, n) def src_conforms_to_dst(src, dst, broadcast=False): ''' returns True if src conforms to dst, False otherwise. If conformable, the types are the same, the ndims are equal, and each axis spec is conformable. Any packing/access spec is conformable to itself. 'direct' and 'ptr' are conformable to 'full'. 'contig' and 'follow' are conformable to 'strided'. Any other combo is not conformable. ''' if src.dtype != dst.dtype: return False if src.ndim != dst.ndim: if broadcast: src, dst = broadcast_types(src, dst) else: return False for src_spec, dst_spec in zip(src.axes, dst.axes): src_access, src_packing = src_spec dst_access, dst_packing = dst_spec if src_access != dst_access and dst_access != 'full': return False if src_packing != dst_packing and dst_packing != 'strided': return False return True def valid_memslice_dtype(dtype, i=0): """ Return whether type dtype can be used as the base type of a memoryview slice. We support structs, numeric types and objects """ if dtype.is_complex and dtype.real_type.is_int: return False if dtype is PyrexTypes.c_bint_type: return False if dtype.is_struct and dtype.kind == 'struct': for member in dtype.scope.var_entries: if not valid_memslice_dtype(member.type): return False return True return ( dtype.is_error or # Pointers are not valid (yet) # (dtype.is_ptr and valid_memslice_dtype(dtype.base_type)) or (dtype.is_array and i < 8 and valid_memslice_dtype(dtype.base_type, i + 1)) or dtype.is_numeric or dtype.is_pyobject or dtype.is_fused or # accept this as it will be replaced by specializations later (dtype.is_typedef and valid_memslice_dtype(dtype.typedef_base_type)) ) def validate_memslice_dtype(pos, dtype): if not valid_memslice_dtype(dtype): error(pos, "Invalid base type for memoryview slice: %s" % dtype) class MemoryViewSliceBufferEntry(Buffer.BufferEntry): def __init__(self, entry): self.entry = entry self.type = entry.type self.cname = entry.cname self.buf_ptr = "%s.data" % self.cname dtype = self.entry.type.dtype dtype = PyrexTypes.CPtrType(dtype) self.buf_ptr_type = dtype def get_buf_suboffsetvars(self): return self._for_all_ndim("%s.suboffsets[%d]") def get_buf_stridevars(self): return self._for_all_ndim("%s.strides[%d]") def get_buf_shapevars(self): return self._for_all_ndim("%s.shape[%d]") def generate_buffer_lookup_code(self, code, index_cnames): axes = [(dim, index_cnames[dim], access, packing) for dim, (access, packing) in enumerate(self.type.axes)] return self._generate_buffer_lookup_code(code, axes) def _generate_buffer_lookup_code(self, code, axes, cast_result=True): bufp = self.buf_ptr type_decl = self.type.dtype.empty_declaration_code() for dim, index, access, packing in axes: shape = "%s.shape[%d]" % (self.cname, dim) stride = "%s.strides[%d]" % (self.cname, dim) suboffset = "%s.suboffsets[%d]" % (self.cname, dim) flag = get_memoryview_flag(access, packing) if flag in ("generic", "generic_contiguous"): # Note: we cannot do cast tricks to avoid stride multiplication # for generic_contiguous, as we may have to do (dtype *) # or (dtype **) arithmetic, we won't know which unless # we check suboffsets code.globalstate.use_utility_code(memviewslice_index_helpers) bufp = ('__pyx_memviewslice_index_full(%s, %s, %s, %s)' % (bufp, index, stride, suboffset)) elif flag == "indirect": bufp = "(%s + %s * %s)" % (bufp, index, stride) bufp = ("(*((char **) %s) + %s)" % (bufp, suboffset)) elif flag == "indirect_contiguous": # Note: we do char ** arithmetic bufp = "(*((char **) %s + %s) + %s)" % (bufp, index, suboffset) elif flag == "strided": bufp = "(%s + %s * %s)" % (bufp, index, stride) else: assert flag == 'contiguous', flag bufp = '((char *) (((%s *) %s) + %s))' % (type_decl, bufp, index) bufp = '( /* dim=%d */ %s )' % (dim, bufp) if cast_result: return "((%s *) %s)" % (type_decl, bufp) return bufp def generate_buffer_slice_code(self, code, indices, dst, have_gil, have_slices, directives): """ Slice a memoryviewslice. indices - list of index nodes. If not a SliceNode, or NoneNode, then it must be coercible to Py_ssize_t Simply call __pyx_memoryview_slice_memviewslice with the right arguments. """ src = self.cname code.putln("%(dst)s.data = %(src)s.data;" % locals()) code.putln("%(dst)s.memview = %(src)s.memview;" % locals()) code.put_incref_memoryviewslice(dst) all_dimensions_direct = all(access == 'direct' for access, packing in self.type.axes) suboffset_dim_temp = [] def get_suboffset_dim(): # create global temp variable at request if not suboffset_dim_temp: suboffset_dim = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False) code.putln("%s = -1;" % suboffset_dim) suboffset_dim_temp.append(suboffset_dim) return suboffset_dim_temp[0] dim = -1 new_ndim = 0 for index in indices: if index.is_none: # newaxis for attrib, value in [('shape', 1), ('strides', 0), ('suboffsets', -1)]: code.putln("%s.%s[%d] = %d;" % (dst, attrib, new_ndim, value)) new_ndim += 1 continue dim += 1 access, packing = self.type.axes[dim] error_goto = code.error_goto(index.pos) if isinstance(index, ExprNodes.SliceNode): # slice, unspecified dimension, or part of ellipsis d = dict(locals()) for s in "start stop step".split(): idx = getattr(index, s) have_idx = d['have_' + s] = not idx.is_none d[s] = idx.result() if have_idx else "0" if not (d['have_start'] or d['have_stop'] or d['have_step']): # full slice (:), simply copy over the extent, stride # and suboffset. Also update suboffset_dim if needed d['access'] = access util_name = "SimpleSlice" else: util_name = "ToughSlice" new_ndim += 1 else: # normal index idx = index.result() indirect = access != 'direct' if indirect: generic = access == 'full' if new_ndim != 0: return error(index.pos, "All preceding dimensions must be " "indexed and not sliced") d = dict( locals(), wraparound=int(directives['wraparound']), boundscheck=int(directives['boundscheck']) ) util_name = "SliceIndex" _, impl = TempitaUtilityCode.load_as_string(util_name, "MemoryView_C.c", context=d) code.put(impl) if suboffset_dim_temp: code.funcstate.release_temp(suboffset_dim_temp[0]) def empty_slice(pos): none = ExprNodes.NoneNode(pos) return ExprNodes.SliceNode(pos, start=none, stop=none, step=none) def unellipsify(indices, newaxes, ndim): result = [] seen_ellipsis = False have_slices = False n_indices = len(indices) - len(newaxes) for index in indices: if isinstance(index, ExprNodes.EllipsisNode): have_slices = True full_slice = empty_slice(index.pos) if seen_ellipsis: result.append(full_slice) else: nslices = ndim - n_indices + 1 result.extend([full_slice] * nslices) seen_ellipsis = True else: have_slices = (have_slices or isinstance(index, ExprNodes.SliceNode) or index.is_none) result.append(index) result_length = len(result) - len(newaxes) if result_length < ndim: have_slices = True nslices = ndim - result_length result.extend([empty_slice(indices[-1].pos)] * nslices) return have_slices, result def get_memoryview_flag(access, packing): if access == 'full' and packing in ('strided', 'follow'): return 'generic' elif access == 'full' and packing == 'contig': return 'generic_contiguous' elif access == 'ptr' and packing in ('strided', 'follow'): return 'indirect' elif access == 'ptr' and packing == 'contig': return 'indirect_contiguous' elif access == 'direct' and packing in ('strided', 'follow'): return 'strided' else: assert (access, packing) == ('direct', 'contig'), (access, packing) return 'contiguous' def get_is_contig_func_name(c_or_f, ndim): return "__pyx_memviewslice_is_%s_contig%d" % (c_or_f, ndim) def get_is_contig_utility(c_contig, ndim): C = dict(context, ndim=ndim) if c_contig: utility = load_memview_c_utility("MemviewSliceIsCContig", C, requires=[is_contig_utility]) else: utility = load_memview_c_utility("MemviewSliceIsFContig", C, requires=[is_contig_utility]) return utility def copy_src_to_dst_cname(): return "__pyx_memoryview_copy_contents" def verify_direct_dimensions(node): for access, packing in node.type.axes: if access != 'direct': error(node.pos, "All dimensions must be direct") def copy_broadcast_memview_src_to_dst(src, dst, code): """ Copy the contents of slice src to slice dst. Does not support indirect slices. """ verify_direct_dimensions(src) verify_direct_dimensions(dst) code.putln(code.error_goto_if_neg( "%s(%s, %s, %d, %d, %d)" % (copy_src_to_dst_cname(), src.result(), dst.result(), src.type.ndim, dst.type.ndim, dst.type.dtype.is_pyobject), dst.pos)) def get_1d_fill_scalar_func(type, code): dtype = type.dtype type_decl = dtype.empty_declaration_code() dtype_name = mangle_dtype_name(dtype) context = dict(dtype_name=dtype_name, type_decl=type_decl) utility = load_memview_c_utility("FillStrided1DScalar", context) code.globalstate.use_utility_code(utility) return '__pyx_fill_slice_%s' % dtype_name def assign_scalar(dst, scalar, code): """ Assign a scalar to a slice. dst must be a temp, scalar will be assigned to a correct type and not just something assignable. """ verify_direct_dimensions(dst) dtype = dst.type.dtype type_decl = dtype.empty_declaration_code() slice_decl = dst.type.empty_declaration_code() code.begin_block() code.putln("%s __pyx_temp_scalar = %s;" % (type_decl, scalar.result())) if dst.result_in_temp() or (dst.base.is_name and isinstance(dst.index, ExprNodes.EllipsisNode)): dst_temp = dst.result() else: code.putln("%s __pyx_temp_slice = %s;" % (slice_decl, dst.result())) dst_temp = "__pyx_temp_slice" # with slice_iter(dst.type, dst_temp, dst.type.ndim, code) as p: slice_iter_obj = slice_iter(dst.type, dst_temp, dst.type.ndim, code) p = slice_iter_obj.start_loops() if dtype.is_pyobject: code.putln("Py_DECREF(*(PyObject **) %s);" % p) code.putln("*((%s *) %s) = __pyx_temp_scalar;" % (type_decl, p)) if dtype.is_pyobject: code.putln("Py_INCREF(__pyx_temp_scalar);") slice_iter_obj.end_loops() code.end_block() def slice_iter(slice_type, slice_temp, ndim, code): if slice_type.is_c_contig or slice_type.is_f_contig: return ContigSliceIter(slice_type, slice_temp, ndim, code) else: return StridedSliceIter(slice_type, slice_temp, ndim, code) class SliceIter(object): def __init__(self, slice_type, slice_temp, ndim, code): self.slice_type = slice_type self.slice_temp = slice_temp self.code = code self.ndim = ndim class ContigSliceIter(SliceIter): def start_loops(self): code = self.code code.begin_block() type_decl = self.slice_type.dtype.empty_declaration_code() total_size = ' * '.join("%s.shape[%d]" % (self.slice_temp, i) for i in range(self.ndim)) code.putln("Py_ssize_t __pyx_temp_extent = %s;" % total_size) code.putln("Py_ssize_t __pyx_temp_idx;") code.putln("%s *__pyx_temp_pointer = (%s *) %s.data;" % ( type_decl, type_decl, self.slice_temp)) code.putln("for (__pyx_temp_idx = 0; " "__pyx_temp_idx < __pyx_temp_extent; " "__pyx_temp_idx++) {") return "__pyx_temp_pointer" def end_loops(self): self.code.putln("__pyx_temp_pointer += 1;") self.code.putln("}") self.code.end_block() class StridedSliceIter(SliceIter): def start_loops(self): code = self.code code.begin_block() for i in range(self.ndim): t = i, self.slice_temp, i code.putln("Py_ssize_t __pyx_temp_extent_%d = %s.shape[%d];" % t) code.putln("Py_ssize_t __pyx_temp_stride_%d = %s.strides[%d];" % t) code.putln("char *__pyx_temp_pointer_%d;" % i) code.putln("Py_ssize_t __pyx_temp_idx_%d;" % i) code.putln("__pyx_temp_pointer_0 = %s.data;" % self.slice_temp) for i in range(self.ndim): if i > 0: code.putln("__pyx_temp_pointer_%d = __pyx_temp_pointer_%d;" % (i, i - 1)) code.putln("for (__pyx_temp_idx_%d = 0; " "__pyx_temp_idx_%d < __pyx_temp_extent_%d; " "__pyx_temp_idx_%d++) {" % (i, i, i, i)) return "__pyx_temp_pointer_%d" % (self.ndim - 1) def end_loops(self): code = self.code for i in range(self.ndim - 1, -1, -1): code.putln("__pyx_temp_pointer_%d += __pyx_temp_stride_%d;" % (i, i)) code.putln("}") code.end_block() def copy_c_or_fortran_cname(memview): if memview.is_c_contig: c_or_f = 'c' else: c_or_f = 'f' return "__pyx_memoryview_copy_slice_%s_%s" % ( memview.specialization_suffix(), c_or_f) def get_copy_new_utility(pos, from_memview, to_memview): if from_memview.dtype != to_memview.dtype: return error(pos, "dtypes must be the same!") if len(from_memview.axes) != len(to_memview.axes): return error(pos, "number of dimensions must be same") if not (to_memview.is_c_contig or to_memview.is_f_contig): return error(pos, "to_memview must be c or f contiguous.") for (access, packing) in from_memview.axes: if access != 'direct': return error( pos, "cannot handle 'full' or 'ptr' access at this time.") if to_memview.is_c_contig: mode = 'c' contig_flag = memview_c_contiguous elif to_memview.is_f_contig: mode = 'fortran' contig_flag = memview_f_contiguous return load_memview_c_utility( "CopyContentsUtility", context=dict( context, mode=mode, dtype_decl=to_memview.dtype.empty_declaration_code(), contig_flag=contig_flag, ndim=to_memview.ndim, func_cname=copy_c_or_fortran_cname(to_memview), dtype_is_object=int(to_memview.dtype.is_pyobject)), requires=[copy_contents_new_utility]) def get_axes_specs(env, axes): ''' get_axes_specs(env, axes) -> list of (access, packing) specs for each axis. access is one of 'full', 'ptr' or 'direct' packing is one of 'contig', 'strided' or 'follow' ''' cythonscope = env.global_scope().context.cython_scope cythonscope.load_cythonscope() viewscope = cythonscope.viewscope access_specs = tuple([viewscope.lookup(name) for name in ('full', 'direct', 'ptr')]) packing_specs = tuple([viewscope.lookup(name) for name in ('contig', 'strided', 'follow')]) is_f_contig, is_c_contig = False, False default_access, default_packing = 'direct', 'strided' cf_access, cf_packing = default_access, 'follow' axes_specs = [] # analyse all axes. for idx, axis in enumerate(axes): if not axis.start.is_none: raise CompileError(axis.start.pos, START_ERR) if not axis.stop.is_none: raise CompileError(axis.stop.pos, STOP_ERR) if axis.step.is_none: axes_specs.append((default_access, default_packing)) elif isinstance(axis.step, IntNode): # the packing for the ::1 axis is contiguous, # all others are cf_packing. if axis.step.compile_time_value(env) != 1: raise CompileError(axis.step.pos, STEP_ERR) axes_specs.append((cf_access, 'cfcontig')) elif isinstance(axis.step, (NameNode, AttributeNode)): entry = _get_resolved_spec(env, axis.step) if entry.name in view_constant_to_access_packing: axes_specs.append(view_constant_to_access_packing[entry.name]) else: raise CompileError(axis.step.pos, INVALID_ERR) else: raise CompileError(axis.step.pos, INVALID_ERR) # First, find out if we have a ::1 somewhere contig_dim = 0 is_contig = False for idx, (access, packing) in enumerate(axes_specs): if packing == 'cfcontig': if is_contig: raise CompileError(axis.step.pos, BOTH_CF_ERR) contig_dim = idx axes_specs[idx] = (access, 'contig') is_contig = True if is_contig: # We have a ::1 somewhere, see if we're C or Fortran contiguous if contig_dim == len(axes) - 1: is_c_contig = True else: is_f_contig = True if contig_dim and not axes_specs[contig_dim - 1][0] in ('full', 'ptr'): raise CompileError(axes[contig_dim].pos, "Fortran contiguous specifier must follow an indirect dimension") if is_c_contig: # Contiguous in the last dimension, find the last indirect dimension contig_dim = -1 for idx, (access, packing) in enumerate(reversed(axes_specs)): if access in ('ptr', 'full'): contig_dim = len(axes) - idx - 1 # Replace 'strided' with 'follow' for any dimension following the last # indirect dimension, the first dimension or the dimension following # the ::1. # int[::indirect, ::1, :, :] # ^ ^ # int[::indirect, :, :, ::1] # ^ ^ start = contig_dim + 1 stop = len(axes) - is_c_contig for idx, (access, packing) in enumerate(axes_specs[start:stop]): idx = contig_dim + 1 + idx if access != 'direct': raise CompileError(axes[idx].pos, "Indirect dimension may not follow " "Fortran contiguous dimension") if packing == 'contig': raise CompileError(axes[idx].pos, "Dimension may not be contiguous") axes_specs[idx] = (access, cf_packing) if is_c_contig: # For C contiguity, we need to fix the 'contig' dimension # after the loop a, p = axes_specs[-1] axes_specs[-1] = a, 'contig' validate_axes_specs([axis.start.pos for axis in axes], axes_specs, is_c_contig, is_f_contig) return axes_specs def validate_axes(pos, axes): if len(axes) >= Options.buffer_max_dims: error(pos, "More dimensions than the maximum number" " of buffer dimensions were used.") return False return True def is_cf_contig(specs): is_c_contig = is_f_contig = False if len(specs) == 1 and specs == [('direct', 'contig')]: is_c_contig = True elif (specs[-1] == ('direct','contig') and all(axis == ('direct','follow') for axis in specs[:-1])): # c_contiguous: 'follow', 'follow', ..., 'follow', 'contig' is_c_contig = True elif (len(specs) > 1 and specs[0] == ('direct','contig') and all(axis == ('direct','follow') for axis in specs[1:])): # f_contiguous: 'contig', 'follow', 'follow', ..., 'follow' is_f_contig = True return is_c_contig, is_f_contig def get_mode(specs): is_c_contig, is_f_contig = is_cf_contig(specs) if is_c_contig: return 'c' elif is_f_contig: return 'fortran' for access, packing in specs: if access in ('ptr', 'full'): return 'full' return 'strided' view_constant_to_access_packing = { 'generic': ('full', 'strided'), 'strided': ('direct', 'strided'), 'indirect': ('ptr', 'strided'), 'generic_contiguous': ('full', 'contig'), 'contiguous': ('direct', 'contig'), 'indirect_contiguous': ('ptr', 'contig'), } def validate_axes_specs(positions, specs, is_c_contig, is_f_contig): packing_specs = ('contig', 'strided', 'follow') access_specs = ('direct', 'ptr', 'full') # is_c_contig, is_f_contig = is_cf_contig(specs) has_contig = has_follow = has_strided = has_generic_contig = False last_indirect_dimension = -1 for idx, (access, packing) in enumerate(specs): if access == 'ptr': last_indirect_dimension = idx for idx, (pos, (access, packing)) in enumerate(zip(positions, specs)): if not (access in access_specs and packing in packing_specs): raise CompileError(pos, "Invalid axes specification.") if packing == 'strided': has_strided = True elif packing == 'contig': if has_contig: raise CompileError(pos, "Only one direct contiguous " "axis may be specified.") valid_contig_dims = last_indirect_dimension + 1, len(specs) - 1 if idx not in valid_contig_dims and access != 'ptr': if last_indirect_dimension + 1 != len(specs) - 1: dims = "dimensions %d and %d" % valid_contig_dims else: dims = "dimension %d" % valid_contig_dims[0] raise CompileError(pos, "Only %s may be contiguous and direct" % dims) has_contig = access != 'ptr' elif packing == 'follow': if has_strided: raise CompileError(pos, "A memoryview cannot have both follow and strided axis specifiers.") if not (is_c_contig or is_f_contig): raise CompileError(pos, "Invalid use of the follow specifier.") if access in ('ptr', 'full'): has_strided = False def _get_resolved_spec(env, spec): # spec must be a NameNode or an AttributeNode if isinstance(spec, NameNode): return _resolve_NameNode(env, spec) elif isinstance(spec, AttributeNode): return _resolve_AttributeNode(env, spec) else: raise CompileError(spec.pos, INVALID_ERR) def _resolve_NameNode(env, node): try: resolved_name = env.lookup(node.name).name except AttributeError: raise CompileError(node.pos, INVALID_ERR) viewscope = env.global_scope().context.cython_scope.viewscope entry = viewscope.lookup(resolved_name) if entry is None: raise CompileError(node.pos, NOT_CIMPORTED_ERR) return entry def _resolve_AttributeNode(env, node): path = [] while isinstance(node, AttributeNode): path.insert(0, node.attribute) node = node.obj if isinstance(node, NameNode): path.insert(0, node.name) else: raise CompileError(node.pos, EXPR_ERR) modnames = path[:-1] # must be at least 1 module name, o/w not an AttributeNode. assert modnames scope = env for modname in modnames: mod = scope.lookup(modname) if not mod or not mod.as_module: raise CompileError( node.pos, "undeclared name not builtin: %s" % modname) scope = mod.as_module entry = scope.lookup(path[-1]) if not entry: raise CompileError(node.pos, "No such attribute '%s'" % path[-1]) return entry # ### Utility loading # def load_memview_cy_utility(util_code_name, context=None, **kwargs): return CythonUtilityCode.load(util_code_name, "MemoryView.pyx", context=context, **kwargs) def load_memview_c_utility(util_code_name, context=None, **kwargs): if context is None: return UtilityCode.load(util_code_name, "MemoryView_C.c", **kwargs) else: return TempitaUtilityCode.load(util_code_name, "MemoryView_C.c", context=context, **kwargs) def use_cython_array_utility_code(env): cython_scope = env.global_scope().context.cython_scope cython_scope.load_cythonscope() cython_scope.viewscope.lookup('array_cwrapper').used = True context = { 'memview_struct_name': memview_objstruct_cname, 'max_dims': Options.buffer_max_dims, 'memviewslice_name': memviewslice_cname, 'memslice_init': memslice_entry_init, } memviewslice_declare_code = load_memview_c_utility( "MemviewSliceStruct", proto_block='utility_code_proto_before_types', context=context, requires=[]) atomic_utility = load_memview_c_utility("Atomics", context, proto_block='utility_code_proto_before_types') memviewslice_init_code = load_memview_c_utility( "MemviewSliceInit", context=dict(context, BUF_MAX_NDIMS=Options.buffer_max_dims), requires=[memviewslice_declare_code, Buffer.acquire_utility_code, atomic_utility], ) memviewslice_index_helpers = load_memview_c_utility("MemviewSliceIndex") typeinfo_to_format_code = load_memview_cy_utility( "BufferFormatFromTypeInfo", requires=[Buffer._typeinfo_to_format_code]) is_contig_utility = load_memview_c_utility("MemviewSliceIsContig", context) overlapping_utility = load_memview_c_utility("OverlappingSlices", context) copy_contents_new_utility = load_memview_c_utility( "MemviewSliceCopyTemplate", context, requires=[], # require cython_array_utility_code ) view_utility_code = load_memview_cy_utility( "View.MemoryView", context=context, requires=[Buffer.GetAndReleaseBufferUtilityCode(), Buffer.buffer_struct_declare_code, Buffer.empty_bufstruct_utility, memviewslice_init_code, is_contig_utility, overlapping_utility, copy_contents_new_utility, ModuleNode.capsule_utility_code], ) view_utility_whitelist = ('array', 'memoryview', 'array_cwrapper', 'generic', 'strided', 'indirect', 'contiguous', 'indirect_contiguous') memviewslice_declare_code.requires.append(view_utility_code) copy_contents_new_utility.requires.append(view_utility_code) Cython-0.23.4/Cython/Compiler/Main.py0000644000175600017570000007252612606202452020474 0ustar jenkinsjenkins00000000000000# # Cython Top Level # from __future__ import absolute_import import os import re import sys import io if sys.version_info[:2] < (2, 6) or (3, 0) <= sys.version_info[:2] < (3, 2): sys.stderr.write("Sorry, Cython requires Python 2.6+ or 3.2+, found %d.%d\n" % tuple(sys.version_info[:2])) sys.exit(1) try: from __builtin__ import basestring except ImportError: basestring = str from . import Errors # Do not import Parsing here, import it when needed, because Parsing imports # Nodes, which globally needs debug command line options initialized to set a # conditional metaclass. These options are processed by CmdLine called from # main() in this file. # import Parsing from .StringEncoding import EncodedString from .Scanning import PyrexScanner, FileSourceDescriptor from .Errors import PyrexError, CompileError, error, warning from .Symtab import ModuleScope from .. import Utils from . import Options from . import Version # legacy import needed by old PyTables versions version = Version.version # legacy attribute - use "Cython.__version__" instead module_name_pattern = re.compile(r"[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$") verbose = 0 class CompilationData(object): # Bundles the information that is passed from transform to transform. # (For now, this is only) # While Context contains every pxd ever loaded, path information etc., # this only contains the data related to a single compilation pass # # pyx ModuleNode Main code tree of this compilation. # pxds {string : ModuleNode} Trees for the pxds used in the pyx. # codewriter CCodeWriter Where to output final code. # options CompilationOptions # result CompilationResult pass class Context(object): # This class encapsulates the context needed for compiling # one or more Cython implementation files along with their # associated and imported declaration files. It includes # the root of the module import namespace and the list # of directories to search for include files. # # modules {string : ModuleScope} # include_directories [string] # future_directives [object] # language_level int currently 2 or 3 for Python 2/3 cython_scope = None def __init__(self, include_directories, compiler_directives, cpp=False, language_level=2, options=None, create_testscope=True): # cython_scope is a hack, set to False by subclasses, in order to break # an infinite loop. # Better code organization would fix it. from . import Builtin, CythonScope self.modules = {"__builtin__" : Builtin.builtin_scope} self.cython_scope = CythonScope.create_cython_scope(self) self.modules["cython"] = self.cython_scope self.include_directories = include_directories self.future_directives = set() self.compiler_directives = compiler_directives self.cpp = cpp self.options = options self.pxds = {} # full name -> node tree self._interned = {} # (type(value), value, *key_args) -> interned_value standard_include_path = os.path.abspath(os.path.normpath( os.path.join(os.path.dirname(__file__), os.path.pardir, 'Includes'))) self.include_directories = include_directories + [standard_include_path] self.set_language_level(language_level) self.gdb_debug_outputwriter = None def set_language_level(self, level): self.language_level = level if level >= 3: from .Future import print_function, unicode_literals, absolute_import, division self.future_directives.update([print_function, unicode_literals, absolute_import, division]) self.modules['builtins'] = self.modules['__builtin__'] def intern_ustring(self, value, encoding=None): key = (EncodedString, value, encoding) try: return self._interned[key] except KeyError: pass value = EncodedString(value) if encoding: value.encoding = encoding self._interned[key] = value return value def intern_value(self, value, *key): key = (type(value), value) + key try: return self._interned[key] except KeyError: pass self._interned[key] = value return value # pipeline creation functions can now be found in Pipeline.py def process_pxd(self, source_desc, scope, module_name): from . import Pipeline if isinstance(source_desc, FileSourceDescriptor) and source_desc._file_type == 'pyx': source = CompilationSource(source_desc, module_name, os.getcwd()) result_sink = create_default_resultobj(source, self.options) pipeline = Pipeline.create_pyx_as_pxd_pipeline(self, result_sink) result = Pipeline.run_pipeline(pipeline, source) else: pipeline = Pipeline.create_pxd_pipeline(self, scope, module_name) result = Pipeline.run_pipeline(pipeline, source_desc) return result def nonfatal_error(self, exc): return Errors.report_error(exc) def find_module(self, module_name, relative_to=None, pos=None, need_pxd=1, absolute_fallback=True): # Finds and returns the module scope corresponding to # the given relative or absolute module name. If this # is the first time the module has been requested, finds # the corresponding .pxd file and process it. # If relative_to is not None, it must be a module scope, # and the module will first be searched for relative to # that module, provided its name is not a dotted name. debug_find_module = 0 if debug_find_module: print("Context.find_module: module_name = %s, relative_to = %s, pos = %s, need_pxd = %s" % ( module_name, relative_to, pos, need_pxd)) scope = None pxd_pathname = None if relative_to: if module_name: # from .module import ... qualified_name = relative_to.qualify_name(module_name) else: # from . import ... qualified_name = relative_to.qualified_name scope = relative_to relative_to = None else: qualified_name = module_name if not module_name_pattern.match(qualified_name): raise CompileError(pos or (module_name, 0, 0), "'%s' is not a valid module name" % module_name) if relative_to: if debug_find_module: print("...trying relative import") scope = relative_to.lookup_submodule(module_name) if not scope: pxd_pathname = self.find_pxd_file(qualified_name, pos) if pxd_pathname: scope = relative_to.find_submodule(module_name) if not scope: if debug_find_module: print("...trying absolute import") if absolute_fallback: qualified_name = module_name scope = self for name in qualified_name.split("."): scope = scope.find_submodule(name) if debug_find_module: print("...scope = %s" % scope) if not scope.pxd_file_loaded: if debug_find_module: print("...pxd not loaded") if not pxd_pathname: if debug_find_module: print("...looking for pxd file") # Only look in sys.path if we are explicitly looking # for a .pxd file. pxd_pathname = self.find_pxd_file(qualified_name, pos, sys_path=need_pxd) if debug_find_module: print("......found %s" % pxd_pathname) if not pxd_pathname and need_pxd: # Set pxd_file_loaded such that we don't need to # look for the non-existing pxd file next time. scope.pxd_file_loaded = True package_pathname = self.search_include_directories(qualified_name, ".py", pos) if package_pathname and package_pathname.endswith('__init__.py'): pass else: error(pos, "'%s.pxd' not found" % qualified_name.replace('.', os.sep)) if pxd_pathname: scope.pxd_file_loaded = True try: if debug_find_module: print("Context.find_module: Parsing %s" % pxd_pathname) rel_path = module_name.replace('.', os.sep) + os.path.splitext(pxd_pathname)[1] if not pxd_pathname.endswith(rel_path): rel_path = pxd_pathname # safety measure to prevent printing incorrect paths source_desc = FileSourceDescriptor(pxd_pathname, rel_path) err, result = self.process_pxd(source_desc, scope, qualified_name) if err: raise err (pxd_codenodes, pxd_scope) = result self.pxds[module_name] = (pxd_codenodes, pxd_scope) except CompileError: pass return scope def find_pxd_file(self, qualified_name, pos, sys_path=True): # Search include path (and sys.path if sys_path is True) for # the .pxd file corresponding to the given fully-qualified # module name. # Will find either a dotted filename or a file in a # package directory. If a source file position is given, # the directory containing the source file is searched first # for a dotted filename, and its containing package root # directory is searched first for a non-dotted filename. pxd = self.search_include_directories(qualified_name, ".pxd", pos, sys_path=sys_path) if pxd is None: # XXX Keep this until Includes/Deprecated is removed if (qualified_name.startswith('python') or qualified_name in ('stdlib', 'stdio', 'stl')): standard_include_path = os.path.abspath(os.path.normpath( os.path.join(os.path.dirname(__file__), os.path.pardir, 'Includes'))) deprecated_include_path = os.path.join(standard_include_path, 'Deprecated') self.include_directories.append(deprecated_include_path) try: pxd = self.search_include_directories(qualified_name, ".pxd", pos) finally: self.include_directories.pop() if pxd: name = qualified_name if name.startswith('python'): warning(pos, "'%s' is deprecated, use 'cpython'" % name, 1) elif name in ('stdlib', 'stdio'): warning(pos, "'%s' is deprecated, use 'libc.%s'" % (name, name), 1) elif name in ('stl'): warning(pos, "'%s' is deprecated, use 'libcpp.*.*'" % name, 1) if pxd is None and Options.cimport_from_pyx: return self.find_pyx_file(qualified_name, pos) return pxd def find_pyx_file(self, qualified_name, pos): # Search include path for the .pyx file corresponding to the # given fully-qualified module name, as for find_pxd_file(). return self.search_include_directories(qualified_name, ".pyx", pos) def find_include_file(self, filename, pos): # Search list of include directories for filename. # Reports an error and returns None if not found. path = self.search_include_directories(filename, "", pos, include=True) if not path: error(pos, "'%s' not found" % filename) return path def search_include_directories(self, qualified_name, suffix, pos, include=False, sys_path=False): return Utils.search_include_directories( tuple(self.include_directories), qualified_name, suffix, pos, include, sys_path) def find_root_package_dir(self, file_path): return Utils.find_root_package_dir(file_path) def check_package_dir(self, dir, package_names): return Utils.check_package_dir(dir, tuple(package_names)) def c_file_out_of_date(self, source_path): c_path = Utils.replace_suffix(source_path, ".c") if not os.path.exists(c_path): return 1 c_time = Utils.modification_time(c_path) if Utils.file_newer_than(source_path, c_time): return 1 pos = [source_path] pxd_path = Utils.replace_suffix(source_path, ".pxd") if os.path.exists(pxd_path) and Utils.file_newer_than(pxd_path, c_time): return 1 for kind, name in self.read_dependency_file(source_path): if kind == "cimport": dep_path = self.find_pxd_file(name, pos) elif kind == "include": dep_path = self.search_include_directories(name, pos) else: continue if dep_path and Utils.file_newer_than(dep_path, c_time): return 1 return 0 def find_cimported_module_names(self, source_path): return [ name for kind, name in self.read_dependency_file(source_path) if kind == "cimport" ] def is_package_dir(self, dir_path): return Utils.is_package_dir(dir_path) def read_dependency_file(self, source_path): dep_path = Utils.replace_suffix(source_path, ".dep") if os.path.exists(dep_path): f = open(dep_path, "rU") chunks = [ line.strip().split(" ", 1) for line in f.readlines() if " " in line.strip() ] f.close() return chunks else: return () def lookup_submodule(self, name): # Look up a top-level module. Returns None if not found. return self.modules.get(name, None) def find_submodule(self, name): # Find a top-level module, creating a new one if needed. scope = self.lookup_submodule(name) if not scope: scope = ModuleScope(name, parent_module = None, context = self) self.modules[name] = scope return scope def parse(self, source_desc, scope, pxd, full_module_name): if not isinstance(source_desc, FileSourceDescriptor): raise RuntimeError("Only file sources for code supported") source_filename = source_desc.filename scope.cpp = self.cpp # Parse the given source file and return a parse tree. num_errors = Errors.num_errors try: with Utils.open_source_file(source_filename) as f: from . import Parsing s = PyrexScanner(f, source_desc, source_encoding = f.encoding, scope = scope, context = self) tree = Parsing.p_module(s, pxd, full_module_name) if self.options.formal_grammar: try: from ..Parser import ConcreteSyntaxTree except ImportError: raise RuntimeError( "Formal grammer can only be used with compiled Cython with an available pgen.") ConcreteSyntaxTree.p_module(source_filename) except UnicodeDecodeError as e: #import traceback #traceback.print_exc() raise self._report_decode_error(source_desc, e) if Errors.num_errors > num_errors: raise CompileError() return tree def _report_decode_error(self, source_desc, exc): msg = exc.args[-1] position = exc.args[2] encoding = exc.args[0] line = 1 column = idx = 0 with io.open(source_desc.filename, "r", encoding='iso8859-1', newline='') as f: for line, data in enumerate(f, 1): idx += len(data) if idx >= position: column = position - (idx - len(data)) + 1 break return error((source_desc, line, column), "Decoding error, missing or incorrect coding= " "at top of source (cannot decode with encoding %r: %s)" % (encoding, msg)) def extract_module_name(self, path, options): # Find fully_qualified module name from the full pathname # of a source file. dir, filename = os.path.split(path) module_name, _ = os.path.splitext(filename) if "." in module_name: return module_name names = [module_name] while self.is_package_dir(dir): parent, package_name = os.path.split(dir) if parent == dir: break names.append(package_name) dir = parent names.reverse() return ".".join(names) def setup_errors(self, options, result): Errors.reset() # clear any remaining error state if options.use_listing_file: path = result.listing_file = Utils.replace_suffix(result.main_source_file, ".lis") else: path = None Errors.open_listing_file(path=path, echo_to_stderr=options.errors_to_stderr) def teardown_errors(self, err, options, result): source_desc = result.compilation_source.source_desc if not isinstance(source_desc, FileSourceDescriptor): raise RuntimeError("Only file sources for code supported") Errors.close_listing_file() result.num_errors = Errors.num_errors if result.num_errors > 0: err = True if err and result.c_file: try: Utils.castrate_file(result.c_file, os.stat(source_desc.filename)) except EnvironmentError: pass result.c_file = None def create_default_resultobj(compilation_source, options): result = CompilationResult() result.main_source_file = compilation_source.source_desc.filename result.compilation_source = compilation_source source_desc = compilation_source.source_desc if options.output_file: result.c_file = os.path.join(compilation_source.cwd, options.output_file) else: if options.cplus: c_suffix = ".cpp" else: c_suffix = ".c" result.c_file = Utils.replace_suffix(source_desc.filename, c_suffix) result.embedded_metadata = options.embedded_metadata return result def run_pipeline(source, options, full_module_name=None, context=None): from . import Pipeline source_ext = os.path.splitext(source)[1] options.configure_language_defaults(source_ext[1:]) # py/pyx if context is None: context = options.create_context() # Set up source object cwd = os.getcwd() abs_path = os.path.abspath(source) full_module_name = full_module_name or context.extract_module_name(source, options) if options.relative_path_in_code_position_comments: rel_path = full_module_name.replace('.', os.sep) + source_ext if not abs_path.endswith(rel_path): rel_path = source # safety measure to prevent printing incorrect paths else: rel_path = abs_path source_desc = FileSourceDescriptor(abs_path, rel_path) source = CompilationSource(source_desc, full_module_name, cwd) # Set up result object result = create_default_resultobj(source, options) if options.annotate is None: # By default, decide based on whether an html file already exists. html_filename = os.path.splitext(result.c_file)[0] + ".html" if os.path.exists(html_filename): with io.open(html_filename, "r", encoding="UTF-8") as html_file: line = html_file.readline() if line.startswith(u' Cython: {filename}

    Generated by Cython {watermark}{more_info}

    Yellow lines hint at Python interaction.
    Click on a line that starts with a "+" to see the C code that Cython generated for it.

    ''').format(css=self._css(), js=self._js, watermark=Version.watermark, filename=os.path.basename(source_filename) if source_filename else '', more_info=coverage_info) ] if c_file: outlist.append(u'

    Raw output: %s

    \n' % (c_file, c_file)) return outlist def _save_annotation_footer(self): return (u'\n',) def _save_annotation(self, code, generated_code, c_file=None, source_filename=None, coverage_xml=None): """ lines : original cython source code split by lines generated_code : generated c code keyed by line number in original file target filename : name of the file in which to store the generated html c_file : filename in which the c_code has been written """ if coverage_xml is not None and source_filename: coverage_timestamp = coverage_xml.get('timestamp', '').strip() covered_lines = self._get_line_coverage(coverage_xml, source_filename) else: coverage_timestamp = covered_lines = None outlist = [] outlist.extend(self._save_annotation_header(c_file, source_filename, coverage_timestamp)) outlist.extend(self._save_annotation_body(code, generated_code, covered_lines)) outlist.extend(self._save_annotation_footer()) return ''.join(outlist) def _get_line_coverage(self, coverage_xml, source_filename): coverage_data = None for entry in coverage_xml.iterfind('.//class'): if not entry.get('filename'): continue if (entry.get('filename') == source_filename or os.path.abspath(entry.get('filename')) == source_filename): coverage_data = entry break elif source_filename.endswith(entry.get('filename')): coverage_data = entry # but we might still find a better match... if coverage_data is None: return None return dict( (int(line.get('number')), int(line.get('hits'))) for line in coverage_data.iterfind('lines/line') ) def _htmlify_code(self, code): try: from pygments import highlight from pygments.lexers import CythonLexer from pygments.formatters import HtmlFormatter except ImportError: # no Pygments, just escape the code return html_escape(code) html_code = highlight( code, CythonLexer(stripnl=False, stripall=False), HtmlFormatter(nowrap=True)) return html_code def _save_annotation_body(self, cython_code, generated_code, covered_lines=None): outlist = [u'
    '] pos_comment_marker = u'/* \N{HORIZONTAL ELLIPSIS} */\n' new_calls_map = dict( (name, 0) for name in 'refnanny trace py_macro_api py_c_api pyx_macro_api pyx_c_api error_goto'.split() ).copy self.mark_pos(None) def annotate(match): group_name = match.lastgroup calls[group_name] += 1 return u"%s" % ( group_name, match.group(group_name)) lines = self._htmlify_code(cython_code).splitlines() lineno_width = len(str(len(lines))) if not covered_lines: covered_lines = None for k, line in enumerate(lines, 1): try: c_code = generated_code[k] except KeyError: c_code = '' else: c_code = _replace_pos_comment(pos_comment_marker, c_code) if c_code.startswith(pos_comment_marker): c_code = c_code[len(pos_comment_marker):] c_code = html_escape(c_code) calls = new_calls_map() c_code = _parse_code(annotate, c_code) score = (5 * calls['py_c_api'] + 2 * calls['pyx_c_api'] + calls['py_macro_api'] + calls['pyx_macro_api']) if c_code: onclick = " onclick='toggleDiv(this)'" expandsymbol = '+' else: onclick = '' expandsymbol = ' ' covered = '' if covered_lines is not None and k in covered_lines: hits = covered_lines[k] if hits is not None: covered = 'run' if hits else 'mis' outlist.append( u'
    '
                    # generate line number with expand symbol in front,
                    # and the right  number of digit
                    u'{expandsymbol}{line:0{lineno_width}d}: {code}
    \n'.format( score=score, expandsymbol=expandsymbol, covered=covered, lineno_width=lineno_width, line=k, code=line.rstrip(), onclick=onclick, )) if c_code: outlist.append(u"
    {code}
    ".format( score=score, covered=covered, code=c_code)) outlist.append(u"
    ") return outlist _parse_code = re.compile(( br'(?P__Pyx_X?(?:GOT|GIVE)REF|__Pyx_RefNanny[A-Za-z]+)|' br'(?P__Pyx_Trace[A-Za-z]+)|' br'(?:' br'(?P__Pyx_[A-Z][A-Z_]+)|' br'(?P__Pyx_[A-Z][a-z_][A-Za-z_]*)|' br'(?PPy[A-Z][a-z]+_[A-Z][A-Z_]+)|' br'(?PPy[A-Z][a-z]+_[A-Z][a-z][A-Za-z_]*)' br')(?=\()|' # look-ahead to exclude subsequent '(' from replacement br'(?P(?:(?<=;) *if .* +)?\{__pyx_filename = .*goto __pyx_L\w+;\})' ).decode('ascii')).sub _replace_pos_comment = re.compile( # this matches what Cython generates as code line marker comment br'^\s*/\*(?:(?:[^*]|\*[^/])*\n)+\s*\*/\s*\n'.decode('ascii'), re.M ).sub class AnnotationItem(object): def __init__(self, style, text, tag="", size=0): self.style = style self.text = text self.tag = tag self.size = size def start(self): return u"%s" % (self.style, self.text, self.tag) def end(self): return self.size, u"" Cython-0.23.4/Cython/Compiler/AnalysedTreeTransforms.py0000644000175600017570000000736212606202452024243 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import from .Visitor import ScopeTrackingTransform from .Nodes import StatListNode, SingleAssignmentNode, CFuncDefNode, DefNode from .ExprNodes import DictNode, DictItemNode, NameNode, UnicodeNode from .PyrexTypes import py_object_type from .StringEncoding import EncodedString from . import Symtab class AutoTestDictTransform(ScopeTrackingTransform): # Handles autotestdict directive blacklist = ['__cinit__', '__dealloc__', '__richcmp__', '__nonzero__', '__bool__', '__len__', '__contains__'] def visit_ModuleNode(self, node): if node.is_pxd: return node self.scope_type = 'module' self.scope_node = node if not self.current_directives['autotestdict']: return node self.all_docstrings = self.current_directives['autotestdict.all'] self.cdef_docstrings = self.all_docstrings or self.current_directives['autotestdict.cdef'] assert isinstance(node.body, StatListNode) # First see if __test__ is already created if u'__test__' in node.scope.entries: # Do nothing return node pos = node.pos self.tests = [] self.testspos = node.pos test_dict_entry = node.scope.declare_var(EncodedString(u'__test__'), py_object_type, pos, visibility='public') create_test_dict_assignment = SingleAssignmentNode(pos, lhs=NameNode(pos, name=EncodedString(u'__test__'), entry=test_dict_entry), rhs=DictNode(pos, key_value_pairs=self.tests)) self.visitchildren(node) node.body.stats.append(create_test_dict_assignment) return node def add_test(self, testpos, path, doctest): pos = self.testspos keystr = u'%s (line %d)' % (path, testpos[1]) key = UnicodeNode(pos, value=EncodedString(keystr)) value = UnicodeNode(pos, value=doctest) self.tests.append(DictItemNode(pos, key=key, value=value)) def visit_ExprNode(self, node): # expressions cannot contain functions and lambda expressions # do not have a docstring return node def visit_FuncDefNode(self, node): if not node.doc or (isinstance(node, DefNode) and node.fused_py_func): return node if not self.cdef_docstrings: if isinstance(node, CFuncDefNode) and not node.py_func: return node if not self.all_docstrings and '>>>' not in node.doc: return node pos = self.testspos if self.scope_type == 'module': path = node.entry.name elif self.scope_type in ('pyclass', 'cclass'): if isinstance(node, CFuncDefNode): if node.py_func is not None: name = node.py_func.name else: name = node.entry.name else: name = node.name if self.scope_type == 'cclass' and name in self.blacklist: return node if self.scope_type == 'pyclass': class_name = self.scope_node.name else: class_name = self.scope_node.class_name if isinstance(node.entry.scope, Symtab.PropertyScope): property_method_name = node.entry.scope.name path = "%s.%s.%s" % (class_name, node.entry.scope.name, node.entry.name) else: path = "%s.%s" % (class_name, node.entry.name) else: assert False self.add_test(node.pos, path, node.doc) return node Cython-0.23.4/Cython/Compiler/Tests/0000755000175600017570000000000012606202455020327 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Compiler/Tests/__init__.py0000644000175600017570000000001512606202452022431 0ustar jenkinsjenkins00000000000000# empty file Cython-0.23.4/Cython/Compiler/Tests/TestVisitor.py0000644000175600017570000000426412606202452023203 0ustar jenkinsjenkins00000000000000from Cython.Compiler.ModuleNode import ModuleNode from Cython.Compiler.Symtab import ModuleScope from Cython.TestUtils import TransformTest from Cython.Compiler.Visitor import MethodDispatcherTransform from Cython.Compiler.ParseTreeTransforms import ( NormalizeTree, AnalyseDeclarationsTransform, AnalyseExpressionsTransform, InterpretCompilerDirectives) class TestMethodDispatcherTransform(TransformTest): _tree = None def _build_tree(self): if self._tree is None: context = None def fake_module(node): scope = ModuleScope('test', None, None) return ModuleNode(node.pos, doc=None, body=node, scope=scope, full_module_name='test', directive_comments={}) pipeline = [ fake_module, NormalizeTree(context), InterpretCompilerDirectives(context, {}), AnalyseDeclarationsTransform(context), AnalyseExpressionsTransform(context), ] self._tree = self.run_pipeline(pipeline, u""" cdef bytes s = b'asdfg' cdef dict d = {1:2} x = s * 3 d.get('test') """) return self._tree def test_builtin_method(self): calls = [0] class Test(MethodDispatcherTransform): def _handle_simple_method_dict_get(self, node, func, args, unbound): calls[0] += 1 return node tree = self._build_tree() Test(None)(tree) self.assertEqual(1, calls[0]) def test_binop_method(self): calls = {'bytes': 0, 'object': 0} class Test(MethodDispatcherTransform): def _handle_simple_method_bytes___mul__(self, node, func, args, unbound): calls['bytes'] += 1 return node def _handle_simple_method_object___mul__(self, node, func, args, unbound): calls['object'] += 1 return node tree = self._build_tree() Test(None)(tree) self.assertEqual(1, calls['bytes']) self.assertEqual(0, calls['object']) Cython-0.23.4/Cython/Compiler/Tests/TestUtilityLoad.py0000644000175600017570000000642712606202452024012 0ustar jenkinsjenkins00000000000000import unittest from Cython.Compiler import Code, UtilityCode def strip_2tup(tup): return tup[0] and tup[0].strip(), tup[1] and tup[1].strip() class TestUtilityLoader(unittest.TestCase): """ Test loading UtilityCodes """ expected = "test {{loader}} prototype", "test {{loader}} impl" required = "req {{loader}} proto", "req {{loader}} impl" context = dict(loader='Loader') name = "TestUtilityLoader" filename = "TestUtilityLoader.c" cls = Code.UtilityCode def test_load_as_string(self): got = strip_2tup(self.cls.load_as_string(self.name)) self.assertEquals(got, self.expected) got = strip_2tup(self.cls.load_as_string(self.name, self.filename)) self.assertEquals(got, self.expected) def test_load(self): utility = self.cls.load(self.name) got = strip_2tup((utility.proto, utility.impl)) self.assertEquals(got, self.expected) required, = utility.requires got = strip_2tup((required.proto, required.impl)) self.assertEquals(got, self.required) utility = self.cls.load(self.name, from_file=self.filename) got = strip_2tup((utility.proto, utility.impl)) self.assertEquals(got, self.expected) utility = self.cls.load_cached(self.name, from_file=self.filename) got = strip_2tup((utility.proto, utility.impl)) self.assertEquals(got, self.expected) class TestTempitaUtilityLoader(TestUtilityLoader): """ Test loading UtilityCodes with Tempita substitution """ expected_tempita = (TestUtilityLoader.expected[0].replace('{{loader}}', 'Loader'), TestUtilityLoader.expected[1].replace('{{loader}}', 'Loader')) required_tempita = (TestUtilityLoader.required[0].replace('{{loader}}', 'Loader'), TestUtilityLoader.required[1].replace('{{loader}}', 'Loader')) cls = Code.TempitaUtilityCode def test_load_as_string(self): got = strip_2tup(self.cls.load_as_string(self.name, context=self.context)) self.assertEquals(got, self.expected_tempita) def test_load(self): utility = self.cls.load(self.name, context=self.context) got = strip_2tup((utility.proto, utility.impl)) self.assertEquals(got, self.expected_tempita) required, = utility.requires got = strip_2tup((required.proto, required.impl)) self.assertEquals(got, self.required_tempita) utility = self.cls.load(self.name, from_file=self.filename, context=self.context) got = strip_2tup((utility.proto, utility.impl)) self.assertEquals(got, self.expected_tempita) class TestCythonUtilityLoader(TestTempitaUtilityLoader): """ Test loading CythonUtilityCodes """ # Just change the attributes and run the same tests expected = None, "test {{cy_loader}} impl" expected_tempita = None, "test CyLoader impl" required = None, "req {{cy_loader}} impl" required_tempita = None, "req CyLoader impl" context = dict(cy_loader='CyLoader') name = "TestCyUtilityLoader" filename = "TestCyUtilityLoader.pyx" cls = UtilityCode.CythonUtilityCode # Small hack to pass our tests above cls.proto = None test_load = TestUtilityLoader.test_load test_load_tempita = TestTempitaUtilityLoader.test_load Cython-0.23.4/Cython/Compiler/Tests/TestTreePath.py0000644000175600017570000001026212606202452023253 0ustar jenkinsjenkins00000000000000import unittest from Cython.Compiler.Visitor import PrintTree from Cython.TestUtils import TransformTest from Cython.Compiler.TreePath import find_first, find_all from Cython.Compiler import Nodes, ExprNodes class TestTreePath(TransformTest): _tree = None def _build_tree(self): if self._tree is None: self._tree = self.run_pipeline([], u""" def decorator(fun): # DefNode return fun # ReturnStatNode, NameNode @decorator # NameNode def decorated(): # DefNode pass """) return self._tree def test_node_path(self): t = self._build_tree() self.assertEquals(2, len(find_all(t, "//DefNode"))) self.assertEquals(2, len(find_all(t, "//NameNode"))) self.assertEquals(1, len(find_all(t, "//ReturnStatNode"))) self.assertEquals(1, len(find_all(t, "//DefNode//ReturnStatNode"))) def test_node_path_star(self): t = self._build_tree() self.assertEquals(10, len(find_all(t, "//*"))) self.assertEquals(8, len(find_all(t, "//DefNode//*"))) self.assertEquals(0, len(find_all(t, "//NameNode//*"))) def test_node_path_attribute(self): t = self._build_tree() self.assertEquals(2, len(find_all(t, "//NameNode/@name"))) self.assertEquals(['fun', 'decorator'], find_all(t, "//NameNode/@name")) def test_node_path_attribute_dotted(self): t = self._build_tree() self.assertEquals(1, len(find_all(t, "//ReturnStatNode/@value.name"))) self.assertEquals(['fun'], find_all(t, "//ReturnStatNode/@value.name")) def test_node_path_child(self): t = self._build_tree() self.assertEquals(1, len(find_all(t, "//DefNode/ReturnStatNode/NameNode"))) self.assertEquals(1, len(find_all(t, "//ReturnStatNode/NameNode"))) def test_node_path_node_predicate(self): t = self._build_tree() self.assertEquals(0, len(find_all(t, "//DefNode[.//ForInStatNode]"))) self.assertEquals(2, len(find_all(t, "//DefNode[.//NameNode]"))) self.assertEquals(1, len(find_all(t, "//ReturnStatNode[./NameNode]"))) self.assertEquals(Nodes.ReturnStatNode, type(find_first(t, "//ReturnStatNode[./NameNode]"))) def test_node_path_node_predicate_step(self): t = self._build_tree() self.assertEquals(2, len(find_all(t, "//DefNode[.//NameNode]"))) self.assertEquals(8, len(find_all(t, "//DefNode[.//NameNode]//*"))) self.assertEquals(1, len(find_all(t, "//DefNode[.//NameNode]//ReturnStatNode"))) self.assertEquals(Nodes.ReturnStatNode, type(find_first(t, "//DefNode[.//NameNode]//ReturnStatNode"))) def test_node_path_attribute_exists(self): t = self._build_tree() self.assertEquals(2, len(find_all(t, "//NameNode[@name]"))) self.assertEquals(ExprNodes.NameNode, type(find_first(t, "//NameNode[@name]"))) def test_node_path_attribute_exists_not(self): t = self._build_tree() self.assertEquals(0, len(find_all(t, "//NameNode[not(@name)]"))) self.assertEquals(2, len(find_all(t, "//NameNode[not(@honking)]"))) def test_node_path_and(self): t = self._build_tree() self.assertEquals(1, len(find_all(t, "//DefNode[.//ReturnStatNode and .//NameNode]"))) self.assertEquals(0, len(find_all(t, "//NameNode[@honking and @name]"))) self.assertEquals(0, len(find_all(t, "//NameNode[@name and @honking]"))) self.assertEquals(2, len(find_all(t, "//DefNode[.//NameNode[@name] and @name]"))) def test_node_path_attribute_string_predicate(self): t = self._build_tree() self.assertEquals(1, len(find_all(t, "//NameNode[@name = 'decorator']"))) def test_node_path_recursive_predicate(self): t = self._build_tree() self.assertEquals(2, len(find_all(t, "//DefNode[.//NameNode[@name]]"))) self.assertEquals(1, len(find_all(t, "//DefNode[.//NameNode[@name = 'decorator']]"))) self.assertEquals(1, len(find_all(t, "//DefNode[.//ReturnStatNode[./NameNode[@name = 'fun']]/NameNode]"))) if __name__ == '__main__': unittest.main() Cython-0.23.4/Cython/Compiler/Tests/TestTreeFragment.py0000644000175600017570000000422012606202452024117 0ustar jenkinsjenkins00000000000000from Cython.TestUtils import CythonTest from Cython.Compiler.TreeFragment import * from Cython.Compiler.Nodes import * from Cython.Compiler.UtilNodes import * import Cython.Compiler.Naming as Naming class TestTreeFragments(CythonTest): def test_basic(self): F = self.fragment(u"x = 4") T = F.copy() self.assertCode(u"x = 4", T) def test_copy_is_taken(self): F = self.fragment(u"if True: x = 4") T1 = F.root T2 = F.copy() self.assertEqual("x", T2.stats[0].if_clauses[0].body.lhs.name) T2.stats[0].if_clauses[0].body.lhs.name = "other" self.assertEqual("x", T1.stats[0].if_clauses[0].body.lhs.name) def test_substitutions_are_copied(self): T = self.fragment(u"y + y").substitute({"y": NameNode(pos=None, name="x")}) self.assertEqual("x", T.stats[0].expr.operand1.name) self.assertEqual("x", T.stats[0].expr.operand2.name) self.assert_(T.stats[0].expr.operand1 is not T.stats[0].expr.operand2) def test_substitution(self): F = self.fragment(u"x = 4") y = NameNode(pos=None, name=u"y") T = F.substitute({"x" : y}) self.assertCode(u"y = 4", T) def test_exprstat(self): F = self.fragment(u"PASS") pass_stat = PassStatNode(pos=None) T = F.substitute({"PASS" : pass_stat}) self.assert_(isinstance(T.stats[0], PassStatNode), T) def test_pos_is_transferred(self): F = self.fragment(u""" x = y x = u * v ** w """) T = F.substitute({"v" : NameNode(pos=None, name="a")}) v = F.root.stats[1].rhs.operand2.operand1 a = T.stats[1].rhs.operand2.operand1 self.assertEquals(v.pos, a.pos) def test_temps(self): TemplateTransform.temp_name_counter = 0 F = self.fragment(u""" TMP x = TMP """) T = F.substitute(temps=[u"TMP"]) s = T.body.stats self.assert_(isinstance(s[0].expr, TempRefNode)) self.assert_(isinstance(s[1].rhs, TempRefNode)) self.assert_(s[0].expr.handle is s[1].rhs.handle) if __name__ == "__main__": import unittest unittest.main() Cython-0.23.4/Cython/Compiler/Tests/TestSignatureMatching.py0000644000175600017570000000652012606202452025155 0ustar jenkinsjenkins00000000000000import unittest from Cython.Compiler import PyrexTypes as pt from Cython.Compiler.ExprNodes import NameNode from Cython.Compiler.PyrexTypes import CFuncTypeArg def cfunctype(*arg_types): return pt.CFuncType(pt.c_int_type, [ CFuncTypeArg("name", arg_type, None) for arg_type in arg_types ]) def cppclasstype(name, base_classes): return pt.CppClassType(name, None, 'CPP_'+name, base_classes) class SignatureMatcherTest(unittest.TestCase): """ Test the signature matching algorithm for overloaded signatures. """ def assertMatches(self, expected_type, arg_types, functions): args = [ NameNode(None, type=arg_type) for arg_type in arg_types ] match = pt.best_match(args, functions) if expected_type is not None: self.assertNotEqual(None, match) self.assertEqual(expected_type, match.type) def test_cpp_reference_single_arg(self): function_types = [ cfunctype(pt.CReferenceType(pt.c_int_type)), cfunctype(pt.CReferenceType(pt.c_long_type)), cfunctype(pt.CReferenceType(pt.c_double_type)), ] functions = [ NameNode(None, type=t) for t in function_types ] self.assertMatches(function_types[0], [pt.c_int_type], functions) self.assertMatches(function_types[1], [pt.c_long_type], functions) self.assertMatches(function_types[2], [pt.c_double_type], functions) def test_cpp_reference_two_args(self): function_types = [ cfunctype( pt.CReferenceType(pt.c_int_type), pt.CReferenceType(pt.c_long_type)), cfunctype( pt.CReferenceType(pt.c_long_type), pt.CReferenceType(pt.c_long_type)), ] functions = [ NameNode(None, type=t) for t in function_types ] self.assertMatches(function_types[0], [pt.c_int_type, pt.c_long_type], functions) self.assertMatches(function_types[1], [pt.c_long_type, pt.c_long_type], functions) self.assertMatches(function_types[1], [pt.c_long_type, pt.c_int_type], functions) def test_cpp_reference_cpp_class(self): classes = [ cppclasstype("Test%d"%i, []) for i in range(2) ] function_types = [ cfunctype(pt.CReferenceType(classes[0])), cfunctype(pt.CReferenceType(classes[1])), ] functions = [ NameNode(None, type=t) for t in function_types ] self.assertMatches(function_types[0], [classes[0]], functions) self.assertMatches(function_types[1], [classes[1]], functions) def test_cpp_reference_cpp_class_and_int(self): classes = [ cppclasstype("Test%d"%i, []) for i in range(2) ] function_types = [ cfunctype(pt.CReferenceType(classes[0]), pt.c_int_type), cfunctype(pt.CReferenceType(classes[0]), pt.c_long_type), cfunctype(pt.CReferenceType(classes[1]), pt.c_int_type), cfunctype(pt.CReferenceType(classes[1]), pt.c_long_type), ] functions = [ NameNode(None, type=t) for t in function_types ] self.assertMatches(function_types[0], [classes[0], pt.c_int_type], functions) self.assertMatches(function_types[1], [classes[0], pt.c_long_type], functions) self.assertMatches(function_types[2], [classes[1], pt.c_int_type], functions) self.assertMatches(function_types[3], [classes[1], pt.c_long_type], functions) Cython-0.23.4/Cython/Compiler/Tests/TestParseTreeTransforms.py0000644000175600017570000002057212606202452025515 0ustar jenkinsjenkins00000000000000import os from Cython.TestUtils import TransformTest from Cython.Compiler.ParseTreeTransforms import * from Cython.Compiler.Nodes import * from Cython.Compiler import Main, Symtab class TestNormalizeTree(TransformTest): def test_parserbehaviour_is_what_we_coded_for(self): t = self.fragment(u"if x: y").root self.assertLines(u""" (root): StatListNode stats[0]: IfStatNode if_clauses[0]: IfClauseNode condition: NameNode body: ExprStatNode expr: NameNode """, self.treetypes(t)) def test_wrap_singlestat(self): t = self.run_pipeline([NormalizeTree(None)], u"if x: y") self.assertLines(u""" (root): StatListNode stats[0]: IfStatNode if_clauses[0]: IfClauseNode condition: NameNode body: StatListNode stats[0]: ExprStatNode expr: NameNode """, self.treetypes(t)) def test_wrap_multistat(self): t = self.run_pipeline([NormalizeTree(None)], u""" if z: x y """) self.assertLines(u""" (root): StatListNode stats[0]: IfStatNode if_clauses[0]: IfClauseNode condition: NameNode body: StatListNode stats[0]: ExprStatNode expr: NameNode stats[1]: ExprStatNode expr: NameNode """, self.treetypes(t)) def test_statinexpr(self): t = self.run_pipeline([NormalizeTree(None)], u""" a, b = x, y """) self.assertLines(u""" (root): StatListNode stats[0]: SingleAssignmentNode lhs: TupleNode args[0]: NameNode args[1]: NameNode rhs: TupleNode args[0]: NameNode args[1]: NameNode """, self.treetypes(t)) def test_wrap_offagain(self): t = self.run_pipeline([NormalizeTree(None)], u""" x y if z: x """) self.assertLines(u""" (root): StatListNode stats[0]: ExprStatNode expr: NameNode stats[1]: ExprStatNode expr: NameNode stats[2]: IfStatNode if_clauses[0]: IfClauseNode condition: NameNode body: StatListNode stats[0]: ExprStatNode expr: NameNode """, self.treetypes(t)) def test_pass_eliminated(self): t = self.run_pipeline([NormalizeTree(None)], u"pass") self.assert_(len(t.stats) == 0) class TestWithTransform(object): # (TransformTest): # Disabled! def test_simplified(self): t = self.run_pipeline([WithTransform(None)], u""" with x: y = z ** 3 """) self.assertCode(u""" $0_0 = x $0_2 = $0_0.__exit__ $0_0.__enter__() $0_1 = True try: try: $1_0 = None y = z ** 3 except: $0_1 = False if (not $0_2($1_0)): raise finally: if $0_1: $0_2(None, None, None) """, t) def test_basic(self): t = self.run_pipeline([WithTransform(None)], u""" with x as y: y = z ** 3 """) self.assertCode(u""" $0_0 = x $0_2 = $0_0.__exit__ $0_3 = $0_0.__enter__() $0_1 = True try: try: $1_0 = None y = $0_3 y = z ** 3 except: $0_1 = False if (not $0_2($1_0)): raise finally: if $0_1: $0_2(None, None, None) """, t) class TestInterpretCompilerDirectives(TransformTest): """ This class tests the parallel directives AST-rewriting and importing. """ # Test the parallel directives (c)importing import_code = u""" cimport cython.parallel cimport cython.parallel as par from cython cimport parallel as par2 from cython cimport parallel from cython.parallel cimport threadid as tid from cython.parallel cimport threadavailable as tavail from cython.parallel cimport prange """ expected_directives_dict = { u'cython.parallel': u'cython.parallel', u'par': u'cython.parallel', u'par2': u'cython.parallel', u'parallel': u'cython.parallel', u"tid": u"cython.parallel.threadid", u"tavail": u"cython.parallel.threadavailable", u"prange": u"cython.parallel.prange", } def setUp(self): super(TestInterpretCompilerDirectives, self).setUp() compilation_options = Main.CompilationOptions(Main.default_options) ctx = compilation_options.create_context() transform = InterpretCompilerDirectives(ctx, ctx.compiler_directives) transform.module_scope = Symtab.ModuleScope('__main__', None, ctx) self.pipeline = [transform] self.debug_exception_on_error = DebugFlags.debug_exception_on_error def tearDown(self): DebugFlags.debug_exception_on_error = self.debug_exception_on_error def test_parallel_directives_cimports(self): self.run_pipeline(self.pipeline, self.import_code) parallel_directives = self.pipeline[0].parallel_directives self.assertEqual(parallel_directives, self.expected_directives_dict) def test_parallel_directives_imports(self): self.run_pipeline(self.pipeline, self.import_code.replace(u'cimport', u'import')) parallel_directives = self.pipeline[0].parallel_directives self.assertEqual(parallel_directives, self.expected_directives_dict) # TODO: Re-enable once they're more robust. if False: from Cython.Debugger import DebugWriter from Cython.Debugger.Tests.TestLibCython import DebuggerTestCase else: # skip test, don't let it inherit unittest.TestCase DebuggerTestCase = object class TestDebugTransform(DebuggerTestCase): def elem_hasattrs(self, elem, attrs): return all(attr in elem.attrib for attr in attrs) def test_debug_info(self): try: assert os.path.exists(self.debug_dest) t = DebugWriter.etree.parse(self.debug_dest) # the xpath of the standard ElementTree is primitive, don't use # anything fancy L = list(t.find('/Module/Globals')) # assertTrue is retarded, use the normal assert statement assert L xml_globals = dict((e.attrib['name'], e.attrib['type']) for e in L) self.assertEqual(len(L), len(xml_globals)) L = list(t.find('/Module/Functions')) assert L xml_funcs = dict((e.attrib['qualified_name'], e) for e in L) self.assertEqual(len(L), len(xml_funcs)) # test globals self.assertEqual('CObject', xml_globals.get('c_var')) self.assertEqual('PythonObject', xml_globals.get('python_var')) # test functions funcnames = ('codefile.spam', 'codefile.ham', 'codefile.eggs', 'codefile.closure', 'codefile.inner') required_xml_attrs = 'name', 'cname', 'qualified_name' assert all(f in xml_funcs for f in funcnames) spam, ham, eggs = [xml_funcs[funcname] for funcname in funcnames] self.assertEqual(spam.attrib['name'], 'spam') self.assertNotEqual('spam', spam.attrib['cname']) assert self.elem_hasattrs(spam, required_xml_attrs) # test locals of functions spam_locals = list(spam.find('Locals')) assert spam_locals spam_locals.sort(key=lambda e: e.attrib['name']) names = [e.attrib['name'] for e in spam_locals] self.assertEqual(list('abcd'), names) assert self.elem_hasattrs(spam_locals[0], required_xml_attrs) # test arguments of functions spam_arguments = list(spam.find('Arguments')) assert spam_arguments self.assertEqual(1, len(list(spam_arguments))) # test step-into functions step_into = spam.find('StepIntoFunctions') spam_stepinto = [x.attrib['name'] for x in step_into] assert spam_stepinto self.assertEqual(2, len(spam_stepinto)) assert 'puts' in spam_stepinto assert 'some_c_function' in spam_stepinto except: f = open(self.debug_dest) try: print(f.read()) finally: f.close() raise if __name__ == "__main__": import unittest unittest.main() Cython-0.23.4/Cython/Compiler/Tests/TestMemView.py0000644000175600017570000000472412606202452023116 0ustar jenkinsjenkins00000000000000from Cython.TestUtils import CythonTest import Cython.Compiler.Errors as Errors from Cython.Compiler.Nodes import * from Cython.Compiler.ParseTreeTransforms import * from Cython.Compiler.Buffer import * class TestMemviewParsing(CythonTest): def parse(self, s): return self.should_not_fail(lambda: self.fragment(s)).root def not_parseable(self, expected_error, s): e = self.should_fail(lambda: self.fragment(s), Errors.CompileError) self.assertEqual(expected_error, e.message_only) def test_default_1dim(self): self.parse(u"cdef int[:] x") self.parse(u"cdef short int[:] x") def test_default_ndim(self): self.parse(u"cdef int[:,:,:,:,:] x") self.parse(u"cdef unsigned long int[:,:,:,:,:] x") self.parse(u"cdef unsigned int[:,:,:,:,:] x") def test_zero_offset(self): self.parse(u"cdef long double[0:] x") self.parse(u"cdef int[0:] x") def test_zero_offset_ndim(self): self.parse(u"cdef int[0:,0:,0:,0:] x") def test_def_arg(self): self.parse(u"def foo(int[:,:] x): pass") def test_cdef_arg(self): self.parse(u"cdef foo(int[:,:] x): pass") def test_general_slice(self): self.parse(u'cdef float[::ptr, ::direct & contig, 0::full & strided] x') def test_non_slice_memview(self): self.not_parseable(u"An axis specification in memoryview declaration does not have a ':'.", u"cdef double[:foo, bar] x") self.not_parseable(u"An axis specification in memoryview declaration does not have a ':'.", u"cdef double[0:foo, bar] x") def test_basic(self): t = self.parse(u"cdef int[:] x") memv_node = t.stats[0].base_type self.assert_(isinstance(memv_node, MemoryViewSliceTypeNode)) # we also test other similar declarations (buffers, anonymous C arrays) # since the parsing has to distinguish between them. def disable_test_no_buf_arg(self): # TODO self.not_parseable(u"Expected ']'", u"cdef extern foo(object[int, ndim=2])") def disable_test_parse_sizeof(self): # TODO self.parse(u"sizeof(int[NN])") self.parse(u"sizeof(int[])") self.parse(u"sizeof(int[][NN])") self.not_parseable(u"Expected an identifier or literal", u"sizeof(int[:NN])") self.not_parseable(u"Expected ']'", u"sizeof(foo[dtype=bar]") if __name__ == '__main__': import unittest unittest.main() Cython-0.23.4/Cython/Compiler/Tests/TestCmdLine.py0000644000175600017570000001047612606202452023061 0ustar jenkinsjenkins00000000000000 import sys from unittest import TestCase try: from StringIO import StringIO except ImportError: from io import StringIO # doesn't accept 'str' in Py2 from .. import Options from ..CmdLine import parse_command_line class CmdLineParserTest(TestCase): def setUp(self): backup = {} for name, value in vars(Options).items(): backup[name] = value self._options_backup = backup def tearDown(self): no_value = object() for name, orig_value in self._options_backup.items(): if getattr(Options, name, no_value) != orig_value: setattr(Options, name, orig_value) def test_short_options(self): options, sources = parse_command_line([ '-V', '-l', '-+', '-t', '-v', '-v', '-v', '-p', '-D', '-a', '-3', ]) self.assertFalse(sources) self.assertTrue(options.show_version) self.assertTrue(options.use_listing_file) self.assertTrue(options.cplus) self.assertTrue(options.timestamps) self.assertTrue(options.verbose >= 3) self.assertTrue(Options.embed_pos_in_docstring) self.assertFalse(Options.docstrings) self.assertTrue(Options.annotate) self.assertEqual(options.language_level, 3) options, sources = parse_command_line([ '-f', '-2', 'source.pyx', ]) self.assertTrue(sources) self.assertTrue(len(sources) == 1) self.assertFalse(options.timestamps) self.assertEqual(options.language_level, 2) def test_long_options(self): options, sources = parse_command_line([ '--version', '--create-listing', '--cplus', '--embed', '--timestamps', '--verbose', '--verbose', '--verbose', '--embed-positions', '--no-docstrings', '--annotate', '--lenient', ]) self.assertFalse(sources) self.assertTrue(options.show_version) self.assertTrue(options.use_listing_file) self.assertTrue(options.cplus) self.assertEqual(Options.embed, 'main') self.assertTrue(options.timestamps) self.assertTrue(options.verbose >= 3) self.assertTrue(Options.embed_pos_in_docstring) self.assertFalse(Options.docstrings) self.assertTrue(Options.annotate) self.assertFalse(Options.error_on_unknown_names) self.assertFalse(Options.error_on_uninitialized) options, sources = parse_command_line([ '--force', 'source.pyx', ]) self.assertTrue(sources) self.assertTrue(len(sources) == 1) self.assertFalse(options.timestamps) def test_options_with_values(self): options, sources = parse_command_line([ '--embed=huhu', '-I/test/include/dir1', '--include-dir=/test/include/dir2', '--include-dir', '/test/include/dir3', '--working=/work/dir', 'source.pyx', '--output-file=/output/dir', '--pre-import=/pre/import', '--cleanup=3', '--annotate-coverage=cov.xml', '--gdb-outdir=/gdb/outdir', '--directive=wraparound=false', ]) self.assertEqual(sources, ['source.pyx']) self.assertEqual(Options.embed, 'huhu') self.assertEqual(options.include_path, ['/test/include/dir1', '/test/include/dir2', '/test/include/dir3']) self.assertEqual(options.working_path, '/work/dir') self.assertEqual(options.output_file, '/output/dir') self.assertEqual(Options.pre_import, '/pre/import') self.assertEqual(Options.generate_cleanup_code, 3) self.assertTrue(Options.annotate) self.assertEqual(Options.annotate_coverage_xml, 'cov.xml') self.assertTrue(options.gdb_debug) self.assertEqual(options.output_dir, '/gdb/outdir') def test_errors(self): def error(*args): old_stderr = sys.stderr stderr = sys.stderr = StringIO() try: self.assertRaises(SystemExit, parse_command_line, list(args)) finally: sys.stderr = old_stderr self.assertTrue(stderr.getvalue()) error('-1') error('-I') error('--version=-a') error('--version=--annotate=true') error('--working') error('--verbose=1') error('--verbose=1') error('--cleanup') Cython-0.23.4/Cython/Compiler/Tests/TestBuffer.py0000644000175600017570000001003212606202452022743 0ustar jenkinsjenkins00000000000000from Cython.TestUtils import CythonTest import Cython.Compiler.Errors as Errors from Cython.Compiler.Nodes import * from Cython.Compiler.ParseTreeTransforms import * from Cython.Compiler.Buffer import * class TestBufferParsing(CythonTest): # First, we only test the raw parser, i.e. # the number and contents of arguments are NOT checked. # However "dtype"/the first positional argument is special-cased # to parse a type argument rather than an expression def parse(self, s): return self.should_not_fail(lambda: self.fragment(s)).root def not_parseable(self, expected_error, s): e = self.should_fail(lambda: self.fragment(s), Errors.CompileError) self.assertEqual(expected_error, e.message_only) def test_basic(self): t = self.parse(u"cdef object[float, 4, ndim=2, foo=foo] x") bufnode = t.stats[0].base_type self.assert_(isinstance(bufnode, TemplatedTypeNode)) self.assertEqual(2, len(bufnode.positional_args)) # print bufnode.dump() # should put more here... def test_type_pos(self): self.parse(u"cdef object[short unsigned int, 3] x") def test_type_keyword(self): self.parse(u"cdef object[foo=foo, dtype=short unsigned int] x") def test_pos_after_key(self): self.not_parseable("Non-keyword arg following keyword arg", u"cdef object[foo=1, 2] x") # See also tests/error/e_bufaccess.pyx and tets/run/bufaccess.pyx # THESE TESTS ARE NOW DISABLED, the code they test was pretty much # refactored away class TestBufferOptions(CythonTest): # Tests the full parsing of the options within the brackets def nonfatal_error(self, error): # We're passing self as context to transform to trap this self.error = error self.assert_(self.expect_error) def parse_opts(self, opts, expect_error=False): assert opts != "" s = u"def f():\n cdef object[%s] x" % opts self.expect_error = expect_error root = self.fragment(s, pipeline=[NormalizeTree(self), PostParse(self)]).root if not expect_error: vardef = root.stats[0].body.stats[0] assert isinstance(vardef, CVarDefNode) # use normal assert as this is to validate the test code buftype = vardef.base_type self.assert_(isinstance(buftype, TemplatedTypeNode)) self.assert_(isinstance(buftype.base_type_node, CSimpleBaseTypeNode)) self.assertEqual(u"object", buftype.base_type_node.name) return buftype else: self.assert_(len(root.stats[0].body.stats) == 0) def non_parse(self, expected_err, opts): self.parse_opts(opts, expect_error=True) # e = self.should_fail(lambda: self.parse_opts(opts)) self.assertEqual(expected_err, self.error.message_only) def __test_basic(self): buf = self.parse_opts(u"unsigned short int, 3") self.assert_(isinstance(buf.dtype_node, CSimpleBaseTypeNode)) self.assert_(buf.dtype_node.signed == 0 and buf.dtype_node.longness == -1) self.assertEqual(3, buf.ndim) def __test_dict(self): buf = self.parse_opts(u"ndim=3, dtype=unsigned short int") self.assert_(isinstance(buf.dtype_node, CSimpleBaseTypeNode)) self.assert_(buf.dtype_node.signed == 0 and buf.dtype_node.longness == -1) self.assertEqual(3, buf.ndim) def __test_ndim(self): self.parse_opts(u"int, 2") self.non_parse(ERR_BUF_NDIM, u"int, 'a'") self.non_parse(ERR_BUF_NDIM, u"int, -34") def __test_use_DEF(self): t = self.fragment(u""" DEF ndim = 3 def f(): cdef object[int, ndim] x cdef object[ndim=ndim, dtype=int] y """, pipeline=[NormalizeTree(self), PostParse(self)]).root stats = t.stats[0].body.stats self.assert_(stats[0].base_type.ndim == 3) self.assert_(stats[1].base_type.ndim == 3) # add exotic and impossible combinations as they come along... if __name__ == '__main__': import unittest unittest.main() Cython-0.23.4/Cython/Build/0000755000175600017570000000000012606202455016512 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Build/__init__.py0000644000175600017570000000004412606202452020616 0ustar jenkinsjenkins00000000000000from .Dependencies import cythonize Cython-0.23.4/Cython/Build/IpythonMagic.py0000644000175600017570000002757112606202452021470 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- """ ===================== Cython related magics ===================== Magic command interface for interactive work with Cython .. note:: The ``Cython`` package needs to be installed separately. It can be obtained using ``easy_install`` or ``pip``. Usage ===== To enable the magics below, execute ``%load_ext cythonmagic``. ``%%cython`` {CYTHON_DOC} ``%%cython_inline`` {CYTHON_INLINE_DOC} ``%%cython_pyximport`` {CYTHON_PYXIMPORT_DOC} Author: * Brian Granger Code moved from IPython and adapted by: * Martín Gaitán Parts of this code were taken from Cython.inline. """ #----------------------------------------------------------------------------- # Copyright (C) 2010-2011, IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file ipython-COPYING.rst, distributed with this software. #----------------------------------------------------------------------------- from __future__ import absolute_import, print_function import imp import io import os import re import sys import time try: reload except NameError: # Python 3 from imp import reload try: import hashlib except ImportError: import md5 as hashlib from distutils.core import Distribution, Extension from distutils.command.build_ext import build_ext from IPython.core import display from IPython.core import magic_arguments from IPython.core.magic import Magics, magics_class, cell_magic from IPython.utils import py3compat try: from IPython.paths import get_ipython_cache_dir except ImportError: # older IPython version from IPython.utils.path import get_ipython_cache_dir from IPython.utils.text import dedent from ..Shadow import __version__ as cython_version from ..Compiler.Errors import CompileError from .Inline import cython_inline from .Dependencies import cythonize @magics_class class CythonMagics(Magics): def __init__(self, shell): super(CythonMagics,self).__init__(shell) self._reloads = {} self._code_cache = {} self._pyximport_installed = False def _import_all(self, module): for k,v in module.__dict__.items(): if not k.startswith('__'): self.shell.push({k:v}) @cell_magic def cython_inline(self, line, cell): """Compile and run a Cython code cell using Cython.inline. This magic simply passes the body of the cell to Cython.inline and returns the result. If the variables `a` and `b` are defined in the user's namespace, here is a simple example that returns their sum:: %%cython_inline return a+b For most purposes, we recommend the usage of the `%%cython` magic. """ locs = self.shell.user_global_ns globs = self.shell.user_ns return cython_inline(cell, locals=locs, globals=globs) @cell_magic def cython_pyximport(self, line, cell): """Compile and import a Cython code cell using pyximport. The contents of the cell are written to a `.pyx` file in the current working directory, which is then imported using `pyximport`. This magic requires a module name to be passed:: %%cython_pyximport modulename def f(x): return 2.0*x The compiled module is then imported and all of its symbols are injected into the user's namespace. For most purposes, we recommend the usage of the `%%cython` magic. """ module_name = line.strip() if not module_name: raise ValueError('module name must be given') fname = module_name + '.pyx' with io.open(fname, 'w', encoding='utf-8') as f: f.write(cell) if 'pyximport' not in sys.modules or not self._pyximport_installed: import pyximport pyximport.install(reload_support=True) self._pyximport_installed = True if module_name in self._reloads: module = self._reloads[module_name] reload(module) else: __import__(module_name) module = sys.modules[module_name] self._reloads[module_name] = module self._import_all(module) @magic_arguments.magic_arguments() @magic_arguments.argument( '-c', '--compile-args', action='append', default=[], help="Extra flags to pass to compiler via the `extra_compile_args` " "Extension flag (can be specified multiple times)." ) @magic_arguments.argument( '--link-args', action='append', default=[], help="Extra flags to pass to linker via the `extra_link_args` " "Extension flag (can be specified multiple times)." ) @magic_arguments.argument( '-l', '--lib', action='append', default=[], help="Add a library to link the extension against (can be specified " "multiple times)." ) @magic_arguments.argument( '-n', '--name', help="Specify a name for the Cython module." ) @magic_arguments.argument( '-L', dest='library_dirs', metavar='dir', action='append', default=[], help="Add a path to the list of libary directories (can be specified " "multiple times)." ) @magic_arguments.argument( '-I', '--include', action='append', default=[], help="Add a path to the list of include directories (can be specified " "multiple times)." ) @magic_arguments.argument( '-+', '--cplus', action='store_true', default=False, help="Output a C++ rather than C file." ) @magic_arguments.argument( '-f', '--force', action='store_true', default=False, help="Force the compilation of a new module, even if the source has been " "previously compiled." ) @magic_arguments.argument( '-a', '--annotate', action='store_true', default=False, help="Produce a colorized HTML version of the source." ) @cell_magic def cython(self, line, cell): """Compile and import everything from a Cython code cell. The contents of the cell are written to a `.pyx` file in the directory `IPYTHONDIR/cython` using a filename with the hash of the code. This file is then cythonized and compiled. The resulting module is imported and all of its symbols are injected into the user's namespace. The usage is similar to that of `%%cython_pyximport` but you don't have to pass a module name:: %%cython def f(x): return 2.0*x To compile OpenMP codes, pass the required `--compile-args` and `--link-args`. For example with gcc:: %%cython --compile-args=-fopenmp --link-args=-fopenmp ... """ args = magic_arguments.parse_argstring(self.cython, line) code = cell if cell.endswith('\n') else cell+'\n' lib_dir = os.path.join(get_ipython_cache_dir(), 'cython') quiet = True key = code, line, sys.version_info, sys.executable, cython_version if not os.path.exists(lib_dir): os.makedirs(lib_dir) if args.force: # Force a new module name by adding the current time to the # key which is hashed to determine the module name. key += time.time(), if args.name: module_name = py3compat.unicode_to_str(args.name) else: module_name = "_cython_magic_" + hashlib.md5(str(key).encode('utf-8')).hexdigest() module_path = os.path.join(lib_dir, module_name + self.so_ext) have_module = os.path.isfile(module_path) need_cythonize = not have_module if args.annotate: html_file = os.path.join(lib_dir, module_name + '.html') if not os.path.isfile(html_file): need_cythonize = True if need_cythonize: c_include_dirs = args.include if 'numpy' in code: import numpy c_include_dirs.append(numpy.get_include()) pyx_file = os.path.join(lib_dir, module_name + '.pyx') pyx_file = py3compat.cast_bytes_py2(pyx_file, encoding=sys.getfilesystemencoding()) with io.open(pyx_file, 'w', encoding='utf-8') as f: f.write(code) extension = Extension( name = module_name, sources = [pyx_file], include_dirs = c_include_dirs, library_dirs = args.library_dirs, extra_compile_args = args.compile_args, extra_link_args = args.link_args, libraries = args.lib, language = 'c++' if args.cplus else 'c', ) build_extension = self._get_build_extension() try: opts = dict( quiet=quiet, annotate = args.annotate, force = True, ) build_extension.extensions = cythonize([extension], **opts) except CompileError: return if not have_module: build_extension.build_temp = os.path.dirname(pyx_file) build_extension.build_lib = lib_dir build_extension.run() self._code_cache[key] = module_name module = imp.load_dynamic(module_name, module_path) self._import_all(module) if args.annotate: try: with io.open(html_file, encoding='utf-8') as f: annotated_html = f.read() except IOError as e: # File could not be opened. Most likely the user has a version # of Cython before 0.15.1 (when `cythonize` learned the # `force` keyword argument) and has already compiled this # exact source without annotation. print('Cython completed successfully but the annotated ' 'source could not be read.', file=sys.stderr) print(e, file=sys.stderr) else: return display.HTML(self.clean_annotated_html(annotated_html)) @property def so_ext(self): """The extension suffix for compiled modules.""" try: return self._so_ext except AttributeError: self._so_ext = self._get_build_extension().get_ext_filename('') return self._so_ext def _clear_distutils_mkpath_cache(self): """clear distutils mkpath cache prevents distutils from skipping re-creation of dirs that have been removed """ try: from distutils.dir_util import _path_created except ImportError: pass else: _path_created.clear() def _get_build_extension(self): self._clear_distutils_mkpath_cache() dist = Distribution() config_files = dist.find_config_files() try: config_files.remove('setup.cfg') except ValueError: pass dist.parse_config_files(config_files) build_extension = build_ext(dist) build_extension.finalize_options() return build_extension @staticmethod def clean_annotated_html(html): """Clean up the annotated HTML source. Strips the link to the generated C or C++ file, which we do not present to the user. """ r = re.compile('

    Raw output: (.*)') html = '\n'.join(l for l in html.splitlines() if not r.match(l)) return html __doc__ = __doc__.format( # rST doesn't see the -+ flag as part of an option list, so we # hide it from the module-level docstring. CYTHON_DOC = dedent(CythonMagics.cython.__doc__\ .replace('-+, --cplus','--cplus ')), CYTHON_INLINE_DOC = dedent(CythonMagics.cython_inline.__doc__), CYTHON_PYXIMPORT_DOC = dedent(CythonMagics.cython_pyximport.__doc__), ) Cython-0.23.4/Cython/Build/Inline.py0000644000175600017570000002572212606202452020307 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import import sys, os, re, inspect import imp try: import hashlib except ImportError: import md5 as hashlib from distutils.core import Distribution, Extension from distutils.command.build_ext import build_ext import Cython from ..Compiler.Main import Context, CompilationOptions, default_options from ..Compiler.ParseTreeTransforms import (CythonTransform, SkipDeclarations, AnalyseDeclarationsTransform, EnvTransform) from ..Compiler.TreeFragment import parse_from_strings from ..Compiler.StringEncoding import _unicode from .Dependencies import strip_string_literals, cythonize, cached_function from ..Compiler import Pipeline, Nodes from ..Utils import get_cython_cache_dir import cython as cython_module IS_PY3 = sys.version_info >= (3, 0) # A utility function to convert user-supplied ASCII strings to unicode. if sys.version_info[0] < 3: def to_unicode(s): if isinstance(s, bytes): return s.decode('ascii') else: return s else: to_unicode = lambda x: x class UnboundSymbols(EnvTransform, SkipDeclarations): def __init__(self): CythonTransform.__init__(self, None) self.unbound = set() def visit_NameNode(self, node): if not self.current_env().lookup(node.name): self.unbound.add(node.name) return node def __call__(self, node): super(UnboundSymbols, self).__call__(node) return self.unbound @cached_function def unbound_symbols(code, context=None): code = to_unicode(code) if context is None: context = Context([], default_options) from ..Compiler.ParseTreeTransforms import AnalyseDeclarationsTransform tree = parse_from_strings('(tree fragment)', code) for phase in Pipeline.create_pipeline(context, 'pyx'): if phase is None: continue tree = phase(tree) if isinstance(phase, AnalyseDeclarationsTransform): break try: import builtins except ImportError: import __builtin__ as builtins return UnboundSymbols()(tree) - set(dir(builtins)) def unsafe_type(arg, context=None): py_type = type(arg) if py_type is int: return 'long' else: return safe_type(arg, context) def safe_type(arg, context=None): py_type = type(arg) if py_type in [list, tuple, dict, str]: return py_type.__name__ elif py_type is complex: return 'double complex' elif py_type is float: return 'double' elif py_type is bool: return 'bint' elif 'numpy' in sys.modules and isinstance(arg, sys.modules['numpy'].ndarray): return 'numpy.ndarray[numpy.%s_t, ndim=%s]' % (arg.dtype.name, arg.ndim) else: for base_type in py_type.mro(): if base_type.__module__ in ('__builtin__', 'builtins'): return 'object' module = context.find_module(base_type.__module__, need_pxd=False) if module: entry = module.lookup(base_type.__name__) if entry.is_type: return '%s.%s' % (base_type.__module__, base_type.__name__) return 'object' def _get_build_extension(): dist = Distribution() # Ensure the build respects distutils configuration by parsing # the configuration files config_files = dist.find_config_files() dist.parse_config_files(config_files) build_extension = build_ext(dist) build_extension.finalize_options() return build_extension @cached_function def _create_context(cython_include_dirs): return Context(list(cython_include_dirs), default_options) def cython_inline(code, get_type=unsafe_type, lib_dir=os.path.join(get_cython_cache_dir(), 'inline'), cython_include_dirs=['.'], force=False, quiet=False, locals=None, globals=None, **kwds): if get_type is None: get_type = lambda x: 'object' code = to_unicode(code) orig_code = code code, literals = strip_string_literals(code) code = strip_common_indent(code) ctx = _create_context(tuple(cython_include_dirs)) if locals is None: locals = inspect.currentframe().f_back.f_back.f_locals if globals is None: globals = inspect.currentframe().f_back.f_back.f_globals try: for symbol in unbound_symbols(code): if symbol in kwds: continue elif symbol in locals: kwds[symbol] = locals[symbol] elif symbol in globals: kwds[symbol] = globals[symbol] else: print("Couldn't find %r" % symbol) except AssertionError: if not quiet: # Parsing from strings not fully supported (e.g. cimports). print("Could not parse code as a string (to extract unbound symbols).") cimports = [] for name, arg in list(kwds.items()): if arg is cython_module: cimports.append('\ncimport cython as %s' % name) del kwds[name] arg_names = sorted(kwds) arg_sigs = tuple([(get_type(kwds[arg], ctx), arg) for arg in arg_names]) key = orig_code, arg_sigs, sys.version_info, sys.executable, Cython.__version__ module_name = "_cython_inline_" + hashlib.md5(_unicode(key).encode('utf-8')).hexdigest() if module_name in sys.modules: module = sys.modules[module_name] else: build_extension = None if cython_inline.so_ext is None: # Figure out and cache current extension suffix build_extension = _get_build_extension() cython_inline.so_ext = build_extension.get_ext_filename('') module_path = os.path.join(lib_dir, module_name + cython_inline.so_ext) if not os.path.exists(lib_dir): os.makedirs(lib_dir) if force or not os.path.isfile(module_path): cflags = [] c_include_dirs = [] qualified = re.compile(r'([.\w]+)[.]') for type, _ in arg_sigs: m = qualified.match(type) if m: cimports.append('\ncimport %s' % m.groups()[0]) # one special case if m.groups()[0] == 'numpy': import numpy c_include_dirs.append(numpy.get_include()) # cflags.append('-Wno-unused') module_body, func_body = extract_func_code(code) params = ', '.join(['%s %s' % a for a in arg_sigs]) module_code = """ %(module_body)s %(cimports)s def __invoke(%(params)s): %(func_body)s return locals() """ % {'cimports': '\n'.join(cimports), 'module_body': module_body, 'params': params, 'func_body': func_body } for key, value in literals.items(): module_code = module_code.replace(key, value) pyx_file = os.path.join(lib_dir, module_name + '.pyx') fh = open(pyx_file, 'w') try: fh.write(module_code) finally: fh.close() extension = Extension( name = module_name, sources = [pyx_file], include_dirs = c_include_dirs, extra_compile_args = cflags) if build_extension is None: build_extension = _get_build_extension() build_extension.extensions = cythonize([extension], include_path=cython_include_dirs, quiet=quiet) build_extension.build_temp = os.path.dirname(pyx_file) build_extension.build_lib = lib_dir build_extension.run() module = imp.load_dynamic(module_name, module_path) arg_list = [kwds[arg] for arg in arg_names] return module.__invoke(*arg_list) # Cached suffix used by cython_inline above. None should get # overridden with actual value upon the first cython_inline invocation cython_inline.so_ext = None _find_non_space = re.compile('[^ ]').search def strip_common_indent(code): min_indent = None lines = code.splitlines() for line in lines: match = _find_non_space(line) if not match: continue # blank indent = match.start() if line[indent] == '#': continue # comment if min_indent is None or min_indent > indent: min_indent = indent for ix, line in enumerate(lines): match = _find_non_space(line) if not match or not line or line[indent:indent+1] == '#': continue lines[ix] = line[min_indent:] return '\n'.join(lines) module_statement = re.compile(r'^((cdef +(extern|class))|cimport|(from .+ cimport)|(from .+ import +[*]))') def extract_func_code(code): module = [] function = [] current = function code = code.replace('\t', ' ') lines = code.split('\n') for line in lines: if not line.startswith(' '): if module_statement.match(line): current = module else: current = function current.append(line) return '\n'.join(module), ' ' + '\n '.join(function) try: from inspect import getcallargs except ImportError: def getcallargs(func, *arg_values, **kwd_values): all = {} args, varargs, kwds, defaults = inspect.getargspec(func) if varargs is not None: all[varargs] = arg_values[len(args):] for name, value in zip(args, arg_values): all[name] = value for name, value in list(kwd_values.items()): if name in args: if name in all: raise TypeError("Duplicate argument %s" % name) all[name] = kwd_values.pop(name) if kwds is not None: all[kwds] = kwd_values elif kwd_values: raise TypeError("Unexpected keyword arguments: %s" % list(kwd_values)) if defaults is None: defaults = () first_default = len(args) - len(defaults) for ix, name in enumerate(args): if name not in all: if ix >= first_default: all[name] = defaults[ix - first_default] else: raise TypeError("Missing argument: %s" % name) return all def get_body(source): ix = source.index(':') if source[:5] == 'lambda': return "return %s" % source[ix+1:] else: return source[ix+1:] # Lots to be done here... It would be especially cool if compiled functions # could invoke each other quickly. class RuntimeCompiledFunction(object): def __init__(self, f): self._f = f self._body = get_body(inspect.getsource(f)) def __call__(self, *args, **kwds): all = getcallargs(self._f, *args, **kwds) if IS_PY3: return cython_inline(self._body, locals=self._f.__globals__, globals=self._f.__globals__, **all) else: return cython_inline(self._body, locals=self._f.func_globals, globals=self._f.func_globals, **all) Cython-0.23.4/Cython/Build/Dependencies.py0000644000175600017570000011160512606202452021453 0ustar jenkinsjenkins00000000000000from __future__ import absolute_import, print_function import cython from .. import __version__ import re, os, sys, time from glob import iglob try: import gzip gzip_open = gzip.open gzip_ext = '.gz' except ImportError: gzip_open = open gzip_ext = '' import shutil import subprocess try: import hashlib except ImportError: import md5 as hashlib try: from io import open as io_open except ImportError: from codecs import open as io_open try: from os.path import relpath as _relpath except ImportError: # Py<2.6 def _relpath(path, start=os.path.curdir): if not path: raise ValueError("no path specified") start_list = os.path.abspath(start).split(os.path.sep) path_list = os.path.abspath(path).split(os.path.sep) i = len(os.path.commonprefix([start_list, path_list])) rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:] if not rel_list: return os.path.curdir return os.path.join(*rel_list) from distutils.extension import Extension from .. import Utils from ..Utils import cached_function, cached_method, path_exists, find_root_package_dir, is_package_dir from ..Compiler.Main import Context, CompilationOptions, default_options join_path = cached_function(os.path.join) if sys.version_info[0] < 3: # stupid Py2 distutils enforces str type in list of sources _fs_encoding = sys.getfilesystemencoding() if _fs_encoding is None: _fs_encoding = sys.getdefaultencoding() def encode_filename_in_py2(filename): if not isinstance(filename, bytes): return filename.encode(_fs_encoding) return filename else: def encode_filename_in_py2(filename): return filename basestring = str def extended_iglob(pattern): if '{' in pattern: m = re.match('(.*){([^}]+)}(.*)', pattern) if m: before, switch, after = m.groups() for case in switch.split(','): for path in extended_iglob(before + case + after): yield path return if '**/' in pattern: seen = set() first, rest = pattern.split('**/', 1) if first: first = iglob(first+'/') else: first = [''] for root in first: for path in extended_iglob(join_path(root, rest)): if path not in seen: seen.add(path) yield path for path in extended_iglob(join_path(root, '*', '**/' + rest)): if path not in seen: seen.add(path) yield path else: for path in iglob(pattern): yield path def nonempty(it, error_msg="expected non-empty iterator"): empty = True for value in it: empty = False yield value if empty: raise ValueError(error_msg) @cached_function def file_hash(filename): path = os.path.normpath(filename.encode("UTF-8")) m = hashlib.md5(str(len(path)) + ":") m.update(path) f = open(filename, 'rb') try: data = f.read(65000) while data: m.update(data) data = f.read(65000) finally: f.close() return m.hexdigest() def parse_list(s): """ >>> parse_list("a b c") ['a', 'b', 'c'] >>> parse_list("[a, b, c]") ['a', 'b', 'c'] >>> parse_list('a " " b') ['a', ' ', 'b'] >>> parse_list('[a, ",a", "a,", ",", ]') ['a', ',a', 'a,', ','] """ if s[0] == '[' and s[-1] == ']': s = s[1:-1] delimiter = ',' else: delimiter = ' ' s, literals = strip_string_literals(s) def unquote(literal): literal = literal.strip() if literal[0] in "'\"": return literals[literal[1:-1]] else: return literal return [unquote(item) for item in s.split(delimiter) if item.strip()] transitive_str = object() transitive_list = object() distutils_settings = { 'name': str, 'sources': list, 'define_macros': list, 'undef_macros': list, 'libraries': transitive_list, 'library_dirs': transitive_list, 'runtime_library_dirs': transitive_list, 'include_dirs': transitive_list, 'extra_objects': list, 'extra_compile_args': transitive_list, 'extra_link_args': transitive_list, 'export_symbols': list, 'depends': transitive_list, 'language': transitive_str, } @cython.locals(start=cython.Py_ssize_t, end=cython.Py_ssize_t) def line_iter(source): if isinstance(source, basestring): start = 0 while True: end = source.find('\n', start) if end == -1: yield source[start:] return yield source[start:end] start = end+1 else: for line in source: yield line class DistutilsInfo(object): def __init__(self, source=None, exn=None): self.values = {} if source is not None: for line in line_iter(source): line = line.strip() if line != '' and line[0] != '#': break line = line[1:].strip() if line[:10] == 'distutils:': line = line[10:] ix = line.index('=') key = str(line[:ix].strip()) value = line[ix+1:].strip() type = distutils_settings[key] if type in (list, transitive_list): value = parse_list(value) if key == 'define_macros': value = [tuple(macro.split('=')) for macro in value] self.values[key] = value elif exn is not None: for key in distutils_settings: if key in ('name', 'sources'): continue value = getattr(exn, key, None) if value: self.values[key] = value def merge(self, other): if other is None: return self for key, value in other.values.items(): type = distutils_settings[key] if type is transitive_str and key not in self.values: self.values[key] = value elif type is transitive_list: if key in self.values: # Change a *copy* of the list (Trac #845) all = self.values[key][:] for v in value: if v not in all: all.append(v) value = all self.values[key] = value return self def subs(self, aliases): if aliases is None: return self resolved = DistutilsInfo() for key, value in self.values.items(): type = distutils_settings[key] if type in [list, transitive_list]: new_value_list = [] for v in value: if v in aliases: v = aliases[v] if isinstance(v, list): new_value_list += v else: new_value_list.append(v) value = new_value_list else: if value in aliases: value = aliases[value] resolved.values[key] = value return resolved def apply(self, extension): for key, value in self.values.items(): type = distutils_settings[key] if type in [list, transitive_list]: value = getattr(extension, key) + list(value) setattr(extension, key, value) @cython.locals(start=cython.Py_ssize_t, q=cython.Py_ssize_t, single_q=cython.Py_ssize_t, double_q=cython.Py_ssize_t, hash_mark=cython.Py_ssize_t, end=cython.Py_ssize_t, k=cython.Py_ssize_t, counter=cython.Py_ssize_t, quote_len=cython.Py_ssize_t) def strip_string_literals(code, prefix='__Pyx_L'): """ Normalizes every string literal to be of the form '__Pyx_Lxxx', returning the normalized code and a mapping of labels to string literals. """ new_code = [] literals = {} counter = 0 start = q = 0 in_quote = False hash_mark = single_q = double_q = -1 code_len = len(code) quote_type = quote_len = None while True: if hash_mark < q: hash_mark = code.find('#', q) if single_q < q: single_q = code.find("'", q) if double_q < q: double_q = code.find('"', q) q = min(single_q, double_q) if q == -1: q = max(single_q, double_q) # We're done. if q == -1 and hash_mark == -1: new_code.append(code[start:]) break # Try to close the quote. elif in_quote: if code[q-1] == u'\\': k = 2 while q >= k and code[q-k] == u'\\': k += 1 if k % 2 == 0: q += 1 continue if code[q] == quote_type and ( quote_len == 1 or (code_len > q + 2 and quote_type == code[q+1] == code[q+2])): counter += 1 label = "%s%s_" % (prefix, counter) literals[label] = code[start+quote_len:q] full_quote = code[q:q+quote_len] new_code.append(full_quote) new_code.append(label) new_code.append(full_quote) q += quote_len in_quote = False start = q else: q += 1 # Process comment. elif -1 != hash_mark and (hash_mark < q or q == -1): new_code.append(code[start:hash_mark+1]) end = code.find('\n', hash_mark) counter += 1 label = "%s%s_" % (prefix, counter) if end == -1: end_or_none = None else: end_or_none = end literals[label] = code[hash_mark+1:end_or_none] new_code.append(label) if end == -1: break start = q = end # Open the quote. else: if code_len >= q+3 and (code[q] == code[q+1] == code[q+2]): quote_len = 3 else: quote_len = 1 in_quote = True quote_type = code[q] new_code.append(code[start:q]) start = q q += quote_len return "".join(new_code), literals dependency_regex = re.compile(r"(?:^from +([0-9a-zA-Z_.]+) +cimport)|" r"(?:^cimport +([0-9a-zA-Z_.]+(?: *, *[0-9a-zA-Z_.]+)*))|" r"(?:^cdef +extern +from +['\"]([^'\"]+)['\"])|" r"(?:^include +['\"]([^'\"]+)['\"])", re.M) def normalize_existing(base_path, rel_paths): return normalize_existing0(os.path.dirname(base_path), tuple(set(rel_paths))) @cached_function def normalize_existing0(base_dir, rel_paths): normalized = [] for rel in rel_paths: path = join_path(base_dir, rel) if path_exists(path): normalized.append(os.path.normpath(path)) else: normalized.append(rel) return normalized def resolve_depends(depends, include_dirs): include_dirs = tuple(include_dirs) resolved = [] for depend in depends: path = resolve_depend(depend, include_dirs) if path is not None: resolved.append(path) return resolved @cached_function def resolve_depend(depend, include_dirs): if depend[0] == '<' and depend[-1] == '>': return None for dir in include_dirs: path = join_path(dir, depend) if path_exists(path): return os.path.normpath(path) return None @cached_function def package(filename): dir = os.path.dirname(os.path.abspath(str(filename))) if dir != filename and is_package_dir(dir): return package(dir) + (os.path.basename(dir),) else: return () @cached_function def fully_qualified_name(filename): module = os.path.splitext(os.path.basename(filename))[0] return '.'.join(package(filename) + (module,)) @cached_function def parse_dependencies(source_filename): # Actual parsing is way to slow, so we use regular expressions. # The only catch is that we must strip comments and string # literals ahead of time. fh = Utils.open_source_file(source_filename, error_handling='ignore') try: source = fh.read() finally: fh.close() distutils_info = DistutilsInfo(source) source, literals = strip_string_literals(source) source = source.replace('\\\n', ' ').replace('\t', ' ') # TODO: pure mode cimports = [] includes = [] externs = [] for m in dependency_regex.finditer(source): cimport_from, cimport_list, extern, include = m.groups() if cimport_from: cimports.append(cimport_from) elif cimport_list: cimports.extend(x.strip() for x in cimport_list.split(",")) elif extern: externs.append(literals[extern]) else: includes.append(literals[include]) return cimports, includes, externs, distutils_info class DependencyTree(object): def __init__(self, context, quiet=False): self.context = context self.quiet = quiet self._transitive_cache = {} def parse_dependencies(self, source_filename): return parse_dependencies(source_filename) @cached_method def included_files(self, filename): # This is messy because included files are textually included, resolving # cimports (but not includes) relative to the including file. all = set() for include in self.parse_dependencies(filename)[1]: include_path = join_path(os.path.dirname(filename), include) if not path_exists(include_path): include_path = self.context.find_include_file(include, None) if include_path: if '.' + os.path.sep in include_path: include_path = os.path.normpath(include_path) all.add(include_path) all.update(self.included_files(include_path)) elif not self.quiet: print("Unable to locate '%s' referenced from '%s'" % (filename, include)) return all @cached_method def cimports_and_externs(self, filename): # This is really ugly. Nested cimports are resolved with respect to the # includer, but includes are resolved with respect to the includee. cimports, includes, externs = self.parse_dependencies(filename)[:3] cimports = set(cimports) externs = set(externs) for include in self.included_files(filename): included_cimports, included_externs = self.cimports_and_externs(include) cimports.update(included_cimports) externs.update(included_externs) return tuple(cimports), normalize_existing(filename, externs) def cimports(self, filename): return self.cimports_and_externs(filename)[0] def package(self, filename): return package(filename) def fully_qualified_name(self, filename): return fully_qualified_name(filename) @cached_method def find_pxd(self, module, filename=None): is_relative = module[0] == '.' if is_relative and not filename: raise NotImplementedError("New relative imports.") if filename is not None: module_path = module.split('.') if is_relative: module_path.pop(0) # just explicitly relative package_path = list(self.package(filename)) while module_path and not module_path[0]: try: package_path.pop() except IndexError: return None # FIXME: error? module_path.pop(0) relative = '.'.join(package_path + module_path) pxd = self.context.find_pxd_file(relative, None) if pxd: return pxd if is_relative: return None # FIXME: error? return self.context.find_pxd_file(module, None) @cached_method def cimported_files(self, filename): if filename[-4:] == '.pyx' and path_exists(filename[:-4] + '.pxd'): pxd_list = [filename[:-4] + '.pxd'] else: pxd_list = [] for module in self.cimports(filename): if module[:7] == 'cython.' or module == 'cython': continue pxd_file = self.find_pxd(module, filename) if pxd_file is not None: pxd_list.append(pxd_file) elif not self.quiet: print("missing cimport in module '%s': %s" % (module, filename)) return tuple(pxd_list) @cached_method def immediate_dependencies(self, filename): all = set([filename]) all.update(self.cimported_files(filename)) all.update(self.included_files(filename)) return all def all_dependencies(self, filename): return self.transitive_merge(filename, self.immediate_dependencies, set.union) @cached_method def timestamp(self, filename): return os.path.getmtime(filename) def extract_timestamp(self, filename): return self.timestamp(filename), filename def newest_dependency(self, filename): return max([self.extract_timestamp(f) for f in self.all_dependencies(filename)]) def transitive_fingerprint(self, filename, extra=None): try: m = hashlib.md5(__version__) m.update(file_hash(filename)) for x in sorted(self.all_dependencies(filename)): if os.path.splitext(x)[1] not in ('.c', '.cpp', '.h'): m.update(file_hash(x)) if extra is not None: m.update(str(extra)) return m.hexdigest() except IOError: return None def distutils_info0(self, filename): info = self.parse_dependencies(filename)[3] externs = self.cimports_and_externs(filename)[1] if externs: if 'depends' in info.values: info.values['depends'] = list(set(info.values['depends']).union(externs)) else: info.values['depends'] = list(externs) return info def distutils_info(self, filename, aliases=None, base=None): return (self.transitive_merge(filename, self.distutils_info0, DistutilsInfo.merge) .subs(aliases) .merge(base)) def transitive_merge(self, node, extract, merge): try: seen = self._transitive_cache[extract, merge] except KeyError: seen = self._transitive_cache[extract, merge] = {} return self.transitive_merge_helper( node, extract, merge, seen, {}, self.cimported_files)[0] def transitive_merge_helper(self, node, extract, merge, seen, stack, outgoing): if node in seen: return seen[node], None deps = extract(node) if node in stack: return deps, node try: stack[node] = len(stack) loop = None for next in outgoing(node): sub_deps, sub_loop = self.transitive_merge_helper(next, extract, merge, seen, stack, outgoing) if sub_loop is not None: if loop is not None and stack[loop] < stack[sub_loop]: pass else: loop = sub_loop deps = merge(deps, sub_deps) if loop == node: loop = None if loop is None: seen[node] = deps return deps, loop finally: del stack[node] _dep_tree = None def create_dependency_tree(ctx=None, quiet=False): global _dep_tree if _dep_tree is None: if ctx is None: ctx = Context(["."], CompilationOptions(default_options)) _dep_tree = DependencyTree(ctx, quiet=quiet) return _dep_tree # This may be useful for advanced users? def create_extension_list(patterns, exclude=[], ctx=None, aliases=None, quiet=False, language=None, exclude_failures=False): if not isinstance(patterns, (list, tuple)): patterns = [patterns] explicit_modules = set([m.name for m in patterns if isinstance(m, Extension)]) seen = set() deps = create_dependency_tree(ctx, quiet=quiet) to_exclude = set() if not isinstance(exclude, list): exclude = [exclude] for pattern in exclude: to_exclude.update(map(os.path.abspath, extended_iglob(pattern))) module_list = [] module_metadata = {} for pattern in patterns: if isinstance(pattern, str): filepattern = pattern template = None name = '*' base = None exn_type = Extension ext_language = language elif isinstance(pattern, Extension): for filepattern in pattern.sources: if os.path.splitext(filepattern)[1] in ('.py', '.pyx'): break else: # ignore non-cython modules module_list.append(pattern) continue template = pattern name = template.name base = DistutilsInfo(exn=template) exn_type = template.__class__ ext_language = None # do not override whatever the Extension says else: raise TypeError(pattern) for file in nonempty(sorted(extended_iglob(filepattern)), "'%s' doesn't match any files" % filepattern): if os.path.abspath(file) in to_exclude: continue pkg = deps.package(file) if '*' in name: module_name = deps.fully_qualified_name(file) if module_name in explicit_modules: continue else: module_name = name if module_name not in seen: try: kwds = deps.distutils_info(file, aliases, base).values except Exception: if exclude_failures: continue raise if base is not None: for key, value in base.values.items(): if key not in kwds: kwds[key] = value sources = [file] if template is not None: sources += [m for m in template.sources if m != filepattern] if 'sources' in kwds: # allow users to add .c files etc. for source in kwds['sources']: source = encode_filename_in_py2(source) if source not in sources: sources.append(source) extra_sources = kwds['sources'] del kwds['sources'] else: extra_sources = None if 'depends' in kwds: depends = resolve_depends(kwds['depends'], (kwds.get('include_dirs') or []) + [find_root_package_dir(file)]) if template is not None: # Always include everything from the template. depends = set(template.depends).union(depends) # Sort depends to make the metadata dump in the # Cython-generated C code predictable. kwds['depends'] = sorted(depends) if ext_language and 'language' not in kwds: kwds['language'] = ext_language module_list.append(exn_type( name=module_name, sources=sources, **kwds)) if extra_sources: kwds['sources'] = extra_sources module_metadata[module_name] = {'distutils': kwds} m = module_list[-1] seen.add(name) return module_list, module_metadata # This is the user-exposed entry point. def cythonize(module_list, exclude=[], nthreads=0, aliases=None, quiet=False, force=False, language=None, exclude_failures=False, **options): """ Compile a set of source modules into C/C++ files and return a list of distutils Extension objects for them. As module list, pass either a glob pattern, a list of glob patterns or a list of Extension objects. The latter allows you to configure the extensions separately through the normal distutils options. When using glob patterns, you can exclude certain module names explicitly by passing them into the 'exclude' option. To globally enable C++ mode, you can pass language='c++'. Otherwise, this will be determined at a per-file level based on compiler directives. This affects only modules found based on file names. Extension instances passed into cythonize() will not be changed. For parallel compilation, set the 'nthreads' option to the number of concurrent builds. For a broad 'try to compile' mode that ignores compilation failures and simply excludes the failed extensions, pass 'exclude_failures=True'. Note that this only really makes sense for compiling .py files which can also be used without compilation. Additional compilation options can be passed as keyword arguments. """ if 'include_path' not in options: options['include_path'] = ['.'] if 'common_utility_include_dir' in options: if options.get('cache'): raise NotImplementedError("common_utility_include_dir does not yet work with caching") if not os.path.exists(options['common_utility_include_dir']): os.makedirs(options['common_utility_include_dir']) c_options = CompilationOptions(**options) cpp_options = CompilationOptions(**options); cpp_options.cplus = True ctx = c_options.create_context() options = c_options module_list, module_metadata = create_extension_list( module_list, exclude=exclude, ctx=ctx, quiet=quiet, exclude_failures=exclude_failures, language=language, aliases=aliases) deps = create_dependency_tree(ctx, quiet=quiet) build_dir = getattr(options, 'build_dir', None) modules_by_cfile = {} to_compile = [] for m in module_list: if build_dir: root = os.path.realpath(os.path.abspath(find_root_package_dir(m.sources[0]))) def copy_to_build_dir(filepath, root=root): filepath_abs = os.path.realpath(os.path.abspath(filepath)) if os.path.isabs(filepath): filepath = filepath_abs if filepath_abs.startswith(root): mod_dir = os.path.join(build_dir, os.path.dirname(_relpath(filepath, root))) if not os.path.isdir(mod_dir): os.makedirs(mod_dir) shutil.copy(filepath, mod_dir) for dep in m.depends: copy_to_build_dir(dep) new_sources = [] for source in m.sources: base, ext = os.path.splitext(source) if ext in ('.pyx', '.py'): if m.language == 'c++': c_file = base + '.cpp' options = cpp_options else: c_file = base + '.c' options = c_options # setup for out of place build directory if enabled if build_dir: c_file = os.path.join(build_dir, c_file) dir = os.path.dirname(c_file) if not os.path.isdir(dir): os.makedirs(dir) if os.path.exists(c_file): c_timestamp = os.path.getmtime(c_file) else: c_timestamp = -1 # Priority goes first to modified files, second to direct # dependents, and finally to indirect dependents. if c_timestamp < deps.timestamp(source): dep_timestamp, dep = deps.timestamp(source), source priority = 0 else: dep_timestamp, dep = deps.newest_dependency(source) priority = 2 - (dep in deps.immediate_dependencies(source)) if force or c_timestamp < dep_timestamp: if not quiet: if source == dep: print("Compiling %s because it changed." % source) else: print("Compiling %s because it depends on %s." % (source, dep)) if not force and hasattr(options, 'cache'): extra = m.language fingerprint = deps.transitive_fingerprint(source, extra) else: fingerprint = None to_compile.append((priority, source, c_file, fingerprint, quiet, options, not exclude_failures, module_metadata.get(m.name))) new_sources.append(c_file) if c_file not in modules_by_cfile: modules_by_cfile[c_file] = [m] else: modules_by_cfile[c_file].append(m) else: new_sources.append(source) if build_dir: copy_to_build_dir(source) m.sources = new_sources if hasattr(options, 'cache'): if not os.path.exists(options.cache): os.makedirs(options.cache) to_compile.sort() # Drop "priority" component of "to_compile" entries and add a # simple progress indicator. N = len(to_compile) progress_fmt = "[{0:%d}/{1}] " % len(str(N)) for i in range(N): progress = progress_fmt.format(i+1, N) to_compile[i] = to_compile[i][1:] + (progress,) if N <= 1: nthreads = 0 if nthreads: # Requires multiprocessing (or Python >= 2.6) try: import multiprocessing pool = multiprocessing.Pool( nthreads, initializer=_init_multiprocessing_helper) except (ImportError, OSError): print("multiprocessing required for parallel cythonization") nthreads = 0 else: # This is a bit more involved than it should be, because KeyboardInterrupts # break the multiprocessing workers when using a normal pool.map(). # See, for example: # http://noswap.com/blog/python-multiprocessing-keyboardinterrupt try: result = pool.map_async(cythonize_one_helper, to_compile, chunksize=1) pool.close() while not result.ready(): try: result.get(99999) # seconds except multiprocessing.TimeoutError: pass except KeyboardInterrupt: pool.terminate() raise pool.join() if not nthreads: for args in to_compile: cythonize_one(*args) if exclude_failures: failed_modules = set() for c_file, modules in modules_by_cfile.items(): if not os.path.exists(c_file): failed_modules.update(modules) elif os.path.getsize(c_file) < 200: f = io_open(c_file, 'r', encoding='iso8859-1') try: if f.read(len('#error ')) == '#error ': # dead compilation result failed_modules.update(modules) finally: f.close() if failed_modules: for module in failed_modules: module_list.remove(module) print("Failed compilations: %s" % ', '.join(sorted([ module.name for module in failed_modules]))) if hasattr(options, 'cache'): cleanup_cache(options.cache, getattr(options, 'cache_size', 1024 * 1024 * 100)) # cythonize() is often followed by the (non-Python-buffered) # compiler output, flush now to avoid interleaving output. sys.stdout.flush() return module_list if os.environ.get('XML_RESULTS'): compile_result_dir = os.environ['XML_RESULTS'] def record_results(func): def with_record(*args): t = time.time() success = True try: try: func(*args) except: success = False finally: t = time.time() - t module = fully_qualified_name(args[0]) name = "cythonize." + module failures = 1 - success if success: failure_item = "" else: failure_item = "failure" output = open(os.path.join(compile_result_dir, name + ".xml"), "w") output.write(""" %(failure_item)s """.strip() % locals()) output.close() return with_record else: record_results = lambda x: x # TODO: Share context? Issue: pyx processing leaks into pxd module @record_results def cythonize_one(pyx_file, c_file, fingerprint, quiet, options=None, raise_on_failure=True, embedded_metadata=None, progress=""): from ..Compiler.Main import compile, default_options from ..Compiler.Errors import CompileError, PyrexError if fingerprint: if not os.path.exists(options.cache): try: os.mkdir(options.cache) except: if not os.path.exists(options.cache): raise # Cython-generated c files are highly compressible. # (E.g. a compression ratio of about 10 for Sage). fingerprint_file = join_path( options.cache, "%s-%s%s" % (os.path.basename(c_file), fingerprint, gzip_ext)) if os.path.exists(fingerprint_file): if not quiet: print("%sFound compiled %s in cache" % (progress, pyx_file)) os.utime(fingerprint_file, None) g = gzip_open(fingerprint_file, 'rb') try: f = open(c_file, 'wb') try: shutil.copyfileobj(g, f) finally: f.close() finally: g.close() return if not quiet: print("%sCythonizing %s" % (progress, pyx_file)) if options is None: options = CompilationOptions(default_options) options.output_file = c_file options.embedded_metadata = embedded_metadata any_failures = 0 try: result = compile([pyx_file], options) if result.num_errors > 0: any_failures = 1 except (EnvironmentError, PyrexError) as e: sys.stderr.write('%s\n' % e) any_failures = 1 # XXX import traceback traceback.print_exc() except Exception: if raise_on_failure: raise import traceback traceback.print_exc() any_failures = 1 if any_failures: if raise_on_failure: raise CompileError(None, pyx_file) elif os.path.exists(c_file): os.remove(c_file) elif fingerprint: f = open(c_file, 'rb') try: g = gzip_open(fingerprint_file, 'wb') try: shutil.copyfileobj(f, g) finally: g.close() finally: f.close() def cythonize_one_helper(m): import traceback try: return cythonize_one(*m) except Exception: traceback.print_exc() raise def _init_multiprocessing_helper(): # KeyboardInterrupt kills workers, so don't let them get it import signal signal.signal(signal.SIGINT, signal.SIG_IGN) def cleanup_cache(cache, target_size, ratio=.85): try: p = subprocess.Popen(['du', '-s', '-k', os.path.abspath(cache)], stdout=subprocess.PIPE) res = p.wait() if res == 0: total_size = 1024 * int(p.stdout.read().strip().split()[0]) if total_size < target_size: return except (OSError, ValueError): pass total_size = 0 all = [] for file in os.listdir(cache): path = join_path(cache, file) s = os.stat(path) total_size += s.st_size all.append((s.st_atime, s.st_size, path)) if total_size > target_size: for time, size, file in reversed(sorted(all)): os.unlink(file) total_size -= size if total_size < target_size * ratio: break Cython-0.23.4/Cython/Build/Cythonize.py0000644000175600017570000001561612606202452021046 0ustar jenkinsjenkins00000000000000#!/usr/bin/env python from __future__ import absolute_import import os import shutil import tempfile from distutils.core import setup from .Dependencies import cythonize, extended_iglob from ..Utils import is_package_dir from ..Compiler import Options try: import multiprocessing parallel_compiles = int(multiprocessing.cpu_count() * 1.5) except ImportError: multiprocessing = None parallel_compiles = 0 class _FakePool(object): def map_async(self, func, args): from itertools import imap for _ in imap(func, args): pass def close(self): pass def terminate(self): pass def join(self): pass def parse_directives(option, name, value, parser): dest = option.dest old_directives = dict(getattr(parser.values, dest, Options.directive_defaults)) directives = Options.parse_directive_list( value, relaxed_bool=True, current_settings=old_directives) setattr(parser.values, dest, directives) def parse_options(option, name, value, parser): dest = option.dest options = dict(getattr(parser.values, dest, {})) for opt in value.split(','): if '=' in opt: n, v = opt.split('=', 1) v = v.lower() not in ('false', 'f', '0', 'no') else: n, v = opt, True options[n] = v setattr(parser.values, dest, options) def find_package_base(path): base_dir, package_path = os.path.split(path) while os.path.isfile(os.path.join(base_dir, '__init__.py')): base_dir, parent = os.path.split(base_dir) package_path = '%s/%s' % (parent, package_path) return base_dir, package_path def cython_compile(path_pattern, options): pool = None all_paths = map(os.path.abspath, extended_iglob(path_pattern)) try: for path in all_paths: if options.build_inplace: base_dir = path while not os.path.isdir(base_dir) or is_package_dir(base_dir): base_dir = os.path.dirname(base_dir) else: base_dir = None if os.path.isdir(path): # recursively compiling a package paths = [os.path.join(path, '**', '*.{py,pyx}')] else: # assume it's a file(-like thing) paths = [path] ext_modules = cythonize( paths, nthreads=options.parallel, exclude_failures=options.keep_going, exclude=options.excludes, compiler_directives=options.directives, force=options.force, quiet=options.quiet, **options.options) if ext_modules and options.build: if len(ext_modules) > 1 and options.parallel > 1: if pool is None: try: pool = multiprocessing.Pool(options.parallel) except OSError: pool = _FakePool() pool.map_async(run_distutils, [ (base_dir, [ext]) for ext in ext_modules]) else: run_distutils((base_dir, ext_modules)) except: if pool is not None: pool.terminate() raise else: if pool is not None: pool.close() pool.join() def run_distutils(args): base_dir, ext_modules = args script_args = ['build_ext', '-i'] cwd = os.getcwd() temp_dir = None try: if base_dir: os.chdir(base_dir) temp_dir = tempfile.mkdtemp(dir=base_dir) script_args.extend(['--build-temp', temp_dir]) setup( script_name='setup.py', script_args=script_args, ext_modules=ext_modules, ) finally: if base_dir: os.chdir(cwd) if temp_dir and os.path.isdir(temp_dir): shutil.rmtree(temp_dir) def parse_args(args): from optparse import OptionParser parser = OptionParser(usage='%prog [options] [sources and packages]+') parser.add_option('-X', '--directive', metavar='NAME=VALUE,...', dest='directives', type=str, action='callback', callback=parse_directives, default={}, help='set a compiler directive') parser.add_option('-s', '--option', metavar='NAME=VALUE', dest='options', type=str, action='callback', callback=parse_options, default={}, help='set a cythonize option') parser.add_option('-3', dest='python3_mode', action='store_true', help='use Python 3 syntax mode by default') parser.add_option('-a', '--annotate', dest='annotate', action='store_true', help='generate annotated HTML page for source files') parser.add_option('-x', '--exclude', metavar='PATTERN', dest='excludes', action='append', default=[], help='exclude certain file patterns from the compilation') parser.add_option('-b', '--build', dest='build', action='store_true', help='build extension modules using distutils') parser.add_option('-i', '--inplace', dest='build_inplace', action='store_true', help='build extension modules in place using distutils (implies -b)') parser.add_option('-j', '--parallel', dest='parallel', metavar='N', type=int, default=parallel_compiles, help=('run builds in N parallel jobs (default: %d)' % parallel_compiles or 1)) parser.add_option('-f', '--force', dest='force', action='store_true', help='force recompilation') parser.add_option('-q', '--quiet', dest='quiet', action='store_true', help='be less verbose during compilation') parser.add_option('--lenient', dest='lenient', action='store_true', help='increase Python compatibility by ignoring some compile time errors') parser.add_option('-k', '--keep-going', dest='keep_going', action='store_true', help='compile as much as possible, ignore compilation failures') options, args = parser.parse_args(args) if not args: parser.error("no source files provided") if options.build_inplace: options.build = True if multiprocessing is None: options.parallel = 0 if options.python3_mode: options.options['language_level'] = 3 return options, args def main(args=None): options, paths = parse_args(args) if options.lenient: # increase Python compatibility by ignoring compile time errors Options.error_on_unknown_names = False Options.error_on_uninitialized = False if options.annotate: Options.annotate = True for path in paths: cython_compile(path, options) if __name__ == '__main__': main() Cython-0.23.4/Cython/Build/BuildExecutable.py0000644000175600017570000001034212606202452022122 0ustar jenkinsjenkins00000000000000""" Compile a Python script into an executable that embeds CPython and run it. Requires CPython to be built as a shared library ('libpythonX.Y'). Basic usage: python cythonrun somefile.py [ARGS] """ from __future__ import absolute_import DEBUG = True import sys import os from distutils import sysconfig def get_config_var(name, default=''): return sysconfig.get_config_var(name) or default INCDIR = sysconfig.get_python_inc() LIBDIR1 = get_config_var('LIBDIR') LIBDIR2 = get_config_var('LIBPL') PYLIB = get_config_var('LIBRARY') PYLIB_DYN = get_config_var('LDLIBRARY') if PYLIB_DYN == PYLIB: # no shared library PYLIB_DYN = '' else: PYLIB_DYN = os.path.splitext(PYLIB_DYN[3:])[0] # 'lib(XYZ).so' -> XYZ CC = get_config_var('CC', os.environ.get('CC', '')) CFLAGS = get_config_var('CFLAGS') + ' ' + os.environ.get('CFLAGS', '') LINKCC = get_config_var('LINKCC', os.environ.get('LINKCC', CC)) LINKFORSHARED = get_config_var('LINKFORSHARED') LIBS = get_config_var('LIBS') SYSLIBS = get_config_var('SYSLIBS') EXE_EXT = sysconfig.get_config_var('EXE') def _debug(msg, *args): if DEBUG: if args: msg = msg % args sys.stderr.write(msg + '\n') def dump_config(): _debug('INCDIR: %s', INCDIR) _debug('LIBDIR1: %s', LIBDIR1) _debug('LIBDIR2: %s', LIBDIR2) _debug('PYLIB: %s', PYLIB) _debug('PYLIB_DYN: %s', PYLIB_DYN) _debug('CC: %s', CC) _debug('CFLAGS: %s', CFLAGS) _debug('LINKCC: %s', LINKCC) _debug('LINKFORSHARED: %s', LINKFORSHARED) _debug('LIBS: %s', LIBS) _debug('SYSLIBS: %s', SYSLIBS) _debug('EXE_EXT: %s', EXE_EXT) def runcmd(cmd, shell=True): if shell: cmd = ' '.join(cmd) _debug(cmd) else: _debug(' '.join(cmd)) try: import subprocess except ImportError: # Python 2.3 ... returncode = os.system(cmd) else: returncode = subprocess.call(cmd, shell=shell) if returncode: sys.exit(returncode) def clink(basename): runcmd([LINKCC, '-o', basename + EXE_EXT, basename+'.o', '-L'+LIBDIR1, '-L'+LIBDIR2] + [PYLIB_DYN and ('-l'+PYLIB_DYN) or os.path.join(LIBDIR1, PYLIB)] + LIBS.split() + SYSLIBS.split() + LINKFORSHARED.split()) def ccompile(basename): runcmd([CC, '-c', '-o', basename+'.o', basename+'.c', '-I' + INCDIR] + CFLAGS.split()) def cycompile(input_file, options=()): from ..Compiler import Version, CmdLine, Main options, sources = CmdLine.parse_command_line(list(options or ()) + ['--embed', input_file]) _debug('Using Cython %s to compile %s', Version.version, input_file) result = Main.compile(sources, options) if result.num_errors > 0: sys.exit(1) def exec_file(program_name, args=()): runcmd([os.path.abspath(program_name)] + list(args), shell=False) def build(input_file, compiler_args=(), force=False): """ Build an executable program from a Cython module. Returns the name of the executable file. """ basename = os.path.splitext(input_file)[0] exe_file = basename + EXE_EXT if not force and os.path.abspath(exe_file) == os.path.abspath(input_file): raise ValueError("Input and output file names are the same, refusing to overwrite") if (not force and os.path.exists(exe_file) and os.path.exists(input_file) and os.path.getmtime(input_file) <= os.path.getmtime(exe_file)): _debug("File is up to date, not regenerating %s", exe_file) return exe_file cycompile(input_file, compiler_args) ccompile(basename) clink(basename) return exe_file def build_and_run(args): """ Build an executable program from a Cython module and runs it. Arguments after the module name will be passed verbatimely to the program. """ cy_args = [] last_arg = None for i, arg in enumerate(args): if arg.startswith('-'): cy_args.append(arg) elif last_arg in ('-X', '--directive'): cy_args.append(arg) else: input_file = arg args = args[i+1:] break last_arg = arg else: raise ValueError('no input file provided') program_name = build(input_file, cy_args) exec_file(program_name, args) if __name__ == '__main__': build_and_run(sys.argv[1:]) Cython-0.23.4/Cython/Build/Tests/0000755000175600017570000000000012606202455017614 5ustar jenkinsjenkins00000000000000Cython-0.23.4/Cython/Build/Tests/__init__.py0000644000175600017570000000001512606202452021716 0ustar jenkinsjenkins00000000000000# empty file Cython-0.23.4/Cython/Build/Tests/TestStripLiterals.py0000644000175600017570000000302012606202452023617 0ustar jenkinsjenkins00000000000000from Cython.Build.Dependencies import strip_string_literals from Cython.TestUtils import CythonTest class TestStripLiterals(CythonTest): def t(self, before, expected): actual, literals = strip_string_literals(before, prefix="_L") self.assertEquals(expected, actual) for key, value in literals.items(): actual = actual.replace(key, value) self.assertEquals(before, actual) def test_empty(self): self.t("", "") def test_single_quote(self): self.t("'x'", "'_L1_'") def test_double_quote(self): self.t('"x"', '"_L1_"') def test_nested_quotes(self): self.t(""" '"' "'" """, """ '_L1_' "_L2_" """) def test_triple_quote(self): self.t(" '''a\n''' ", " '''_L1_''' ") def test_backslash(self): self.t(r"'a\'b'", "'_L1_'") self.t(r"'a\\'", "'_L1_'") self.t(r"'a\\\'b'", "'_L1_'") def test_unicode(self): self.t("u'abc'", "u'_L1_'") def test_raw(self): self.t(r"r'abc\\'", "r'_L1_'") def test_raw_unicode(self): self.t(r"ru'abc\\'", "ru'_L1_'") def test_comment(self): self.t("abc # foo", "abc #_L1_") def test_comment_and_quote(self): self.t("abc # 'x'", "abc #_L1_") self.t("'abc#'", "'_L1_'") def test_include(self): self.t("include 'a.pxi' # something here", "include '_L1_' #_L2_") def test_extern(self): self.t("cdef extern from 'a.h': # comment", "cdef extern from '_L1_': #_L2_") Cython-0.23.4/Cython/Build/Tests/TestIpythonMagic.py0000644000175600017570000000460612606202452023424 0ustar jenkinsjenkins00000000000000# -*- coding: utf-8 -*- # tag: ipython """Tests for the Cython magics extension.""" import os import sys try: from IPython.testing.globalipapp import get_ipython from IPython.utils import py3compat except: __test__ = False try: # disable IPython history thread to avoid having to clean it up from IPython.core.history import HistoryManager HistoryManager.enabled = False except ImportError: pass from Cython.TestUtils import CythonTest ip = get_ipython() code = py3compat.str_to_unicode("""def f(x): return 2*x """) if sys.platform == 'win32': # not using IPython's decorators here because they depend on "nose" try: from unittest import skip as skip_win32 except ImportError: # poor dev's silent @unittest.skip() def skip_win32(f): return lambda self: None else: def skip_win32(f): return f class TestIPythonMagic(CythonTest): def setUp(self): CythonTest.setUp(self) ip.extension_manager.load_extension('cython') def test_cython_inline(self): ip.ex('a=10; b=20') result = ip.run_cell_magic('cython_inline', '', 'return a+b') self.assertEqual(result, 30) @skip_win32 def test_cython_pyximport(self): module_name = '_test_cython_pyximport' ip.run_cell_magic('cython_pyximport', module_name, code) ip.ex('g = f(10)') self.assertEqual(ip.user_ns['g'], 20.0) ip.run_cell_magic('cython_pyximport', module_name, code) ip.ex('h = f(-10)') self.assertEqual(ip.user_ns['h'], -20.0) try: os.remove(module_name + '.pyx') except OSError: pass def test_cython(self): ip.run_cell_magic('cython', '', code) ip.ex('g = f(10)') self.assertEqual(ip.user_ns['g'], 20.0) def test_cython_name(self): # The Cython module named 'mymodule' defines the function f. ip.run_cell_magic('cython', '--name=mymodule', code) # This module can now be imported in the interactive namespace. ip.ex('import mymodule; g = mymodule.f(10)') self.assertEqual(ip.user_ns['g'], 20.0) @skip_win32 def test_extlibs(self): code = py3compat.str_to_unicode(""" from libc.math cimport sin x = sin(0.0) """) ip.user_ns['x'] = 1 ip.run_cell_magic('cython', '-l m', code) self.assertEqual(ip.user_ns['x'], 0) Cython-0.23.4/Cython/Build/Tests/TestInline.py0000644000175600017570000000402712606202452022244 0ustar jenkinsjenkins00000000000000import os, tempfile from Cython.Shadow import inline from Cython.Build.Inline import safe_type from Cython.TestUtils import CythonTest try: import numpy has_numpy = True except: has_numpy = False test_kwds = dict(force=True, quiet=True) global_value = 100 class TestInline(CythonTest): def setUp(self): CythonTest.setUp(self) self.test_kwds = dict(test_kwds) if os.path.isdir('BUILD'): lib_dir = os.path.join('BUILD','inline') else: lib_dir = tempfile.mkdtemp(prefix='cython_inline_') self.test_kwds['lib_dir'] = lib_dir def test_simple(self): self.assertEquals(inline("return 1+2", **self.test_kwds), 3) def test_types(self): self.assertEquals(inline(""" cimport cython return cython.typeof(a), cython.typeof(b) """, a=1.0, b=[], **self.test_kwds), ('double', 'list object')) def test_locals(self): a = 1 b = 2 self.assertEquals(inline("return a+b", **self.test_kwds), 3) def test_globals(self): self.assertEquals(inline("return global_value + 1", **self.test_kwds), global_value + 1) def test_no_return(self): self.assertEquals(inline(""" a = 1 cdef double b = 2 cdef c = [] """, **self.test_kwds), dict(a=1, b=2.0, c=[])) def test_def_node(self): foo = inline("def foo(x): return x * x", **self.test_kwds)['foo'] self.assertEquals(foo(7), 49) def test_pure(self): import cython as cy b = inline(""" b = cy.declare(float, a) c = cy.declare(cy.pointer(cy.float), &b) return b """, a=3, **self.test_kwds) self.assertEquals(type(b), float) if has_numpy: def test_numpy(self): import numpy a = numpy.ndarray((10, 20)) a[0,0] = 10 self.assertEquals(safe_type(a), 'numpy.ndarray[numpy.float64_t, ndim=2]') self.assertEquals(inline("return a[0,0]", a=a, **self.test_kwds), 10.0)