Fix errors reported by mypy

Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
Jan Lindemann 2025-10-13 12:45:51 +02:00
commit bfd0544ff8
13 changed files with 68 additions and 71 deletions

View file

@ -8,10 +8,10 @@ from jwutils.log import *
class ArgsContainer: # export
__args = OrderedDict()
__kwargs = OrderedDict()
__values = {}
__specified_args = list()
__args: OrderedDict[str, str] = OrderedDict()
__kwargs: OrderedDict[str, str] = OrderedDict()
__values: dict[str, str] = {}
__specified_args: list[str] = list()
def __getattr__(self, name):
values = self.__values
@ -47,12 +47,10 @@ class ArgsContainer: # export
def keys(self):
return self.__args.keys()
@property
def args(self, name):
def args(self, name) -> str:
return self.__args[name]
@property
def kwargs(self, name):
def kwargs(self, name) -> str:
return self.__kwargs[name]
def dump(self, prio, *args, **kwargs):

View file

@ -48,7 +48,7 @@ class Cmd(abc.ABC): # export
return
self.child_classes.append(cmd)
# To be overriden by derived class in case the command does take arguments.
# To be overridden by derived class in case the command does take arguments.
# Will be called from App base class constructor and set up the parser hierarchy
def add_arguments(self, parser: ArgumentParser) -> None:
pass

View file

@ -90,6 +90,10 @@ class Cmds: # export
slog(DEBUG, f'Adding top-level command {cmd} to parser')
self.__add_cmd_to_parser(cmd, subparsers)
# Run all sub-commands. Overwrite if you want to do anything before or after
async def _run(self, argv=None):
return await self.args.func(self.args)
async def __run(self, argv=None):
argcomplete.autocomplete(self.__parser)
self.args = self.__parser.parse_args(args=argv)
@ -115,7 +119,7 @@ class Cmds: # export
pr.enable()
try:
ret = await self.args.func(self.args)
ret = await self._run(self.args)
except Exception as e:
if hasattr(e, 'message'):
slog(ERR, e.message)

View file

@ -103,7 +103,7 @@ class Config(): # export
self.__conf.dump(DEBUG, "superposed configuration")
def __getitem__(self, key: str) -> Optional[str]:
def __getitem__(self, key: str) -> str:
ret = self.get(key)
if ret is None:
raise KeyError(key)

View file

@ -5,12 +5,6 @@ from collections import namedtuple
from ..log import *
# --- python 2 / 3 compatibility stuff
try:
basestring # type: ignore
except NameError:
basestring = str
L, R = 'Left Right'.split()
ARG, KEYW, QUOTED, LPAREN, RPAREN = 'arg kw quoted ( )'.split()
@ -252,7 +246,7 @@ class ShuntingYard(object): # export
return vals.pop()
def eval(self, infix):
if not isinstance(infix, basestring):
if not isinstance(infix, str):
return infix
postfix = self.infix_to_postfix(infix)
self.debug(f'"{infix}" --> {postfix}')

View file

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
# >> -------------------------- generated by python-tools.sh >>
from pkgutil import extend_path
from typing import Iterable
__path__ = extend_path(__path__, __name__) # type: ignore
from jwutils.asyncio.Process import Process
# << -------------------------- generated by python-tools.sh <<

View file

@ -74,11 +74,12 @@ class Auth(abc.ABC): # export
@classmethod
def load(cls, conf: Config, tp: str='') -> Self:
if tp == '':
tp = conf.get('type')
if tp is None:
val = conf.get('type')
if val is None:
msg = f'No type specified in auth configuration'
conf.dump(ERR, msg)
raise Exception(msg)
tp = val
return load_object(f'jwutils.auth.{tp}.Auth', Auth, 'Auth', conf)
def __init__(self, conf: Config):
@ -112,7 +113,7 @@ class Auth(abc.ABC): # export
return self._user(name)
@abc.abstractmethod
def _users(self) -> list[User]:
def _users(self) -> dict[str, User]:
raise NotImplementedError
def _user_by_email(self, email: str) -> User:
@ -128,7 +129,7 @@ class Auth(abc.ABC): # export
return self._user_by_email(email)
@property
def users(self) -> list[User]:
def users(self) -> dict[str, User]:
return self._users()
@abc.abstractmethod

View file

