Add documentation for NotQuery, cleanup

* Add changelog and query.rst documentation entries for the usage of negated
queries.
* Cleanup NotQuery class as suggested during code review (PEP conforming
docstring, clarification on empty clause match behaviour).
This commit is contained in:
Diego Moreda 2015-11-20 18:06:22 +01:00
parent 40bfed756b
commit 51bf6a1c9f
4 changed files with 37 additions and 4 deletions

View file

@ -449,7 +449,8 @@ class OrQuery(MutableCollectionQuery):
class NotQuery(Query):
"""A query that matches the negation of its `subquery`, as a shorcut for
performing `not(subquery)` without using regular expressions."""
performing `not(subquery)` without using regular expressions.
"""
def __init__(self, subquery):
self.subquery = subquery
@ -458,7 +459,8 @@ class NotQuery(Query):
if clause:
return 'not ({0})'.format(clause), subvals
else:
# special case for RegexpQuery, (None, ())
# If there is no clause, there is nothing to negate. All the logic
# is handled by match() for slow queries.
return clause, subvals
def match(self, item):

View file

@ -20,6 +20,10 @@ New:
:doc:`/plugins/discogs` also adopts the same setting.
* :doc:`/plugins/embyupdate`: A plugin to trigger a library refresh on a
`Emby Server`_ if database changed.
* Queries can now use "not" logic: if you prepend a query term with "-" or
"^", items or albums matching that term will be excluded from the results.
For example, ``beet ls foo ^artist:bar`` will get all the items matching
`foo` but whose artist do not match `bar`. See :ref:`not_query`. :bug:`819`
For developers:

View file

@ -181,6 +181,35 @@ Find all items with a file modification time between 2008-12-01 and
$ beet ls 'mtime:2008-12-01..2008-12-02'
.. _not_query:
Query Term Negation
-------------------
Query terms can also be negated, acting like a Boolean "not", by prepending
them with ``-`` or ``^``. This has the effect of returning all the items that
do **not** match the query term. For example, this command::
$ beet list ^love
matches all the songs in the library that do not have "love" in any of their
fields.
Negation can be combined with the rest of the query mechanisms, allowing to
negate specific fields, regular expressions, etc. For example, this command::
$ beet list -a artist:dylan ^year:1980..1990 "^album::the(y)?"
matches all the albums with an artist containing "dylan", but excluding those
released on the eighties and those that have "the" or "they" on the title.
Note that the ``-`` character is treated by most shells as a reserved character
for passing arguments, and as such needs to be escaped if using it for query
negation. In most UNIX derivatives shells, using a double dash ``--``
(indicating that everything after that point should not be treated as
arguments) before the query terms should prevent conflicts, such as::
$ beet list -a -- artist:dylan -year:1980..1990 "-album::the(y)?"
.. _pathquery:

View file

@ -782,8 +782,6 @@ class NotQueryTest(DummyDataTestCase):
"""Test `query.NotQuery` against the dummy data:
- `test_type_xxx`: tests for the negation of a particular XxxQuery class.
- `test_get_yyy`: tests on query strings (similar to `GetTest`)
TODO: add test_type_bytes, for ByteQuery?
"""
def assertNegationProperties(self, q):
"""Given a Query `q`, assert that: