On 22.09.21 21:53, John Snow wrote:
(This email just explains python packaging stuff. No action items in
here. Skim away.)
On Fri, Sep 17, 2021 at 5:43 AM Hanna Reitz <hre...@redhat.com
<mailto:hre...@redhat.com>> wrote:
On 16.09.21 06:09, John Snow wrote:
> 'pylint-3' is another Fedora-ism. Use "python3 -m pylint" or
"python3 -m
> mypy" to access these scripts instead. This style of invocation will
> prefer the "correct" tool when run in a virtual environment.
>
> Note that we still check for "pylint-3" before the test begins
-- this
> check is now "overly strict", but shouldn't cause anything that was
> already running correctly to start failing.
>
> Signed-off-by: John Snow <js...@redhat.com
<mailto:js...@redhat.com>>
> Reviewed-by: Vladimir Sementsov-Ogievskiy
<vsement...@virtuozzo.com <mailto:vsement...@virtuozzo.com>>
> Reviewed-by: Philippe Mathieu-Daudé <phi...@redhat.com
<mailto:phi...@redhat.com>>
> ---
> tests/qemu-iotests/297 | 45
++++++++++++++++++++++++------------------
> 1 file changed, 26 insertions(+), 19 deletions(-)
I know it sounds silly, but to be honest I have no idea if replacing
`mypy` by `python3 -m mypy` is correct, because no mypy documentation
seems to suggest it.
Right, I don't think it's necessarily documented that you can do this.
It just happens to be a very convenient way to invoke the same script
without needing to know *where* mypy is. You let python figure out
where it's going to import mypy from, and it handles the rest.
(This also makes it easier to use things like mypy, pylint etc with an
explicitly specified PYTHON interpreter. I don't happen to do that in
this patch, but ... we could.)
From what I understand, that’s generally how Python “binaries” work,
though (i.e., installed as a module invokable with `python -m`,
and then
providing some stub binary that, well, effectively does this, but
kind
of in a weird way, I just don’t understand it), and none of the
parameters seem to be hurt in this conversion, so:
Right. Technically, any python package can ask for any number of
executables to be installed, but the setuptools packaging ecosystem
provides a way to "generate" these based on package configuration. I
use a few in our own Python packages. If you look in python/setup.cfg,
you'll see stuff like this:
[options.entry_points]
console_scripts =
qom = qemu.qmp.qom:main
qom-set = qemu.qmp.qom:QOMSet.entry_point
qom-get = qemu.qmp.qom:QOMGet.entry_point
qom-list = qemu.qmp.qom:QOMList.entry_point
qom-tree = qemu.qmp.qom:QOMTree.entry_point
qom-fuse = qemu.qmp.qom_fuse:QOMFuse.entry_point [fuse]
qemu-ga-client = qemu.qmp.qemu_ga_client:main
qmp-shell = qemu.qmp.qmp_shell:main
These entries cause those weird little binary wrapper scripts to be
generated for you when the package is *installed*. So our packages
will put 'qmp-shell' and 'qom-tree' into your $PATH*.The stuff to the
right of the equals sign is just a pointer to a function that can be
executed that implements the CLI command. qemu.qmp.qmp_shell points to
the module to import, and ':main' points to the function to run.
The last bit of this is that many, though not all (and there's zero
requirement this has to be true), python packages that implement CLI
commands will often have a stanza in their __init__.py module that
says something like this:
if __name__ == '__main__':
do_the_command_line_stuff()
Alternatively, a package can include a literal __main__.py file that
python knows to check for, and this module is the one that gets
executed for `python3 -m mypackage` invocations. This is what mypy does.
Those are the magical blurbs that allow you to execute a module as if
it were a script by running "python3 -m mymodule" -- that hooks
directly into that little execution stanza. For python code
distributed as packages, that's the real reason to have that little
magic stanza -- it provides a convenient way to run stuff without
needing to write the incredibly more tedious:
python3 -c "from mypy.__main__ import console_entry; console_entry();"
... which is quite a bit more porcelain too, depending on how they
re/factor the code inside of the package.
Seeing as how mypy explicitly includes a __main__.py file:
https://github.com/python/mypy/blob/master/mypy/__main__.py
<https://github.com/python/mypy/blob/master/mypy/__main__.py>, I am
taking it as a given that they are fully aware of invoking mypy in
this fashion, and believe it safe to rely on.
Wow, thanks a lot for this detailed explanation!
There will be a quiz later.
(There will not be a quiz.)
I’m ready to fail any test on Python so one day I can get a “Officially
knows nothing about Python” badge.
Hanna