Repository navigation
Added support for providing multiple scripts with psyclone - #3594
schreiberx wants to merge 8 commits into
Conversation
|
I am happy to review this one (once the tests pass) but @arporter @LonelyCat124 @hiker haven't we discussed this one before (having multiple |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3594 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 401 401
Lines 56540 56624 +84
=========================================
+ Hits 56540 56624 +84 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Not that I remember. I am a big fan of using more OO approach (i.e. one script inheriting from another) - which we can do already (i.e. What is the use case of multiple script - especially what can be achieved with that that we can't already do? FWIW, I already have an example in my tutorial (e.g. Together with arguments for scripts (which can e.g. be used to specify which scripts to tun), I can't see anything that multiple scripts can do that we can't already do, or am I missing something? I don't really object, but am a big fan of KISS :) |
|
And I just notice, how does this work together with keyword arguments? I assume they would be provided for both scripts? |
Ah, I had a quick look now (sorry, should have checked before writing) - each script get its own kwargs. |
You're asking why this would be nice? Here we go:
For this, I don't like to mess around with calling scripts from other scripts, but just pipeline all of them on the command line. |
|
Another reason is that scripts are not always properly packaged to guarantee that imports always work. This is not now we use NEMO, but there is a way to let the NEMO build system call psyclone that copies the scripts from the source directory to a build directory with a different structure. Currently any "imports" in those scripts become broken. You could say that it is the build system problem, but the problem also goes away if they are "independent" scripts that are applied one after the other. In any case this doesn't remove the current functionality, it just provides an alternative. |
|
@schreiberx Have a look at the coverage misses before I do the review. We can also have a discussion in the next telco to make sure everybody agrees. |
One alternative to a PR: Usage: Though this of course needs some additional work to support different command line options per script, and to use the TBH, in your case, I would just use command line options ( Re Sergi's comment about the old-style(?) NEMO build system moving files around: since this is using the PSyclone loader, I think this should work with whatever NEMO is doing there. I don't object to adding this, but I feel that PSyclone is moving away from it's core ability, and instead handles issues with build systems, script design etc. (and the above |
|
What do @arporter @LonelyCat124 think about this? I still find it relatively natural that a psyclone command accepts multiple @schreiberx We still need some clarity/tests about what happens with global script options: https://psyclone.readthedocs.io/en/latest/user_guide/user_scripts.html#script-global-variables |
|
I think that neither E.g., to avoid this, a script could look like this: |
|
@schreiberx This is not possible:
This is already done when the issue is the script, the FILES_TO_SKIP is to skip files where the issue is in the frontend or backend, so an empty passthrough (skipping the script) also generated invalid code.
This works but it is much slower (because changing symbol information after parsing needs to traverse the tree updating some nodes with the new information to keep things consistent), also some logic during the frontend, e.g. resolving WHERE constructs is worse without the symbol information. |
|
OK. This now makes all sense to me. Then, concatenating all FILES_TO_SKIP and OR-ing RESOLVE_IMPORTS would be the approach we'd go for? |
Yes for Or-ing (or Union-ing is Set notation terms), with a 'True' taking precedence for RESOLVE_IMPORTS. |
|
I think we're ready to go. |
sergisiso
left a comment
There was a problem hiding this comment.
@schreiberx As I mentioned I'm fine with the overall idea of providing multiple scripts to a psyclone command, but the current implementation have some problems that need to be fixed, see inline.
| # Pair each script with its kwargs | ||
| # kwargs[i] corresponds to script[i] for backward compatibility | ||
| # This works for the common case: | ||
| # -s script1 --script-kwargs arg1 -s script2 --script-kwargs arg2 | ||
| script_kwargs_pairs = [] | ||
| for i, script in enumerate(args.script): | ||
| kwargs = args.script_kwargs[i] if i < len(args.script_kwargs) else None | ||
| script_kwargs_pairs.append((script, kwargs)) | ||
|
|
There was a problem hiding this comment.
This is not sufficient. For -s first.py -s second.py --script-kwargs 'x: 1', this assigns x to the first script rather than the most recent script, contrary to the documented behaviour.
Add a test about this.
We also want to check that something like:
-s first.py --script-kwargs 'x: 1' --script-kwargs 'x: 2' -s second.py is invalid instead of silently overwritten/misaligned
| # Clean up sys.path after loading each script | ||
| # TODO #3514: proper cleanup using with | ||
| if inserted_path in sys.path: | ||
| sys.path.remove(inserted_path) |
There was a problem hiding this comment.
Remove the previous version of this at line 1059
There was a problem hiding this comment.
In fact this changes the behaviour, if we have:
folder1/script.py
def trans():
import utils
folder1/utils.py
folder2/script.py
def trans():
import utils
folder2/utils.py
And we do
psyclone -s folder1/script.py -s folder2/script.py , now the utils.py won't be found because it is a runtime import which only happens when the trans_recipe(psyir, **kwargs) is called below.
You will need to restructure all this section so the the sys.path.remove(inserted_path) happens after trans_recipe but still before the load_script of the next script is executed, otherwise it gets the wrong path for that (e.g. it would impor the wrong utils in the example above)
| if resolve_mods: | ||
| final_resolve_mods = resolve_mods |
There was a problem hiding this comment.
That's wrong, here we load all scripts and just rewrite the final_resolve_mods. When two recipes specify different RESOLVE_IMPORTS lists, only the last nonempty list reaches FortranReader, so the first recipe no longer receives the resolved symbols it requested.
I thought we said we would be "or-ing"/"union-ing" the requested RESOLVE_IMPORTS, and let a "True" take precedence about everything else.
|
@sergisiso It seems that there's no way to relate some 'script-arguments' argument following a 'script' argument with argparse. I couldn't find a way to determine the argument's position, and I think mixing it up with sys.argv parsing isn't good. How about this solution that is also backward compatible:
|
|
@schreiberx Let's revert to just accepting one set of script-kargs and provide the same set to all scripts. A script is free to ignore kwargs anyway. |
I first thought that it was a good idea since it might look like some over-engineering, but then I thought about use cases similar to what I have in my other development: |
No description provided.