Skip to content

Commit

Permalink
In make_reader(), use storage.make_search() instead of Search (hardco…
Browse files Browse the repository at this point in the history
…ded).

For #325.
  • Loading branch information
lemon24 committed Nov 6, 2023
1 parent 27588d1 commit 67c73ad
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 22 deletions.
22 changes: 8 additions & 14 deletions docs/internal.rst
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Storage
-------

.. autoattribute:: reader.Reader._storage

.. autoattribute:: reader.Reader._search

.. module:: reader._types
:noindex:
Expand All @@ -127,6 +127,13 @@ Storage
:members:
:special-members: __enter__, __exit__

.. autoclass:: BoundSearchStorageType()
:members:
:show-inheritance:

.. autoclass:: SearchType()
:members:


Data objects
~~~~~~~~~~~~
Expand All @@ -151,19 +158,6 @@ Type aliases
.. autodata:: TristateFilter


Search
------

.. autoattribute:: reader.Reader._search


.. module:: reader._types
:noindex:

.. autoclass:: SearchType
:members:


Recipes
-------

Expand Down
6 changes: 6 additions & 0 deletions src/reader/_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from ._types import FeedFilter
from ._types import FeedForUpdate
from ._types import FeedUpdateIntent
from ._types import SearchType
from ._types import TagFilter
from ._utils import chunks
from ._utils import exactly_one
Expand Down Expand Up @@ -457,6 +458,11 @@ def __exit__(self, *_: Any) -> None:
def close(self) -> None:
self.factory.close()

def make_search(self) -> SearchType:
from ._search import Search

return Search(self)

@wrap_exceptions(StorageError)
def add_feed(self, url: str, added: datetime) -> None:
with self.get_db() as db:
Expand Down
27 changes: 26 additions & 1 deletion src/reader/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from typing import NamedTuple
from typing import overload
from typing import Protocol
from typing import runtime_checkable
from typing import TYPE_CHECKING
from typing import TypeVar
from typing import Union
Expand Down Expand Up @@ -670,6 +671,7 @@ class StorageType(Protocol): # pragma: no cover
are implemented at the storage level; specifically:
* The storage can be used directly, without :meth:`__enter__`\ing it.
There is no guarantee :meth:`close` will be called at the end.
* The storage can be reused after :meth:`__exit__` / :meth:`close`.
* The storage can be used from multiple threads,
either directly, or as a context manager.
Expand Down Expand Up @@ -1074,9 +1076,23 @@ def set_entry_recent_sort(
"""


@runtime_checkable
class BoundSearchStorageType(StorageType, Protocol):

"""A storage that can create a storage-bound search provider."""

def make_search(self) -> SearchType:
"""Create a search provider.
Returns:
A search provider.
"""


class SearchType(Protocol): # pragma: no cover

"""Search DAO.
"""Search DAO protocol.
Any method can raise :exc:`.SearchError`.
Expand All @@ -1101,6 +1117,15 @@ def is_enabled(self) -> bool:
"""

def check_dependencies(self) -> None:
"""Raise :exc:`.SearchError` if any required dependencies are missing.
.. admonition:: Unstable
This method may be removed in the future.
"""

def search_entries(
self,
query: str,
Expand Down
10 changes: 6 additions & 4 deletions src/reader/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
from ._parser import default_parser
from ._parser.requests import DEFAULT_TIMEOUT
from ._parser.requests import TimeoutType
from ._search import Search
from ._storage import Storage
from ._types import BoundSearchStorageType
from ._types import DEFAULT_RESERVED_NAME_SCHEME
from ._types import entry_data_from_obj
from ._types import EntryData
Expand Down Expand Up @@ -100,7 +100,7 @@ def make_reader(
session_timeout: TimeoutType = DEFAULT_TIMEOUT,
reserved_name_scheme: Mapping[str, str] = DEFAULT_RESERVED_NAME_SCHEME,
search_enabled: bool | None | Literal['auto'] = 'auto',
_storage: Storage | None = None,
_storage: StorageType | None = None,
_storage_factory: Any = None,
) -> Reader:
"""Create a new :class:`Reader`.
Expand Down Expand Up @@ -258,11 +258,13 @@ def make_reader(
# See this comment for details on how it should evolve:
# https://github.com/lemon24/reader/issues/168#issuecomment-642002049

storage = _storage or Storage(url, factory=_storage_factory)
storage: StorageType = _storage or Storage(url, factory=_storage_factory)

try:
# For now, we're using a storage-bound search provider.
search = Search(storage)
if not isinstance(storage, BoundSearchStorageType): # pragma: no cover
raise TypeError("storage must have a make_search factory")
search = storage.make_search()

if search_enabled is True:
search.check_dependencies()
Expand Down
6 changes: 3 additions & 3 deletions tests/test_reader_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ def strip_html(*args, **kwargs):
return Search.strip_html(*args, **kwargs)

# TODO: remove monkeypatching when make_reader() gets a search_cls argument
monkeypatch.setattr('reader.core.Search', MySearch)
monkeypatch.setattr('reader.core.Storage.make_search', lambda s: MySearch(s))

reader = make_reader(db_path)
reader._parser = parser = Parser()
Expand Down Expand Up @@ -870,7 +870,7 @@ def strip_html(*args, **kwargs):
return Search.strip_html(*args, **kwargs)

# TODO: remove monkeypatching when make_reader() gets a search_cls argument
monkeypatch.setattr('reader.core.Search', MySearch)
monkeypatch.setattr('reader.core.Storage.make_search', lambda s: MySearch(s))

reader = make_reader(db_path)
try:
Expand Down Expand Up @@ -1024,7 +1024,7 @@ def strip_html(*args, **kwargs):
return Search.strip_html(*args, **kwargs)

# TODO: remove monkeypatching when make_reader() gets a search_cls argument
monkeypatch.setattr('reader.core.Search', MySearch)
monkeypatch.setattr('reader.core.Storage.make_search', lambda s: MySearch(s))

reader = make_reader(db_path)
try:
Expand Down

0 comments on commit 67c73ad

Please sign in to comment.