import gc
import codecs
import shutil
+import time
import unittest
import doctest
import operator
except ImportError: # No threads, no problems
threading = None
-
WITH_CYTHON = True
+CY3_DIR = None
from distutils.dist import Distribution
from distutils.core import Extension
from distutils.command.build_ext import build_ext as _build_ext
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)
+
TEST_DIRS = ['compile', 'errors', 'run', 'wrappers', 'pyregr', 'build']
TEST_RUN_DIRS = ['run', 'wrappers', 'pyregr']
'run.special_methods_T561_py2']),
}
+# files that should not be converted to Python 3 code with 2to3
+KEEP_2X_FILES = [
+ os.path.join('Cython', 'Debugger', 'Tests', 'test_libcython_in_gdb.py'),
+ os.path.join('Cython', 'Debugger', 'Tests', 'test_libpython_in_gdb.py'),
+ os.path.join('Cython', 'Debugger', 'libcython.py'),
+ os.path.join('Cython', 'Debugger', 'libpython.py'),
+]
+
+COMPILER = None
INCLUDE_DIRS = [ d for d in os.getenv('INCLUDE', '').split(os.pathsep) if d ]
CFLAGS = os.getenv('CFLAGS', '').split()
def build_extension(self, ext):
if ext.language == 'c++':
try:
- try: # Py2.7+ & Py3.2+
+ try: # Py2.7+ & Py3.2+
compiler_obj = self.compiler_obj
except AttributeError:
compiler_obj = self.compiler
continue
suite.addTest(
self.handle_directory(path, filename))
- if sys.platform not in ['win32'] and sys.version_info[0] < 3:
- # Non-Windows makefile, can't run Cython under Py3.
- if [1 for selector in self.selectors if selector("embedded")]:
+ 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
filenames = os.listdir(path)
filenames.sort()
for filename in filenames:
- if context == "build" and filename.endswith(".srctree"):
+ if filename.endswith(".srctree"):
if not [ 1 for match in self.selectors if match(filename) ]:
continue
- suite.addTest(EndToEndTest(filename, workdir, self.cleanup_workdir))
+ if self.exclude_selectors:
+ if [1 for match in self.exclude_selectors if match(filename)]:
+ continue
+ suite.addTest(EndToEndTest(os.path.join(path, filename), workdir, self.cleanup_workdir))
continue
if not (filename.endswith(".pyx") or filename.endswith(".py")):
continue
source = self.find_module_source_file(
os.path.join(test_directory, module + '.pyx'))
target = os.path.join(targetdir, self.build_target_filename(module))
-
+
if extra_compile_options is None:
extra_compile_options = {}
-
+
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
-
+
options = CompilationOptions(
default_options,
include_path = include_dirs,
cython_compile(source, options=options,
full_module_name=module)
- def run_distutils(self, test_directory, module, workdir, incdir,
+ def run_distutils(self, test_directory, module, workdir, incdir,
extra_extension_args=None):
cwd = os.getcwd()
os.chdir(workdir)
if incdir:
build_extension.include_dirs.append(incdir)
build_extension.finalize_options()
+ if COMPILER:
+ build_extension.compiler = COMPILER
ext_include_dirs = []
for match, get_additional_include_dirs in EXT_DEP_INCLUDES:
if match(module):
ext_include_dirs += get_additional_include_dirs()
- self.copy_related_files(test_directory, workdir, module)
-
+ ext_compile_flags = CFLAGS[:]
+ if build_extension.compiler == 'mingw32':
+ ext_compile_flags.append('-Wno-format')
if extra_extension_args is None:
extra_extension_args = {}
-
+
+ self.copy_related_files(test_directory, workdir, module)
extension = Extension(
module,
sources = self.find_source_files(workdir, module),
include_dirs = ext_include_dirs,
- extra_compile_args = CFLAGS,
+ extra_compile_args = ext_compile_flags,
**extra_extension_args
)
if self.language == 'cpp':
except (unittest.SkipTest, support.ResourceDenied):
result.addSkip(self, 'ok')
-# Someone wrapped this in a:
-# 'try: import gdb; ... except: include_debugger = False' thing, but don't do
-# this, it doesn't work as gdb is a builtin module in GDB. The tests themselves
-# are doing the skipping. If there's a problem with the tests, please file an
-# issue.
include_debugger = sys.version_info[:2] > (2, 5)
def collect_unittests(path, module_prefix, suite, selectors):
return dirname == "Tests"
loader = unittest.TestLoader()
-
+
if include_debugger:
skipped_dirs = []
else:
- cython_dir = os.path.dirname(os.path.abspath(__file__))
- skipped_dirs = [os.path.join(cython_dir, 'Cython', 'Debugger')]
+ 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:
return dirname not in ("Mac", "Distutils", "Plex")
def file_matches(filename):
filename, ext = os.path.splitext(filename)
- blacklist = ['libcython', 'libpython', 'test_libcython_in_gdb',
+ blacklist = ['libcython', 'libpython', 'test_libcython_in_gdb',
'TestLibCython']
return (ext == '.py' and not
'~' in filename and not
modulename = module_prefix + filepath[len(path)+1:].replace(os.path.sep, '.')
if not [ 1 for match in 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)
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, os.path.splitext(treefile)[0])
+ self.workdir = os.path.join(workdir, self.name)
self.cleanup_workdir = cleanup_workdir
cython_syspath = self.cython_root
for path in sys.path[::-1]:
unittest.TestCase.__init__(self)
def shortDescription(self):
- return "End-to-end %s" % self.treefile
+ return "End-to-end %s" % self.name
def setUp(self):
from Cython.TestUtils import unpack_source_tree
- _, self.commands = unpack_source_tree(
- os.path.join('tests', 'build', self.treefile), self.workdir)
+ _, 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:
def tearDown(self):
if self.cleanup_workdir:
- shutil.rmtree(self.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 runTest(self):
commands = (self.commands
.replace("CYTHON", "PYTHON %s" % os.path.join(self.cython_root, 'cython.py'))
# 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(
except:
pass
os.chdir(self.old_dir)
-
+
def test_embed(self):
from distutils import sysconfig
libname = sysconfig.get_config_var('LIBRARY')
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:
+ cython = os.path.join(CY3_DIR, cython)
+ cython = os.path.abspath(os.path.join('..', '..', cython))
self.assert_(os.system(
- "make PYTHON='%s' LIBDIR1='%s' test > make.output" % (sys.executable, libdir)) == 0)
+ "make PYTHON='%s' CYTHON='%s' LIBDIR1='%s' test > make.output" % (sys.executable, cython, libdir)) == 0)
try:
os.remove('make.output')
except OSError:
self.excludes[line.split()[0]] = True
finally:
f.close()
-
+
def __call__(self, testname):
return testname in self.excludes or testname.split('.')[-1] in self.excludes
graft Cython
recursive-exclude Cython *
recursive-include Cython *.py *.pyx *.pxd
+ recursive-include Cython/Debugger/Tests *
+ include runtests.py
+ include cython.py
''')
sys.path.insert(0, cy3_dir)
+ for keep_2x_file in KEEP_2X_FILES:
+ destfile = os.path.join(cy3_dir, keep_2x_file)
+ shutil.copy(keep_2x_file, destfile)
+
class PendingThreadsError(RuntimeError):
pass
raise PendingThreadsError("left-over threads found after running test")
def main():
+
+ 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",
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")
parser.add_option("--no-c", dest="use_c",
action="store_false", default=True,
help="do not test C compilation")
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/")
+ 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("--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")
options, cmd_args = parser.parse_args()
- DISTDIR = os.path.join(os.getcwd(), os.path.dirname(sys.argv[0]))
- ROOTDIR = os.path.join(DISTDIR, 'tests')
- WORKDIR = os.path.join(os.getcwd(), 'BUILD')
+ ROOTDIR = os.path.abspath(options.root_dir)
+ WORKDIR = os.path.abspath(options.work_dir)
if sys.version_info[0] >= 3:
options.doctests = False
for name in cy_modules:
del sys.modules[name]
# hasn't been refactored yet - do it now
- cy3_dir = os.path.join(WORKDIR, 'Cy3')
+ global CY3_DIR
+ CY3_DIR = cy3_dir = os.path.join(WORKDIR, 'Cy3')
if sys.version_info >= (3,1):
refactor_for_py3(DISTDIR, cy3_dir)
elif os.path.isdir(cy3_dir):
# RUN ALL TESTS!
UNITTEST_MODULE = "Cython"
- UNITTEST_ROOT = os.path.join(os.getcwd(), UNITTEST_MODULE)
+ 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):
# Chech 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)
+ missing_dep_excluder = MissingDependencyExcluder(EXT_DEP_MODULES)
+ version_dep_excluder = VersionDependencyExcluder(VER_DEP_MODULES)
exclude_selectors = [missing_dep_excluder, version_dep_excluder] # want to pring msg at exit
if options.exclude:
exclude_selectors += [ re.compile(r, re.I|re.U).search for r in options.exclude ]
-
+
if not test_bugs:
- exclude_selectors += [ FileListExcluder("tests/bugs.txt") ]
-
+ exclude_selectors += [ FileListExcluder(os.path.join(ROOTDIR, "bugs.txt")) ]
+
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
languages = []
if options.use_c:
languages.append('c')
ignored_modules = ('Options', 'Version', 'DebugFlags', 'CmdLine')
modules = [ module for name, module in sys.modules.items()
if module is not None and
- name.startswith('Cython.Compiler.') and
+ name.startswith('Cython.Compiler.') and
name[len('Cython.Compiler.'):] not in ignored_modules ]
if options.coverage:
coverage.report(modules, show_missing=0)