Created
April 28, 2016 12:54
-
-
Save andreasvc/75be5b98c28af175674d36f5ef763615 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Tool to check if function/class definitions in Python files match with | |
their __all__ attribute. Rudimentary support for Cython. | |
""" | |
import sys | |
import re | |
from collections import Counter | |
for filename in sys.argv[1:]: | |
with open(filename, 'rt') as inp: | |
code = inp.read() | |
match = re.search(r'^__all__ = (\[.*\])', code, | |
flags=re.MULTILINE | re.DOTALL) | |
if match is None: | |
print('%s: no __all__' % filename) | |
continue | |
declared = eval(match.group(1)) | |
found = re.findall(r'^(?:def|class|cpdef|cdef class)' | |
r'(?: inline| extern)?' | |
r'(?: int| bint| void| long| double| bytes| str)?' | |
r' ([a-zA-Z]\w*)', | |
code, flags=re.MULTILINE) | |
foundset = set(found) | |
declaredset = set(declared) | |
diff1 = foundset - declaredset | |
diff2 = declaredset - foundset | |
flag = False | |
if diff1: | |
print('%s missing: %r' % (filename, diff1)) | |
flag = True | |
if diff2: | |
print('%s not a defined function/class: %r' % (filename, diff2)) | |
flag = True | |
if len(found) != len(foundset): | |
print('%s: multiply defined function/class: %s' % ( | |
filename, [a for a, b in Counter(found).items() if b > 1])) | |
flag = True | |
if len(declared) != len(declaredset): | |
print('%s: repetition in __all__: %s' % ( | |
filename, [a for a, b in Counter(declared).items() if b > 1])) | |
flag = True | |
if not flag: | |
print('%s: OK' % filename) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment