| | |
| | | if self._clean_principal(userid) is None: |
| | | debug and self._log( |
| | | ( |
| | | 'unauthenticated_userid returned disallowed %r; returning %r ' |
| | | 'as if it was None' % (userid, effective_principals) |
| | | 'unauthenticated_userid returned disallowed %r; returning ' |
| | | '%r as if it was None' % (userid, effective_principals) |
| | | ), |
| | | 'effective_principals', |
| | | request, |
| | |
| | | if groups is None: # is None! |
| | | self.debug and self._log( |
| | | ( |
| | | 'security policy groups callback returned None; returning %r' |
| | | % effective_principals |
| | | 'security policy groups callback returned None; returning ' |
| | | '%r' % effective_principals |
| | | ), |
| | | 'effective_principals', |
| | | request, |
| | |
| | | if self._clean_principal(userid) is None: |
| | | self.debug and self._log( |
| | | ( |
| | | 'unauthenticated_userid returned disallowed %r; returning %r ' |
| | | 'as if it was None' % (userid, effective_principals) |
| | | 'unauthenticated_userid returned disallowed %r; returning ' |
| | | '%r as if it was None' % (userid, effective_principals) |
| | | ), |
| | | 'effective_principals', |
| | | request, |
| | |
| | | .. versionchanged:: 1.10 |
| | | |
| | | Added the ``samesite`` option and made the default ``'Lax'``. |
| | | |
| | | |
| | | Objects of this class implement the interface described by |
| | | :class:`pyramid.interfaces.IAuthenticationPolicy`. |
| | | |
| | |
| | | "userid is of type {}, and is not supported by the " |
| | | "AuthTktAuthenticationPolicy. Explicitly converting to string " |
| | | "and storing as base64. Subsequent requests will receive a " |
| | | "string as the userid, it will not be decoded back to the type " |
| | | "provided.".format(type(userid)), |
| | | "string as the userid, it will not be decoded back to the " |
| | | "type provided.".format(type(userid)), |
| | | RuntimeWarning, |
| | | ) |
| | | encoding, encoder = self.userid_type_encoders.get(text_type) |
| | |
| | | |
| | | ``realm`` |
| | | |
| | | Default: ``"Realm"``. The Basic Auth Realm string. Usually displayed to |
| | | the user by the browser in the login dialog. |
| | | Default: ``"Realm"``. The Basic Auth Realm string. Usually displayed |
| | | to the user by the browser in the login dialog. |
| | | |
| | | ``debug`` |
| | | |
| | |
| | | # commit below because: |
| | | # |
| | | # - the default exceptionresponse_view requires the superdefault view |
| | | # mapper, so we need to configure it before adding default_view_mapper |
| | | # mapper, so we need to configure it before adding |
| | | # default_view_mapper |
| | | # |
| | | # - superdefault renderers should be overrideable without requiring |
| | | # the user to commit before calling config.add_renderer |
| | |
| | | For backwards compatibility purposes (as of :app:`Pyramid` 1.0), a |
| | | ``path`` keyword argument passed to this function will be used to |
| | | represent the pattern value if the ``pattern`` argument is |
| | | ``None``. If both ``path`` and ``pattern`` are passed, ``pattern`` |
| | | wins. |
| | | ``None``. If both ``path`` and ``pattern`` are passed, |
| | | ``pattern`` wins. |
| | | |
| | | xhr |
| | | |
| | |
| | | if custom_predicates: |
| | | warnings.warn( |
| | | ( |
| | | 'The "custom_predicates" argument to Configurator.add_route ' |
| | | 'is deprecated as of Pyramid 1.5. Use ' |
| | | '"config.add_route_predicate" and use the registered ' |
| | | 'The "custom_predicates" argument to ' |
| | | 'Configurator.add_route is deprecated as of Pyramid 1.5. ' |
| | | 'Use "config.add_route_predicate" and use the registered ' |
| | | 'route predicate as a predicate argument to add_route ' |
| | | 'instead. See "Adding A Third Party View, Route, or ' |
| | | 'Subscriber Predicate" in the "Hooks" chapter of the ' |
| | |
| | | if '*' in accept: |
| | | warnings.warn( |
| | | ( |
| | | 'Passing a media range to the "accept" argument of ' |
| | | 'Configurator.add_route is deprecated as of Pyramid ' |
| | | '1.10. Use a list of explicit media types.' |
| | | 'Passing a media range to the "accept" argument ' |
| | | 'of Configurator.add_route is deprecated as of ' |
| | | 'Pyramid 1.10. Use a list of explicit media types.' |
| | | ), |
| | | DeprecationWarning, |
| | | stacklevel=3, |
| | |
| | | - An iterable of any combination of the above. This allows the user |
| | | to specify fallbacks if the desired tween is not included, as well |
| | | as compatibility with multiple other tweens. |
| | | |
| | | |
| | | ``under`` means 'closer to the main Pyramid application than', |
| | | ``over`` means 'closer to the request ingress than'. |
| | | |
| | |
| | | def add(self, name, factory, weighs_more_than=None, weighs_less_than=None): |
| | | # Predicates should be added to a predicate list in (presumed) |
| | | # computation expense order. |
| | | ## if weighs_more_than is None and weighs_less_than is None: |
| | | ## weighs_more_than = self.last_added or FIRST |
| | | ## weighs_less_than = LAST |
| | | # if weighs_more_than is None and weighs_less_than is None: |
| | | # weighs_more_than = self.last_added or FIRST |
| | | # weighs_less_than = LAST |
| | | self.last_added = name |
| | | self.sorter.add( |
| | | name, factory, after=weighs_more_than, before=weighs_less_than |
| | |
| | | If CSRF checking is performed, the checked value will be the value of |
| | | ``request.params[check_name]``. This value will be compared against |
| | | the value of ``policy.get_csrf_token()`` (where ``policy`` is an |
| | | implementation of :meth:`pyramid.interfaces.ICSRFStoragePolicy`), and the |
| | | check will pass if these two values are the same. If the check |
| | | implementation of :meth:`pyramid.interfaces.ICSRFStoragePolicy`), and |
| | | the check will pass if these two values are the same. If the check |
| | | passes, the associated view will be permitted to execute. If the |
| | | check fails, the associated view will not be permitted to execute. |
| | | |
| | |
| | | if custom_predicates: |
| | | warnings.warn( |
| | | ( |
| | | 'The "custom_predicates" argument to Configurator.add_view ' |
| | | 'is deprecated as of Pyramid 1.5. Use ' |
| | | '"config.add_view_predicate" and use the registered ' |
| | | 'view predicate as a predicate argument to add_view instead. ' |
| | | 'See "Adding A Third Party View, Route, or Subscriber ' |
| | | 'Predicate" in the "Hooks" chapter of the documentation ' |
| | | 'for more information.' |
| | | 'The "custom_predicates" argument to ' |
| | | 'Configurator.add_view is deprecated as of Pyramid 1.5. ' |
| | | 'Use "config.add_view_predicate" and use the registered ' |
| | | 'view predicate as a predicate argument to add_view ' |
| | | 'instead. See "Adding A Third Party View, Route, or ' |
| | | 'Subscriber Predicate" in the "Hooks" chapter of the ' |
| | | 'documentation for more information.' |
| | | ), |
| | | DeprecationWarning, |
| | | stacklevel=4, |
| | |
| | | warnings.warn( |
| | | ( |
| | | 'The "check_csrf" argument to Configurator.add_view is ' |
| | | 'deprecated as of Pyramid 1.7. Use the "require_csrf" option ' |
| | | 'instead or see "Checking CSRF Tokens Automatically" in the ' |
| | | '"Sessions" chapter of the documentation for more ' |
| | | 'information.' |
| | | 'deprecated as of Pyramid 1.7. Use the "require_csrf" ' |
| | | 'option instead or see "Checking CSRF Tokens ' |
| | | 'Automatically" in the "Sessions" chapter of the ' |
| | | 'documentation for more information.' |
| | | ), |
| | | DeprecationWarning, |
| | | stacklevel=4, |
| | |
| | | warnings.warn( |
| | | ( |
| | | 'Passing a media range to the "accept" argument of ' |
| | | 'Configurator.add_view is deprecated as of Pyramid 1.10. ' |
| | | 'Use explicit media types to avoid ambiguities in ' |
| | | 'content negotiation that may impact your users.' |
| | | 'Configurator.add_view is deprecated as of ' |
| | | 'Pyramid 1.10. Use explicit media types to avoid ' |
| | | 'ambiguities in content negotiation that may impact ' |
| | | 'your users.' |
| | | ), |
| | | DeprecationWarning, |
| | | stacklevel=4, |
| | |
| | | config.add_notfound_view(append_slash=HTTPMovedPermanently) |
| | | |
| | | The above means that a redirect to a slash-appended route will be |
| | | attempted, but instead of :class:`~pyramid.httpexceptions.HTTPTemporaryRedirect` |
| | | attempted, but instead of |
| | | :class:`~pyramid.httpexceptions.HTTPTemporaryRedirect` |
| | | being used, :class:`~pyramid.httpexceptions.HTTPMovedPermanently will |
| | | be used` for the redirect response if a slash-appended route is found. |
| | | |
| | |
| | | |
| | | .. versionchanged: 1.10 |
| | | |
| | | Default response was changed from :class:`~pyramid.httpexceptions.HTTPFound` |
| | | Default response was changed from |
| | | :class:`~pyramid.httpexceptions.HTTPFound` |
| | | to :class:`~pyramid.httpexceptions.HTTPTemporaryRedirect`. |
| | | |
| | | """ |
| | |
| | | Check the ``Origin`` of the request to see if it is a cross site request or |
| | | not. |
| | | |
| | | If the value supplied by the ``Origin`` or ``Referer`` header isn't one of the |
| | | trusted origins and ``raises`` is ``True``, this function will raise a |
| | | If the value supplied by the ``Origin`` or ``Referer`` header isn't one of |
| | | the trusted origins and ``raises`` is ``True``, this function will raise a |
| | | :exc:`pyramid.exceptions.BadCSRFOrigin` exception, but if ``raises`` is |
| | | ``False``, this function will return ``False`` instead. If the CSRF origin |
| | | checks are successful this function will return ``True`` unconditionally. |
| | |
| | | |
| | | @implementer(IExceptionResponse) |
| | | class HTTPException(Response, Exception): |
| | | |
| | | ## You should set in subclasses: |
| | | # You should set in subclasses: |
| | | # code = 200 |
| | | # title = 'OK' |
| | | # explanation = 'why this happens' |
| | |
| | | # implies that this class' ``exception`` property always returns |
| | | # ``self`` (it exists only for bw compat at this point). |
| | | # |
| | | # - documentation improvements (Pyramid-specific docstrings where necessary) |
| | | # - documentation improvements (Pyramid-specific docstrings where |
| | | # necessary) |
| | | # |
| | | code = 520 |
| | | title = 'Unknown Error' |
| | |
| | | </html>''' |
| | | ) |
| | | |
| | | ## Set this to True for responses that should have no request body |
| | | # Set this to True for responses that should have no request body |
| | | empty_body = False |
| | | |
| | | def __init__( |
| | |
| | | |
| | | |
| | | ############################################################ |
| | | ## 2xx success |
| | | # 2xx success |
| | | ############################################################ |
| | | |
| | | |
| | |
| | | title = 'Partial Content' |
| | | |
| | | |
| | | ## FIXME: add 207 Multi-Status (but it's complicated) |
| | | # FIXME: add 207 Multi-Status (but it's complicated) |
| | | |
| | | ############################################################ |
| | | ## 3xx redirection |
| | | # 3xx redirection |
| | | ############################################################ |
| | | |
| | | |
| | |
| | | |
| | | |
| | | ############################################################ |
| | | ## 4xx client error |
| | | # 4xx client error |
| | | ############################################################ |
| | | |
| | | |
| | |
| | | code: 422, title: Unprocessable Entity |
| | | """ |
| | | |
| | | ## Note: from WebDAV |
| | | # Note: from WebDAV |
| | | code = 422 |
| | | title = 'Unprocessable Entity' |
| | | explanation = 'Unable to process the contained instructions' |
| | |
| | | code: 423, title: Locked |
| | | """ |
| | | |
| | | ## Note: from WebDAV |
| | | # Note: from WebDAV |
| | | code = 423 |
| | | title = 'Locked' |
| | | explanation = 'The resource is locked' |
| | |
| | | code: 424, title: Failed Dependency |
| | | """ |
| | | |
| | | ## Note: from WebDAV |
| | | # Note: from WebDAV |
| | | code = 424 |
| | | title = 'Failed Dependency' |
| | | explanation = ( |
| | |
| | | |
| | | |
| | | ############################################################ |
| | | ## 5xx Server Error |
| | | # 5xx Server Error |
| | | ############################################################ |
| | | # Response status codes beginning with the digit "5" indicate cases in |
| | | # which the server is aware that it has erred or is incapable of |
| | |
| | | and ``plural`` objects should be unicode strings. There is no |
| | | reason to use translation string objects as arguments as all |
| | | metadata is ignored. |
| | | |
| | | |
| | | ``n`` represents the number of elements. ``domain`` is the |
| | | translation domain to use to do the pluralization, and ``mapping`` |
| | | is the interpolation mapping that should be used on the result. If |
| | | the ``domain`` is not supplied, a default domain is used (usually |
| | | ``messages``). |
| | | |
| | | |
| | | Example:: |
| | | |
| | | num = 1 |
| | |
| | | num, |
| | | mapping={'num':num}) |
| | | |
| | | |
| | | |
| | | """ |
| | | if self.pluralizer is None: |
| | | self.pluralizer = Pluralizer(self.translations) |
| | |
| | | the request object (possibly set by a view or a listener for an |
| | | :term:`event`). If the attribute exists and it is not ``None``, |
| | | its value will be used. |
| | | |
| | | |
| | | - Then it looks for the ``request.params['_LOCALE_']`` value. |
| | | |
| | | - Then it looks for the ``request.cookies['_LOCALE_']`` value. |
| | |
| | | |
| | | def make_localizer(current_locale_name, translation_directories): |
| | | """ Create a :class:`pyramid.i18n.Localizer` object |
| | | corresponding to the provided locale name from the |
| | | corresponding to the provided locale name from the |
| | | translations found in the list of translation directories.""" |
| | | translations = Translations() |
| | | translations._catalog = {} |
| | |
| | | return self._domains.get(domain, self).gettext(message) |
| | | |
| | | def ldgettext(self, domain, message): |
| | | """Like ``lgettext()``, but look the message up in the specified |
| | | """Like ``lgettext()``, but look the message up in the specified |
| | | domain. |
| | | """ |
| | | return self._domains.get(domain, self).lgettext(message) |
| | |
| | | method = getattr(introspector, methodname) |
| | | method((i.category_name, i.discriminator), |
| | | (category_name, discriminator)) |
| | | """ |
| | | """ # noqa: E501 |
| | | |
| | | def __hash__(): |
| | | |
| | |
| | | |
| | | class IActionInfo(Interface): |
| | | """ Class which provides code introspection capability associated with an |
| | | action. The ParserInfo class used by ZCML implements the same interface.""" |
| | | action. The ParserInfo class used by ZCML implements the same interface. |
| | | """ |
| | | |
| | | file = Attribute('Filename of action-invoking code as a string') |
| | | line = Attribute( |
| | |
| | | |
| | | Calling ``lineage(thing2)`` will return a generator. When we turn |
| | | it into a list, we will get:: |
| | | |
| | | |
| | | list(lineage(thing2)) |
| | | [ <Thing object at thing2>, <Thing object at thing1> ] |
| | | """ |
| | |
| | | for you if none is provided. You can mutate the request's ``environ`` |
| | | later to setup a specific host/port/scheme/etc. |
| | | |
| | | ``options`` Is passed to get_app for use as variable assignments like |
| | | ``options`` Is passed to get_app for use as variable assignments like |
| | | {'http_port': 8080} and then use %(http_port)s in the |
| | | config file. |
| | | |
| | |
| | | """ Backwards compatibility shim module (forever). """ |
| | | from pyramid.asset import * # b/w compat |
| | | from pyramid.asset import * # noqa b/w compat |
| | | |
| | | resolve_resource_spec = resolve_asset_spec |
| | | resource_spec_from_abspath = asset_spec_from_abspath |
| | | abspath_from_resource_spec = abspath_from_asset_spec |
| | | resolve_resource_spec = resolve_asset_spec # noqa |
| | | resource_spec_from_abspath = asset_spec_from_abspath # noqa |
| | | abspath_from_resource_spec = abspath_from_asset_spec # noqa |
| | |
| | | |
| | | Welcome to Pyramid. Sorry for the convenience. |
| | | %(separator)s |
| | | """ |
| | | """ # noqa: E501 |
| | | % {'separator': separator} |
| | | ) |
| | | |
| | |
| | | """ |
| | | A function that calls :meth:`pyramid.request.Request.has_permission` |
| | | and returns its result. |
| | | |
| | | |
| | | .. deprecated:: 1.5 |
| | | Use :meth:`pyramid.request.Request.has_permission` instead. |
| | | |
| | |
| | | """ |
| | | A function that returns the value of the property |
| | | :attr:`pyramid.request.Request.authenticated_userid`. |
| | | |
| | | |
| | | .. deprecated:: 1.5 |
| | | Use :attr:`pyramid.request.Request.authenticated_userid` instead. |
| | | """ |
| | |
| | | |
| | | |
| | | def unauthenticated_userid(request): |
| | | """ |
| | | """ |
| | | A function that returns the value of the property |
| | | :attr:`pyramid.request.Request.unauthenticated_userid`. |
| | | |
| | | |
| | | .. deprecated:: 1.5 |
| | | Use :attr:`pyramid.request.Request.unauthenticated_userid` instead. |
| | | """ |
| | |
| | | """ |
| | | A function that returns the value of the property |
| | | :attr:`pyramid.request.Request.effective_principals`. |
| | | |
| | | |
| | | .. deprecated:: 1.5 |
| | | Use :attr:`pyramid.request.Request.effective_principals` instead. |
| | | """ |
| | |
| | | The :term:`root` resource *must* have a ``__name__`` attribute with a |
| | | value of either ``None`` or the empty string for path tuples to be |
| | | generated properly. If the root resource has a non-null ``__name__`` |
| | | attribute, its name will be the first element in the generated path tuple |
| | | rather than the empty string. |
| | | attribute, its name will be the first element in the generated path |
| | | tuple rather than the empty string. |
| | | """ |
| | | return tuple(_resource_path_list(resource, *elements)) |
| | | |
| | |
| | | |
| | | |
| | | def _resource_path_list(resource, *elements): |
| | | """ Implementation detail shared by resource_path and resource_path_tuple""" |
| | | """ Implementation detail shared by resource_path and |
| | | resource_path_tuple""" |
| | | path = [loc.__name__ or '' for loc in lineage(resource)] |
| | | path.reverse() |
| | | path.extend(elements) |
| | |
| | | |
| | | This function does not generate the same type of tuples that |
| | | :func:`pyramid.traversal.resource_path_tuple` does. In particular, the |
| | | leading empty string is not present in the tuple it returns, unlike tuples |
| | | returned by :func:`pyramid.traversal.resource_path_tuple`. As a result, |
| | | tuples generated by ``traversal_path`` are not resolveable by the |
| | | :func:`pyramid.traversal.find_resource` API. ``traversal_path`` is a |
| | | function mostly used by the internals of :app:`Pyramid` and by people |
| | | leading empty string is not present in the tuple it returns, unlike |
| | | tuples returned by :func:`pyramid.traversal.resource_path_tuple`. As a |
| | | result, tuples generated by ``traversal_path`` are not resolveable by |
| | | the :func:`pyramid.traversal.find_resource` API. ``traversal_path`` is |
| | | a function mostly used by the internals of :app:`Pyramid` and by people |
| | | writing their own traversal machinery, as opposed to users writing |
| | | applications in :app:`Pyramid`. |
| | | """ |
| | |
| | | |
| | | Python data structures that are passed as ``_query`` which are |
| | | sequences or dictionaries are turned into a string under the same |
| | | rules as when run through :func:`urllib.urlencode` with the ``doseq`` |
| | | argument equal to ``True``. This means that sequences can be passed |
| | | as values, and a k=v pair will be placed into the query string for |
| | | each value. |
| | | rules as when run through :func:`urllib.urlencode` with the |
| | | ``doseq`` argument equal to ``True``. This means that sequences can |
| | | be passed as values, and a k=v pair will be placed into the query |
| | | string for each value. |
| | | |
| | | If a keyword argument ``_anchor`` is present, its string |
| | | representation will be quoted per :rfc:`3986#section-3.5` and used as |
| | |
| | | ``_host='foo.com'``, and the URL that would have been generated |
| | | without the host replacement is ``http://example.com/a``, the result |
| | | will be ``http://foo.com/a``. |
| | | |
| | | |
| | | Note that if ``_scheme`` is passed as ``https``, and ``_port`` is not |
| | | passed, the ``_port`` value is assumed to have been passed as |
| | | ``443``. Likewise, if ``_scheme`` is passed as ``http`` and |
| | |
| | | |
| | | Python data structures that are passed as ``query`` which are |
| | | sequences or dictionaries are turned into a string under the same |
| | | rules as when run through :func:`urllib.urlencode` with the ``doseq`` |
| | | argument equal to ``True``. This means that sequences can be passed |
| | | as values, and a k=v pair will be placed into the query string for |
| | | each value. |
| | | rules as when run through :func:`urllib.urlencode` with the |
| | | ``doseq`` argument equal to ``True``. This means that sequences can |
| | | be passed as values, and a k=v pair will be placed into the query |
| | | string for each value. |
| | | |
| | | If a keyword argument ``anchor`` is present, its string |
| | | representation will be used as a named anchor in the generated URL |
| | |
| | | ``host='foo.com'``, and the URL that would have been generated |
| | | without the host replacement is ``http://example.com/a``, the result |
| | | will be ``http://foo.com/a``. |
| | | |
| | | |
| | | If ``scheme`` is passed as ``https``, and an explicit ``port`` is not |
| | | passed, the ``port`` value is assumed to have been passed as ``443``. |
| | | Likewise, if ``scheme`` is passed as ``http`` and ``port`` is not |
| | |
| | | If the ``resource`` passed in has a ``__resource_url__`` method, it |
| | | will be used to generate the URL (scheme, host, port, path) for the |
| | | base resource which is operated upon by this function. |
| | | |
| | | |
| | | .. seealso:: |
| | | |
| | | See also :ref:`overriding_resource_url_generation`. |
| | | |
| | | |
| | | If ``route_name`` is passed, this function will delegate its URL |
| | | production to the ``route_url`` function. Calling |
| | | ``resource_url(someresource, 'element1', 'element2', query={'a':1}, |
| | |
| | | is passed, the ``__resource_url__`` method of the resource passed is |
| | | ignored unconditionally. This feature is incompatible with |
| | | resources which generate their own URLs. |
| | | |
| | | |
| | | .. note:: |
| | | |
| | | If the :term:`resource` used is the result of a :term:`traversal`, it |
| | | must be :term:`location`-aware. The resource can also be the context |
| | | of a :term:`URL dispatch`; contexts found this way do not need to be |
| | | location-aware. |
| | | If the :term:`resource` used is the result of a :term:`traversal`, |
| | | it must be :term:`location`-aware. The resource can also be the |
| | | context of a :term:`URL dispatch`; contexts found this way do not |
| | | need to be location-aware. |
| | | |
| | | .. note:: |
| | | |
| | | If a 'virtual root path' is present in the request environment (the |
| | | value of the WSGI environ key ``HTTP_X_VHM_ROOT``), and the resource |
| | | was obtained via :term:`traversal`, the URL path will not include the |
| | | virtual root prefix (it will be stripped off the left hand side of |
| | | the generated URL). |
| | | was obtained via :term:`traversal`, the URL path will not include |
| | | the virtual root prefix (it will be stripped off the left hand side |
| | | of the generated URL). |
| | | |
| | | .. note:: |
| | | |
| | |
| | | |
| | | See the :py:func:`venusian.attach` function in Venusian for more |
| | | information about the ``_depth`` and ``_category`` arguments. |
| | | |
| | | |
| | | .. seealso:: |
| | | |
| | | |
| | | See also :ref:`mapping_views_using_a_decorator_section` for |
| | | details about using :class:`pyramid.view.view_config`. |
| | | |
| | | .. warning:: |
| | | |
| | | |
| | | ``view_config`` will work ONLY on module top level members |
| | | because of the limitation of ``venusian.Scanner.scan``. |
| | | |
| | |
| | | return HTTPNotFound('not found') |
| | | |
| | | The above means that a redirect to a slash-appended route will be |
| | | attempted, but instead of :class:`~pyramid.httpexceptions.HTTPTemporaryRedirect` |
| | | attempted, but instead of |
| | | :class:`~pyramid.httpexceptions.HTTPTemporaryRedirect` |
| | | being used, :class:`~pyramid.httpexceptions.HTTPMovedPermanently will |
| | | be used` for the redirect response if a slash-appended route is found. |
| | | |
| | |
| | | if is_unbound_method(view) and self.attr is None: |
| | | raise ConfigurationError( |
| | | ( |
| | | 'Unbound method calls are not supported, please set the class ' |
| | | 'as your `view` and the method as your `attr`' |
| | | 'Unbound method calls are not supported, please set the ' |
| | | 'class as your `view` and the method as your `attr`' |
| | | ) |
| | | ) |
| | | |