Skip to content

Commit bed8574

Browse files
committed
more typing and smaller fixes
1 parent 4808f1d commit bed8574

File tree

4 files changed

+51
-32
lines changed

4 files changed

+51
-32
lines changed

src/pyff/builtins.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ def load(req, *opts):
632632
url = r.pop(0)
633633

634634
# Copy parent node opts as a starting point
635-
child_opts = req.md.rm.opts.copy(update={"via": [], "cleanup": [], "verify": None, "as": url})
635+
child_opts = req.md.rm.opts.copy(update={"via": [], "cleanup": [], "verify": None, "alias": url})
636636

637637
while len(r) > 0:
638638
elt = r.pop(0)

src/pyff/parse.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
22
from abc import ABC
33
from collections import deque
4-
from typing import Any, List, Mapping
4+
from typing import Any, AnyStr, Dict, List, Mapping, Optional, Union
55

66
from xmlsec.crypto import CertDict
77

@@ -49,10 +49,10 @@ def __init__(self):
4949
def __str__(self):
5050
return "Not a supported type"
5151

52-
def magic(self, content):
52+
def magic(self, content: str) -> bool:
5353
return True
5454

55-
def parse(self, resource, content):
55+
def parse(self, resource: Resource, content: str) -> Mapping[str, Any]:
5656
raise ParserException("No matching parser found for %s" % resource.url)
5757

5858

@@ -66,7 +66,7 @@ def __str__(self):
6666
def magic(self, content: str) -> bool:
6767
return os.path.isdir(content)
6868

69-
def parse(self, resource: Resource, content: str):
69+
def parse(self, resource: Resource, content: str) -> Mapping[str, Any]:
7070
resource.children = deque()
7171
info = dict()
7272
info['Description'] = 'Directory'
@@ -128,8 +128,9 @@ def add_parser(parser):
128128
_parsers.insert(0, parser)
129129

130130

131-
def parse_resource(resource: Resource, content: str):
131+
def parse_resource(resource: Resource, content: str) -> Optional[Mapping[str, Any]]:
132132
for parser in _parsers:
133133
if parser.magic(content):
134134
resource.last_parser = parser
135135
return parser.parse(resource, content)
136+
return None

src/pyff/pipes.py

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,16 @@
77
import functools
88
import os
99
import traceback
10-
from typing import Any, Callable, Dict, List, Optional
10+
from typing import Any, Callable, Dict, Iterable, List, Optional
1111
from typing import Type
1212

1313
import yaml
1414
from apscheduler.schedulers.background import BackgroundScheduler
15+
from lxml.etree import ElementTree
1516

1617
from .logs import get_log
1718
from .repo import MDRepository
19+
from .store import SAMLStoreBase
1820
from .utils import PyffException, is_text, resource_string
1921

