diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3bf6d56b..c2c3571c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ exclude: ^src/reader/_vendor/.*$ repos: - repo: https://github.com/pycqa/isort - rev: 7.0.0 + rev: 8.0.1 hooks: - id: isort @@ -14,7 +14,7 @@ repos: args: ["--py311-plus"] - repo: https://github.com/psf/black-pre-commit-mirror - rev: 25.12.0 + rev: 26.3.1 hooks: - id: black args: ["-S"] diff --git a/docs/conf.py b/docs/conf.py index 20554a49..6731bfcb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -6,7 +6,6 @@ import packaging.version from setuptools.config.pyprojecttoml import read_configuration - sys.path.insert(0, os.path.abspath('../src')) # mock some things "by hand", so we can import reader below without any dependencies @@ -25,7 +24,6 @@ import reader - extensions = [ 'sphinx_rtd_theme', 'sphinx.ext.autodoc', diff --git a/examples/podcast.py b/examples/podcast.py index 1591ee1a..097507c3 100644 --- a/examples/podcast.py +++ b/examples/podcast.py @@ -14,7 +14,6 @@ from reader import make_reader - feed_url = "http://www.hellointernet.fm/podcast?format=rss" podcasts_dir = "podcasts" diff --git a/scripts/bench.py b/scripts/bench.py index 16e2cd7d..47463973 100644 --- a/scripts/bench.py +++ b/scripts/bench.py @@ -14,7 +14,6 @@ import click - root_dir = os.path.dirname(__file__) sys.path.insert(0, os.path.join(root_dir, '../src')) sys.path.insert(0, os.path.join(root_dir, '../tests')) diff --git a/scripts/debug_storage_stats.py b/scripts/debug_storage_stats.py index fa28a5cd..c0867dd1 100644 --- a/scripts/debug_storage_stats.py +++ b/scripts/debug_storage_stats.py @@ -29,7 +29,6 @@ import numpy as np from tabulate import tabulate - # assumes dict()s are ordered value_funcs = { diff --git a/scripts/entry_dedupe_backtest.py b/scripts/entry_dedupe_backtest.py index 68671fe4..87776011 100644 --- a/scripts/entry_dedupe_backtest.py +++ b/scripts/entry_dedupe_backtest.py @@ -21,7 +21,6 @@ from reader import make_reader from reader.plugins import entry_dedupe - DB_ARCHIVE = "_backups/reader.sqlite.2025-10-04.gz" file = sys.argv[1] diff --git a/scripts/jscontrols.py b/scripts/jscontrols.py index 788f7fdf..ddd212d7 100644 --- a/scripts/jscontrols.py +++ b/scripts/jscontrols.py @@ -8,14 +8,12 @@ from flask import redirect from flask import request - root_dir = os.path.dirname(__file__) sys.path.insert(0, os.path.join(root_dir, '../src')) from reader._app.api_thing import APIError from reader._app.api_thing import APIThing - app = Flask( __name__, template_folder='../src/reader/_app/templates', diff --git a/scripts/vendor_app_stuff.py b/scripts/vendor_app_stuff.py index 63b27c43..0afe9b0b 100644 --- a/scripts/vendor_app_stuff.py +++ b/scripts/vendor_app_stuff.py @@ -3,7 +3,6 @@ import requests - STUFF = { "htmx.org@2.0.8": ["dist/htmx.min.js"], "htmx-ext-response-targets@2.0.4": ["dist/response-targets.min.js"], diff --git a/src/reader/__init__.py b/src/reader/__init__.py index 5c318b14..887bc7a9 100644 --- a/src/reader/__init__.py +++ b/src/reader/__init__.py @@ -93,7 +93,6 @@ ReaderWarning as ReaderWarning, ) - # Constants. USER_AGENT = f'python-reader/{__version__} (+https://github.com/lemon24/reader)' diff --git a/src/reader/__main__.py b/src/reader/__main__.py index bb60a94d..5479c878 100644 --- a/src/reader/__main__.py +++ b/src/reader/__main__.py @@ -1,6 +1,5 @@ import sys - CANNOT_IMPORT = """\ Error: cannot import reader._cli diff --git a/src/reader/_app/__init__.py b/src/reader/_app/__init__.py index d2c00c31..610d9860 100644 --- a/src/reader/_app/__init__.py +++ b/src/reader/_app/__init__.py @@ -38,7 +38,6 @@ from .forms import EntryFilter from .forms import FeedFilter - # for a prototype with tags and search support, see # https://github.com/lemon24/reader/tree/3.21/src/reader/_app/v2 diff --git a/src/reader/_app/ext.py b/src/reader/_app/ext.py index 6747cf6b..6bcf4532 100644 --- a/src/reader/_app/ext.py +++ b/src/reader/_app/ext.py @@ -10,7 +10,6 @@ from reader import make_reader from reader.plugins._loader import PluginLoader - _plugin_loader = PluginLoader('init_app') diff --git a/src/reader/_app/legacy/__init__.py b/src/reader/_app/legacy/__init__.py index 145e7ec6..68fa059b 100644 --- a/src/reader/_app/legacy/__init__.py +++ b/src/reader/_app/legacy/__init__.py @@ -44,7 +44,6 @@ from .api_thing import APIError from .api_thing import APIThing - blueprint = Blueprint( 'reader', __name__, static_folder='static', template_folder='templates' ) diff --git a/src/reader/_app/legacy/wsgi.py b/src/reader/_app/legacy/wsgi.py index f57e4824..f2284d3c 100644 --- a/src/reader/_app/legacy/wsgi.py +++ b/src/reader/_app/legacy/wsgi.py @@ -15,7 +15,6 @@ import reader._app.legacy import reader._cli - config = reader._cli.load_reader_config() app = reader._app.legacy.create_app(config) app.config['TRAP_BAD_REQUEST_ERRORS'] = bool( diff --git a/src/reader/_app/wsgi.py b/src/reader/_app/wsgi.py index 90bc1fe1..2c9d5c94 100644 --- a/src/reader/_app/wsgi.py +++ b/src/reader/_app/wsgi.py @@ -15,7 +15,6 @@ import reader._app import reader._cli - config = reader._cli.load_reader_config() app = reader._app.create_app(config) app.config['TRAP_BAD_REQUEST_ERRORS'] = bool( diff --git a/src/reader/_cli.py b/src/reader/_cli.py index 2924b060..0c7c5ee2 100644 --- a/src/reader/_cli.py +++ b/src/reader/_cli.py @@ -19,7 +19,6 @@ from ._config_utils import load_config_from_context from .plugins._loader import PluginLoader - app_name = reader.__name__ app_dir = click.get_app_dir(app_name) diff --git a/src/reader/_hash_utils.py b/src/reader/_hash_utils.py index 88f4816c..78c0454f 100644 --- a/src/reader/_hash_utils.py +++ b/src/reader/_hash_utils.py @@ -27,7 +27,6 @@ from collections.abc import Collection from typing import Any - # The first byte of the hash contains its version, # to allow upgrading the implementation without changing existing hashes. # (In practice, it's likely we'll just let the hash change and update diff --git a/src/reader/_parser/__init__.py b/src/reader/_parser/__init__.py index 3c52a6ee..e7cb0f0c 100644 --- a/src/reader/_parser/__init__.py +++ b/src/reader/_parser/__init__.py @@ -33,7 +33,6 @@ from .requests import SessionFactory from .requests import TimeoutType - if TYPE_CHECKING: # pragma: no cover from werkzeug.datastructures import RequestCacheControl diff --git a/src/reader/_parser/_http_utils.py b/src/reader/_parser/_http_utils.py index c6bf8934..1ecaf0f3 100644 --- a/src/reader/_parser/_http_utils.py +++ b/src/reader/_parser/_http_utils.py @@ -10,7 +10,6 @@ from werkzeug.datastructures import MIMEAccept from werkzeug.datastructures import ResponseCacheControl - parse_options_header = werkzeug.http.parse_options_header parse_accept_header = werkzeug.http.parse_accept_header parse_date = werkzeug.http.parse_date diff --git a/src/reader/_parser/_lazy.py b/src/reader/_parser/_lazy.py index e73dc3bc..dbd24fca 100644 --- a/src/reader/_parser/_lazy.py +++ b/src/reader/_parser/_lazy.py @@ -36,7 +36,6 @@ from ._url_utils import normalize_url from .requests import SessionFactory - log = logging.getLogger('reader') diff --git a/src/reader/_parser/feedparser.py b/src/reader/_parser/feedparser.py index c56b7291..a1c859be 100644 --- a/src/reader/_parser/feedparser.py +++ b/src/reader/_parser/feedparser.py @@ -20,7 +20,6 @@ from ._http_utils import parse_accept_header from ._http_utils import unparse_accept_header - if os.environ.get('READER_NO_VENDORED_FEEDPARSER', '') not in ('', '0'): import feedparser # type: ignore else: diff --git a/src/reader/_parser/jsonfeed.py b/src/reader/_parser/jsonfeed.py index 35f593c4..1f2db285 100644 --- a/src/reader/_parser/jsonfeed.py +++ b/src/reader/_parser/jsonfeed.py @@ -18,7 +18,6 @@ from ..types import Content from ..types import Enclosure - if TYPE_CHECKING: # pragma: no cover from . import FeedAndEntries from .requests import Headers diff --git a/src/reader/_parser/requests/__init__.py b/src/reader/_parser/requests/__init__.py index a4c069ac..26478cae 100644 --- a/src/reader/_parser/requests/__init__.py +++ b/src/reader/_parser/requests/__init__.py @@ -21,7 +21,6 @@ from ..._utils import lazy_import - if TYPE_CHECKING: # pragma: no cover import requests diff --git a/src/reader/_parser/requests/_lazy.py b/src/reader/_parser/requests/_lazy.py index 2b494c84..85bdeb70 100644 --- a/src/reader/_parser/requests/_lazy.py +++ b/src/reader/_parser/requests/_lazy.py @@ -13,7 +13,6 @@ from . import CachingInfo from . import TimeoutType - if TYPE_CHECKING: # pragma: no cover from . import Headers from . import RequestHook diff --git a/src/reader/_plugins/legacy/enclosure_tags.py b/src/reader/_plugins/legacy/enclosure_tags.py index 6d66e70b..19e8f529 100644 --- a/src/reader/_plugins/legacy/enclosure_tags.py +++ b/src/reader/_plugins/legacy/enclosure_tags.py @@ -40,7 +40,6 @@ from flask import url_for from jinja2.filters import do_striptags as striptags - blueprint = Blueprint('enclosure_tags', __name__) diff --git a/src/reader/_plugins/legacy/preview_feed_list.py b/src/reader/_plugins/legacy/preview_feed_list.py index b9bcbe7c..495802f9 100644 --- a/src/reader/_plugins/legacy/preview_feed_list.py +++ b/src/reader/_plugins/legacy/preview_feed_list.py @@ -36,7 +36,6 @@ from reader._app.legacy import get_reader from reader._app.legacy import got_preview_parse_error - blueprint = Blueprint('preview_feed_list', __name__, template_folder='templates') diff --git a/src/reader/_plugins/legacy/share.py b/src/reader/_plugins/legacy/share.py index cc25caad..1b225575 100644 --- a/src/reader/_plugins/legacy/share.py +++ b/src/reader/_plugins/legacy/share.py @@ -14,7 +14,6 @@ from urllib.parse import quote from urllib.parse import urlparse - TEMPLATES = { 'Twitter': "https://twitter.com/share?text={title}&url={url}", 'HN': "https://news.ycombinator.com/submitlink?u={url}&t={title}", diff --git a/src/reader/_plugins/sqlite_releases.py b/src/reader/_plugins/sqlite_releases.py index 799d01d5..36b36eb0 100644 --- a/src/reader/_plugins/sqlite_releases.py +++ b/src/reader/_plugins/sqlite_releases.py @@ -35,7 +35,6 @@ from reader._types import EntryData from reader._types import FeedData - warnings.filterwarnings( 'ignore', message='No parser was explicitly specified', diff --git a/src/reader/_storage/__init__.py b/src/reader/_storage/__init__.py index b34d42da..56696b3e 100644 --- a/src/reader/_storage/__init__.py +++ b/src/reader/_storage/__init__.py @@ -8,7 +8,6 @@ from ._feeds import FeedsMixin from ._tags import TagsMixin - # Row value support was added in 3.15. # pragma_*() tabled-valued functions were added in 3.16. # last_insert_rowid() support for FTS5 was added in 3.18. diff --git a/src/reader/_storage/_base.py b/src/reader/_storage/_base.py index ecbffa57..d91e1a1b 100644 --- a/src/reader/_storage/_base.py +++ b/src/reader/_storage/_base.py @@ -15,7 +15,6 @@ from ._sql_utils import paginated_query from ._sql_utils import Query - APPLICATION_ID = b'read' _T = TypeVar('_T') diff --git a/src/reader/_storage/_changes.py b/src/reader/_storage/_changes.py index 41a40617..ab8019f0 100644 --- a/src/reader/_storage/_changes.py +++ b/src/reader/_storage/_changes.py @@ -12,7 +12,6 @@ from ._sql_utils import Query from ._sqlite_utils import ddl_transaction - if TYPE_CHECKING: # pragma: no cover from ._base import StorageBase @@ -41,12 +40,10 @@ def _enable(cls, db: sqlite3.Connection) -> None: for object in objects.values(): object.create(db) db.execute("UPDATE entries SET sequence = randomblob(16)") - db.execute( - """ + db.execute(""" INSERT INTO changes SELECT sequence, feed, id, '', 1 FROM entries - """ - ) + """) @wrap_exceptions() def disable(self) -> None: diff --git a/src/reader/_storage/_entries.py b/src/reader/_storage/_entries.py index c5fff1ca..a9b1fb9b 100644 --- a/src/reader/_storage/_entries.py +++ b/src/reader/_storage/_entries.py @@ -37,7 +37,6 @@ from ._tags import entry_tags_filter from ._tags import feed_tags_filter - if TYPE_CHECKING: # pragma: no cover from ._base import StorageBase else: @@ -404,10 +403,7 @@ def set_entry_recent_sort( def get_entries_query( filter: EntryFilter, sort: EntrySort ) -> tuple[Query, dict[str, Any]]: - query = ( - Query() - .SELECT( - *""" + query = Query().SELECT(*""" entries.feed feeds.updated feeds.title @@ -441,11 +437,7 @@ def get_entries_query( entries.last_updated entries.original_feed entries.sequence - """.split() - ) - .FROM("entries") - .JOIN("feeds ON feeds.url = entries.feed") - ) + """.split()).FROM("entries").JOIN("feeds ON feeds.url = entries.feed") context = entry_filter(query, filter) ENTRIES_SORT[sort](query) return query, context @@ -540,13 +532,11 @@ def entry_filter( add(TRISTATE_FILTER_TO_SQL[important].format(expr='entries.important')) if has_enclosures is not None: - add( - f""" + add(f""" {'NOT' if has_enclosures else ''} (json_array_length(entries.enclosures) IS NULL OR json_array_length(entries.enclosures) = 0) - """ - ) + """) if source_url: add("json_extract(entries.source, '$.url') = :source_url") diff --git a/src/reader/_storage/_feeds.py b/src/reader/_storage/_feeds.py index 282511a5..7f27bb7b 100644 --- a/src/reader/_storage/_feeds.py +++ b/src/reader/_storage/_feeds.py @@ -28,7 +28,6 @@ from ._sqlite_utils import rowcount_exactly_one from ._tags import feed_tags_filter - if TYPE_CHECKING: # pragma: no cover from ._base import StorageBase else: diff --git a/src/reader/_storage/_html_utils.py b/src/reader/_storage/_html_utils.py index 331568c0..ae6c02eb 100644 --- a/src/reader/_storage/_html_utils.py +++ b/src/reader/_storage/_html_utils.py @@ -8,7 +8,6 @@ import warnings from typing import TYPE_CHECKING - if TYPE_CHECKING: # pragma: no cover import bs4 diff --git a/src/reader/_storage/_schema.py b/src/reader/_storage/_schema.py index e74ff6e2..c93305bf 100644 --- a/src/reader/_storage/_schema.py +++ b/src/reader/_storage/_schema.py @@ -4,7 +4,6 @@ from ._sqlite_utils import ddl_transaction from ._sqlite_utils import HeavyMigration - SCHEMA = parse_schema(""" CREATE TABLE feeds ( @@ -153,12 +152,10 @@ def create_indexes(db: sqlite3.Connection) -> None: def update_from_36_to_37(db: sqlite3.Connection, /) -> None: # pragma: no cover # for https://github.com/lemon24/reader/issues/279 db.execute("ALTER TABLE entries ADD COLUMN recent_sort TIMESTAMP;") - db.execute( - """ + db.execute(""" UPDATE entries SET recent_sort = coalesce(published, updated, first_updated_epoch); - """ - ) + """) db.execute("DROP INDEX entries_by_kinda_first_updated;") db.execute("DROP INDEX entries_by_kinda_published;") entries_by_recent_index.create(db) @@ -168,8 +165,7 @@ def update_from_37_to_38(db: sqlite3.Connection, /) -> None: # pragma: no cover # https://github.com/lemon24/reader/issues/254#issuecomment-1404215814 entries_table.create(db, 'new_entries') - db.execute( - """ + db.execute(""" INSERT INTO new_entries ( id, feed, @@ -226,8 +222,7 @@ def update_from_37_to_38(db: sqlite3.Connection, /) -> None: # pragma: no cover feed_order, recent_sort FROM entries; - """ - ) + """) # IMPORTANT: this drops ALL indexes and triggers ON entries db.execute("DROP TABLE entries;") diff --git a/src/reader/_storage/_search.py b/src/reader/_storage/_search.py index fd4beff6..d7134693 100644 --- a/src/reader/_storage/_search.py +++ b/src/reader/_storage/_search.py @@ -40,7 +40,6 @@ from ._sqlite_utils import ddl_transaction from ._sqlite_utils import SQLiteType - APPLICATION_ID = b'reaD' _T = TypeVar('_T') @@ -142,8 +141,7 @@ def _enable(cls, db: sqlite3.Connection, schema: str = 'main') -> None: # We put the unindexed stuff at the end to avoid having to adjust # stuff depended on the column index if we add new columns. # - db.execute( - f""" + db.execute(f""" CREATE VIRTUAL TABLE {schema}.entries_search USING fts5( title, -- entries.title content, -- entries.summary or one of entries.content @@ -154,18 +152,14 @@ def _enable(cls, db: sqlite3.Connection, schema: str = 'main') -> None: _is_feed_user_title UNINDEXED, tokenize = "porter unicode61 remove_diacritics 1 tokenchars '_'" ); - """ - ) + """) # TODO: we still need to tune the rank weights, these are just guesses - db.execute( - """ + db.execute(""" INSERT INTO entries_search(entries_search, rank) VALUES ('rank', 'bm25(4, 1, 2)'); - """ - ) + """) - db.execute( - f""" + db.execute(f""" CREATE TABLE {schema}.entries_search_sync_state ( sequence BLOB NOT NULL, feed TEXT NOT NULL, @@ -173,8 +167,7 @@ def _enable(cls, db: sqlite3.Connection, schema: str = 'main') -> None: es_rowids TEXT NOT NULL DEFAULT '[]', PRIMARY KEY (sequence, feed, id) ); - """ - ) + """) @wrap_exceptions() def disable(self) -> None: @@ -532,8 +525,7 @@ def make_search_entries_query( ) -> tuple[Query, dict[str, Any]]: search = ( Query() - .SELECT( - """ + .SELECT(""" _id, _feed, rank, @@ -545,8 +537,7 @@ def make_search_entries_query( 'value', snippet(entries_search, 1, :before, :after, '...', :tokens), 'rank', rank ) AS content - """ - ) + """) .FROM("entries_search") .JOIN("entries ON (entries.id, entries.feed) = (_id, _feed)") .WHERE("entries_search MATCH :query") diff --git a/src/reader/_storage/_sql_utils.py b/src/reader/_storage/_sql_utils.py index 6470fbbc..093dfbe3 100644 --- a/src/reader/_storage/_sql_utils.py +++ b/src/reader/_storage/_sql_utils.py @@ -39,7 +39,6 @@ from typing import TypeVar from typing import Union - if TYPE_CHECKING: # pragma: no cover import sqlite3 diff --git a/src/reader/_storage/_sqlite_utils.py b/src/reader/_storage/_sqlite_utils.py index c9a963d9..14316e41 100644 --- a/src/reader/_storage/_sqlite_utils.py +++ b/src/reader/_storage/_sqlite_utils.py @@ -29,7 +29,6 @@ from typing import no_type_check from typing import TypeVar - SQLiteType = TypeVar('SQLiteType', None, int, float, str, bytes) diff --git a/src/reader/_storage/_tags.py b/src/reader/_storage/_tags.py index a25ab128..93af4018 100644 --- a/src/reader/_storage/_tags.py +++ b/src/reader/_storage/_tags.py @@ -24,7 +24,6 @@ from ._sql_utils import Query from ._sqlite_utils import rowcount_exactly_one - if TYPE_CHECKING: # pragma: no cover from ._base import StorageBase else: diff --git a/src/reader/_types.py b/src/reader/_types.py index bae593e2..3f021039 100644 --- a/src/reader/_types.py +++ b/src/reader/_types.py @@ -56,7 +56,6 @@ from .types import TagFilterInput from .types import TristateFilterInput - log = logging.getLogger("reader") # Private API diff --git a/src/reader/_update.py b/src/reader/_update.py index d8cecb09..98706a6c 100644 --- a/src/reader/_update.py +++ b/src/reader/_update.py @@ -34,7 +34,6 @@ from .types import UpdatedFeed from .types import UpdateResult - if TYPE_CHECKING: # pragma: no cover from ._parser import ParsedFeed from ._types import FeedFilter diff --git a/src/reader/_utils.py b/src/reader/_utils.py index fe729c6d..f8ea1b7a 100644 --- a/src/reader/_utils.py +++ b/src/reader/_utils.py @@ -18,7 +18,6 @@ from typing import cast from typing import TypeVar - FuncType = Callable[..., Any] F = TypeVar('F', bound=FuncType) diff --git a/src/reader/core.py b/src/reader/core.py index 2cfa9fb3..f46adf84 100644 --- a/src/reader/core.py +++ b/src/reader/core.py @@ -75,7 +75,6 @@ from .types import UpdatedFeed from .types import UpdateResult - if TYPE_CHECKING: # pragma: no cover from ._parser import Parser diff --git a/src/reader/plugins/__init__.py b/src/reader/plugins/__init__.py index 34eefe06..1ac33f54 100644 --- a/src/reader/plugins/__init__.py +++ b/src/reader/plugins/__init__.py @@ -13,7 +13,6 @@ from ._loader import PluginLoader - if TYPE_CHECKING: # pragma: no cover from .. import Reader # noqa: F401 diff --git a/src/reader/plugins/_loader.py b/src/reader/plugins/_loader.py index 7967050a..9eceb792 100644 --- a/src/reader/plugins/_loader.py +++ b/src/reader/plugins/_loader.py @@ -11,7 +11,6 @@ from ..exceptions import InvalidPluginError from ..exceptions import PluginInitError - T = TypeVar('T') PluginFunc = Callable[[T], None] PluginInput = Union[str, PluginFunc[T]] diff --git a/src/reader/plugins/entry_dedupe.py b/src/reader/plugins/entry_dedupe.py index c4b310c7..fe1dcc0e 100644 --- a/src/reader/plugins/entry_dedupe.py +++ b/src/reader/plugins/entry_dedupe.py @@ -156,7 +156,6 @@ from reader._utils import BetterStrPartial as partial from reader.exceptions import EntryNotFoundError - log = logging.getLogger(__name__) @@ -839,8 +838,7 @@ def merge_tags(make_reserved, entry, duplicates): # text tokenization -_TOKEN_RE = re.compile( - r"""(?x) +_TOKEN_RE = re.compile(r"""(?x) \b # word boundary (?: \d{1,4} (?: [/-] \d{1,4} ){1,2} # dates @@ -850,8 +848,7 @@ def merge_tags(make_reserved, entry, duplicates): \w+ # other words ) \b # word boundary - """ -) + """) def tokenize(s, preprocessor=lambda x: x): diff --git a/src/reader/plugins/mark_as_read.py b/src/reader/plugins/mark_as_read.py index 2c697edb..64539e6a 100644 --- a/src/reader/plugins/mark_as_read.py +++ b/src/reader/plugins/mark_as_read.py @@ -63,7 +63,6 @@ from reader.exceptions import TagNotFoundError from reader.types import EntryUpdateStatus - # avoid circular imports log = logging.getLogger(__name__) diff --git a/src/reader/plugins/readtime.py b/src/reader/plugins/readtime.py index 9aeed64b..7a40e34d 100644 --- a/src/reader/plugins/readtime.py +++ b/src/reader/plugins/readtime.py @@ -56,7 +56,6 @@ from reader.exceptions import EntryNotFoundError from reader.types import _get_entry_content - log = logging.getLogger('reader.plugins.readtime') diff --git a/src/reader/plugins/ua_fallback.py b/src/reader/plugins/ua_fallback.py index 41c7f565..6556280e 100644 --- a/src/reader/plugins/ua_fallback.py +++ b/src/reader/plugins/ua_fallback.py @@ -26,7 +26,6 @@ import logging - _LOG_HEADERS = ['Server', 'X-Powered-By'] log = logging.getLogger(__name__) diff --git a/src/reader/types.py b/src/reader/types.py index 037fa19c..7f6c1f09 100644 --- a/src/reader/types.py +++ b/src/reader/types.py @@ -24,7 +24,6 @@ from reader.exceptions import UpdateError - # can't be defined here because of circular imports from reader._utils import MISSING as MISSING # isort: skip # noqa: F401 from reader._utils import MissingType as MissingType # isort: skip # noqa: F401 diff --git a/tests/data/10.json.py b/tests/data/10.json.py index faafe153..8c7cb174 100644 --- a/tests/data/10.json.py +++ b/tests/data/10.json.py @@ -5,7 +5,6 @@ from reader._types import EntryData from reader._types import FeedData - feed = FeedData( url=f'{url_base}10.json', version='json10', diff --git a/tests/data/empty.atom.py b/tests/data/empty.atom.py index 258dcb24..c1319ff1 100644 --- a/tests/data/empty.atom.py +++ b/tests/data/empty.atom.py @@ -5,7 +5,6 @@ from reader._types import EntryData from reader._types import FeedData - feed = FeedData(url=f'{url_base}empty.atom', version='atom10') entries = [ diff --git a/tests/data/empty.json.py b/tests/data/empty.json.py index e8b22b01..d3396ab3 100644 --- a/tests/data/empty.json.py +++ b/tests/data/empty.json.py @@ -5,7 +5,6 @@ from reader._types import EntryData from reader._types import FeedData - feed = FeedData( url=f'{url_base}empty.json', version='json11', diff --git a/tests/data/empty.rss.py b/tests/data/empty.rss.py index 047d4a5b..bdf63662 100644 --- a/tests/data/empty.rss.py +++ b/tests/data/empty.rss.py @@ -5,7 +5,6 @@ from reader._types import EntryData from reader._types import FeedData - feed = FeedData(url=f'{url_base}empty.rss', version='rss20') entries = [ diff --git a/tests/data/full.atom.py b/tests/data/full.atom.py index 59232cec..30e00446 100644 --- a/tests/data/full.atom.py +++ b/tests/data/full.atom.py @@ -6,7 +6,6 @@ from reader._types import EntryData from reader._types import FeedData - feed = FeedData( url=f'{url_base}full.atom', updated=datetime.datetime(2003, 12, 13, 18, 30, 2, tzinfo=datetime.UTC), diff --git a/tests/data/full.json.py b/tests/data/full.json.py index 2c39b683..fdc2a48c 100644 --- a/tests/data/full.json.py +++ b/tests/data/full.json.py @@ -5,7 +5,6 @@ from reader._types import EntryData from reader._types import FeedData - feed = FeedData( url=f'{url_base}full.json', updated=None, diff --git a/tests/data/full.rss.py b/tests/data/full.rss.py index 8db1290b..1afb79e9 100644 --- a/tests/data/full.rss.py +++ b/tests/data/full.rss.py @@ -6,7 +6,6 @@ from reader._types import EntryData from reader._types import FeedData - feed = FeedData( url=f'{url_base}full.rss', updated=datetime.datetime(2010, 9, 6, 0, 1, tzinfo=datetime.UTC), diff --git a/tests/data/invalid.json.py b/tests/data/invalid.json.py index 22a2bd2a..f195d92c 100644 --- a/tests/data/invalid.json.py +++ b/tests/data/invalid.json.py @@ -5,7 +5,6 @@ from reader._types import EntryData from reader._types import FeedData - feed = FeedData( url=f'{url_base}invalid.json', version='json11', diff --git a/tests/data/relative.atom.py b/tests/data/relative.atom.py index 12969415..e88a5fb4 100644 --- a/tests/data/relative.atom.py +++ b/tests/data/relative.atom.py @@ -5,7 +5,6 @@ from reader._types import EntryData from reader._types import FeedData - feed = FeedData( url=f'{url_base}relative.atom', link=f'{rel_base}file.html', diff --git a/tests/data/relative.rss.py b/tests/data/relative.rss.py index 122a4daf..b8eb4c27 100644 --- a/tests/data/relative.rss.py +++ b/tests/data/relative.rss.py @@ -5,7 +5,6 @@ from reader._types import EntryData from reader._types import FeedData - feed = FeedData( url=f'{url_base}relative.rss', link=f'{rel_base}file.html', diff --git a/tests/data/unknown.json.py b/tests/data/unknown.json.py index f89596c3..61f0a3c4 100644 --- a/tests/data/unknown.json.py +++ b/tests/data/unknown.json.py @@ -5,7 +5,6 @@ from reader._types import EntryData from reader._types import FeedData - feed = FeedData( url=f'{url_base}unknown.json', version='json', diff --git a/tests/test__types.py b/tests/test__types.py index 5fa4ab7f..3ae57d32 100644 --- a/tests/test__types.py +++ b/tests/test__types.py @@ -8,7 +8,6 @@ from reader._types import tag_filter_argument from reader._types import tristate_filter_argument - TAG_DATA = [ ([], [None, [], (), [[]], ((),), [[], []]]), ([[True]], [True, [True], [[True]]]), diff --git a/tests/test__utils.py b/tests/test__utils.py index c2e80eef..15de8278 100644 --- a/tests/test__utils.py +++ b/tests/test__utils.py @@ -3,7 +3,6 @@ from reader._utils import deprecated from reader._utils import deprecated_wrapper - # Normally, the stuff in _utils is tested by tests for higher level code, # but some of the things aren't always used. diff --git a/tests/test_app_legacy.py b/tests/test_app_legacy.py index 07294094..2e5df369 100644 --- a/tests/test_app_legacy.py +++ b/tests/test_app_legacy.py @@ -8,7 +8,6 @@ from reader._app.legacy import create_app from utils import utc_datetime as datetime - # mechanicalsoup depends on lxml, but we don't have that everywhere. try: import mechanicalsoup diff --git a/tests/test_bench.py b/tests/test_bench.py index 443aa8c6..39db1928 100644 --- a/tests/test_bench.py +++ b/tests/test_bench.py @@ -8,13 +8,11 @@ from test_cli import patch_app_dir from test_reader_filter import setup_reader_for_tags - root_dir = os.path.dirname(__file__) sys.path.insert(0, os.path.join(root_dir, '../scripts')) import bench from bench import cli - pytestmark = pytest.mark.slow pytest.importorskip("numpy") diff --git a/tests/test_changes.py b/tests/test_changes.py index f63cf626..1d429ef1 100644 --- a/tests/test_changes.py +++ b/tests/test_changes.py @@ -7,7 +7,6 @@ from reader._types import Change from reader.exceptions import ChangeTrackingNotEnabledError - pytestmark = pytest.mark.noscheduled diff --git a/tests/test_config_utils.py b/tests/test_config_utils.py index a7aa13d0..15cd41b8 100644 --- a/tests/test_config_utils.py +++ b/tests/test_config_utils.py @@ -63,14 +63,12 @@ def test_empty_config(with_config): def test_config(with_config): - with_config( - """\ + with_config("""\ [cli] plugin=['config'] [cli.sub] option='config' - """ - ) + """) expected = {'': {'plugin': ('CONFIG',)}, 'sub': {'option': 'CONFIG'}} assert invoke(cli, ['sub']) == expected diff --git a/tests/test_html_utils.py b/tests/test_html_utils.py index c3ae98d5..575e9c41 100644 --- a/tests/test_html_utils.py +++ b/tests/test_html_utils.py @@ -3,7 +3,6 @@ from reader._storage._html_utils import strip_html - STRIP_HTML_DATA = [ ('', ''), ('
', ''), diff --git a/tests/test_lazy_imports.py b/tests/test_lazy_imports.py index e31ba41b..f6859cee 100644 --- a/tests/test_lazy_imports.py +++ b/tests/test_lazy_imports.py @@ -14,7 +14,6 @@ import reader.plugins from utils import parametrize_dict - # these tests take ~1s in total pytestmark = pytest.mark.slow @@ -65,8 +64,7 @@ def get_imported_modules(code): return process.stdout.split() -LAZY_MODULES = frozenset( - """\ +LAZY_MODULES = frozenset("""\ bs4 requests feedparser @@ -74,8 +72,7 @@ def get_imported_modules(code): urllib.request multiprocessing concurrent.futures - """.split() -) + """.split()) # all in a single script to save time diff --git a/tests/test_plugins_entry_dedupe.py b/tests/test_plugins_entry_dedupe.py index 19bb2be7..2dd571bb 100644 --- a/tests/test_plugins_entry_dedupe.py +++ b/tests/test_plugins_entry_dedupe.py @@ -20,7 +20,6 @@ from utils import parametrize_dict from utils import utc_datetime as datetime - pytestmark = pytest.mark.noscheduled diff --git a/tests/test_plugins_mark_as_read.py b/tests/test_plugins_mark_as_read.py index 5a0ee283..5185a230 100644 --- a/tests/test_plugins_mark_as_read.py +++ b/tests/test_plugins_mark_as_read.py @@ -5,7 +5,6 @@ from utils import utc_datetime as datetime - pytestmark = pytest.mark.noscheduled diff --git a/tests/test_plugins_preview_feed_list.py b/tests/test_plugins_preview_feed_list.py index cc9d9d1e..0436385c 100644 --- a/tests/test_plugins_preview_feed_list.py +++ b/tests/test_plugins_preview_feed_list.py @@ -5,7 +5,6 @@ from test_app_legacy import make_browser from test_app_legacy import pytestmark - pytestmark = list(pytestmark) pytestmark.append( pytest.mark.filterwarnings("ignore:No parser was explicitly specified") diff --git a/tests/test_plugins_readtime.py b/tests/test_plugins_readtime.py index 9f179726..3f223220 100644 --- a/tests/test_plugins_readtime.py +++ b/tests/test_plugins_readtime.py @@ -5,7 +5,6 @@ from utils import rename_argument from utils import utc_datetime as datetime - pytestmark = pytest.mark.noscheduled diff --git a/tests/test_reader_deprecations.py b/tests/test_reader_deprecations.py index d122302f..ec146d68 100644 --- a/tests/test_reader_deprecations.py +++ b/tests/test_reader_deprecations.py @@ -4,5 +4,4 @@ from fakeparser import Parser - # Nothing here (yet). diff --git a/tests/test_reader_hooks.py b/tests/test_reader_hooks.py index a85fa9d2..229ee64a 100644 --- a/tests/test_reader_hooks.py +++ b/tests/test_reader_hooks.py @@ -12,7 +12,6 @@ from test_reader_private import CustomRetriever from utils import utc_datetime as datetime - pytestmark = pytest.mark.noscheduled diff --git a/tests/test_reader_lifecycle.py b/tests/test_reader_lifecycle.py index c48804bc..304251d7 100644 --- a/tests/test_reader_lifecycle.py +++ b/tests/test_reader_lifecycle.py @@ -21,7 +21,6 @@ from reader import StorageError from utils import rename_argument - pytestmark = pytest.mark.noscheduled diff --git a/tests/test_reader_private.py b/tests/test_reader_private.py index 3e947343..01529e67 100644 --- a/tests/test_reader_private.py +++ b/tests/test_reader_private.py @@ -19,7 +19,6 @@ from utils import utc_datetime from utils import utc_datetime as datetime - pytestmark = pytest.mark.noscheduled diff --git a/tests/test_reader_search.py b/tests/test_reader_search.py index 339559c7..65318b49 100644 --- a/tests/test_reader_search.py +++ b/tests/test_reader_search.py @@ -27,7 +27,6 @@ from utils import utc_datetime from utils import utc_datetime as datetime - pytestmark = pytest.mark.noscheduled @@ -563,14 +562,10 @@ def get_entries_search(): ) def get_entries_search_sync_state(): - return sorted( - db.execute( - """ + return sorted(db.execute(""" select feed, id, sequence, json_array_length(es_rowids) from entries_search_sync_state - """ - ) - ) + """)) reader.update_search() one, two = sorted(reader.get_entries(), key=lambda e: e.resource_id) diff --git a/tests/test_reader_sort.py b/tests/test_reader_sort.py index ecc8b3bb..c7ab4490 100644 --- a/tests/test_reader_sort.py +++ b/tests/test_reader_sort.py @@ -6,7 +6,6 @@ from utils import rename_argument from utils import utc_datetime as datetime - pytestmark = pytest.mark.noscheduled diff --git a/tests/test_reader_update.py b/tests/test_reader_update.py index 03b96e17..fceec044 100644 --- a/tests/test_reader_update.py +++ b/tests/test_reader_update.py @@ -27,7 +27,6 @@ from utils import parametrize_dict from utils import utc_datetime as datetime - # fmt: off def prepare_feed(reader): diff --git a/tests/test_reader_utils.py b/tests/test_reader_utils.py index 1dcdbe40..3e7a08cb 100644 --- a/tests/test_reader_utils.py +++ b/tests/test_reader_utils.py @@ -5,7 +5,6 @@ from reader import EntryNotFoundError from reader.utils import archive_entries - pytestmark = pytest.mark.noscheduled diff --git a/tests/test_search.py b/tests/test_search.py index 878992d9..9767c5ed 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -16,7 +16,6 @@ from reader._storage._sqlite_utils import require_version from utils import utc_datetime as datetime - STRIP_HTML_DATA = [(i, i) for i in [None, 10, 11.2, b'aabb', b'aa
bb']] + [ ('aabb', 'aabb'), ('aa
bb', 'aabb'), diff --git a/tests/test_sql_utils.py b/tests/test_sql_utils.py index 1c3db61c..7eb11c76 100644 --- a/tests/test_sql_utils.py +++ b/tests/test_sql_utils.py @@ -9,8 +9,7 @@ def test_query_simple(): query = BaseQuery().SELECT('select').FROM('from').JOIN('join').WHERE('where') - assert str(query) == dedent( - """\ + assert str(query) == dedent("""\ SELECT select FROM @@ -19,8 +18,7 @@ def test_query_simple(): join WHERE where - """ - ) + """) def test_query_complicated(): @@ -63,8 +61,7 @@ def test_query_complicated(): .SELECT() .SELECT() ) - assert str(query) == dedent( - """\ + assert str(query) == dedent("""\ WITH ( first cte @@ -105,19 +102,16 @@ def test_query_complicated(): third LIMIT limit - """ - ) + """) def test_query_flag(): query = BaseQuery().SELECT('one').SELECT('two').SELECT_DISTINCT() - assert str(query) == dedent( - """\ + assert str(query) == dedent("""\ SELECT DISTINCT one, two - """ - ) + """) with pytest.raises(ValueError): BaseQuery().SELECT_MAGIC('one') @@ -151,39 +145,25 @@ def make_query(cls=Query): query.scrolling_window_order_by('one') query.LIMIT('limit') query.add_last([]) - assert str(query) == str( - make_query(BaseQuery) - .WHERE( - """ + assert str(query) == str(make_query(BaseQuery).WHERE(""" ( one ) > ( :last_0 ) - """ - ) - .ORDER_BY('one ASC') - .LIMIT('limit') - ) + """).ORDER_BY('one ASC').LIMIT('limit')) query = make_query() query.scrolling_window_order_by('one', desc=True, keyword='HAVING') query.LIMIT('limit') query.add_last([]) - assert str(query) == str( - make_query(BaseQuery) - .HAVING( - """ + assert str(query) == str(make_query(BaseQuery).HAVING(""" ( one ) < ( :last_0 ) - """ - ) - .ORDER_BY('one DESC') - .LIMIT('limit') - ) + """).ORDER_BY('one DESC').LIMIT('limit')) def test_scrolling_window_last(): diff --git a/tests/test_sqlite_utils.py b/tests/test_sqlite_utils.py index d0b04c0e..0f71ab1f 100644 --- a/tests/test_sqlite_utils.py +++ b/tests/test_sqlite_utils.py @@ -22,7 +22,6 @@ from reader._storage._sqlite_utils import wrap_exceptions from utils import rename_argument - original_sqlite3_connect = sqlite3.connect