Mercurial > cgi-bin > hgweb.cgi > tincan
comparison tincan.py @ 19:5d9a1b82251a draft before-template-changes
Return the "deepest" subclass; this allows subclassing tincan.Page and
making a standard base page class for a webapp.
author | David Barts <n5jrn@me.com> |
---|---|
date | Mon, 20 May 2019 17:42:18 -0700 |
parents | e88ab99914cf |
children | ca2029ce95c7 |
comparison
equal
deleted
inserted
replaced
18:e88ab99914cf | 19:5d9a1b82251a |
---|---|
487 spec = importlib.util.spec_from_file_location(_mangle(self._name), pycpath) | 487 spec = importlib.util.spec_from_file_location(_mangle(self._name), pycpath) |
488 mod = importlib.util.module_from_spec(spec) | 488 mod = importlib.util.module_from_spec(spec) |
489 spec.loader.exec_module(mod) | 489 spec.loader.exec_module(mod) |
490 except Exception as e: | 490 except Exception as e: |
491 raise TinCanError("{0}: error importing: {1!s}".format(pycpath, e)) from e | 491 raise TinCanError("{0}: error importing: {1!s}".format(pycpath, e)) from e |
492 # Locate a suitable class | 492 # Locate a suitable class. We look for the "deepest" class object |
493 # we can find in the inheritance tree. | |
493 self._class = None | 494 self._class = None |
495 score = -1 | |
496 ambig = False | |
494 for i in dir(mod): | 497 for i in dir(mod): |
495 v = getattr(mod, i) | 498 v = getattr(mod, i) |
496 if isclass(v) and issubclass(v, klass) and v is not klass: | 499 if not isclass(v): |
497 if self._class is not None: | 500 continue |
498 raise TinCanError("{0}: contains multiple {1} classes".format(pypath, klass.__name__)) | 501 d = self._cldepth(klass, v) |
502 if d > score: | |
499 self._class = v | 503 self._class = v |
504 score = d | |
505 ambig = False | |
506 elif d == score: | |
507 ambig = True | |
500 if self._class is None: | 508 if self._class is None: |
501 raise TinCanError("{0}: contains no {1} classes".format(pypath, klass.__name__)) | 509 raise TinCanError("{0}: contains no {1} classes".format(pypath, klass.__name__)) |
510 if ambig: | |
511 raise TinCanError("{0}: contains ambiguous {1} classes".format(pypath, klass.__name__)) | |
512 | |
513 # This might fail for complex inheritance schemes from the classes of | |
514 # interest (so don't use them!). | |
515 def _cldepth(self, base, klass, count=0): | |
516 if klass is object: | |
517 # not found | |
518 return -1 | |
519 elif klass is base: | |
520 # just found | |
521 return count | |
522 else: | |
523 # must recurse | |
524 for c in klass.__bases__: | |
525 result = self._cldepth(base, c, count=count+1) | |
526 if result > 0: | |
527 return result | |
528 return -1 | |
502 | 529 |
503 def _redirect(self): | 530 def _redirect(self): |
504 try: | 531 try: |
505 rlist = self._splitpath(self._header.forward) | 532 rlist = self._splitpath(self._header.forward) |
506 forw = '/' + '/'.join(rlist) | 533 forw = '/' + '/'.join(rlist) |