Return the parent directory of `path` after trimming a `match` from the end. The match is expected to contain `/` as a path separator, while the `path` is expected to use the platform's path separator (e.g., `os.sep`). The path components are compared case-insensitively and a `*` wi
(path: str | None, match: str)
| 59 | |
| 60 | |
| 61 | def _matching_parents(path: str | None, match: str) -> str | None: |
| 62 | """ |
| 63 | Return the parent directory of `path` after trimming a `match` from the end. |
| 64 | The match is expected to contain `/` as a path separator, while the `path` |
| 65 | is expected to use the platform's path separator (e.g., `os.sep`). The path |
| 66 | components are compared case-insensitively and a `*` wildcard can be used |
| 67 | in the `match`. |
| 68 | """ |
| 69 | from fnmatch import fnmatch |
| 70 | |
| 71 | if not path: |
| 72 | return None |
| 73 | parts = path.split(os.sep) |
| 74 | match_parts = match.split("/") |
| 75 | if len(parts) < len(match_parts): |
| 76 | return None |
| 77 | |
| 78 | if not all( |
| 79 | fnmatch(part, match_part) |
| 80 | for part, match_part in zip(reversed(parts), reversed(match_parts)) |
| 81 | ): |
| 82 | return None |
| 83 | |
| 84 | return os.sep.join(parts[: -len(match_parts)]) |
| 85 | |
| 86 | |
| 87 | def _join(path: str | None, *parts: str) -> str | None: |
no outgoing calls
no test coverage detected
searching dependent graphs…