To illustrate my point, I took the liberty and use your example from your post
========================== On Thursday, November 20, 2025 at 4:24:37 AM UTC-6 Edward K. Ream wrote: Leo issue #4472 <https://github.com/leo-editor/leo-editor/issues/4472>is a hobby project...This sentence [from gemini3] captures my initial vague idea exactly: Your proposal essentially transforms Pylint from an *Inference Engine* (which is slow and guess-prone) into a *Logic Validator* (which is fast and deterministic). All well and good, but pylint's --prefer-stubs <https://pylint.pycqa.org/en/latest/user_guide/configuration/all-options.html#prefer-stubs> command-line option may be the best way to help pylint. gemini3 had no part in my thought process, and I have the feeling that gemini3 may have led me astray had I continued the original discussion. In a weird way, AIs seem to have blind spots. My next step will be to adapt Leo's python importer so that it copies signatures for classes, methods and functions into a .pyi (stub) file. This will be a *much* easier project than my old make-stub-files <https://github.com/edreamleo/make-stub-files> script. It should take only a few days. ============================== and put that into Windsurf (first my request, then the answer): Take the file D:\WORKSPACE\leo-editor-devel\leo\core\leoImport.py and adapt it so that it copies signatures for classes, methods and functions into a .pyi (stub) file. This will be a much easier project than my old make-stub-files script. ANSWER: Good idea to integrate stub generation directly with Leo’s import machinery. I’ll first scan [leoImport.py](cci:7://file:///d:/WORKSPACE/leo-editor-devel/leo/core/leoImport.py:0:0-0:0) to see its structure and existing import commands, then propose a concrete design (e.g. a new command that walks classes/functions and writes a `.pyi` alongside the source). After that, I can suggest or implement the code changes. I’ll create a short TODO plan and read the file now. Here’s a concrete plan and some design questions before I touch the code. --- ## High‑level idea Add a **new command + helper(s)** in [leoImport.py](cci:7://file:///d:/WORKSPACE/leo-editor-devel/leo/core/leoImport.py:0:0-0:0) that: 1. Takes a Python module path (or uses the current `@file` node’s file). 2. Uses `ast` to parse it. 3. Walks classes, methods, and functions. 4. Writes a corresponding `.pyi` file (next to the `.py` or into a chosen directory) containing only **signatures** and minimal bodies (`...`). This stays strictly simpler than a general “make-stub-files” script: no cross‑module analysis, no type inference; just copy what’s already in annotations/defaults. --- ## Design questions for you To avoid guessing, I’d like your preferences on these: 1. **Source of file to stub** - **Option A**: a command that uses the **current `@file` node**’s external file (`c.p`). - **Option B**: a command that prompts for one or more `.py` files (similar to other `import*` commands). - We can support both, but which should be the primary workflow? 2. **Where to write `.pyi`** - Same directory as the `.py` (`foo.py` → `foo.pyi`)? - Or some configurable “stubs directory” (setting) relative to the project? 3. **What to include** - Only top‑level `def` and `class` definitions? - For classes: include all methods, `@classmethod`, `@staticmethod`, properties? - Skip private names starting with `_` or include everything? 4. **Handling existing `.pyi` files** - Always **overwrite**? - Or refuse if exists (unless a config/argument says “force”)? If you answer these, I can implement something that matches your intended workflow. --- ## Proposed concrete changes in [leoImport.py](cci:7://file:///d:/WORKSPACE/leo-editor-devel/leo/core/leoImport.py:0:0-0:0) ### 1. Add a small AST-based stub generator Implement a pure helper (no Leo dependency) near [LeoImportCommands](cci:2://file:///d:/WORKSPACE/leo-editor-devel/leo/core/leoImport.py:137:0-1339:13) or at the bottom: - `generate_stub(source: str) -> str` - Parse with `ast.parse`. - Collect: - `ast.FunctionDef` / `ast.AsyncFunctionDef` at module level. - `ast.ClassDef` and their methods. - Reconstruct signatures: - Use `ast.get_source_segment` if feasible, or format `args`, `returns` yourself. - Body is always `...` (ellipsis). - `write_stub_for_file(path: str) -> str` - Read file. - Call `generate_stub`. - Write to `path.replace('.py', '.pyi')` (or similar logic). - Return path of written stub. This part will be straightforward and fully testable without GUI. ### 2. Add Leo-facing helpers in [LeoImportCommands](cci:2://file:///d:/WORKSPACE/leo-editor-devel/leo/core/leoImport.py:137:0-1339:13) For example: - `def makeStubForCurrentFile(self) -> None:` - Use `c.p` to find the underlying external `.py` (via `c.fullPath(p)` / `atFileCommands` if needed). - Call `write_stub_for_file`. - Report in the log (`g.es(f"created stub: {stub_path}")`). - Optionally: `def makeStubsForFiles(self, paths: list[str]) -> None:` - Loop over a list of `.py` files (if you want a “batch” mode with a dialog). ### 3. Add commands (decorated functions) near the other `@g.command` definitions Following the style you showed: ```python @g.command('make-stub-for-current-file') def make_stub_for_current_file(event: LeoKeyEvent) -> None: c = event.get('c') if c: c.importCommands.makeStubForCurrentFile() ``` Optionally another command taking multiple files via an open dialog, if you want parity with other import commands. --- ## Behavior details (default proposal) Unless you say otherwise, I’d implement: - **Source**: - Primary: current `@file` node’s underlying `.py`. - Fallback: if `c.p` is not an `@file` node with `.py`, show an error. - **Destination**: - Same directory, same basename, `.pyi` extension. - **Included items**: - All **top‑level** functions and classes. - For classes: - All methods (including async) and static/class methods. - Properties exposed via `@property`. - Don’t filter private names initially (keep it simple and predictable). - **Docstrings**: - Omitted in `.pyi` (just signatures + `...`). - **Existing stubs**: - **Overwrite** by default, with a log message. We can add a config bool later, e.g. `@bool stub_generation_overwrite = True/False`. --- ## Next step If you confirm your answers to the 4 design questions (or accept the defaults above), I’ll: - Implement the stub generator helpers in [leoImport.py](cci:7://file:///d:/WORKSPACE/leo-editor-devel/leo/core/leoImport.py:0:0-0:0). - Add a `LeoImportCommands.makeStubForCurrentFile` (and optional batch variant). - Add a `@g.command` wrapper to invoke it from Leo. - Keep comments/structure consistent with existing code and not touch unrelated parts. Then I’ll summarize exactly what changed and how to use the new command. END OF ANSWER The technical details are over my head. But they will be meaningful to you. And I guess, with some additionl questions the days will shrink into hours... Regards Reinhard On Tuesday, November 25, 2025 at 10:36:58 AM UTC+1 Edward K. Ream wrote: > On Tuesday, November 25, 2025 at 3:10:02 AM UTC-6 rengel wrote: > > Thanks for sharing! Did you try to put the complete Leo codebase into an > AI-based IDE like Windsurf or Google Antigravity? Then you can get a > critique of the entire codebase or parts thereof or the complete > documentation within the IDE and get automatic improvements (if you wish > so) or suggestions for improvements. > I know that this isn't the Leonine way of programming, but it might be > worth a try. > > > No, I haven't tried that. Thanks for the suggestion. > > Edward > -- You received this message because you are subscribed to the Google Groups "leo-editor" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/leo-editor/125440c4-dff2-497d-a748-a529e872244fn%40googlegroups.com.
