chore: update types + minor fixes

This commit is contained in:
relikd
2022-11-22 10:51:28 +01:00
parent b75102a211
commit e7ae59fadf
11 changed files with 46 additions and 34 deletions

View File

@@ -1,5 +1,5 @@
from lektor.context import get_ctx
from typing import TYPE_CHECKING, Union, Iterable, Iterator, Optional
from typing import TYPE_CHECKING, Set, Union, Iterable, Iterator
import weakref
from .util import split_strip
if TYPE_CHECKING:
@@ -13,6 +13,7 @@ if TYPE_CHECKING:
class WeakVGroupsList(list):
def add(self, strong: 'FieldKeyPath', weak: 'GroupBySource') -> None:
super().append((strong, weakref.ref(weak)))
# super().append((strong, weak)) # strong-ref
class GroupByRef:
@@ -71,11 +72,11 @@ class VGroups:
flows = [flows]
# find groups
proc_list = [record]
done_list = set()
done_list = set() # type: Set[GroupBySource]
while proc_list:
page = proc_list.pop(0)
if recursive and hasattr(page, 'children'):
proc_list.extend(page.children) # type: ignore[attr-defined]
proc_list.extend(page.children)
for key, vobj in VGroups.of(page):
if fields and key.fieldKey not in fields:
continue
@@ -87,11 +88,11 @@ class VGroups:
if order_by:
if isinstance(order_by, str):
order = split_strip(order_by, ',')
order = split_strip(order_by, ',') # type: Iterable[str]
elif isinstance(order_by, (list, tuple)):
order = order_by
else:
raise TypeError('order_by must be either str or list type.')
raise AttributeError('order_by must be str or list type.')
# using get_sort_key() of GroupBySource
yield from sorted(done_list, key=lambda x: x.get_sort_key(order))
else:

View File

@@ -4,9 +4,9 @@ from typing import TYPE_CHECKING, Set, List
from .config import Config
from .watcher import Watcher
if TYPE_CHECKING:
from .config import AnyConfig
from lektor.builder import Builder
from lektor.sourceobj import SourceObject
from .config import AnyConfig
from .resolver import Resolver
from .vobj import GroupBySource
@@ -55,9 +55,9 @@ class GroupBy:
while queue:
record = queue.pop()
if hasattr(record, 'attachments'):
queue.extend(record.attachments) # type: ignore[attr-defined]
queue.extend(record.attachments)
if hasattr(record, 'children'):
queue.extend(record.children) # type: ignore[attr-defined]
queue.extend(record.children)
if isinstance(record, Record):
for w in self._watcher:
if w.should_process(record):

View File

@@ -1,14 +1,20 @@
from lektor import datamodel
from typing import TYPE_CHECKING, Any
if TYPE_CHECKING:
from lektor.db import Record
from lektor.pagination import Pagination
from lektor.sourceobj import SourceObject
class PaginationConfig(datamodel.PaginationConfig):
# because original method does not work for virtual sources.
@staticmethod
def get_record_for_page(source: 'Record', page_num: int) -> Any:
def get_record_for_page(source: 'SourceObject', page_num: int) -> Any:
for_page = getattr(source, '__for_page__', None)
if callable(for_page):
return for_page(page_num)
return datamodel.PaginationConfig.get_record_for_page(source, page_num)
if TYPE_CHECKING:
def get_pagination_controller(self, source: 'SourceObject') \
-> 'Pagination':
...

View File

@@ -1,4 +1,4 @@
from lektor.assets import File, Directory # isinstance
from lektor.assets import Asset # isinstance
from lektor.pluginsystem import Plugin # subclass
from typing import TYPE_CHECKING, Iterator, Any
from .backref import GroupByRef, VGroups
@@ -27,7 +27,7 @@ class GroupByPlugin(Plugin):
) -> None:
# before-build may be called before before-build-all (issue #1017)
# make sure it is always evaluated first
if isinstance(source, (File, Directory)):
if isinstance(source, Asset):
return
groupby = self._init_once(builder)
if groupby.isNew and isinstance(source, GroupBySource):

View File

@@ -37,7 +37,7 @@ def prune(builder: 'Builder', vpath: str, url_cache: Iterable[str]) -> None:
for artifact_name, _ in infos:
if vpath not in artifact_name:
continue # we only care about our Virtuals
reporter.report_pruned_artifact(url)
reporter.report_pruned_artifact(url) # type: ignore
prune_file_and_folder(file.filename, dest_path)
build_state.remove_artifact(url)
break # there is only one VPATH-entry per source

View File

