Add `py.typed` marker file to support PEP 561 typing
This PR adds a `py.typed` marker file to the package directory to
indicate that the package includes inline type hints and is PEP 561
compliant.
## Description
This might be a quick one, depending on how you feel about it... It
allows you to pickle DB model objects. I don't think this is used
directly in Beets, but it might be useful in general. For instance, we
encountered an issue where we wanted to quickly pickle an Item or Album.
This sometimes worked and other times failed, which seemed quite
inconsistent.
Some DB model methods and properties have the side effect of attaching
an SQLite connection to self (._db), which prevents serialization. The
fix is quite straightforward, so I thought we might want to integrate
this into beets directly.
## To Do
- [x] Changelog
- [x] Tests
In order to include the table name for fields in this query, use the
`field_query` method.
Since `AnyFieldQuery` is just an `OrQuery` under the hood, remove it and
construct `OrQuery` explicitly instead.
Unify query creation logic from
- queryparse.py:construct_query_part,
- Model.field_query,
- DefaultTemplateFunctions._tmpl_unique
to a single implementation under `LibModel.field_query` class method.
This method should be used for query resolution for model fields.
In order to include the table name for fields in this query, use the
`field_query` method.
Since `AnyFieldQuery` is just an `OrQuery` under the hood, remove it and
construct `OrQuery` explicitly instead.
Unify query creation logic from
- queryparse.py:construct_query_part,
- Model.field_query,
- DefaultTemplateFunctions._tmpl_unique
to a single implementation under `LibModel.field_query` class method.
This method should be used for query resolution for model (flex)fields.
Allow filtering item attributes in album queries and vice versa by
merging `flex_attrs` from Album and Item together as `all_flex_attrs`.
This field is only used for filtering and is discarded after.
Remove 'NamedQuery' since it is not being used by any queries any more.
This simplifies query parsing logic in 'queryparse.py'. We know that
this logic can only receive 'FieldQuery' thus I adjusted types and
removed the logic that handles other cases.
Effectively, this means that the query parsing logic does not any more
care whether the query is named by the corresponding DB field. Instead,
queries like 'SingletonQuery' and 'PlaylistQuery' are responsible for
translating 'singleton' and 'playlist' to the underlying DB filters.
External Python packages interfacing beets may want to use an in-memory
beets library instance for testing beets-related code.
The `TestHelper` class is very helpful for this purpose.
Previously `TestHelper` was located in the `test/` directory.
Now it is part of `beets` itself (`beets.test.helper.TestHelper`) and
can be easily imported.
- Add NamedQuery abstract class to be able to express the expectation
that a query should be such a query (and have a specific constructor
signature) in construct_query_part
- slightly (and probably completely irrelevantly) improve Query.__hash__
- also, sprinkle some ABC/abstractmethod around to clarify things
- renamed test test_format_fixed_field to test_format_fixed_field_string
- test_format_fixed_field_string not tests `field_two` with string values
- added new test_format_fixed_field_integer to test field `field_one` as INTEGER
- added new test_format_fixed_field_integer_normalized to test rounding float values
Prevents reloading a model from the database when it hasn't changed.
Now we're back to almost the same speed as before the addition of album
field fallbacks.
When using pytest's test collector, any class with a name starting with
Test is collected. If it notices that the class has an `__init__` member
then it skips it with a warning since it's probably a false positive.
This isn't a big deal, but we can avoid warnings like this:
test/test_ui_importer.py:33
beets/test/test_ui_importer.py:33: PytestCollectionWarning: cannot collect test class 'TestTerminalImportSession' because it has a __init__ constructor
class TestTerminalImportSession(TerminalImportSession):
simply by renaming TestX to XFixture.
This was a vestige from when we used to need the unittest2 library for pre-2.7
compatibility. Now that we require Python 2.7, we aren't using that library
and this indirection wasn't doing any good.
This reverts commit 9c41c39913.
That commit used byte strings for the `if __name__ == '__main__'` pattern,
which was necessary when we were doing unicode_literals. But it is wrong on
Python 3, and now that we're liberated from unicode_literals, we need to go
back to native strings for this comparison.