Skip to content
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

Add --python option #150

Merged
merged 7 commits into from
Apr 8, 2023
Merged

Add --python option #150

merged 7 commits into from
Apr 8, 2023

Conversation

ClementPinard
Copy link
Contributor

Fixes #149
Still Work in Progress, happy to receive feedback !

Not particularly happy with the fact that you have to specify until the site-packages folder and not just the venv folder. suggestions welcome.

@ClementPinard
Copy link
Contributor Author

here is how you can use it if you want licenses (and version numbers) from another environment. This would be particularly useful in a CI where you want exact license and versions of your project dependencies, which could be clashing with pip-licenses's dependencies (even though they are minimal)

source /path/to/venv/bin/activate
/path/to/pip-licenses --path $(python -c "import sys; print(','.join(filter(bool, sys.path)))")

this would be particularly interesting with pip-licenses installed in you system python

example with poetry

pip install pip-licences
source `poetry env info --path`/bin/activate
pip-licenses --path $(python -c "import sys; print(','.join(filter(bool, sys.path)))")

@thejcannon
Copy link
Contributor

Not particularly happy with the fact that you have to specify until the site-packages folder and not just the venv folder.

I've seen other tools allow for a --python flag pointing to a python interpreter, then it grabs sys.path from that. So you'd point to <venv>/bin/python which is much more stomachable and also helps with custom Python shenanigans and might handle .pth files better.

@ClementPinard
Copy link
Contributor Author

ClementPinard commented Mar 23, 2023

So I guess launching another python from subprocess ? and then getting back the printed sys.path ? That would be possible indeed ! I'll try to come up with something that uses both --python and --path as they could be added together in the end.

@raimon49
Copy link
Owner

@ClementPinard I read #149 and using distributions([folder_path]) to explore outside folders is a cool and interesting idea. Will the implementation of the --path option be further updated as we see the discussion?

@raimon49 raimon49 mentioned this pull request Apr 2, 2023
@raimon49
Copy link
Owner

raimon49 commented Apr 2, 2023

I am not sure if I should merge this PR and include it in the next release 4.2.0.

Is the implementation of the --path option complete?

@ClementPinard
Copy link
Contributor Author

Hey,
sorry for late answer. If no objections, I'm going to implement the --python option as suggested by @thejcannon very soon (today if I find the time)

From that we can work on potential review comments, and I think the feature will be complete.

@ClementPinard
Copy link
Contributor Author

So I said I would keep both --path and --python. Turns out, when I had to give an example of how you would need a path option, I could not come up with something useful not already done by the --python .

I you need to get licenses from an extra folder, you might as well install the package with -e option instead of playing with sys.path

As a result, I decided to only keep the --python option, to not add a superfluous option in an already packed arg parser. Feel free to share your thoughts on this, and an example on how you would need it in a clean way 🙃

@raimon49 I now think this PR is finished, and open for review.

@ClementPinard ClementPinard changed the title Add path option Add --python option Apr 4, 2023
@codecov
Copy link

codecov bot commented Apr 5, 2023

Codecov Report

Merging #150 (4129b76) into master (471fc3d) will decrease coverage by 0.24%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master     #150      +/-   ##
==========================================
- Coverage   99.74%   99.50%   -0.24%     
==========================================
  Files           1        1              
  Lines         392      408      +16     
==========================================
+ Hits          391      406      +15     
- Misses          1        2       +1     
Impacted Files Coverage Δ
piplicenses.py 99.50% <100.00%> (-0.24%) ⬇️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

Comment on lines +100 to +102
#### Option: python

By default, this tools finds the packages from the environment pip-licenses is launched from, by searching in current python's `sys.path` folders. In the case you want to search for packages in an other environment (e.g. if you want to run pip-licenses from its own isolated environment), you can specify a path to a python executable. The packages will be searched for in the given python's `sys.path`, free of pip-licenses dependencies.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also checked the importlib_metadata source code. It was using sys.path by default as you described 👍

There is a ToC at the top of the README document. Could you also add a link to "Option: python"?

Comment on lines +201 to +206
if args.python == sys.executable:
search_paths = sys.path
else:
search_paths = get_python_sys_path(args.python)

pkgs = importlib_metadata.distributions(path=search_paths)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To resolve the points that Codecov points out, we need a test case that mocks the call to importlib_metadata.distributions(), for example. Any ideas on how to do this?

Of course, it is preferable to have test cases, but if it is too difficult, I will merge the PR as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting to that L203 is not covered, I would have thought that the L202 would not be covered since we don't test other python environments

@ClementPinard
Copy link
Contributor Author

I add a test that creates a temporary empty virtual env, and thus should only find pip and setuptools.

I had some troubles figuring out why it still found all packages in main virtual environment, and solved this problem by calling the alternative python executable with empty environment variables for PYTHONPATH and VIRTUAL_ENV

output = subprocess.run(
            [executable, "-c", script],
            capture_output=True,
            env={**os.environ, "PYTHONPATH": "", "VIRTUAL_ENV": ""},
        )

Would there be some usecase where keeping them is actually important ? FYI, not resetting PYTHONPATH breaks the tests because it is set to the main virtual environment, resetting VIRTUAL_ENV does not

@raimon49
Copy link
Owner

raimon49 commented Apr 6, 2023

I add a test that creates a temporary empty virtual env, and thus should only find pip and setuptools.

Oh, it had never occurred to me that this was the way to do it. I consider it a good enough test case.

Why are CI tests failing only in the Python 3.8 environment?

@ClementPinard
Copy link
Contributor Author

Looks like I was not typehinting the right way. The venvBuilder context is a types.SimpleNamespace object (https://docs.python.org/3.8/library/types.html#types.SimpleNamespace), but I typehinted it as venv.SimpleNamespace I suspect venv did import SimpleNamespace but only after a certain version, because mypy did not complain for my python3.10 version

I put back the original type in the typehinbt and we should be good to go. If not, I'll just remove the typehint altogether.

@raimon49
Copy link
Owner

raimon49 commented Apr 7, 2023

@ClementPinard Thank you for your great contribution! I will merge this PR into the next release candidate version.

@raimon49 raimon49 merged commit 8b38914 into raimon49:master Apr 8, 2023
@raimon49
Copy link
Owner

raimon49 commented Apr 8, 2023

pip-licenses version 4.2.0 RC2 is now available. This PR includes.

If you have any concerns about the actual use of the system, please provide feedback. Thanks.

$ pip install "pip-licenses==4.2.0rc2"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Retrieve licenses from other environment
3 participants