misc/coding_tools/check-interfaces.py: clean-ups (warnings about Windows-specific modules and error stream handling).
This commit is contained in:
parent
854afc095f
commit
28069a9641
|
@ -4,7 +4,7 @@
|
||||||
#
|
#
|
||||||
# bin/tahoe @misc/coding_tools/check-interfaces.py
|
# bin/tahoe @misc/coding_tools/check-interfaces.py
|
||||||
|
|
||||||
import os, sys, re
|
import os, sys, re, platform
|
||||||
|
|
||||||
import zope.interface as zi
|
import zope.interface as zi
|
||||||
# We use the forked version of verifyClass below.
|
# We use the forked version of verifyClass below.
|
||||||
|
@ -17,7 +17,10 @@ excluded_classnames = re.compile(r'(_)|(Mock)|(Fake)|(Dummy).*')
|
||||||
excluded_file_basenames = re.compile(r'(check)|(bench)_.*')
|
excluded_file_basenames = re.compile(r'(check)|(bench)_.*')
|
||||||
|
|
||||||
|
|
||||||
other_modules_with_violations = set()
|
_other_modules_with_violations = set()
|
||||||
|
_err = sys.stderr
|
||||||
|
_report_argname_mismatch = False # very noisy and usually not important
|
||||||
|
|
||||||
|
|
||||||
# deep magic
|
# deep magic
|
||||||
def strictly_implements(*interfaces):
|
def strictly_implements(*interfaces):
|
||||||
|
@ -42,31 +45,41 @@ def strictly_implements(*interfaces):
|
||||||
try:
|
try:
|
||||||
verifyClass(interface, cls)
|
verifyClass(interface, cls)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print >>sys.stderr, ("%s.%s does not correctly implement %s.%s:\n%s"
|
print >>_err, ("%s.%s does not correctly implement %s.%s:\n%s"
|
||||||
% (cls.__module__, cls.__name__,
|
% (cls.__module__, cls.__name__,
|
||||||
interface.__module__, interface.__name__, e))
|
interface.__module__, interface.__name__, e))
|
||||||
else:
|
else:
|
||||||
other_modules_with_violations.add(cls.__module__)
|
_other_modules_with_violations.add(cls.__module__)
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
f_locals['__implements_advice_data__'] = interfaces, zi.classImplements
|
f_locals['__implements_advice_data__'] = interfaces, zi.classImplements
|
||||||
addClassAdvisor(_implements_advice, depth=2)
|
addClassAdvisor(_implements_advice, depth=2)
|
||||||
|
|
||||||
|
|
||||||
def check(err):
|
def check():
|
||||||
# patchee-monkey
|
# patchee-monkey
|
||||||
zi.implements = strictly_implements
|
zi.implements = strictly_implements
|
||||||
|
|
||||||
|
if len(sys.argv) >= 2:
|
||||||
|
if sys.argv[1] == '--help' or len(sys.argv) > 2:
|
||||||
|
print >>_err, "Usage: check-miscaptures.py [SOURCEDIR]"
|
||||||
|
return
|
||||||
|
srcdir = sys.argv[1]
|
||||||
|
else:
|
||||||
|
# import modules under src/ by default
|
||||||
|
srcdir = 'src'
|
||||||
|
|
||||||
# attempt to avoid side-effects from importing command scripts
|
# attempt to avoid side-effects from importing command scripts
|
||||||
sys.argv = ['', '--help']
|
sys.argv = ['', '--help']
|
||||||
|
|
||||||
# import modules under src/
|
syslow = platform.system().lower()
|
||||||
srcdir = 'src'
|
is_windows = 'cygwin' in syslow or 'windows' in syslow
|
||||||
|
|
||||||
for (dirpath, dirnames, filenames) in os.walk(srcdir):
|
for (dirpath, dirnames, filenames) in os.walk(srcdir):
|
||||||
for fn in filenames:
|
for fn in filenames:
|
||||||
(basename, ext) = os.path.splitext(fn)
|
(basename, ext) = os.path.splitext(fn)
|
||||||
if ext in ('.pyc', '.pyo') and not os.path.exists(os.path.join(dirpath, basename+'.py')):
|
if ext in ('.pyc', '.pyo') and not os.path.exists(os.path.join(dirpath, basename+'.py')):
|
||||||
print >>err, ("Warning: no .py source file for %r.\n"
|
print >>_err, ("Warning: no .py source file for %r.\n"
|
||||||
% (os.path.join(dirpath, fn),))
|
% (os.path.join(dirpath, fn),))
|
||||||
|
|
||||||
if ext == '.py' and not excluded_file_basenames.match(basename):
|
if ext == '.py' and not excluded_file_basenames.match(basename):
|
||||||
|
@ -74,14 +87,18 @@ def check(err):
|
||||||
module = relpath.replace(os.sep, '/').replace('/', '.')
|
module = relpath.replace(os.sep, '/').replace('/', '.')
|
||||||
try:
|
try:
|
||||||
__import__(module)
|
__import__(module)
|
||||||
except ImportError:
|
except ImportError, e:
|
||||||
|
if not is_windows and (' _win' in str(e) or 'win32' in str(e)):
|
||||||
|
print >>_err, ("Warning: %r imports a Windows-specific module, so we cannot check it (%s).\n"
|
||||||
|
% (module, str(e)))
|
||||||
|
else:
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc(2, err)
|
traceback.print_exc(file=_err)
|
||||||
print >>err
|
print >>_err
|
||||||
|
|
||||||
others = list(other_modules_with_violations)
|
others = list(_other_modules_with_violations)
|
||||||
others.sort()
|
others.sort()
|
||||||
print >>err, "There were also interface violations in:\n", ", ".join(others), "\n"
|
print >>_err, "There were also interface violations in:\n", ", ".join(others), "\n"
|
||||||
|
|
||||||
|
|
||||||
# Forked from
|
# Forked from
|
||||||
|
@ -196,10 +213,6 @@ def verifyObject(iface, candidate, tentative=0):
|
||||||
return _verify(iface, candidate, tentative, vtype='o')
|
return _verify(iface, candidate, tentative, vtype='o')
|
||||||
|
|
||||||
def _incompat(required, implemented):
|
def _incompat(required, implemented):
|
||||||
#if (required['positional'] !=
|
|
||||||
# implemented['positional'][:len(required['positional'])]
|
|
||||||
# and implemented['kwargs'] is None):
|
|
||||||
# return 'imlementation has different argument names'
|
|
||||||
if len(implemented['required']) > len(required['required']):
|
if len(implemented['required']) > len(required['required']):
|
||||||
return 'implementation requires too many arguments'
|
return 'implementation requires too many arguments'
|
||||||
if ((len(implemented['positional']) < len(required['positional']))
|
if ((len(implemented['positional']) < len(required['positional']))
|
||||||
|
@ -209,9 +222,13 @@ def _incompat(required, implemented):
|
||||||
return "implementation doesn't support keyword arguments"
|
return "implementation doesn't support keyword arguments"
|
||||||
if required['varargs'] and not implemented['varargs']:
|
if required['varargs'] and not implemented['varargs']:
|
||||||
return "implementation doesn't support variable arguments"
|
return "implementation doesn't support variable arguments"
|
||||||
|
if (_report_argname_mismatch and required['positional'] !=
|
||||||
|
implemented['positional'][:len(required['positional'])]
|
||||||
|
and implemented['kwargs'] is None):
|
||||||
|
return 'implementation has different argument names'
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
check(sys.stderr)
|
check()
|
||||||
# Avoid spurious warnings about ignored exceptions during shutdown by doing a hard exit.
|
# Avoid spurious warnings about ignored exceptions during shutdown by doing a hard exit.
|
||||||
os._exit(0)
|
os._exit(0)
|
||||||
|
|
Loading…
Reference in New Issue