@@ -1,8 +1,7 @@
# adapting https://github.com/dairiki/lektorlib/blob/master/lektorlib/query.py
from lektor.constants import PRIMARY_ALT
from lektor.db import Query # subclass
from typing import TYPE_CHECKING, List, Optional, Iterator, Iterable
from typing import TYPE_CHECKING, List, Optional, Generator, Iterable
if TYPE_CHECKING:
from lektor.db import Record, Pad
@@ -26,7 +25,7 @@ class FixedRecordsQuery(Query):
return self.pad.get( # type: ignore[no-any-return]
path, alt=self.alt, page_num=page_num, persist=persist)
def _iterate(self) -> Iterator['Record']:
def _iterate(self) -> Generator['Record', None, None]:
''' Iterate over internal set of Record elements. '''
# ignore self record dependency from super()
for path in self.__child_paths:
@@ -51,7 +50,7 @@ class FixedRecordsQuery(Query):
def get_order_by(self) -> Optional[List[str]]:
''' Return list of attribute strings for sort order. '''
# ignore datamodel ordering from super()
return self._order_by
return self._order_by # type: ignore[no-any-return]
def count(self) -> int:
''' Count matched objects. '''
@@ -69,4 +68,8 @@ class FixedRecordsQuery(Query):
def __bool__(self) -> bool:
if self._pristine:
return len(self.__child_paths) > 0
return super().__bool__() # type: ignore[no-any-return]
return super().__bool__()
if TYPE_CHECKING:
def request_page(self, page_num: Optional[int]) -> 'FixedRecordsQuery':
...

View File

@@ -1,4 +1,4 @@
from lektor.db import Record # isinstance
from lektor.db import Page # isinstance
from typing import TYPE_CHECKING, Dict, List, NamedTuple, Optional, Iterable
from .util import build_url
from .vobj import VPATH, GroupBySource
@@ -60,7 +60,7 @@ class Resolver:
def resolve_server_path(self, node: 'SourceObject', pieces: List[str]) \
-> Optional[GroupBySource]:
''' Local server only: resolve /tag/rss/ -> /tag/rss/index.html '''
if isinstance(node, Record):
if isinstance(node, Page):
rv = self._data.get(build_url([node.url_path] + pieces))
if rv:
return GroupBySource(
@@ -70,7 +70,7 @@ class Resolver:
def resolve_virtual_path(self, node: 'SourceObject', pieces: List[str]) \
-> Optional[GroupBySource]:
''' Admin UI only: Prevent server error and null-redirect. '''
if isinstance(node, Record) and len(pieces) >= 2:
if isinstance(node, Page) and len(pieces) >= 2:
path = node['_path'] # type: str
attr, grp, *optional_page = pieces
page = None

View File

@@ -1,6 +1,8 @@
from lektor.reporter import reporter, style
from typing import List, Dict, Optional, TypeVar
from typing import Callable, Any, Union, Generic
from typing import List, Dict
T = TypeVar('T')
def report_config_error(key: str, field: str, val: str, e: Exception) -> None:
@@ -13,13 +15,13 @@ def report_config_error(key: str, field: str, val: str, e: Exception) -> None:
print(msg) # fallback in case Lektor API changes
def most_used_key(keys: List[str]) -> str:
def most_used_key(keys: List[T]) -> Optional[T]:
''' Find string with most occurrences. '''
if len(keys) < 3:
return keys[0] if keys else '' # TODO: first vs last occurrence
return keys[0] if keys else None # TODO: first vs last occurrence
best_count = 0
best_key = ''
tmp = {} # type: Dict[str, int]
best_key = None
tmp = {} # type: Dict[T, int]
for k in keys:
num = (tmp[k] + 1) if k in tmp else 1
tmp[k] = num
@@ -53,6 +55,6 @@ def build_url(parts: List[str]) -> str:
txt = str(comp).strip('/')
if txt:
url += '/' + txt
if '.' not in url.split('/')[-1]:
if '.' not in url.rsplit('/', 1)[-1]:
url += '/'
return url or '/'

View File

@@ -121,7 +121,7 @@ class GroupBySource(VirtualSourceObject):
# ---------------------
@property
def path(self) -> str:
def path(self) -> str: # type: ignore[override]
# Used in VirtualSourceInfo, used to prune VirtualObjects
vpath = f'{self.record.path}{VPATH}/{self.config.key}/{self.key}'
if self.page_num:
@@ -149,7 +149,7 @@ class GroupBySource(VirtualSourceObject):
parts.append(self.slug)
return build_url(parts)
def iter_source_filenames(self) -> Iterator[str]:
def iter_source_filenames(self) -> Generator[str, None, None]:
''' Enumerate all dependencies '''
if self.config.dependencies:
yield from self.config.dependencies
@@ -186,7 +186,7 @@ class GroupBySource(VirtualSourceObject):
# Used for virtual path resolver
if key in ('_path', '_alt'):
return getattr(self, key[1:])
return self.__missing__(key) # type: ignore[attr-defined]
return self.__missing__(key)
def __lt__(self, other: 'GroupBySource') -> bool:
# Used for |sort filter ("group" is the provided original string)

View File

@@ -56,7 +56,7 @@ class Watcher:
def should_process(self, node: 'Record') -> bool:
''' Check if record path is being watched. '''
return node['_path'].startswith(self._root)
return str(node['_path']).startswith(self._root)
def process(self, record: 'Record') -> None:
'''
@@ -106,5 +106,5 @@ class Watcher:
del self._state
def __repr__(self) -> str:
return '<GroupByWatcher key="{}" enabled={} callback={}>'.format(
self.config.key, self.config.enabled, self.callback)
return '<GroupByWatcher key="{}" enabled={}>'.format(
self.config.key, self.config.enabled)

View File

@@ -1,6 +1,6 @@
from setuptools import setup
with open('README.md') as fp:
with open('README.md', encoding='utf8') as fp:
longdesc = fp.read()
setup(