2022
log = get_log(__name__)
@@ -202,11 +204,12 @@ class Plumbing(object):
202204
would then be signed (using signer.key) and finally published in /var/metadata/public/metadata.xml
203205
"""
204206

205-
def __init__(self, pipeline: List[Dict[str, Any]], pid: str):
207+
def __init__(self, pipeline: Iterable[Dict[str, Any]], pid: str):
206208
self._id = pid
207209
self.pipeline = pipeline
208210

209-
def to_json(self):
211+
def to_json(self) -> Iterable[Dict[str, Any]]:
212+
# TODO: to_json seems like the wrong name for this function?
210213
return self.pipeline
211214

212215
@property
@@ -217,7 +220,7 @@ def id(self) -> str:
217220
def pid(self) -> str:
218221
return self._id
219222

220-
def __iter__(self):
223+
def __iter__(self) -> Iterable[Dict[str, Any]]:
221224
return self.pipeline
222225

223226
def __str__(self):
@@ -245,19 +248,19 @@ def __init__(
245248
state = dict()
246249
if not args:
247250
args = []
248-
self.plumbing = pl
249-
self.md = md
250-
self.t = t
251+
self.plumbing: Plumbing = pl
252+
self.md: MDRepository = md
253+
self.t: ElementTree = t
251254
self._id = None
252255
self.name = name
253-
self.args = args
254-
self.state = state
255-
self.done = False
256-
self._store = store
257-
self.scheduler = scheduler
258-
self.raise_exceptions = raise_exceptions
256+
self.args: Iterable[Dict[str, Any]] = args
257+
self.state: Dict[str, Any] = state
258+
self.done: bool = False
259+
self._store: SAMLStoreBase = store
260+
self.scheduler: Optional[BackgroundScheduler] = scheduler
261+
self.raise_exceptions: bool = raise_exceptions
259262
self.exception: Optional[BaseException] = None
260-
self.parent = None
263+
self.parent: Optional[Plumbing.Request] = None
261264

262265
def scope_of(self, entry_point):
263266
if 'with {}'.format(entry_point) in self.plumbing.pipeline:
@@ -284,7 +287,7 @@ def set_parent(self, _parent):
284287
self.parent = _parent
285288

286289
@property
287-
def store(self):
290+
def store(self) -> SAMLStoreBase:
288291
if self._store:
289292
return self._store
290293
return self.md.store

src/pyff/resource.py

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010
from collections import deque
1111
from datetime import datetime
1212
from threading import Condition, Lock
13-
from typing import Any, Callable, Deque, Dict, List, Optional, TYPE_CHECKING, Tuple
13+
from typing import Any, Callable, Deque, Dict, List, Optional, TYPE_CHECKING, Tuple, Union
1414
from urllib.parse import quote as urlescape
1515

1616
import requests
17+
from lxml.etree import ElementTree
1718
from requests.adapters import Response
1819
from pydantic import BaseModel, Field
1920

@@ -159,11 +160,11 @@ def to_dict(self) -> Dict[str, Any]:
159160
class Resource(Watchable):
160161
def __init__(self, url: Optional[str], opts: ResourceOpts):
161162
super().__init__()
162-
self.url: str = url
163-
self.opts = opts
164-
self.t = None
165-
self.type = "text/plain"
166-
self.etag = None
163+
self.url: Optional[str] = url
164+
self.opts: ResourceOpts = opts
165+
self.t: Optional[ElementTree] = None
166+
self.type: str = "text/plain"
167+
self.etag: Optional[str] = None
167168
self.expire_time: Optional[datetime] = None
168169
self.never_expires: bool = False
169170
self.last_seen: Optional[datetime] = None
@@ -304,12 +305,15 @@ def errors(self):
304305
else:
305306
return []
306307

307-
def load_backup(self):
308+
def load_backup(self) -> Optional[str]:
308309
if config.local_copy_dir is None:
309310
return None
310311

311312
try:
312-
return resource_string(self.local_copy_fn)
313+
res = resource_string(self.local_copy_fn)
314+
if isinstance(res, bytes):
315+
return res.decode('utf-8')
316+
return res
313317
except IOError as ex:
314318
log.warning(
315319
"Caught an exception trying to load local backup for {} via {}: {}".format(
@@ -318,7 +322,7 @@ def load_backup(self):
318322
)
319323
return None
320324

321-
def save_backup(self, data):
325+
def save_backup(self, data: Optional[str]) -> None:
322326
if config.local_copy_dir is not None:
323327
try:
324328
safe_write(self.local_copy_fn, data, True)
@@ -332,6 +336,10 @@ def load_resource(self, getter: Callable[[str], Response]) -> Tuple[Optional[str
332336

333337
log.debug("Loading resource {}".format(self.url))
334338

339+
if not self.url:
340+
log.error(f'No URL for resource {self}')
341+
return data, status, info
342+
335343
try:
336344
r = getter(self.url)
337345

@@ -346,7 +354,10 @@ def load_resource(self, getter: Callable[[str], Response]) -> Tuple[Optional[str
346354

347355
if r.ok:
348356
data = r.text
349-
self.etag = r.headers.get('ETag', None) or hex_digest(r.text, 'sha256')
357+
_etag = r.headers.get('ETag', None)
358+
if not _etag:
359+
_etag = hex_digest(r.text, 'sha256')
360+
self.etag = _etag
350361
elif self.local_copy_fn is not None:
351362
log.warning(
352363
"Got status={:d} while getting {}. Attempting fallback to local copy.".format(
@@ -379,12 +390,16 @@ def load_resource(self, getter: Callable[[str], Response]) -> Tuple[Optional[str
379390

380391
def parse(self, getter: Callable[[str], Response]) -> Deque[Resource]:
381392
data, status, info = self.load_resource(getter)
393+
394+
if not data:
395+
raise ResourceException(f'Nothing to parse when loading resource {self}')
396+
382397
info['State'] = 'Parsing'
383398
# local import to avoid circular import
384399
from .parse import parse_resource
385400

386401
parse_info = parse_resource(self, data)
387-
if parse_info is not None and isinstance(parse_info, dict):
402+
if parse_info is not None:
388403
info.update(parse_info)
389404

390405
if status != 218: # write backup unless we just loaded from backup

0 commit comments

Comments
 (0)