Skip to content

Commit 8c79328

Browse files
authored
fix: script pull abort and async generator cleanup (#212)
## Problems **1. `new_event_loop().run_until_complete()` skips async generator cleanup** As the Python docs note: > "consider using the higher-level `asyncio.run()` function, instead of using these lower level functions to manually create and close an event loop." — [asyncio event loop](https://docs.python.org/3/library/asyncio-eventloop.html) `asyncio.run()` additionally calls `loop.shutdown_asyncgens()` before closing, which `run_until_complete()` does not. Async generators (e.g. `TreeModule.list`) that are not fully exhausted have their `aclose()` scheduled but never awaited, producing a `RuntimeWarning`. **2. `click.Abort` during overwrite prompt aborts the entire pull** `click.confirm()` raises `click.exceptions.Abort` when it receives EOF (non-interactive stdin, e.g. scripts or some IDEs) or the user presses Ctrl+C. Previously this propagated uncaught out of `process_entry`, aborting the whole pull and leaving all remaining files unpulled. ## Fixes - Replace all `asyncio.new_event_loop().run_until_complete()` calls with `asyncio.run()` (`get_modules`, `pull`, `push`, `run`) - Catch `click.exceptions.Abort` per file in `script pull` and skip to the next entry instead of aborting
1 parent 5f3694f commit 8c79328

1 file changed

Lines changed: 12 additions & 9 deletions

File tree

src/viur_cli/scriptor/cli.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def get_modules():
2323
global _modules
2424
if _modules is None:
2525
_modules = Modules(scriptor_config["base_url"], cookies=scriptor_config["cookies"])
26-
asyncio.new_event_loop().run_until_complete(_modules.init())
26+
asyncio.run(_modules.init())
2727

2828
return _modules
2929

@@ -146,9 +146,12 @@ def create_file():
146146
with open(_path, "r") as f:
147147
if hashlib.sha256(entry["script"].encode()).digest() \
148148
!= hashlib.sha256(f.read().encode()).digest():
149-
if click.confirm(f"There is a difference with {entry['path']}. Overwrite?"):
150-
os.remove(_path)
151-
create_file()
149+
try:
150+
if click.confirm(f"There is a difference with {entry['path']}. Overwrite?"):
151+
os.remove(_path)
152+
create_file()
153+
except click.exceptions.Abort:
154+
click.echo("\nSkipping...")
152155

153156
else:
154157
create_file()
@@ -161,7 +164,7 @@ def create_file():
161164
async for leaf in tree.list(skel_type="leaf"):
162165
await process_entry(leaf, False)
163166

164-
asyncio.new_event_loop().run_until_complete(main())
167+
asyncio.run(main())
165168

166169

167170
@script.command()
@@ -313,7 +316,7 @@ def on_modified(event):
313316
elif os.path.getmtime(event.src_path) == modified_files[event.src_path]:
314317
return
315318
modified_files[event.src_path] = os.path.getmtime(event.src_path)
316-
asyncio.new_event_loop().run_until_complete(main(event.src_path))
319+
asyncio.run(main(event.src_path))
317320
except Exception as e:
318321
import traceback
319322
print(f"Error: on file {event.src_path} {e}")
@@ -341,9 +344,9 @@ def on_modified(event):
341344
observer.stop()
342345
observer.join()
343346

344-
asyncio.new_event_loop().run_until_complete(watch_loop())
347+
watch_loop()
345348
return
346-
asyncio.new_event_loop().run_until_complete(main())
349+
asyncio.run(main())
347350

348351

349352
@script.command()
@@ -376,4 +379,4 @@ async def main():
376379

377380
await module.main()
378381

379-
asyncio.new_event_loop().run_until_complete(main())
382+
asyncio.run(main())

0 commit comments

Comments
 (0)