Esempio n. 1
0
    def __init__(self, config):
        settings = dict((name[6:], value) for name, value in
                        config.registry.settings.items()
                        if name.startswith('breve.'))
        self.tags = config.maybe_dotted(settings.get('tags', html.tags))
        self.doctype = settings.get('doctype', html.doctype)
        if self.doctype and not self.doctype.startswith('<!DOCTYPE '):
            self.doctype = '<!DOCTYPE %s>' % self.doctype
        self.xmlns = settings.get('xmlns', html.xmlns)
        self.fragment = asbool(settings.get('fragment', False))

        if 'monitor' in settings:
            monitor = config.maybe_dotted(settings['monitor'])
            assert IFileMonitor in providedBy(monitor)
        else:
            interval = int(settings.get('monitor_interval', 5))
            monitor = IntervalMonitor(interval)

        default_package = settings.get('default_package')
        if default_package is None:
            # Configurator.include('pyramid_breve') has different
            # "depth" than when it's configured via INI-file
            default_package = caller_package(4)
            if default_package.__name__ == 'pyramid.config':
                default_package = caller_package(6)

        self.loader = TemplateLoader(default_package, monitor)
Esempio n. 2
0
def cleanUp(*arg, **kw):
    """ An alias for :func:`pyramid.testing.setUp`. """
    package = kw.get('package', None)
    if package is None:
        package = caller_package()
        kw['package'] = package
    return setUp(*arg, **kw)
Esempio n. 3
0
def render(renderer_name, value, request=None, package=None):
    """ Using the renderer ``renderer_name`` (a template
    or a static renderer), render the value (or set of values) present
    in ``value``. Return the result of the renderer's ``__call__``
    method (usually a string or Unicode).

    If the ``renderer_name`` refers to a file on disk, such as when the
    renderer is a template, it's usually best to supply the name as an
    :term:`asset specification`
    (e.g. ``packagename:path/to/template.pt``).

    You may supply a relative asset spec as ``renderer_name``.  If
    the ``package`` argument is supplied, a relative renderer path
    will be converted to an absolute asset specification by
    combining the package ``package`` with the relative
    asset specification ``renderer_name``.  If ``package``
    is ``None`` (the default), the package name of the *caller* of
    this function will be used as the package.

    The ``value`` provided will be supplied as the input to the
    renderer.  Usually, for template renderings, this should be a
    dictionary.  For other renderers, this will need to be whatever
    sort of value the renderer expects.

    The 'system' values supplied to the renderer will include a basic set of
    top-level system names, such as ``request``, ``context``,
    ``renderer_name``, and ``view``.  See :ref:`renderer_system_values` for
    the full list.  If :term:`renderer globals` have been specified, these
    will also be used to augment the value.

    Supply a ``request`` parameter in order to provide the renderer
    with the most correct 'system' values (``request`` and ``context``
    in particular).

    """
    try:
        registry = request.registry
    except AttributeError:
        registry = None
    if package is None:
        package = caller_package()
    helper = RendererHelper(name=renderer_name, package=package,
                            registry=registry)

    saved_response = None
    # save the current response, preventing the renderer from affecting it
    attrs = request.__dict__ if request is not None else {}
    if 'response' in attrs:
        saved_response = attrs['response']
        del attrs['response']

    result = helper.render(value, None, request=request)

    # restore the original response, overwriting any changes
    if saved_response is not None:
        attrs['response'] = saved_response
    elif 'response' in attrs:
        del attrs['response']

    return result
Esempio n. 4
0
def cleanUp(*arg, **kw):
    """ An alias for :func:`pyramid.testing.setUp`. """
    package = kw.get('package', None)
    if package is None:
        package = caller_package()
        kw['package'] = package
    return setUp(*arg, **kw)
Esempio n. 5
0
 def __init__(
     self,
     root_dir,
     cache_max_age=3600,
     package_name=None,
     use_subpath=False,
     index='index.html',
     reload=False,
     content_encodings=(),
 ):
     # package_name is for bw compat; it is preferred to pass in a
     # package-relative path as root_dir
     # (e.g. ``anotherpackage:foo/static``).
     self.cache_max_age = cache_max_age
     if package_name is None:
         package_name = caller_package().__name__
     package_name, docroot = resolve_asset_spec(root_dir, package_name)
     self.use_subpath = use_subpath
     self.package_name = package_name
     self.docroot = docroot
     self.norm_docroot = normcase(normpath(docroot))
     self.index = index
     self.reload = reload
     self.content_encodings = _compile_content_encodings(content_encodings)
     self.filemap = {}
Esempio n. 6
0
def path(spec, package_name=None):
    if os.path.exists(spec):
        return spec, caller_package(3).__name__

    try:
        package_name, filename = spec.split(':', 1)
    except ValueError:
        # somehow we were passed a relative pathname
        if package_name is None:
            package_name = caller_package(2).__name__
        filename = spec

    abspath = pkg_resources.resource_filename(package_name, filename)
    if not pkg_resources.resource_exists(package_name, filename):
        return None, package_name
    return abspath, package_name
Esempio n. 7
0
    def __init__(self, settings=None, appname=None, global_config=None, **base_kwargs):
        package = base_kwargs.get('package') or caller_package()
        base_kwargs['package'] = package
        super(configurator, self).__init__(settings=settings, **base_kwargs)
        if 'root_factory' in base_kwargs:
            self.root_factory_set = True
        if settings:
            settings = dict(settings)
            self._settings = settings.copy()
            base_kwargs['settings'] = settings

            self.app_factory = self.rf_kw in settings \
                               and self.open_resolve(settings[self.rf_kw]) 

            self.request_factory = self.req_kw in settings \
                                   and self.open_resolve(settings[self.req_kw]) 

            self.plugin_spec = settings.get(self.stack_key, None)
        
        if appname:
            self.appname = appname

        if global_config:
            self.config_file = global_config['__file__']
            self.exec_dir = global_config['here']        
