Do "from . import log" instead of "from jwutils import log". It works and looks cleaner than a module referencing itself. Not entirely sure if that's the way to go, I must admit.
Commit 72d56d9 (Move type argument into config) swapped the order of arguments in Auth.load(), but the ctor of ldap.Auth didn't follow the change, fix that.
Auth.load() takes a "tp" argument, specifying the Auth module name to load. In case of jw-devops, this is part of the configuration, which is also passed as an argument. Make taking 'type' from the config the default. Note that this changes the prototype.
jw-client-devops configures its databases with a set of config keys which are identical - except for the 'bind_pw' key, which is called 'password'. Allow that, too.
ldap.Auth lost a lot of code when jwutils.ldap was introduced, and rightfully so, because jwutils.ldap contains most of it. OTOH, it was used wrongly, fix that.
MapAttr2Shape is a class which allows processing GraphML files, such that nodes get added shape attributes understood by the yEd editor, based on the values of other node attributes. This allows to programmatically visualize node attributes.
WSGI doesn't like sys.exit() being called, so avoid it. Two cases need to be taken into consideration:
1. No exception thrown by self.args.func()
The variable exit_status is zero, we can check that and _not_
call sys.exit()
2. Exception thrown by self.args.func()
In that case, the exception should be raised, to be caught by
WSGI / ASGI whatever to do what they want with it. The code
calling sys.exit() is never reached. Hence, we need to add
--backtrace to the invocation options.
cast.from_env() takes an environment variable name instead of the string as the first argument and does the obvious thing. It also takes a default and saves the conversion in case the environment variable doesn't exist.
<W> jw-client-devops-web.py [ 29] Exiting jw-client-devops-web.py Exception ignored in: <function App.__del__ at 0x7f3ddeb8f560> Traceback (most recent call last): File "/home/jan/local/src/jw.dev/proj/jw-client-devops-web/src/python/jw/devops/client/web/cmds/App.py", line 43, in __del__ File "/home/jan/local/src/jw.dev/proj/jw-python/tools/python/jwutils/log.py", line 167, in slog File "/home/jan/local/src/jw.dev/proj/jw-python/tools/python/jwutils/log.py", line 126, in get_caller_pos AttributeError: 'NoneType' object has no attribute '__name__'
add_argument() at the face of it looks much like ArgumentParser.add_argument(), but is a function, not a class method. It takes the ArgsContainer|ArgParser instance as first argument, then decides what type it is, and proceeds to use this knowledge to decide whether or not the argument to be added already has a definition.
Add functions log.(add|rm)_capture_stream(). The functions are meant to capture everything passed to syslog into the stream objects installed by it. Not sure about future semantics changes: add_capture_stream() takes a currently unused flags argument, and it suppresses everything else logged until the stream is removed again.
If module is present in the log flags string, the module is prepended to each log message. The length of the module prefix can be set via the new set_module_name_length() function.
StringTree.find(key, val) (and Config.find(), for that matter) returns a list of paths with sections containing children matching key / val pairs. One of them can be None, which acts as a wildcard.