Generally for the logic cleanups it was replacing giant list
comprehensions with slightly smaller filter calls. filter() is just
plain cleaner when all you're doing in a list comp is
[x for x in y if somecondition].
timeout_session provides two things, TimeoutAdapter, a HTTP adapter
subclass that automatically adds timeouts to all requests, and
new_session, which automatically creates a request.Session with the
adapter in the correct place.
* find_caller_frame() to do the frame walk.
* munge_module_name() to fix up for plugins.
NB: caller_attributes() now has a noqa on CCR001 as I don't think it
can sensibly be made any less complex. Pulling out the 'if frame:'
section just results in *that* new method then being labelled as too
complex.:244
* Settled on `plugins.internal` and `<plugins>.found` as the format.
* A PyCharm recommendation was to use 'cls' instead of 'self' on class
methods, so the class detection code needs to cater for that.
Technically a developer could use any string for the "myself" member
name, but we'll assume just these two.
* Found will always have at least one folder level within plugin_dir
* Internal should always have *no* folder within internal_plugin_dir,
but cater for it just in case in future.
1. This makes setting up logging everywhere slightly more involved.
2. If I then want to change, say, %(module)s value I'll end up needing
to stack walk again.
So this might be better done in a filter. But these commits for the
record, and to come back to if needs be.
* Log messages propagate up Parent.Child chains, so we don't need a
channel on the plugin logger.
* But it still needs the filter to define qualname and class for
formatting.