@ -26,7 +26,7 @@ class User(UserBase): # export
self.__conf = conf
self.__auth = auth
self.__groups: Optional[list[GroupBase]] = None
self.__email = conf.get('email')
self.__email: str = conf['email']
@property
def conf(self):
@ -51,14 +51,15 @@ class Auth(AuthBase): # export
def __init__(self, conf: Config):
super().__init__(conf)
self.___users: Optional[dict[str, User]] = None
self.___users: Optional[dict[str, UserBase]] = None
self.__groups = None
self.__current_user: User|None = None
self.__current_user: UserBase|None = None
self.__user_by_email: Optional[dict[str, UserBase]] = None
@property
def __users(self) -> User:
def __users(self) -> dict[str, UserBase]:
if self.___users is None:
ret: dict[str, User] = {}
ret: dict[str, UserBase] = {}
for name in self.conf.entries('user'):
conf = self.conf.branch('user.' + name)
ret[name] = User(self, name, conf)
@ -69,24 +70,24 @@ class Auth(AuthBase): # export
slog(WARNING, f'Returning False for {access_type} access to resource {what} by {who}')
return False
def _user(self, name) -> User:
def _user(self, name) -> UserBase:
return self.__users[name]
def _users(self) -> list[User]:
def _users(self) -> dict[str, UserBase]:
return self.__users
def _current_user(self) -> User:
def _current_user(self) -> UserBase:
if self.__current_user is None:
self.__current_user = self._user(self.conf['current_user'])
return self.__current_user
def _user_by_email(self, email: str) -> User:
def _user_by_email(self, email: str) -> UserBase:
if self.__user_by_email is None:
ret: dict[str, User] = dict()
ret: dict[str, UserBase] = dict()
for user in self.__users.values():
ret[user.email] = user
self.__user_by_email = ret
return self.__user_by_email[email]
def _projects(self, name, flags: ProjectFlags) -> list[str]:
return None
return []

View file

