Search code examples
python-3.xpathcommand-line-interfacepython-click

Error 'No such file or directory' when use click


I'm using click 8.1.3 to parse my command,and my cli.py is like this:

@click.option('--output_dir', default=os.curdir, help='when outdated is true,choose directory which you want to put your cache file')
@click.option('--cache_dir', default=os.curdir, help='when outdated if false,choose directory where put cache file')
def main(outdated, nodes_path, river_path, cur_sta, up_sta, cutoff, upstream, downstream, cache_dir, output_dir):
……

But when I try to read cache files from a directory such as C:\Users\UserName\Desktop\test-cache, it occured wrong:

PS C:\Users\UserName\Desktop\test_cache2> calcstream --nodes_path XXX --river_path YYY --cur_sta 0 --up_sta 10 --cache_dir C:\Users\UserName\Desktop\test-cache --outdated False
Traceback (most recent call last):
File "C:\Python310\lib\runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Python310\lib\runpy.py", line 86, in _run_code
exec(code, run_globals)
File "C:\Python310\Scripts\calcstream.exe\__main__.py", line 7, in <module>
File "C:\Python310\lib\site-packages\click\core.py", line 1130, in __call__
return self.main(*args, **kwargs)
File "C:\Python310\lib\site-packages\click\core.py", line 1055, in main
rv = self.invoke(ctx)
File "C:\Python310\lib\site-packages\click\core.py", line 1404, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "C:\Python310\lib\site-packages\click\core.py", line 760, in invoke
return __callback(*args, **kwargs)
File "C:\Python310\lib\site-packages\dijkstra_conda\cli.py", line 35, in main
upstream_node_on_mainstream(nodes_reader, network_reader, cur_sta, up_sta, outdated, cache_dir, output_dir)
File "C:\Python310\lib\site-packages\dijkstra_conda\dfs_path_test.py", line 463, in upstream_node_on_mainstream
origin_graph = get_upstream_stations_graph(node_reader, network_reader, number_src, outdated)[2]
File "C:\Python310\lib\site-packages\dijkstra_conda\dfs_path_test.py", line 348, in get_upstream_stations_graph
upstream_graph = get_upstream_stations(node_reader, network_reader, number, outdated, cutoff, cache_dir, output_path)[0]
File "C:\Python310\lib\site-packages\dijkstra_conda\dfs_path_test.py", line 243, in get_upstream_stations
stations_graph = build_graph(node_reader, network_reader, outdated, cache_dir, output_path)
File "C:\Python310\lib\site-packages\dijkstra_conda\dfs_path_test.py", line 205, in build_graph
nearest_point_line_dict = tie_outside_node(node_reader, network_reader, outdated, cache_dir, output_path)[1]
File "C:\Python310\lib\site-packages\dijkstra_conda\dfs_path_test.py", line 115, in tie_outside_node
source_point_frame = pd.read_csv(os.path.join(cache_dir, 'source_project_points.csv'))
File "C:\Python310\lib\site-packages\pandas\util\_decorators.py", line 211, in wrapper
return func(*args, **kwargs)
File "C:\Python310\lib\site-packages\pandas\util\_decorators.py", line 317, in wrapper
return func(*args, **kwargs)
File "C:\Python310\lib\site-packages\pandas\io\parsers\readers.py", line 950, in read_csv
return _read(filepath_or_buffer, kwds)
File "C:\Python310\lib\site-packages\pandas\io\parsers\readers.py", line 605, in _read
parser = TextFileReader(filepath_or_buffer, **kwds)
File "C:\Python310\lib\site-packages\pandas\io\parsers\readers.py", line 1442, in __init__
self._engine = self._make_engine(f, self.engine)
File "C:\Python310\lib\site-packages\pandas\io\parsers\readers.py", line 1729, in _make_engine
self.handles = get_handle(
File "C:\Python310\lib\site-packages\pandas\io\common.py", line 857, in get_handle
handle = open(
FileNotFoundError: [Errno 2] No such file or directory: '.\\source_project_points.csv'

It seems that the program still uses os.curdir(C:\Users\UserName\Desktop\test_cache2) to find source_project_points.csv, and I'm sure source_project_points.csv is in C:\Users\UserName\Desktop\test-cache, so how to solve the problem?

This is my project link.


Solution

  • Now I know, you shouldn't set default parameter in business code, rather write in @click.option(default=).