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