Skip to content

Commit 15969f0

Browse files
committed
refactor code to make typechecking happy, mostly adding safe guards
1 parent f9887e3 commit 15969f0

File tree

5 files changed

+54
-37
lines changed

5 files changed

+54
-37
lines changed

src/pyff/api.py

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ def _d(x: Optional[str], do_split: bool = True) -> Tuple[Optional[str], Optional
178178

179179
return x, None
180180

181-
log.debug(request)
181+
log.debug(f'Processing request: {request}')
182182

183183
if request.matchdict is None:
184184
raise exc.exception_response(400)
@@ -190,18 +190,18 @@ def _d(x: Optional[str], do_split: bool = True) -> Tuple[Optional[str], Optional
190190
pass
191191

192192
entry = request.matchdict.get('entry', 'request')
193-
path = list(request.matchdict.get('path', []))
193+
path_elem = list(request.matchdict.get('path', []))
194194
match = request.params.get('q', request.params.get('query', None))
195195

196196
# Enable matching on scope.
197197
match = match.split('@').pop() if match and not match.endswith('@') else match
198198
log.debug("match={}".format(match))
199199

200-
if 0 == len(path):
201-
path = ['entities']
200+
if not path_elem:
201+
path_elem = ['entities']
202202

203-
alias = path.pop(0)
204-
path = '/'.join(path)
203+
alias = path_elem.pop(0)
204+
path = '/'.join(path_elem)
205205

206206
# Ugly workaround bc WSGI drops double-slashes.
207207
path = path.replace(':/', '://')
@@ -234,23 +234,31 @@ def _d(x: Optional[str], do_split: bool = True) -> Tuple[Optional[str], Optional
234234
accept = str(request.accept).split(',')[0]
235235
valid_accept = accept and not ('application/*' in accept or 'text/*' in accept or '*/*' in accept)
236236

237-
path_no_extension, extension = _d(path, True)
238-
accept_from_extension = _ctypes.get(extension, accept)
237+
new_path: Optional[str] = path
238+
path_no_extension, extension = _d(new_path, True)
239+
accept_from_extension = accept
240+
if extension:
241+
accept_from_extension = _ctypes.get(extension, accept)
239242

240243
if policy == 'extension':
241-
path = path_no_extension
244+
new_path = path_no_extension
242245
if not valid_accept:
243246
accept = accept_from_extension
244247
elif policy == 'adaptive':
245248
if not valid_accept:
246-
path = path_no_extension
249+
new_path = path_no_extension
247250
accept = accept_from_extension
248251

249-
if pfx and path:
250-
q = "{%s}%s" % (pfx, path)
251-
path = "/%s/%s" % (alias, path)
252+
if not accept:
253+
log.warning('Could not determine accepted response type')
254+
raise exc.exception_response(400)
255+
256+
q: Optional[str]
257+
if pfx and new_path:
258+
q = f'{{{pfx}}}{new_path}'
259+
new_path = f'/{alias}/{new_path}'
252260
else:
253-
q = path
261+
q = new_path
254262

255263
try:
256264
accepter = MediaAccept(accept)
@@ -262,18 +270,19 @@ def _d(x: Optional[str], do_split: bool = True) -> Tuple[Optional[str], Optional
262270
'url': request.current_route_url(),
263271
'select': q,
264272
'match': match.lower() if match else match,
265-
'path': path,
273+
'path': new_path,
266274
'stats': {},
267275
}
268276

269277
r = p.process(request.registry.md, state=state, raise_exceptions=True, scheduler=request.registry.scheduler)
270-
log.debug(r)
278+
log.debug(f'Plumbing process result: {r}')
271279
if r is None:
272280
r = []
273281

274282
response = Response()
275-
response.headers.update(state.get('headers', {}))
276-
ctype = state.get('headers').get('Content-Type', None)
283+
_headers = state.get('headers', {})
284+
response.headers.update(_headers)
285+
ctype = _headers.get('Content-Type', None)
277286
if not ctype:
278287
r, t = _fmt(r, accepter)
279288
ctype = t
@@ -288,13 +297,13 @@ def _d(x: Optional[str], do_split: bool = True) -> Tuple[Optional[str], Optional
288297
import traceback
289298

290299
log.debug(traceback.format_exc())
291-
log.warning(ex)
300+
log.warning(f'Exception from processing pipeline: {ex}')
292301
raise exc.exception_response(409)
293302
except BaseException as ex:
294303
import traceback
295304

296305
log.debug(traceback.format_exc())
297-
log.error(ex)
306+
log.error(f'Exception from processing pipeline: {ex}')
298307
raise exc.exception_response(500)
299308

300309
if request.method == 'GET':
@@ -332,7 +341,7 @@ def webfinger_handler(request: Request) -> Response:
332341
"subject": "http://reep.refeds.org:8080"
333342
}
334343
335-
Depending on which version of pyFF your're running and the configuration you
344+
Depending on which version of pyFF you're running and the configuration you
336345
may also see downstream metadata listed using the 'role' attribute to the link
337346
elements.
338347
"""
@@ -344,7 +353,7 @@ def webfinger_handler(request: Request) -> Response:
344353
resource = request.host_url
345354

346355
jrd: Dict[str, Any] = dict()
347-
dt = datetime.now() + duration2timedelta("PT1H")
356+
dt = datetime.now() + timedelta(hours=1)
348357
jrd['expires'] = dt.isoformat()
349358
jrd['subject'] = request.host_url
350359
links: List[Dict[str, Any]] = list()
@@ -509,7 +518,9 @@ def mkapp(*args: Any, **kwargs: Any) -> Any:
509518
for mn in config.modules:
510519
importlib.import_module(mn)
511520

512-
pipeline = args or None
521+
pipeline = None
522+
if args:
523+
pipeline = list(args)
513524
if pipeline is None and config.pipeline:
514525
pipeline = [config.pipeline]
515526

src/pyff/logs.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import logging
44
import os
55
import syslog
6-
from typing import Any
6+
from typing import Any, Optional
77

88
import six
99

@@ -65,7 +65,7 @@ def get_log(name: str) -> PyFFLogger:
6565
log = get_log('pyff')
6666

6767

68-
def log_config_file(ini: str) -> None:
68+
def log_config_file(ini: Optional[str]) -> None:
6969
if ini is not None:
7070
import logging.config
7171

@@ -76,7 +76,7 @@ def log_config_file(ini: str) -> None:
7676
logging.config.fileConfig(ini)
7777

7878

79-
log_config_file(os.getenv('PYFF_LOGGING', None))
79+
log_config_file(os.getenv('PYFF_LOGGING'))
8080

8181
# http://www.aminus.org/blogs/index.php/2008/07/03/writing-high-efficiency-large-python-sys-1?blog=2
8282
# blog post explicitly gives permission for use

src/pyff/pipes.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def _n(_d: str) -> Tuple[str, List[str]]:
108108

109109
name = None
110110
args = None
111-
opts = []
111+
opts: List[str] = []
112112
if is_text(d):
113113
name, opts = _n(d)
114114
elif hasattr(d, '__iter__') and not type(d) is dict:
@@ -172,7 +172,7 @@ def __call__(self, *args: Any, **kwargs: Any) -> Any:
172172
return self.plumbing.process(self.req.md, store=self.store, state=state, t=t)
173173
except Exception as ex:
174174
log.debug(traceback.format_exc())
175-
log.error(ex)
175+
log.error(f'Got an exception executing the plumbing process: {ex}')
176176
raise ex
177177

178178

@@ -327,7 +327,7 @@ def iprocess(self, req: Plumbing.Request) -> ElementTree:
327327
break
328328
except BaseException as ex:
329329
log.debug(traceback.format_exc())
330-
log.error(ex)
330+
log.error(f'Got exception when loading/executing pipe: {ex}')
331331
req.exception = ex
332332
if req.raise_exceptions:
333333
raise ex

src/pyff/tools.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from xmldiff.main import diff_trees
1515

1616
from pyff.constants import config, parse_options
17-
from pyff.resource import Resource
17+
from pyff.resource import Resource, ResourceOpts
1818
from pyff.samlmd import diff, iter_entities
1919
from pyff.store import MemoryStore
2020

@@ -31,12 +31,12 @@ def difftool():
3131

3232
try:
3333
rm = Resource()
34-
r1 = Resource(args[0])
35-
r2 = Resource(args[1])
3634
rm.add(r1)
3735
rm.add(r2)
3836
store = MemoryStore()
3937
rm.reload(store=store)
38+
r1 = Resource(url=args[0], opts=ResourceOpts())
39+
r2 = Resource(url=args[1], opts=ResourceOpts())
4040
status = 0
4141

4242
if r1.t.get('Name') != r2.t.get('Name'):

src/pyff/utils.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from itertools import chain
2626
from threading import local
2727
from time import gmtime, strftime
28-
from typing import Any, BinaryIO, Callable, List, Optional, Sequence, Set, Tuple, Union
28+
from typing import Any, BinaryIO, Callable, Dict, List, Optional, Sequence, Set, Tuple, Union
2929

3030
import pkg_resources
3131
import requests
@@ -390,17 +390,20 @@ def duration2timedelta(period: str) -> Optional[timedelta]:
390390
return delta
391391

392392

393-
def _lang(elt, default_lang):
393+
def _lang(elt: Element, default_lang: Optional[str]) -> Optional[str]:
394394
return elt.get("{http://www.w3.org/XML/1998/namespace}lang", default_lang)
395395

396396

397-
def lang_dict(elts, getter=lambda e: e, default_lang=None):
397+
def lang_dict(elts: Sequence[Element], getter=lambda e: e, default_lang: Optional[str] = None) -> Dict[str, Callable]:
398398
if default_lang is None:
399399
default_lang = config.langs[0]
400400

401401
r = dict()
402402
for e in elts:
403-
r[_lang(e, default_lang)] = getter(e)
403+
_l = _lang(e, default_lang)
404+
if not _l:
405+
raise ValueError('Could not get lang from element, and no default provided')
406+
r[_l] = getter(e)
404407
return r
405408

406409

@@ -422,6 +425,9 @@ def filter_lang(elts: Any, langs: Optional[Sequence[str]] = None) -> List[Elemen
422425
if len(elts) == 0:
423426
return []
424427

428+
if not langs:
429+
raise RuntimeError('Configuration is missing langs')
430+
425431
dflt = langs[0]
426432
lst = [find_lang(elts, l, dflt) for l in langs]
427433
if len(lst) > 0:
@@ -773,7 +779,7 @@ def img_to_data(data: bytes, content_type: str) -> Optional[str]:
773779
assert data64
774780
mime_type = "image/png"
775781
except BaseException as ex:
776-
log.warning(ex)
782+
log.warning(f'Exception when making Image: {ex}')
777783
log.debug(traceback.format_exc())
778784

779785
if data64 is None or len(data64) == 0:

0 commit comments

Comments
 (0)