Register permission function & return the original function.

        This is typically used as a decorator::

            permissions = PermissionsRegistry()
            @permissions.register
            def can_do_something(user):
                ...

        For internal use only: you can pass ``_return_entry=True`` to
        have the registry :class:`.Entry` returned instead of
        ``perm_func``.

def register(self, perm_func=None, model=None, allow_staff=None, allow_superuser=None,
                 allow_anonymous=None, unauthenticated_handler=None, request_types=None, name=None,
                 replace=False, _return_entry=False):
        """Register permission function & return the original function.

        This is typically used as a decorator::

            permissions = PermissionsRegistry()
            @permissions.register
            def can_do_something(user):
                ...

        For internal use only: you can pass ``_return_entry=True`` to
        have the registry :class:`.Entry` returned instead of
        ``perm_func``.

        """
        allow_staff = _default(allow_staff, self._allow_staff)
        allow_superuser = _default(allow_superuser, self._allow_superuser)
        allow_anonymous = _default(allow_anonymous, self._allow_anonymous)
        unauthenticated_handler = _default(unauthenticated_handler, self._unauthenticated_handler)
        request_types = _default(request_types, self._request_types)

        if perm_func is None:
            return (
                lambda perm_func_:
                    self.register(
                        perm_func_, model, allow_staff, allow_superuser, allow_anonymous,
                        unauthenticated_handler, request_types, name, replace, _return_entry)
            )

        name = _default(name, perm_func.__name__)
        if name == 'register':
            raise PermissionsError('register cannot be used as a permission name')
        elif name in self._registry and not replace:
            raise DuplicatePermissionError(name)

        view_decorator = self._make_view_decorator(
            name, perm_func, model, allow_staff, allow_superuser, allow_anonymous,
            unauthenticated_handler, request_types)
        entry = Entry(
            name, perm_func, view_decorator, model, allow_staff, allow_superuser, allow_anonymous,
            unauthenticated_handler, request_types, set())
        self._registry[name] = entry

        @wraps(perm_func)
        def wrapped_func(user, instance=NO_VALUE):
            if user is None:
                return False
            if not allow_anonymous and user.is_anonymous():
                return False
            test = lambda: perm_func(user) if instance is NO_VALUE else perm_func(user, instance)
            return (
                allow_staff and user.is_staff or
                allow_superuser and user.is_superuser or
                test()
            )

        register.filter(name, wrapped_func)

        log.debug('Registered permission: {0}'.format(name))
        return entry if _return_entry else wrapped_func