示例#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)
示例#2
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
示例#3
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,
         )
示例#4
0
文件: tmpl.py 项目: blaflamme/ptah
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
示例#5
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
示例#6
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)
示例#7
0
文件: config.py 项目: SMFOSS/Prism
    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']        
示例#8
0
文件: static.py 项目: canni/pyramid
    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()
示例#9
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
示例#10
0
文件: core.py 项目: fschulze/stasis
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))
示例#11
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)
示例#12
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)
示例#13
0
文件: url.py 项目: csenger/pyramid
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)
示例#14
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
示例#15
0
文件: view.py 项目: 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)
示例#16
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
示例#17
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)
示例#18
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)
示例#19
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
示例#20
0
文件: static.py 项目: rjweir/pyramid
 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
示例#21
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
示例#22
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()
示例#23
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,
         )
示例#24
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()
示例#25
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()
示例#26
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
示例#27
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
示例#28
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)
示例#29
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)
示例#30
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