Skip to content

Commit d46aae0

Browse files
committed
reader.opml.Feed -> reader.FeedToImport. #165
1 parent d17a055 commit d46aae0

7 files changed

Lines changed: 42 additions & 44 deletions

File tree

docs/api.rst

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ Data objects
6767
.. autoclass:: EntryUpdateStatus
6868
:members:
6969

70+
.. autoclass:: FeedToImport
71+
:members:
72+
:undoc-members:
73+
7074
.. autoclass:: FeedImportResult
7175
:members:
7276

@@ -162,11 +166,11 @@ Exceptions
162166
.. autoexception:: PluginInitError
163167
:show-inheritance:
164168

165-
166-
.. autoexception:: ReaderWarning
169+
.. autoexception:: FeedImportError
167170
:show-inheritance:
168171

169-
.. autoexception:: FeedImportError
172+
173+
.. autoexception:: ReaderWarning
170174
:show-inheritance:
171175

172176

src/reader/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
UpdateResult as UpdateResult,
6565
UpdatedFeed as UpdatedFeed,
6666
EntryUpdateStatus as EntryUpdateStatus,
67+
FeedToImport as FeedToImport,
6768
FeedImportResult as FeedImportResult,
6869
FeedExport as FeedExport,
6970
)

src/reader/_app/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from reader import EntryNotFoundError
3131
from reader import FeedExistsError
3232
from reader import FeedNotFoundError
33+
from reader import FeedToImport
3334
from reader import InvalidFeedURLError
3435
from reader import opml
3536
from reader import UpdateError
@@ -290,7 +291,9 @@ def import_feeds():
290291
except opml.OPMLError as e:
291292
error = str(e)
292293
else:
293-
feeds = (opml.Feed(**json.loads(f)) for f in request.form.getlist('feed'))
294+
feeds = (
295+
FeedToImport(**json.loads(f)) for f in request.form.getlist('feed')
296+
)
294297
imported_feeds = list(reader.import_feeds_iter(feeds))
295298
# TODO: out of band update (unlike add, there's too many to do here)
296299

src/reader/core.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
from .types import FeedImportResult
7171
from .types import FeedInput
7272
from .types import FeedSort
73+
from .types import FeedToImport
7374
from .types import JSONType
7475
from .types import MISSING
7576
from .types import MissingType
@@ -80,7 +81,6 @@
8081
from .types import UpdateResult
8182

8283
if TYPE_CHECKING: # pragma: no cover
83-
from . import opml
8484
from ._parser import Parser
8585

8686

@@ -2207,12 +2207,12 @@ def import_feeds(self, file: IO[bytes], /) -> None:
22072207
pass
22082208

22092209
def import_feeds_iter(
2210-
self, feeds: Iterable[opml.Feed], /
2210+
self, feeds: Iterable[FeedToImport], /
22112211
) -> Iterable[FeedImportResult]:
22122212
"""Import feeds returned by :func:`reader.opml.parse`.
22132213
22142214
Args:
2215-
feeds (iterable(reader.opml.Feed)): The feeds to import.
2215+
feeds (iterable(FeedToImport)): The feeds to import.
22162216
22172217
Yields:
22182218
:class:`FeedImportResult`: The feed and whether it was added.

src/reader/opml.py

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,13 @@
55
66
.. _OPML: https://opml.org/spec2.opml
77
8-
98
.. autofunction:: parse
109
.. autofunction:: unparse
11-
12-
.. autoclass:: Feed
13-
:members:
14-
:undoc-members:
15-
1610
.. autoexception:: OPMLError
1711
:show-inheritance:
1812
19-
2013
.. versionadded:: 3.23
2114
22-
2315
.. todo::
2416
2517
* use text= as user_title (both directions)
@@ -33,43 +25,27 @@
3325
import re
3426
import xml.etree.ElementTree as etree
3527
from collections.abc import Iterable
36-
from dataclasses import dataclass
37-
from dataclasses import KW_ONLY
3828
from datetime import datetime
3929
from email.utils import format_datetime
4030
from typing import cast
4131
from typing import IO
4232

4333
import reader
44-
45-
46-
@dataclass
47-
class Feed:
48-
"""A feed in an OPML subscription list.
49-
50-
Attributes are similar to those of :class:`reader.Feed`.
51-
52-
"""
53-
54-
url: str
55-
_: KW_ONLY
56-
title: str | None = None
57-
link: str | None = None
58-
subtitle: str | None = None
34+
from reader.types import FeedToImport
5935

6036

6137
class OPMLError(reader.FeedImportError):
6238
"""An error occurred while parsing an OPML subscription list."""
6339

6440

65-
def parse(file: IO[bytes], max_depth: int = 10) -> list[Feed]:
41+
def parse(file: IO[bytes], max_depth: int = 10) -> list[FeedToImport]:
6642
"""Extract a list of feeds from an OPML subscription list.
6743
6844
Args:
6945
file (file): A binary file.
7046
7147
Returns:
72-
list(reader.opml.Feed): A list of feeds.
48+
list(FeedToImport): A list of feeds.
7349
7450
Raises:
7551
OPMLError:
@@ -88,7 +64,7 @@ def parse(file: IO[bytes], max_depth: int = 10) -> list[Feed]:
8864
if root.tag.lower() != 'opml':
8965
raise OPMLError(f"expected <opml> root tag, got: <{root.tag}>")
9066

