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

Leverage existing requirements.txt parsing logic to close #225 #227

Merged
merged 3 commits into from
Mar 15, 2023

Conversation

vreuter
Copy link
Contributor

@vreuter vreuter commented Mar 14, 2023

Once aboutcode-org/pip-requirements-parser#17 is merged, we could more directly use pip-requirements-parser (namely, the RequirementsParser.from_string method). Until then, this works around a NameError that comes up when using the less common from_string method in the RequirementsFile class in that project.

@vreuter vreuter marked this pull request as draft March 14, 2023 17:38
@vreuter vreuter force-pushed the vr/line-continuation-225 branch from d4096c5 to dad9423 Compare March 14, 2023 17:44
@vreuter vreuter marked this pull request as ready for review March 14, 2023 17:44
@vreuter vreuter force-pushed the vr/line-continuation-225 branch from dad9423 to 3d3ce17 Compare March 14, 2023 17:45
@jherland
Copy link
Member

Hmm. I took a closer look at pip-requirements-parser's own code, and AFAICS it boils down to a single Python script of almost 3000 lines (😱), the vast majority of which is copied directly from pip itself. After reading through the project's own README, my initial WTF!? reaction is somewhat softened, and the project argues well for why things are done this way.

Still, what I don't like about this integration here is having to write out a temporary file to parse some requirements text, when this text (with the sole exception of parsing setup.cfg) already comes directly from a file!

However, fixing this requires firrst some moderate refactoring in our extract_declared_dependencies.py to adjust our various parsers to work on Paths directly rather than str + Location arguments.

Coincidentally, this also frees up our parser to decide for themselves exactly how to read the given file (i.e. they may choose something more appropriate than Path.read_text(), depending on their context. I think this refactoring might be a net win overall, and worth doing in any case...

After this refactoring parse_requirements_contents() would be reduced to a single call to RequirementsFile.from_file(filename=str(path), include_nested=False).requirements.

Then there is the special case of parse_setup_cfg_contents() which also leans on parse_requirements_contents() to parse its requirements values, but given that requirements.txt probably outnumber setup.cfg files 1000:1, I'd rather put the clumsy workaround (writing a temp file) inside parse_setup_cfg_contents() rather than inside parse_requirements_contents().

I started looking at this refactoring, and I'd rather you rebuild this PR on top of that, instead of having to write temporary files for every single requirements.txt file we will ever parse... Will post a branch as soon as I got something that passes tests...

jherland added a commit that referenced this pull request Mar 14, 2023
Take a single Path argument instead of separate contents + source. This
allows the parser function itself to choose how to open the file and
pass it to the underlying parser. This is also necessary for the
upcoming rewrite of our requirements.txt parser (#227).
@jherland
Copy link
Member

I started looking at this refactoring, and I'd rather you rebuild this PR on top of that, instead of having to write temporary files for every single requirements.txt file we will ever parse... Will post a branch as soon as I got something that passes tests...

#229

vreuter added a commit that referenced this pull request Mar 15, 2023
#227 (#229)

* test_extract_declared_dependencies_succes: Harmless test refactoring

Move the dependency_factory() call into the test case instead of in the
parametrized test data. Also remove unnecessary "__" prefix from test
ids.

* extract_declared_dependencies: Refactor API of parser functions

Take a single Path argument instead of separate contents + source. This
allows the parser function itself to choose how to open the file and
pass it to the underlying parser. This is also necessary for the
upcoming rewrite of our requirements.txt parser (#227).

* test_extract_declared_dependencies_pyproject_toml: Remove unnecessary dedent()

* extract_declared_dependencies: Rename parser functions

The rename reflects that these now parse file paths, and not extracted
file contents.

---------

Co-authored-by: Vince Reuter <vince.reuter@gmail.com>
@vreuter vreuter force-pushed the vr/line-continuation-225 branch from 3d3ce17 to 33aa6a1 Compare March 15, 2023 10:59
@vreuter vreuter force-pushed the vr/line-continuation-225 branch from 33aa6a1 to 014533a Compare March 15, 2023 11:01
Copy link
Member

@jherland jherland left a comment

Choose a reason for hiding this comment

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

Looks great! Two things missing:

For the second one, I've been looking at pip-requirements-parser to see if there is anything in there we could benefit from1.

AFAICS, we have to dig all the way in to RequirementsFileParser._parse_file() before we've actually opened and read the file. so a cleaner implementation of RequirementsFile.from_string() would have to copy all but the first line of ._parse_file()...

Footnotes

  1. Even if we were to call into its internal functions, this could still be considered acceptable as we can pin our use of pip-requirements-parser (and control when we upgrade it) as opposed to pip itself where we are only given whatever is available on the user's machine.

@vreuter
Copy link
Contributor Author

vreuter commented Mar 15, 2023

Looks great! Two things missing:

* An added test (demonstrating #225) that is fixed by this PR.

* A comment/consideration on how to possibly make the `setup.cfg` situation better.

Thanks for reviewing @jherland !
The test I add here: 0dac8e8
And the comment I add here: dab88d4

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.

2 participants