11import os
22import sys
33from pathlib import Path
4- from typing import Iterable , Union
4+ from typing import Iterable , Optional , Union
55
66from dotenv import load_dotenv
77
88
9- def _pyrootutils_recursive_search (path : Path , indicators : Iterable [str ]) -> Path :
9+ def _pyrootutils_recursive_search (path : Path , indicators : Iterable [str ]) -> Optional [ Path ] :
1010 """Recursively search for files from the `indicators` list, starting from given path.
1111
1212 Args:
@@ -17,22 +17,28 @@ def _pyrootutils_recursive_search(path: Path, indicators: Iterable[str]) -> Path
1717 FileNotFoundError: if root is not found.
1818
1919 Returns:
20- Path: path to folder containing at list one of the files from the list.
20+ Optional[ Path] : path to folder containing at list one of the files from the list.
2121 """
2222 for file in indicators :
2323 found = list (path .glob (file ))
2424 if len (found ) > 0 :
2525 return path
2626
2727 if path .parent == path :
28- raise FileNotFoundError ( "Project root directory not found." )
28+ return None
2929
3030 return _pyrootutils_recursive_search (path .parent , indicators )
3131
3232
3333def find_root (
3434 search_from : Union [str , Path ] = "." ,
35- indicator : Union [str , Iterable [str ]] = ".project-root" ,
35+ indicator : Union [str , Iterable [str ]] = (
36+ ".project-root" ,
37+ "setup.cfg" ,
38+ "setup.py" ,
39+ ".git" ,
40+ "pyproject.toml" ,
41+ ),
3642) -> Path :
3743 """Recursively searches for project root indicator(s), starting from given path.
3844
@@ -63,8 +69,8 @@ def find_root(
6369
6470 path = _pyrootutils_recursive_search (search_from , indicator )
6571
66- if not path .exists ():
67- raise FileNotFoundError ("Project root directory not found." )
72+ if not path or not path .exists ():
73+ raise FileNotFoundError (f "Project root directory not found. Indicators: { indicator } " )
6874
6975 return path
7076
@@ -94,7 +100,7 @@ def set_root(
94100 path = str (path )
95101
96102 if not os .path .exists (path ):
97- raise FileNotFoundError ("Project root path does not exist. " )
103+ raise FileNotFoundError (f "Project root path does not exist: { path } " )
98104
99105 if pythonpath :
100106 sys .path .insert (0 , path )
@@ -111,7 +117,13 @@ def set_root(
111117
112118def setup_root (
113119 search_from : Union [str , Path ],
114- indicator : Union [str , Iterable [str ]] = ".project-root" ,
120+ indicator : Union [str , Iterable [str ]] = (
121+ ".project-root" ,
122+ "setup.cfg" ,
123+ "setup.py" ,
124+ ".git" ,
125+ "pyproject.toml" ,
126+ ),
115127 pythonpath : bool = True ,
116128 cwd : bool = True ,
117129 project_root_env_var : bool = True ,
0 commit comments