@ -54,7 +54,7 @@ class Auth(AuthBase): # export
def __init__(self, conf: Config):
super().__init__(conf)
self.___users: Optional[dict[str, User]] = None
self.___users: Optional[dict[str, UserBase]] = None
self.___user_by_email: Optional[dict[str, User]] = None
self.__groups = None
self.__current_user: User|None = None
@ -66,9 +66,9 @@ class Auth(AuthBase): # export
return bind(self.conf)
@property
def __users(self) -> User:
def __users(self) -> dict[str, UserBase]:
if self.___users is None:
ret: dict[str, User] = {}
ret: dict[str, UserBase] = {}
ret_by_email: dict[str, User] = {}
for res in self.__conn.find(
self.__user_base_dn,
@ -101,40 +101,40 @@ class Auth(AuthBase): # export
slog(WARNING, f'Exception {e}')
raise
continue
for user in self.__dummy.users.values():
ret[user.name] = user
for dummy_user in self.__dummy.users.values():
ret[dummy_user.name] = dummy_user
self.___users = ret
self.___user_by_email = ret_by_email
return self.___users
@property
def __user_by_email(self) -> User:
def __user_by_email(self) -> dict[str, UserBase]:
if self.___user_by_email is None:
self.__users
return self.___user_by_email
return self.___user_by_email # type: ignore # We are sure that ___user_by_email is not None at this point
def _access(self, what: str, access_type: Optional[Access], who: User|GroupBase|None) -> bool: # type: ignore
slog(WARNING, f'Returning False for {access_type} access to resource {what} by {who}')
return False
def _user(self, name) -> User:
def _user(self, name) -> UserBase:
try:
return self.__users[name]
except:
slog(ERR, f'No such user: "{name}"')
raise
def _user_by_email(self, email: str) -> User:
def _user_by_email(self, email: str) -> UserBase:
return self.__user_by_email[email]
def _current_user(self) -> User:
raise NotImplementedError
def _users(self) -> list[User]:
def _users(self) -> dict[str, UserBase]:
return self.__users
def _projects(self, name, flags: ProjectFlags) -> list[str]:
if flags & ProjectFlags.Contributing:
# TODO: Ask LDAP
pass
return None
slog(WARNING, f'Querying LDAP for projects a user contributes to is not implemented, ignoring')
return []

View file

@ -29,7 +29,7 @@ class MapAttr2Shape: # export
for name, url in self.__ns.items():
ET.register_namespace(name, url)
def __keys(self, root):
def __keys(self, root) -> dict[str, str]:
ret: dict[str, str] = {}
for el in root.findall('key', self.__ns):
attr_name = el.get('attr.name')
@ -44,7 +44,7 @@ class MapAttr2Shape: # export
return None
return data.text
def __attribs(self, node, keys):
def __attribs(self, node, keys) -> dict[str, str]:
ret: dict[str, str] = {}
for name, key in keys.items():
val = self.__value(node, key)
@ -93,13 +93,13 @@ class MapAttr2Shape: # export
values[key] = default
continue
try:
if isinstance(str, mapping):
if isinstance(mapping, str):
values[key] = mapping
continue
except:
pass
mapped = mapping(self.__attribs(node, keys))
values[key] = mapped or default
except:
pass
color = values['color']
text = values['text']

View file

@ -83,7 +83,7 @@ class Connection: # export
raise Exception(f'Failed to bind to {c.ldap_uri} with dn {c.bind_dn} ({e})')
self.__ldap = ret
self.__backtrace = backtrace
self.__object_classes: dict[str, ObjectClass]|None = None
self.__object_classes_by_oid: dict[str, ObjectClass]|None = None
self.__object_class_tree: nx.Graph|None = None
self.__object_classes_by_name: dict[str, ObjectClass]|None = None
@ -93,10 +93,8 @@ class Connection: # export
def add(self, attrs: dict[str, bytes], dn: str|None=None):
if dn is None:
dn = attrs.get('dn')
if dn is None:
if not 'dn' in attrs:
raise Exception('No DN to add an LDAP entry to')
else:
attrs = copy.deepcopy(attrs)
del attrs['dn']
try:
@ -175,14 +173,14 @@ class Connection: # export
assert_not_empty=False,
):
def __walk_cb_find(conn: Connection, entry, context):
def __walk_cb_find(conn: Connection, entry: Any, context: Any):
result.append(entry)
def __search():
return f'{base} -> "{filterstr}"'
try:
result = []
result: list[Any] = []
self.walk(__walk_cb_find, base, scope=scope, filterstr=filterstr, attrlist=attrlist)
except Exception as e:
slog(ERR, f'Failed search {__search()} ({e})')
@ -194,9 +192,9 @@ class Connection: # export
return result
@property
def object_classes(self) -> list[ObjectClass]:
def object_classes(self) -> dict[str, ObjectClass]:
#def object_classes(self):
if self.__object_classes is None:
if self.__object_classes_by_oid is None:
res = self.find(base='', scope=ldap.SCOPE_BASE, filterstr='(objectClass=*)', attrlist=['subschemaSubentry'])
dn = res[0][1]['subschemaSubentry'][0].decode('utf-8') # Usually yields cn=Subschema
res = self.find(base=dn, scope=ldap.SCOPE_BASE, filterstr='(objectClass=*)', attrlist=['*', '+'])
@ -204,13 +202,13 @@ class Connection: # export
subschema_subentry = ldap.cidict.cidict(subschema_entry[1])
subschema = ldap.schema.SubSchema(subschema_subentry)
object_class_oids = subschema.listall(ObjectClass)
self.__object_classes = {
self.__object_classes_by_oid = {
oid: subschema.get_obj(ObjectClass, oid) for oid in object_class_oids
}
return self.__object_classes
return self.__object_classes_by_oid
@property
def object_class_by_name(self):
def object_class_by_name(self) -> dict[str, ObjectClass]:
if self.__object_classes_by_name is None:
ret: dict[str, ObjectClass] = {}
self.__object_classes_by_name = ret
@ -230,7 +228,7 @@ class Connection: # export
def object_class_path(self, leaf: str|ObjectClass):
def cb(oc, context):
ret.append(oc)
ret = []
ret: list[str] = []
self.__oc_recurse_to_top(leaf, cb, None)
return reversed(ret)

View file

@ -98,7 +98,7 @@ class Stream:
self.stream = stream
self.flags = flags
_streams: dict[int, io.IOBase] = dict()
_streams: dict[int, Stream] = dict()
_stream_descriptors = [reversed(range(1, 16))]
def add_capture_stream(stream, flags=0x0):
@ -120,7 +120,7 @@ def log_level(s: Optional[str]=None) -> int: # export
return _level
return parse_log_prio_str(s)
def get_caller_pos(up: int = 1, kwargs: Optional[dict[str, Any]] = None) -> Tuple[str, int]:
def get_caller_pos(up: int = 1, kwargs: Optional[dict[str, Any]] = None) -> Tuple[str, str, int]:
if kwargs and 'caller' in kwargs:
r = kwargs['caller']
del kwargs['caller']
@ -261,10 +261,10 @@ def set_level(level_: str) -> None: # export
return
_level = level_
def set_flags(flags: str|None) -> None: # export
def set_flags(flags: str|None) -> str: # export
global _flags
ret = ','.join(_flags)
if _flags is not None:
if flags is not None:
_flags = set(flags.split(','))
return ret

View file

@ -287,7 +287,7 @@ class StringTree: # export
case _:
raise NotImplementedError(f'Matcher {match} is not yet implemented')
ret = []
ret: list[StringTree] = []
if depth_first:
__children()