91-
def walk(node: etree.Element, depth: int = 1) -> Iterable[Feed]:
67+
def walk(node: etree.Element, depth: int = 1) -> Iterable[FeedToImport]:
9268
if depth > max_depth:
9369
raise OPMLError("tag depth limit exceeded")
9470

@@ -100,7 +76,7 @@ def walk(node: etree.Element, depth: int = 1) -> Iterable[Feed]:
10076

10177
if tag == 'outline' and type == 'rss':
10278
if url := attrib.get('xmlurl'):
103-
yield Feed(
79+
yield FeedToImport(
10480
url,
10581
title=attrib.get('title', attrib.get('text')),
10682
link=attrib.get('htmlurl'),
@@ -154,7 +130,7 @@ def unparse(
154130
"""Convert a list of feeds to an OPML subscription list.
155131
156132
Args:
157-
feeds (list(reader.Feed)): An iterable of feeds.
133+
feeds (list(Feed)): An iterable of feeds.
158134
title (str or None): The list title.
159135
created (datetime or None): The list creation date.
160136

src/reader/types.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from collections.abc import Sequence
1111
from dataclasses import dataclass
1212
from dataclasses import field
13+
from dataclasses import KW_ONLY
1314
from datetime import datetime
1415
from types import MappingProxyType
1516
from typing import Any
@@ -19,7 +20,6 @@
1920
from typing import overload
2021
from typing import Protocol
2122
from typing import Self
22-
from typing import TYPE_CHECKING
2323
from typing import TypedDict
2424
from typing import Union
2525

@@ -31,9 +31,6 @@
3131
from reader._utils import MISSING as MISSING # isort: skip # noqa: F401
3232
from reader._utils import MissingType as MissingType # isort: skip # noqa: F401
3333

34-
if TYPE_CHECKING:
35-
from . import opml
36-
3734

3835
class _namedtuple_compat:
3936
"""Add namedtuple-like methods to a dataclass."""
@@ -1242,6 +1239,23 @@ class UpdateConfig(TypedDict, total=False):
12421239
jitter: float
12431240

12441241

1242+
@dataclass
1243+
class FeedToImport:
1244+
"""A feed to be imported.
1245+
1246+
Attributes are similar to those of :class:`Feed`.
1247+
1248+
.. versionadded:: 3.23
1249+
1250+
"""
1251+
1252+
url: str
1253+
_: KW_ONLY
1254+
title: str | None = None
1255+
link: str | None = None
1256+
subtitle: str | None = None
1257+
1258+
12451259
@dataclass(frozen=True)
12461260
class FeedImportResult:
12471261
"""The result of importing a single feed.
@@ -1251,7 +1265,7 @@ class FeedImportResult:
12511265
"""
12521266

12531267
#: The feed parsed from the import file.
1254-
feed: opml.Feed
1268+
feed: FeedToImport
12551269

12561270
#: Exception raised by :meth:`~add_feed`, if any.
12571271
exception: FeedError | None = None

tests/test_opml.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import pytest
44

5+
from reader import FeedImportError
56
from reader import InvalidFeedURLError
6-
from reader.opml import OPMLError
77
from reader.opml import parse
88
from reader.opml import unparse
99
from utils import utc_datetime as datetime
@@ -92,7 +92,7 @@ def test_empty():
9292
],
9393
)
9494
def test_parse_error(input, message):
95-
with pytest.raises(OPMLError, match=message):
95+
with pytest.raises(FeedImportError, match=message):
9696
parse(io.BytesIO(input.encode()), max_depth=3)
9797

9898

0 commit comments

Comments
 (0)