-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Simplify PackageFinder best candidate API some more #6787
Conversation
5c4e738
to
5952a38
Compare
I must admit I'm getting kind of confused in the multiple refactors and the new It might help to write down how it currently works and where we want to go ? |
Agreed - with all the various refactorings going on at the moment, I think this is a great opportunity to create additional internal documentation explaining how the various utility classes we have work. The old classes weren't well documented, but people had over time gained a rough feeling for how things hung together. Significant refactoring without adding docs loses that implicit knowledge, so better if we can capture some details in writing while they are still fresh. |
For now, where would you like me to document those things — in the comments to this PR or to make a separate documentation PR? These docs would only be for pip maintainers (us) and contributors, as they would document the code and not the public API. Before this refactoring started, the various responsibilities were all handled by one giant PackageFinder class. Now distinct stages of the process are handled by different classes, which makes certain things easier like testing, reasoning about and adding new features to individual stages (e.g. yanked files and preferring hash matches), and knowing which options affect which stages. |
I'd go for comment blocks in the code (or if you get really verbose, I'd assume it's easier to include in this PR while the details are fresh in your mind (these are internal usage notes, so polishing the wording isn't necessary), but it's up to you how you prefer to organise the work - if you find it easier to do as a separate PR, I'm fine with that. |
Internal Documentation. \o/ Here's how I'd planned to structure it while working on the overall architecture docs, at PyCon 2019:
|
I'll be happy to initiate the skeleton in a PR for the above -- I think I already have some this stuff written. If no one thinks that has major issues (it's something we can add to incrementally and then require updating on major refactors), I'll file the PR. |
@pradyunsg That sounds really nice - but more than I'm talking about here, which is really just "capture the insights that resulted in the current refactoring, so that people who had a feel for the old layout can find their way round the new layout (and ideally, people who didn't know the old layout have a head start understanding the current one)". |
@pfmoore yep yep -- that's the kind of content I imagined the dedicated pages would contain. 🙈 |
My preference would be if it's something I can work on / write up now rather than having to wait for an architecture document for all of pip to be written, reviewed, and merged. (I already see the scope increasing quite a bit in the few hours since the initial request.) |
@cjerdonek would the following work for you: add a docs/html/development/architecture/ folder and a file named whatever you want, with whatever content you deem necessary (and I'll be happy to do the rest in a follow-up PR after that. |
@cjerdonek +1 from me. Someone can move the information later if they want to make it more formal. And I apologise if it sounds like scope creep. I was only ever intending to support @xavfernandez request - not to ask for anything more than that. |
That would be okay, thanks.
And yes, understood, @pfmoore. I appreciate it. |
f2ddd7a
to
23fd624
Compare
Okay, I was finally able to finish drafting the architecture document / section for I also addressed @chrahunt's review comment on the code portion (which was to add an additional assertion to parallel the one that @xavfernandez had requested earlier). |
23fd624
to
9de34e3
Compare
* Rename FoundCandidates to BestCandidateResult. * Rename CandidateEvaluator's make_found_candidates() to compute_best_candidate(). * Rename CandidateEvaluator's get_best_candidate() to sort_best_candidate(). * Rename PackageFinder's find_candidates() to find_best_candidate().
9de34e3
to
8db3944
Compare
PR updated. I moved the architecture section to a separate file as requested. |
Thanks for the documentation! It seems we got a lot of work to do in |
Hi, @atugushev! Most of this documentation is of what was there before. The code changes in the PR are mostly just some renames that may not even affect you. |
Happy to merge this. |
@cjerdonek you were right, that was easy 👍 |
Great! |
The `get_best_candidate` has been renamed to `compute_best_candidate`, which now returns an instance of `BestCandidateResult`. See pypa/pip#6787
This PR makes a few minor changes to
PackageFinder
's "best candidate" API to simplify things and improve the readability / make it easier to understand. Specifically, the PR does the following--Rename
PackageFinder.find_candidates()
toPackageFinder.find_best_candidate()
because that is what the method is used for. There is also already aPackageFinder.find_all_candidates()
method, so the rename makes things less confusing since there are now no longer two methodsfind_all_candidates()
andfind_candidates()
with similar-sounding names.Change the type of the return value of
PackageFinder.find_best_candidate()
fromFoundCandidates
toBestCandidateResult
(by renamingFoundCandidates
toBestCandidateResult
), since the purpose of this class is to expose the best candidate.Compute the
best_candidate
and pass it to theBestCandidateResult
constructor instead of computing the best candidate lazily. The best candidate is now exposed as abest_candidate
attribute of theBestCandidateResult
object instead of viaFoundCandidates.get_best()
. This is better for a couple reasons: (1) the applicable candidates and best candidate are now both handled the same way (namely by passing them in when instantiating instead of computing lazily), and (2) we no longer need to pass the wholeCandidateEvaluator
object into theFoundCandidates
object, eliminating a bit of circularity that was of concern before. This completes the process of convertingFoundCandidates
to a simple data container class, so that it doesn't actually compute anything on its own.Rename the current
CandidateEvaluator.get_best_candidate()
toCandidateEvaluator.sort_best_candidate()
because this is the method that gets the best candidate by sorting, and add a newCandidateEvaluator.compute_best_candidate()
method responsible for filtering applicable candidates, callingsort_best_candidate()
, and constructing theBestCandidateResult
object.Adds to the
BestCandidateResult
constructor the assertion that @xavfernandez requested here: Simplify FoundCandidates #6684 (comment)