Parse path arguments optionally containing selection parts and return (fspath, names). Command-line arguments can point to files and/or directories, and optionally contain parts for specific tests selection, for example: "pkg/tests/test_foo.py::TestClass::test_foo" This functi
(
invocation_path: Path, arg: str, *, as_pypath: bool = False
)
| 847 | |
| 848 | |
| 849 | def resolve_collection_argument( |
| 850 | invocation_path: Path, arg: str, *, as_pypath: bool = False |
| 851 | ) -> Tuple[Path, List[str]]: |
| 852 | """Parse path arguments optionally containing selection parts and return (fspath, names). |
| 853 | |
| 854 | Command-line arguments can point to files and/or directories, and optionally contain |
| 855 | parts for specific tests selection, for example: |
| 856 | |
| 857 | "pkg/tests/test_foo.py::TestClass::test_foo" |
| 858 | |
| 859 | This function ensures the path exists, and returns a tuple: |
| 860 | |
| 861 | (Path("/full/path/to/pkg/tests/test_foo.py"), ["TestClass", "test_foo"]) |
| 862 | |
| 863 | When as_pypath is True, expects that the command-line argument actually contains |
| 864 | module paths instead of file-system paths: |
| 865 | |
| 866 | "pkg.tests.test_foo::TestClass::test_foo" |
| 867 | |
| 868 | In which case we search sys.path for a matching module, and then return the *path* to the |
| 869 | found module. |
| 870 | |
| 871 | If the path doesn't exist, raise UsageError. |
| 872 | If the path is a directory and selection parts are present, raise UsageError. |
| 873 | """ |
| 874 | strpath, *parts = str(arg).split("::") |
| 875 | if as_pypath: |
| 876 | strpath = search_pypath(strpath) |
| 877 | fspath = invocation_path / strpath |
| 878 | fspath = absolutepath(fspath) |
| 879 | if not fspath.exists(): |
| 880 | msg = ( |
| 881 | "module or package not found: {arg} (missing __init__.py?)" |
| 882 | if as_pypath |
| 883 | else "file or directory not found: {arg}" |
| 884 | ) |
| 885 | raise UsageError(msg.format(arg=arg)) |
| 886 | if parts and fspath.is_dir(): |
| 887 | msg = ( |
| 888 | "package argument cannot contain :: selection parts: {arg}" |
| 889 | if as_pypath |
| 890 | else "directory argument cannot contain :: selection parts: {arg}" |
| 891 | ) |
| 892 | raise UsageError(msg.format(arg=arg)) |
| 893 | return fspath, parts |