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
Sort packages alphabetically inside each category #5965
Conversation
When installing any package, sort all package names alphabetically inside the category, for easier reading. Unsure if this is the best place or way to implement. Small prototype to add to discussion in pypa#5964 Tests: before patch: ``` AssertionError: assert ['atomicwrite...ama', 'build'] == ['atomicwrite...', 'colorama'] At index 1 diff: 'colorama' != 'build' Full diff: - ['atomicwrites', 'build', 'colorama'] ? --------- + ['atomicwrites', 'colorama', 'build'] ? +++++++++ ``` after patch: pass.
assert c.returncode == 0 | ||
assert "build" in p.pipfile["packages"] | ||
assert list(p.pipfile["packages"].keys()) == ["atomicwrites", "build", "colorama"] | ||
|
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.
For this test I just chose three arbitrary packages that are already used inside pipenv's own Pipfile.
I would recommend making this a behavior driven by a [pipenv] directive in the Pipfile -- the reason why is because then its opt-in/opt-out at the project level if the directive is in the Pipfile; it will sort the packages alphabetically for the project whenever a change is made, install/uninstall/update/upgrade -- but otherwise it will continue to behave as is for folks that don't want this behavior. |
Hello, thank you for the feedback. Implementing this as a config setting/directive sounds quite reasonable. The [pipenv] section appears to be the same place that stores settings such as
Does that sound like a good way to do it? Let me know if there is a particular setting name you want. Perhaps |
Sort packages alphabetically inside each category. Currently runs on `install`.
Which commands should we make this run on? Perhaps |
Thanks @daveschaefer -- some thoughts:
That makes sense, just calling out: upgrade and update (update uses upgrade, but I forget if it touches Pipfile directly so worth taking a look). |
`sort_pipfile` , as requested in pypa#5965
using sorting directive
Thank you. I have updated the code to use Once this is implemented, is there a place in the docs that I can or should update to mention this new directive? |
@@ -243,3 +243,54 @@ def test_uninstall_multiple_categories(pipenv_instance_private_pypi): | |||
|
|||
assert "six" not in p.lockfile.get("prereq", {}) | |||
assert "six" not in p.lockfile["default"] | |||
|
|||
|
|||
@pytest.mark.uninstall |
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 see some of the uninstall tests are marked with @pytest.mark.install
, and some are not. Is this based on whether the test calls install
during the test? Something else? Let me know if you want me to mark these two tests with @pytest.mark.install
also.
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.
Is this based on whether the test calls install during the test?
Yeah, the test markers needs some separate TLC -- but that is the idea.
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.
Thank you. I have marked these tests with @pytest.mark.install
.
I saw there are some other tests in test_uninstall.py
that call install
, but don't have the mark.
Since I am here editing the file, I marked those tests as well.
I can drop the commit if that's not helpful.
We should include the documentation in this PR -- let's see ... probably this is the closest section that documents the Pipfile: https://pipenv.pypa.io/en/latest/pipfile/ Any TLC you put into the docs would be appreciated. |
Based on notes from existing code and release docs Note that `keep_outdated` has been discontinued, so no docs added for it.
Thank you. I added a section to Feedback on any of the docs or wording is welcome. I may not have time immediately, but I will see if I can add tests and code for sorting on |
since the test calls `install` while running. as discussed in pypa#5965
Since the goal of the mark is to note which tests use it.
Currently these fail. Will be fixed shortly in the next patch. Pipfiles can contain different formats for package specifications. Current default behaivour is to sort packages into groups - all string values will be sorted first, followed by all dictionary values. e.g. ``` aa = "*" bb = "*" cc = "*" aaa = {version = "*"} bbb = {version = "*"} ccc = {version = "*"} ``` This will have to be fixed.
This is not as clean as only working with dicts. `p[category]`, the parsed pipfile category, is already of type `tomlkit.items.Table` when it is passed to `_sort_category()`. Currently this is only constructing the table right before data is sent to `write_tom()`.
So, the good news: the The bad news: sorting categories and passing a dict to What I mean is: If all of the package entries use strings like
I have added test cases to Currently I have solved this by implementing a private Let me know what you think. If there is a better way to solve this, I am all ears. |
Is it helpful if I annotate functions with argument types and return types? |
@@ -0,0 +1,52 @@ | |||
import pytest |
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 didn't see any existing integration tests for the upgrade
command, so I created this file.
I am attempting to match the pattern of test format from other tests.
Let me know if you want me to put these somewhere else.
def _sort_category(self, category): | ||
# toml tables won't maintain sorted dictionary order | ||
# so construct the table in the order that we need | ||
sorted_category = dict(sorted(category.items())) |
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 think this will definitely work, but I am wondering if it would be more efficient to move into the loop and not cast to a dict so like:
for key, value in sorted(category.items():
Correct me if that won't work or there is an issue with it, but thats my last bit of feedback. I'll see if @oz123 can review this too but I want to get this merged into the release for this month.
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.
Thank you very much! That is very kind.
Are there other test cases I should consider or other tests I can add?
I noticed some projects that have # comments
on some lines of their Pipfiles. When I add a comment on both string-type lines and dictionary-type lines those are both sorted correctly.
Are there other values or types that can go on a line?
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 am wondering if it would be more efficient to move into the loop and not cast to a dict so like:
for key, value in sorted(category.items():
Thanks! I created a PR to do that - https://github.com/pypa/pipenv/pull/5990/files
Is it helpful if I create a news fragment .rst
? Or is that no longer useful since the PR has been merged?
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 new change is trivial and the docs change you did is good -- we just need to figure out why the docs don't seem to be getting published at some point during the new releases.
Add a new
[pipenv]
directive to sort package names alphabetically inside the category, for easier reading.install
uninstall
upgrade
update
?--
Unsure if this is the best place or way to implement. Small prototype to add to discussion in #5964 .
Tests:
before patch:
after patch: pass.
The checklist
news/
directory to describe this fix with the extension.bugfix.rst
,.feature.rst
,.behavior.rst
,.doc.rst
..vendor.rst
. or.trivial.rst
(this will appear in the release changelog). Use semantic line breaks and name the file after the issue number or the PR #.