diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2025-01-10 15:10:09 +0100 |
|---|---|---|
| committer | Eli Schwartz <eschwartz93@gmail.com> | 2025-03-09 13:05:08 -0400 |
| commit | 528696300afd3236e173242e1e09d1ac80dfec81 (patch) | |
| tree | f3989f6d6c49e188201719dd13468e10128a755d /mesonbuild/utils | |
| parent | 9c125a26dbf1b6ecc674df2bd1abc02ca48da2cd (diff) | |
| download | meson-528696300afd3236e173242e1e09d1ac80dfec81.tar.gz | |
mesonlib: extract and optimize is_parent_path
Introduce an alternative to os.path.commonpath(name, path) == path,
which is a common idiom throughout Meson. Call it is_parent_path
just like the existing static method in Generator.
It is a bit faster and handles drives on Windows without the need
for an exception handler.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'mesonbuild/utils')
| -rw-r--r-- | mesonbuild/utils/universal.py | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/mesonbuild/utils/universal.py b/mesonbuild/utils/universal.py index 45c0b7c13..3481aaa88 100644 --- a/mesonbuild/utils/universal.py +++ b/mesonbuild/utils/universal.py @@ -124,6 +124,7 @@ __all__ = [ 'is_netbsd', 'is_openbsd', 'is_osx', + 'is_parent_path', 'is_qnx', 'is_sunos', 'is_windows', @@ -1113,6 +1114,26 @@ def determine_worker_count(varnames: T.Optional[T.List[str]] = None) -> int: num_workers = 1 return num_workers +def is_parent_path(parent: str, trial: str) -> bool: + '''Checks if @trial is a file under the directory @parent. Both @trial and @parent should be + adequately normalized, though empty and '.' segments in @parent and @trial are accepted + and discarded, matching the behavior of os.path.commonpath. Either both or none should + be absolute.''' + assert os.path.isabs(parent) == os.path.isabs(trial) + if is_windows(): + parent = parent.replace('\\', '/') + trial = trial.replace('\\', '/') + + split_parent = parent.split('/') + split_trial = trial.split('/') + + split_parent = [c for c in split_parent if c and c != '.'] + split_trial = [c for c in split_trial if c and c != '.'] + + components = len(split_parent) + return len(split_trial) >= components and split_trial[:components] == split_parent + + def has_path_sep(name: str, sep: str = '/\\') -> bool: 'Checks if any of the specified @sep path separators are in @name' for each in sep: |