Esempio n. 8
0
def _traced_init(wrapped, instance, args, kwargs):
    settings = kwargs.get("settings", {})
    tweens = aslist(settings.get("pyramid.tweens", []))

    if tweens and TWEEN_NAME not in settings:
        # pyramid.tweens.EXCVIEW is the name of built-in exception view provided by
        # pyramid.  We need our tween to be before it, otherwise unhandled
        # exceptions will be caught before they reach our tween.
        tweens = [TWEEN_NAME] + tweens

        settings["pyramid.tweens"] = "\n".join(tweens)

    kwargs["settings"] = settings

    # `caller_package` works by walking a fixed amount of frames up the stack
    # to find the calling package. So if we let the original `__init__`
    # function call it, our wrapper will mess things up.
    if not kwargs.get("package", None):
        # Get the package for the third frame up from this one.
        # Default is `level=2` which will give us the package from `wrapt`
        # instead of the desired package (the caller)
        kwargs["package"] = caller_package(level=3)

    wrapped(*args, **kwargs)
    instance.include("opentelemetry.instrumentation.pyramid.callbacks")
Esempio n. 9
0
 def __init__(self,
              registry=None,
              package=None,
              settings=None,
              root_factory=None,
              authentication_policy=None,
              authorization_policy=None,
              renderers=DEFAULT_RENDERERS,
              debug_logger=None,
              locale_negotiator=None,
              request_factory=None,
              renderer_globals_factory=None,
              default_permission=None,
              session_factory=None,
              autocommit=True,
              ):
     if package is None:
         package = caller_package()
     BaseConfigurator.__init__(
         self,
         registry=registry,
         package=package,
         settings=settings,
         root_factory=root_factory,
         authentication_policy=authentication_policy,
         authorization_policy=authorization_policy,
         renderers=renderers,
         debug_logger=debug_logger,
         locale_negotiator=locale_negotiator,
         request_factory=request_factory,
         renderer_globals_factory=renderer_globals_factory,
         default_permission=default_permission,
         session_factory=session_factory,
         autocommit=autocommit,
         )
Esempio n. 10
0
def traced_init(wrapped, instance, args, kwargs):
    settings = kwargs.pop('settings', {})
    service = os.environ.get('DATADOG_SERVICE_NAME') or 'pyramid'
    distributed_tracing = asbool(get_env('pyramid', 'distributed_tracing', True))
    trace_settings = {
        SETTINGS_SERVICE: service,
        SETTINGS_DISTRIBUTED_TRACING: distributed_tracing,
    }
    # Update over top of the defaults
    # DEV: If we did `settings.update(trace_settings)` then we would only ever
    #      have the default values.
    trace_settings.update(settings)
    # If the tweens are explicitly set with 'pyramid.tweens', we need to
    # explicitly set our tween too since `add_tween` will be ignored.
    insert_tween_if_needed(trace_settings)
    kwargs['settings'] = trace_settings

    # `caller_package` works by walking a fixed amount of frames up the stack
    # to find the calling package. So if we let the original `__init__`
    # function call it, our wrapper will mess things up.
    if not kwargs.get('package', None):
        # Get the packge for the third frame up from this one.
        #   - ddtrace.contrib.pyramid.path
        #   - ddtrace.vendor.wrapt
        #   - (this is the frame we want)
        # DEV: Default is `level=2` which will give us the package from `wrapt`
        kwargs['package'] = caller_package(level=3)

    wrapped(*args, **kwargs)
    trace_pyramid(instance)
Esempio n. 11
0
    def login(self):
        args = self.params()
        result = {}
        headers = {}
        registry = self.request.registry
        if args.get('external_login', False):
            data = {'external_login': args.pop('external_login')}
            data['preferredUsername'] = args.pop('user_name')
            data['profile'] = {'accounts': [args]}
            login_result = create_user(None, None, data)
            user = login_result.get('user', None)
            if not user:
                result = {'loggedin': False}
            else:
                headers = remember(self.request, get_oid(user))
                registry.notify(
                    LoggedIn(data['preferredUsername'], user, self.context,
                             self.request))
                result = {'loggedin': True}
        else:
            user, valid, headers = validate_user(self.context, self.request,
                                                 args)
            result = {'loggedin': valid}

        renderer = RendererHelper(name='json',
                                  package=caller_package(),
                                  registry=registry)
        response = renderer.render_view(self.request, result, self,
                                        self.context)
        response.headerlist.extend(headers)
        return response
Esempio n. 12
0
    def login(self):
        args = self.params()
        result = {}
        headers = {}
        registry = self.request.registry
        if args.get('external_login', False):
            data = {'external_login': args.pop('external_login')}
            data['preferredUsername'] = args.pop('user_name')
            data['profile'] = {'accounts': [args]}
            login_result = create_user(None, None, data)
            user = login_result.get('user', None)
            if not user:
                result = {'loggedin': False}
            else:
                headers = remember(self.request, get_oid(user))
                registry.notify(LoggedIn(
                    data['preferredUsername'], user,
                    self.context, self.request))
                result = {'loggedin': True}
        else:
            user, valid, headers = validate_user(
                self.context, self.request, args)
            result = {'loggedin': valid}

        renderer = RendererHelper(name='json', package=caller_package(),
                                  registry=registry)
        response = renderer.render_view(self.request, result, self,
                                        self.context)
        response.headerlist.extend(headers)
        return response
Esempio n. 13
0
 def __init__(self, template_name=None):
     pkg = caller_package(level=3)
     if template_name:
         _, template_name = resolve_asset_spec(
             template_name, pkg.__name__)
         template_name = '%s:%s' % (_, template_name)
     self.template_name = template_name
     self.exposed = True
Esempio n. 14
0
def config_celery(settings, package=None):
    if package is None:
        package = caller_package()
    touch_all_package(package)
    obj_config = config_celery_for_mongo(settings)
    global celery
    celery = _Celery()
    celery.config_from_object(obj_config)
Esempio n. 15
0
 def __init__(self, root_dir, cache_max_age=3600, package_name=None):
     if package_name is None:
         package_name = caller_package().__name__
     static_view.__init__(self,
                          root_dir,
                          cache_max_age=cache_max_age,
                          package_name=package_name,
                          use_subpath=True)
Esempio n. 16
0
    def __init__(self, manifest_spec, reload=False):
        package_name = caller_package().__name__
        self.manifest_path = abspath_from_asset_spec(manifest_spec, package_name)
        self.reload = reload

        self._mtime = None
        if not reload:
            self._manifest = self.get_manifest()
Esempio n. 17
0
 def __new__(cls, namespace, base, *args, **kw):
     # Dotted name support makes it easy to configure with pyramid_multiauth
     name_resolver = DottedNameResolver(caller_package())
     base = name_resolver.maybe_resolve(base)
     # Dynamically create a subclass
     name = 'Namespaced_%s_%s' % (namespace, base.__name__)
     klass = type(name, (cls, base), {'_namespace_prefix': namespace + '.'})
     return super(NamespacedAuthenticationPolicy, klass).__new__(klass)
Esempio n. 18
0
 def __new__(cls, namespace, base, *args, **kw):
     # Dotted name support makes it easy to configure with pyramid_multiauth
     name_resolver = DottedNameResolver(caller_package())
     base = name_resolver.maybe_resolve(base)
     # Dynamically create a subclass
     name = 'Namespaced_%s_%s' % (namespace, base.__name__)
     klass = type(name, (cls, base), {'_namespace_prefix': namespace + '.'})
     return super(NamespacedAuthenticationPolicy, klass).__new__(klass)
Esempio n. 19
0
def static_path(request, path, **kw):
    if not os.path.isabs(path):
        if not ':' in path:
            package = caller_package()
            path = '%s:%s' % (package.__name__, path)
    kw['_app_url'] = ''
    path = request.static_url(path, **kw)
    return os.path.relpath(path, os.path.dirname(request.path))
Esempio n. 20
0
def static_url(path, request, **kw):
    """
    Generates a fully qualified URL for a static :term:`asset`.
    The asset must live within a location defined via the
    :meth:`pyramid.config.Configurator.add_static_view`
    :term:`configuration declaration` or the ``<static>`` ZCML
    directive (see :ref:`static_assets_section`).

    .. note:: Calling :meth:`pyramid.Request.static_url` can be used to
              achieve the same result as :func:`pyramid.url.static_url`.

    Example::

        static_url('mypackage:static/foo.css', request) =>

                                http://example.com/static/foo.css


    The ``path`` argument points at a file or directory on disk which
    a URL should be generated for.  The ``path`` may be either a
    relative path (e.g. ``static/foo.css``) or a :term:`asset
    specification` (e.g. ``mypackage:static/foo.css``).  A ``path``
    may not be an absolute filesystem path (a :exc:`ValueError` will
    be raised if this function is supplied with an absolute path).

    The ``request`` argument should be a :term:`request` object.

    The purpose of the ``**kw`` argument is the same as the purpose of
    the :func:`pyramid.url.route_url` ``**kw`` argument.  See the
    documentation for that function to understand the arguments which
    you can provide to it.  However, typically, you don't need to pass
    anything as ``*kw`` when generating a static asset URL.

    This function raises a :exc:`ValueError` if a static view
    definition cannot be found which matches the path specification.

    """
    if os.path.isabs(path):
        raise ValueError('Absolute paths cannot be used to generate static '
                         'urls (use a package-relative path or an asset '
                         'specification).')
    if not ':' in path:
        # if it's not a package:relative/name and it's not an
        # /absolute/path it's a relative/path; this means its relative
        # to the package in which the caller's module is defined.
        package = caller_package()
        path = '%s:%s' % (package.__name__, path)

    try:
        reg = request.registry
    except AttributeError:
        reg = get_current_registry() # b/c
    
    info = reg.queryUtility(IStaticURLInfo)
    if info is None:
        raise ValueError('No static URL definition matching %s' % path)
        
    return info.generate(path, request, **kw)
Esempio n. 21
0
def static_url(path, request, **kw):
    """
    Generates a fully qualified URL for a static :term:`asset`.
    The asset must live within a location defined via the
    :meth:`pyramid.config.Configurator.add_static_view`
    :term:`configuration declaration` (see :ref:`static_assets_section`).

    .. note:: Calling :meth:`pyramid.Request.static_url` can be used to
              achieve the same result as :func:`pyramid.url.static_url`.

    Example::

        static_url('mypackage:static/foo.css', request) =>

                                http://example.com/static/foo.css


    The ``path`` argument points at a file or directory on disk which
    a URL should be generated for.  The ``path`` may be either a
    relative path (e.g. ``static/foo.css``) or a :term:`asset
    specification` (e.g. ``mypackage:static/foo.css``).  A ``path``
    may not be an absolute filesystem path (a :exc:`ValueError` will
    be raised if this function is supplied with an absolute path).

    The ``request`` argument should be a :term:`request` object.

    The purpose of the ``**kw`` argument is the same as the purpose of
    the :func:`pyramid.url.route_url` ``**kw`` argument.  See the
    documentation for that function to understand the arguments which
    you can provide to it.  However, typically, you don't need to pass
    anything as ``*kw`` when generating a static asset URL.

    This function raises a :exc:`ValueError` if a static view
    definition cannot be found which matches the path specification.

    """
    if os.path.isabs(path):
        raise ValueError('Absolute paths cannot be used to generate static '
                         'urls (use a package-relative path or an asset '
                         'specification).')
    if not ':' in path:
        # if it's not a package:relative/name and it's not an
        # /absolute/path it's a relative/path; this means its relative
        # to the package in which the caller's module is defined.
        package = caller_package()
        path = '%s:%s' % (package.__name__, path)

    try:
        reg = request.registry
    except AttributeError:
        reg = get_current_registry()  # b/c

    info = reg.queryUtility(IStaticURLInfo)
    if info is None:
        raise ValueError('No static URL definition matching %s' % path)

    return info.generate(path, request, **kw)
Esempio n. 22
0
def LoadConfiguration(conf, base=None):
    """
    same as ResolveConfiguration except only the configuration object is
    returned
    """
    if not base:
        base = caller_package()
    i,c = ResolveConfiguration(conf, base)
    return c
Esempio n. 23
0
File: view.py Progetto: slmf/pyramid
 def __init__(self, root_dir, cache_max_age=3600, package_name=None):
     if package_name is None:
         package_name = caller_package().__name__
     static_view.__init__(
         self,
         root_dir,
         cache_max_age=cache_max_age,
         package_name=package_name,
         use_subpath=True)
Esempio n. 24
0
    def __init__(self, manifest_spec, reload=False):
        package_name = caller_package().__name__
        self.manifest_path = abspath_from_asset_spec(manifest_spec,
                                                     package_name)
        self.reload = reload

        self._mtime = None
        if not reload:
            self._manifest = self.get_manifest()
Esempio n. 25
0
 def __init__(self, package_name=CALLER_PACKAGE, *args, **kw):
     # add a registry-instance-specific lock, which is used when the lookup
     # cache is mutated
     self._lock = threading.Lock()
     # add a view lookup cache
     self._clear_view_lookup_cache()
     if package_name is CALLER_PACKAGE:
         package_name = caller_package().__name__
     Components.__init__(self, package_name, *args, **kw)
     dict.__init__(self)
Esempio n. 26
0
 def logout(self):
     headers = forget(self.request)
     result = {'loggedout': True}
     registry = self.request.registry
     renderer = RendererHelper(name='json', package=caller_package(),
                               registry=registry)
     response = renderer.render_view(self.request, result, self,
                                     self.context)
     response.headerlist.extend(headers)
     return response
Esempio n. 27
0
 def __init__(self,
              registry=None,
              package=None,
              autocommit=True,
              # Entity level services.
              filter_specification_factory=None,
              order_specification_factory=None,
              # Application level services.
              service=None,
              cql_filter_specification_visitor=None,
              sql_filter_specification_visitor=None,
              eval_filter_specification_visitor=None,
              cql_order_specification_visitor=None,
              sql_order_specification_visitor=None,
              eval_order_specification_visitor=None,
              url_converter=None,
              **kw
              ):
     if package is None:
         package = caller_package()
     call_setup = registry is None
     if call_setup:
         # Need to initialize our registry here to call our setup_registry
         # with the given custom option values rather than from the base
         # class constructor.
         # FIXME: There is some code duplication with Pyramid here.
         name_resolver = DottedNameResolver(package)
         package_name = name_resolver.get_package_name()
         registry = Registry(package_name)
         self.registry = registry
     # FIXME: Investigate why we need the "autocommit=True" flag here.
     PyramidConfigurator.__init__(self,
                                  registry=registry, package=package,
                                  autocommit=autocommit, **kw)
     # Set up configurator's load_zcml method.
     self.add_directive('load_zcml', load_zcml, action_wrap=False)
     if call_setup:
         self.setup_registry(
            filter_specification_factory=filter_specification_factory,
            order_specification_factory=order_specification_factory,
            service=service,
            cql_filter_specification_visitor=
                                 cql_filter_specification_visitor,
            sql_filter_specification_visitor=
                                 sql_filter_specification_visitor,
            eval_filter_specification_visitor=
                                 eval_filter_specification_visitor,
            cql_order_specification_visitor=
                                 cql_order_specification_visitor,
            sql_order_specification_visitor=
                                 sql_order_specification_visitor,
            eval_order_specification_visitor=
                                 eval_order_specification_visitor,
            url_converter=url_converter,
            **kw)
Esempio n. 28
0
 def __init__(
     self,
     registry=None,
     package=None,
     settings=None,
     root_factory=None,
     security_policy=None,
     authentication_policy=None,
     authorization_policy=None,
     renderers=None,
     debug_logger=None,
     locale_negotiator=None,
     request_factory=None,
     response_factory=None,
     default_permission=None,
     session_factory=None,
     default_view_mapper=None,
     autocommit=False,
     exceptionresponse_view=default_exceptionresponse_view,
     route_prefix=None,
     introspection=True,
     root_package=None,
 ):
     if package is None:
         package = caller_package()
     if root_package is None:
         root_package = package
     name_resolver = DottedNameResolver(package)
     self.name_resolver = name_resolver
     self.package_name = name_resolver.get_package_name()
     self.package = name_resolver.get_package()
     self.root_package = root_package
     self.registry = registry
     self.autocommit = autocommit
     self.route_prefix = route_prefix
     self.introspection = introspection
     if registry is None:
         registry = Registry(self.package_name)
         self.registry = registry
         self.setup_registry(
             settings=settings,
             root_factory=root_factory,
             authentication_policy=authentication_policy,
             authorization_policy=authorization_policy,
             security_policy=security_policy,
             renderers=renderers,
             debug_logger=debug_logger,
             locale_negotiator=locale_negotiator,
             request_factory=request_factory,
             response_factory=response_factory,
             default_permission=default_permission,
             session_factory=session_factory,
             default_view_mapper=default_view_mapper,
             exceptionresponse_view=exceptionresponse_view,
         )
Esempio n. 29
0
 def logout(self):
     headers = forget(self.request)
     result = {'loggedout': True}
     registry = self.request.registry
     renderer = RendererHelper(name='json',
                               package=caller_package(),
                               registry=registry)
     response = renderer.render_view(self.request, result, self,
                                     self.context)
     response.headerlist.extend(headers)
     return response
Esempio n. 30
0
    def __call__(self, info):
        spec = self.get_spec(info.name, info.package)
        registry = info.registry

        if os.path.isabs(spec):
            # 'spec' is an absolute filename
            if not os.path.exists(spec):
                raise ValueError('Missing template file: %s' % spec)
            renderer = registry.queryUtility(ITemplateRenderer, name=spec)
            if renderer is None:
                renderer = self.impl(spec, self, macro=None)
                # cache the template
                try:
                    self.lock.acquire()
                    registry.registerUtility(renderer,
                                             ITemplateRenderer, name=spec)
                finally:
                    self.lock.release()
        else:
            # spec is a package:relpath asset spec
            renderer = registry.queryUtility(ITemplateRenderer, name=spec)
            if renderer is None:
                p = re.compile(
                    r'(?P<asset>[\w_.:/]+)'
                    r'(?:\#(?P<defname>[\w_]+))?'
                    r'(\.(?P<ext>.*))'
                    )
                asset, macro, ext = p.match(spec).group(
                    'asset', 'defname', 'ext')
                spec = '%s.%s' % (asset, ext)
                try:
                    package_name, filename = spec.split(':', 1)
                except ValueError: # pragma: no cover
                    # somehow we were passed a relative pathname; this
                    # should die
                    package_name = caller_package(4).__name__
                    filename = spec
                abspath = pkg_resources.resource_filename(package_name,
                                                          filename)
                if not pkg_resources.resource_exists(package_name, filename):
                    raise ValueError(
                        'Missing template asset: %s (%s)' % (spec, abspath))
                renderer = self.impl(abspath, self, macro=macro)
                settings = info.settings
                if not settings.get('reload_assets'):
                    # cache the template
                    self.lock.acquire()
                    try:
                        registry.registerUtility(renderer, ITemplateRenderer,
                                                 name=spec)
                    finally:
                        self.lock.release()

        return renderer
Esempio n. 31
0
def get_template(path):
    """ Return the underlying object representing a :term:`Chameleon`
    ZPT template using the template implied by the ``path`` argument.
    The ``path`` argument may be a package-relative path, an absolute
    path, or a :term:`resource specification`.

        .. warning:: This API is deprecated in :mod:`pyramid_chameleon_genshi`
       1.0.  Use :func:`pyramid.renderers.get_renderer` instead.
    """
    package = caller_package()
    factory = renderers.RendererHelper(name=path, package=package)
    return factory.get_renderer().implementation()
Esempio n. 32
0
 def __init__(self, root_dir, cache_max_age=3600, package_name=None):
     # package_name is for bw compat; it is preferred to pass in a
     # package-relative path as root_dir
     # (e.g. ``anotherpackage:foo/static``).
     caller_package_name = caller_package().__name__
     package_name = package_name or caller_package_name
     package_name, root_dir = resolve_resource_spec(root_dir, package_name)
     if package_name is None:
         app = StaticURLParser(root_dir, cache_max_age=cache_max_age)
     else:
         app = PackageURLParser(package_name, root_dir, cache_max_age=cache_max_age)
     self.app = app
Esempio n. 33
0
def template_renderer_factory(info, impl, lock=registry_lock):
    spec = info.name
    reg = info.registry
    package = info.package

    isabs = os.path.isabs(spec)

    if (not isabs) and (not ':' in spec) and package:
        # relative resource spec
        if not isabs:
            pp = package_path(package)
            spec = os.path.join(pp, spec)
        spec = resource_spec_from_abspath(spec, package)
    
    if os.path.isabs(spec):
        # 'spec' is an absolute filename
        if not os.path.exists(spec):
            raise ValueError('Missing template file: %s' % spec)
        renderer = reg.queryUtility(ITemplateRenderer, name=spec)
        if renderer is None:
            renderer = impl(spec)
            # cache the template
            try:
                lock.acquire()
                reg.registerUtility(renderer, ITemplateRenderer, name=spec)
            finally:
                lock.release()
    else:
        # spec is a package:relpath resource spec
        renderer = reg.queryUtility(ITemplateRenderer, name=spec)
        if renderer is None:
            try:
                package_name, filename = spec.split(':', 1)
            except ValueError: # pragma: no cover
                # somehow we were passed a relative pathname; this
                # should die
                package_name = caller_package(4).__name__
                filename = spec
            abspath = pkg_resources.resource_filename(package_name, filename)
            if not pkg_resources.resource_exists(package_name, filename):
                raise ValueError(
                    'Missing template resource: %s (%s)' % (spec, abspath))
            renderer = impl(abspath)
            settings = info.settings
            if settings and not settings.get('reload_resources'):
                # cache the template
                try:
                    lock.acquire()
                    reg.registerUtility(renderer, ITemplateRenderer, name=spec)
                finally:
                    lock.release()
        
    return renderer
Esempio n. 34
0
 def __init__(
     self,
     registry=None,
     package=None,
     settings=None,
     root_factory=None,
     authentication_policy=None,
     authorization_policy=None,
     renderers=None,
     debug_logger=None,
     locale_negotiator=None,
     request_factory=None,
     response_factory=None,
     default_permission=None,
     session_factory=None,
     default_view_mapper=None,
     autocommit=False,
     exceptionresponse_view=default_exceptionresponse_view,
     route_prefix=None,
     introspection=True,
     root_package=None,
 ):
     if package is None:
         package = caller_package()
     if root_package is None:
         root_package = package
     name_resolver = DottedNameResolver(package)
     self.name_resolver = name_resolver
     self.package_name = name_resolver.get_package_name()
     self.package = name_resolver.get_package()
     self.root_package = root_package
     self.registry = registry
     self.autocommit = autocommit
     self.route_prefix = route_prefix
     self.introspection = introspection
     if registry is None:
         registry = Registry(self.package_name)
         self.registry = registry
         self.setup_registry(
             settings=settings,
             root_factory=root_factory,
             authentication_policy=authentication_policy,
             authorization_policy=authorization_policy,
             renderers=renderers,
             debug_logger=debug_logger,
             locale_negotiator=locale_negotiator,
             request_factory=request_factory,
             response_factory=response_factory,
             default_permission=default_permission,
             session_factory=session_factory,
             default_view_mapper=default_view_mapper,
             exceptionresponse_view=exceptionresponse_view,
         )
Esempio n. 35
0
 def __init__(
         self,
         registry=None,
         package=None,
         # Entity level services.
         filter_specification_factory=None,
         order_specification_factory=None,
         # Application level services.
         service=None,
         cql_filter_specification_visitor=None,
         sql_filter_specification_visitor=None,
         eval_filter_specification_visitor=None,
         cql_order_specification_visitor=None,
         sql_order_specification_visitor=None,
         eval_order_specification_visitor=None,
         url_converter=None,
         **kw):
     if package is None:
         package = caller_package()
     call_setup = registry is None
     if call_setup:
         # Need to initialize our registry here to call our setup_registry
         # with the given custom option values rather than from the base
         # class constructor.
         # FIXME: There is some code duplication with Pyramid here.
         name_resolver = DottedNameResolver(package)
         name_resolver = name_resolver
         package_name = name_resolver.get_package_name()
         registry = Registry(package_name)
         self.registry = registry
     PyramidConfigurator.__init__(self,
                                  registry=registry,
                                  package=package,
                                  **kw)
     # Set up configurator's load_zcml method.
     self.add_directive('load_zcml', load_zcml, action_wrap=False)
     if call_setup:
         self.setup_registry(
             filter_specification_factory=filter_specification_factory,
             order_specification_factory=order_specification_factory,
             service=service,
             cql_filter_specification_visitor=
             cql_filter_specification_visitor,
             sql_filter_specification_visitor=
             sql_filter_specification_visitor,
             eval_filter_specification_visitor=
             eval_filter_specification_visitor,
             cql_order_specification_visitor=cql_order_specification_visitor,
             sql_order_specification_visitor=sql_order_specification_visitor,
             eval_order_specification_visitor=
             eval_order_specification_visitor,
             url_converter=url_converter,
             **kw)
Esempio n. 36
0
 def __init__(self, root_dir, cache_max_age=3600, package_name=None):
     # package_name is for bw compat; it is preferred to pass in a
     # package-relative path as root_dir
     # (e.g. ``anotherpackage:foo/static``).
     if package_name is None:
         package_name = caller_package().__name__
     package_name, root_dir = resolve_asset_spec(root_dir, package_name)
     if package_name is None:
         app = StaticURLParser(root_dir, cache_max_age=cache_max_age)
     else:
         app = PackageURLParser(
             package_name, root_dir, cache_max_age=cache_max_age)
     self.app = app
Esempio n. 37
0
def get_renderer(path):
    """ Return a callable object which can be used to render a
    :term:`Chameleon` ZPT template using the template implied by the
    ``path`` argument.  The ``path`` argument may be a
    package-relative path, an absolute path, or a :term:`resource
    specification`.
    
    .. warning:: This API is deprecated in :app:`Pyramid` 1.0.  Use
       :func:`pyramid.renderers.get_renderer` instead.
    """
    package = caller_package()
    factory = renderers.RendererHelper(name=path, package=package)
    return factory.get_renderer()
Esempio n. 38
0
 def __init__(self, root_dir, cache_max_age=3600, package_name=None, use_subpath=False, index="index.html"):
     # package_name is for bw compat; it is preferred to pass in a
     # package-relative path as root_dir
     # (e.g. ``anotherpackage:foo/static``).
     self.cache_max_age = cache_max_age
     if package_name is None:
         package_name = caller_package().__name__
     package_name, docroot = resolve_asset_spec(root_dir, package_name)
     self.use_subpath = use_subpath
     self.package_name = package_name
     self.docroot = docroot
     self.norm_docroot = normcase(normpath(docroot))
     self.index = index
Esempio n. 39
0
def get_template(path):
    """ Return the underyling object representing a :term:`Chameleon`
    text template using the template implied by the ``path`` argument.
    The ``path`` argument may be a package-relative path, an absolute
    path, or a :term:`asset specification`.

    .. warning:: This API is deprecated in :app:`Pyramid` 1.0.  Use
       the ``implementation()`` method of a template renderer retrieved via
       :func:`pyramid.renderers.get_renderer` instead.
    """
    package = caller_package()
    factory = renderers.RendererHelper(path, package=package)
    return factory.get_renderer().implementation()
Esempio n. 40
0
 def __init__(self, name, path=None, attribute='render',
              interface=Interface, permission='view',
              strict=True, _level=2):
     """ see ``registerTile`` for details on the other parameters.
     """
     self.name = name
     if path and not (':' in path or os.path.isabs(path)): 
         path = '%s:%s' % (caller_package(_level).__name__, path)
     self.path = path
     self.attribute = attribute
     self.interface = interface
     self.permission = permission
     self.strict = strict
Esempio n. 41
0
def get_renderer(path):
    """ Return a callable object which can be used to render a
    :term:`Chameleon` text template using the template implied by the
    ``path`` argument.  The ``path`` argument may be a
    package-relative path, an absolute path, or a :term:`asset
    specification`.
    
    .. warning:: This API is deprecated in :app:`Pyramid` 1.0.  Use
       :func:`pyramid.renderers.get_renderer` instead.
    """
    package = caller_package()
    factory = renderers.RendererHelper(path, package=package)
    return factory.get_renderer()
Esempio n. 42
0
def get_template(path):
    """ Return the underyling object representing a :term:`Chameleon`
    ZPT template using the template implied by the ``path`` argument.
    The ``path`` argument may be a package-relative path, an absolute
    path, or a :term:`asset specification`.

    .. warning:: This API is deprecated in :app:`Pyramid` 1.0.  Use
       the ``implementation()`` method of a template renderer retrieved via
       :func:`pyramid.renderers.get_renderer` instead.
    """
    package = caller_package()
    factory = renderers.RendererHelper(name=path, package=package)
    return factory.get_renderer().implementation()
Esempio n. 43
0
    def scan(self, package=None, categories=None, onerror=None, **kw):
        """Scan a Python package and any of its subpackages for objects
        marked with :term:`configuration decoration` such as
        :class:`pyramid.view.view_config`.  Any decorated object found will
        influence the current configuration state.

        The ``package`` argument should be a Python :term:`package` or module
        object (or a :term:`dotted Python name` which refers to such a
        package or module).  If ``package`` is ``None``, the package of the
        *caller* is used.

        The ``categories`` argument, if provided, should be the
        :term:`Venusian` 'scan categories' to use during scanning.  Providing
        this argument is not often necessary; specifying scan categories is
        an extremely advanced usage.  By default, ``categories`` is ``None``
        which will execute *all* Venusian decorator callbacks including
        :app:`Pyramid`-related decorators such as
        :class:`pyramid.view.view_config`.  See the :term:`Venusian`
        documentation for more information about limiting a scan by using an
        explicit set of categories.

        The ``onerror`` argument, if provided, should be a Venusian
        ``onerror`` callback function.  The onerror function is passed to
        :meth:`venusian.Scanner.scan` to influence error behavior when an
        exception is raised during the scanning process.  See the
        :term:`Venusian` documentation for more information about ``onerror``
        callbacks.

        To perform a ``scan``, Pyramid creates a Venusian ``Scanner`` object.
        The ``kw`` argument represents a set of keyword arguments to pass to
        the Venusian ``Scanner`` object's constructor.  See the
        :term:`venusian` documentation (its ``Scanner`` class) for more
        information about the constructor.  By default, the only keyword
        arguments passed to the Scanner constructor are ``{'config':self}``
        where ``self`` is this configurator object.  This services the
        requirement of all built-in Pyramid decorators, but extension systems
        may require additional arguments.  Providing this argument is not
        often necessary; it's an advanced usage.

        .. note:: the ``**kw`` argument is new in Pyramid 1.1
        """
        package = self.maybe_dotted(package)
        if package is None:  # pragma: no cover
            package = caller_package()

        ctorkw = {'config': self}
        ctorkw.update(kw)

        scanner = self.venusian.Scanner(**ctorkw)
        scanner.scan(package, categories=categories, onerror=onerror)
