more type hints

This commit is contained in:
Henri Dickson 2024-05-31 11:15:10 -04:00
parent b644efd93f
commit 20ca5fa240
7 changed files with 25 additions and 20 deletions

View file

@ -4,7 +4,7 @@ import re
import time import time
from io import BytesIO, StringIO from io import BytesIO, StringIO
from pathlib import Path from pathlib import Path
from typing import Tuple from typing import Tuple, cast
from urllib.parse import quote from urllib.parse import quote
import filetype import filetype
@ -93,10 +93,6 @@ class MockResponse:
} }
requests.Response.html = MockResponse.html # type:ignore
requests.Response.xml = MockResponse.xml # type:ignore
class DownloaderResponse(Response): class DownloaderResponse(Response):
def html(self): def html(self):
return html.fromstring( # may throw exception unexpectedly due to OS bug, see https://github.com/neodb-social/neodb/issues/5 return html.fromstring( # may throw exception unexpectedly due to OS bug, see https://github.com/neodb-social/neodb/issues/5
@ -159,8 +155,9 @@ class BasicDownloader:
def _download(self, url) -> Tuple[DownloaderResponse | MockResponse | None, int]: def _download(self, url) -> Tuple[DownloaderResponse | MockResponse | None, int]:
try: try:
if not _mock_mode: if not _mock_mode:
resp = requests.get( resp = cast(
url, headers=self.headers, timeout=self.get_timeout() DownloaderResponse,
requests.get(url, headers=self.headers, timeout=self.get_timeout()),
) )
if settings.DOWNLOADER_SAVEDIR: if settings.DOWNLOADER_SAVEDIR:
try: try:
@ -179,7 +176,7 @@ class BasicDownloader:
{"response_type": response_type, "url": url, "exception": None} {"response_type": response_type, "url": url, "exception": None}
) )
return resp, response_type # type: ignore return resp, response_type
except RequestException as e: except RequestException as e:
self.logs.append( self.logs.append(
{"response_type": RESPONSE_NETWORK_ERROR, "url": url, "exception": e} {"response_type": RESPONSE_NETWORK_ERROR, "url": url, "exception": e}

View file

@ -623,6 +623,7 @@ class ExternalResource(models.Model):
if TYPE_CHECKING: if TYPE_CHECKING:
required_resources: list[dict[str, str]] required_resources: list[dict[str, str]]
related_resources: list[dict[str, str]] related_resources: list[dict[str, str]]
prematched_resources: list[dict[str, str]]
item = models.ForeignKey( item = models.ForeignKey(
Item, null=True, on_delete=models.SET_NULL, related_name="external_resources" Item, null=True, on_delete=models.SET_NULL, related_name="external_resources"
) )
@ -659,7 +660,7 @@ class ExternalResource(models.Model):
prematched_resources = jsondata.ArrayField( prematched_resources = jsondata.ArrayField(
models.CharField(), null=False, blank=False, default=list models.CharField(), null=False, blank=False, default=list
) ) # type: ignore
"""links to help match an existing Item from this resource""" """links to help match an existing Item from this resource"""
class Meta: class Meta:

View file

@ -118,7 +118,7 @@ class AbstractSite:
2. look for Item by primary_lookup_id_type and primary_lookup_id_value 2. look for Item by primary_lookup_id_type and primary_lookup_id_value
""" """
for resource_link in resource.prematched_resources: # type: ignore for resource_link in resource.prematched_resources:
url = resource_link.get("url") url = resource_link.get("url")
if url: if url:
matched_resource = ExternalResource.objects.filter(url=url).first() matched_resource = ExternalResource.objects.filter(url=url).first()
@ -247,7 +247,7 @@ class AbstractSite:
p.item.save() p.item.save()
self.scrape_additional_data() self.scrape_additional_data()
if auto_link: if auto_link:
for linked_resource in p.required_resources: # type: ignore for linked_resource in p.required_resources:
linked_url = linked_resource.get("url") linked_url = linked_resource.get("url")
if linked_url: if linked_url:
linked_site = SiteManager.get_site_by_url(linked_url) linked_site = SiteManager.get_site_by_url(linked_url)
@ -266,7 +266,7 @@ class AbstractSite:
return p return p
T = TypeVar("T") T = TypeVar("T", bound=AbstractSite)
class SiteManager: class SiteManager:
@ -274,7 +274,7 @@ class SiteManager:
@staticmethod @staticmethod
def register(target: Type[T]) -> Type[T]: def register(target: Type[T]) -> Type[T]:
id_type = target.ID_TYPE # type: ignore id_type = target.ID_TYPE
if id_type in SiteManager.registry: if id_type in SiteManager.registry:
raise ValueError(f"Site for {id_type} already exists") raise ValueError(f"Site for {id_type} already exists")
SiteManager.registry[id_type] = target SiteManager.registry[id_type] = target
@ -322,7 +322,7 @@ class SiteManager:
return cls(url) if cls else None return cls(url) if cls else None
@staticmethod @staticmethod
def get_site_by_id(id_type: IdType, id_value: str) -> AbstractSite | None: def get_site_by_id(id_type: IdType | str, id_value: str) -> AbstractSite | None:
if id_type not in SiteManager.registry: if id_type not in SiteManager.registry:
return None return None
cls = SiteManager.registry[id_type] cls = SiteManager.registry[id_type]
@ -338,8 +338,8 @@ def crawl_related_resources_task(resource_pk):
if not resource: if not resource:
logger.warning(f"crawl resource not found {resource_pk}") logger.warning(f"crawl resource not found {resource_pk}")
return return
links = (resource.related_resources or []) + (resource.prematched_resources or []) # type: ignore links = (resource.related_resources or []) + (resource.prematched_resources or [])
for w in links: # type: ignore for w in links:
try: try:
item = None item = None
site = None site = None

View file

@ -1,5 +1,5 @@
from functools import cached_property from functools import cached_property
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Self
import django.dispatch import django.dispatch
from django.db import models from django.db import models
@ -73,7 +73,7 @@ class List(Piece):
e.g. collection.append_item(item, note="abc") works, but collection.append_item(item, metadata={"note":"abc"}) doesn't e.g. collection.append_item(item, note="abc") works, but collection.append_item(item, metadata={"note":"abc"}) doesn't
""" """
if item is None: if item is None:
return None raise ValueError("item is None")
member = self.get_member_for_item(item) member = self.get_member_for_item(item)
if member: if member:
return member return member

View file

@ -22,6 +22,7 @@ class CollectionTest(TestCase):
collection = Collection.objects.get(title="test", owner=self.user.identity) collection = Collection.objects.get(title="test", owner=self.user.identity)
self.assertEqual(collection.catalog_item.title, "test") self.assertEqual(collection.catalog_item.title, "test")
member1 = collection.append_item(self.book1) member1 = collection.append_item(self.book1)
self.assertIsNotNone(member1)
member1.note = "my notes" member1.note = "my notes"
member1.save() member1.save()
collection.append_item(self.book2, note="test") collection.append_item(self.book2, note="test")
@ -34,8 +35,14 @@ class CollectionTest(TestCase):
collection.update_member_order([members[1].id, members[0].id]) collection.update_member_order([members[1].id, members[0].id])
self.assertEqual(list(collection.ordered_items), [self.book1, self.book2]) self.assertEqual(list(collection.ordered_items), [self.book1, self.book2])
member1 = collection.get_member_for_item(self.book1) member1 = collection.get_member_for_item(self.book1)
self.assertIsNotNone(member1)
if member1 is None:
return
self.assertEqual(member1.note, "my notes") self.assertEqual(member1.note, "my notes")
member2 = collection.get_member_for_item(self.book2) member2 = collection.get_member_for_item(self.book2)
self.assertIsNotNone(member2)
if member2 is None:
return
self.assertEqual(member2.note, "test") self.assertEqual(member2.note, "test")

View file

@ -117,7 +117,7 @@ class WrappedShareView(LoginRequiredMixin, TemplateView):
comment = request.POST.get("comment", "") comment = request.POST.get("comment", "")
visibility = int(request.POST.get("visibility", 0)) visibility = int(request.POST.get("visibility", 0))
user: User = request.user # type: ignore user: User = request.user # type: ignore
identity = user.identity # type: ignore identity = user.identity
media = Takahe.upload_image( media = Takahe.upload_image(
identity.pk, "year.png", img, "image/png", "NeoDB Yearly Summary" identity.pk, "year.png", img, "image/png", "NeoDB Yearly Summary"
) )

View file

@ -11,7 +11,7 @@ profile = "black"
[tool.mypy] [tool.mypy]
exclude = [ exclude = [
'^neodb/', '^neodb-takahe/',
'^legacy/', '^legacy/',
] ]
plugins = ["mypy_django_plugin.main"] plugins = ["mypy_django_plugin.main"]