Reader

Latest version: v3.16

Safety actively analyzes 706267 Python packages for vulnerabilities to keep your Python projects secure.

Scan your dependencies

Page 6 of 14

2.5

-----------

Released 2021-10-28

* In :meth:`~Reader.add_feed` and :meth:`~Reader.change_feed_url`,
validate if the current Reader configuration can handle the new feed URL;
if not, raise :exc:`InvalidFeedURLError` (a :exc:`ValueError` subclass).
(:issue:`155`)

.. warning::

**This is a minor compatibility break**; previously,
:exc:`ValueError` would never be raised for :class:`str` arguments.
To get the previous behavior (no validation),
use ``allow_invalid_url=True``.

* Allow users to add entries to an existing feed
through the new :meth:`~Reader.add_entry` method.
Allow deleting user-added entries through :meth:`~Reader.delete_entry`.
(:issue:`239`)
* Add the :attr:`~Entry.added` and :attr:`~Entry.added_by` Entry attributes.
(:issue:`239`)

* :attr:`Entry.updated` is now :const:`None` if missing in the feed
(:attr:`~Entry.updated` became optional in `version 2.0`_).
Use :attr:`~Entry.updated_not_none` for the pre-2.5 behavior.
Do not swap :attr:`Entry.published` with :attr:`Entry.updated`
for RSS feeds where :attr:`~Entry.updated` is missing.
(:issue:`183`)

* Support PyPy 3.8.

* Fix bug causing
:attr:`~Entry.read_modified` and :attr:`~Entry.important_modified`
to be reset to :const:`None` when an entry is updated.
* Fix bug where deleting an entry and then adding it again
(with the same id) would fail
if search was enabled and :meth:`~Reader.update_search`
was not run before adding the new entry.

2.4

-----------

Released 2021-10-19

* Enable search by default. (:issue:`252`)

* Add the ``search_enabled`` :func:`make_reader` argument.
By default, search is enabled on the first
:meth:`~Reader.update_search` call;
the previous behavior was to do nothing.
* Always install the full-text search dependencies (previously optional).
The ``search`` extra remains available to avoid breaking dependent packages.

* Add the :attr:`~Feed.subtitle` and :attr:`~Feed.version` Feed attributes.
(:issue:`223`)

* Change the :mod:`~reader.plugins.mark_as_read` plugin to also
explicitly mark matching entries as unimportant,
similar to how the *don't care* web application button works.
(:issue:`260`)

* In the web application, show the feed subtitle.
(:issue:`223`)

2.3

-----------

Released 2021-10-11

* Support Python 3.10. (:issue:`248`)

* :mod:`~reader.plugins.entry_dedupe` now
deletes old duplicates instead of marking them as read/unimportant.
(:issue:`140`)

.. note::

Please comment in :issue:`140` / open an issue
if you were relying on the old behavior.

* .. _yanked 2.2:

Fix :mod:`~reader.plugins.entry_dedupe` bug introduced in 2.2,
causing the newest read entry to be marked as unread
if none of its duplicates are read (idem for important).
This was an issue *only when re-running the plugin for existing entries*,
not for new entries (since new entries are unread/unimportant).

2.2

-----------

Released 2021-10-08

* :mod:`~reader.plugins.entry_dedupe` plugin improvements:
reduce false negatives by using approximate content matching,
and make it possible to re-run the plugin for existing entries.
(:issue:`202`)
* Allow running arbitrary actions for updated feeds
via :attr:`~Reader.after_feed_update_hooks`.
(:issue:`202`)

* Add :meth:`~Reader.set_entry_read` and :meth:`~Reader.set_entry_important`
to allow marking an entry as (un)read/(un)important through a boolean flag.
(:issue:`256`)

