diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2020-12-24 18:04:19 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-24 18:04:19 (GMT) |
commit | 7ec59d8861ef1104c3028678b2cacde4c5693e19 (patch) | |
tree | b499f0504f79e1a218229e93ca1847fb61d80831 /Tools/c-analyzer/cpython/_files.py | |
parent | b57ada98da0d5b0cf1ebc2c9c5502d04aa962042 (diff) | |
download | cpython-7ec59d8861ef1104c3028678b2cacde4c5693e19.zip cpython-7ec59d8861ef1104c3028678b2cacde4c5693e19.tar.gz cpython-7ec59d8861ef1104c3028678b2cacde4c5693e19.tar.bz2 |
bpo-36876: [c-analyzer tool] Add a "capi" subcommand to the c-analyzer tool. (gh-23918)
This will help identify which C-API items will need to be updated for subinterpreter support.
https://bugs.python.org/issue36876
Diffstat (limited to 'Tools/c-analyzer/cpython/_files.py')
-rw-r--r-- | Tools/c-analyzer/cpython/_files.py | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/Tools/c-analyzer/cpython/_files.py b/Tools/c-analyzer/cpython/_files.py new file mode 100644 index 0000000..3e39788 --- /dev/null +++ b/Tools/c-analyzer/cpython/_files.py @@ -0,0 +1,69 @@ +import os.path + +from c_common.fsutil import expand_filenames, iter_files_by_suffix +from . import REPO_ROOT, INCLUDE_DIRS, SOURCE_DIRS + + +GLOBS = [ + 'Include/*.h', + 'Include/internal/*.h', + 'Modules/**/*.h', + 'Modules/**/*.c', + 'Objects/**/*.h', + 'Objects/**/*.c', + 'Python/**/*.h', + 'Parser/**/*.c', + 'Python/**/*.h', + 'Parser/**/*.c', +] +LEVEL_GLOBS = { + 'stable': 'Include/*.h', + 'cpython': 'Include/cpython/*.h', + 'internal': 'Include/internal/*.h', +} + + +def resolve_filename(filename): + orig = filename + filename = os.path.normcase(os.path.normpath(filename)) + if os.path.isabs(filename): + if os.path.relpath(filename, REPO_ROOT).startswith('.'): + raise Exception(f'{orig!r} is outside the repo ({REPO_ROOT})') + return filename + else: + return os.path.join(REPO_ROOT, filename) + + +def iter_filenames(*, search=False): + if search: + yield from iter_files_by_suffix(INCLUDE_DIRS, ('.h',)) + yield from iter_files_by_suffix(SOURCE_DIRS, ('.c',)) + else: + globs = (os.path.join(REPO_ROOT, file) for file in GLOBS) + yield from expand_filenames(globs) + + +def iter_header_files(filenames=None, *, levels=None): + if not filenames: + if levels: + levels = set(levels) + if 'private' in levels: + levels.add('stable') + levels.add('cpython') + for level, glob in LEVEL_GLOBS.items(): + if level in levels: + yield from expand_filenames([glob]) + else: + yield from iter_files_by_suffix(INCLUDE_DIRS, ('.h',)) + return + + for filename in filenames: + orig = filename + filename = resolve_filename(filename) + if filename.endswith(os.path.sep): + yield from iter_files_by_suffix(INCLUDE_DIRS, ('.h',)) + elif filename.endswith('.h'): + yield filename + else: + # XXX Log it and continue instead? + raise ValueError(f'expected .h file, got {orig!r}') |