from distutils.dist import Distribution
from distutils.core import Extension
-from distutils.command.build_ext import build_ext
+from distutils.command.build_ext import build_ext as _build_ext
distutils_distro = Distribution()
TEST_DIRS = ['compile', 'errors', 'run', 'pyregr']
-TEST_RUN_DIRS = ['run', 'pyregr']
+TEST_RUN_DIRS = ['run', 'pyregr', 'bugs']
# Lists external modules, and a matcher matching tests
# which should be excluded if the module is not present.
'numpy' : re.compile('.*\.numpy_.*').match
}
+VER_DEP_MODULES = {
+# such as:
+# (2,4) : lambda x: x in ['run.set']
+}
+
INCLUDE_DIRS = [ d for d in os.getenv('INCLUDE', '').split(os.pathsep) if d ]
CFLAGS = os.getenv('CFLAGS', '').split()
+class build_ext(_build_ext):
+ def build_extension(self, ext):
+ if ext.language == 'c++':
+ try:
+ self.compiler.compiler_so.remove('-Wstrict-prototypes')
+ 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
class TestBuilder(object):
def __init__(self, rootdir, workdir, selectors, exclude_selectors, annotate,
cleanup_workdir, cleanup_sharedlibs, with_pyregr, cython_only,
- languages):
+ languages, test_bugs):
self.rootdir = rootdir
self.workdir = workdir
self.selectors = selectors
self.with_pyregr = with_pyregr
self.cython_only = cython_only
self.languages = languages
+ self.test_bugs = test_bugs
def build_suite(self):
suite = unittest.TestSuite()
+ test_dirs = TEST_DIRS
+ if self.test_bugs and 'bugs' not in test_dirs:
+ test_dirs.append('bugs')
filenames = os.listdir(self.rootdir)
filenames.sort()
for filename in filenames:
# we won't get any errors without running Cython
continue
path = os.path.join(self.rootdir, filename)
- if os.path.isdir(path) and filename in TEST_DIRS:
+ if os.path.isdir(path) and filename in test_dirs:
if filename == 'pyregr' and not self.with_pyregr:
continue
suite.addTest(
if incdir:
build_extension.include_dirs.append(incdir)
build_extension.finalize_options()
-
extension = Extension(
module,
sources = [self.build_target_filename(module)],
extra_compile_args = CFLAGS,
)
+ if self.language == 'cpp':
+ extension.language = 'c++'
build_extension.extensions = [extension]
build_extension.build_temp = workdir
build_extension.build_lib = workdir
self.setUp()
self.runCompileTest()
if not self.cython_only:
- sys.stderr.write('running doctests in %s ...\n' % self.module)
doctest.DocTestSuite(self.module).run(result)
except Exception:
result.addError(self, sys.exc_info())
try:
self.setUp()
self.runCompileTest()
- sys.stderr.write('running tests in %s ...\n' % self.module)
unittest.defaultTestLoader.loadTestsFromName(self.module).run(result)
except Exception:
result.addError(self, sys.exc_info())
return True
return False
+class VersionDependencyExcluder:
+ def __init__(self, deps):
+ # deps: { version : matcher func }
+ from sys import version_info
+ self.exclude_matchers = []
+ for ver, matcher in deps.items():
+ if version_info < ver:
+ self.exclude_matchers.append(matcher)
+ self.tests_missing_deps = []
+ def __call__(self, testname):
+ for matcher in self.exclude_matchers:
+ if matcher(testname):
+ self.tests_missing_deps.append(testname)
+ return True
+ return False
+
if __name__ == '__main__':
from optparse import OptionParser
parser = OptionParser()
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("--sys-pyregr", dest="system_pyregr",
action="store_true", default=False,
help="run the regression tests of the CPython installation")
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/bugs'")
options, cmd_args = parser.parse_args()
UNITTEST_ROOT = os.path.join(os.getcwd(), UNITTEST_MODULE)
if WITH_CYTHON:
if os.path.exists(WORKDIR):
- shutil.rmtree(WORKDIR, ignore_errors=True)
+ for path in os.listdir(WORKDIR):
+ if path in ("support",): continue
+ shutil.rmtree(os.path.join(WORKDIR, path), ignore_errors=True)
if not os.path.exists(WORKDIR):
os.makedirs(WORKDIR)
sys.stderr.write("Python %s\n" % sys.version)
sys.stderr.write("\n")
+ 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")
+
+ test_bugs = False
+ if options.tickets:
+ for ticket_number in options.tickets:
+ test_bugs = True
+ cmd_args.append('bugs.*T%s$' % ticket_number)
+ if not test_bugs:
+ for selector in cmd_args:
+ if selector.startswith('bugs'):
+ test_bugs = True
+
import re
selectors = [ re.compile(r, re.I|re.U).search for r in cmd_args ]
if not selectors:
# which depends on them (by prefix)
missing_dep_excluder = MissingDependencyExcluder(EXT_DEP_MODULES)
- exclude_selectors = [missing_dep_excluder] # want to pring msg at exit
+ 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 ]
filetests = TestBuilder(ROOTDIR, WORKDIR, selectors, exclude_selectors,
options.annotate_source, options.cleanup_workdir,
options.cleanup_sharedlibs, options.pyregr,
- options.cython_only, languages)
+ options.cython_only, languages, test_bugs)
test_suite.addTest(filetests.build_suite())
if options.system_pyregr and languages:
if options.coverage:
coverage.stop()
- ignored_modules = ('Options', 'Version', 'DebugFlags')
+ 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
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]))