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 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 import weakref
from .util import split_strip from .util import split_strip
if TYPE_CHECKING: if TYPE_CHECKING:
@@ -13,6 +13,7 @@ if TYPE_CHECKING:
class WeakVGroupsList(list): class WeakVGroupsList(list):
def add(self, strong: 'FieldKeyPath', weak: 'GroupBySource') -> None: def add(self, strong: 'FieldKeyPath', weak: 'GroupBySource') -> None:
super().append((strong, weakref.ref(weak))) super().append((strong, weakref.ref(weak)))
# super().append((strong, weak)) # strong-ref
class GroupByRef: class GroupByRef:
@@ -71,11 +72,11 @@ class VGroups:
flows = [flows] flows = [flows]
# find groups # find groups
proc_list = [record] proc_list = [record]
done_list = set() done_list = set() # type: Set[GroupBySource]
while proc_list: while proc_list:
page = proc_list.pop(0) page = proc_list.pop(0)
if recursive and hasattr(page, 'children'): 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): for key, vobj in VGroups.of(page):
if fields and key.fieldKey not in fields: if fields and key.fieldKey not in fields:
continue continue
@@ -87,11 +88,11 @@ class VGroups:
if order_by: if order_by:
if isinstance(order_by, str): if isinstance(order_by, str):
order = split_strip(order_by, ',') order = split_strip(order_by, ',') # type: Iterable[str]
elif isinstance(order_by, (list, tuple)): elif isinstance(order_by, (list, tuple)):
order = order_by order = order_by
else: 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 # using get_sort_key() of GroupBySource
yield from sorted(done_list, key=lambda x: x.get_sort_key(order)) yield from sorted(done_list, key=lambda x: x.get_sort_key(order))
else: else:

View File

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

View File

@@ -1,14 +1,20 @@
from lektor import datamodel from lektor import datamodel
from typing import TYPE_CHECKING, Any from typing import TYPE_CHECKING, Any
if TYPE_CHECKING: if TYPE_CHECKING:
from lektor.db import Record from lektor.pagination import Pagination
from lektor.sourceobj import SourceObject
class PaginationConfig(datamodel.PaginationConfig): class PaginationConfig(datamodel.PaginationConfig):
# because original method does not work for virtual sources. # because original method does not work for virtual sources.
@staticmethod @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) for_page = getattr(source, '__for_page__', None)
if callable(for_page): if callable(for_page):
return for_page(page_num) return for_page(page_num)
return datamodel.PaginationConfig.get_record_for_page(source, 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 lektor.pluginsystem import Plugin # subclass
from typing import TYPE_CHECKING, Iterator, Any from typing import TYPE_CHECKING, Iterator, Any
from .backref import GroupByRef, VGroups from .backref import GroupByRef, VGroups
@@ -27,7 +27,7 @@ class GroupByPlugin(Plugin):
) -> None: ) -> None:
# before-build may be called before before-build-all (issue #1017) # before-build may be called before before-build-all (issue #1017)
# make sure it is always evaluated first # make sure it is always evaluated first
if isinstance(source, (File, Directory)): if isinstance(source, Asset):
return return
groupby = self._init_once(builder) groupby = self._init_once(builder)
if groupby.isNew and isinstance(source, GroupBySource): 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: for artifact_name, _ in infos:
if vpath not in artifact_name: if vpath not in artifact_name:
continue # we only care about our Virtuals 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) prune_file_and_folder(file.filename, dest_path)
build_state.remove_artifact(url) build_state.remove_artifact(url)
break # there is only one VPATH-entry per source 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 # adapting https://github.com/dairiki/lektorlib/blob/master/lektorlib/query.py
from lektor.constants import PRIMARY_ALT from lektor.constants import PRIMARY_ALT
from lektor.db import Query # subclass from lektor.db import Query # subclass
from typing import TYPE_CHECKING, List, Optional, Generator, Iterable
from typing import TYPE_CHECKING, List, Optional, Iterator, Iterable
if TYPE_CHECKING: if TYPE_CHECKING:
from lektor.db import Record, Pad from lektor.db import Record, Pad
@@ -26,7 +25,7 @@ class FixedRecordsQuery(Query):
return self.pad.get( # type: ignore[no-any-return] return self.pad.get( # type: ignore[no-any-return]
path, alt=self.alt, page_num=page_num, persist=persist) 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. ''' ''' Iterate over internal set of Record elements. '''
# ignore self record dependency from super() # ignore self record dependency from super()
for path in self.__child_paths: for path in self.__child_paths:
@@ -51,7 +50,7 @@ class FixedRecordsQuery(Query):
def get_order_by(self) -> Optional[List[str]]: def get_order_by(self) -> Optional[List[str]]:
''' Return list of attribute strings for sort order. ''' ''' Return list of attribute strings for sort order. '''
# ignore datamodel ordering from super() # ignore datamodel ordering from super()
return self._order_by return self._order_by # type: ignore[no-any-return]
def count(self) -> int: def count(self) -> int:
''' Count matched objects. ''' ''' Count matched objects. '''
@@ -69,4 +68,8 @@ class FixedRecordsQuery(Query):
def __bool__(self) -> bool: def __bool__(self) -> bool:
if self._pristine: if self._pristine:
return len(self.__child_paths) > 0 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 typing import TYPE_CHECKING, Dict, List, NamedTuple, Optional, Iterable
from .util import build_url from .util import build_url
from .vobj import VPATH, GroupBySource from .vobj import VPATH, GroupBySource
@@ -60,7 +60,7 @@ class Resolver:
def resolve_server_path(self, node: 'SourceObject', pieces: List[str]) \ def resolve_server_path(self, node: 'SourceObject', pieces: List[str]) \
-> Optional[GroupBySource]: -> Optional[GroupBySource]:
''' Local server only: resolve /tag/rss/ -> /tag/rss/index.html ''' ''' 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)) rv = self._data.get(build_url([node.url_path] + pieces))
if rv: if rv:
return GroupBySource( return GroupBySource(
@@ -70,7 +70,7 @@ class Resolver:
def resolve_virtual_path(self, node: 'SourceObject', pieces: List[str]) \ def resolve_virtual_path(self, node: 'SourceObject', pieces: List[str]) \
-> Optional[GroupBySource]: -> Optional[GroupBySource]:
''' Admin UI only: Prevent server error and null-redirect. ''' ''' 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 path = node['_path'] # type: str
attr, grp, *optional_page = pieces attr, grp, *optional_page = pieces
page = None page = None

View File

@@ -1,6 +1,8 @@
from lektor.reporter import reporter, style 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: 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 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. ''' ''' Find string with most occurrences. '''
if len(keys) < 3: 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_count = 0
best_key = '' best_key = None
tmp = {} # type: Dict[str, int] tmp = {} # type: Dict[T, int]
for k in keys: for k in keys:
num = (tmp[k] + 1) if k in tmp else 1 num = (tmp[k] + 1) if k in tmp else 1
tmp[k] = num tmp[k] = num
@@ -53,6 +55,6 @@ def build_url(parts: List[str]) -> str:
txt = str(comp).strip('/') txt = str(comp).strip('/')
if txt: if txt:
url += '/' + txt url += '/' + txt
if '.' not in url.split('/')[-1]: if '.' not in url.rsplit('/', 1)[-1]:
url += '/' url += '/'
return url or '/' return url or '/'

View File

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

View File

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