Last active
October 26, 2021 12:28
-
-
Save lemon24/047f71abe76c47661634459eada7b50a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
API proposals for Reader.add_entry(). | |
""" | |
### 1a: one-shot add entry | |
reader.add_entry( | |
feed_url='https://explainxkcd.com/rss.xml', | |
id='http://www.explainxkcd.com/2433', | |
updated=now, | |
content=[Content(html, type='text/html')], | |
) | |
### 1b: build entry to add, add_entry() options | |
# entry is dict[str, Any] | |
entry_data = { | |
feed_url='https://explainxkcd.com/rss.xml', | |
id='http://www.explainxkcd.com/2433', | |
} | |
if whatever: | |
entry_data['updated'] = now | |
entry_data['summary'] = html | |
reader.add_entry(**entry_data, update_if_exists=True) | |
### 1c: add existing entry | |
entry = reader.get_entry(...) | |
entry_data = vars(entry) | |
entry_data['id'] += 'suffix' | |
# otherwise we get "add_entry() got an unexpected keyword argument 'read'" | |
for attr in ('read', 'read_modified', 'important', 'important_modified', ...): | |
entry_data.pop(attr) | |
reader.add_entry(**entry_data) | |
### 2a: one-shot add entry | |
from reader import EntryData | |
reader.add_entry( | |
EntryData( | |
feed_url='https://explainxkcd.com/rss.xml', | |
id='http://www.explainxkcd.com/2433', | |
updated=now, | |
content=[Content(html, type='text/html')], | |
) | |
) | |
### 2b: build entry to add, add_entry() options | |
from reader import EntryData | |
# entry is EntryData (with type-annotated attributes), | |
# but any objects with those attributes works too | |
entry = EntryData( | |
feed_url='https://explainxkcd.com/rss.xml', | |
id='http://www.explainxkcd.com/2433', | |
) | |
if whatever: | |
entry.updated = now | |
content.summary = html | |
reader.add_entry(entry, update_if_exists=True) | |
### 2c: add existing entry | |
from reader import EntryData | |
entry = reader.get_entry(...) | |
entry.id += 'suffix' | |
# add_entry() just looks at the attributes it cares about | |
reader.add_entry(entry) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
An example of how to model a Union[EntryDataLikeProtocol, EntryDataTypedDict] argument. | |
""" | |
from dataclasses import dataclass | |
from types import SimpleNamespace | |
from typing import Optional | |
from typing import Union | |
from typing_extensions import Protocol | |
from typing_extensions import TypedDict | |
class EntryDataLike(Protocol): | |
"""An object that looks like EntryData.""" | |
@property | |
def feed_url(self) -> str: | |
... | |
@property | |
def id(self) -> str: | |
... | |
@property | |
def title(self) -> Optional[str]: | |
# presumably, this can be missing, but I don't know how to model it | |
... | |
class EntryDataDictBase(TypedDict): | |
feed_url: str | |
id: str | |
class EntryDataDict(EntryDataDictBase, total=False): | |
"""A dict that looks like EntryData. | |
Notably, optional EntryData attributes can be missing entirely. | |
""" | |
title: Optional[str] | |
EntryDataInput = Union[EntryDataLike, EntryDataDict] | |
def add_entry(entry: EntryDataInput) -> None: | |
... | |
@dataclass | |
class ClassWithoutTitle: | |
feed_url: str | |
id: str | |
@dataclass | |
class ClassWithTitle(ClassWithoutTitle): | |
title: Optional[str] = None | |
# Error! missing protocol member: title | |
# in reality, this will work, we just can't type it | |
# (PEP 544 postpones optional protocol members) | |
add_entry(ClassWithoutTitle('id', 'feed')) | |
# OK | |
add_entry(ClassWithTitle('id', 'feed')) | |
# OK | |
add_entry({'id': 'id', 'feed_url': 'feed'}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment