[rtags] Allow to 'derive' rtags
Since some releases, rtags (structure underlying uicfg) have selector and may be
copied using something like:
new_rtags = deepcopy(original_rtags)
new_rtags.__module__ = __name__
new_rtags.__select__ = custom_selector
The problem is that starting from that, both rtags wil diverge and changes in
original_rtags won't be considered, while we usually want to set a few specific
rules only in new_rtags. To fix this problem, this cset introduces the notion of
"derivated/parent" rtag, eg:
new_rtags = original_rtags.derive(__name__, custom_selector)
Beside easier copying, when using the above method changes in original_rtags
which are not overriden by new_rtags will be considered since it only hold its
specific rules but look among its parent chain for non-found keys.
Along the way, flake8 unittest_rtags.
Closes #16164880
""" Tools for profiling.
See :ref:`profiling`."""
from __future__ import print_function
import cProfile
import itertools
from pyramid.view import view_config
@view_config(route_name='profile_ping')
def ping(request):
""" View that handle '/_profile/ping'
It simply reply 'ping', without requiring connection to the repository.
It is a useful as a comparison point to evaluate the actual overhead of
more costly views.
"""
request.response.text = u'pong'
return request.response
@view_config(route_name='profile_cnx')
def cnx(request):
""" View that handle '/_profile/cnx'
Same as :func:`ping`, but it first ask for a connection to the repository.
Useful to evaluate the overhead of opening a connection.
"""
request.cw_cnx
request.response.text = u'pong'
return request.response
def wsgi_profile(app, filename='program.prof', dump_every=50):
""" A WSGI middleware for profiling
It enable the profiler before passing the request to the underlying
application, and disable it just after.
The stats will be dumped after ``dump_every`` requests
:param filename: The filename to dump the stats to.
:param dump_every: Number of requests after which to dump the stats.
"""
profile = cProfile.Profile()
counter = itertools.count(1)
def application(environ, start_response):
profile.enable()
try:
return app(environ, start_response)
finally:
profile.disable()
if not counter.next() % dump_every:
print("Dump profile stats to %s" % filename)
profile.create_stats()
profile.dump_stats(filename)
return application