list command: add -l/--limit flag, deprecate limit plugin - #6985
Conversation
d312797 to
e1a1cbb
Compare
There was a problem hiding this comment.
🟡 Changes recommended
current SQL join building can produce invalid SQL when sorting by related fields, and limit handling has edge-case bugs (0/negative) plus ordering-sensitive tests.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
PR move list result limiting into beets core with new -l/--limit flag, so users no need limit plugin for simple cap. PR also change sort plumbing so db layer can decide when it safe to push LIMIT into SQL vs apply after slow (python) sort.
Changes:
- Add
-l/--limittobeet list, threadlimitthroughLibrary.items()/albums()down intodbcore._get_results(). - Refactor sort picking into model-level
field_sort()and add sortfield_namestracking to choose SQL vs post-sort limiting. - Deprecate
limitplugin and update docs/changelog/tests.
File summaries
| File | Description |
|---|---|
| test/ui/commands/test_list.py | Add coverage for -l limit and flex sort; adjust existing assertions for multiple items. |
| test/dbcore/test_sort.py | Add sort coverage for related album field (artpath) and adjust test path normalization helper. |
| test/dbcore/test_db.py | Update fixture model computed-field API to new getters classproperty. |
| docs/reference/cli.rst | Document -l/--limit in list command usage and description. |
| docs/plugins/limit.rst | Mark limit plugin deprecated in favor of beet ls -l. |
| docs/changelog.rst | Note new list limit flag and plugin deprecation. |
| beetsplug/limit.py | Emit user-facing deprecation notice for LimitPlugin. |
| beets/ui/commands/list.py | Add -l/--limit option and pass limit into library query calls. |
| beets/test/fixtures.py | Update fixture model computed-field API to getters classproperty. |
| beets/library/models.py | Add field_sort() and migrate computed-field getter mapping to getters classproperty. |
| beets/library/library.py | Add limit param to items()/albums() and _fetch(). |
| beets/dbcore/sort.py | Add field_names to sort types; refactor FieldSort field naming for table-qualified fields. |
| beets/dbcore/queryparse.py | Delegate sort construction to model_cls.field_sort(). |
| beets/dbcore/db.py | Add limit support in results + SQL generation, and migrate computed-field getter access to getters. |
| .git-blame-ignore-revs | Add ignore-rev entry for getters refactor commit. |
Review details
- Files reviewed: 15/15 changed files
- Comments generated: 6
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #6985 +/- ##
==========================================
+ Coverage 77.19% 77.24% +0.04%
==========================================
Files 163 163
Lines 21789 21830 +41
Branches 3360 3367 +7
==========================================
+ Hits 16820 16862 +42
Misses 4149 4149
+ Partials 820 819 -1
🚀 New features to boost your workflow:
|
9ddf0c8 to
6c419ff
Compare
There was a problem hiding this comment.
🟡 Changes recommended
grug see 2 real bugs in new sort path (bad isinstance check for SmartArtistSort, and python sorting break for table-qualified fields) that can make sorting wrong or silently skip sort parts.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 15/15 changed files
- Comments generated: 3
- Review effort level: Lite
6c419ff to
2f51977
Compare
|
Thanks for adding this....I was never a fan of |
There was a problem hiding this comment.
🟡 Changes recommended
grug see 2 correctness bugs: field_sort() has dead isinstance check and can generate ambiguous SQL ORDER BY with joins, and slow-query + slow-sort still apply order-sensitive slow query before sort (can re-break old <N behavior).
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
beets/library/models.py:123
- grug see bug in field_sort.
sort_clsis class from_sorts, soisinstance(sort_cls, sort.SmartArtistSort)always false, smart-artist field swap never run. also param namecase_sensitiveis lie: caller passcase_insensitive, and this value go straight into Sort ascase_insensitive. last, when SQL add relation join for sorting by other table field, shared field likeyearcan become ambiguous unless qualified (Item/Album share many fields). grug want simple and correct: useissubclass, rename param, and qualify shared fields with main table name.
def field_sort(
cls, field: str, is_ascending: bool, case_sensitive: bool
) -> FieldSort:
if sort_cls := cls._sorts.get(field):
if isinstance(sort_cls, sort.SmartArtistSort):
- Files reviewed: 15/15 changed files
- Comments generated: 1
- Review effort level: Lite
904e127 to
08b0ca7
Compare
|
Removed the commit which cached |
There was a problem hiding this comment.
🟡 Changes recommended
db layer can still apply SQL LIMIT before slow-query filtering, so -l/--limit can return fewer matches than requested for flex/computed-field queries.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
beets/dbcore/db.py:1424
- grug see limit push into SQL even when query is slow (like flex attr filter). then slow query match happen after SQL, so
-lcan return fewer row than asked. grug want: only push limit into SQL when query fully fast; else apply limit after python match/sort. also reject negative limit here, not just in list cmd.
sql_limit = flex_limit = None
if limit is not None:
if sort.field_names - model_cls.all_db_fields:
# sorting by at least one flexible attr.
# Limit will be applied after slow field sort.
flex_limit = limit
- Files reviewed: 12/12 changed files
- Comments generated: 3
- Review effort level: Lite
9b86730 to
155f2ac
Compare
There was a problem hiding this comment.
🟡 Changes recommended
tests/docs and DB limit path have concrete correctness/perf issues that should be fixed before merge.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (1)
test/ui/commands/test_list.py:18
- same Path-vs-str problem for
another_itemsetup. pass str viaos.fspathso Item path type stay consistent (bytes in db).
self.another_item = _common.item(
path=self.lib_path / "another/path", flex=2
)
- Files reviewed: 12/12 changed files
- Comments generated: 3
- Review effort level: Lite
155f2ac to
971f2bd
Compare
971f2bd to
bb77a1f
Compare
Closes #5076
Supersedes #6690
What changed
-l/--limitflag to thelistcommand, so result limiting now lives inbeetscore instead of thelimitplugin.limitsupport through the main query path:beets.ui.commands.list->Library.items()/Library.albums()->dbcore._get_results().field_sort()logic, which also improves sorting for related database fields.LimitPluginand updated docs/changelog to point users tobeet ls -l <number>.Architecture impact
listcommand flow, making it a first-class CLI capability.LIMITcan be pushed into SQL or must be applied after slow sorting.High-level outcome
listresults.listnow works correctly withlimiteven when sorting by flexible attributes or related fields.limitplugin is being phased out in favor of a smaller, more integrated command path.modify,writeandupdate.