Esempio n. 44
0
    def scan(self, package=None, categories=None, onerror=None, **kw):
        """Scan a Python package and any of its subpackages for objects
        marked with :term:`configuration decoration` such as
        :class:`pyramid.view.view_config`.  Any decorated object found will
        influence the current configuration state.

        The ``package`` argument should be a Python :term:`package` or module
        object (or a :term:`dotted Python name` which refers to such a
        package or module).  If ``package`` is ``None``, the package of the
        *caller* is used.

        The ``categories`` argument, if provided, should be the
        :term:`Venusian` 'scan categories' to use during scanning.  Providing
        this argument is not often necessary; specifying scan categories is
        an extremely advanced usage.  By default, ``categories`` is ``None``
        which will execute *all* Venusian decorator callbacks including
        :app:`Pyramid`-related decorators such as
        :class:`pyramid.view.view_config`.  See the :term:`Venusian`
        documentation for more information about limiting a scan by using an
        explicit set of categories.

        The ``onerror`` argument, if provided, should be a Venusian
        ``onerror`` callback function.  The onerror function is passed to
        :meth:`venusian.Scanner.scan` to influence error behavior when an
        exception is raised during the scanning process.  See the
        :term:`Venusian` documentation for more information about ``onerror``
        callbacks.

        To perform a ``scan``, Pyramid creates a Venusian ``Scanner`` object.
        The ``kw`` argument represents a set of keyword arguments to pass to
        the Venusian ``Scanner`` object's constructor.  See the
        :term:`venusian` documentation (its ``Scanner`` class) for more
        information about the constructor.  By default, the only keyword
        arguments passed to the Scanner constructor are ``{'config':self}``
        where ``self`` is this configurator object.  This services the
        requirement of all built-in Pyramid decorators, but extension systems
        may require additional arguments.  Providing this argument is not
        often necessary; it's an advanced usage.

        .. note:: the ``**kw`` argument is new in Pyramid 1.1
        """
        package = self.maybe_dotted(package)
        if package is None: # pragma: no cover
            package = caller_package()

        ctorkw = {'config':self}
        ctorkw.update(kw)

        scanner = self.venusian.Scanner(**ctorkw)
        scanner.scan(package, categories=categories, onerror=onerror)
Esempio n. 45
0
def get_renderer(renderer_name, package=None):
    """ Return the renderer object for the renderer ``renderer_name``.

    You may supply a relative asset spec as ``renderer_name``.  If
    the ``package`` argument is supplied, a relative renderer name
    will be converted to an absolute asset specification by
    combining the package ``package`` with the relative
    asset specification ``renderer_name``.  If ``package`` is ``None``
    (the default), the package name of the *caller* of this function
    will be used as the package.
    """
    if package is None:
        package = caller_package()
    helper = RendererHelper(name=renderer_name, package=package)
    return helper.renderer
Esempio n. 46
0
def render_template(path, **kw):
    """ Render a :term:`Chameleon` ZPT template using the template
    implied by the ``path`` argument.  The ``path`` argument may be a
    package-relative path, an absolute path, or a :term:`resource
    specification`.  The arguments in ``*kw`` are passed as top-level
    names to the template, and so may be used within the template
    itself.  Returns a string.

    .. warning:: This API is deprecated in :app:`Pyramid` 1.0.  Use
       :func:`pyramid.renderers.render` instead.
    """
    package = caller_package()
    request = kw.pop('request', None)
    renderer = renderers.RendererHelper(name=path, package=package)
    return renderer.render(kw, None, request=request)
Esempio n. 47
0
def load_schema(filename):
    if isinstance(filename, dict):
        schema = filename
        resolver = NoRemoteResolver.from_schema(schema)
    else:
        utf8 = codecs.getreader("utf-8")
        asset = AssetResolver(caller_package()).resolve(filename)
        schema = json.load(utf8(asset.stream()),
                           object_pairs_hook=collections.OrderedDict)
        resolver = RefResolver('file://' + asset.abspath(), schema)
    schema = mixinProperties(schema, resolver)

    # SchemaValidator is not thread safe for now
    SchemaValidator(schema, resolver=resolver, serialize=True)
    return schema
Esempio n. 48
0
def render_template(path, **kw):
    """ Render a :term:`Chameleon` text template using the template
    implied by the ``path`` argument.  The ``path`` argument may be a
    package-relative path, an absolute path, or a :term:`asset
    specification`.  The arguments in ``*kw`` are passed as top-level
    names to the template, and so may be used within the template
    itself.  Returns a string.

    .. warning:: This API is deprecated in :app:`Pyramid` 1.0.  Use
       :func:`pyramid.renderers.render` instead.
    """
    package = caller_package()
    request = kw.pop('request', None)
    renderer = renderers.RendererHelper(path, package=package)
    return renderer.render(kw, None, request=request)
Esempio n. 49
0
    def __call__(self, info):
        spec = self.get_spec(info.name, info.package)
        registry = info.registry

        if os.path.isabs(spec):
            # 'spec' is an absolute filename
            if not os.path.exists(spec):
                raise ValueError('Missing template file: %s' % spec)
            renderer = registry.queryUtility(ITemplateRenderer, name=spec)
            if renderer is None:
                renderer = self.impl(spec, self)
                # cache the template
                try:
                    self.lock.acquire()
                    registry.registerUtility(renderer,
                                             ITemplateRenderer,
                                             name=spec)
                finally:
                    self.lock.release()
        else:
            # spec is a package:relpath asset spec
            renderer = registry.queryUtility(ITemplateRenderer, name=spec)
            if renderer is None:
                try:
                    package_name, filename = spec.split(':', 1)
                except ValueError:  # pragma: no cover
                    # somehow we were passed a relative pathname; this
                    # should die
                    package_name = caller_package(4).__name__
                    filename = spec
                abspath = pkg_resources.resource_filename(
                    package_name, filename)
                if not pkg_resources.resource_exists(package_name, filename):
                    raise ValueError('Missing template asset: %s (%s)' %
                                     (spec, abspath))
                renderer = self.impl(abspath, self)
                settings = info.settings
                if not settings.get('reload_assets'):
                    # cache the template
                    self.lock.acquire()
                    try:
                        registry.registerUtility(renderer,
                                                 ITemplateRenderer,
                                                 name=spec)
                    finally:
                        self.lock.release()

        return renderer
Esempio n. 50
0
def render_to_response(renderer_name, value, request=None, package=None):
    """ Using the renderer specified as ``renderer_name`` (a template
    or a static renderer) render the value (or set of values) using
    the result of the renderer's ``__call__`` method (usually a string
    or Unicode) as the response body.

    If the renderer name refers to a file on disk (such as when the
    renderer is a template), it's usually best to supply the name as a
    :term:`asset specification`.

    You may supply a relative asset spec as ``renderer_name``.  If
    the ``package`` argument is supplied, a relative renderer name
    will be converted to an absolute asset specification by
    combining the package supplied as ``package`` with the relative
    asset specification supplied as ``renderer_name``.  If you do
    not supply a ``package`` (or ``package`` is ``None``) the package
    name of the *caller* of this function will be used as the package.

    The ``value`` provided will be supplied as the input to the
    renderer.  Usually, for template renderings, this should be a
    dictionary.  For other renderers, this will need to be whatever
    sort of value the renderer expects.

    The 'system' values supplied to the renderer will include a basic set of
    top-level system names, such as ``request``, ``context``,
    ``renderer_name``, and ``view``.  See :ref:`renderer_system_values` for
    the full list.  If :term:`renderer globals` have been specified, these
    will also be used to agument the value.

    Supply a ``request`` parameter in order to provide the renderer
    with the most correct 'system' values (``request`` and ``context``
    in particular). Keep in mind that if the ``request`` parameter is
    not passed in, any changes to ``request.response`` attributes made
    before calling this function will be ignored.

    """
    try:
        registry = request.registry
    except AttributeError:
        registry = None
    if package is None:
        package = caller_package()
    helper = RendererHelper(name=renderer_name,
                            package=package,
                            registry=registry)
    return helper.render_to_response(value, None, request=request)
Esempio n. 51
0
def static_path(path, request, **kw):
    """
    This is a backwards compatibility function.  Its result is the same as
    calling::

        request.static_path(path, **kw)

    See :meth:`pyramid.request.Request.static_path` for more information.
    """
    if not os.path.isabs(path):
        if not ':' in path:
            # if it's not a package:relative/name and it's not an
            # /absolute/path it's a relative/path; this means its relative
            # to the package in which the caller's module is defined.
            package = caller_package()
            path = '%s:%s' % (package.__name__, path)
    return request.static_path(path, **kw)
Esempio n. 52
0
def traced_init(wrapped, instance, args, kwargs):
    settings = kwargs.pop("settings", {})
    service = config._get_service(default="pyramid")
    distributed_tracing = asbool(
        get_env("pyramid", "distributed_tracing", default=True))
    # DEV: integration-specific analytics flag can be not set but still enabled
    # globally for web frameworks
    old_analytics_enabled = get_env("pyramid", "analytics_enabled")
    analytics_enabled = os.environ.get("DD_TRACE_PYRAMID_ANALYTICS_ENABLED",
                                       old_analytics_enabled)
    if analytics_enabled is not None:
        analytics_enabled = asbool(analytics_enabled)
    # TODO: why is analytics sample rate a string or a bool here?
    old_analytics_sample_rate = get_env("pyramid",
                                        "analytics_sample_rate",
                                        default=True)
    analytics_sample_rate = os.environ.get(
        "DD_TRACE_PYRAMID_ANALYTICS_SAMPLE_RATE", old_analytics_sample_rate)
    trace_settings = {
        SETTINGS_SERVICE: service,
        SETTINGS_DISTRIBUTED_TRACING: distributed_tracing,
        SETTINGS_ANALYTICS_ENABLED: analytics_enabled,
        SETTINGS_ANALYTICS_SAMPLE_RATE: analytics_sample_rate,
    }
    # Update over top of the defaults
    # DEV: If we did `settings.update(trace_settings)` then we would only ever
    #      have the default values.
    trace_settings.update(settings)
    # If the tweens are explicitly set with 'pyramid.tweens', we need to
    # explicitly set our tween too since `add_tween` will be ignored.
    insert_tween_if_needed(trace_settings)
    kwargs["settings"] = trace_settings

    # `caller_package` works by walking a fixed amount of frames up the stack
    # to find the calling package. So if we let the original `__init__`
    # function call it, our wrapper will mess things up.
    if not kwargs.get("package", None):
        # Get the packge for the third frame up from this one.
        #   - ddtrace.contrib.pyramid.path
        #   - ddtrace.vendor.wrapt
        #   - (this is the frame we want)
        # DEV: Default is `level=2` which will give us the package from `wrapt`
        kwargs["package"] = caller_package(level=3)

    wrapped(*args, **kwargs)
    trace_pyramid(instance)
Esempio n. 53
0
def traced_init(wrapped, instance, args, kwargs):
    settings = kwargs.pop('settings', {})
    service = os.environ.get('DATADOG_SERVICE_NAME') or 'pyramid'
    trace_settings = {
        'datadog_trace_service': service,
    }
    settings.update(trace_settings)
    kwargs['settings'] = settings

    # `caller_package` works by walking a fixed amount of frames up the stack
    # to find the calling package. So if we let the original `__init__`
    # function call it, our wrapper will mess things up.
    if not kwargs.get('package', None):
        kwargs['package'] = caller_package()

    wrapped(*args, **kwargs)
    trace_pyramid(instance)
Esempio n. 54
0
def ResolveName(name, base=None, raiseExcp=True):
    """
    Lookup python object by dotted python name.
    Wraps pyramid.DottedNameResolver.
    
    returns object or None
    """
    if not name:
        return None
    if not isinstance(name, basestring):
        return name
    if not base:
        base = caller_package()
    if not raiseExcp:
        d = DottedNameResolver(base)
        return d.maybe_resolve(name)
    d = DottedNameResolver(base)
    return d.resolve(name)
Esempio n. 55
0
    def __call__(self, info):
        spec = self.get_spec(info.name, info.package)
        registry = info.registry

        if os.path.isabs(spec):
            # 'spec' is an absolute filename
            if not os.path.exists(spec):
                raise ValueError('Missing template file: %s' % spec)
            renderer = registry.queryUtility(IChameleonTemplateRenderer, name=spec)
            if renderer is None:
                renderer = self.impl(spec, self, macro=None)
                # cache the template
                with self.lock:
                    registry.registerUtility(renderer,
                                             IChameleonTemplateRenderer, name=spec)
        else:
            # spec is a package:relpath asset spec
            renderer = registry.queryUtility(IChameleonTemplateRenderer, name=spec)
            if renderer is None:
                asset, macro, ext = self._crack_spec(spec)
                spec_without_macro = '%s.%s' % (asset, ext)
                try:
                    package_name, filename = spec_without_macro.split(':', 1)
                except ValueError: # pragma: no cover
                    # somehow we were passed a relative pathname; this
                    # should die
                    package_name = caller_package(4).__name__
                    filename = spec_without_macro
                abspath = pkg_resources.resource_filename(package_name,
                                                          filename)
                if not pkg_resources.resource_exists(package_name, filename):
                    raise ValueError(
                        'Missing template asset: %s (%s)' % (
                            spec_without_macro, abspath)
                        )
                renderer = self.impl(abspath, self, macro=macro)
                settings = info.settings
                if not settings.get('reload_assets'):
                    # cache the template
                    with self.lock:
                        registry.registerUtility(renderer, IChameleonTemplateRenderer,
                                                 name=spec)

        return renderer