* Record when an entry is marked as read/important,
and make it available through :attr:`~Entry.read_modified` and
:attr:`~Entry.important_modified`.
Allow providing a custom value using the ``modified``
argument of :meth:`~Reader.set_entry_read`
and :meth:`~Reader.set_entry_important`.
(:issue:`254`)
* Make :mod:`~reader.plugins.entry_dedupe` copy
:attr:`~Entry.read_modified` and :attr:`~Entry.important_modified`
from the duplicates to the new entry.
(:issue:`254`)

* In the web application, allow marking an entry as *don't care*
(read + unimportant explicitly set by the user) with a single button.
(:issue:`254`)
* In the web application, show the entry read modified / important modified
timestamps as button tooltips.
(:issue:`254`)

2.1

-----------

Released 2021-08-18

* Return :ref:`entry averages <entry averages>` for the past 1, 3, 12 months
from the entry count methods. (:issue:`249`)

* Use an index for ``get_entry_counts(feed=...)`` calls.
Makes the /feeds?counts=yes page load 2-4x faster. (:issue:`251`)

* Add :class:`UpdateResult` :attr:`~UpdateResult.updated_feed`,
:attr:`~UpdateResult.error`, and :attr:`~UpdateResult.not_modified`
convenience properties. (:issue:`204`)

* In the web application, show the feed entry count averages as a bar sparkline.
(:issue:`249`)

* Make the minimum SQLite version and required SQLite compile options
``reader._storage`` module globals, for easier monkeypatching. (:issue:`163`)

This is allows supplying a user-defined ``json_array_length`` function
on platforms where SQLite doesn't come with the JSON1 extension
(e.g. on Windows with stock Python earlier than 3.9;
`details <https://github.com/lemon24/reader/issues/163#issuecomment-895041943>`_).

Note these globals are private, and thus *not* covered by the
:ref:`backwards compatibility policy <compat>`.

2.0

-----------

Released 2021-07-17


.. attention::

This release contains backwards incompatible changes.


* Remove old database migrations.

If you are upgrading from *reader* 1.15 or newer, no action is required.

.. _removed migrations 2.0:

.. attention::

If you are upgrading to *reader* 2.0 from a version **older than 1.15**,
you must open your database with *reader* 1.15 or newer once,
to run the removed migrations:

.. code-block:: sh

pip install 'reader>=1.15,<2' && \
python - db.sqlite << EOF
import sys
from reader import make_reader
make_reader(sys.argv[1])
print("OK")
EOF

* Remove code that issued deprecation warnings in versions 1.* (:issue:`183`):

* :meth:`Reader.remove_feed`
* :meth:`Reader.mark_as_read`
* :meth:`Reader.mark_as_unread`
* :meth:`Reader.mark_as_important`
* :meth:`Reader.mark_as_unimportant`
* :meth:`Reader.iter_feed_metadata`
* the ``get_feed_metadata(feed, key, default=no value, /)``
form of :meth:`Reader.get_feed_metadata`
* :meth:`Reader.set_feed_metadata`
* :meth:`Reader.delete_feed_metadata`
* the ``new_only`` parameter of
:meth:`~Reader.update_feeds()` and :meth:`~Reader.update_feeds_iter()`
* :attr:`EntryError.url`
* :attr:`UpdatedFeed.updated`

* The :class:`~datetime.datetime` attributes
of :class:`Feed` and :class:`Entry` objects are now timezone-aware,
with the timezone set to :attr:`~datetime.timezone.utc`.
Previously, they were naive datetimes representing UTC times.
(:issue:`233`)

* The parameters of
:meth:`~Reader.update_feeds()` and :meth:`~Reader.update_feeds_iter()`
are now keyword-only. (:issue:`183`)

* The ``feed_root`` argument of :func:`make_reader`
now defaults to ``None`` (don't open local feeds)
instead of ``''`` (full filesystem access).

* :func:`make_reader` may now raise any :exc:`ReaderError`,
not just :exc:`StorageError`.

* :attr:`Entry.updated` may now be :const:`None`;
use :attr:`~Entry.updated_not_none` for the pre-2.0 behavior.

Page 6 of 14

© 2025 Safety CLI Cybersecurity Inc. All Rights Reserved.