Commit ccb67088 authored by mattip's avatar mattip

MAINT: localize is_property handling to CFuncDefNode.analyse_declarations

parent e936829f
......@@ -2340,13 +2340,13 @@ class CFuncDefNode(FuncDefNode):
return self.py_func.code_object if self.py_func else None
def analyse_declarations(self, env):
is_property = False
is_property = 0
if self.decorators:
for decorator in self.decorators:
func = decorator.decorator
if func.is_name:
if func.name == 'property':
is_property = True
is_property = 1
elif func.name == 'staticmethod':
pass
else:
......@@ -2429,7 +2429,11 @@ class CFuncDefNode(FuncDefNode):
name, type, self.pos,
cname=cname, visibility=self.visibility, api=self.api,
defining=self.body is not None, modifiers=self.modifiers,
overridable=self.overridable, is_property=is_property)
overridable=self.overridable)
if is_property:
self.entry.is_property = 1
env.property_entries.append(self.entry)
env.cfunc_entries.remove(self.entry)
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':
......
......@@ -755,7 +755,7 @@ class Scope(object):
def declare_cfunction(self, name, type, pos,
cname=None, visibility='private', api=0, in_pxd=0,
defining=0, modifiers=(), utility_code=None,
overridable=False, is_property=False):
overridable=False):
# Add an entry for a C function.
if not cname:
if visibility != 'private' or api:
......@@ -833,7 +833,7 @@ class Scope(object):
return entry
def add_cfunction(self, name, type, pos, cname, visibility, modifiers,
inherited=False, is_property=False):
inherited=False):
# Add a C function entry without giving it a func_cname.
entry = self.declare(name, cname, type, pos, visibility)
entry.is_cfunction = 1
......@@ -841,8 +841,6 @@ class Scope(object):
entry.func_modifiers = modifiers
if inherited or type.is_fused:
self.cfunc_entries.append(entry)
elif is_property:
self.property_entries.append(entry)
else:
# For backwards compatibility reasons, we must keep all non-fused methods
# before all fused methods, but separately for each type.
......@@ -1442,7 +1440,7 @@ class ModuleScope(Scope):
def declare_cfunction(self, name, type, pos,
cname=None, visibility='private', api=0, in_pxd=0,
defining=0, modifiers=(), utility_code=None,
overridable=False, is_property=False):
overridable=False):
if not defining and 'inline' in modifiers:
# TODO(github/1736): Make this an error.
warning(pos, "Declarations should not be declared inline.", 1)
......@@ -1466,7 +1464,7 @@ class ModuleScope(Scope):
self, name, type, pos,
cname=cname, visibility=visibility, api=api, in_pxd=in_pxd,
defining=defining, modifiers=modifiers, utility_code=utility_code,
overridable=overridable, is_property=is_property)
overridable=overridable)
return entry
def declare_global(self, name, pos):
......@@ -1940,8 +1938,8 @@ class StructOrUnionScope(Scope):
def declare_cfunction(self, name, type, pos,
cname=None, visibility='private', api=0, in_pxd=0,
defining=0, modifiers=(), overridable=False,
is_property=False): # currently no utility code ...
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,
......@@ -2223,7 +2221,7 @@ class CClassScope(ClassScope):
def declare_cfunction(self, name, type, pos,
cname=None, visibility='private', api=0, in_pxd=0,
defining=0, modifiers=(), utility_code=None,
overridable=False, is_property=False):
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
......@@ -2268,7 +2266,7 @@ class CClassScope(ClassScope):
"C method '%s' not previously declared in definition part of"
" extension type '%s'" % (name, self.class_name))
entry = self.add_cfunction(name, type, pos, cname, visibility,
modifiers, is_property=is_property)
modifiers)
if defining:
entry.func_cname = self.mangle(Naming.func_prefix, name)
entry.utility_code = utility_code
......@@ -2285,12 +2283,12 @@ class CClassScope(ClassScope):
return entry
def add_cfunction(self, name, type, pos, cname, visibility, modifiers,
inherited=False, is_property=False):
inherited=False):
# 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,
inherited=inherited, is_property=is_property)
inherited=inherited)
entry.is_cmethod = 1
entry.prev_entry = prev_entry
return entry
......@@ -2411,8 +2409,7 @@ class CppClassScope(Scope):
def declare_cfunction(self, name, type, pos,
cname=None, visibility='extern', api=0, in_pxd=0,
defining=0, modifiers=(), utility_code=None, overridable=False,
is_property=False):
defining=0, modifiers=(), utility_code=None, overridable=False):
class_name = self.name.split('::')[-1]
if name in (class_name, '__init__') and cname is None:
cname = "%s__init__%s" % (Naming.func_prefix, class_name)
......
......@@ -428,6 +428,7 @@ VER_DEP_MODULES = {
(3,3) : (operator.lt, lambda x: x in ['build.package_compilation',
'run.yield_from_py33',
'pyximport.pyximport_namespace',
'run.qualname',
]),
(3,4): (operator.lt, lambda x: x in ['run.py34_signature',
'run.test_unicode', # taken from Py3.7, difficult to backport
......@@ -640,6 +641,7 @@ class TestBuilder(object):
self.default_mode = default_mode
self.stats = stats
self.add_embedded_test = add_embedded_test
self.capture = options.capture
def build_suite(self):
suite = unittest.TestSuite()
......@@ -697,7 +699,9 @@ class TestBuilder(object):
if ext == '.srctree':
if 'cpp' not in tags['tag'] or 'cpp' in self.languages:
suite.addTest(EndToEndTest(filepath, workdir, self.cleanup_workdir, stats=self.stats))
suite.addTest(EndToEndTest(filepath, workdir,
self.cleanup_workdir, stats=self.stats,
capture=self.capture))
continue
# Choose the test suite.
......@@ -1570,6 +1574,8 @@ class TestCodeFormat(unittest.TestCase):
def runTest(self):
import pycodestyle
config_file = os.path.join(self.cython_dir, "tox.ini")
if not os.path.exists(config_file):
config_file=os.path.join(os.path.dirname(__file__), "tox.ini")
paths = glob.glob(os.path.join(self.cython_dir, "**/*.py"), recursive=True)
style = pycodestyle.StyleGuide(config_file=config_file)
print("") # Fix the first line of the report.
......@@ -1670,12 +1676,14 @@ class EndToEndTest(unittest.TestCase):
"""
cython_root = os.path.dirname(os.path.abspath(__file__))
def __init__(self, treefile, workdir, cleanup_workdir=True, stats=None):
def __init__(self, treefile, workdir, cleanup_workdir=True, stats=None,
capture=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
self.stats = stats
self.capture = capture
cython_syspath = [self.cython_root]
for path in sys.path:
if path.startswith(self.cython_root) and path not in cython_syspath:
......@@ -1731,16 +1739,23 @@ class EndToEndTest(unittest.TestCase):
for command_no, command in enumerate(filter(None, commands.splitlines()), 1):
with self.stats.time('%s(%d)' % (self.name, command_no), 'c',
'etoe-build' if ' setup.py ' in command else 'etoe-run'):
p = subprocess.Popen(command,
if self.capture:
p = subprocess.Popen(command,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
shell=True,
env=env)
_out, _err = p.communicate()
_out, _err = p.communicate()
res = p.returncode
else:
p = subprocess.call(command,
shell=True,
env=env)
_out, _err = b'', b''
res = p
cmd.append(command)
out.append(_out)
err.append(_err)
res = p.returncode
if res != 0:
for c, o, e in zip(cmd, out, err):
sys.stderr.write("%s\n%s\n%s\n\n" % (
......@@ -2092,6 +2107,8 @@ def main():
help="test whether Cython's output is deterministic")
parser.add_option("--pythran-dir", dest="pythran_dir", default=None,
help="specify Pythran include directory. This will run the C++ tests using Pythran backend for Numpy")
parser.add_option("--no-capture", dest="capture", default=True, action="store_false",
help="do not capture stdout, stderr in srctree tests. Makes pdb.set_trace interactive")
options, cmd_args = parser.parse_args(args)
......@@ -2118,6 +2135,10 @@ def main():
if options.xml_output_dir:
shutil.rmtree(options.xml_output_dir, ignore_errors=True)
if options.capture:
keep_alive_interval = 10
else:
keep_alive_interval = None
if options.shard_count > 1 and options.shard_num == -1:
import multiprocessing
pool = multiprocessing.Pool(options.shard_count)
......@@ -2126,7 +2147,7 @@ def main():
# NOTE: create process pool before time stamper thread to avoid forking issues.
total_time = time.time()
stats = Stats()
with time_stamper_thread():
with time_stamper_thread(interval=keep_alive_interval):
for shard_num, shard_stats, return_code in pool.imap_unordered(runtests_callback, tasks):
if return_code != 0:
errors.append(shard_num)
......@@ -2143,7 +2164,7 @@ def main():
else:
return_code = 0
else:
with time_stamper_thread():
with time_stamper_thread(interval=keep_alive_interval):
_, stats, return_code = runtests(options, cmd_args, coverage)
if coverage:
......@@ -2182,27 +2203,31 @@ def time_stamper_thread(interval=10):
from datetime import datetime
from time import sleep
interval = _xrange(interval * 4)
now = datetime.now
write = sys.__stderr__.write
stop = False
def time_stamper():
while True:
for _ in interval:
if stop:
return
sleep(1./4)
write('\n#### %s\n' % now())
thread = threading.Thread(target=time_stamper, name='time_stamper')
thread.setDaemon(True) # Py2 ...
thread.start()
try:
if not interval or interval < 0:
# Do nothing
yield
finally:
stop = True
thread.join()
else:
interval = _xrange(interval * 4)
now = datetime.now
write = sys.__stderr__.write
stop = False
def time_stamper():
while True:
for _ in interval:
if stop:
return
sleep(1./4)
write('\n#### %s\n' % now())
thread = threading.Thread(target=time_stamper, name='time_stamper')
thread.setDaemon(True) # Py2 ...
thread.start()
try:
yield
finally:
stop = True
thread.join()
def configure_cython(options):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment