-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Editable install: do not show any output in verbose mode when there is no work to do #579
Editable install: do not show any output in verbose mode when there is no work to do #579
Conversation
85fb89b
to
6bc67f6
Compare
I think the lines:
would be ok, if they were prefixed by some user friendlier message:
But I agree that the repeated message is a bit annoying when using parallelism that spawn Python workers that import |
But I am also fine with what @lesteve suggests in this PR because it fixes both problems at once. |
Thanks! I agree that this message can be confusing. I hadn't seen it printed multiple times yet, but that makes it worse. So looks like a good idea to suppress it. |
mesonpy/_editable.py
Outdated
dry_run_build_cmd = self._build_cmd + ['-n'] | ||
p = subprocess.run(dry_run_build_cmd, cwd=self._build_path, env=env, capture_output=True) | ||
if b'ninja: no work to do.' not in p.stdout and b'samu: nothing to do' not in p.stdout: | ||
print('+ ' + ' '.join(self._build_cmd)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find the build command not very informative because it does not reflect which editable install is being rebuilt, nor does it state that meson-python
's editable install is in charge of making this build happen.
So maybe consider:
print('+ ' + ' '.join(self._build_cmd)) | |
module_names = ", ".join(sorted(self._top_level_modules)) | |
print(f"meson-python: building {module_names}") |
Here is the resulting user experience:
$ touch sklearn/ensemble/_gradient_boosting.pyx
$ python -c "import sklearn"
meson-python: building sklearn
[3/3] Linking target sklearn/ensemble/_gradient_boosting.cpython-311-darwin.so
$ python -c "import sklearn" # nothing to rebuild => no further output
$
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two questions:
- do we want to keep the
ninja
build command for troubleshooting or are we fine not showing it? - do we want to keep the
+
at the beginning of the first line? I guess maybe this was a marker to make it stand out in the output?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have an opinion on those points as long as the first message mentions "meson-python" and the name of the package(s) being rebuilt prior to displaying build outputs.
mesonpy/_editable.py
Outdated
stdout = None | ||
# We do not want any output if there is no work to do. Code is adapted from: | ||
# https://github.com/mesonbuild/meson/blob/a35d4d368a21f4b70afa3195da4d6292a649cb4c/mesonbuild/mtest.py#L1635-L1636 | ||
dry_run_build_cmd = self._build_cmd + ['-n'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not work on Windows, where the compilation command is meson compile
, which does not accept a -n
argument. This demonstrates that this feature needs tests.
It would be great if someone with the necessary rights could enable the Github actions workflow 🙏! I can reproduce the Alpine failure in a Docker container and the bad news is that My basic gdb skills only allowed me to get this information:
Suggestions how to get more info more than welcome ... |
This is: michaelforney/samurai#66 Possibly something Alpine should backport... |
I have skipped the test on Alpine for now based on detecting musllinux. To know whether the test pass on Windows it would be nice that someone enable Github workflows. Full disclosure: locally the Windows tests don't pass and I don't really know why yet. |
Done. this can be a pain because the approve button has to be pressed after every push. If you want to submit a trivial PR to side-step this problem, I'm happy to merge that straight away (e.g, in the readme, change |
mesonpy/_editable.py
Outdated
if self._build_cmd[0] == 'meson': | ||
# On Windows meson compile is used so to do a dry run you need | ||
# --ninja-args | ||
dry_run_build_cmd = self._build_cmd + ['--ninja-args="-n"'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The double quotes around -n
are wrong, if the command is not interpreted by a shell (and it is not when run with subprocess.run()
). Also, what happens when self._build_cmd
already contains a --ninja-args
argument?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch the quoting was the issue indeed, now the test passes locally on a Windows VM.
About multiple --ninja-args
, you probably know a lot more than me about this, so any suggestions welcome!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know whether meson compile
accepts multiple --ninja-args
options. This is why I am asking. If I knew I would not have posed this as a question. You are the proponent of this feature, thus it is on you to verify and to find a solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just tested this and meson compile
does accept multiple --ninja-args
arguments where the last argument overrides all the others.
For example, meson compile --ninja-args="-n" --ninja-args="-h"
does the same as meson compile --ninja-args="-h"
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not acceptable to discard the user supplied argument and keep only the -n
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Point taken, my current plan for this is to fine the last arguments in self._build_cmd
that starts with --ninja-args
and if there is one to append ,-n
to it. This does seem a bit complicated though, let me know if you have a better suggestion!
In order to test this (at least locally), do you have an example in mind on Windows where ninja arguments would be already in the build command (i.e. before adding -n
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My assumption is this would happen when users specify -C...
options to the build frontend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As @eli-schwartz says, you can pass install with pip install -e . -Ccompile-args=-j1
for example.
As for the implementation, it is ok to check if the component of the command starts with --ninja-args
, then you need to parse the value passed to the option and add -n
to the list. You can take some inspiration for how to do it from the code in this test
meson-python/tests/test_project.py
Lines 49 to 56 in b337334
# intercept and filter out test arguments and forward the call | |
if cmd[:2] == ['meson', 'compile']: | |
# when using meson compile instead of ninja directly, the | |
# arguments needs to be unmarshalled from the form used to | |
# pass them to the --ninja-args option | |
assert cmd[-1].startswith('--ninja-args=') | |
cmds.append(cmd[:2]) | |
args.append(ast.literal_eval(cmd[-1].split('=')[1])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have changed the code to deal with existing and multiple --ninja-args
in self._build_cmd
but I haven't written a test for it yet.
…o editable-verbose-no-output-when-no-work-to-do
@eli-schwartz Are you implying that Alpine uses samurai but calls it ninja? I wonder if we can pull in a fixed package in our CI image... |
Yes, it seems that installing ninja on Alpine Linux puts the executable in a location outside The bug @eli-schwartz mentions was fixed in samurai back in 2021, but samurai hasn't seen a release since 2020. |
The CI failures for the development meson version are also Edit: the development meson builds seem to have been fixed. I don't really know what the freebsd issue is about but it does not seem related to this PR either, see build log
|
…o editable-verbose-no-output-when-no-work-to-do
.github/workflows/tests.yml
Outdated
@@ -116,7 +116,7 @@ jobs: | |||
|
|||
- name: Run tests | |||
run: >- | |||
python -m pytest --showlocals -vv --cov --cov-report=xml | |||
python -m pytest --showlocals -vv --cov --cov-report=xml -s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be reverted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep I was about to do it 😉, done in my last commit.
Please don't merge the main branch into your branch the next time: it makes rebasing the commits harder without reason. |
I added the missing tests and fixed up the last issue and submitted as #594 |
Why the current behaviour is problematic
The "ninja: no work to do" output can be confusing as noted for example by @ogrisel in scikit-learn/scikit-learn#28040 (comment). @eli-schwartz mentioned that it could potentially be changed in meson-python scikit-learn/scikit-learn#28040 (comment).
Personally, when working on scikit-learn code, I find it reassuring to see some output if the sklearn import takes a while and get the feed-back that some compilation is happening. In the case when there is nothing to do I would rather have nothing printed. One thing I realised recently is that the "no work to do" output can be printed multiple times if you use subprocesses (makes complete sense since sklearn is imported in each subprocess). This can happen easily in scikit-learn for example with this snippet.
Output is:
Current implementation
The simplest thing I could find was to first execute the
ninja
command in dry-run mode and to check if "no work to do" is in the captured stdout. This may be a bit brittle in case the ninja output changes. Maybe there is a better way to check withninja
that there is no work to do?There does not seem to be any test right now for the editable verbose behavior, but I can try to add some if you think this is worth it.
Alternative implementation
If you think the overhead of having a
ninja
dry-run command is too much overhead, one possible alternative implementation would be to capturestdout
withp = subprocess.Popen(..., stdout=subprocess.PIPE)
and look at the first two lines of output. In my experience, this kind of manipulation are always more complicated than you would hope, but maybe I have been doing it wrong all this time ...The kind of complications I have in mind:
p.stdout.read
is blocking so in the case that there is no output for some reason, it will wait for ever. Maybe we know there will always be some output with theninja
command. You can also put you can usefcntl
to put stdout in non-blocking mode.