espressif / clang-tidy-runner

MIT License
9 stars 5 forks source link

`clang-check` fails on windows: attempts to open tempfile twice (RDT-245) #17

Closed xobs closed 2 years ago

xobs commented 2 years ago

Running idf.py clang-check errors with a traceback:

$ idf.py clang-check --run-clang-tidy-py "python $HOME\esp\esp-idf\tools\run-clang-tidy.py"
...
Traceback (most recent call last):
  File "C:\Users\Sean\esp\esp-idf\tools\idf.py", line 800, in <module>
    main()
  File "C:\Users\Sean\esp\esp-idf\tools\idf.py", line 735, in main
    cli(sys.argv[1:], prog_name=PROG, complete_var=SHELL_COMPLETE_VAR)
  File "C:\Users\Sean\.espressif\python_env\idf5.0_py3.10_env\lib\site-packages\click\core.py", line 1128, in __call__
    return self.main(*args, **kwargs)
  File "C:\Users\Sean\.espressif\python_env\idf5.0_py3.10_env\lib\site-packages\click\core.py", line 1053, in main
    rv = self.invoke(ctx)
  File "C:\Users\Sean\.espressif\python_env\idf5.0_py3.10_env\lib\site-packages\click\core.py", line 1691, in invoke
    return _process_result(rv)
  File "C:\Users\Sean\.espressif\python_env\idf5.0_py3.10_env\lib\site-packages\click\core.py", line 1628, in _process_result
    value = ctx.invoke(self._result_callback, value, **ctx.params)
  File "C:\Users\Sean\.espressif\python_env\idf5.0_py3.10_env\lib\site-packages\click\core.py", line 754, in invoke
    return __callback(*args, **kwargs)
  File "C:\Users\Sean\esp\esp-idf\tools\idf.py", line 629, in execute_tasks
    task(ctx, global_args, task.action_args)
  File "C:\Users\Sean\esp\esp-idf\tools\idf.py", line 216, in __call__
    self.callback(self.name, context, global_args, **action_args)
  File "C:\Users\Sean\.espressif\python_env\idf5.0_py3.10_env\lib\site-packages\pyclang\idf_extension.py", line 25, in call_runner
    runner()
  File "C:\Users\Sean\.espressif\python_env\idf5.0_py3.10_env\lib\site-packages\pyclang\runner.py", line 169, in __call__
    self._run(folder, log_fs, output_dir)
  File "C:\Users\Sean\.espressif\python_env\idf5.0_py3.10_env\lib\site-packages\pyclang\runner.py", line 140, in _run
    func(folder, log_fs, output_dir)
  File "C:\Users\Sean\.espressif\python_env\idf5.0_py3.10_env\lib\site-packages\pyclang\runner.py", line 183, in _f
    return func(self, *args, **kwargs)
  File "C:\Users\Sean\.espressif\python_env\idf5.0_py3.10_env\lib\site-packages\pyclang\runner.py", line 296, in run_clang_tidy
    run_cmd(
  File "C:\Users\Sean\.espressif\python_env\idf5.0_py3.10_env\lib\site-packages\pyclang\utils.py", line 46, in run_cmd
    with open(fw.name, 'rb') as fr:
PermissionError: [Errno 13] Permission denied: 'C:\\Users\\Sean\\AppData\\Local\\Temp\\tmpmhuxs4ss'

This is due to a bug in pyclang.

It attempts to open a file using with tempfile.NamedTemporaryFile() as fw:, which opens the file. However, it then attempts to open the file a second time, which is an undefined operation.

This results in a permissions error on Windows, since tempfiles are exclusive access.

The following patch to Lib/site-packages/pyclang/utils.py fixes the problem:

diff --git a/utils.py b/utils.py
index 59a1713..091a146 100644
--- a/utils.py
+++ b/utils.py
@@ -43,8 +43,7 @@ def run_cmd(

         return_code = p.wait()
         if return_code:
-            with open(fw.name, 'rb') as fr:
-                raw_stderr = to_str(fr.read())
+            raw_stderr = to_str(fw.read())
             if ignore_error and ignore_error in raw_stderr:
                 return KnownIssue()  # nothing happens
             if raw_stderr:
xobs commented 2 years ago

This error is called out on the Python docs page at https://docs.python.org/3.9/library/tempfile.html#tempfile.NamedTemporaryFile:

Whether the name can be used to open the file a second time, while the named temporary file is still open, varies across platforms (it can be so used on Unix; it cannot on Windows).