reader 3.17__tar.gz → 3.19__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {reader-3.17 → reader-3.19}/CHANGES.rst +41 -0
- {reader-3.17/src/reader.egg-info → reader-3.19}/PKG-INFO +11 -40
- {reader-3.17 → reader-3.19}/docs/api.rst +17 -0
- {reader-3.17 → reader-3.19}/docs/conf.py +0 -14
- {reader-3.17 → reader-3.19}/docs/dev.rst +16 -10
- {reader-3.17 → reader-3.19}/docs/install.rst +3 -1
- {reader-3.17 → reader-3.19}/pyproject.toml +29 -31
- reader-3.19/run.sh +125 -0
- {reader-3.17 → reader-3.19}/scripts/release.py +9 -19
- {reader-3.17 → reader-3.19}/src/reader/__init__.py +4 -1
- {reader-3.17 → reader-3.19}/src/reader/_parser/__init__.py +2 -7
- {reader-3.17 → reader-3.19}/src/reader/_parser/_lazy.py +1 -2
- {reader-3.17 → reader-3.19}/src/reader/_parser/requests/_lazy.py +1 -2
- {reader-3.17 → reader-3.19}/src/reader/_plugins/cli_status.py +2 -2
- {reader-3.17 → reader-3.19}/src/reader/_plugins/enclosure_tags.py +4 -2
- {reader-3.17 → reader-3.19}/src/reader/_storage/_base.py +1 -1
- {reader-3.17 → reader-3.19}/src/reader/_storage/_entries.py +6 -6
- {reader-3.17 → reader-3.19}/src/reader/_storage/_feeds.py +6 -4
- {reader-3.17 → reader-3.19}/src/reader/_storage/_search.py +12 -11
- {reader-3.17 → reader-3.19}/src/reader/_storage/_sql_utils.py +2 -3
- {reader-3.17 → reader-3.19}/src/reader/_storage/_sqlite_utils.py +15 -4
- {reader-3.17 → reader-3.19}/src/reader/_types.py +3 -7
- {reader-3.17 → reader-3.19}/src/reader/_update.py +1 -2
- {reader-3.17 → reader-3.19}/src/reader/core.py +39 -87
- {reader-3.17 → reader-3.19}/src/reader/exceptions.py +15 -81
- {reader-3.17 → reader-3.19}/src/reader/types.py +74 -22
- {reader-3.17 → reader-3.19/src/reader.egg-info}/PKG-INFO +11 -40
- {reader-3.17 → reader-3.19}/src/reader.egg-info/SOURCES.txt +0 -6
- reader-3.19/src/reader.egg-info/requires.txt +27 -0
- {reader-3.17 → reader-3.19}/tests/conftest.py +1 -0
- {reader-3.17 → reader-3.19}/tests/data/full.atom.py +5 -11
- {reader-3.17 → reader-3.19}/tests/data/full.json.py +3 -3
- {reader-3.17 → reader-3.19}/tests/data/full.rss.py +3 -3
- {reader-3.17 → reader-3.19}/tests/test_parser.py +10 -29
- {reader-3.17 → reader-3.19}/tests/test_plugins_cli_status.py +2 -1
- {reader-3.17 → reader-3.19}/tests/test_reader.py +5 -0
- {reader-3.17 → reader-3.19}/tests/test_reader_hooks.py +14 -4
- {reader-3.17 → reader-3.19}/tests/test_reader_update.py +17 -0
- {reader-3.17 → reader-3.19}/tests/utils.py +33 -43
- reader-3.19/tox.ini +40 -0
- reader-3.17/docs/.DS_Store +0 -0
- reader-3.17/docs/Makefile +0 -20
- reader-3.17/docs/make.bat +0 -36
- reader-3.17/run.sh +0 -188
- reader-3.17/scripts/.coverage +0 -0
- reader-3.17/scripts/generate_import_all.py +0 -15
- reader-3.17/src/reader.egg-info/requires.txt +0 -67
- reader-3.17/tests/test_test_utils.py +0 -36
- reader-3.17/tox.ini +0 -40
- {reader-3.17 → reader-3.19}/LICENSE +0 -0
- {reader-3.17 → reader-3.19}/MANIFEST.in +0 -0
- {reader-3.17 → reader-3.19}/README.rst +0 -0
- {reader-3.17 → reader-3.19}/docs/app.rst +0 -0
- {reader-3.17 → reader-3.19}/docs/changelog.rst +0 -0
- {reader-3.17 → reader-3.19}/docs/cli.rst +0 -0
- {reader-3.17 → reader-3.19}/docs/config.rst +0 -0
- {reader-3.17 → reader-3.19}/docs/contributing.rst +0 -0
- {reader-3.17 → reader-3.19}/docs/dev-app.rst +0 -0
- {reader-3.17 → reader-3.19}/docs/guide.rst +0 -0
- {reader-3.17 → reader-3.19}/docs/images/redesign-01.png +0 -0
- {reader-3.17 → reader-3.19}/docs/index.rst +0 -0
- {reader-3.17 → reader-3.19}/docs/internal.rst +0 -0
- {reader-3.17 → reader-3.19}/docs/plugins.rst +0 -0
- {reader-3.17 → reader-3.19}/docs/screenshots/dillo.png +0 -0
- {reader-3.17 → reader-3.19}/docs/screenshots/entries-feed.png +0 -0
- {reader-3.17 → reader-3.19}/docs/screenshots/entries-v2-dark.png +0 -0
- {reader-3.17 → reader-3.19}/docs/screenshots/entries-v2-filters-light.png +0 -0
- {reader-3.17 → reader-3.19}/docs/screenshots/entries.png +0 -0
- {reader-3.17 → reader-3.19}/docs/screenshots/entry-one.png +0 -0
- {reader-3.17 → reader-3.19}/docs/screenshots/entry-two.png +0 -0
- {reader-3.17 → reader-3.19}/docs/screenshots/feeds.png +0 -0
- {reader-3.17 → reader-3.19}/docs/screenshots/lynx.png +0 -0
- {reader-3.17 → reader-3.19}/docs/screenshots/search.png +0 -0
- {reader-3.17 → reader-3.19}/docs/tutorial.rst +0 -0
- {reader-3.17 → reader-3.19}/docs/why.rst +0 -0
- {reader-3.17 → reader-3.19}/examples/config.yaml +0 -0
- {reader-3.17 → reader-3.19}/examples/custom_headers.py +0 -0
- {reader-3.17 → reader-3.19}/examples/feed_slugs.py +0 -0
- {reader-3.17 → reader-3.19}/examples/parser_only.py +0 -0
- {reader-3.17 → reader-3.19}/examples/podcast.py +0 -0
- {reader-3.17 → reader-3.19}/examples/terminal.py +0 -0
- {reader-3.17 → reader-3.19}/scripts/backup.sh +0 -0
- {reader-3.17 → reader-3.19}/scripts/bench.py +0 -0
- {reader-3.17 → reader-3.19}/scripts/debug_storage_stats.py +0 -0
- {reader-3.17 → reader-3.19}/scripts/jscontrols.html +0 -0
- {reader-3.17 → reader-3.19}/scripts/jscontrols.py +0 -0
- {reader-3.17 → reader-3.19}/scripts/lines.sh +0 -0
- {reader-3.17 → reader-3.19}/setup.cfg +0 -0
- {reader-3.17 → reader-3.19}/src/reader/__main__.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/__init__.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/api_thing.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/cli.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/static/controls.js +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/static/style.css +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/templates/add_entry.html +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/templates/entries.html +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/templates/entry.html +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/templates/feeds.html +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/templates/layout.html +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/templates/macros.html +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/templates/metadata.html +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/templates/tags.html +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/v2/__init__.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/v2/forms.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/v2/static/style.css +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/v2/static/theme.js +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/v2/templates/v2/entries.html +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/v2/templates/v2/layout.html +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/v2/templates/v2/macros.html +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_app/wsgi.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_cli.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_config.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_hash_utils.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_parser/_http_utils.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_parser/_url_utils.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_parser/feedparser.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_parser/file.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_parser/http.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_parser/jsonfeed.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_parser/requests/__init__.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_plugins/__init__.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_plugins/preview_feed_list.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_plugins/share.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_plugins/sqlite_releases.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_plugins/templates/preview_feed_list.html +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_plugins/timer.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_storage/__init__.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_storage/_changes.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_storage/_html_utils.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_storage/_schema.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_storage/_tags.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_utils.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/__init__.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/__init__.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/api.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/datetimes/__init__.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/datetimes/asctime.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/datetimes/greek.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/datetimes/hungarian.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/datetimes/iso8601.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/datetimes/korean.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/datetimes/perforce.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/datetimes/rfc822.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/datetimes/w3dtf.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/encodings.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/exceptions.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/html.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/http.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/mixin.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/namespaces/__init__.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/namespaces/_base.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/namespaces/admin.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/namespaces/cc.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/namespaces/dc.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/namespaces/georss.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/namespaces/itunes.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/namespaces/mediarss.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/namespaces/psc.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/parsers/__init__.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/parsers/json.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/parsers/loose.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/parsers/strict.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/py.typed +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/sanitizer.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/sgml.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/urls.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/_vendor/feedparser/util.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/plugins/__init__.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/plugins/enclosure_dedupe.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/plugins/entry_dedupe.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/plugins/mark_as_read.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/plugins/readtime.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/plugins/ua_fallback.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader/py.typed +0 -0
- {reader-3.17 → reader-3.19}/src/reader/utils.py +0 -0
- {reader-3.17 → reader-3.19}/src/reader.egg-info/dependency_links.txt +0 -0
- {reader-3.17 → reader-3.19}/src/reader.egg-info/top_level.txt +0 -0
- {reader-3.17 → reader-3.19}/tests/data/10.json +0 -0
- {reader-3.17 → reader-3.19}/tests/data/10.json.py +0 -0
- {reader-3.17 → reader-3.19}/tests/data/custom +0 -0
- {reader-3.17 → reader-3.19}/tests/data/empty.atom +0 -0
- {reader-3.17 → reader-3.19}/tests/data/empty.atom.py +0 -0
- {reader-3.17 → reader-3.19}/tests/data/empty.json +0 -0
- {reader-3.17 → reader-3.19}/tests/data/empty.json.py +0 -0
- {reader-3.17 → reader-3.19}/tests/data/empty.rss +0 -0
- {reader-3.17 → reader-3.19}/tests/data/empty.rss.py +0 -0
- {reader-3.17 → reader-3.19}/tests/data/full.atom +0 -0
- {reader-3.17 → reader-3.19}/tests/data/full.json +0 -0
- {reader-3.17 → reader-3.19}/tests/data/full.rss +0 -0
- {reader-3.17 → reader-3.19}/tests/data/invalid.json +0 -0
- {reader-3.17 → reader-3.19}/tests/data/invalid.json.py +0 -0
- {reader-3.17 → reader-3.19}/tests/data/relative.atom +0 -0
- {reader-3.17 → reader-3.19}/tests/data/relative.atom.py +0 -0
- {reader-3.17 → reader-3.19}/tests/data/relative.rss +0 -0
- {reader-3.17 → reader-3.19}/tests/data/relative.rss.py +0 -0
- {reader-3.17 → reader-3.19}/tests/data/sqlite_releases.html +0 -0
- {reader-3.17 → reader-3.19}/tests/data/unknown.json +0 -0
- {reader-3.17 → reader-3.19}/tests/data/unknown.json.py +0 -0
- {reader-3.17 → reader-3.19}/tests/fakeparser.py +0 -0
- {reader-3.17 → reader-3.19}/tests/reader_methods.py +0 -0
- {reader-3.17 → reader-3.19}/tests/reader_test_plugins/__init__.py +0 -0
- {reader-3.17 → reader-3.19}/tests/reader_test_plugins/good.py +0 -0
- {reader-3.17 → reader-3.19}/tests/reader_test_plugins/init_error.py +0 -0
- {reader-3.17 → reader-3.19}/tests/reader_test_plugins/missing_dependency.py +0 -0
- {reader-3.17 → reader-3.19}/tests/reader_test_plugins/missing_entry_point.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test__types.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test__utils.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_app.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_app_wsgi.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_bench.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_changes.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_cli.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_config.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_exceptions.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_hash_utils.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_html_utils.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_lazy_imports.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_plugins_enclosure_dedupe.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_plugins_entry_dedupe.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_plugins_mark_as_read.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_plugins_preview_feed_list.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_plugins_readtime.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_plugins_sqlite_releases.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_plugins_ua_fallback.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_reader_context.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_reader_counts.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_reader_deprecations.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_reader_filter.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_reader_integration.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_reader_plugins.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_reader_private.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_reader_search.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_reader_sort.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_reader_utils.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_search.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_sql_utils.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_sqlite_utils.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_storage.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_tags.py +0 -0
- {reader-3.17 → reader-3.19}/tests/test_types.py +0 -0
|
@@ -6,6 +6,47 @@ Changelog
|
|
|
6
6
|
:no-index:
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
Version 3.19
|
|
10
|
+
------------
|
|
11
|
+
|
|
12
|
+
Released 2025-10-01
|
|
13
|
+
|
|
14
|
+
* Support Python 3.14.
|
|
15
|
+
* Remove deprecated empty ``search`` and ``readtime`` extras.
|
|
16
|
+
* Remove undocumented development ``tests``, ``docs``, and ``dev`` extras.
|
|
17
|
+
|
|
18
|
+
* :mod:`~reader._plugins.enclosure_tags` plugin:
|
|
19
|
+
strip HTML tags from values used as MP3 tags
|
|
20
|
+
(for example, ``<b>`` tags used to highlight search result matches).
|
|
21
|
+
|
|
22
|
+
* Project infrastructure improvements.
|
|
23
|
+
|
|
24
|
+
* Clean up :doc:`contributing` documentation and :gh:`run.sh <run.sh>` script.
|
|
25
|
+
* Use GitHub Actions to publish releases to PyPI.
|
|
26
|
+
* Split type checking and testing jobs in the ``build`` GHA workflow.
|
|
27
|
+
* Make tox runs slightly faster.
|
|
28
|
+
* Use dependency groups instead of extras for development dependencies.
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
Version 3.18
|
|
32
|
+
------------
|
|
33
|
+
|
|
34
|
+
Released 2025-05-04
|
|
35
|
+
|
|
36
|
+
* Drop Python 3.10 support. (:issue:`354`)
|
|
37
|
+
|
|
38
|
+
* Add the ``overwrite`` argument to :meth:`~Reader.add_entry`.
|
|
39
|
+
* Add :class:`FeedSort`, :class:`EntrySort`, and :class:`EntrySearchSort` enums.
|
|
40
|
+
(:issue:`354`)
|
|
41
|
+
|
|
42
|
+
* Fix bug causing :meth:`.Reader.update_feeds`
|
|
43
|
+
to not honor ``updates_enabled=True`` when ``scheduled=True``.
|
|
44
|
+
(:issue:`365`)
|
|
45
|
+
|
|
46
|
+
* In the :mod:`~reader._plugins.cli_status` plugin,
|
|
47
|
+
overwrite the entry so it doesn't appear briefly as unread.
|
|
48
|
+
|
|
49
|
+
|
|
9
50
|
Version 3.17
|
|
10
51
|
------------
|
|
11
52
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: reader
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.19
|
|
4
4
|
Summary: A Python feed reader library.
|
|
5
5
|
Author: lemon24
|
|
6
6
|
License: BSD-3-Clause
|
|
7
7
|
Project-URL: Documentation, https://reader.readthedocs.io/
|
|
8
|
-
Project-URL:
|
|
9
|
-
Project-URL:
|
|
10
|
-
Project-URL:
|
|
8
|
+
Project-URL: Repository, https://github.com/lemon24/reader
|
|
9
|
+
Project-URL: Issues, https://github.com/lemon24/reader/issues
|
|
10
|
+
Project-URL: Changelog, https://reader.readthedocs.io/en/latest/changelog.html
|
|
11
11
|
Keywords: atom,cdf,feed,rdf,rss,json feed,web feed,podcast,feed reader,feed aggregator
|
|
12
12
|
Classifier: Development Status :: 5 - Production/Stable
|
|
13
13
|
Classifier: Environment :: Console
|
|
@@ -19,10 +19,10 @@ Classifier: Operating System :: OS Independent
|
|
|
19
19
|
Classifier: Programming Language :: Python
|
|
20
20
|
Classifier: Programming Language :: Python :: 3
|
|
21
21
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.11
|
|
24
23
|
Classifier: Programming Language :: Python :: 3.12
|
|
25
24
|
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
26
26
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
27
27
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
28
28
|
Classifier: Topic :: Internet
|
|
@@ -32,7 +32,7 @@ Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
|
|
|
32
32
|
Classifier: Topic :: Software Development :: Libraries
|
|
33
33
|
Classifier: Topic :: Utilities
|
|
34
34
|
Classifier: Typing :: Typed
|
|
35
|
-
Requires-Python: >=3.
|
|
35
|
+
Requires-Python: >=3.11
|
|
36
36
|
Description-Content-Type: text/x-rst
|
|
37
37
|
License-File: LICENSE
|
|
38
38
|
Requires-Dist: typing-extensions>=4
|
|
@@ -41,14 +41,14 @@ Requires-Dist: requests>=2.18
|
|
|
41
41
|
Requires-Dist: werkzeug>2
|
|
42
42
|
Requires-Dist: iso8601>=1
|
|
43
43
|
Requires-Dist: beautifulsoup4>=4.5
|
|
44
|
-
Provides-Extra:
|
|
45
|
-
|
|
44
|
+
Provides-Extra: all
|
|
45
|
+
Requires-Dist: reader[app,cli,unstable-plugins]; extra == "all"
|
|
46
46
|
Provides-Extra: cli
|
|
47
47
|
Requires-Dist: click>=7; extra == "cli"
|
|
48
48
|
Requires-Dist: PyYAML; extra == "cli"
|
|
49
49
|
Provides-Extra: app
|
|
50
50
|
Requires-Dist: flask>=0.10; extra == "app"
|
|
51
|
-
Requires-Dist: humanize
|
|
51
|
+
Requires-Dist: humanize>=4; extra == "app"
|
|
52
52
|
Requires-Dist: PyYAML; extra == "app"
|
|
53
53
|
Requires-Dist: WTForms; extra == "app"
|
|
54
54
|
Requires-Dist: jinja2-fragments; extra == "app"
|
|
@@ -60,36 +60,7 @@ Requires-Dist: beautifulsoup4; extra == "unstable-plugins"
|
|
|
60
60
|
Requires-Dist: blinker>=1.4; extra == "unstable-plugins"
|
|
61
61
|
Requires-Dist: beautifulsoup4; extra == "unstable-plugins"
|
|
62
62
|
Requires-Dist: tabulate; extra == "unstable-plugins"
|
|
63
|
-
|
|
64
|
-
Requires-Dist: pytest>=4; extra == "tests"
|
|
65
|
-
Requires-Dist: pytest-randomly; extra == "tests"
|
|
66
|
-
Requires-Dist: pytest-subtests; extra == "tests"
|
|
67
|
-
Requires-Dist: pytest-rerunfailures; extra == "tests"
|
|
68
|
-
Requires-Dist: coverage; extra == "tests"
|
|
69
|
-
Requires-Dist: pytest-cov; extra == "tests"
|
|
70
|
-
Requires-Dist: requests-mock; extra == "tests"
|
|
71
|
-
Requires-Dist: mechanicalsoup; (implementation_name != "pypy" and python_version <= "3.12") and extra == "tests"
|
|
72
|
-
Requires-Dist: requests-wsgi-adapter; extra == "tests"
|
|
73
|
-
Requires-Dist: lxml; (implementation_name != "pypy" and python_version <= "3.12") and extra == "tests"
|
|
74
|
-
Requires-Dist: html5lib; extra == "tests"
|
|
75
|
-
Requires-Dist: numpy; (implementation_name != "pypy" and os_name == "posix" and python_version <= "3.12") and extra == "tests"
|
|
76
|
-
Requires-Dist: mypy; implementation_name != "pypy" and extra == "tests"
|
|
77
|
-
Requires-Dist: types-requests; extra == "tests"
|
|
78
|
-
Requires-Dist: types-beautifulsoup4; extra == "tests"
|
|
79
|
-
Provides-Extra: docs
|
|
80
|
-
Requires-Dist: sphinx; extra == "docs"
|
|
81
|
-
Requires-Dist: sphinx-rtd-theme>=1.3.0rc1; extra == "docs"
|
|
82
|
-
Requires-Dist: click>=7; extra == "docs"
|
|
83
|
-
Requires-Dist: sphinx-click; extra == "docs"
|
|
84
|
-
Requires-Dist: sphinx-hoverxref; extra == "docs"
|
|
85
|
-
Requires-Dist: sphinxcontrib-log-cabinet; extra == "docs"
|
|
86
|
-
Requires-Dist: setuptools; extra == "docs"
|
|
87
|
-
Provides-Extra: dev
|
|
88
|
-
Requires-Dist: reader[app,cli,docs,tests,unstable-plugins]; extra == "dev"
|
|
89
|
-
Requires-Dist: tox; extra == "dev"
|
|
90
|
-
Requires-Dist: pre-commit; extra == "dev"
|
|
91
|
-
Requires-Dist: build; extra == "dev"
|
|
92
|
-
Requires-Dist: twine; extra == "dev"
|
|
63
|
+
Dynamic: license-file
|
|
93
64
|
|
|
94
65
|
.. begin-intro
|
|
95
66
|
|
|
@@ -171,6 +171,23 @@ The class hierarchy for :mod:`reader` exceptions is:
|
|
|
171
171
|
|
|
172
172
|
|
|
173
173
|
|
|
174
|
+
Enumerations
|
|
175
|
+
------------
|
|
176
|
+
|
|
177
|
+
.. autoclass:: reader.FeedSort(value)
|
|
178
|
+
:show-inheritance:
|
|
179
|
+
:members:
|
|
180
|
+
|
|
181
|
+
.. autoclass:: reader.EntrySort(value)
|
|
182
|
+
:show-inheritance:
|
|
183
|
+
:members:
|
|
184
|
+
|
|
185
|
+
.. autoclass:: reader.EntrySearchSort(value)
|
|
186
|
+
:show-inheritance:
|
|
187
|
+
:members:
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
|
|
174
191
|
.. _type aliases:
|
|
175
192
|
|
|
176
193
|
Type aliases
|
|
@@ -33,7 +33,6 @@ extensions = [
|
|
|
33
33
|
'sphinx.ext.intersphinx',
|
|
34
34
|
'sphinx.ext.extlinks',
|
|
35
35
|
'sphinx_click.ext',
|
|
36
|
-
'hoverxref.extension',
|
|
37
36
|
'sphinxcontrib.log_cabinet',
|
|
38
37
|
]
|
|
39
38
|
|
|
@@ -112,19 +111,6 @@ extlinks = {
|
|
|
112
111
|
}
|
|
113
112
|
|
|
114
113
|
|
|
115
|
-
hoverxref_auto_ref = True
|
|
116
|
-
hoverxref_domains = ["py"]
|
|
117
|
-
hoverxref_role_types = {
|
|
118
|
-
'ref': 'tooltip',
|
|
119
|
-
'mod': 'tooltip',
|
|
120
|
-
'class': 'tooltip',
|
|
121
|
-
'meth': 'tooltip',
|
|
122
|
-
'attr': 'tooltip',
|
|
123
|
-
'exc': 'tooltip',
|
|
124
|
-
'func': 'tooltip',
|
|
125
|
-
'data': 'tooltip',
|
|
126
|
-
}
|
|
127
|
-
|
|
128
114
|
pygments_style = 'friendly'
|
|
129
115
|
|
|
130
116
|
html_theme = 'sphinx_rtd_theme'
|
|
@@ -226,25 +226,31 @@ Making a release
|
|
|
226
226
|
|
|
227
227
|
.. note::
|
|
228
228
|
|
|
229
|
-
:gh:`
|
|
229
|
+
The :gh:`release.py <scripts/release.py>` script together with
|
|
230
|
+
the :gh:`publish <.github/workflows/publish.yaml>` GitHub Actions workflow
|
|
231
|
+
already do most of these.
|
|
230
232
|
|
|
231
233
|
Making a release (from ``x`` to ``y`` == ``x + 1``):
|
|
232
234
|
|
|
233
235
|
* (release.py) bump version in ``src/reader/__init__.py`` to ``y``
|
|
234
236
|
* (release.py) update changelog with release version and date
|
|
235
237
|
* (release.py) make sure tests pass / docs build
|
|
236
|
-
* (release.py) clean up dist/: ``rm -rf dist/``
|
|
237
|
-
* (release.py) build tarball and wheel: ``python -m build``
|
|
238
238
|
* (release.py) push to GitHub
|
|
239
|
-
* (release.py prompts) wait for GitHub Actions /
|
|
240
|
-
* upload to test PyPI and check: ``twine upload --repository-url https://test.pypi.org/legacy/ dist/*``
|
|
241
|
-
* (release.py) upload to PyPI: ``twine upload dist/*``
|
|
239
|
+
* (release.py prompts) wait for GitHub Actions / Read the Docs builds to pass
|
|
242
240
|
* (release.py) tag current commit with `<major>.<minor>` and `<major>.x`
|
|
243
|
-
(e.g. when releasing `1.20`: `1.20` and `1.x`)
|
|
244
|
-
* (release.py prompts)
|
|
245
|
-
*
|
|
241
|
+
(e.g. when releasing `1.20`: `1.20` and `1.x`) and push tags to GitHub
|
|
242
|
+
* (release.py prompts) approve publish workflow
|
|
243
|
+
* (publish workflow) build and upload to PyPI
|
|
244
|
+
* alternatively, to make a manual release (should not be needed)
|
|
245
|
+
|
|
246
|
+
* clean up dist/: ``rm -rf dist/``
|
|
247
|
+
* build tarball and wheel: ``python -m build``
|
|
248
|
+
* upload to test PyPI and check: ``twine upload --repository-url https://test.pypi.org/legacy/ dist/*``
|
|
249
|
+
* upload to PyPI: ``twine upload dist/*``
|
|
250
|
+
|
|
251
|
+
* (publish workflow) create draft release in GitHub
|
|
252
|
+
* (release.py prompts) publish release in GitHub
|
|
246
253
|
* (release.py) bump versions from ``y`` to ``(y + 1).dev0``, add ``(y + 1)`` changelog section
|
|
247
|
-
* (release.py prompts) trigger Read the Docs build for `<major>.x` (doesn't happen automatically)
|
|
248
254
|
|
|
249
255
|
|
|
250
256
|
|
|
@@ -109,11 +109,13 @@ Use the following command to update *reader*
|
|
|
109
109
|
pip install --upgrade reader
|
|
110
110
|
|
|
111
111
|
|
|
112
|
+
.. _install-pre-release:
|
|
113
|
+
|
|
112
114
|
Living on the edge
|
|
113
115
|
~~~~~~~~~~~~~~~~~~
|
|
114
116
|
|
|
115
117
|
If you want to use the latest *reader* code before it’s released,
|
|
116
|
-
install or update from the master branch:
|
|
118
|
+
install or update from the ``master`` branch:
|
|
117
119
|
|
|
118
120
|
.. code-block:: bash
|
|
119
121
|
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["setuptools", "wheel"]
|
|
3
|
-
build-backend = "setuptools.build_meta"
|
|
4
|
-
|
|
5
1
|
[project]
|
|
6
2
|
name = "reader"
|
|
7
3
|
authors = [{name = "lemon24"}]
|
|
@@ -23,10 +19,10 @@ classifiers = [
|
|
|
23
19
|
"Programming Language :: Python",
|
|
24
20
|
"Programming Language :: Python :: 3",
|
|
25
21
|
"Programming Language :: Python :: 3 :: Only",
|
|
26
|
-
"Programming Language :: Python :: 3.10",
|
|
27
22
|
"Programming Language :: Python :: 3.11",
|
|
28
23
|
"Programming Language :: Python :: 3.12",
|
|
29
24
|
"Programming Language :: Python :: 3.13",
|
|
25
|
+
"Programming Language :: Python :: 3.14",
|
|
30
26
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
31
27
|
"Programming Language :: Python :: Implementation :: PyPy",
|
|
32
28
|
"Topic :: Internet",
|
|
@@ -37,7 +33,7 @@ classifiers = [
|
|
|
37
33
|
"Topic :: Utilities",
|
|
38
34
|
"Typing :: Typed",
|
|
39
35
|
]
|
|
40
|
-
requires-python = ">=3.
|
|
36
|
+
requires-python = ">=3.11"
|
|
41
37
|
dependencies = [
|
|
42
38
|
"typing-extensions>=4",
|
|
43
39
|
"feedparser>=6",
|
|
@@ -53,19 +49,16 @@ dynamic = ["version"]
|
|
|
53
49
|
|
|
54
50
|
[project.urls]
|
|
55
51
|
Documentation = "https://reader.readthedocs.io/"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
52
|
+
Repository = "https://github.com/lemon24/reader"
|
|
53
|
+
Issues = "https://github.com/lemon24/reader/issues"
|
|
54
|
+
Changelog = "https://reader.readthedocs.io/en/latest/changelog.html"
|
|
59
55
|
|
|
60
56
|
[project.optional-dependencies]
|
|
61
57
|
|
|
62
|
-
# STABLE
|
|
63
|
-
|
|
64
|
-
search = [] # empty since 2.4, kept to avoid breaking dependents
|
|
65
|
-
readtime = [] # empty since 3.1, kept to avoid breaking dependents
|
|
66
|
-
|
|
67
58
|
# UNSTABLE
|
|
68
59
|
|
|
60
|
+
all = ["reader[cli,app,unstable-plugins]"]
|
|
61
|
+
|
|
69
62
|
cli = [
|
|
70
63
|
"click>=7",
|
|
71
64
|
# for config
|
|
@@ -73,8 +66,7 @@ cli = [
|
|
|
73
66
|
]
|
|
74
67
|
app = [
|
|
75
68
|
"flask>=0.10",
|
|
76
|
-
|
|
77
|
-
"humanize>=4,!=4.7.*",
|
|
69
|
+
"humanize>=4",
|
|
78
70
|
# for config
|
|
79
71
|
"PyYAML",
|
|
80
72
|
# for v2
|
|
@@ -82,8 +74,6 @@ app = [
|
|
|
82
74
|
"jinja2-fragments",
|
|
83
75
|
]
|
|
84
76
|
|
|
85
|
-
# UNSTABLE PLUGINS
|
|
86
|
-
|
|
87
77
|
# mushed together for convenience
|
|
88
78
|
unstable-plugins = [
|
|
89
79
|
# enclosure-tags
|
|
@@ -99,16 +89,14 @@ unstable-plugins = [
|
|
|
99
89
|
"tabulate",
|
|
100
90
|
]
|
|
101
91
|
|
|
102
|
-
|
|
92
|
+
[dependency-groups]
|
|
103
93
|
|
|
104
|
-
# run tests under one interpreter
|
|
105
94
|
tests = [
|
|
106
95
|
"pytest>=4",
|
|
107
96
|
"pytest-randomly",
|
|
108
97
|
"pytest-subtests",
|
|
109
98
|
"pytest-rerunfailures",
|
|
110
99
|
"coverage",
|
|
111
|
-
"pytest-cov",
|
|
112
100
|
"requests-mock",
|
|
113
101
|
# mechanicalsoup hard-depends on lxml (see below)
|
|
114
102
|
'mechanicalsoup; (implementation_name != "pypy" and python_version <= "3.12")',
|
|
@@ -120,35 +108,38 @@ tests = [
|
|
|
120
108
|
"html5lib",
|
|
121
109
|
# for bench.py
|
|
122
110
|
'numpy; (implementation_name != "pypy" and os_name == "posix" and python_version <= "3.12")',
|
|
123
|
-
|
|
124
|
-
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
typing = [
|
|
114
|
+
'mypy',
|
|
125
115
|
"types-requests",
|
|
126
116
|
"types-beautifulsoup4",
|
|
127
117
|
]
|
|
128
118
|
|
|
129
|
-
# build docs
|
|
130
119
|
docs = [
|
|
131
120
|
"sphinx",
|
|
132
|
-
|
|
133
|
-
# https://github.com/readthedocs/sphinx_rtd_theme/pull/1464#issuecomment-1664799982
|
|
134
|
-
"sphinx-rtd-theme>=1.3.0rc1",
|
|
121
|
+
"sphinx-rtd-theme",
|
|
135
122
|
"click>=7",
|
|
136
123
|
"sphinx-click",
|
|
137
|
-
"sphinx-hoverxref",
|
|
138
124
|
"sphinxcontrib-log-cabinet",
|
|
139
125
|
# for read_configuration used in conf.py
|
|
140
126
|
"setuptools",
|
|
141
127
|
]
|
|
142
128
|
|
|
143
|
-
# things needed to develop / test locally / make releases
|
|
144
129
|
dev = [
|
|
145
|
-
"
|
|
130
|
+
{include-group = "tests"},
|
|
131
|
+
{include-group = "typing"},
|
|
132
|
+
{include-group = "docs"},
|
|
146
133
|
"tox",
|
|
147
134
|
"pre-commit",
|
|
148
135
|
"build",
|
|
149
136
|
"twine",
|
|
150
137
|
]
|
|
151
138
|
|
|
139
|
+
[build-system]
|
|
140
|
+
requires = ["setuptools", "wheel"]
|
|
141
|
+
build-backend = "setuptools.build_meta"
|
|
142
|
+
|
|
152
143
|
[tool.setuptools.dynamic]
|
|
153
144
|
version = {attr = "reader.__version__"}
|
|
154
145
|
|
|
@@ -171,9 +162,16 @@ source = ["reader", "tests"]
|
|
|
171
162
|
omit = [
|
|
172
163
|
"src/reader/_vendor/*",
|
|
173
164
|
]
|
|
165
|
+
# TODO: remove when https://github.com/nedbat/coveragepy/issues/1987 is solved
|
|
166
|
+
core = "ctrace"
|
|
174
167
|
[tool.coverage.paths]
|
|
175
168
|
source = ["src", "*/site-packages"]
|
|
176
169
|
|
|
170
|
+
[tool.mypy]
|
|
171
|
+
files = ["src"]
|
|
172
|
+
show_error_codes = true
|
|
173
|
+
pretty = true
|
|
174
|
+
strict = true
|
|
177
175
|
[[tool.mypy.overrides]]
|
|
178
176
|
module = [
|
|
179
177
|
"reader.__main__",
|
|
@@ -189,7 +187,7 @@ ignore_errors = true
|
|
|
189
187
|
|
|
190
188
|
[tool.isort]
|
|
191
189
|
profile = "black"
|
|
192
|
-
py_version =
|
|
190
|
+
py_version = 311
|
|
193
191
|
src_paths = ["src", "tests"]
|
|
194
192
|
extend_skip = ["examples", "src/reader/_vendor"]
|
|
195
193
|
skip_gitignore = true
|
reader-3.19/run.sh
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# usage: ./run.sh command [argument ...]
|
|
4
|
+
#
|
|
5
|
+
# Executable documentation for the development workflow.
|
|
6
|
+
#
|
|
7
|
+
# See https://death.andgravity.com/run-sh for how this works.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# preamble
|
|
11
|
+
|
|
12
|
+
set -o nounset
|
|
13
|
+
set -o pipefail
|
|
14
|
+
set -o errexit
|
|
15
|
+
|
|
16
|
+
PROJECT_ROOT=${0%/*}
|
|
17
|
+
if [[ $0 != $PROJECT_ROOT && $PROJECT_ROOT != "" ]]; then
|
|
18
|
+
cd "$PROJECT_ROOT"
|
|
19
|
+
fi
|
|
20
|
+
readonly PROJECT_ROOT=$( pwd )
|
|
21
|
+
readonly SCRIPT="$PROJECT_ROOT/$( basename "$0" )"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# main development workflow
|
|
25
|
+
|
|
26
|
+
function install {
|
|
27
|
+
pip install -e '.[all]' --group dev --upgrade --upgrade-strategy eager
|
|
28
|
+
pre-commit install --install-hooks
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function test {
|
|
32
|
+
pytest --runslow "$@"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function test-all {
|
|
36
|
+
tox run-parallel "$@"
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function coverage {
|
|
40
|
+
unset -f coverage
|
|
41
|
+
coverage run -m pytest --runslow "$@"
|
|
42
|
+
coverage html
|
|
43
|
+
coverage-report
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function typing {
|
|
47
|
+
mypy "$@"
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function docs {
|
|
51
|
+
sphinx-build -E -W docs docs/_build/html "$@"
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# "watch" versions of the main commands
|
|
56
|
+
|
|
57
|
+
function test-dev {
|
|
58
|
+
watch pytest "$@"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function typing-dev {
|
|
62
|
+
watch typing "$@"
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function docs-dev {
|
|
66
|
+
rm -r docs/_build/html
|
|
67
|
+
watch sphinx-build -W docs docs/_build/html "$@"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function serve-dev {
|
|
71
|
+
export READER_DB=db.sqlite
|
|
72
|
+
flask -A reader._app.wsgi --debug run "$@"
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# low level commands
|
|
77
|
+
|
|
78
|
+
function coverage-report {
|
|
79
|
+
# --fail-under only for the library, not the CLI or the web app
|
|
80
|
+
unset -f coverage
|
|
81
|
+
coverage report \
|
|
82
|
+
--omit "$(
|
|
83
|
+
echo "
|
|
84
|
+
*/reader/_vendor/*
|
|
85
|
+
*/reader/__main__.py
|
|
86
|
+
*/reader/_cli*
|
|
87
|
+
*/reader/_config*
|
|
88
|
+
*/reader/_app/*
|
|
89
|
+
*/reader/_plugins/*
|
|
90
|
+
tests/*
|
|
91
|
+
" | xargs echo | sed 's/ /,/g'
|
|
92
|
+
)" \
|
|
93
|
+
--skip-covered \
|
|
94
|
+
--show-missing \
|
|
95
|
+
--fail-under $( on-pypy && echo 99 || echo 100 )
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# utilities
|
|
100
|
+
|
|
101
|
+
function on-pypy {
|
|
102
|
+
[[ $( python -c 'import sys; print(sys.implementation.name)' ) == pypy ]]
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function watch {
|
|
106
|
+
entr-project-files -cdr "$SCRIPT" "$@"
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function entr-project-files {
|
|
110
|
+
set +o errexit
|
|
111
|
+
while true; do
|
|
112
|
+
ls-project-files | entr "$@"
|
|
113
|
+
if [[ $? -eq 0 ]]; then
|
|
114
|
+
break
|
|
115
|
+
fi
|
|
116
|
+
done
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function ls-project-files {
|
|
120
|
+
git ls-files "$@"
|
|
121
|
+
git ls-files --exclude-standard --others "$@"
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
"$@"
|
|
@@ -34,11 +34,6 @@ def run_tox():
|
|
|
34
34
|
run_no_venv('tox -p all', shell=True)
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
def build():
|
|
38
|
-
run('rm -rf dist/', shell=True)
|
|
39
|
-
run('python -m build', shell=True)
|
|
40
|
-
|
|
41
|
-
|
|
42
37
|
def path_sub(pattern, repl, path):
|
|
43
38
|
with open(path) as f:
|
|
44
39
|
text = f.read()
|
|
@@ -112,10 +107,6 @@ def check_unpushed():
|
|
|
112
107
|
abort("unpushed changes\n\n{}\n", p.stdout.strip('\n'))
|
|
113
108
|
|
|
114
109
|
|
|
115
|
-
def upload_to_pypi():
|
|
116
|
-
run('twine upload dist/*', shell=True)
|
|
117
|
-
|
|
118
|
-
|
|
119
110
|
def add_and_push_tags(tags):
|
|
120
111
|
for tag in tags:
|
|
121
112
|
run(['git', 'tag', '--force', tag])
|
|
@@ -150,10 +141,6 @@ def main(version, new_version, date, tox, changelog):
|
|
|
150
141
|
|
|
151
142
|
confirm("Wait for GitHub Actions / Read the Docs builds to pass.")
|
|
152
143
|
|
|
153
|
-
confirm("Upload to PyPI?")
|
|
154
|
-
build()
|
|
155
|
-
upload_to_pypi()
|
|
156
|
-
|
|
157
144
|
tags = [version]
|
|
158
145
|
version_x = version.partition('.')[0] + '.x'
|
|
159
146
|
if new_version_is_final:
|
|
@@ -162,7 +149,15 @@ def main(version, new_version, date, tox, changelog):
|
|
|
162
149
|
confirm(f"Add and push tags ({', '.join(tags)})?")
|
|
163
150
|
add_and_push_tags(tags)
|
|
164
151
|
|
|
165
|
-
confirm(
|
|
152
|
+
confirm(
|
|
153
|
+
"Approve publish workflow to upload to PyPI.\n {}\nDone?",
|
|
154
|
+
"https://github.com/lemon24/reader/actions/workflows/publish.yaml",
|
|
155
|
+
)
|
|
156
|
+
confirm(
|
|
157
|
+
"Publish draft release {} in GitHub.\n {}\nDone?",
|
|
158
|
+
version,
|
|
159
|
+
"https://github.com/lemon24/reader/releases",
|
|
160
|
+
)
|
|
166
161
|
|
|
167
162
|
new_version_full = f"{new_version}.dev0"
|
|
168
163
|
update_init_version(new_version_full)
|
|
@@ -173,11 +168,6 @@ def main(version, new_version, date, tox, changelog):
|
|
|
173
168
|
confirm("Push version {}?", new_version_full)
|
|
174
169
|
push()
|
|
175
170
|
|
|
176
|
-
# TODO: I just enabled branch or tag creation/deletion for the RtD webhook in GitHub, this might not be needed next time.
|
|
177
|
-
confirm(
|
|
178
|
-
f"Trigger Read the Docs build for {version_x} (doesn't happen automatically)."
|
|
179
|
-
)
|
|
180
|
-
|
|
181
171
|
|
|
182
172
|
if __name__ == '__main__':
|
|
183
173
|
main()
|
|
@@ -37,7 +37,7 @@ Print the titles of the unread entries::
|
|
|
37
37
|
|
|
38
38
|
"""
|
|
39
39
|
|
|
40
|
-
__version__ = '3.
|
|
40
|
+
__version__ = '3.19'
|
|
41
41
|
|
|
42
42
|
# isort: off
|
|
43
43
|
|
|
@@ -58,6 +58,9 @@ from .types import (
|
|
|
58
58
|
FeedCounts as FeedCounts,
|
|
59
59
|
EntryCounts as EntryCounts,
|
|
60
60
|
EntrySearchCounts as EntrySearchCounts,
|
|
61
|
+
FeedSort as FeedSort,
|
|
62
|
+
EntrySort as EntrySort,
|
|
63
|
+
EntrySearchSort as EntrySearchSort,
|
|
61
64
|
UpdateResult as UpdateResult,
|
|
62
65
|
UpdatedFeed as UpdatedFeed,
|
|
63
66
|
EntryUpdateStatus as EntryUpdateStatus,
|
|
@@ -239,13 +239,9 @@ class NotModified(RetrieveError):
|
|
|
239
239
|
_default_message = "not modified"
|
|
240
240
|
|
|
241
241
|
|
|
242
|
-
|
|
243
|
-
class RetrieveResult(_namedtuple_compat, Generic[F, T, E]):
|
|
242
|
+
class RetrieveResult(NamedTuple, Generic[F, T, E]):
|
|
244
243
|
"""The result of retrieving a feed, regardless of the outcome."""
|
|
245
244
|
|
|
246
|
-
# should be a NamedTuple, but the typing one became generic only in 3.11,
|
|
247
|
-
# and we don't want to depend on typing_extensions at runtime
|
|
248
|
-
|
|
249
245
|
#: The feed (a :class:`FeedArgument`, usually a :class:`FeedForUpdate`).
|
|
250
246
|
feed: F
|
|
251
247
|
|
|
@@ -339,8 +335,7 @@ class FeedForUpdateRetrieverType(RetrieverType[T_co], Protocol): # pragma: no c
|
|
|
339
335
|
"""
|
|
340
336
|
|
|
341
337
|
|
|
342
|
-
|
|
343
|
-
class ParseResult(_namedtuple_compat, Generic[F, E]):
|
|
338
|
+
class ParseResult(NamedTuple, Generic[F, E]):
|
|
344
339
|
"""The result of retrieving and parsing a feed, regardless of the outcome."""
|
|
345
340
|
|
|
346
341
|
#: The feed (a :class:`FeedArgument`, usually a :class:`.FeedForUpdate`).
|
|
@@ -4,6 +4,7 @@ from collections.abc import Sequence
|
|
|
4
4
|
from dataclasses import dataclass
|
|
5
5
|
from dataclasses import field
|
|
6
6
|
from typing import Any
|
|
7
|
+
from typing import Self
|
|
7
8
|
from typing import TYPE_CHECKING
|
|
8
9
|
from typing import TypeVar
|
|
9
10
|
|
|
@@ -14,8 +15,6 @@ from . import TimeoutType
|
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
if TYPE_CHECKING: # pragma: no cover
|
|
17
|
-
from typing_extensions import Self
|
|
18
|
-
|
|
19
18
|
from . import Headers
|
|
20
19
|
from . import RequestHook
|
|
21
20
|
from . import ResponseHook
|