Being more careful about truthiness and catching negative values (they could be supported, but it's probably not intuitive).
Moving command into single plugin as suggested.
Fixing linter objections.
@@ -21,11 +21,10 @@ from itertools import islice
def lslimit(lib, opts, args):
"""Query command with head/tail"""
- head = opts.head
- tail = opts.tail
-
- if head and tail:
- raise RuntimeError("Only use one of --head and --tail")
+ if (opts.head is not None) and (opts.tail is not None):
+ raise ValueError("Only use one of --head and --tail")
+ if (opts.head or opts.tail or 0) < 0:
+ raise ValueError("Limit value must be non-negative")
query = decargs(args)
if opts.album:
@@ -33,10 +32,10 @@ def lslimit(lib, opts, args):
else:
objs = lib.items(query)
- if head:
- objs = islice(objs, head)
- elif tail:
- objs = deque(objs, tail)
+ if opts.head is not None:
+ objs = islice(objs, opts.head)
+ elif opts.tail is not None:
+ objs = deque(objs, opts.tail)
for obj in objs:
print_(format(obj))
@@ -65,30 +64,31 @@ lslimit_cmd.parser.add_all_common_options()
lslimit_cmd.func = lslimit
-class LsLimitPlugin(BeetsPlugin):
+class LimitPlugin(BeetsPlugin):
+ """Query limit functionality via command and query prefix
+ """
+
def commands(self):
return [lslimit_cmd]
-
-class HeadPlugin(BeetsPlugin):
- """Head of an arbitrary query.
-
- This allows a user to limit the results of any query to the first
- `pattern` rows. Example usage: return first 10 tracks `beet ls '<10'`.
- """
-
def queries(self):
class HeadQuery(FieldQuery):
- """Singleton query implementation that tracks result count."""
+ """This inner class pattern allows the query to track state
+ """
n = 0
- include = True
+ N = None
+
@classmethod
def value_match(cls, pattern, value):
+
+ if cls.N is None:
+ cls.N = int(pattern)
+ if cls.N < 0:
+ raise ValueError("Limit value must be non-negative")
+
cls.n += 1
- if cls.include:
- cls.include = cls.n <= int(pattern)
- return cls.include
+ return cls.n <= cls.N
return {
"<": HeadQuery
