Hi Edward, I wrote my first Leo plugin: python_auto_imports. It works for me --- but there is still a lot of work to be done before it can be shared.
My question is: What is the best place to discuss the different aspects of the work and to keep the work itself? On the top level, we have two choices: (A) Do the work in private until we have some project that can be integrated and used by others. (B) "Work in the open" --- discuss the design choices with anyone interested, share the work-in-progress code in github and release it to the official Leo source when it's ready. For option (B), there may be different appropriate locations for the different parts of the work: (1) Motivation and normal UX design/documentation. (2) UX design/documentation for error reporting and user choices --- integration with pylint and other error detection extensions. (3) Technical integration with the Leo sources. Here is a high-level overview of these three parts of work: *(1) Motivation and normal UX design/documentation:* In order for other people to use the plugin, I need to clearly motivate it and explain how to use it. For most parts, the `import` statements in python are trivial -- but for some case (e.g. import cycles and import side-effects), things can become complicated. These problems need to be discovered and discussed. For documentation, I believe a simple LeoVue page could collect all the relevant information. For discussion we may either continue in this e-mail thread or create a github issue in the leo-editor repository for this extension. *(2) UX design/documentation for user choices and error reporting --- fix-errors and pyflakes integration:* Instead of copying the UI/UX of the automatic imports from PyCharm (that opens modal input windows whenever the user needs to make a choice), I want to create a UX that *lives inside the Leo outline.* This same UX will integrate with other features that can detect errors and warnings about the project currently edited -- e.g. pyflakes and capturing stack traces from test exceptions. Here is the idea: You define all choices as configurations (e.g. with @auto-import nodes) in the outline of your project. It's OK not to create any such configuration at the outset. This will simply trigger errors --- to be fixed with `fix-errors`. The *fix-errors command* works similar to the cfa command: it populates a 'fix-errors' node at the bottom of the outline with explanations of any detected errors/warnings, suggestions of corrections and clones of the offending source nodes. These child nodes will be organized into an easy-to navigate tree so that you can quickly get to the action that you want to perform to resolve the problem. For example, you may see just two direct children of the `fix-errors` node: One exception trace (showing just the message of the exception) and one node titled '4 auto-import problems'. By expanding the first child (exceptions) -- you would see the code lines of the exception stack trace that are appear as clones of the actual sources of these lines. Just with the cursor keys, you can flip through these code nodes until you find the problem and fix it on the spot. Alternatively, you could expand the node '4 auto-import problems' -- which has four children. One for each discovered problem. By expanding one of these problems, you will see the relevant problem information --- and children with suggested solutions (e.g. imports from external libraries). If we have more information about a suggestion, we can add as sub-children to each option. Hence, just with your cursor keys you can investigate all problems, suggested solutions --- and solve the problem on the spot. This *fix-errors extension* is a project by itself --- and should be documented in a separate project page and discussed in a separate e-mail thread or in a separate github issue. *(3) Technical integration with the Leo sources:* Currently, my plugin is a hack. I just started to play with Leo a few days ago and needed some solution quickly to continue with my main day job (with Leo). Very likely, I will need to change the current Leo source to add hooks that my extensions can connect to. For coding we have two choices: Either work on feature branches inside the leo-editor repository or to clone this repository and send pull requests from this external copy. What are your preferences for these choices? Yaakov On Wed, Feb 19, 2020 at 2:43 AM Yaakov Belch <yaakov.be...@gmail.com> wrote: > Hi Matt, > > Thanks for sharing your workflow. Here are some comments: > > For #1 (remember where the function comes from -- yb), I find it important >> to remember what the module has the function. I wouldn't want to get *os.path >> *confused with *foorbar.null.path. *When I don't like the extra typing I >> use the idiom *"from foobar import null as fbn"* and then use it as >> *"fbn.path".* >> > > My plan is that the programmer explicitly declares where functions are > imported from --- but he does this only for external dependencies and only > once per project. Imports for all python files will be built from these > definitions. The rules are: > > * If you define a class, function or global variable `path` in your > project --- then any undefined use of a name `path` will be provided with > an automatic matching import statement. > * The first time I want to use an external dependency (e.g. > `Pathlib.path`) I have to define the corresponding import statement. > * However, you can reuse this definition for all python files in this > project --- and copy your favorite definitions in bulk to other projects. > * If there is any conflict --- multiple definitions for the same name --- > then you get an error message. You will have to decide on a unique name to > feature map of names that you want to use in this project. > > As a result, there will be no ambiguity. > > For #2 and thus #3 (move the import statement to the top -- yb): just skip >> them! When I'm in flow and need a new module I just "import foo" right >> where I am, inside the function even. Later, after the thing is working >> well enough, I move the import where it belongs. There are probably subtle >> (or not so subtle!) scenarios where this pattern causes problems but so far >> it hasn't happened to me. >> > > Here is a problem with automatically moving import out of the body of > functions or methods to the top of the file: When you have cyclic data > dependencies between classes, you can resolve them by putting some import > statements inside functions and not at the top of the file. These imports > will be executed at run time (when the function is actually called) and > hence break the import cycle. > > I came across a few special cases where swapping import statements with > other statements can cause problems: > * If a statement affects the import mechanism (such as setting the search > path for modules) then it has to come before the imports. > * gevent.monkey_patch() needs to run before other imports --- otherwise it > won't work as intended. > > I'm not arguing against an auto-import feature, just answering the "what >> do you do?" part of the question. >> > > That's understood --- I appreciate the discussion. > > I saw a python utilty somewhere on pypi.org that handled >> move-imports-automatically as part of a code linting process but didn't >> feel the need to follow up on it. I see an active feature request for Black >> to move and order imports: https://github.com/psf/black/issues/333. A >> quick read of the comments seems to indicate it might be forthcoming soon. >> If it does, then I expect Leo to be able to use it straightforwardly. >> > > The 'optimize imports' feature of PyCharm (taken as a motivating example > of this issue 333) does not move imports past function definitions. It > only optimizes contiguous runs of import statements --- for the sake of > correctness. > -- 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 leo-editor+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/leo-editor/CAHWiE3X_-NCgBgZ4EPWLCahtdYQrkgJmoAALBbxNP6sj7zeiEg%40mail.gmail.com.